Skip to content

refactor(test): migrate the unit suite from Jest 30 to Vitest 4 - #859

Merged
github-actions[bot] merged 1 commit into
mainfrom
refactor/vitest
Aug 31, 2026
Merged

refactor(test): migrate the unit suite from Jest 30 to Vitest 4#859
github-actions[bot] merged 1 commit into
mainfrom
refactor/vitest

Conversation

@catomean

Copy link
Copy Markdown
Collaborator

Summary

Replaces Jest 30 (+ ts-jest) with Vitest 4 for the whole unit/smoke suite. Full parity: 282 test files / 2645 tests, green before and after — same coverage ratchet, same CI entry points (npm run verifytest:unit, test:ci).

What changed

  • vitest.config.ts — mirrors the old moduleNameMapper as ordered resolve.alias entries (specific @/... mocks before the @/ catch-all); jsdom env, globals, 30s timeout, v8 coverage with the identical threshold ratchet.
  • vitest.setup.ts (ports jest.setup.ts) — same polyfills/mocks; lucide-react is now a vi.mock Proxy, so ANY icon name resolves. The old hand-written allowlist meant every unlisted icon rendered undefined and crashed as "Element type is invalid" — an error class this deletes outright (it was aliased as a CJS Proxy first, which surfaces no named exports; the factory form is the one that works).
  • Tests — mechanical jest.*vi.* codemod plus the real behavioral deltas:
    • constructor mocks use function expressions (vitest constructs implementations with new; arrows aren't constructable),
    • vi.mock factories returning a bare component now return { default: ... },
    • one TDZ factory moved under vi.hoisted, one require()await import(),
    • @jest-environment pragmas → @vitest-environment,
    • jest.isolateModulesAsync dropped in the auth smoke test (per-test resetModules + doMock covers it),
    • snapshot rewritten in Vitest format — content byte-identical.
  • Scripts--testPathPatterns regexes become Vitest positional path filters; verify loses the dead --watchAll flag; test:watch is plain vitest.
  • Deletedjest.config.js, jest.setup.ts, __mocks__/vitest.js (the old vitest→jest shim, now inverted into real globals), tsconfig.test.json, tests/jest-dom.d.ts, unimported jest-era tests/utils.ts, and the mcp:jest script; uninstalled jest, ts-jest, jest-environment-jsdom, @types/jest.

Verification

  • npx vitest run: 282 files / 2645 tests passed (matches the Jest baseline exactly).
  • npm run type-check: clean. npm run lint: 0 errors.
  • Pre-push gate (type-check + unit tests) passed on push.

Note: mcp-servers/jest-server.js (optional local MCP helper) still shells out to a jest binary and is now inert; left in place, flagged for a follow-up.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WqKqMnHQHSmkGFfc5t7Rxn

Full parity: 282 test files / 2645 tests green before and after.

- vitest.config.ts mirrors the old moduleNameMapper as ordered resolve.alias
  entries; jsdom env, globals, 30s timeout, v8 coverage with the same ratchet.
- vitest.setup.ts ports jest.setup.ts; lucide-react is now a vi.mock Proxy
  (any icon resolves — the old CJS-alias Proxy surfaced no named exports and
  every unlisted icon crashed renders as "Element type is invalid").
- Codemod jest.* -> vi.* across tests; @jest-environment -> @vitest-environment.
- Constructor mocks use function expressions (vitest news the implementation;
  arrows are not constructable).
- Factories returning a bare component now return { default: ... };
  one TDZ factory moved under vi.hoisted; one require() -> await import().
- jest.isolateModulesAsync dropped in the auth smoke test (resetModules +
  doMock per test covers it).
- Scripts ported (positional path filters replace --testPathPatterns);
  verify's --watchAll flag removed; ci.yml comment updated.
- Deleted jest.config.js, jest.setup.ts, __mocks__/vitest.js,
  tsconfig.test.json, tests/jest-dom.d.ts, and the unimported jest-era
  tests/utils.ts; uninstalled jest, ts-jest, jest-environment-jsdom,
  @types/jest; dropped the dead mcp:jest script.
- Snapshot file rewritten in Vitest format (content byte-identical).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WqKqMnHQHSmkGFfc5t7Rxn
*/

import { redirect } from 'next/navigation'
import { redirect } from 'next/navigation';
@github-actions
github-actions Bot merged commit bae4be1 into main Aug 31, 2026
6 checks passed
@github-actions
github-actions Bot deleted the refactor/vitest branch August 31, 2026 16:14
github-actions Bot pushed a commit that referenced this pull request Sep 1, 2026
PR #859 migrated the suite to Vitest and deleted jest; the optional local
MCP helper still shelled out to a jest binary that is no longer installed —
inert since the cutover, flagged in that PR as follow-up. Ported:
vitest-server.js (vitest_run / vitest_file; --update for snapshots, filter
as positional, --ci dropped — vitest run is non-interactive), setup.md, and
the shell helper's allowlist. jest-server.js deleted. The two touched CJS
scripts gain a justified no-require-imports disable: mcp-servers/ is plain
CommonJS node with its own package.json, and lint-staged applies the app's
TS rules there.


Claude-Session: https://claude.ai/code/session_01WqKqMnHQHSmkGFfc5t7Rxn

Co-authored-by: Georgy Butaev <41178744+g-but@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.

2 participants