test(uncheck): rewrite the tests as e2e suites with 100% coverage - #19
Conversation
commit: |
There was a problem hiding this comment.
ℹ️ No critical issues — the e2e rewrite is thorough and its assertions are exact; two of the source cleanups are not strictly behavior-preserving.
Reviewed changes
- E2e test rewrite — replaces the in-process unit tests with spawned-CLI suites, one folder per command (
uncheck,staged,prepare,hooks install,hooks run), each run in both a single repo and a pnpm monorepo. - Shared harness —
tests/utils/project.tsbuilds real temp projects with real git and real tools;tests/utils/register.tsloadssrc/bin.tsvia Node'sregisterHooks; the environment is pinned and refuses to start if a project marker leaks in from aboveTMPDIR. - Subprocess coverage —
vitest.config.tsaddsautoAttachSubprocessand a globalthresholds: { 100: true }; collection rides onNODE_V8_COVERAGE, whichenvironment()preserves. - Source cleanups —
tsc.tscase handling,errors.tsplatformMessage,tool.tsargvBatches/MAX_ARGV_LENGTH,staged.tsgitEach,hooks/run.tssummary extraction andprepare.tsdestructuring all drop fallbacks described as unreachable. - Old unit tests removed —
command.test.ts,files.test.ts,fixture.ts,tool.test.ts,tsc.test.ts.
ℹ️ New tests pin three known path-resolution bugs as intended behavior
The PR notes that three path-resolution bugs are now pinned by the suite "as if intended": paths above the working directory rejected by oxlint/oxfmt, !pattern exclusions always going through the glob matcher, and a symlinked folder inside git being checked twice. Encoding today's output as the expected value is reasonable for a regression baseline, but it does mean the follow-up fix will have to churn these tests rather than confirm a behavior they never asserted. Worth a tracking issue now so the follow-up is not deferred indefinitely.
Technical details
# Pinned bugs
## Affected sites
- `packages/uncheck/tests/uncheck/paths-exclusions.test.ts` — `!` exclusions and glob-like names pinned as-is.
- `packages/uncheck/tests/uncheck/paths-*.test.ts` — above-cwd and symlink cases.
- `packages/uncheck/src/files.ts` — `resolvePaths` / `existingFiles`, the likely fix site.
## Open questions for the human
- Are these three follow-ups already tracked, or should a tracking issue be opened so the now-pinned expectations get revisited?DeepSeek Flash (default — pick a model for stronger reviews) | 𝕏
…achine-independent Include patterns now match the way tsc does on case-sensitive and case-insensitive file systems alike, so a Node_Modules folder or a .Min.js file tsc checks on Linux still selects its project. The e2e harness drops GITHUB_ACTIONS, under which oxlint prints annotations instead of its report, and two assertions no longer depend on the git or Node version.
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes — the delta since Pullfrog review 5374082387 (3d94946..401457d):
- Fixed tsc include case handling —
compileGlobnow returns a matcher that unions a case-sensitive and a case-folded include regex, so it is a true superset oftscon either filesystem kind whileexcludekeeps case. - Pinned the fix with a regression test —
tsc-patternscovers case-variantnode_modules/.min.js; I confirmed it fails against the pre-fix always-iinclude regex. - Made two assertions machine-independent — the prepare EISDIR expectation tolerates Node 26's appended path, and the staged
index.lockexpectation checks the first error line so git's trailing advice no longer matters. - Stabilized oxlint under Actions — the harness environment now strips
GITHUB_ACTIONS, so oxlint prints its normal report instead of GitHub annotations.
Both relaxed assertions still pin their specific failure (they are toContain/replace of the exact message, not truthiness), and all three affected tests pass in this Actions environment on Node 24.
DeepSeek Flash (default — pick a model for stronger reviews) | 𝕏
…rocesses oxlint and oxfmt change their output for the AI agents they detect, which made two assertions pass inside an agent and fail on CI. The harness now builds the whole environment of the processes it starts instead of filtering the machine's one.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
ℹ️ No critical issues — one minor test-assertion suggestion inline.
Reviewed changes — the delta since Pullfrog review 5374168756 (401457d..f480c19):
- Fixed the spawned processes' environment —
environment()now builds every child's environment from a strict allowlist (HOME,TMPDIR,NODE_V8_COVERAGE) instead of filtering the machine's variables, so tools can no longer seeCLAUDECODE/CI and switch to a different output format. - Reworked two oxlint assertions —
paths-gitandpathsnow match oxlint's default reporter marker (,-[<file>:<line>:<col>]) in place of the agent format the old assertions were written against.
The allowlist is the right shape and the suite (including the pseudo-terminal tests) passes on Node 24; the suggestion is on the new assertions themselves.
DeepSeek Flash (default — pick a model for stronger reviews) | 𝕏

Replaces the in-process unit tests with end-to-end tests that spawn the real CLI in real projects, one folder per command (
uncheck,staged,prepare,hooks install,hooks run). Every behavior runs in both a single repo and a pnpm monorepo. Together the suites cover 100% of statements, branches, functions and lines ofpackages/uncheck/src, and CI now enforces that threshold.Tests
node_modules) and runs the CLI from source as a subprocess. Subprocess coverage is collected with vitest'sautoAttachSubprocess.git commitruns through the hookpreparewritesNODE_OPTIONSis dropped. Git cannot find a repository above the test folders, and the harness refuses to start if apackage.json,node_modulesor lockfile sits above the temp dir.pnpm run test:coveragetakes about 4 minutes on 8 CPUs.Source changes
?? ''after a filter that always matches, a redundantArray.isArraycheck, and aninstanceof Errorcheck on errors that always carry one.git resetcan never run.Notes for reviewers
!patternexclusions always go through the glob matcher