From 6dee41911bd3bdac386964fa104c685b40fc02fd Mon Sep 17 00:00:00 2001 From: Chemaclass Date: Thu, 16 Jul 2026 07:29:36 +0200 Subject: [PATCH] test(snapshot): cover the placeholder matcher and normalization internals assert_match_snapshot's end-to-end paths were tested, but the internals that define snapshot semantics were not. Pin them: - normalize_actual: strips CR and trailing newlines, keeps inner blank lines - match_with_placeholder: ::ignore:: in the middle of a line, spanning multiple lines, rejecting non-matching fixed text, regex metacharacters in snapshots treated literally, and BASHUNIT_SNAPSHOT_PLACEHOLDER overrides - resolve_file: an explicit path hint is used verbatim --- tests/unit/assert_snapshot_test.sh | 73 ++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/tests/unit/assert_snapshot_test.sh b/tests/unit/assert_snapshot_test.sh index 64a77697..97e0eccc 100644 --- a/tests/unit/assert_snapshot_test.sh +++ b/tests/unit/assert_snapshot_test.sh @@ -128,3 +128,76 @@ function test_assert_snapshot_with_custom_placeholder() { export BASHUNIT_SNAPSHOT_PLACEHOLDER='__ANY__' assert_empty "$(assert_match_snapshot "Value 42" "$snapshot_path")" } + +# --- internals --------------------------------------------------------------- + +function test_snapshot_normalize_actual_strips_cr_and_trailing_newlines() { + local _snapshot_normalized + bashunit::snapshot::normalize_actual $'line1\r\nline2\r\n\n\n' + + assert_same $'line1\nline2' "$_snapshot_normalized" +} + +function test_snapshot_normalize_actual_keeps_inner_blank_lines() { + local _snapshot_normalized + bashunit::snapshot::normalize_actual $'a\n\nb\n' + + assert_same $'a\n\nb' "$_snapshot_normalized" +} + +function test_snapshot_placeholder_matches_variable_middle() { + local snapshot=$'Version: ::ignore:: (stable)' + local actual=$'Version: 1.2.3-rc4 (stable)' + + assert_successful_code "$( + bashunit::snapshot::match_with_placeholder "$actual" "$snapshot" + echo $? + )" + bashunit::snapshot::match_with_placeholder "$actual" "$snapshot" +} + +function test_snapshot_placeholder_spans_multiple_lines() { + local snapshot=$'start\n::ignore::\nend' + local actual=$'start\nanything\nat all\nend' + + bashunit::snapshot::match_with_placeholder "$actual" "$snapshot" + assert_successful_code $? +} + +function test_snapshot_placeholder_rejects_nonmatching_fixed_text() { + local snapshot=$'Version: ::ignore:: (stable)' + local actual=$'Release: 1.2.3 (stable)' + + local status=0 + bashunit::snapshot::match_with_placeholder "$actual" "$snapshot" || status=$? + assert_same 1 "$status" +} + +function test_snapshot_placeholder_escapes_regex_metacharacters() { + # Literal regex chars in the snapshot must match themselves, not act as regex. + local snapshot=$'value: [a-z]+ ::ignore::' + local actual_literal=$'value: [a-z]+ tail' + local actual_regexy=$'value: abc tail' + + bashunit::snapshot::match_with_placeholder "$actual_literal" "$snapshot" + assert_successful_code $? + + local status=0 + bashunit::snapshot::match_with_placeholder "$actual_regexy" "$snapshot" || status=$? + assert_same 1 "$status" +} + +function test_snapshot_placeholder_honours_custom_placeholder() { + local snapshot=$'id=<> done' + local actual=$'id=12345 done' + + BASHUNIT_SNAPSHOT_PLACEHOLDER="<>" \ + bashunit::snapshot::match_with_placeholder "$actual" "$snapshot" + assert_successful_code $? +} + +function test_snapshot_resolve_file_uses_explicit_hint_verbatim() { + bashunit::snapshot::resolve_file "/tmp/custom.snapshot" "test_whatever" + + assert_same "/tmp/custom.snapshot" "$_BASHUNIT_SNAPSHOT_FILE_OUT" +}