Skip to content

test: reach 100% unit test coverage by deleting dead code, and enforce it - #1655

Merged
joshunrau merged 9 commits into
DouglasNeuroInformatics:mainfrom
joshunrau:enforce-coverage
Oct 5, 2026
Merged

joshunrau merged 9 commits into
DouglasNeuroInformatics:mainfrom
joshunrau:enforce-coverage

Conversation

@joshunrau

Copy link
Copy Markdown
Collaborator

Follow-up to #1632, which raised unit coverage to about 99.8% and was merged before this work landed. This PR takes every metric to 100% and makes 100% the gate locally and in CI.

Metric Before After
Lines 99.82% (8720/8736) 100% (8704/8704)
Statements 99.80% (9151/9169) 100% (9129/9129)
Functions 99.89% (2698/2701) 100% (2695/2695)
Branches 99.03% (4816/4863) 100% (4775/4775)

The denominators shrink because the gap was not untested code. It was code no input can reach, so it was deleted.

Dead code removed

Each location was proved dead from the types, every caller, or the library contract, then deleted or restructured so the impossible state cannot be written. Where a deletion relies on a type guarantee, tsc confirms it.

  • Dialogs with no Dialog.Trigger. Radix only ever calls onOpenChange(false) for these (checked against @radix-ui/react-dialog), so if (!open) goes. Affected: the instrument preview, admin instruments, instrument repos, admin users and group manage.
  • Fallbacks on values that cannot be null:
    • ?? [] on a useSuspenseQuery result;
    • ?? {} and ?? '' on schema-required fields;
    • if (records) on a required array.
  • Guards repeating an earlier guard:
    • MapStep resolving behind a disabled button;
    • the login-page submit re-checking a colour it already rejected;
    • the ManageGroupForm reseed that its per-group key already performs (the key site now says so);
    • users.service's null check after a findById that throws.
  • Branches the data cannot take:
    • the PERSONAL_INFO else if on a two-value enum (zod skips superRefine when the base parse fails);
    • an exhaustive switch default;
    • zod 4's int type name (z.int().def.type is 'number');
    • a .trim()med value compared to '\n';
    • split() results checked for falsiness.
  • Exhaustive matches. SeriesInstrumentRenderer's .otherwise(() => null) arms after exhaustive status and step matches are now .exhaustive(), so the compiler holds the guarantee.
  • Submit handlers. The scalar and series handlers are only ever passed to content rendered once the instrument is DONE, so they now take that instrument instead of re-checking the status.
  • Small restructures:
    • EmailTemplateEditor is read-only when given no onChange, replacing a no-op handler;
    • mail settings read zod's flattened errors for the four fields that can fail;
    • the API's mail service decides password inheritance once (passwordSource), instead of guarding impossible null fallbacks at two call sites.
  • API export worker: expandData never produces a failure entry, and the worker only ever acknowledges INIT with success. Both checks, the unused types and the test pinning an impossible failure are gone.
  • Smaller packages: getTargetLanguage is narrowed to multilingual instruments, and the service worker no longer checks a module-level const Map for falsiness.

Bug fixed

#1651: the in-memory replica set is now stored and stopped in onApplicationShutdown, with a unit test. That is what apps/api/AGENTS.md already claimed happened.

Enforcement

  • Threshold: the root vitest.config.ts sets coverage.thresholds: { 100: true }.
  • CI: the unit step runs pnpm test:coverage.
  • Rules: a new root AGENTS.md hard rule says code no test can reach is proved dead and deleted, never ignored or excluded. coverage.exclude stays reserved for non-code.
  • Docs: "Before you are done", odc-done, odc-testing, testing-strategy.md (new §Coverage) and the playbooks now name pnpm test:coverage. They also note that a scoped coverage run needs --coverage.thresholds.100=false.

Verification

  • pnpm lint: green (34/34 tasks).
  • pnpm test:coverage: green at 100% on all four metrics, 4,392 tests passing plus 5 it.fails.
  • pnpm test:e2e: 277/277 passed.

One deletion was wrong at first, and a unit test caught it before commit: the login-page colour check also feeds the live preview, where invalid colours do occur. It was restored, and only the post-guard submit copy was removed.

Exception: no new testing/ spec. The removals change no reachable behaviour, the #1651 fix has no browser-visible effect, and the existing suite passes unchanged.

Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com

joshunrau and others added 9 commits October 5, 2026 13:04
createMemoryConnection kept the replica set in a local, so onApplicationShutdown never saw it
and every test run left a mongod and its temp dbPath behind until the process exited.

Closes DouglasNeuroInformatics#1651

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- export worker: expandData only builds successful entries, so the failure branch and its type go
- users: GroupsService.findById throws on a miss, so the null check after it never ran
- mail: passwordSource decides password inheritance once, which removes the impossible
  null-saved fallbacks and the empty-plaintext branch in encryptPassword
- instrument records: the export worker only acknowledges INIT with success, so the check and
  the test pinning a failure it cannot send go

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each removal is backed by the types, every caller, or the library contract:

- dialogs without a Dialog.Trigger: Radix only calls onOpenChange(false), so `if (!open)` goes
- fallbacks on values the schema or the query makes non-null (`?? []`, `?? {}`, `?? ''`)
- guards repeating an earlier guard: the bulk mapping resolve behind a disabled button, the
  login page submit after its colour check, the group reseed the per-group key already performs
- branches the data cannot take: the PERSONAL_INFO `else if` on a two-value enum, an exhaustive
  switch default, zod 4's never-produced `int` type name, a trimmed value compared to '\n'
- EmailTemplateEditor is read-only when given no onChange, so the default-template dialog no
  longer passes a no-op handler
- mail settings read the flattened field errors of the four fields that can fail

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- the scalar and series submit handlers are only ever given to content rendered once the
  instrument is DONE, so they now take that instrument instead of re-checking the status
- the series renderer's status and step matches are exhaustive, so `.otherwise(() => null)`
  becomes `.exhaustive()` and the compiler holds the guarantee
- inside isSubjectWithPersonalInfo the date of birth and sex are non-null, so their null arms go
- the zod error map test for an affix-less issue describes a hand-raised issue, not a defect

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…instruments

Both callers return early for a unilingual instrument and throw for any other non-array
language, so the string branch never ran.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…le-level map

staticAssets is a const Map created at module load, so it can never be falsy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Only vitest and worker threads reject the target; the `pnpm dev` main thread resolves it through
swc-node. Links the it.fails case to DouglasNeuroInformatics#1653.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The root vitest config sets a 100% threshold on every metric, CI's unit step runs
`pnpm test:coverage`, and AGENTS.md, the testing strategy, odc-done, odc-testing and the
playbooks name it as the gate. Code no test can reach is to be proved dead and deleted, never
ignored or excluded.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The generic --open test only reached the darwin arm of openInBrowser when the suite ran on a Mac,
so on CI's Linux runner that branch was uncovered and the 100% gate failed. Every arm is now
pinned by its own test, and AGENTS.md describes cli.test.ts and the need to pin the platform.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@joshunrau
joshunrau merged commit 2f8fb84 into DouglasNeuroInformatics:main Oct 5, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant