testlib.bash
## testlib.bash: shared scaffolding for pave's tests.
##
## Each test file sources this, then builds goal files in a scratch dir
## and runs the real `bin/pave` against them.
## HOME and HOSTNAME point into the scratch dir, so the real machine is never touched.
set -euo pipefail
PAVE=$(cd -P -- "${BASH_SOURCE[0]%/*}/.." && pwd)/bin/pave
scratch=$(mktemp -d)
trap 'rm -rf "$scratch"' EXIT
export HOME="$scratch/home"
export HOSTNAME=testhost
unset XDG_STATE_HOME XDG_CONFIG_HOME
mkdir -p "$HOME"
fails=0
## pv runs pave, capturing its combined output and exit status.
##
## - @param $1... arguments to pave.
## - @state out the combined stdout and stderr.
## - @state rc the exit status.
# shellcheck disable=SC2034 # rc is for the test files to read.
pv() {
rc=0
out=$("$PAVE" "$@" 2>&1) || rc=$?
}
## exact prints a file's content followed by a '.', so a command substitution can't hide trailing newlines.
exact() {
cat -- "$1"
printf .
}
## goals writes a goal file, creating its directory.
##
## - @param $1 path of the goal file.
## - @stdin the file's content.
goals() {
mkdir -p -- "${1%/*}"
cat >"$1"
}
_failed() {
>&2 printf 'FAIL: %s\n' "$1"
fails=$((fails + 1))
}
## assert checks that a command succeeds.
assert() {
local label=$1
shift
"$@" || _failed "$label"
}
## assert_eq checks two strings are equal.
assert_eq() {
[ "$2" = "$3" ] || _failed "$1 (want '$2', got '$3')"
}
## assert_has checks that the last pv output contains a line with the given text.
assert_has() {
grep -qF -- "$2" <<<"$out" || _failed "$1 (no '$2' in output)"
}
## assert_lacks checks that the last pv output doesn't contain the given text.
assert_lacks() {
! grep -qF -- "$2" <<<"$out" || _failed "$1 (unwanted '$2' in output)"
}
## assert_count checks how many lines of the last pv output contain the given text.
assert_count() {
local n
n=$(grep -cF -- "$2" <<<"$out" || :)
assert_eq "$1" "$3" "$n"
}
## verdict reports the outcome and exits accordingly.
verdict() {
local name=${BASH_SOURCE[1]##*/}
if [ "$fails" -ne 0 ]; then
>&2 echo "$name: $fails case(s) failed."
exit 1
fi
echo "$name: all cases passed."
}
tests/testlib.bash · 2.1 KiB · 7240887182