04759e9245
The “Scripts” folder is temporarily moved out of "Tests" because it doesn't work with the Swift Package Manager.
149 lines
4.8 KiB
Bash
Executable File
149 lines
4.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# assert.sh 1.0 - bash unit testing framework
|
|
# Copyright (C) 2009, 2010, 2011, 2012 Robert Lehmann
|
|
#
|
|
# http://github.com/lehmannro/assert.sh
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Lesser General Public License as published
|
|
# by the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Lesser General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
export DISCOVERONLY=${DISCOVERONLY:-}
|
|
export DEBUG=${DEBUG:-}
|
|
export STOP=${STOP:-}
|
|
export INVARIANT=${INVARIANT:-}
|
|
export CONTINUE=${CONTINUE:-}
|
|
|
|
args="$(getopt -n "$0" -l \
|
|
verbose,help,stop,discover,invariant,continue vhxdic $*)" \
|
|
|| exit -1
|
|
for arg in $args; do
|
|
case "$arg" in
|
|
-h)
|
|
echo "$0 [-vxidc]" \
|
|
"[--verbose] [--stop] [--invariant] [--discover] [--continue]"
|
|
echo "`sed 's/./ /g' <<< "$0"` [-h] [--help]"
|
|
exit 0;;
|
|
--help)
|
|
cat <<EOF
|
|
Usage: $0 [options]
|
|
Language-agnostic unit tests for subprocesses.
|
|
|
|
Options:
|
|
-v, --verbose generate output for every individual test case
|
|
-x, --stop stop running tests after the first failure
|
|
-i, --invariant do not measure timings to remain invariant between runs
|
|
-d, --discover collect test suites only, do not run any tests
|
|
-c, --continue do not modify exit code to test suite status
|
|
-h show brief usage information and exit
|
|
--help show this help message and exit
|
|
EOF
|
|
exit 0;;
|
|
-v|--verbose)
|
|
DEBUG=1;;
|
|
-x|--stop)
|
|
STOP=1;;
|
|
-i|--invariant)
|
|
INVARIANT=1;;
|
|
-d|--discover)
|
|
DISCOVERONLY=1;;
|
|
-c|--continue)
|
|
CONTINUE=1;;
|
|
esac
|
|
done
|
|
|
|
printf -v _indent "\n\t" # local format helper
|
|
|
|
_assert_reset() {
|
|
tests_ran=0
|
|
tests_failed=0
|
|
tests_errors=()
|
|
tests_starttime="$(date +%s.%N)" # seconds_since_epoch.nanoseconds
|
|
}
|
|
|
|
assert_end() {
|
|
# assert_end [suite ..]
|
|
tests_endtime="$(date +%s.%N)"
|
|
tests="$tests_ran ${*:+$* }tests"
|
|
[[ -n "$DISCOVERONLY" ]] && echo "collected $tests." && _assert_reset && return
|
|
[[ -n "$DEBUG" ]] && echo
|
|
[[ -z "$INVARIANT" ]] && report_time=" in $(bc \
|
|
<<< "${tests_endtime%.N} - ${tests_starttime%.N}" \
|
|
| sed -e 's/\.\([0-9]\{0,3\}\)[0-9]*/.\1/' -e 's/^\./0./')s" \
|
|
|| report_time=
|
|
|
|
if [[ "$tests_failed" -eq 0 ]]; then
|
|
echo "all $tests passed$report_time."
|
|
else
|
|
for error in "${tests_errors[@]}"; do echo "$error"; done
|
|
echo "$tests_failed of $tests failed$report_time."
|
|
fi
|
|
tests_failed_previous=$tests_failed
|
|
[[ $tests_failed -gt 0 ]] && tests_suite_status=1
|
|
_assert_reset
|
|
return $tests_failed_previous
|
|
}
|
|
|
|
assert() {
|
|
# assert <command> <expected stdout> [stdin]
|
|
(( tests_ran++ )) || :
|
|
[[ -n "$DISCOVERONLY" ]] && return || true
|
|
# printf required for formatting
|
|
printf -v expected "x${2:-}" # x required to overwrite older results
|
|
result="$(eval 2>/dev/null $1 <<< ${3:-})" || true
|
|
# Note: $expected is already decorated
|
|
if [[ "x$result" == "$expected" ]]; then
|
|
[[ -n "$DEBUG" ]] && echo -n . || true
|
|
return
|
|
fi
|
|
result="$(sed -e :a -e '$!N;s/\n/\\n/;ta' <<< "$result")"
|
|
[[ -z "$result" ]] && result="nothing" || result="\"$result\""
|
|
[[ -z "$2" ]] && expected="nothing" || expected="\"$2\""
|
|
_assert_fail "expected $expected${_indent}got $result" "$1" "$3"
|
|
}
|
|
|
|
assert_raises() {
|
|
# assert_raises <command> <expected code> [stdin]
|
|
(( tests_ran++ )) || :
|
|
[[ -n "$DISCOVERONLY" ]] && return || true
|
|
status=0
|
|
(eval $1 <<< ${3:-}) > /dev/null 2>&1 || status=$?
|
|
expected=${2:-0}
|
|
if [[ "$status" -eq "$expected" ]]; then
|
|
[[ -n "$DEBUG" ]] && echo -n . || true
|
|
return
|
|
fi
|
|
_assert_fail "program terminated with code $status instead of $expected" "$1" "$3"
|
|
}
|
|
|
|
_assert_fail() {
|
|
# _assert_fail <failure> <command> <stdin>
|
|
[[ -n "$DEBUG" ]] && echo -n X
|
|
report="test #$tests_ran \"$2${3:+ <<< $3}\" failed:${_indent}$1"
|
|
if [[ -n "$STOP" ]]; then
|
|
[[ -n "$DEBUG" ]] && echo
|
|
echo "$report"
|
|
exit 1
|
|
fi
|
|
tests_errors[$tests_failed]="$report"
|
|
(( tests_failed++ )) || :
|
|
}
|
|
|
|
_assert_reset
|
|
: ${tests_suite_status:=0} # remember if any of the tests failed so far
|
|
_assert_cleanup() {
|
|
local status=$?
|
|
# modify exit code if it's not already non-zero
|
|
[[ $status -eq 0 && -z $CONTINUE ]] && exit $tests_suite_status
|
|
}
|
|
trap _assert_cleanup EXIT
|