From d8b936383a214f5b3db86daa3c56391d28122263 Mon Sep 17 00:00:00 2001 From: Luke Shumaker Date: Mon, 10 Apr 2017 21:48:52 -0400 Subject: [PATCH 1/2] Gracefully handle errors from before() and after(). See the comments for a fuller explanation of the changes. This should obsolete https://github.com/bmizerany/roundup/pull/23 (though the test cases from it should still be merged). This should fix https://github.com/bmizerany/roundup/issues/29 . This should fix https://github.com/bmizerany/roundup/issues/44 . --- roundup.sh | 60 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/roundup.sh b/roundup.sh index d7465dc..70b1e90 100755 --- a/roundup.sh +++ b/roundup.sh @@ -243,28 +243,12 @@ do # test. Drop into an subshell to contain operations that may throw # off roundup; such as `cd`. ( - # Output `before` trace to temporary file. If `before` runs cleanly, - # the trace will be overwritten by the actual test case below. - { - # redirect tracing output of `before` into file. - { - set -x - # If `before` wasn't redefined, then this is `:`. - before - } &>"$roundup_tmp/$roundup_test_name" - # disable tracing again. Its trace output goes to /dev/null. - set +x - } &>/dev/null - # exit subshell with return code of last failing command. This # is needed to see the return code 253 on failed assumptions. # But, only do this if the error handling is activated. set -E trap 'rc=$?; set +x; set -o | grep "errexit.*on" >/dev/null && exit $rc' ERR - # If `before` wasn't redefined, then this is `:`. - before - # Momentarily turn off auto-fail to give us access to the tests # exit status in `$?` for capturing. set +e @@ -275,24 +259,42 @@ do # failed test should not immediately fail roundup. Each # tests trace output is saved in temporary storage. set -xe - $roundup_test_name - ) >"$roundup_tmp/$roundup_test_name" 2>&1 - # We need to capture the exit status before returning the `set - # -e` mode. Returning with `set -e` before we capture the exit - # status will result in `$?` being set with `set`'s status - # instead. - roundup_result=$? - - # It's safe to return to normal operation. - set -e + # Run the setup routine; if `before` wasn't redefined, then + # this is `:`. + before + + # Similarly to above, momentarily turn off auto-fail, so + # that we can have the tear-down function run even if the + # test fails. + set +e + ( + # Turn auto-fail back on to allow the test to fail fast. + set -e + $roundup_test_name + ) + # Capture the test's exit status. If tear-down goes ok, we + # will exit with this status to report a test failure. + roundup_status=$? + # It's safe to turn auto-fail back on now. + set -e + + # Run the tear-down routine; if `after` wasn't redefined, + # then this is `:`. + after + + # Report the result of the test. + exit $roundup_status + ) >"$roundup_tmp/$roundup_test_name" 2>&1 - # If `after` wasn't redefined, then this runs `:`. - after + # This is where we might turn auto-fail back on; but don't + # bother. The only thing it would affect is a couple of + # `printf` statements, and failing on error from them wouldn't + # be handled usefully anyway. # This is the final step of a test. Print its pass/fail signal # and name. - if [ "$roundup_result" -ne 0 ] + if [ "$?" -ne 0 ] then printf "f" else printf "p" fi From 1321a73d6de8ae10a70db0e2a75fe400c29ef293 Mon Sep 17 00:00:00 2001 From: "Dr. Stefan Schimanski" Date: Wed, 25 Jul 2012 10:52:28 +0000 Subject: [PATCH 2/2] Backport the tests from PR #23 Fix multiple invocation of the `before` function and `before` tracing 1. The `before` function had been called twice, once with proper tracing and error output redirection and once directly. This is fixed now. 2. The result output was moved out of the inner subshell. This is necessary because: in case the `before` function has an error, roundup's error trap is triggered and the inner subshell is left. Still, we need a proper result ouput. 3. A test case with a broken `before` function was added which gives the following output: roundup before trace it_works: [FAIL] + false exit code 1 for the following before function: before () { false } --- roundup-1-test.sh | 5 +++++ roundup-before-test.sh | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 roundup-before-test.sh diff --git a/roundup-1-test.sh b/roundup-1-test.sh index 967e9f0..263c84c 100644 --- a/roundup-1-test.sh +++ b/roundup-1-test.sh @@ -46,3 +46,8 @@ it_exits_non_zero() { it_survives_edge_cases() { rup edge } + +it_exits_non_zero_on_broken_before () { + status=$(set +e ; rup roundup-5 >/dev/null ; echo $?) + test 2 -eq $status +} diff --git a/roundup-before-test.sh b/roundup-before-test.sh new file mode 100644 index 0000000..aac7c93 --- /dev/null +++ b/roundup-before-test.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env roundup +# +# This Will Fail +# -------------- +# +# The before function +describe "roundup before trace" + +# This `before` function is run before it_works. The `false` will simulate +# an error. Hence, `it_works` should not be called at all, but it should be +# marked as failed and the `before` trace should be displayed. +before () { + false +} + +# A trivial and correct test case. But because `before` is broken, this +# testcase will fail as well. +it_works () { + true +}