164 lines
4.0 KiB
Bash
164 lines
4.0 KiB
Bash
#!/usr/bin/env bash
|
|
# Minimal test framework. Source this file; do not execute it directly.
|
|
#
|
|
# Globals maintained per-process:
|
|
# _PASS — count of passing assertions
|
|
# _FAIL — count of failing assertions
|
|
|
|
_PASS=0
|
|
_FAIL=0
|
|
|
|
# Color codes (self-contained; do not rely on colors.sh)
|
|
_R='\033[0;31m' # red
|
|
_G='\033[0;32m' # green
|
|
_Y='\033[1;33m' # yellow
|
|
_B='\033[1m' # bold
|
|
_D='\033[2m' # dim
|
|
_N='\033[0m' # reset
|
|
|
|
# suite <name>
|
|
# Print a section header for a group of related tests.
|
|
suite() {
|
|
printf "\n${_B}%s${_N}\n" "$1"
|
|
}
|
|
|
|
# pass / fail — low-level counters; prefer assert_* helpers instead
|
|
pass() {
|
|
_PASS=$((_PASS + 1))
|
|
printf " ${_G}✓${_N} %s\n" "$1"
|
|
}
|
|
|
|
fail() {
|
|
_FAIL=$((_FAIL + 1))
|
|
printf " ${_R}✗${_N} %s\n" "$1"
|
|
[[ -n "${2:-}" ]] && printf " expected: %s\n" "$2"
|
|
[[ -n "${3:-}" ]] && printf " got: %s\n" "${3:-<empty>}"
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Assertion helpers
|
|
# ---------------------------------------------------------------------------
|
|
|
|
assert_eq() {
|
|
local expected="$1" actual="$2" msg="${3:-assert_eq}"
|
|
if [[ "$expected" == "$actual" ]]; then
|
|
pass "$msg"
|
|
else
|
|
fail "$msg" "$expected" "$actual"
|
|
fi
|
|
}
|
|
|
|
assert_not_eq() {
|
|
local unexpected="$1" actual="$2" msg="${3:-assert_not_eq}"
|
|
if [[ "$unexpected" != "$actual" ]]; then
|
|
pass "$msg"
|
|
else
|
|
fail "$msg (expected values to differ)" "$unexpected" "$actual"
|
|
fi
|
|
}
|
|
|
|
assert_empty() {
|
|
local actual="$1" msg="${2:-assert_empty}"
|
|
if [[ -z "$actual" ]]; then
|
|
pass "$msg"
|
|
else
|
|
fail "$msg (expected empty)" "" "$actual"
|
|
fi
|
|
}
|
|
|
|
assert_not_empty() {
|
|
local actual="$1" msg="${2:-assert_not_empty}"
|
|
if [[ -n "$actual" ]]; then
|
|
pass "$msg"
|
|
else
|
|
fail "$msg (expected non-empty)"
|
|
fi
|
|
}
|
|
|
|
assert_contains() {
|
|
local needle="$1" haystack="$2" msg="${3:-assert_contains}"
|
|
if [[ "$haystack" == *"$needle"* ]]; then
|
|
pass "$msg"
|
|
else
|
|
fail "$msg" "*${needle}*" "$haystack"
|
|
fi
|
|
}
|
|
|
|
# assert_success <msg> <cmd> [args...]
|
|
# Passes when the command exits 0.
|
|
assert_success() {
|
|
local msg="$1"; shift
|
|
local rc=0
|
|
"$@" 2>/dev/null || rc=$?
|
|
if [[ $rc -eq 0 ]]; then
|
|
pass "$msg"
|
|
else
|
|
fail "$msg (expected exit 0, got $rc)"
|
|
fi
|
|
}
|
|
|
|
# assert_failure <msg> <cmd> [args...]
|
|
# Passes when the command exits non-zero.
|
|
assert_failure() {
|
|
local msg="$1"; shift
|
|
local rc=0
|
|
"$@" 2>/dev/null || rc=$?
|
|
if [[ $rc -ne 0 ]]; then
|
|
pass "$msg"
|
|
else
|
|
fail "$msg (expected non-zero exit)"
|
|
fi
|
|
}
|
|
|
|
assert_file_exists() {
|
|
local file="$1" msg="${2:-assert_file_exists}"
|
|
if [[ -f "$file" ]]; then
|
|
pass "$msg"
|
|
else
|
|
fail "$msg" "<file: $file>" "(not found)"
|
|
fi
|
|
}
|
|
|
|
assert_file_contains() {
|
|
local pattern="$1" file="$2" msg="${3:-assert_file_contains}"
|
|
if [[ ! -f "$file" ]]; then
|
|
fail "$msg (file not found: $file)"
|
|
return
|
|
fi
|
|
if grep -qF "$pattern" "$file"; then
|
|
pass "$msg"
|
|
else
|
|
fail "$msg" "$pattern" "(not found in $file)"
|
|
fi
|
|
}
|
|
|
|
assert_file_not_contains() {
|
|
local pattern="$1" file="$2" msg="${3:-assert_file_not_contains}"
|
|
if [[ ! -f "$file" ]]; then
|
|
fail "$msg (file not found: $file)"
|
|
return
|
|
fi
|
|
if ! grep -qF "$pattern" "$file"; then
|
|
pass "$msg"
|
|
else
|
|
fail "$msg" "(should not contain $pattern)" "(found in $file)"
|
|
fi
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Summary
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# print_summary
|
|
# Print pass/fail totals and exit 1 if any tests failed.
|
|
print_summary() {
|
|
local total=$((_PASS + _FAIL))
|
|
printf "\n"
|
|
if [[ $_FAIL -eq 0 ]]; then
|
|
printf "${_G}%d/%d passed${_N}\n" "$_PASS" "$total"
|
|
else
|
|
printf "${_R}%d failed${_N}, %d passed, %d total\n" "$_FAIL" "$_PASS" "$total"
|
|
fi
|
|
[[ $_FAIL -eq 0 ]]
|
|
}
|