Add end-to-end main() tests for the fj/rg tool-state matrix #172
Labels
No labels
bug
chore
documentation
enhancement
feature
ready
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
david/pi-extensions-and-skills#172
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Add full end-to-end
main()tests inscripts/local-install.test.mjscovering the complete fj(absent/unauthenticated/ok) × rg(absent/present) install flow, including a re-run scenario proving tool-state changes between runs are picked up correctly (no stale filtering).Background
By this point,
scripts/local-install.mjshas:rgAvailable()/detectFjState()detection helpers.preflight()returning{ rgOk, fjState }instead of hard-failing on missingrg/fj.buildPackageFilters()mapping tool state to a settings.json filter shape.dedupeAndRegister()applying that filter to the settings.json package entry.reminder()printing a dynamic summary based ontoolState.Each of the above has unit-level test coverage from its own step. This step adds integration-level coverage: running the full
main()pipeline (preflight → git pull → npm install → dedupe/register with filtering → reminder) end-to-end against the existing PATH-shim test harness, to catch any wiring mistakes between the pieces that unit tests in isolation wouldn't catch (e.g.toolStatenot actually threaded all the way through, or the settings file ending up with the wrong shape after a full run).Depends on: #170 (Wire settings.json filter rewrite into dedupeAndRegister()) and #171 (Make reminder() report dynamic install/skip counts; remove dead fj/rg fail() code) — both must be complete so the full
main()pipeline has all pieces wired together to test end-to-end.Implementation Details
Extend the existing
runMainAndCaptureAbort()test helper inscripts/local-install.test.mjs(or add a sibling helper) to acceptwithRg,withFj,fjAuthFails,fjAuthEmptypassthrough options into its underlyingmakeShimDir()call, alongside the existingpullFails/npmFails/etc. options.Add the following end-to-end tests:
Both fj and rg missing:
main(cwd, { globalSettingsFile })withwithRg: false, withFj: false.aborted === false.stderrcontains both skip messages (rg-skip, fj-skip).rg,pr-comments, andforgejo-cli.globalSettingsJSON has the fully-combined filtered entry (extensions: ["!extensions/pr-comments/src/index.ts", "!extensions/rg/index.ts"],skills: ["!skills/forgejo-cli"]).fj unauthenticated, rg present:
withFj: true(default),fjAuthFails: true(orfjAuthEmpty: true),withRg: true.aborted === false.stderrcontains the unauthenticated warning.globalSettingsentry is the plain string (no filtering).Both fully available (happy path): default shim (no missing-tool flags).
aborted === false, no fj/rg warnings instderr.globalSettingsentry is the plain string.Re-run picks up fj becoming available between runs:
main()call against a freshglobalSettingsfile withwithFj: false→ assert the filtered entry (excluding pr-comments/forgejo-cli).main()call against the sameglobalSettingsfile, now withwithFj: true(default, authenticated) → assert the entry is rewritten back to a plain string (assumingrgis present in both calls) — proving stale filters don't persist across runs.dedupeAndRegistertests from the earlier "Wire settings.json filter rewrite" step — check for overlap before duplicating; if the unit-level test already proves this at thededupeAndRegisterlevel, a lighter-weightmain()-level version (asserting just the settings outcome, not every side-channel) is sufficient here.Regression — existing reminder-text assertion update: The existing test
"direct invocation exits 0 and prints the Step-4 reminder on the happy path"currently asserts the old hardcoded reminder string. Update its assertion to match the new dynamic reminder format for the fully-available case (same meaning — full counts — but new exact wording per thereminder()step). Do NOT duplicate this test; update it in place.Regression — pull-failure test unaffected: Confirm
"direct invocation exits non-zero when git pull fails"still passes unmodified (it fails before tool detection ever runs, since preflight happens beforegit pull— wait, actually preflight runs beforegit pullin the existing step order, so tool detection does run first; just confirm this test's assertions about the pull-failure message are unaffected by the preflight changes, since preflight succeeds in this test's shim setup by default).Acceptance Criteria
runMainAndCaptureAbort()(or a new sibling helper) supportswithRg,withFj,fjAuthFails,fjAuthEmptypassthrough options.main()against the same settings file after fj becomes available removes the previously-applied filter (no stale state).npm test— all green, full suite (unit + end-to-end) passes with no regressions.Test Plan
node --test scripts/local-install.test.mjs -t "<test name>"or equivalent name-filtering, if supported by the Node version in use) to isolate failures.npm testandnode --test scripts/local-install.test.mjs(direct invocation) — both green.docs/INSTALL_SCRIPT_TOOL_DETECTION_PLAN.mdanddocs/INSTALL_SCRIPT_TOOL_DETECTION_TEST_PLAN.md(if still present in the repo) and confirm every scenario listed there has a corresponding automated test — flag any gap found instead of silently leaving it uncovered.pi-loop opened and merged a pull request for this issue: #181