Learn Claude Code by Building DevPulse · Chapter 5

Tests for the streak

The streak looks right on screen, so how do you know it is right for every day and every timezone? By the end of this chapter, DevPulse has 18 tests, you will have written one function yourself, and Claude will have checked the page in a real browser.

One sitting~9 min read, ~25 min to build along
You start fromchapter 4's DevPulse, under git
You buildstreak.js with 18 tests, and a best streak
Chapter 5 of 15Claude writes, you judge
Goes with Episode 5"It runs, but is it right?". The video is being made. This page teaches the same steps, at your own pace.
In a hurry?Jump to the quick reference: every command and key in this chapter, what it does, and when to use it.
Every prompt, ready to copyThis chapter's prompts and commands, each with a Copy button. Type them yourself first; copy if you are stuck or behind.
Where you areDevPulse with a server, two views and a git history, from chapter 4.

It runs. Is it right?

The Week view shows a streak: how many days in a row you logged a task. It looks right. Nothing crashes.

But say you log a task at 00:30 at night, in India. Which day does it count for? If the code takes the date in UTC, it is still the previous day there. Your streak breaks, and nothing on screen tells you.

A program can run and still be wrong. Our eyes will not catch this one.

The question for this chapter

How do you prove the streak is right, not just that it looks right?

Write tests that check it for you

A test is a small program that runs your code with known input and checks the answer. The streak lives inside index.html, where a test cannot reach it. So first it moves to its own file.

Type this into Claude Code, as one lineMove the streak calculation out of index.html into streak.js so it can be tested, and write tests for it in streak.test.js with node's built-in test runner. Include a task logged at 00:30 India time (set TZ=Asia/Kolkata in the test). Don't change how the streak works.
Claude's summary: streak.js now holds the logic and index.html loads it; server.py got a /streak.js route, a small addition beyond what you asked for; streak.test.js sets TZ=Asia/Kolkata and tests a task at 00:30 IST plus no tasks, yesterday only, consecutive days, a gap, old tasks, duplicates and a month boundary.
The tests it wrote, listed. It also tells you about one change you did not ask for: a route in server.py.

Now run them yourself. Node has a test runner built in; nothing to install.

Type this into Claude Code! node --test
node --test: older tasks without yesterday or today give no streak, duplicate tasks on one day count once, streak spans a month boundary; tests 9, pass 9, fail 0.
tests 9, pass 9, fail 0. Each tick is one situation checked.

See what the test protects

All pass. So was the test even needed? In our recording, Claude's streak code already used the local date. Let's try to understand what the 00:30 test guards against: ask Claude to break it on purpose.

Type this into Claude Code, as one lineShow me why the 00:30 test matters: change ymd to use toISOString() for a moment, run node --test and show me what fails, then put it back.
Claude changes one line in streak.js: toLocaleDateString('en-CA') becomes toISOString().slice(0, 10) with a TEMP BREAK comment, then runs node --test.
One line changes: the local date becomes the UTC date. It even marks it TEMP BREAK.
Claude explains: the task is dated the 29th, but the app looks for the 28th, so it doesn't find it; streaks come out one day short; the same bug would hit any user ahead of UTC, and would pass unnoticed on a UTC machine, which is why the test sets TZ=Asia/Kolkata.
The tests fail, and Claude says why. On a computer set to UTC this bug would never show. That is why the test sets India's timezone.

Then it puts the line back. Run ! node --test again: 9 pass. The test now guards that line for every future change.

Write the key part yourself

Claude writes fast. But if it writes everything, you learn nothing. Claude Code has an output style for learning. In it, Claude leaves the key part for you.

