#!/usr/bin/env bash # scripts/test-check-stale-promote-pr.sh # # Exhaustive bash unit tests for check-stale-promote-pr.sh. # Goal: 100% branch coverage on the detector logic. # # Each case writes a fixture JSON, freezes the clock with NOW_OVERRIDE, # runs the script with --fixture + --no-comment (so we don't try to # actually call `gh pr comment`), and asserts on stdout/exit code. # # Run: bash scripts/test-check-stale-promote-pr.sh # Expected: "All N tests passed" + exit 0. set -euo pipefail SCRIPT="$(cd "$(dirname "$0")" && pwd)/check-stale-promote-pr.sh" TMP="$(mktemp -d)" trap 'rm -rf "$TMP"' EXIT PASS=0 FAIL=0 # ───────────────────────────────────────────────────────────────────────────── # Helpers # ───────────────────────────────────────────────────────────────────────────── # Frozen "now" — 2026-05-06T05:00:00Z. Compute dynamically so the # tests stay correct regardless of platform-specific date semantics # (gnu vs bsd) and any author math errors on the epoch. if FROZEN_NOW="$(date -u -d '2026-05-06T05:00:00Z' +%s 2>/dev/null)"; then : # gnu-date worked elif FROZEN_NOW="$(date -u -j -f '%Y-%m-%dT%H:%M:%SZ' '2026-05-06T05:00:00Z' +%s 2>/dev/null)"; then : # bsd-date worked else echo "FATAL: cannot compute FROZEN_NOW on this platform" >&2 exit 1 fi run_script() { # Args: # Returns stdout + exit code via a known marker. local fixture="$1" shift set +e NOW_OVERRIDE="$FROZEN_NOW" \ POST_COMMENT="false" \ bash "$SCRIPT" --fixture "$fixture" "$@" 2>&1 local rc=$? set -e echo "EXIT_CODE=$rc" } assert_pass() { local name="$1" local got="$2" local want_pattern="$3" if printf '%s' "$got" | grep -qE "$want_pattern"; then PASS=$((PASS + 1)) printf ' ✓ %s\n' "$name" else FAIL=$((FAIL + 1)) printf ' ✗ %s\n want pattern: %s\n got:\n%s\n' "$name" "$want_pattern" "$got" fi } assert_no_match() { local name="$1" local got="$2" local bad_pattern="$3" if printf '%s' "$got" | grep -qE "$bad_pattern"; then FAIL=$((FAIL + 1)) printf ' ✗ %s\n bad pattern matched: %s\n got:\n%s\n' "$name" "$bad_pattern" "$got" else PASS=$((PASS + 1)) printf ' ✓ %s\n' "$name" fi } # ───────────────────────────────────────────────────────────────────────────── # Test cases # ───────────────────────────────────────────────────────────────────────────── echo "1. Empty PR list — clean exit" echo '[]' > "$TMP/empty.json" got=$(run_script "$TMP/empty.json") assert_pass "empty-no-warning" "$got" "No stale auto-promote PRs detected" assert_pass "empty-exit-zero" "$got" "EXIT_CODE=0" echo echo "2. Single PR, BLOCKED+REVIEW_REQUIRED, 5h old — fires alarm" cat > "$TMP/stale1.json" < "$TMP/young.json" < "$TMP/dirty.json" < "$TMP/clean.json" < "$TMP/mixed.json" < "$TMP/two-stale.json" <&1) help_rc=$? set -e assert_pass "help-exits-zero" "EXIT_CODE=$help_rc" "EXIT_CODE=0" assert_pass "help-mentions-issue" "$help_out" "issue #2975" echo echo "10. Unknown arg exits 64 (EX_USAGE)" set +e bad_out=$(bash "$SCRIPT" --bogus 2>&1) bad_rc=$? set -e assert_pass "unknown-arg-rc" "EXIT_CODE=$bad_rc" "EXIT_CODE=64" echo echo "11. Missing repo + missing fixture exits 2" set +e out=$(REPO="" bash "$SCRIPT" 2>&1) rc=$? set -e assert_pass "no-repo-exit-2" "EXIT_CODE=$rc" "EXIT_CODE=2" # ───────────────────────────────────────────────────────────────────────────── # Summary # ───────────────────────────────────────────────────────────────────────────── echo echo "─────────────────────────────────────────────" echo "Tests: $PASS passed, $FAIL failed" if [ "$FAIL" -gt 0 ]; then exit 1 fi echo "All tests passed."