40 lines
2.4 KiB
Markdown
40 lines
2.4 KiB
Markdown
---
|
|
name: bats-line-scoped-assert-traps
|
|
description: "When writing or reviewing bats tests over multi-line command output, catch glued-glob adjacency that hops lines, env-exec of shell functions (127), and file-wise runs that hide full-suite reds."
|
|
---
|
|
|
|
Three traps that produced false-green bats runs; check each when writing or reviewing tests that assert over multi-line `$output`.
|
|
|
|
## 1. `[[ "$output" == *"a b"* ]]` can hop lines
|
|
`$output` is multiline; a glob `*url auth=Bearer key*` matches across newline boundaries, and inserting a new column into a per-line log format silently breaks *old* adjacency pins elsewhere in the file.
|
|
|
|
Pin per-line facts with a line-scoped grep instead:
|
|
|
|
```bash
|
|
grep -Eq '/audio/speech .*auth=Bearer dk-speech' <<<"$output"
|
|
```
|
|
|
|
`grep` is line-scoped by construction: the assertion can only match within one CALL/log line. When a fixture adds a column to its log lines, grep the test suite for glued globs over those lines first (`grep -n '\[\[ "\$output" == \*' tests/`).
|
|
|
|
## 2. `run env PATH=... my_shell_function args` is always 127
|
|
`env` execs an external binary; bats test-file functions are invisible to it, and `BW01` (127) does not by itself fail the test — a following `[ "$status" -eq 0 ]` does, or worse, nothing checks it.
|
|
|
|
Inherit and extend PATH around the function call instead:
|
|
|
|
```bash
|
|
export PATH="$WORK/bothbin:$PATH"
|
|
DV_VAR=x my_function scenario
|
|
```
|
|
|
|
If a restricted PATH is truly required, write an executable wrapper script into that bin (`exec bun "$DRIVER" "$@"` with an absolute interpreter path).
|
|
|
|
## 3. File-wise green ≠ suite green
|
|
A single file (`bats tests/behavior.bats`) can pass while `bats tests/` is red (order-dependent state, shared fixtures, or simply a stale dist pin file in another file). Always run the whole gate — `bats tests/` plus unit runner (`bun test`) — on the exact final tree before opening a PR, and grep the log, never tail it:
|
|
|
|
```bash
|
|
bats tests/ > /tmp/gate.log 2>&1; echo "EXIT $?"; grep "^not ok" /tmp/gate.log; grep -c "^ok" /tmp/gate.log
|
|
```
|
|
|
|
## Verify a red is red for the stated reason
|
|
When a freshly-added test fails immediately and inexplicably fast (seconds), suspect harness-level breakage (127, missing exec) rather than product behavior — inspect with a temporary `printf '%s\n' "$output" > /tmp/dbg.txt` dump inside the test, delete it after, and reproduce the actual line format before fixing assertions.
|