grub-themes/tests/bash_unit
Matthias Morin 81cee16d76 Full rewrite
2021-03-09 00:45:26 +01:00

381 lines
8.2 KiB
Bash
Executable file

#!/usr/bin/env bash
#
# bash unit testing enterprise edition framework for professionals
# Copyright (C) 2011-2016 Pascal Grange
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU 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 General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
# https://github.com/pgrange/bash_unit
VERSION=v1.7.1
ESCAPE=$(printf "\033")
NOCOLOR="${ESCAPE}[0m"
RED="${ESCAPE}[91m"
GREEN="${ESCAPE}[92m"
YELLOW="${ESCAPE}[93m"
BLUE="${ESCAPE}[94m"
# Make bash_unit immune to some basic unix commands faking
CAT="$(which cat)"
SED="$(which sed)"
GREP="$(which grep)"
RM="$(which rm)"
fail() {
local message=${1:-}
local stdout=${2:-}
local stderr=${3:-}
notify_test_failed "$__bash_unit_current_test__" "$message"
[[ ! -z $stdout ]] && [ -s "$stdout" ] && notify_stdout < "$stdout"
[[ ! -z $stderr ]] && [ -s "$stderr" ] && notify_stderr < "$stderr"
stacktrace | notify_stack
exit 1
}
assert() {
local assertion=$1
local message=${2:-}
_assert_expression \
"$assertion" \
"[ \$status == 0 ]" \
"\"$message\""
}
assert_fails() {
local assertion=$1
local message=${2:-}
_assert_expression \
"$assertion" \
"[ \$status != 0 ]" \
"\"$message\""
}
assert_fail() {
#deprecated, use assert_fails instead
assert_fails "$@"
}
assert_status_code() {
local expected_status=$1
local assertion="$2"
local message="${3:-}"
_assert_expression \
"$assertion" \
"[ \$status == $expected_status ]" \
"\"$message\" expected status code $expected_status but was \$status"
}
_assert_expression() {
local assertion=$1
local condition=$2
local message=$3
(
local stdout=$(mktemp)
local stderr=$(mktemp)
trap "$RM -f \"$stdout\" \"$stderr\"" EXIT
local status
eval "($assertion)" >"$stdout" 2>"$stderr" && status=$? || status=$?
if ! eval "$condition"
then
fail "$(eval echo $message)" "$stdout" "$stderr"
fi
) || exit $?
}
assert_equals() {
local expected=$1
local actual=$2
local message=${3:-}
[[ -z $message ]] || message="$message\n"
if [ "$expected" != "$actual" ]
then
fail "$message expected [$expected] but was [$actual]"
fi
}
assert_not_equals() {
local unexpected=$1
local actual=$2
local message=${3:-}
[[ -z $message ]] || message="$message\n"
[ "$unexpected" != "$actual" ] || \
fail "$message expected different value than [$unexpected] but was the same"
}
fake() {
local command=$1
shift
if [ $# -gt 0 ]
then
eval "function $command() { export FAKE_PARAMS=\"\$@\" ; $@ ; }"
else
eval "function $command() { echo \"$($CAT)\" ; }"
fi
export -f $command
}
stacktrace() {
local i=1
while ! [ -z "${BASH_SOURCE[$i]:-}" ]
do
echo ${BASH_SOURCE[$i]}:${BASH_LINENO[$((i-1))]}:${FUNCNAME[$i]}\(\)
i=$((i + 1))
done | "$GREP" -v "^$BASH_SOURCE"
}
run_test_suite() {
local failure=0
declare -F | "$GREP" ' setup_suite$' >/dev/null && setup_suite
for pending_test in $(set | "$GREP" -E '^(pending|todo).* \(\)' | "$GREP" -E "$test_pattern" | "$SED" -e 's: .*::')
do
notify_test_starting "$pending_test"
notify_test_pending "$pending_test"
done
for test in $(set | "$GREP" -E '^test.* \(\)' | "$GREP" -E "$test_pattern" | "$SED" -e 's: .*::')
do
(
local status=0
declare -F | "$GREP" ' setup$' >/dev/null && setup
(__bash_unit_current_test__="$test" run_test) || status=$?
declare -F | "$GREP" ' teardown$' >/dev/null && teardown
exit $status
)
failure=$(( $? || failure))
done
declare -F | "$GREP" ' teardown_suite$' >/dev/null && teardown_suite
return $failure
}
run_test() {
set -e
notify_test_starting "$__bash_unit_current_test__"
"$__bash_unit_current_test__" && notify_test_succeeded "$__bash_unit_current_test__"
}
usage() {
echo "$1" >&2
echo "$0 [-f <output format>] [-p <pattern1>] [-p <pattern2>]... <test_file1> <test_file2>..." >&2
echo >&2
echo "Runs tests in test files that match <pattern>s" >&2
echo "<output format> is optional only supported value is tap" >&2
echo "-v to get current version information" >&2
echo "See https://github.com/pgrange/bash_unit" >&2
exit 1
}
# Formating
pretty_success() {
pretty_format "$GREEN" "\u2713" "${1:-}"
}
pretty_warning() {
pretty_format "$YELLOW" "\u2717" "$1"
}
pretty_failure() {
pretty_format "$RED" "\u2717" "${1:-}"
}
pretty_format() {
local color="$1"
local pretty_symbol="$2"
local alt_symbol="$3"
local term_utf8=false
if is_terminal && [[ "$LANG" =~ .*UTF-8.* ]]
then
term_utf8=true
fi
(
$CAT
if $term_utf8
then
echo -en " $pretty_symbol "
else
[[ ! -z "$alt_symbol" ]] && echo -en " $alt_symbol "
fi
) | color "$color"
}
color() {
_start_color() {
if is_terminal ; then echo -en "$color" ; fi
}
_stop_color() {
if is_terminal ; then echo -en "$NOCOLOR" ; fi
}
local color=$1
shift
_start_color
if [ $# -gt 0 ]
then
echo $*
else
$CAT
fi
_stop_color
}
is_terminal() {
[ -t 1 ] || [[ "${FORCE_COLOR}" == true ]]
}
text_format() {
notify_suite_starting() {
local test_file="$1"
echo "Running tests in $test_file"
}
notify_test_starting() {
local test="$1"
echo -n "Running $test... " | color "$BLUE"
}
notify_test_pending() {
echo -n "PENDING" | pretty_warning
echo
}
notify_test_succeeded() {
echo -n "SUCCESS" | pretty_success
echo
}
notify_test_failed() {
local message="$2"
echo -n "FAILURE" | pretty_failure
echo
[[ -z $message ]] || printf -- "$message\n"
}
notify_stdout() {
"$SED" 's:^:out> :' | color "$GREEN"
}
notify_stderr() {
"$SED" 's:^:err> :' | color "$RED"
}
notify_stack() {
color "$YELLOW"
}
}
tap_format() {
notify_suite_starting() {
local test_file="$1"
echo "# Running tests in $test_file"
}
notify_test_starting() {
echo -n
}
notify_test_pending() {
local test="$1"
echo -n "ok" | pretty_warning -
echo -n "$test" | color "$BLUE"
echo " # skip test to be written" | color "$YELLOW"
}
notify_test_succeeded() {
local test="$1"
echo -n "ok" | pretty_success -
echo "$test" | color "$BLUE"
}
notify_test_failed() {
local test="$1"
local message="$2"
echo -n "not ok" | pretty_failure -
echo "$test" | color "$BLUE"
[[ -z $message ]] || printf -- "$message\n" | "$SED" -u -e 's/^/# /'
}
notify_stdout() {
"$SED" 's:^:# out> :' | color "$GREEN"
}
notify_stderr() {
"$SED" 's:^:# err> :' | color "$RED"
}
notify_stack() {
"$SED" 's:^:# :' | color "$YELLOW"
}
}
output_format=text
test_pattern=""
separator=""
while getopts "vp:f:" option
do
case "$option" in
p)
test_pattern="${test_pattern}${separator}${OPTARG}"
separator="|"
;;
f)
output_format="${OPTARG}"
;;
v)
echo "bash_unit $VERSION"
exit
;;
?|:)
usage
;;
esac
done
shift $((OPTIND-1))
for test_file in "$@"
do
test -e "$test_file" || usage "file does not exist: $test_file"
test -r "$test_file" || usage "can not read file: $test_file"
done
case "$output_format" in
text)
text_format
;;
tap)
tap_format
;;
*)
usage "unsupproted output format: $output_format"
;;
esac
#run tests received as parameters
failure=0
for test_file in "$@"
do
notify_suite_starting "$test_file"
(
set -e # Ensure bash_unit with exit with failure
# in case of syntax error.
if [[ "${STICK_TO_CWD}" != true ]]
then
cd "$(dirname "$test_file")"
source "$(basename "$test_file")"
else
source "$test_file"
fi
set +e
run_test_suite
)
failure=$(( $? || failure))
done
exit $failure