test: migrate test suites from Jest to Vitest#46
Merged
Conversation
Replace the two Jest configurations (web via next/jest + jsdom, CLI via
ts-jest + node) with a single Vitest config exposing two projects that mirror
the previous split:
- web: jsdom environment, testing-library, next/server mock + URLPattern
polyfill setup, covers everything except src/cli/** and src/lib/**.
- cli: node environment, covers src/cli/**/*.test.ts and src/lib/**/*.test.ts,
v8 coverage -> coverage/cli.
Both projects use globals: true and resolve the @/ alias (vite-tsconfig-paths
plus an explicit resolve alias so require/import both resolve).
Changes:
- Add vitest, @vitest/coverage-v8, jsdom, @testing-library/jest-dom,
vite-tsconfig-paths; remove jest, @jest/globals, @types/jest,
jest-environment-jsdom, ts-jest.
- Scripts: test -> "vitest run", test:web -> "vitest run --project web",
test:cli -> "vitest run --project cli", update-snapshots -> "vitest run
--update". test:e2e (Playwright) is unchanged.
- Codemod all ~94 test files: jest.* -> vi.*, jest type helpers -> vitest
(Mock/Mocked/MockedFunction/MockedClass/MockInstance), @jest/globals ->
vitest, @jest-environment docblocks -> @vitest-environment.
- Port setup file to vitest.setup.web.ts (vi.mock next/server, keep URLPattern
polyfill, drop the global.jest shim).
- Add vitest.d.ts referencing vitest/globals so tsc knows the test globals.
- Delete jest.config.js, jest.config.cli.js, _jest.setup.web.ts,
_jest.setup.cli.ts.
- Update the pr-check skill description to say Vitest.
Vitest-vs-Jest fixes required during the migration:
- jest.requireActual inside mock factories -> async factory + await
vi.importActual.
- require('@/...') / require('../x.ts') inside tests -> top-level import or
await import (Vitest's require does not resolve the @ alias or .ts).
- Default-export module mocks (pLimit, keyv) must return { default: ... }.
- fs / fs/promises mock factories must expose a default key so storageService's
default imports are intercepted.
- Duplicate/auto-mock of llm-evaluation-service removed (the factory mock is
the intended one; the auto-mock overrode it).
- Fake-timer hook test uses useFakeTimers({ shouldAdvanceTime: true }) so
testing-library waitFor can progress.
- Empty (all-commented-out) describe marked describe.skip (Vitest errors on
suites with no tests).
Two pre-existing broken tests (they fail on main too; unit suites are not run
in CI) are marked .skip with an explanatory note rather than deleted:
llm-coverage-evaluator "backup judge" (stale vs current DEFAULT_JUDGES) and
useGitHub "throw when branchName missing" (source returns null, not throws).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T9z5V7UM3FhqomggQ3XTVG
Contributor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #45
Summary
Migrates both test suites (~94 test files) from Jest to Vitest. The two Jest configs (web via
next/jest+ jsdom, CLI viats-jest+ node) are replaced by a singlevitest.config.tsexposing two projects that mirror the previous split. Playwright e2e is left untouched.jsdomenvironment, testing-library, ported setup (next/servermock +URLPatternpolyfill), covers everything exceptsrc/cli/**andsrc/lib/**.nodeenvironment, coverssrc/cli/**/*.test.tsandsrc/lib/**/*.test.ts, v8 coverage →coverage/cli.globals: trueand resolve the@/alias (vite-tsconfig-paths+ explicitresolve.alias).Changes
vitest,@vitest/coverage-v8,jsdom,@testing-library/jest-dom,vite-tsconfig-paths; removejest,@jest/globals,@types/jest,jest-environment-jsdom,ts-jest.@testing-library/reactkept.test→vitest run,test:web→vitest run --project web,test:cli→vitest run --project cli,update-snapshots→vitest run --update.--experimental-vm-modulesremoved.test:e2eunchanged.vitest.config.ts(two projects + root coverage),vitest.setup.web.ts(ported:vi.mock('next/server'),URLPatternpolyfill; dropped theglobal.jestshim), andvitest.d.ts(/// <reference types="vitest/globals" />sotscknows the test globals).jest.*→vi.*; jest type helpers → vitest (Mock/Mocked/MockedFunction/MockedClass,SpyInstance→MockInstance);@jest/globals→vitest;@jest-environmentdocblocks →@vitest-environment.jest.config.js,jest.config.cli.js,_jest.setup.web.ts,_jest.setup.cli.ts.pr-checkskill description (Jest → Vitest). No CI workflow changes (e2e workflow left as-is, no conflict with CI: run typecheck, lint & Vitest suites on pull requests #33).Vitest-vs-Jest behavioral fixes (minimal, no tests deleted)
jest.requireActualinside mock factories → async factory +await vi.importActual.require('@/...')/require('../x.ts')inside tests → top-levelimportorawait import(Vitest'srequiredoes not resolve the@alias or.tsextensions the way ts-jest did).pLimit,keyv) must return{ default: ... }.fs/fs/promisesmock factories must expose adefaultkey sostorageService's default imports are intercepted.llm-evaluation-servicethat was overriding the intended factory mock.useFakeTimers({ shouldAdvanceTime: true })so testing-librarywaitForcan make progress.describeis markeddescribe.skip(Vitest errors on suites with no tests; Jest tolerated it).Two pre-existing broken tests marked
.skip(not deleted)Both fail on
mainas well — the unit suites are not run in CI, so the drift went unnoticed. Skipped with explanatory notes rather than deleted or weakened, so they can be fixed separately:llm-coverage-evaluator→ "should use backup judge when one primary judge fails" (stale relative to the currentDEFAULT_JUDGESset).useGitHub→ "should throw an error if branchName is missing" (source returnsnullafter a toast rather than throwing).Test plan
pnpm install— clean.pnpm test— 94 files passed; 1115 passed, 2 skipped.pnpm test:web— 49 files, 596 passed, 1 skipped.pnpm test:cli— 45 files, 519 passed, 1 skipped.pnpm typecheck— passes.pnpm test:cli <path/to/file.test.ts>path filtering still works (used indocs/REGRESSIONS.md).next/servermock and default-export mocks work under Vitest. (aws-sdk-client-mock/sinonare not actually used in any test.)🤖 Generated with Claude Code
https://claude.ai/code/session_01T9z5V7UM3FhqomggQ3XTVG
Generated by Claude Code