diff --git a/libexec/bats-exec-test b/libexec/bats-exec-test index 266d15c..190ef30 100755 --- a/libexec/bats-exec-test +++ b/libexec/bats-exec-test @@ -41,20 +41,37 @@ load() { run() { local e E T + [[ ! "$-" =~ e ]] || e=1 [[ ! "$-" =~ E ]] || E=1 [[ ! "$-" =~ T ]] || T=1 + set +e set +E set +T - output="$("$@" 2>&1)" - status="$?" + + output=$( + "$@" 2>&1; status=$? + bats_capture_vars > "$BATS_VARS" + exit $status + ) + + status=$? IFS=$'\n' lines=($output) + [ -z "$e" ] || set -e [ -z "$E" ] || set -E [ -z "$T" ] || set -T } +set_run_vars() { + local var_names=("$@") + + for n in "${var_names[@]}"; do + eval "$(grep "$n=" "$BATS_VARS")" 2> /dev/null || true + done +} + setup() { true } @@ -82,6 +99,10 @@ bats_test_function() { BATS_TEST_NAMES["${#BATS_TEST_NAMES[@]}"]="$test_name" } +bats_capture_vars() { + comm -3 <(declare | sort) <(declare -f | sort) +} + bats_capture_stack_trace() { if [ "$BASH_SOURCE" != "$1" ]; then BATS_STACK_TRACE=() @@ -200,7 +221,7 @@ bats_exit_trap() { status=0 fi - rm -f "$BATS_OUT" + rm -f "$BATS_OUT" "$BATS_VARS" exit "$status" } @@ -247,6 +268,7 @@ fi BATS_TMPNAME="$BATS_TMPDIR/bats.$$" BATS_PARENT_TMPNAME="$BATS_TMPDIR/bats.$PPID" BATS_OUT="${BATS_TMPNAME}.out" +BATS_VARS="${BATS_TMPNAME}.vars" bats_preprocess_source() { BATS_TEST_SOURCE="${BATS_TMPNAME}.src" diff --git a/test/bats.bats b/test/bats.bats index 37d55c2..f1e626f 100755 --- a/test/bats.bats +++ b/test/bats.bats @@ -186,3 +186,10 @@ fixtures bats [ "${lines[0]}" = "This isn't TAP!" ] [ "${lines[1]}" = "Good day to you" ] } + +@test "variables are preserved" { + run bats "$FIXTURE_ROOT/preserved_variables.bats" + echo $status + echo $output + [ $status -eq 0 ] +} diff --git a/test/fixtures/bats/preserved_variables.bats b/test/fixtures/bats/preserved_variables.bats new file mode 100644 index 0000000..e47ce8d --- /dev/null +++ b/test/fixtures/bats/preserved_variables.bats @@ -0,0 +1,78 @@ +@test "set_run_vars sets variables from run" { + odd_characters="'(')'"'!@#$$%^&*~`{}[]:;"<>,./\' + normal_var=1 + + change_vars() { + normal_var=3 + new_var=4 + new_array=() + new_array[0]=" item with spaces " + new_array[3]="item after gap" + new_array[4]="$odd_characters" + } + + run change_vars + + [ "$normal_var" -eq 1 ] + set_run_vars normal_var + [ "$normal_var" -eq 3 ] + + [ -z "$new_var" ] + set_run_vars new_var + [ "$new_var" -eq 4 ] + + [ -z "$new_array" ] + set_run_vars new_array + [ "${new_array[0]}" == " item with spaces " ] + [ "${new_array[3]}" == "item after gap" ] + [ "${new_array[4]}" == "$odd_characters" ] +} + +@test "set_run_vars handles readonly variables" { + readonly readonly_var=2 + + change_vars() { + : + } + + run change_vars + + [ "$readonly_var" -eq 2 ] + set_run_vars readonly_var + [ "$readonly_var" -eq 2 ] +} + +@test "local variables are not available after run" { + change_vars() { + local local_var="local" + global_var=1 + } + + run change_vars + + [ -z "$local_var" ] + set_run_vars local_var + [ -z "$local_var" ] + + [ -z "$global_var" ] + set_run_vars global_var + [ "$global_var" -eq 1 ] +} + +@test "set_run_vars accepts multiple variables" { + change_vars() { + var1=1 + var2=2 + var3=3 + } + + run change_vars + + [ -z "$var1" ] + [ -z "$var2" ] + [ -z "$var3" ] + set_run_vars var1 var2 var3 + [ "$var1" -eq 1 ] + [ "$var2" -eq 2 ] + [ "$var3" -eq 3 ] +}