test(gates): pin hook wiring and enforce the bats TAP plan
The repo's gates were not pinned to their wiring. Deleting the check-skill-version-bump block from .pre-commit-config.yaml left the whole suite green; deleting eight blocks at once, run-tests among them, also left it green. Only 4 of 20 hook ids had their wiring pinned anywhere, so a merge conflict resolved badly could stop the suite running at pre-push forever while every test still reported green. test-adr0020-contract now derives the repo-authored hooks from the repo: local entries and pins each one's id, entry and stages against an explicit expected set, both directions, with the same non-vacuity guards the file already applies to its own fixtures. Upstream hooks and their rev: values are untouched, so a rev bump does not churn the test. Mutation-checked: a removed block, a repointed entry and a hook moved off pre-push each go red; a rev bump, a comment edit and reordering stay green. 29 -> 44 assertions. run-bats computed each file's TAP plan and then discarded it, so a process printing "1..10", three ok lines and exit 0 was counted as "3 tests, 0 failures" with seven tests silently gone. That is exactly the wrapper-swallows-the-status case the runner's own comment puts in its threat model, and the plan was the only surviving signal. The plan is now enforced in both directions when a file emits exactly one. Also: test-no-pipefail-early-exit-grep's live-tree floor goes from 20 to 50 against an actual 57, matching test-vale-wrap's per-glob discipline, and test-vale-wrap's header names the real path to vale-wrap.sh. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NwD8Egs5r4ndqeFLmhusX2
This commit is contained in:
@@ -444,6 +444,38 @@ else
|
||||
pass "a root under .claude/worktrees/ runs its own files and skips nested worktrees"
|
||||
fi
|
||||
|
||||
# --- 11. A file that emits fewer results than its own plan promised fails the
|
||||
# run. This is the third aggregation signal, and the only one left standing in
|
||||
# exactly the case run-bats.sh's own comment puts in its threat model: a bats
|
||||
# formatter or wrapper that swallows the exit status. A process printing `1..10`,
|
||||
# three `ok` lines and exiting 0 emits no `not ok` and no non-zero status, so both
|
||||
# other halves stay silent -- the plan was already being computed for the
|
||||
# aggregate zero-count guard and was then thrown away, so the run was counted as
|
||||
# "6 tests, 0 failures" and went green with fourteen tests silently gone.
|
||||
echo ""
|
||||
echo "--- a file emitting fewer results than its plan fails the run ---"
|
||||
DIR11="$(make_fake_repo)"
|
||||
FIXTURES+=("$DIR11")
|
||||
seed_bats_files "$DIR11"
|
||||
install_stub_bats "$DIR11" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
echo "1..10"
|
||||
echo "ok 1 first"
|
||||
echo "ok 2 second"
|
||||
echo "ok 3 third"
|
||||
exit 0
|
||||
EOF
|
||||
run_fake "$DIR11"
|
||||
if [[ $FAKE_RC -eq 0 ]]; then
|
||||
fail "a file delivering 3 of its 10 planned tests exited 0 — a truncated run reported as a pass"
|
||||
elif ! grep -q "planned 10 test(s) but emitted 3 result line(s)" <<< "$FAKE_OUT"; then
|
||||
fail "the run failed but not with the plan-shortfall message: $FAKE_OUT"
|
||||
elif grep -q "^6 tests, 0 failures$" <<< "$FAKE_OUT"; then
|
||||
pass "a plan promising more tests than were delivered fails the run and names the shortfall"
|
||||
else
|
||||
fail "the plan-shortfall run failed with the wrong count: $FAKE_OUT"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Results: $PASS passed, $FAIL failed"
|
||||
[[ $FAIL -eq 0 ]]
|
||||
|
||||
Reference in New Issue
Block a user