Skip to content

test(FAFF-367): add merge-gate shell control-flow tests#286

Merged
alechill merged 2 commits into
mainfrom
faff-367-merge-gate-add-pure-control-flow-tests-for-check-only-and
Jul 7, 2026
Merged

test(FAFF-367): add merge-gate shell control-flow tests#286
alechill merged 2 commits into
mainfrom
faff-367-merge-gate-add-pure-control-flow-tests-for-check-only-and

Conversation

@alechill

@alechill alechill commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Adds node:test coverage for the impure SHELL control-flow branches of faff merge-gate that mergeGateSelftest (pure cores) and test/merge-gate.test.mjs (arg validation) don't reach — the --check-only short-circuit, the plain-refuse exit, the already-MERGED idempotent no-op, and the FAFF-375 --human-override TTY fence. Test-only: no production change to the merge interlock.

Mechanism: a stub gh executable is prepended to PATH, the real faff merge-gate is driven via runCli with a doctored env, and assertions bind to the CLI seam (exit code / --json stdout / on-disk artifacts) per ADR 0002. A merge sentinel file (touched only on gh pr merge) proves whether an actual merge was attempted; the stub exits non-zero on any unhandled subcommand so a drift in the shell's gh surface fails loudly.

Acceptance Criteria

  • Tests for --check-only (merge-ok floor + refuse floor) and the --human-override fence; all assertions bind to exit code / --json stdout / on-disk artifacts (no narrative asserts).
    Verified: test/merge-gate-controlflow.test.mjs — 7/7 passing (node --test).
  • Runs under node --test with no new dependency and no network.
    Verified: zero deps (node:test/node:child_process/node:fs only); the stub answers all gh calls locally.
  • Stub gh records pr merge via a sentinel; unhandled subcommand exits non-zero.
    Verified: STUB_GH case-dispatch + exit 3 default; execute-on-merge-ok test asserts sentinel PRESENT, check-only tests assert ABSENT.
  • check-only never merges (sentinel absent on both merge-ok and refuse floors); execute-on-merge-ok merges (sentinel present); already-MERGED is an idempotent no-op.
    Verified: cases 1-5 in the test file.
  • FAFF-375 fence: non-TTY --interactive --human-override → exit 2 before any gh call, no override file written.
    Verified: cases 6-7.

Drift note (FAFF-375, PR #285)

FAFF-375 merged ~1h before this build and fences --human-override/--allow-no-ci on process.stdin.isTTY===true AND --interactive, returning exit 2 before any gh call. runCli spawns a non-TTY child, so the spec's original "override recorded + merge falls through" scenario is unreachable from the harness — the fence fires first. Tests assert the current behaviour. Separately, the shipped refuse-return precedes the --check-only short-circuit, so --check-only on a refuse floor returns exit 1 refuse (not a false-green merge-ok) — the code is safer than the spec's test-case prose implied. Tests follow the code.

Closes FAFF-367.

@alechill alechill merged commit ea5dd0f into main Jul 7, 2026
2 checks passed
@alechill alechill deleted the faff-367-merge-gate-add-pure-control-flow-tests-for-check-only-and branch July 7, 2026 14:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant