chore(deps): upgrade Vitest 3.x to 4.x (#458)#461
Conversation
Bump vitest and @vitest/coverage-v8 to ^4.1.8 (latest release older than the
repo's 7-day minimumReleaseAge gate). Vitest 4 requires Vite >= 6, which was
only an auto-installed peer pinned at v5; declare vite (^7.3.5) in the catalog
and as a direct devDependency in each vitest package so it resolves to 7.x
deterministically, with no peer warnings.
Preserve whole-src coverage measurement: Vitest 4's v8 provider drops
coverage.all and only counts imported files unless coverage.include is set. Add
a shared coverageInclude to @acme/vitest-config and apply it to me/api/map (plus
literal includes in packages storage/api). auth keeps its narrow phone.ts scope.
Re-ratchet thresholds to the honest whole-src baseline. Vitest 4's AST-aware v8
remapping counts branches/functions more granularly, lowering those numbers;
autoUpdate only raises, so me's branch/function thresholds and map's static
branch/function floors are lowered manually to match the v4 baseline.
Fix a Vitest 4 mock regression: vi.fn().mockImplementation(() => ({...})) used
with `new` throws "is not a constructor" (arrow functions have no [[Construct]]).
Convert the MemoryRatelimiter mock to a function form across 19 test files.
Also bumps the packageManager pin to pnpm@11.7.0.
Verified: all 7 test tasks pass, coverage idempotent across two runs, and
lint/typecheck/prettier clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Warning Review limit reached
More reviews will be available in 43 minutes and 35 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (8)
📝 WalkthroughWalkthroughUpgrades Vitest from v3 to v4 across the monorepo: bumps ChangesVitest 4 Upgrade
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related issues
Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
packages/api and packages/storage set coverage.include to "src/**/*.ts",
which does not match .tsx. packages/api/src/get-sorting-columns.tsx was
therefore silently dropped from the coverage denominator under Vitest 4
(harmless to CI since the package has no thresholds, but the measurement
was incomplete and inconsistent with the apps' shared coverageInclude).
Widen both packages to "src/**/*.{ts,tsx}" so whole-src coverage matches
@acme/vitest-config's coverageInclude.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
mcmxcdev
left a comment
There was a problem hiding this comment.
Went through changes manually, looks great!
I see some potential to have a base vitest config that other configs extend from but that's out of scope.
I don't know what that means! But I like it. |
Recently published dependenciesFound 1 package published in the last 3 days:
Publish-time check healthAll package publish-time checks completed successfully. |
|
@mcmxcdev agreed a shared base vitest config that apps extend from would be a nice cleanup — capturing it as a follow-up rather than expanding scope on this upgrade PR. Thanks for the review! |
Move the Vitest 4 coverage rationale out of the per-app vitest.config.ts files (whose hand-written comment blocks varied per file and hardcoded threshold percentages prone to rot) into a canonical docs/testing.md, linked from AGENTS.md. Configs are now declarative; the shared globs keep their JSDoc in tooling/vitest/coverage.ts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Closes #458
👋 TL;DR
Upgrade the monorepo from Vitest 3.2.6 → 4.1.8 (with
@vitest/coverage-v8to match), force a compatible Vite (≥6), preserve whole-srccoverage measurement, and fix a Vitest 4 mock regression across the API tests.🔎 Details
Version bumps
vitest+@vitest/coverage-v8→^4.1.8(latest release older than the repo's 7-dayminimumReleaseAgegate;4.1.9is too new).packageManagerpin →pnpm@11.7.0.Vite ≥6 gate (the real work)
Vitest 4 requires Vite ≥6, but Vite was only an auto-installed peer pinned at 5.4.21, and pnpm
overrideswouldn't dislodge it on an incremental install. Declaredvite(^7.3.5) in the catalog and as a directdevDependencyin each vitest package, so it resolves to 7.3.5 everywhere with no peer warnings. The lockfile diff is kept scoped to the vite/vitest closure (a from-scratch regen would have floated 100+ unrelated transitive deps).Whole-
srccoverageVitest 4's v8 provider drops
coverage.all/coverage.extensionsand only measures files a test imported unlesscoverage.includeis set. Added a sharedcoverageInclude = ["src/**/*.{ts,tsx}"]to@acme/vitest-configand applied it tome/api/map(plus literalsrc/**/*.tsincludes inpackages/storageandpackages/api).authkeeps its intentional narrowphone.tsscope.Threshold re-ratchet to the honest baseline
Vitest 4's AST-aware v8 remapping counts branches/functions more granularly, so whole-
srcbranch/function coverage measures lower than under v3.autoUpdateonly ratchets up, so a couple of values were lowered manually:f3-mef3-mapf3-apif3-authVitest 4 mock regression fix
vi.fn().mockImplementation(() => ({ ... }))used withnewnow throws"is not a constructor"(arrow functions have no[[Construct]]). Converted theMemoryRatelimitermock to afunctionform across 19@acme/apitest files (the Vitest 4 docs' recommended pattern).✅ How to Test
CI runs the full suite, lint, typecheck, and coverage gates. Locally (with Docker Postgres up +
pnpm reset-test-db):pnpm install— clean under strict catalog;pnpm why vitest→ 4.1.8,pnpm why vite→ 7.3.5, no peer warnings.pnpm test— all 7 test tasks pass (@acme/storage,f3-me,f3-auth,f3-api,f3-map,@acme/api= 22 files / 397 tests).autoUpdatedrift / idempotent).pnpm typecheck(22 ✓),pnpm lint(21 ✓),prettier --checkon changed files ✓.References
🤖 Generated with Claude Code
Summary by CodeRabbit
Chores
Tests