#!/usr/bin/env bash # Tests for hooks/bash-pipeline-guard.sh # # Convention: bash, `set -uo pipefail`, one PASS:/FAIL: per assertion, # FAIL=1 aggregate, ALL_OK on full pass. # # Each test invokes the hook as a subprocess with real JSON on stdin — never # source the hook, so we test its actual stdin/stdout/stderr contract. set -uo pipefail PASS_COUNT=0 FAIL_COUNT=0 FAIL=0 HOOK="$(cd "$(dirname "$0")/.." && pwd)/bash-pipeline-guard.sh" [ -x "$HOOK" ] || { echo "FATAL: hook not found or not executable: $HOOK" >&2 exit 2 } command -v python3 >/dev/null 2>&1 || { echo "FATAL: python3 required to build test JSON" >&2 exit 2 } pass() { printf 'PASS: %s\n' "$1" PASS_COUNT=$((PASS_COUNT + 1)) } fail() { printf 'FAIL: %s\n' "$1" FAIL_COUNT=$((FAIL_COUNT + 1)) FAIL=1 } # Build the JSON envelope the hook expects. json_for_cmd() { python3 -c ' import json, sys print(json.dumps({"tool_input": {"command": sys.argv[1]}})) ' "$1" } # Run the hook with the given stdin payload. Captures stderr to a file (so the # test name stays readable on stdout) and stdout to nothing. run_hook_with_stdin() { local payload="$1" local stderr_file stderr_file="$(mktemp)" printf '%s' "$payload" | "$HOOK" 2>"$stderr_file" >/dev/null HOOK_RC=$? HOOK_STDERR="$(cat "$stderr_file")" rm -f "$stderr_file" } # assert_flag