The first thing I was to start working on under my mentor’s guidance, Carlos Soriano, was the implementation of unit tests.
While unit tests are meant to be fairly short and simple, tackling individual instances of a functionality or component, Nautilus would not really allow us to do that. Due to Nautilus’ nature and its tight relation to I/O operations, unit testing for us meant cherry-picking the simpler functions which we use and testing these. However, for the larger, more important components, we’d rely on integration tests, which represented one of the following items on our list.
We started working on nautilus file operations first, which involves functionalities such as copy/paste, move, trashing, deleting. Before this, although I had contributed one unit test before, I decided I would start small. So, while going through our file-operations code, I found a function which tests if a directory contains any children files. As I needed to get a better hold of the libraries we would work with (the glib testing framework, in particular), I decided to write an unit test for this function. Fortunately, its implementation was straight-forward, more or less, so testing it did not prove too difficult (designing some tests and the edge cases). The merge request I opened on it was accepted, after a few changes, and is now in our master version (as you can see here).
Next, I wanted to go with something bigger, something which we outlined when talking about what we wanted to test exactly, so copy/paste it was! As per my previous experience, I tried creating a couple of small file hierarchies and copy/paste-ing these expecting everything to go smooth. Boy, was I wrong. What followed was my mentor explaining me why it did not work as I would suspect it to and how to work on it. Turns out, pretty much all of these operations are asynchronous, so before writing any actual tests, we need to create a synchronous version, one which can be used by the “async” one, just that it would be on a different thread.
Moving forward with the implementation of the asynchronous alternative for the copy operation, I started designing the tests, only to bump into another issue. Whenever we would copy file X to directory Y, we had the option of renaming it so, naturally, I designed cases for both alternatives. The bigger issue here was if we tried to copy directory X containing file Y into directory Z. Copying X into Z, while changing its name to “T”, would result in Y containing a directory named T (which is fine) aaaaand a file named Z (which wasn’t really fine). This was a flaw in our code, so after a quick discussion on it with my mentor, we concluded that its fine to split tests into two here as well: one where we don’t change any name (so the result would be Z/X/Y) and one where do change the target name (resulting in Z/T/T), only we would comment the second one and flag the issue in order to be worked on afterwards. I opened an issue on it and moved on with the implementation of the test.
Unfortunately, my finals session started so I had less time to work on my project. My mentor was awesome about it and said I should focus on my exams and it would be fine to contribute when I have the time for it. While it’s not final yet, this would be a sneak-peek at the copying test right now which I aim to finish alongside the move one (which I started writing while trying to figure out the new name issue regarding copying I’ve just mentioned above).
I honestly can’t wait to be done with finals in order to work on these. Contributing to to Nautilus, being an active member of its community feels way more rewarding than studying algorithms in uni. 🙂