test: start applying the isolated testing style - #16
Conversation
First slice of the sweep: stream, time-rules and index. Each test now opens with given/when/then filled in with the case rather than a restatement of the code, the helper that was at module scope has moved inside its describe, and take's count comes from faker so the test proves it honours whatever it is given. Dates stay fixed throughout. They are the domain data under test, and randomising them would mean computing the expected boundaries with the code under test. Comments follow the prose rules too, so the significance tails and the colon explainers in the old ones are gone.
cascade, rota and schedule. The shared ON_CALL and OPENING_HOURS fixtures are gone: each test builds what it needs from a local factory, so no test can lean on how another left things. Rota names now come from faker, through uniqueArray so two people are never the same person, and the rendered expectations interpolate them. That proves the value is carried through rather than matching a literal the test also wrote. One test keeps literal names on purpose, because the type is what it asserts and a faker name widens to string. One lint rule had to give way. unicorn/consistent-function-scoping wants a helper hoisted to module scope, which is where shared mutable fixtures come from and what the style exists to avoid. It is off for test files now, with the reasoning in .oxlintrc.json.
The edge instants move inside a root describe, and each test says which case it is about. The half-open cases carry their reason now: closing time is outside the day so that two adjacent days cannot both claim it, and the touching-versus-overlapping pair says what the gap between the two comparisons buys a union.
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 52 minutes Limit details: You’ve used all 2 included reviews currently available under your plan. You completed 83 included PR reviews in the past 7 days; at that activity level, included reviews refill at 2 reviews per hour. This review is too large to run within your organization's remaining usage spending cap. Raise or remove your spending cap in the billing tab, then retry. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (9)
Comment |
Applies the
isolated-testing-styleandpart-factory-test-dataskills toQuando's test suite. Seven of the thirteen test files are done here, and the
remaining six are listed at the bottom.
The survey found less to fix than expected. No mocks, no spies, no
beforeEach/afterEach, and no call-count assertions outside one deliberatecase. What was missing was given/when/then, and what needed removing was the
module-level fixtures every file shared.
Shared fixtures out, local factories in
Before, one rota built at module scope and used by six tests:
After, each test builds its own from a factory inside the
describe, with namesfrom faker:
uniqueArrayis there so two people are never the same person. The renderedexpectations interpolate the names as well, which is the part that earns the
change: a test comparing against a literal it also wrote proves less than one
checking the value it was handed comes back.
Given, when, then
Filled in with the case, not with a restatement of the code. The half-open
boundary tests now carry the reason they exist:
Three decisions worth reviewing
Dates stay fixed. They are the domain data under test. Randomising them
would mean computing the expected boundaries with the code under test, which the
skill rules out. Faker is used for values the assertions do not turn on: names, a
count, a
takesize.One test keeps literal names. The type is what it asserts, and a faker name
widens to
string:A lint rule had to give way.
unicorn/consistent-function-scopingwants ahelper hoisted to module scope, which is where the shared fixtures this change
removes come from. It is off for test files now, with the reasoning in place:
Still to do
build,parse,query,resolve,interval-streamandinterpret, in afollow-up. One deliberate exception is planned for
interval-stream: it assertspull counts through
metered(), which reads as a call-count assertion. Lazinessis real behaviour and the pull count is the only way to observe it, so it stays,
with a comment saying why.
Checks
pnpm checkpasses, and passed at each commit on the branch.Behaviour is untouched. Every one of the 200 tests asserts what it asserted
before, and
@faker-js/fakeris the one new devDependency.