#!/bin/bash root="$TEST_TMPDIR/root" TEST_log="$TEST_TMPDIR/log" PKG="pkg" function set_up() { ERROR=0 mkdir -p "$root" cd "$root" touch WORKSPACE } # Runs buildozer, including saving the log and error messages, by sending the # BUILD file contents ($1) to STDIN. function run() { options=(--buildifier=) while [[ "$1" == --* ]]; do options+=("$1") shift done input="$1" shift mkdir -p "$PKG" pwd echo "$input" > "$PKG/BUILD" run_with_current_workspace "$buildozer ${options[*]}" "$@" } # Runs buildozer, including saving the log and error messages. function run_with_current_workspace() { log="$TEST_TMPDIR/log" log_err="$TEST_TMPDIR/log_err" cmd="$1" shift echo "$cmd $*" ret=0 $cmd "$@" > "$log" 2> "$log_err" || ret=$? if [ "$ret" -ne "$ERROR" ]; then cat "$log" cat "$log_err" fail "Expected error code $ERROR, got $ret" fi # There must be an error message if error code is 1 or 2. if [ "$ret" -eq "1" -o "$ret" -eq "2" ]; then [ -s "$log_err" ] || fail "No error message, despite error code $ret" fi } function assert_equals() { expected="$1" pkg="${2-}" if [ -z "$pkg" ]; then pkg="$PKG" fi echo "$expected" > "$pkg/expected" diff -u "$root/$pkg/expected" "$root/$pkg/BUILD" || fail "Output didn't match" } function assert_err() { if ! grep "$1" "$log_err"; then cat "$log_err" fail "Error log doesn't contain '$1'" fi } function assert_no_err() { if grep "$1" "$log_err"; then cat "$log_err" fail "Error log contains '$1'" fi } function fail() { __show_log >&2 echo "$TEST_name FAILED:" "$@" "." >&2 echo "$@" >$TEST_TMPDIR/__fail TEST_passed="false" # Cleanup as we are leaving the subshell now exit 1 } function __show_log() { echo "-- Test log: -----------------------------------------------------------" [[ -e $TEST_log ]] && cat $TEST_log || echo "(Log file did not exist.)" echo "------------------------------------------------------------------------" } function __pad() { local title=$1 local pad=$2 { echo -n "$pad$pad $title " printf "%80s" " " | tr ' ' "$pad" } | head -c 80 echo } function __trap_with_arg() { func="$1" ; shift for sig ; do trap "$func $sig" "$sig" done } function run_suite() { local message="$1" echo >&2 echo "$message" >&2 echo >&2 local total=0 local passed=0 TESTS=$(declare -F | awk '{print $3}' | grep ^test_ || true) for TEST_name in ${TESTS[@]}; do >$TEST_log # Reset the log. TEST_passed="true" total=$(($total + 1)) __pad $TEST_name '*' >&2 if [ "$(type -t $TEST_name)" = function ]; then # Run test in a subshell. rm -f $TEST_TMPDIR/__err_handled __trap_with_arg __test_terminated INT KILL PIPE TERM ABRT FPE ILL QUIT SEGV ( set_up eval $TEST_name test $TEST_passed == "true" ) 2>&1 | tee $TEST_TMPDIR/__log # Note that tee will prevent the control flow continuing if the test # spawned any processes which are still running and have not closed # their stdout. test_subshell_status=${PIPESTATUS[0]} if [ "$test_subshell_status" != 0 ]; then TEST_passed="false" fi else # Bad test explicitly specified in $TESTS. fail "Not a function: '$TEST_name'" fi local red='\033[0;31m' local green='\033[0;32m' local no_color='\033[0m' if [[ "$TEST_passed" == "true" ]]; then echo -e "${green}PASSED${no_color}: $TEST_name" >&2 passed=$(($passed + 1)) else echo -e "${red}FAILED${no_color}: $TEST_name" >&2 # end marker in CDATA cannot be escaped, we need to split the CDATA sections log=$(cat $TEST_TMPDIR/__log | sed 's/]]>/]]>]]>&2 done }