|
3 | 3 | ## Unreleased |
4 | 4 |
|
5 | 5 | ### Fixed |
6 | | -- `--test-timeout` no longer intermittently reports a fast test as timed out. The watchdog's process-group kill could miss when `set -m` had not made the backgrounded subshell a group leader, leaving it to sleep the full timeout and fire against an already-finished test; it is now signalled by pid directly and skips marking a test that already completed |
| 6 | +- `--test-timeout` no longer intermittently reports a fast test as timed out; the watchdog now signals by pid and skips a test that already completed |
7 | 7 |
|
8 | 8 | ### Added |
9 | | -- The `watch` subcommand no longer fails when neither `inotifywait` nor `fswatch` is installed: it degrades to a pure-shell polling loop (using `find -newer`) and prints a one-line notice instead of exiting. Polling checks every `BASHUNIT_WATCH_INTERVAL` seconds (default `2`, positive integer); created/modified `.sh` files trigger a rerun, deletions are not detected on this fallback path. Installing a watcher still gives instant, event-driven triggers (#779) |
10 | | -- Shell tab-completion scripts for bash and zsh under `completions/` — subcommands, all `test` flags (with value hints like `--jobs auto`, `--output tap`, file completion for `--env`), and assertion names after `bashunit assert`. An anti-drift CI test fails when a flag is added to the CLI but not to the scripts (#778) |
11 | | -- `--rerun-failed` (env: `BASHUNIT_RERUN_FAILED`) replays only the tests that failed on the previous run. Every run records its failing tests as `<test_file>:<function_name>` in `.bashunit/last-failed` under the working directory (a green run clears it); with the flag, discovery is restricted to those files and functions. Falls back to the full suite with a notice when the cache is empty, composes with `--filter`/`--tag` (intersection) and `--parallel`. Add `.bashunit/` to your `.gitignore` (#776) |
12 | | -- Coverage badge: an optional, nightly `coverage.yml` CI workflow dogfoods `--coverage` over the unit suite, uploads `coverage/lcov.info` as an artifact, and publishes a shields.io endpoint badge (now shown in the README) to an orphan `badges` branch — no third-party coverage service. It runs on a schedule / manual dispatch only (never on push or pull requests, so it never gates merges). The engine's own meta-tests are excluded from the measured run to avoid double-instrumenting `src/coverage.sh` (#754) |
13 | | -- `--jobs auto` (and `-j auto`) caps parallel concurrency at the detected CPU core count, portable across Linux/macOS/BSD (`nproc`, then `sysctl`, then `getconf`, falling back to 4). The default stays unlimited (`--jobs 0`) (#766) |
| 9 | +- `watch` subcommand no longer fails when neither `inotifywait` nor `fswatch` is installed — it falls back to pure-shell polling (interval via `BASHUNIT_WATCH_INTERVAL`, default `2`s) instead of exiting (#779) |
| 10 | +- Shell tab-completion scripts for bash and zsh under `completions/` (subcommands, `test` flags with value hints, assertion names), kept in sync by an anti-drift CI test (#778) |
| 11 | +- `--rerun-failed` (`BASHUNIT_RERUN_FAILED`) replays only the previously failing tests, recorded in `.bashunit/last-failed`; composes with `--filter`/`--tag`/`--parallel` and falls back to the full suite when empty (add `.bashunit/` to `.gitignore`) (#776) |
| 12 | +- Optional nightly `coverage.yml` workflow publishes a shields.io coverage badge (now in the README) from `--coverage` over the unit suite; schedule/manual only, never gates merges (#754) |
| 13 | +- `--jobs auto` / `-j auto` caps parallel concurrency at the CPU core count (portable across Linux/macOS/BSD); the default stays unlimited (#766) |
14 | 14 |
|
15 | 15 | ### Changed |
16 | | -- `assert_equals`/`assert_same` failures with multiline values now render a git word-diff below the `Expected/but got` header, making differences in command output or file contents easy to spot (the inline values are truncated to their first line while the diff is shown). Requires git; single-line failures are unchanged. Opt out with `BASHUNIT_NO_DIFF=true`, and it respects `--no-color`. Machine reports (JUnit/TAP/JSON) keep the raw values (#777) |
17 | | -- Faster test execution: `assert_match_snapshot` no longer forks on the success path. Carriage-return stripping, the test-function-name and snapshot-path resolution, and the snapshot-file read are now pure-bash (return slots + `$(<file)`), and `assert_match_snapshot_ignore_colors` only forks `sed` when the input actually contains an escape sequence. On-disk `.snapshot` files stay byte-compatible. 500 matching snapshot assertions ~7.5s -> ~3.0s on bash 3.2. No behaviour change (#775) |
18 | | -- Faster test execution with `--tag`/`--exclude-tag`: each test file's `# @tag` annotations are scanned once in a single `awk` pass and cached, replacing a per-function backward walk that forked `grep`+`sed` on every comment line (and ran twice per function). 100 tagged tests with `--tag` ~2.92s -> ~0.68s on bash 3.2. No behaviour change (#773) |
19 | | -- Faster test execution: removed the remaining `run_test` hot-path forks. Test-label normalization and the per-test clock capture use fork-free return slots (`bashunit::clock::now_to_slot` reads `EPOCHREALTIME` directly on Bash 5.0+), parallel mode is resolved once instead of re-checking env + OS on every `is_enabled` call, and the `no-parallel-tests` opt-out is detected in the existing single-pass file scan rather than a separate per-file `grep`. No behaviour change (#774) |
20 | | -- Faster test execution: removed the remaining per-assertion subshell forks. `assert_equals`/`assert_not_equals` strip ANSI via a return slot (2 fewer forks each on the success path), failure-path label resolution (`assert::label`, `fail`, `handle_bool_assertion_failure`) uses fork-free return slots, and `assert_true`/`assert_false` detect aliases with the `alias` builtin instead of `command -v | grep`. 100x10 `assert_equals` ~1.50s -> ~0.76s on bash 3.2. No behaviour change (#772) |
21 | | -- Faster test execution: removed avoidable subshell forks from the per-test hot path (runtime-error detection, subshell-output decode, name normalization, test-id generation, retry-count lookup, and the passing-test line are now fork-free), and per-test temp-file cleanup no longer forks `rm` when the test created none (`rm` 102 -> 2 on a 100-test file). No behaviour change (#764) |
22 | | -- Per-test execution time now defaults to `auto` (`BASHUNIT_SHOW_EXECUTION_TIME=true|false|auto`): shown when the shell has a fork-free clock (Bash 5.0+, GNU `date`), hidden when measuring would fork an interpreter (e.g. Bash 3.2 on macOS, which falls back to `perl`). This removes ~2 `perl` forks per test on those shells. `--profile`, `--verbose`, reports, and `=true` still measure. See `adrs/adr-008-auto-skip-per-test-timing.md` (#765) |
23 | | -- Faster test execution: each test file's data-provider annotations are scanned once and cached, replacing a per-test `grep`+`sed` probe with a pure-bash lookup (no behaviour change) (#763) |
24 | | -- Faster test execution: skip the base64 encode fork for a test's empty title, hook message and output (the common case), and short-circuit decoding of empty fields (no behaviour change) (#762) |
| 16 | +- `assert_equals`/`assert_same` failures with multiline values now render a git word-diff below the header (requires git, opt out with `BASHUNIT_NO_DIFF=true`, respects `--no-color`); machine reports keep the raw values (#777) |
| 17 | +- Faster `assert_match_snapshot`: fork-free success path, byte-compatible snapshots; 500 snapshot assertions ~7.5s -> ~3.0s on bash 3.2 (#775) |
| 18 | +- Faster `--tag`/`--exclude-tag`: per-file `# @tag` annotations scanned once and cached; 100 tagged tests ~2.92s -> ~0.68s on bash 3.2 (#773) |
| 19 | +- Faster tests: removed the remaining `run_test` hot-path forks (fork-free clock/label, parallel mode resolved once) (#774) |
| 20 | +- Faster tests: removed per-assertion subshell forks; 100x10 `assert_equals` ~1.50s -> ~0.76s on bash 3.2 (#772) |
| 21 | +- Faster tests: removed avoidable per-test forks (error detection, decoding, cleanup); `rm` 102 -> 2 on a 100-test file (#764) |
| 22 | +- Per-test timing now defaults to `auto` (`BASHUNIT_SHOW_EXECUTION_TIME=true|false|auto`): shown only when the clock is fork-free, avoiding `perl` forks on bash 3.2; `--profile`/`--verbose`/reports still measure (see `adrs/adr-008-auto-skip-per-test-timing.md`) (#765) |
| 23 | +- Faster tests: per-file data-provider annotations scanned once and cached (#763) |
| 24 | +- Faster tests: skip the base64 encode fork for a test's empty title, hook message, and output (#762) |
25 | 25 |
|
26 | 26 | ## [0.41.0](https://github.com/TypedDevs/bashunit/compare/0.40.0...0.41.0) - 2026-07-11 |
27 | 27 |
|
|
0 commit comments