@@ -568,6 +568,11 @@ function bashunit::runner::run_test() {
568568 [[ -f ~ /.profile ]] && source ~ /.profile 2> /dev/null || true
569569 fi
570570
571+ # Enable coverage tracking early to include set_up/tear_down hooks
572+ if bashunit::env::is_coverage_enabled; then
573+ bashunit::coverage::enable_trap
574+ fi
575+
571576 # Run set_up and capture exit code without || to preserve errexit behavior
572577 local setup_exit_code=0
573578 bashunit::runner::run_set_up " $test_file "
@@ -583,11 +588,6 @@ function bashunit::runner::run_test() {
583588 set +euo pipefail
584589 fi
585590
586- # Enable coverage tracking if enabled
587- if bashunit::env::is_coverage_enabled; then
588- bashunit::coverage::enable_trap
589- fi
590-
591591 # 2>&1: Redirects the std-error (FD 2) to the std-output (FD 1).
592592 # points to the original std-output.
593593 " $fn_name " " $@ " 2>&1
@@ -994,16 +994,8 @@ function bashunit::runner::execute_file_hook() {
994994 trap ' _BASHUNIT_HOOK_ERR_STATUS=$?; set +eE; trap - ERR; return $_BASHUNIT_HOOK_ERR_STATUS' ERR
995995
996996 {
997- # Enable coverage trap inside hooks to attribute lines executed during setup/teardown
998- if bashunit::env::is_coverage_enabled; then
999- bashunit::coverage::enable_trap
1000- fi
1001997 " $hook_name "
1002998 } > " $hook_output_file " 2>&1
1003- # Disable coverage trap after hook execution
1004- if bashunit::env::is_coverage_enabled; then
1005- bashunit::coverage::disable_trap
1006- fi
1007999
10081000 # Capture exit status from global variable and clean up
10091001 status=$_BASHUNIT_HOOK_ERR_STATUS
@@ -1049,10 +1041,20 @@ function bashunit::runner::run_set_up_before_script() {
10491041 local start_time
10501042 start_time=$( bashunit::clock::now)
10511043
1044+ # Enable coverage trap to attribute lines executed during set_up_before_script
1045+ if bashunit::env::is_coverage_enabled; then
1046+ bashunit::coverage::enable_trap
1047+ fi
1048+
10521049 # Execute the hook (render_header=false since header is already rendered)
10531050 bashunit::runner::execute_file_hook ' set_up_before_script' " $test_file " false
10541051 local status=$?
10551052
1053+ # Disable coverage trap after hook execution
1054+ if bashunit::env::is_coverage_enabled; then
1055+ bashunit::coverage::disable_trap
1056+ fi
1057+
10561058 local end_time
10571059 end_time=$( bashunit::clock::now)
10581060 local duration_ns=$(( end_time - start_time))
@@ -1093,16 +1095,8 @@ function bashunit::runner::execute_test_hook() {
10931095 trap ' _BASHUNIT_HOOK_ERR_STATUS=$?; set +eE; trap - ERR; return $_BASHUNIT_HOOK_ERR_STATUS' ERR
10941096
10951097 {
1096- # Enable coverage trap inside test-level hooks
1097- if bashunit::env::is_coverage_enabled; then
1098- bashunit::coverage::enable_trap
1099- fi
11001098 " $hook_name "
11011099 } > " $hook_output_file " 2>&1
1102- # Disable coverage trap after hook execution
1103- if bashunit::env::is_coverage_enabled; then
1104- bashunit::coverage::disable_trap
1105- fi
11061100
11071101 # Capture exit status from global variable and clean up
11081102 status=$_BASHUNIT_HOOK_ERR_STATUS
@@ -1182,10 +1176,20 @@ function bashunit::runner::run_tear_down_after_script() {
11821176 local start_time
11831177 start_time=$( bashunit::clock::now)
11841178
1179+ # Enable coverage trap to attribute lines executed during tear_down_after_script
1180+ if bashunit::env::is_coverage_enabled; then
1181+ bashunit::coverage::enable_trap
1182+ fi
1183+
11851184 # Execute the hook
11861185 bashunit::runner::execute_file_hook ' tear_down_after_script' " $test_file "
11871186 local status=$?
11881187
1188+ # Disable coverage trap after hook execution
1189+ if bashunit::env::is_coverage_enabled; then
1190+ bashunit::coverage::disable_trap
1191+ fi
1192+
11891193 local end_time
11901194 end_time=$( bashunit::clock::now)
11911195 local duration_ns=$(( end_time - start_time))
0 commit comments