After posting, I was asked how I made the connection. The short answer is I spent a bunch of time stepping through Jest source code in my debugger. The longer answer is I followed a process I picked up in the humanities. Reading Plutarch's Parallel Lives may not seem like reading source code, but you have the same goal. You read to understand the intentions and ideas of another person.
How To Read a Book by Mortimer J. Adler and Charles Van Doren best describes the reading process. They describe four types of reading: elementary, inspectional, analytical, and syntoptical. Each type of reading played a crucial role in researching and writing the last article. I’ve structured this article around them.
Elementary Reading is being able to understand the grammar and syntax of a language. This level of reading is the prerequisite to understanding another person's ideas. There's not much to discuss at this level of reading for our purposes.
Inspectional reading is strategic skimming. You want to grasp, as quickly as possible, the structure and meaning of a work. The sooner you learn the structure of a work, the sooner you can grasp its finer points. This means skimming the chapters, watching the movie first, or listening to a podcast.
Analytical reading means reading for intent, structure, and relations. Different genres have different rules for these things as does code. Some parts of a file are "the main point" while others serve a supporting purpose. Since analytical reading is the most time-consuming and fruitful, prefer primary sources. Formal specs and source files are harder to read than summaries. But source docs give you unfiltered detail at a granular level. How do you know that blog post didn’t miss something relevant to your problem? If you haven’t read specs and source files, you’re trusting someone else’s interpretation.
I started with the ECMAScript spec section 9. It didn't have any direct answers, but I had a better mental model of what was happening when my tests ran. The ECMAScript spec made sense of the
Closure section of the
Scope tab in Chrome DevTools. Monitoring the closures section during debugging helped answer several of my questions.
Setting up the Debugger
node --inspect node_modules/.bin/jest --runInBand path/to/your/test1
Open up Chrome and go to
chrome://inspectand click Open dedicated DevTools for Node.
Open up your test file in Sources tab and run your tests
Using the Sources Tab, I executed the test line-by-line. I did this for test files, the components under test, and some Jest source code. The key Jest file I looked at was
node-modules/jest-runtime/build/index.js. At each step, I monitored the Closure section and paid attention to the mocks. I monitored when the mocks received references and documented those changes. I then followed this line-by-line process for each of the four examples. Following code execution, while writing down my thoughts yielded the most results. I wrote out what I thought was happening, noted my questions, and made sure to answer every one of them.
This stage of analytical reading is when I figured out:
describeblocks but then executes them later
When Jest was actually evaluating function expressions defined within the test files
When doing analytical reading across several works, you produce a lot of notes. Organizing those notes into something coherent is the next step.
Syntoptical reading is a term coined by Adler to mean reading across many authors. If analytical reading is conversing with a single author answering their own question, then syntoptical reading is conversing with many authors to answer your own questions. You then take your answers and synthesize them into a cohesive line of thought.
A good sign the end is near is when you can create a rough outline from your notes. Here was one of my earlier outlines:
- Sneaky Temporal Deadzone
- Test Step Through
- Import parent module
- Jest function:
- Jest function:
- Critical line of Jest code:
const module = this._mockFactories.get(moduleID)()
- ECMA Script Sepc
- Function Declaration vs Function Definition
- Jest Docs
This outline differs from the one I finally published. I still had questions and every time I answered one I saw a better way to organize my thoughts. The final iteration came after I had answered my questions on how the 4 examples were executed. When I put that final set of notes together, I could see there were 6 stages that each example went through. Those stages explained the differences in how the examples were executed. From that point, the rest of the article was filling in details from my exploration.
Code describes machine instructions which distinguishes it from other textual works. Despite its mechanical nature, source code still embeds ideas in human-readable language. So reading to grasp ideas in code will use the four types of reading I've mentioned. By understanding each type of reading, you can focus your intent when doing your research. So dig into that source code and make sense of your problem. All the rest is commentary.
Our awesome Jobber technology teams span across Payments, Infrastructure, AI/ML, Business Workflows & Communications. We work on cutting edge & modern tech stacks using React, React Native, Ruby on Rails, & GraphQL.
If you want to be a part of a collaborative work culture, help small home service businesses scale and create a positive impact on our communities, then visit our careers site to learn more!
Debugger explanation: ↩
inspectallows you to access the test in your chrome dev tools
runInBandprevents Jest from running in parallel (not great for debugging)
running Jest from the
node_modulesdirectory was necessary in my environment to properly connect to the node debugger. This might vary depending on your environment.