Skip to content

test: put every unit test in a __tests__ folder beside the file it tests - #1656

Merged
joshunrau merged 7 commits into
DouglasNeuroInformatics:mainfrom
joshunrau:test-layout
Oct 5, 2026
Merged

joshunrau merged 7 commits into
DouglasNeuroInformatics:mainfrom
joshunrau:test-layout

Conversation

@joshunrau

Copy link
Copy Markdown
Collaborator

What

Every unit test now lives in a __tests__/ folder beside the file it tests, named after it: src/index.ts is tested by src/__tests__/index.test.ts. Package-wide suites stay in test/ (apps/api/test, runtime-bundler/test, runtime/v1/test).

  • apps/web/src/__tests__ held 69 specs, mostly for routes, because the TanStack generator treats any file under src/routes as a route. routeFileIgnorePattern: '^__tests__$' in apps/web/vite.config.ts now skips test folders, so route specs sit beside their routes.
  • Specs that tested another package's code moved there. Web's LanguageToggle and zod error-map specs are merged into react-core's own. This undoes the error-map split from test: reach 100% unit test coverage by deleting dead code, and enforce it #1655.
  • Specs covering several files were split, and duplicates removed. Three of the four routes in gateway-route-guards already tested their own guards; group/email-templates gained the missing cases. The libui DataTable spec is now asserted through the audit logs route, its only consumer. record-array-initial-values is deleted, since nothing uses record-array any more.
  • Stray specs in other packages (schemas, playground-url, instrument-bundler, runtime-meta, subject-utils) moved into __tests__/. runtime-meta's specs are now linted for the first time. subject-utils/src/test.ts ran only because of a root vitest glob, which is removed.
  • api's .spec.ts unit tests are renamed .test.ts, so .spec now means the Playwright suite only.
  • eslint enforces the layout. Two inline rules in eslint.config.js:
    • odc/unit-test-names-subject: a test must sit in __tests__/, beside a file of the same name, with the .test suffix.
    • odc/test-tooling-in-tests-folder: only __tests__/ and __mocks__/ may import vitest or @testing-library. This replaces the routes-only ban.
    • instrument-library is exempt from the naming rule, because a __tests__/ folder inside an instrument directory breaks its build.

Verification

  • pnpm lint is green.
  • pnpm test:coverage: 386 files, 4372 tests, 100% on every metric.
  • vitest list --filesOnly collects all 386 tracked test files.
  • pnpm test:e2e: 277 passed. That run regenerated route-tree.ts with the route test folders present, and the file came out unchanged.
  • pnpm pack --dry-run: no specs are published from instrument-bundler or playground-url. instrument-bundler's files exclusion is widened to !/src/**/__tests__.

Exceptions

  • No new e2e spec. This only moves and merges tests and changes no behaviour.
  • The two eslint rules have no unit tests. Each violation kind was checked with throwaway files.
  • serve-instrument already publishes its 4 specs to npm, because it has no files field. This PR doesn't touch that package.

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

joshunrau and others added 7 commits October 5, 2026 16:19
… map cases

Both web specs tested react-core code, so a spec named after the file it tests belongs here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each spec now sits in a __tests__/ folder next to its subject and is named after it. The
reconcileInterfaceLanguage half of the old language spec becomes the services/i18n spec, and its
_app beforeLoad half joins the _app guard spec. The record-array spec pinned a libui contract that
no code in the repo depends on any more, so it is gone.

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

The router generator now skips any __tests__ folder under src/routes, and the eslint ban on test
imports there exempts those folders, so a route's spec can sit next to it like every other spec.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each route spec now sits in a __tests__ folder next to its route file and is named after it.

- The gateway guard spec repeated cases three route specs already had; the one route it alone
  covered, group/email-templates, carries its guard cases in its own spec now.
- The branding spec covered two routes, so it is split into index and login-page.
- The libui DataTable server-mode spec pinned a contract only the audit logs route relies on, so
  that route's spec asserts it through the page instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- schemas and playground-url specs sat beside their sources; they now sit in __tests__ folders.
- instrument-bundler's vendor spec is named after vendor/esbuild.ts and lives beside it, and the
  package's files field now excludes nested __tests__ folders so it stays out of the tarball.
- runtime-meta's two specs both tested src/index.js; they are one spec under src/__tests__ now,
  which also brings them under eslint for the first time.
- subject-utils had a second spec, src/test.ts, that only ran because of a root vitest glob for
  files named test.*; its one unique case joins the index spec and the glob is gone.

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

api was the only workspace using .spec for unit tests, which the Playwright suite in testing/ also
uses. With no .spec files left, the project's own include added nothing to the root glob, so it is
gone too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two inline rules keep tests from drifting back into shared folders:

- odc/unit-test-names-subject: a *.test.* file under src/ must sit in a __tests__ folder, beside a
  file of the same name, and must not use the Playwright suite's .spec suffix.
- odc/test-tooling-in-tests-folder: only a file in a __tests__ or __mocks__ folder may import vitest
  or @testing-library. It replaces the routes-only restriction, which flat config would have needed
  restated in every narrower no-restricted-imports block.

instrument-library is exempt from the naming rule, since its tests cannot live inside instrument
directories.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@joshunrau
joshunrau merged commit f211fbf 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