Skip to content

fix(cli): preserve exact mutation filtering with vitest 5 - #1003

Merged
blafourcade merged 3 commits into
nextfrom
fix/vitest-five-mutation-filter
Oct 12, 2026
Merged

blafourcade merged 3 commits into
nextfrom
fix/vitest-five-mutation-filter

Conversation

@blafourcade

@blafourcade blafourcade commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

🎯 What & why

Complete the CLI Vitest 5 migration deferred in #912. Stryker 10 built space-joined test names, while Vitest 5 filters canonical suite names; an unpatched nested dynamic canary survived with zero executed tests (50% instead of the required 100%).

🛠️ How it works

A pnpm patch pinned to @stryker-mutator/vitest-runner@10.0.0 uses native fullTestName for both runner IDs and worker coverage IDs. Each selected file receives its own escaped, anchored name pattern through Vitest specifications, with an exact file check to avoid substring filename matches. Standalone initialization preserves reporter setup; unfiltered runs retain related-file selection.

Explicit extends: false preserves project boundaries under Vitest 5. Reporter fixtures include the new task fields. Static load-failure and dynamic selection canaries retain the 100% floor, and dynamic mutants must execute exactly their covering test. A real-runner integration test checks cross-file selection and similarly named sibling files. Replaying framework mutants after the canonical-ID change exposed 92.2% beneath its existing 93% floor. Thirty-eight contract cases now verify recipe diagnostics and visibility, and plugin name/tool/scope isolation, native refs, dependents, and neighbouring files. The complete framework mutation run passes at 93.028% against its unchanged 93% floor (9,466 mutants). No product behavior, thresholds, or exclusions change.

🧪 How to verify

  • cd cli && pnpm install --frozen-lockfile && pnpm test:coverage && pnpm typecheck && pnpm lint && pnpm knip && pnpm build
  • cd cli && node scripts/run-mutation.mjs canary --force: 4 mutants killed, 100%; each dynamic mutant runs exactly one covering test.
  • Local validation on the latest next: 6,987 tests passed, 1 skipped; coverage 98.77% statements, 95.77% branches, 99.55% functions, 99.39% lines. Architecture (145 tests), typecheck, lint, Knip, type honesty, and build pass (750.5 KB within the existing 751 KB budget). Canary passes both fresh and incremental runs. Full framework mutation validation passes at 93.028% with the existing 93% floor. Smoke before rebasing: 136 passed, 0 failed, 1 optional remote skip; CI repeats it on the final commit.

⚠️ Heads-up

Final remote validation on 81c5c4ab: all 33 checks pass, including Windows, coverage, smoke, build, every mutation scope, and cli / gate. CI confirms 6,987 passing tests with 1 skipped; framework meets its unchanged 93% mutation floor.

The runner patch is specific to Vitest 5 and runner 10.0.0. Reassess or remove it when upgrading the runner; the committed patch and frozen lockfile make installation reproducible.

✅ I certify

  • I DO CERTIFY I READ EACH LINE OF THE PULL REQUEST BECAUSE I AM A SOFTWARE ENGINEER, NOT A AI PUPPY.

@blafourcade
blafourcade requested a review from a team as a code owner October 12, 2026 09:26
@blafourcade
blafourcade merged commit 0940c07 into next Oct 12, 2026
39 checks passed
blafourcade added a commit that referenced this pull request Oct 12, 2026
Brings #1003, which restores Stryker's per-test filtering under Vitest 5
(#912): without it, mutants survive with no test run, and the telemetry
and presentation scores fell under their floors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VWNxk63AGKkqE8HRqHLjGp
@aidd-bot aidd-bot Bot mentioned this pull request Oct 16, 2026
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