Skip to content

test: migrate test suites from Jest to Vitest#46

Merged
nojibe merged 1 commit into
mainfrom
claude/vitest-migration-45
Jul 1, 2026
Merged

test: migrate test suites from Jest to Vitest#46
nojibe merged 1 commit into
mainfrom
claude/vitest-migration-45

Conversation

@nojibe

@nojibe nojibe commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Closes #45

Summary

Migrates both test suites (~94 test files) from Jest to Vitest. The two Jest configs (web via next/jest + jsdom, CLI via ts-jest + node) are replaced by a single vitest.config.ts exposing two projects that mirror the previous split. Playwright e2e is left untouched.

  • web project: jsdom environment, testing-library, ported setup (next/server mock + URLPattern polyfill), covers everything except src/cli/** and src/lib/**.
  • cli project: node environment, covers src/cli/**/*.test.ts and src/lib/**/*.test.ts, v8 coverage → coverage/cli.
  • Both use globals: true and resolve the @/ alias (vite-tsconfig-paths + explicit resolve.alias).

Changes

  • Deps: add vitest, @vitest/coverage-v8, jsdom, @testing-library/jest-dom, vite-tsconfig-paths; remove jest, @jest/globals, @types/jest, jest-environment-jsdom, ts-jest. @testing-library/react kept.
  • Scripts: testvitest run, test:webvitest run --project web, test:clivitest run --project cli, update-snapshotsvitest run --update. --experimental-vm-modules removed. test:e2e unchanged.
  • Config: new vitest.config.ts (two projects + root coverage), vitest.setup.web.ts (ported: vi.mock('next/server'), URLPattern polyfill; dropped the global.jest shim), and vitest.d.ts (/// <reference types="vitest/globals" /> so tsc knows the test globals).
  • Codemod across all test files: jest.*vi.*; jest type helpers → vitest (Mock/Mocked/MockedFunction/MockedClass, SpyInstanceMockInstance); @jest/globalsvitest; @jest-environment docblocks → @vitest-environment.
  • Deleted jest.config.js, jest.config.cli.js, _jest.setup.web.ts, _jest.setup.cli.ts.
  • Updated the pr-check skill 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.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 extensions the way ts-jest did).
  • 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.
  • Removed a duplicate auto-mock of llm-evaluation-service that was overriding the intended factory mock.
  • Fake-timer hook test uses useFakeTimers({ shouldAdvanceTime: true }) so testing-library waitFor can make progress.
  • An empty (all-commented-out) describe is marked describe.skip (Vitest errors on suites with no tests; Jest tolerated it).

Two pre-existing broken tests marked .skip (not deleted)

Both fail on main as 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 current DEFAULT_JUDGES set).
  • useGitHub → "should throw an error if branchName is missing" (source returns null after a toast rather than throwing).

Test plan

  • pnpm install — clean.
  • pnpm test94 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.
  • Verified pnpm test:cli <path/to/file.test.ts> path filtering still works (used in docs/REGRESSIONS.md).
  • Confirmed the next/server mock and default-export mocks work under Vitest. (aws-sdk-client-mock/sinon are not actually used in any test.)

🤖 Generated with Claude Code

https://claude.ai/code/session_01T9z5V7UM3FhqomggQ3XTVG


Generated by Claude Code

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
@railway-app railway-app Bot temporarily deployed to weval / app-pr-46 July 1, 2026 17:00 Destroyed
@railway-app

railway-app Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

🚅 Deployed to the app-pr-46 environment in weval

Service Status Web Updated (UTC)
weval-app ✅ Success (View Logs) Web Jul 1, 2026 at 5:09 pm

@nojibe nojibe changed the title Migrate test suites from Jest to Vitest test: migrate test suites from Jest to Vitest Jul 1, 2026
@nojibe nojibe merged commit 0411e3d into main Jul 1, 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.

Migrate test suites from Jest to Vitest

2 participants