✨ Improvements
bashunit doc --customlists the assertions your project defines, rendering the comment block above each one; plainbashunit docappends them as a "Custom assertions" section. Needs--boot/BASHUNIT_BOOTSTRAP, whichbashunit docnow accepts (#918)bashunit::assert_once <label> <actual>makes a composed assertion count and report once instead of once per inner step, under its own label. Opt-in, so existing totals are unchanged (#917)assert_assertion_passes,assert_assertion_failsandassert_assertion_fails_with <message>assert the verdict a custom assertion reports. The inner assertion runs isolated (counters, output and stop-on-failure guard restored), so testing a failing assertion no longer means rebuilding its expected output by hand (#916)bashunit::assert_that <expected> <actual> <cmd> [args...]writes a custom assertion in one call: it runs the command and marks the assertion passed or failed, so a forgottenreturnorbashunit::assertion_passedcan no longer drift the two counters apart (#915)bashunit::assertion_failedtakes an optional 4th argument labelling the failure block, so a custom assertion can name itself instead of showing the test name (#915)--snapshot-report-unusedlists snapshot files no test resolved, the leftovers of a rename or deletion. Reports only, never deletes; refused on partial runs (#902)--no-snapshot-create/BASHUNIT_SNAPSHOT_CREATE=falsefails on a missing snapshot instead of recording it. Recommended in CI, where a never-committed snapshot used to pass while asserting nothing (#901)--snapshot-update/BASHUNIT_SNAPSHOT_UPDATE=truere-records existing snapshots (combine with--filter); snapshots holding a placeholder are left alone (#900)bashunit::mock <cmd> <code>: a lone all-digits argument is an exit code, matchingbashunit::spy; no throwawayreturn 1helper needed (#898)assert_have_been_called_with_any <spy> <expected>: passes when any recorded call matches, not only the last one (#897)- A failed call assertion prints the calls recorded for that spy, capped at 10 with an explicit
… and N more(#896) assert_have_been_called_with_args <spy> <arg>...: compares the recorded arguments one by one, socmd "a b"no longer matchescmd a b(#894)BASHUNIT_COVERAGE_ENGINE=auto|xtrace|trap: a newxtraceengine, ~4x cheaper per captured line. Needs Bash 4.1+, soauto(the default) falls back totrapbelow that (#860)BASHUNIT_COVERAGE_SHOW_LINE_HITS=trueprints per-line execution counts in the text coverage report (#856)- Docs: an Agentic coding page, linked
llms.txt/llms-full.txt, and a drop-in agent skill at bashunit.com/bashunit-skill.md - Docs: Nix as an install option, since bashunit is in nixpkgs (
nix-shell -p bashunit,nix run nixpkgs#bashunit)
🛠️ Changes
- A failed
assert_have_been_called_with/_with_argsstates which call it compared (compared 'the last of 2 calls') (#897) - Deprecated forms warn at runtime on stderr; silence with
BASHUNIT_NO_DEPRECATION_WARNINGS=true(#866) bashunit::state::print_line/print_tap_linemoved tobashunit::console_results::*; no alias kept (#868)bashunit docand the Assertions page now cover all 71 assertions, with a quick-reference table- The
--parallelunsupported-OS warning no longer claims Alpine is excluded - Docs:
bashunit::unmockand the lifecycle of a double: automatic per-test cleanup,set_up_before_scriptdoubles, and whatunmockreaches (#899) - Docs: invalid-input handling,
BASHUNIT_REPORT_TAP/BASHUNIT_REPORT_JSON, the standalone exit code, and the optional["snapshot_file"]argument - Docs: the sidebar outline now lists
h3headings
🐛 Bug Fixes
- Failure and snapshot diffs render with
--no-ext-diff, so a configureddiff.external(difftastic) no longer blanks them (#912) - Time reads and the JUnit report pass the locale via
env; theLC_ALL=C cmdprefix segfaults inside$()on Bash 5.3 macOS (#912) - Call assertions (
assert_not_called,assert_have_been_called*) fail withwas never registered as a spyinstead of reporting zero calls when the name was never spied, so a typo no longer passes silently (#895) - The per-argument form a spy records held a literal
$'\x1f'string instead of the separator byte, so it could not be compared against (#894) --parallelno longer discards worker stderr written outside a test body; it renders as aStderr from <file>block (#864)- The minimum-bash gate compares the minor version and parses suffixed versions; the floor is unchanged at Bash 3.0+
- An empty entry in
.envno longer blanks a value the caller exported or passed on the command line (#865) - Malformed benchmark annotations (
@revs,@its,@max_ms) error instead of silently falling back, and@max_msaccepts a decimal value (#884) - An unknown option is rejected instead of being treated as a test path (#871)
--jobs,--retry,--test-timeout,--coverage-minand--outputreject invalid values;--jobs abcused to hang (#873)- A missing
--env/--bootfile errors instead of a green run that tested nothing; report paths and--seedare validated too (#875) BASHUNIT_COVERAGE_THRESHOLD_LOW/BASHUNIT_COVERAGE_THRESHOLD_HIGHvalidate as non-negative integersbashunit assert <name>with no arguments errors instead of exiting0(#877)- The exit-code assertions fail closed on a non-integer exit code, which used to count as passed
- Variadic assertions with the actual value omitted fail cleanly on Bash 3.2 under
--strict assert_arrays_equalfailing outside a test function shows its real label- Scratch directories that cannot be created under
TMPDIRabort with an actionable error - A
set_up_before_scriptthat changes directory no longer drops the remaining test files - A test path combining a glob and a space (
./bashunit "my tests/*") is no longer word-split - An unreadable or truncated parallel
.resultfile counts as a failed test instead of aborting aggregation release.shreports a failed rollback as failed- Docs: the quickstart's duration format, and the real
BASHUNIT_SHOW_EXECUTION_TIMEdefault (auto)
Removed
bin/create-pr, an unreferenced vendored copy of Chemaclass/create-pr; use the upstream tool (#867)- Dead internal helpers with no remaining callers
👥 Contributors
Checksum
SHA256: d3d8ed473f414bdbcce89e215d489646461f2dc90796d98dba42d9768036900c
Full Changelog: 0.43.0...0.44.0