A Systematic Approach to Solving Bugs

Background

Ever wonder if it was possible to replicate a file system within your browser? Filer, “a POSIX-like file system interface for node and browser-based JavaScript” is just what you’re looking for! Filer works on all modern browsers and can be configured to store contents on different storage providers (ie. data stores) such as IndexedDB, WebSQL, and even regular memory.

Interested in integrating Filer into your projects? Check out the docs here.

Gitting Setup

In this post, I’ll walk through in great detail about my proposal for Issue #499— adding a test for fs.truncate(). This function changes the size of a specified file to be a certain amount of bytes long. In my issue, I’ll need to write a new test to verify if the truncate function properly handles a non-numeric value for it’s len parameter.

First off, I needed to fork the original source code, found at filerjs/filer on GitHub, so that I have my own copy that I can work with:

Step 1: Fork the source code on GitHub

2. Next, I’ll need to clone (or download) the source code to my local laptop in order to actually work with it. First I’ll grab the unique .git URL that GitHub provides:

Step 2: Copy the unique URL to use when downloading the source code

3. With that URL handy, I’ll now clone the source code to my local machine:

Step 3: Clone the source code to your computer

4. This next step is very important! We’ll need to add a remote to point to the original repo. The original source code for Filer lives at filerjs/filer but we created our own copy by forking it — which for me is located at seanprashad/filer.

In order to get the latest code, we want to add a remote, aka a “connection”, to filerjs/filer, which allows us to “pull” any new changes at our own will. This step requires us to go back to the original Filer repo and copy that unique download URL once more:

Step 4.1: Copy the original repo’s unique download URL

With that URL copied, the next step is to actually create the connection to the original repo. I’ll make sure to cd into the newly cloned repo and then run the following command with upstream as the alias for filerjs/filer:

7. Nice — now let’s make sure that our own version of Filer is working by executing the unit tests using npm test. All tests should succeed:

Step 7: Running npm test to make sure that our code works

8. With a confirmed working codebase, let’s create a branch to perform our work on. This will ensure that we can work in parallel with others (who will be performing work on different branches). I’ll create a branch called issue-499 with git checkout -b issue-499:

Step 8.1: Checking out a branch to do my work on

Now we’ll need to find where the tests for fs.truncate() live. Luckily, VSCode has a feature where I can recursively searchthe current directory. I’ll make use of this by pressing Shift + Cmd + F on my Macbook:

Step 8.2: My first attempt at locating the unit test for fs.truncate()

UH OH! I see fs.truncate() being mentioned but those results aren’t what I’m looking for. Ideally, the file name should have truncate in it if it contains the tests for fs.truncate(), right? Let’s try again — this time removing the pair of parenthesis — ( and ):

Step 8.3: Adjusting our search results

Sweet! Adjusting our search results helped us to find fs.truncate.spec.js which has all of the tests we were looking for!

9. Let’s use an existing test as ours will closely resemble the ones that are currently there. We’ll need to pass a string, like 'notAnInteger' for the length parameter:

11. We need to investigate where the definition for filer’s fs.truncate is. To save some time, searching for truncate provides us with a file called implementation.js. There seems to be a section of the truncate_file function that has the implementation for what we’re looking for. I noticed that there was no check to see if the length parameter was an actual integer, so I added it in using Number.IsInteger():

Step 11: Updating the implementation for fs.truncate()

12. Running the tests after the fix shows that we’ve successfully passed all test cases!

Step 12: Checking that the new implementation doesn’t cause regressions

13. We’ve updated the functionality and the respective test to not accept a non-numeric value! We’re ready to push our changed to our forked repo and then open a PR (Pull Request) to request that our code be merged into the original Filer repo (aka, the upstream repo).

Let’s begin by checking what files we’ve changed and only adding those that are relevant to a new commit:

git add src/filesystem/implementation.js

git add tests/spec/fs.truncate.spec.js

Step 13: Preparing the updated file for a commit

If you’re unfamiliar to what a “commit” is, think of it like a “snapshot” of your code at a certain point in time. This way, we can go back in time if we need to.

Let’s add the commit message with something relevant like…

Fixes #499: Add a test for truncate when length is not a number

Step 14: Adding a new commit

After we’re done, a simple git push -u origin issue-499 will upload our code to our forked version of the repository. One last thing to do is open a pull request to have our changes reviewed and merged.

14. From our forked version of Filer, we can easily open a new PR:

Step 14: Opening a new Pull Request to have our code merged in

And that’s it! We’ve hopefully squashed this bug but we’ll have to wait until someone else can review it. Pr’s are an iterative process that takes multiple rounds of review before they’re usually accepted and merged.