84 lines
2.7 KiB
Bash
Executable file
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
|