🤔 Background
bashunit --parallel --output json over a selection with no tests writes a coloured No tests found line to stdout, ahead of the document. --output promises stdout is the document, so the result does not parse.
Verified on main, same fixture both modes:
| mode | --output json | --output junit |
|---|
--no-parallel | valid | valid |
--parallel | JSONDecodeError line 1 col 1 | ExpatError: not well-formed, line 1 col 0 |
On the console the same run prints the notice twice — once as the stray line, once as the banner the summary renders — where sequential prints it once:
bashunit - 0.49.0
No tests found <- stray, parallel only
Tests: 0 total
Assertions: 0 total
No tests found <- the real banner, both modes
This is likely to be hit: --pass-with-no-tests was added precisely because an empty selection is a routine CI state (an unpopulated shard, a --changed run that touched nothing), and CI is exactly where --output is consumed.
Same family as #1007, which fixed only the --list trigger.
💡 Cause
bashunit::state::aggregate_parallel_results (src/state/parallel.sh) enables nullglobinside its loop, for the inner *.result glob, so it does not cover the outer one:
forscript_dirin"$temp_dir_parallel_test_suite"/*;doshopt -s nullglob
When no worker ran, the temp dir is empty and the outer glob stays unexpanded, so the loop iterates once over the pattern itself. That phantom directory has no .result files, which takes the "no results" branch and prints the notice.
Guarding the loop with [ -d "$script_dir" ] || continue skips the phantom iteration and leaves the notice for a directory that genuinely produced nothing.
💡 Found by
A systematic sequential-vs---parallel sweep, since the architecture map names that disagreement as the signature of this bug class (#1145, #1147). 18 flags and 10 pathological fixtures — syntax error, failing hooks, duplicate function names, undefined and empty data providers, mid-body exit, a file with no test functions. This was the only divergence; everything else agreed.
🤔 Background
bashunit --parallel --output jsonover a selection with no tests writes a colouredNo tests foundline to stdout, ahead of the document.--outputpromises stdout is the document, so the result does not parse.Verified on
main, same fixture both modes:--output json--output junit--no-parallel--parallelOn the console the same run prints the notice twice — once as the stray line, once as the banner the summary renders — where sequential prints it once:
This is likely to be hit:
--pass-with-no-testswas added precisely because an empty selection is a routine CI state (an unpopulated shard, a--changedrun that touched nothing), and CI is exactly where--outputis consumed.Same family as #1007, which fixed only the
--listtrigger.💡 Cause
bashunit::state::aggregate_parallel_results(src/state/parallel.sh) enablesnullglobinside its loop, for the inner*.resultglob, so it does not cover the outer one:When no worker ran, the temp dir is empty and the outer glob stays unexpanded, so the loop iterates once over the pattern itself. That phantom directory has no
.resultfiles, which takes the "no results" branch and prints the notice.Guarding the loop with
[ -d "$script_dir" ] || continueskips the phantom iteration and leaves the notice for a directory that genuinely produced nothing.💡 Found by
A systematic sequential-vs-
--parallelsweep, since the architecture map names that disagreement as the signature of this bug class (#1145, #1147). 18 flags and 10 pathological fixtures — syntax error, failing hooks, duplicate function names, undefined and empty data providers, mid-bodyexit, a file with no test functions. This was the only divergence; everything else agreed.