Connecting the pieces on how I solve bugs

A Systematic Approach to Solving Bugs

Explaining my thought process on approaching 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.

Improving Filer

Filer aims to mimic the Node.js fs API, but currently lacks support for the newly introduced fs.promises API in Node v10.0.0.

Recently, a student from Seneca College landed support for asynchronous, or promise-based functions, which in-turn, requires new tests to be written for this functionality. That’s where we (70+ open source students) come into play. Cue the horde of PR’s:

54 PR’s made by 52 people!

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.

  1. 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:

git remote add upstream https://github.com/filerjs/filer.git

Step 4.2: Adding the remote for filerjs/filer
The git remote -v command allows us to view all remotes!

5. Our setup so far is looking promising — let’s actually open up the source code now. I use VSCode, so I can simply open the currently directory with code .:

Step 5: Opening the source code — finally!

And that’s it for our setup — let’s dive into actually fixing this bug! 👊🏽

Solving Our Bug

Getting setup was the easy part — we now need to:

  • Install dependencies for Filer
  • Make sure the project is working on my machine by running npm run test
  • Locate where the unit tests for fs.truncate() live
  • Add a test that passes when given a string for the length to truncate by

6. Reviewing Filer’s documentation states that we have to run npm install to download dependencies:

Step 6: Installing required dependencies for Filer using npm install

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 search the 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:

Step 9: Adding our new test

10. Let’s check that our test passes by running npm run test again. Uh oh — it looks like something is wrong:

Step 10. Getting the test to pass

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:

  1. git add src/filesystem/implementation.js
  2. 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.

Check out the PR on GitHub here!

Final Thoughts

The great thing about open source is that there exists a process behind it all. From my own experience, the more exposure to different projects, the wider your problem solving skillset grows.

Cheers,

Sean 👨🏽‍💻