Skip to content

Commit d2ed146

Browse files
authored
fix(runner): detect set_up failure when source file does not exist (#612)
1 parent a3f2198 commit d2ed146

5 files changed

Lines changed: 65 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
## Unreleased
44

5+
### Fixed
6+
- Fix `source` of non-existent file in `set_up()` silently passing all tests (#611)
7+
58
## [0.34.0](https://github.com/TypedDevs/bashunit/compare/0.33.0...0.34.0) - 2026-03-17
69

710
### Added

src/runner.sh

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,11 @@ function bashunit::runner::run_test() {
590590
exec 3>&1
591591

592592
local test_execution_result=$(
593+
# Save subshell stdout to FD 5 so the EXIT trap can restore it.
594+
# When set -e kills the subshell during a redirected block in
595+
# execute_test_hook, the redirect leaks into the EXIT trap,
596+
# causing export_subshell_context output to be lost.
597+
exec 5>&1
593598
# shellcheck disable=SC2064
594599
trap "exit_code=\$?; bashunit::runner::cleanup_on_exit \"$test_file\" \"\$exit_code\"" EXIT
595600
bashunit::state::initialize_assertions_count
@@ -612,9 +617,12 @@ function bashunit::runner::run_test() {
612617
fi
613618
614619
# Run set_up and capture exit code without || to preserve errexit behavior
620+
# shellcheck disable=SC2030
621+
_BASHUNIT_SETUP_COMPLETED=false
615622
local setup_exit_code=0
616623
bashunit::runner::run_set_up "$test_file"
617624
setup_exit_code=$?
625+
_BASHUNIT_SETUP_COMPLETED=true
618626
if [[ $setup_exit_code -ne 0 ]]; then
619627
exit $setup_exit_code
620628
fi
@@ -829,6 +837,26 @@ function bashunit::runner::cleanup_on_exit() {
829837
fi
830838

831839
set +e
840+
841+
# Detect unexpected subshell exit during set_up (Issue #611).
842+
# When 'source' of a non-existent file fails under set -eE, the ERR trap
843+
# does not fire. On macOS Bash 3.2, $? is 0 in the EXIT trap; on Linux
844+
# Bash 5.x, $? is 1. In both cases the hook failure is not recorded.
845+
# Additionally, the stdout redirect from execute_test_hook leaks into the
846+
# EXIT trap. Restore stdout from saved FD 5 so export_subshell_context
847+
# output reaches test_execution_result.
848+
# shellcheck disable=SC2031
849+
if [[ "${_BASHUNIT_SETUP_COMPLETED:-true}" != "true" ]]; then
850+
exec 1>&5
851+
if [[ "$exit_code" -eq 0 ]]; then
852+
exit_code=1
853+
fi
854+
if [[ -z "${_BASHUNIT_TEST_HOOK_FAILURE:-}" ]]; then
855+
bashunit::state::set_test_hook_failure "set_up"
856+
bashunit::state::set_test_hook_message "Hook 'set_up' failed unexpectedly (e.g., source of non-existent file)"
857+
fi
858+
fi
859+
832860
# Don't use || here - it disables ERR trap in the entire call chain
833861
bashunit::runner::run_tear_down "$test_file"
834862
local teardown_status=$?

tests/acceptance/bashunit_setup_error_test.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,26 @@ function test_bashunit_set_up_stops_on_first_failure() {
106106
# Clean up
107107
rm -f "$marker_file"
108108
}
109+
110+
# Issue #611: Sourcing a non-existent file in set_up should fail the test
111+
function test_bashunit_when_set_up_sources_nonexistent_file() {
112+
local test_file=./tests/acceptance/fixtures/test_bashunit_when_setup_sources_nonexistent_file.sh
113+
local fixture=$test_file
114+
115+
local error_line="✗ Error: Set up"
116+
local tests_summary="Tests: 1 failed, 1 total"
117+
local assertions_summary="Assertions: 0 failed, 0 total"
118+
119+
local actual_raw
120+
set +e
121+
actual_raw="$(./bashunit --no-parallel --detailed --env "$TEST_ENV_FILE" "$test_file")"
122+
set -e
123+
124+
local actual
125+
actual="$(printf "%s" "$actual_raw" | strip_ansi)"
126+
127+
assert_contains "$error_line" "$actual"
128+
assert_contains "$tests_summary" "$actual"
129+
assert_contains "$assertions_summary" "$actual"
130+
assert_general_error "$(./bashunit --no-parallel --env "$TEST_ENV_FILE" "$test_file")"
131+
}

tests/acceptance/coverage_hooks_test.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ function test_coverage_tracks_src_lines_executed_in_hooks() {
1212
output=$(BASHUNIT_PARALLEL_RUN=false ./bashunit \
1313
--coverage \
1414
--no-coverage-report \
15+
--coverage-min 0 \
1516
--coverage-paths "src/globals.sh" \
1617
--coverage-report "$LCOV_FILE" \
1718
tests/acceptance/fixtures/test_coverage_hooks.sh 2>&1)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/usr/bin/env bash
2+
3+
function set_up() {
4+
# shellcheck disable=SC1091
5+
source ./this_file_does_not_exist.sh
6+
}
7+
8+
function test_dummy() {
9+
assert_same "foo" "foo"
10+
}

0 commit comments

Comments
 (0)