Skip to content

fix(doubles): assert_have_been_called_with cannot distinguish argument boundaries #894

Description

@Chemaclass

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

  • New assertion distinguishes touch "a b" from touch a b
  • Existing assert_have_been_called_with behaviour unchanged
  • Tests in tests/functional/doubles_test.sh for both directions (one arg
    with a space asserted as two args must FAIL; asserted as one arg must PASS)
  • Documented in docs/test-doubles.md, docs/public/bashunit-skill.md and
    docs/ai-agents.md
  • Bash 3.0+ compatible, make sa + make lint green

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingpure testingPure testing related

Type

No type

Projects

  • Status
    Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions