Context
assert_have_been_called_with compares the expected arguments against the spy's
raw field, which is "$*" — a space-joined string (src/test_doubles.sh:99,
src/test_doubles.sh:149). Argument boundaries are therefore invisible to the
assertion: one argument containing a space is indistinguishable from two
arguments.
The spy already records a boundary-preserving form. Every call writes a second
field built from printf '%q' per argument, joined with \x1f
(src/test_doubles.sh:102-106). No assertion reads it — every call
assertion discards it via IFS=$'\x1e' read -r raw _.
Evidence
This test passes today, and it should not:
function test_arg_boundaries_are_lost() {
bashunit::spy touch
touch "a b"
assert_have_been_called_with touch "a" "b" # PASSES
}
Proposal
Add an assertion that compares against the serialized field so boundaries are
respected, e.g. assert_have_been_called_with_args <spy> <arg>... (name open to
discussion), built by serializing the expected arguments the same way the spy
does and comparing the two \x1f-joined strings.
Keep assert_have_been_called_with as-is for backwards compatibility — its
space-joined semantics are documented and widely used.
Why this matters for agentic coding
An agent writing a test for a command invoked with quoted paths
(rm -f "$dir/file with space") gets a green assertion whether or not the code
under test quotes correctly. The false green is worse than no assertion: the
agent reports the behaviour as verified and moves on. Boundary-exact assertions
turn a whole class of quoting bugs — the most common defect class in shell code —
into something a test can actually catch.
Acceptance criteria
Context
assert_have_been_called_withcompares the expected arguments against the spy'srawfield, which is"$*"— a space-joined string (src/test_doubles.sh:99,src/test_doubles.sh:149). Argument boundaries are therefore invisible to theassertion: one argument containing a space is indistinguishable from two
arguments.
The spy already records a boundary-preserving form. Every call writes a second
field built from
printf '%q'per argument, joined with\x1f(
src/test_doubles.sh:102-106). No assertion reads it — every callassertion discards it via
IFS=$'\x1e' read -r raw _.Evidence
This test passes today, and it should not:
Proposal
Add an assertion that compares against the serialized field so boundaries are
respected, e.g.
assert_have_been_called_with_args <spy> <arg>...(name open todiscussion), built by serializing the expected arguments the same way the spy
does and comparing the two
\x1f-joined strings.Keep
assert_have_been_called_withas-is for backwards compatibility — itsspace-joined semantics are documented and widely used.
Why this matters for agentic coding
An agent writing a test for a command invoked with quoted paths
(
rm -f "$dir/file with space") gets a green assertion whether or not the codeunder test quotes correctly. The false green is worse than no assertion: the
agent reports the behaviour as verified and moves on. Boundary-exact assertions
turn a whole class of quoting bugs — the most common defect class in shell code —
into something a test can actually catch.
Acceptance criteria
touch "a b"fromtouch a bassert_have_been_called_withbehaviour unchangedtests/functional/doubles_test.shfor both directions (one argwith a space asserted as two args must FAIL; asserted as one arg must PASS)
docs/test-doubles.md,docs/public/bashunit-skill.mdanddocs/ai-agents.mdmake sa+make lintgreen