Charles N Wyble
210db946d7
git-vendor-name: mo git-vendor-dir: vendor/git.knownelement.com/ExternalVendorCode/mo git-vendor-repository: https://git.knownelement.com/ExternalVendorCode/mo.git git-vendor-ref: master
163 lines
3.9 KiB
Bash
Executable File
163 lines
3.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
#
|
||
# Run one or more tests.
|
||
#
|
||
# Command-line usage to run all tests.
|
||
#
|
||
# ./run-tests
|
||
#
|
||
# To run only one test, run "tests/test-name".
|
||
#
|
||
# Usage within a test as a template. Source run-tests to get functions, export
|
||
# any necessary variables, then call runTest.
|
||
#
|
||
# #!/usr/bin/env bash
|
||
# cd "${0%/*}" || exit 1
|
||
# . ../run-tests
|
||
#
|
||
# export template="This is a template"
|
||
# export expected="This is a template"
|
||
# runTest
|
||
#
|
||
# When used within the test, you control various aspects with environment
|
||
# variables or functions.
|
||
#
|
||
# - The content passed into mo is either the variable "$template" or the output
|
||
# of the function called template.
|
||
# - The expected result is either "$expected" or the function called expected.
|
||
# - The expected return code is "$returnCode" and defaults to 0.
|
||
# - The arguments to pass to mo is the array "${arguments[@]}" and defaults to ().
|
||
#
|
||
# When $MO_DEBUG is set to a non-empty value, the test does not run, but mo is
|
||
# simply executed directly. This allows for calling mo in the same manner as
|
||
# the test but does not buffer output nor expect the output to match the
|
||
# expected.
|
||
#
|
||
# When $MO_DEBUG_TEST is set to a non-empty value, the expected and actual
|
||
# results are shown using "declare -p" to provide an easier time seeing the
|
||
# differences, especially with whitespace.
|
||
|
||
testCase() {
|
||
echo "Input: $1"
|
||
echo "Expected: $2"
|
||
}
|
||
|
||
indirect() {
|
||
unset -v "$1"
|
||
printf -v "$1" '%s' "$2"
|
||
}
|
||
|
||
getValue() {
|
||
local name temp len hardSpace
|
||
|
||
name=$2
|
||
hardSpace=" "
|
||
|
||
if declare -f "$name" &> /dev/null; then
|
||
temp=$("$name"; echo -n "$hardSpace")
|
||
len=$((${#temp} - 1))
|
||
|
||
if [[ "${temp:$len}" == "$hardSpace" ]]; then
|
||
temp=${temp:0:$len}
|
||
fi
|
||
else
|
||
temp=${!name}
|
||
fi
|
||
|
||
local "$1" && indirect "$1" "$temp"
|
||
}
|
||
|
||
runTest() (
|
||
local testTemplate testExpected testActual hardSpace len testReturnCode testFail
|
||
|
||
hardSpace=" "
|
||
. ../mo
|
||
|
||
getValue testTemplate template
|
||
getValue testExpected expected
|
||
|
||
if [[ -n "${MO_DEBUG:-}" ]]; then
|
||
echo -n "$testTemplate" | mo ${arguments[@]+"${arguments[@]}"} 2>&1
|
||
|
||
return $?
|
||
fi
|
||
|
||
testActual=$(echo -n "$testTemplate" | mo ${arguments[@]+"${arguments[@]}"} 2>&1; echo -n "$hardSpace$?")
|
||
testReturnCode=${testActual##*$hardSpace}
|
||
testActual=${testActual%$hardSpace*}
|
||
testFail=false
|
||
|
||
if [[ "$testActual" != "$testExpected" ]]; then
|
||
echo "Failure"
|
||
echo "Expected:"
|
||
echo "$testExpected"
|
||
echo "Actual:"
|
||
echo "$testActual"
|
||
|
||
if [[ -n "${MO_DEBUG_TEST-}" ]]; then
|
||
declare -p testExpected
|
||
# Align the two declare outputs
|
||
echo -n " "
|
||
declare -p testActual
|
||
fi
|
||
|
||
testFail=true
|
||
fi
|
||
|
||
if [[ "$testReturnCode" != "$returnCode" ]]; then
|
||
echo "Expected return code $returnCode, but got $testReturnCode"
|
||
testFail=true
|
||
fi
|
||
|
||
if [[ "$testFail" == "true" ]]; then
|
||
return 1
|
||
fi
|
||
|
||
return 0
|
||
)
|
||
|
||
runTestFile() (
|
||
local file=$1
|
||
|
||
echo "Test: $file"
|
||
"$file"
|
||
)
|
||
|
||
runTests() (
|
||
PASS=0
|
||
FAIL=0
|
||
|
||
if [[ $# -gt 0 ]]; then
|
||
for TEST in "$@"; do
|
||
runTestFile "$TEST" && PASS=$((PASS + 1)) || FAIL=$((FAIL + 1))
|
||
done
|
||
else
|
||
cd "${0%/*}"
|
||
for TEST in tests/*; do
|
||
if [[ -f "$TEST" ]]; then
|
||
runTestFile "$TEST" && PASS=$((PASS + 1)) || FAIL=$((FAIL + 1))
|
||
fi
|
||
done
|
||
fi
|
||
|
||
echo ""
|
||
echo "Pass: $PASS"
|
||
echo "Fail: $FAIL"
|
||
|
||
if [[ $FAIL -gt 0 ]]; then
|
||
exit 1
|
||
fi
|
||
)
|
||
|
||
# Clear test related variables
|
||
template="Template not defined"
|
||
expected="Expected not defined"
|
||
returnCode=0
|
||
arguments=()
|
||
|
||
# If sourced, load functions.
|
||
# If executed, perform the actions as expected.
|
||
if [[ "$0" == "${BASH_SOURCE[0]}" ]] || [[ -z "${BASH_SOURCE[0]}" ]]; then
|
||
runTests ${@+"${@}"}
|
||
fi
|