Type these into Claude Code, one at a time/output-style learning Add a best streak, the longest run of days ever, under the streak on the Week view.
/output-style lists the styles: default, Proactive, Concise, Explanatory, Learning (Claude pauses and asks you to write small pieces of code for hands-on practice).
The styles on offer. Learning: Claude pauses and asks you to write small pieces of code.
Your Task: in streak.js, implement bestStreak(tasks). Look for TODO(human). Guidance: task dates are YYYY-MM-DD strings, dedupe them first, sort and walk them, step with new Date(y, m, d + 1) and compare, an empty list returns 0.
Claude wires up the page and leaves one function empty, marked TODO(human), with guidance on how to think about it.

Open streak.js in your editor, find TODO(human), and write the function. Here is what I wrote.

Writing bestStreak in VS Code, shown 2 times faster. Try yours before you watch mine.
What I wrote, if you want to compareconst days = [...new Set(tasks.map(t => t.date))].sort(); let best = 0, run = 0, prev = null; for (const day of days) { const [y, m, d] = prev ? prev.split("-").map(Number) : []; run = prev && ymd(new Date(y, m - 1, d + 1)) === day ? run + 1 : 1; best = Math.max(best, run); prev = day; } return best;

Now Claude checks your code

You wrote it. Now turn the tables.

Type this into Claude CodeI wrote bestStreak. Check it, add tests for it, and run them.
The new tests cover unsorted input, duplicate days, a one-day gap, month and year boundaries, a leap day, and best streak at least the current streak. Limits of the tests: daylight saving time is not covered, since Asia/Kolkata has none; index.html not tested in a browser.
New tests, and an honest Limits of the tests: what they still do not prove.
node --test: bestStreak never less than the current streak; tests 18, pass 18, fail 0. Your run matches mine: 18 of 18 pass.
18 of 18 pass, run by you, not only by Claude.

One limit is still open: nobody has looked at the page. For that there is /verify. It builds and runs the app, opens it in a real browser and checks the change.

Type this into Claude Code/verify
/verify's report: the best streak line renders correctly in a browser; a 404 in the console is the missing favicon; an unrelated server already held port 8765 so it used another and left that one running; and: A mistake on my side. I ran git stash and git stash apply without being asked. I confirmed the working tree was identical.
It checked the page in a browser. And read its last points: it owns up to running a git command you did not ask for, and confirms nothing changed.

That is the habit of this whole series. Claude writes. You judge. It told us about its own mistake, and we checked the files ourselves.

When you are done, type /output-style default to go back to the normal style, and commit with /commit-commands:commit.

What tests cost

Tests are more code to keep. When the streak rule changes, the tests change too. And tests only check what you thought of: Claude itself said daylight saving time is not covered.

Look at how much this chapter cost to build: two long prompts, a review and a browser check. Do that all day, and your plan's limit arrives early. That is chapter 6.

Quick reference

The prompts from this chapter, ready to copy: every prompt, chapter 5.

Command or keyWhat it doesUse it when
Move … into streak.js so it can be testedPuts logic in its own file, where a test can reach itCode you want to test is buried in a page
! node --testRuns every test file in the folderYou changed something and want proof it still works
Show me why this test matters …Breaks the code on purpose, runs the tests, puts it backYou want to see what a test protects
/output-style learningClaude explains and leaves TODO(human) for you to writeYou want to learn the key part, not just get it
/output-style defaultBack to the normal styleYou are done practising
I wrote … Check it, add testsClaude reviews your code and tests itYou wrote code and want a second check
/verifyBuilds and runs the app to confirm a change really worksTests pass but you have not seen it run

References

Where each command and fact on this page comes from. Every screenshot is from our own recording on 29 Oct 2026, Claude Code 2.1.312, Node 24.

  1. Node.js · Test runner (node:test) node --test finds and runs test files with no package to install. https://nodejs.org/api/test.html
  2. MDN · Date.prototype.toISOString() toISOString always gives the date in UTC, which is why a task at 00:30 India time lands on the previous day. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString
  3. Anthropic · Output styles The Learning style: Claude explains and leaves TODO(human) for you to write. https://code.claude.com/docs/en/output-styles
  4. My own recording · 29 Oct 2026, Windows 11 Claude's first streak code was already right; the test showed what one small change would break.