#!/usr/bin/env bash ASK="${ASK:-$(dirname "$0")/ask}" PASS=0 FAIL=0 RESULTS=() OUTFILE=$(mktemp /tmp/ask_test_out.XXXXXX) ERRFILE=$(mktemp /tmp/ask_test_err.XXXXXX) cleanup() { rm -f "$OUTFILE" "$ERRFILE" rm -f /tmp/ask_test_*.out /tmp/ask_test_*.err /tmp/ask_test_*.tmp /tmp/ask_test_*.tmp2 } err() { echo " FAIL: $*" >&2; ((FAIL++)); } ok() { echo " PASS"; ((PASS++)); } run_test() { local label=$1 expected_exit=$2 shift 2 > "$OUTFILE" > "$ERRFILE" set +e "$ASK" "$@" >"$OUTFILE" 2>"$ERRFILE" local ec=$? set -e if [[ "$ec" -ne "$expected_exit" ]]; then err "$label: expected exit $expected_exit, got $ec" echo " stderr: $(head -c 200 "$ERRFILE" 2>/dev/null)" return 1 fi ok RESULTS+=("$label: PASS") return 0 } check_stdout_not_empty() { local label=$1 if [[ ! -s "$OUTFILE" ]]; then err "$label: stdout is empty" return 1 fi return 0 } check_stdout_contains() { local label=$1 pattern=$2 if ! grep -q "$pattern" "$OUTFILE" 2>/dev/null; then err "$label: stdout missing '$pattern'" echo " stdout: $(head -c 200 "$OUTFILE")" return 1 fi return 0 } check_stderr_contains() { local label=$1 pattern=$2 if ! grep -q "$pattern" "$ERRFILE" 2>/dev/null; then err "$label: stderr missing '$pattern'" echo " stderr: $(head -c 200 "$ERRFILE")" return 1 fi return 0 } check_exit_ok() { local label=$1 if ! run_test "$label" 0 "${@:2}"; then return 1 fi return 0 } echo "=== Test suite: ask CLI ===" echo "" # --- test 1: help output --- echo "1) -h flag prints help" if run_test "1) -h" 0 -h; then check_stdout_contains "1) -h" "Usage: ask" fi # --- test 2: no arguments exits 1 --- echo "2) no arguments exits with error" if run_test "2) no args" 1; then check_stderr_contains "2) no args" "no question" fi # --- test 3: default mode — simple command query --- echo "3) default mode: list files by size" if run_test "3) default" 0 how to list files by size; then check_stdout_not_empty "3) default" fi # --- test 4: default mode — different tool --- echo "4) default mode: kill process by name" if run_test "4) default" 0 how to kill a process by name; then check_stdout_not_empty "4) default" fi # --- test 5: -q flag (general question) --- echo "5) -q mode: explain grep" if run_test "5) -q" 0 -q explain grep; then check_stdout_not_empty "5) -q" fi # --- test 6: -H flag (history query) --- echo "6) -H mode: ask about docker usage" if run_test "6) -H" 0 -H "did I use docker recently"; then check_stdout_not_empty "6) -H" fi # --- test 7: -p flag paginates via less --- echo "7) -p flag paginates via less" # non-interactive: timeout after 2s, less exits 0 on normal, 141 on SIGPIPE, 124 on timeout set +e timeout 2 "$ASK" -p how to find large files >/dev/null 2>&1 ec=$? set -e if [[ "$ec" -eq 0 || "$ec" -eq 141 || "$ec" -eq 124 ]]; then ok RESULTS+=("7) -p paginate: PASS") else err "7) -p: unexpected exit $ec" fi # --- test 8: -q with -p combined --- echo "8) -q -p combined" set +e timeout 2 "$ASK" -q -p "what is awk" >/dev/null 2>&1 ec=$? set -e if [[ "$ec" -eq 0 || "$ec" -eq 141 || "$ec" -eq 124 ]]; then ok RESULTS+=("8) -q -p: PASS") else err "8) -q -p: unexpected exit $ec" fi # --- test 9: query about a less common tool --- echo "9) default mode: monitor disk IO" if run_test "9) default" 0 how to monitor disk IO; then check_stdout_not_empty "9) default" fi # --- test 10: -H with a different question --- echo "10) -H mode: what commands today" if run_test "10) -H" 0 -H "what commands did I run today"; then check_stdout_not_empty "10) -H" fi cleanup echo "" echo "=== Results: $PASS pass, $FAIL fail ===" exit $FAIL