Skip to content

A .test.tsx is invisible to test discovery *and* to the independent oracle that exists to catch discovery holes — 6th cycle, and the coverage rewrite now globs {ts,tsx} while discovery does not #950

Description

@sroussey

What

scripts/lib/testDiscovery.ts matches only .test.ts, in all four walks:

$ grep -n '\.test\.ts"' scripts/lib/testDiscovery.ts
163:    for (const f of walkFiles(join(TEST_BASE, dir), ".test.ts")) {
175:      for (const f of walkFiles(join(ROOT, group, pkg, "src"), ".test.ts")) {
185:    for (const f of walkFiles(join(ROOT, dir), ".test.ts")) {
206:  return walkFiles(ROOT, ".test.ts");

Line 206 is the part that makes this more than a missing glob. It is findAllTestFiles(), whose own docstring says it is the check on the other three:

"This is the independent oracle discoverTestFiles() is checked against: the section of a discovered file is derived from its own directory, so asking 'is every discovered file in a known section' is vacuously true. The failure that actually matters is a test file in a location discovery never scans."

The oracle and the thing it audits share the same blind spot, so --check-sections reports clean on a tree containing a .test.tsx that runs nowhere:

$ bun scripts/test.ts --check-sections
Discovered 781 test file(s) across 31 section(s)
...
Every test file is discovered and reachable by section+kind selection.

Why it matters now rather than in the abstract

There are no .test.tsx files today (find … -name '*.test.tsx' | wc -l0), which is exactly why nothing has caught it for six cycles. What has changed is the surrounding surface:

$ find examples/cli/src examples/web/src -name '*.tsx' | wc -l
53

53 .tsx source files sit inside discovered sections (cli, web), and this window added two more view components to the console that a React test would naturally accompany:

$ git diff --name-status fb861bb..HEAD -- 'examples/*' | grep '^A.*\.tsx$'
A	examples/cli/src/web/client/views/ChatTranscript.tsx
A	examples/cli/src/web/client/views/GroupView.tsx

ChatTranscript.tsx is the console's rendering of chatTranscript (web/client/state.ts), which zips what the console sent against the AgentTask rows it saw — the kind of pure-presentation logic the repo's own src/ui/model/ convention says should be tested. Anyone writing ChatTranscript.test.tsx gets a file that is never selected by any runner, never reported as unreachable, and never counted.

And the repo now disagrees with itself about whether .tsx is a thing:

$ grep -rn 'ts,tsx' scripts/
scripts/workspaceSource.test.ts:141:        expect(globs).toContain(`${group}/*/src/**/*.{ts,tsx}`);

The coverage source-rewrite (4de62cd1d, this window) globs {ts,tsx}; discovery does not. Two adjacent scripts, opposite answers.

Proposed fix

  1. Make the three section walks accept .test.tsx as well as .test.ts — the suffix is the only thing that needs to change, and kindOf() already keys on .integration. / .e2e. infixes which work identically on a .tsx name.
  2. Separately and more importantly, make findAllTestFiles() match a broader pattern than the walks it audits — /\.test\.[cm]?[jt]sx?$/. An oracle that uses the same predicate as the thing under test cannot find a predicate bug, which is the failure mode here. testDiscovery.test.ts already fails on a file "in a location discovery never scans"; it should equally fail on a file discovery's pattern never matches.
  3. Either add a .tsx project to vitest.config.ts's derived project map, or — if React tests are deliberately out of scope — say so in scripts/lib/testDiscovery.ts and have the broadened oracle fail on a .test.tsx, so the decision is enforced rather than implied by a missing character.

Measured on origin/main @ 2d36880 (0.6.0). First recorded 2026-08-10; this is the sixth consecutive cycle.

Found during the 2026-09-14 review of packages/.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions