session-tools/tests/run-tests.sh
Natalie 4a5b2f7273 feat(@scripts/session-tools): add rvoice dictation tool
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-05-17 17:54:08 -07:00

84 lines
2.7 KiB
Bash
Executable file

#!/bin/sh
# tests/run-tests.sh — lightweight test runner for session-tools.
#
# Each test file (tests/test_*.sh) defines one or more functions starting
# with `test_`. The runner sources every file, finds those functions, and
# invokes them with PS4 trace + per-test pass/fail tally. Exits non-zero on
# any failure.
#
# Conventions:
# - Use the `assert_eq <expected> <actual> [msg]` helper.
# - Tests should be isolated: each function builds its own fixtures.
# - Tests must not require network or sudo.
set -u
ROOT=$(cd "$(dirname "$0")/.." && pwd)
TESTS_DIR=$ROOT/tests
pass=0; fail=0; failed_names=""
# ---------------------------------------------------------------------------
# Assertion helpers (available to every test file)
# ---------------------------------------------------------------------------
assert_eq() {
_exp=$1; _got=$2; _msg=${3:-}
if [ "$_exp" = "$_got" ]; then return 0; fi
printf ' ✗ assertion failed%s\n expected: %s\n actual: %s\n' \
"${_msg:+: $_msg}" "$_exp" "$_got" >&2
return 1
}
assert_contains() {
_hay=$1; _needle=$2; _msg=${3:-}
case $_hay in
*"$_needle"*) return 0 ;;
esac
printf ' ✗ assertion failed%s\n haystack: %s\n missing: %s\n' \
"${_msg:+: $_msg}" "$_hay" "$_needle" >&2
return 1
}
assert_exit() {
_exp=$1; shift
"$@" >/dev/null 2>&1
_got=$?
if [ "$_exp" -eq "$_got" ]; then return 0; fi
printf ' ✗ exit assertion failed\n expected: %s\n actual: %s\n cmd: %s\n' \
"$_exp" "$_got" "$*" >&2
return 1
}
# ---------------------------------------------------------------------------
# Runner
# ---------------------------------------------------------------------------
for tf in "$TESTS_DIR"/test_*.sh; do
[ -f "$tf" ] || continue
printf '\n── %s\n' "$(basename "$tf")"
# shellcheck disable=SC1090
. "$tf"
# Find every `test_*` function defined by this file. POSIX has no
# introspection, but the loaded source declared them; we grep the file
# for `test_<name>()`.
for name in $(grep -oE '^test_[A-Za-z0-9_]+\b' "$tf" | sort -u); do
# Skip if grep matched a comment.
if ! type "$name" >/dev/null 2>&1; then continue; fi
if ( set -e; "$name" ); then
printf ' ✓ %s\n' "$name"
pass=$((pass + 1))
else
failed_names="$failed_names $name"
fail=$((fail + 1))
fi
# Unset so the next file's same-named test (if any) reloads cleanly.
unset -f "$name" 2>/dev/null || true
done
done
printf '\n────────────────\n %d passed, %d failed\n' "$pass" "$fail"
if [ "$fail" -gt 0 ]; then
printf ' failed:%s\n' "$failed_names"
exit 1
fi