diff --git a/CHANGELOG.md b/CHANGELOG.md index 20f73ede..1df7df98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased ### Fixed +- `assert_match_snapshot` placeholders (`::ignore::`) now work on systems without perl: the grep fallback escaped its own wildcard and never matched. Placeholders spanning multiple lines still need perl (grep matches line-by-line) - Every run cleans up its run-output scratch directory on exit (test runs, `--version`/`--help`/subcommand exits, and Ctrl-C); previously each invocation leaked one directory under `$TMPDIR/bashunit/run/`. Sourcing errors are captured in that directory too, saving a `mktemp` and an `rm` fork per test file - `bashunit::helper::get_function_line_number` no longer disables `extdebug` for its caller: it enables the option only inside a subshell (also dropping an `awk` fork) - `--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 diff --git a/src/assert_snapshot.sh b/src/assert_snapshot.sh index 5b6e2a10..12f2b2d8 100644 --- a/src/assert_snapshot.sh +++ b/src/assert_snapshot.sh @@ -71,8 +71,15 @@ function bashunit::snapshot::match_with_placeholder() { exit($input =~ /$r/s ? 0 : 1); ' && return 0 || return 1 else - local fallback=$(printf '%s' "$snapshot" | sed -e "s|$placeholder|.*|g" -e 's/[][\.^$*+?{}|()]/\\&/g') - fallback="^${fallback}$" + # No perl: build the pattern exactly like the perl branch — swap the + # placeholder for a token that survives escaping, escape the regex + # metacharacters, then turn the token into `.*`. (The previous order, + # escaping after inserting `.*`, escaped the `.*` itself and broke every + # fallback match.) grep matches line-by-line, so unlike the perl branch a + # placeholder cannot span multiple lines here. + local fallback="${snapshot//$placeholder/$token}" + fallback=$(printf '%s' "$fallback" | sed -e 's/[.[\\^$*+?{}()|]/\\&/g') + fallback="^${fallback//$token/.*}$" echo "$actual" | grep -Eq "$fallback" && return 0 || return 1 fi } diff --git a/tests/unit/assert_snapshot_test.sh b/tests/unit/assert_snapshot_test.sh index 97e0eccc..cdc68a71 100644 --- a/tests/unit/assert_snapshot_test.sh +++ b/tests/unit/assert_snapshot_test.sh @@ -157,6 +157,12 @@ function test_snapshot_placeholder_matches_variable_middle() { } function test_snapshot_placeholder_spans_multiple_lines() { + # Only the perl matcher can span lines; the grep fallback (e.g. Alpine + # without perl) matches line-by-line and documents that limitation. + if ! command -v perl >/dev/null 2>&1; then + bashunit::skip "multi-line placeholders need perl" && return + fi + local snapshot=$'start\n::ignore::\nend' local actual=$'start\nanything\nat all\nend'