diff --git a/libexec/bats-exec-test b/libexec/bats-exec-test index 8242d17..d9a556c 100755 --- a/libexec/bats-exec-test +++ b/libexec/bats-exec-test @@ -91,42 +91,42 @@ bats_test_function() { } bats_capture_stack_trace() { - if [ "$BASH_SOURCE" != "$1" ]; then - BATS_STACK_TRACE=() - BATS_LINE_NUMBER="$BATS_LINE_NUMBER_" - BATS_LINE_NUMBER_="$2" + BATS_PREVIOUS_STACK_TRACE=( "${BATS_CURRENT_STACK_TRACE[@]}" ) + BATS_CURRENT_STACK_TRACE=() - local test_pattern=" $BATS_TEST_NAME $BATS_TEST_SOURCE" - local setup_pattern=" setup $BATS_TEST_SOURCE" - local teardown_pattern=" teardown $BATS_TEST_SOURCE" + local test_pattern=" $BATS_TEST_NAME $BATS_TEST_SOURCE" + local setup_pattern=" setup $BATS_TEST_SOURCE" + local teardown_pattern=" teardown $BATS_TEST_SOURCE" - local index=0 - local frame + local frame + local index=1 - while frame="$(caller "$index")"; do - BATS_STACK_TRACE[$index]="$frame" - if [[ "$frame" = *"$test_pattern" || \ - "$frame" = *"$setup_pattern" || \ - "$frame" = *"$teardown_pattern" ]]; then - break - else - let index+=1 - fi - done - fi + while frame="$(caller "$index")"; do + BATS_CURRENT_STACK_TRACE["${#BATS_CURRENT_STACK_TRACE[@]}"]="$frame" + if [[ "$frame" = *"$test_pattern" || \ + "$frame" = *"$setup_pattern" || \ + "$frame" = *"$teardown_pattern" ]]; then + break + else + let index+=1 + fi + done + + BATS_SOURCE="$(bats_frame_filename "${BATS_CURRENT_STACK_TRACE[0]}")" + BATS_LINENO="$(bats_frame_lineno "${BATS_CURRENT_STACK_TRACE[0]}")" } bats_print_stack_trace() { + local frame + local lineno local index=1 - local count="${#BATS_STACK_TRACE[@]}" - local line + local count="${#@}" - for frame in "${BATS_STACK_TRACE[@]}"; do + for frame in "$@"; do + lineno="$(bats_frame_lineno "$frame")" if [ $index -eq 1 ]; then - line="$BATS_LINE_NUMBER" echo -n "# (" else - line="$(bats_frame_line "$frame")" echo -n "# " fi @@ -136,20 +136,20 @@ bats_print_stack_trace() { fi if [ $index -eq $count ]; then - echo "in test file $BATS_TEST_FILENAME, line $line)" + echo "in test file $BATS_TEST_FILENAME, line $lineno)" else local filename="$(bats_frame_filename "$frame")" - echo "in file $filename, line $line," + echo "in file $filename, line $lineno," fi let index+=1 done } -bats_frame_line() { +bats_frame_lineno() { local frame="$1" - local line="${frame%% *}" - echo "$line" + local lineno="${frame%% *}" + echo "$lineno" } bats_frame_function() { @@ -171,16 +171,23 @@ bats_frame_filename() { fi } +bats_debug_trap() { + if [ "$BASH_SOURCE" != "$1" ]; then + bats_capture_stack_trace + fi +} + bats_error_trap() { + BATS_ERROR_STACK_TRACE=( "${BATS_PREVIOUS_STACK_TRACE[@]}" ) trap - debug } bats_teardown_trap() { - trap bats_exit_trap exit + trap "bats_exit_trap" exit if teardown >>"$BATS_OUT" 2>&1; then BATS_TEARDOWN_COMPLETED=1 elif [ -n "$BATS_TEST_COMPLETED" ]; then - BATS_LINE_NUMBER="$BATS_LINE_NUMBER_" + BATS_ERROR_STACK_TRACE=( "${BATS_CURRENT_STACK_TRACE[@]}" ) fi bats_exit_trap } @@ -200,7 +207,7 @@ bats_exit_trap() { if [ -z "$BATS_TEST_COMPLETED" ] || [ -z "$BATS_TEARDOWN_COMPLETED" ]; then echo "not ok $BATS_TEST_NUMBER $BATS_TEST_DESCRIPTION" >&3 - bats_print_stack_trace >&3 + bats_print_stack_trace "${BATS_ERROR_STACK_TRACE[@]}" >&3 sed -e "s/^/# /" < "$BATS_OUT" >&3 status=1 else @@ -234,7 +241,7 @@ bats_perform_test() { BATS_TEST_COMPLETED="" BATS_TEARDOWN_COMPLETED="" - trap "bats_capture_stack_trace \"\$BASH_SOURCE\" \$LINENO" debug + trap "bats_debug_trap \"\$BASH_SOURCE\"" debug trap "bats_error_trap" err trap "bats_teardown_trap" exit "$BATS_TEST_NAME" >>"$BATS_OUT" 2>&1 @@ -259,7 +266,7 @@ BATS_OUT="${BATS_TMPNAME}.out" bats_preprocess_source() { BATS_TEST_SOURCE="${BATS_TMPNAME}.src" { tr -d '\r' < "$BATS_TEST_FILENAME"; echo; } | bats-preprocess > "$BATS_TEST_SOURCE" - trap bats_cleanup_preprocessed_source err exit + trap "bats_cleanup_preprocessed_source" err exit trap "bats_cleanup_preprocessed_source; exit 1" int }