Conversation
The Vitest baseExclude contract this issue was filed against is gone: PR #3056 replaced it with structural discovery in packages/cli/run-bun-tests.ts, and all 670 tracked CLI test files are now discovered and run. What was missing is the third resolution the issue asks for — something that makes a future silent exclusion fail loudly. run-bun-tests.ts walks a hardcoded TEST_ROOTS list, so a tracked test file added anywhere else under packages/cli would never run while every existing test still passed. The new guard compares the git-tracked test set against the runner's own discoverTestFiles() and fails, naming the file, when the two disagree or when a path is discovered more than once.
…meout The sorted-output test passed pre-sorted input, so it would still pass if sorting were dropped. It now supplies unsorted input. Node kills a child with SIGTERM for both a timeout and a maxBuffer overflow, so the helper reported runaway output as a timeout and hid the real cause. The overflow is now identified by its error code first, matching the handling in scripts/tests/cli-import-boundary.test.ts.
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 58 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?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 reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. 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, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (4)
Comment |
WalkthroughThis PR changes 5 file(s).
Changes
Magnitude🎯 2 (M) RelatedNo related items found. Walkthrough generated by LLxprt PR Review. Planner issue: #2256 |
OpenCodeReview — PR #3099
|
Code Coverage Summary
CLI Package - Full Text ReportCore Package - Full Text ReportFor detailed HTML reports, please see the 'coverage-reports-24.x-ubuntu-latest' artifact from the main CI run. |
evaluateDiscovery returned as soon as it found duplicates, so a run that had both duplicates and undiscovered files only reported the duplicates. The reader had to fix one, re-run, and only then learn about the other. Both are now computed up front and every violation present is reported together.
TLDR
Issue #2923 was filed against a Vitest exclude contract that no longer exists. PR #3056 (Fixes #2843) deleted
packages/cli/vitest.config.ts,vitest.test-groups.ts,baseExcludeandSELECTED_FILE_COUNT, replacing them with structural discovery inpackages/cli/run-bun-tests.ts. Measured onmain: all 670 tracked CLI test files are discovered and run — zero excluded, and the issue's own repro file passes.So resolutions 1 and 2 of the issue are already satisfied. What was still missing is resolution 3: a guard that makes a future silent exclusion fail loudly. That is what this PR adds.
The hole being closed:
run-bun-tests.tswalks a hardcodedTEST_ROOTS = ['src', 'test', 'test-bun', 'test-utils']. A tracked test file added anywhere else underpackages/cli—scripts/,bin/, the workspace root, a brand-new directory — would never run, and every existing test would still pass.packages/cli/scripts/andpackages/cli/bin/already exist, so this is reachable, not hypothetical.Reviewers should look closely at: the deliberate duplication of the test-file regex (justified below), and
evaluateDiscovery(), which holds the guard's entire decision so both halves of the contract are covered by tests of real decision-making.Dive Deeper
Measured ground truth on
main(42ca2a9)git ls-files packages/climatching.(test|spec|bun).(ts|tsx)discoverTestFiles()fromrun-bun-tests.tsbun test ./src/ui/components/ModelConfigDialog.test.tsxsrc/ui/components/*.test.tsx, one process per filedescribe.skip/it.skip/test.skipTEST_ROOTSCI path confirmed:
npm run test:ci --workspaces->packages/cli->bun run-bun-tests.ts. The runner measured is the runner CI uses.What the guard does
scripts/check-cli-test-discovery.tscompares two independently-derived sets and fails when they disagree:git ls-filesinpackages/cli, classified by the guard's own pattern constant.discoverTestFiles()imported fromrun-bun-tests.ts— not a copy.It fails on either half of the contract: a tracked test file that is not discovered, or a path discovered more than once.
Why the regex is deliberately duplicated
Importing the runner's
TEST_FILE_PATTERNwould let both sides of the comparison shrink together. If someone narrowed the runner to drop.bun, the candidate set and the discovered set would both lose those files and the guard would pass while eleven suites stopped running. Duplicating keeps the sides independent. The DRY cost is one small regex; the test atpattern independence (AC4) > detects drift...is the lock that flips to failing if the runner narrows.Design note
evaluateDiscovery()returns a verdict plus the exact text to print, andmain()is a thin shell over it (gather inputs, print, exit). This exists so the "exactly once" half is covered by a test of the program's real decision rather than of a helper the program might not consult. A duplicate cannot be produced through the real runner — eachTEST_ROOTSentry is walked once and directories are de-duplicated by real path — so the decision function is the deepest level at which that half can be exercised.Deliberately out of scope
TEST_ROOTSor any discovery behaviour. The guard makes the gap loud; widening discovery is a separate decision.git ls-filesis strictly stronger than theSELECTED_FILE_COUNTinteger the issue names, and does not generate churn on every added test.packages/cli/test/ui/commands/authCommand-logout.test.tsgates all four suites onprocess.env.CI === 'true'. Measured: 0 pass / 21 skip underCI=true, 21 pass underCI=false. It is discovered and invoked — the runner and this guard both do their job — but it asserts nothing on CI. That is an explicit, greppable skip rather than the silent structural exclusion this issue is about, and unpicking an OAuth logout suite is a different subsystem. Documented in the plan; worth its own issue.Review findings triage
evaluateDiscovery().--rot /tmp/xwould run against the real repo and report a misleading PASS. Now fails fast.scripts/tests/cli-import-boundary.test.ts.import.meta.main. Verified against the codebase: 8 siblingscripts/check-*.tsguards use theprocess.argv[1]comparison and zero useimport.meta.main. Adopting it would make this guard the odd one out.Reviewer Test Plan
Confirm the guard passes today:
Confirm it actually catches a silently-unrun file — plant one where the runner cannot reach it:
Expected: exit 1, naming
scripts/rogue.test.tsand pointing atTEST_ROOTS— never at an exclude list. Then clean up:Run the guard's own suite:
Verify the issue's original claim is resolved:
Testing Matrix
Verified locally on macOS:
npm run lint(exit 0),npm run typecheck(0 errors),npm run build(exit 0),npm run test:scripts(PASSED),npm run lint:eslint-guard(passed), prettier clean, and the CLI smoke test viabun scripts/start.ts --profile-load stepfun-37. The guard's own suite: 24 pass / 0 fail. Paths are normalised to POSIX so behaviour is identical on Windows; the CI lint job itself runs on Ubuntu.Linked issues / bugs
Fixes #2923