Repository navigation
Description
Problem
A snapshot whose value is exactly -n, -e, -E or a combination of those letters is recorded as an empty file, so the next run fails against it.
Reproduced on main 776997e9, macOS arm64, Bash 3.2.57 and Bash 5.3:
function test_snapshot_dash_n() {
assert_match_snapshot "-n"
}First run: ✎ Snapshot: Snapshot dash n, and the recorded .snapshot file is 0 bytes. Second run: ✗ Failed: Snapshot dash n. --snapshot-update writes the same empty file.
Where
src/assert/snapshot.sh:405 (bashunit::snapshot::initialize) and :434 (bashunit::snapshot::update) write the value with echo "$content". Bash's echo consumes a first argument made only of -n, -e or -E flags.
Why it matters
Snapshots capture command output verbatim; a command that prints a flag name is not unusual. The failure appears one run later with no hint about the cause, and the file looks like an empty snapshot was intended.
Suggested change
Write with printf '%s\n' "$content" in both places. The comparison side already strips trailing newlines, so existing snapshot files keep matching.
Acceptance criteria
-
assert_match_snapshot "-n"records-nand passes on the second run; the same for-eand-E. - Existing snapshot files are unaffected.
- A test covers it and fails on the current code.
Proposed fix
Replace echo "$content" >"$path" in bashunit::snapshot::initialize (src/assert/snapshot.sh:405) and echo "$actual" >"$path" in bashunit::snapshot::update (:434) with printf '%s\n' "$content" >"$path" and printf '%s\n' "$actual" >"$path". Public behaviour that must not change: the on-disk format (value plus one trailing newline), which compare reads with $(<file) and already strips. Bash 3.0: printf '%s\n' is a builtin on every version. No docs change. CHANGELOG: one line under Unreleased, Fixed.
Agent brief
- Branch:
fix/1402-snapshot-dash-valuefrom freshorigin/main. Commit:fix(assert): record a snapshot whose value is an echo flag, bodyCloses #1402. - Files:
src/assert/snapshot.sh; test intests/unit/assert/snapshot_test.sh, next totest_creates_a_snapshot(line 13), copying its temp-dir snapshot path shape. - RED first:
function test_creates_a_snapshot_whose_value_is_an_echo_flag() {
local snapshot_path="$(bashunit::temp_dir)/snapshot_test_sh.test_creates_a_snapshot_whose_value_is_an_echo_flag.snapshot"
assert_match_snapshot "-n" "$snapshot_path"
assert_same "-n" "$(cat "$snapshot_path")"
}Run only that file: ./bashunit tests/unit/assert/snapshot_test.sh.
- Non-goals: the placeholder matcher,
--snapshot-prune, and the comparison path; assert_files_equals passes when a file does not exist #1397 is separate. - Gate, once, when the change is complete:
./bashunit tests/,./bashunit --parallel --simple --strict tests/,make sa,make lint.make lintis the formatting authority; nevershfmt -w; 2-space indent. - Done when: every acceptance box is checked, the gate is green, CHANGELOG is updated, and a PR is open with the
prskill.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
Activity