Decision
Two test runners, by workspace type:
| Workspace type |
Runner |
Rationale |
checkin-app/ (the Next.js app) |
Jest |
Already in place; jsdom + RTL + ts-jest + next integration. No reason to migrate working suites. |
packages/*, *-function (incoming from Inventory) |
Vitest |
The Inventory code ships ~30 Vitest suites, vitest configs (incl. a custom resolve-js-to-ts ESM resolver), @vitest/coverage-v8, and testcontainers integration tests. Porting to Jest is large, error-prone, and buys nothing. |
This resolves deferred-risk #5 in #214 (Jest vs Vitest). It is prep work — it lands the runner split before any Inventory function/package is moved, so the eventual move PR does not also introduce a cold second runner.
Why not unify on one runner
- Port Vitest→Jest: ~30 suites + the
.js-specifier-on-.ts ESM resolver + coverage config rewritten. High effort, high regression risk, zero behavior gain.
- Port Jest→Vitest (the app): churns a large, working, jsdom/RTL/next suite for cosmetic uniformity. Not worth it now.
- A clean per-workspace-type boundary is unambiguous: a workspace is either the app (Jest) or a library/function (Vitest). No file ever runs under both.
Scope
-
Runner boundary
- Keep
checkin-app/ on Jest unchanged.
- Adopt Vitest as the standard for every
packages/* and *-function workspace.
- Each such workspace owns its
vitest.config.ts + vitest devDep (mirrors Inventory — no shared root config required).
-
Root scripts (workspace-aware)
test → app suite (Jest) — unchanged default.
test:packages → vitest run across packages/*.
test:functions → vitest run across *-function (no-op until functions land).
test:all → app + packages + functions.
-
Jest isolation
- Confirm
checkin-app/jest.config.js roots/testPathIgnorePatterns never pick up packages/* or *-function (note the worktree-rootDir ignore-pattern quirk: memory/jest-worktree-ignore.md). A stray Vitest .test.ts must not be swept into the Jest run.
-
Docker-in-CI for integration tests
@inventory/pg-test-harness uses @testcontainers/postgresql — integration suites spin an ephemeral Postgres and need a Docker daemon on the CI runner.
- Add the Docker-enabled integration lane now (even if it runs zero suites until packages land), so the move doesn't simultaneously debug CI Docker availability.
-
CI wiring
Non-goals
- No migration of any existing suite between runners.
- No moving of Inventory code (that is the later merge).
- No coverage-threshold policy changes (carried per-workspace from Inventory).
Acceptance criteria
Dependencies / sequence
Decision
Two test runners, by workspace type:
checkin-app/(the Next.js app)packages/*,*-function(incoming from Inventory)resolve-js-to-tsESM resolver),@vitest/coverage-v8, and testcontainers integration tests. Porting to Jest is large, error-prone, and buys nothing.This resolves deferred-risk #5 in #214 (Jest vs Vitest). It is prep work — it lands the runner split before any Inventory function/package is moved, so the eventual move PR does not also introduce a cold second runner.
Why not unify on one runner
.js-specifier-on-.tsESM resolver + coverage config rewritten. High effort, high regression risk, zero behavior gain.Scope
Runner boundary
checkin-app/on Jest unchanged.packages/*and*-functionworkspace.vitest.config.ts+vitestdevDep (mirrors Inventory — no shared root config required).Root scripts (workspace-aware)
test→ app suite (Jest) — unchanged default.test:packages→vitest runacrosspackages/*.test:functions→vitest runacross*-function(no-op until functions land).test:all→ app + packages + functions.Jest isolation
checkin-app/jest.config.jsroots/testPathIgnorePatternsnever pick uppackages/*or*-function(note the worktree-rootDir ignore-pattern quirk:memory/jest-worktree-ignore.md). A stray Vitest.test.tsmust not be swept into the Jest run.Docker-in-CI for integration tests
@inventory/pg-test-harnessuses@testcontainers/postgresql— integration suites spin an ephemeral Postgres and need a Docker daemon on the CI runner.CI wiring
packages/*(and*-functionlater), path-filtered so unrelated changes don't trigger them.Non-goals
Acceptance criteria
packages/*+*-function; Jest stays the app standard. Recorded in repo docs (CONTRIBUTING / monorepo README).test,test:packages,test:functions,test:allexist and behave as above (vitest lanes no-op cleanly with zero workspaces present).checkin-appJest run provably ignorespackages/*and*-function.Dependencies / sequence