59 lines
3.9 KiB
Markdown
59 lines
3.9 KiB
Markdown
---
|
|
name: dankvoice-bundle-swap-red-proof
|
|
description: "Prove a dankvoice behavior test is red against the pre-change bundle by pointing DV_EXT at git show HEAD:dist/index.js, with the driver extracted from the bats heredoc into a pinned scratch directory. Use before claiming a new bats assertion is red-capable."
|
|
---
|
|
|
|
Prove a new `tests/behavior.bats` assertion is **red-capable** — that it fails against the *previous* build, not just passes against the new one — without stashing, branching, or editing `src/`.
|
|
|
|
## Why
|
|
|
|
`tests/behavior.bats` is a black-box suite: the plugin bundle is loaded through `DV_EXT`, so a *different bundle* is the red side. Stashing the fix would break the `dist` byte-identity pin test and the shared worktree.
|
|
|
|
## Working recipe
|
|
|
|
```bash
|
|
cd ~/Projects/dankvoice # or the feature worktree: ~/Projects/wt-dv-*
|
|
bun run build # current src = the green side
|
|
git show HEAD:dist/index.js > /tmp/old-dist.js # the red side (pre-change bundle)
|
|
|
|
W=/tmp/dv-redproof # PINNED name; see traps below
|
|
rm -rf "$W" && mkdir -p "$W/bin"
|
|
cat > "$W/player.sh" <<'SH'
|
|
#!/usr/bin/env bash
|
|
printf '%s\n' "$*" >> "$DV_STUB_LOG"
|
|
for arg in "$@"; do case "$arg" in *.wav) cp "$arg" "$DV_COPY" ;; esac; done
|
|
sleep "${DV_HOLD:-0.1}"
|
|
SH
|
|
chmod +x "$W/player.sh"
|
|
ln -s "$W/player.sh" "$W/bin/pw-play"
|
|
printf '#!/usr/bin/env bash\nprintf "116\\talsa_output.usb-KT.0\\taudio/sink\\t*\\n"\n' > "$W/bin/wpctl"
|
|
chmod +x "$W/bin/wpctl"
|
|
# The driver lives inside the bats file as a heredoc: extract it verbatim.
|
|
end=$(grep -n '^TS$' tests/behavior.bats | cut -d: -f1)
|
|
sed -n "86,$((end - 1))p" tests/behavior.bats > "$W/driver.ts"
|
|
|
|
export DV_EXT="$PWD/dist/index.js" DV_STUB="$W/player.sh" DV_STUB_LOG="$W/player.log" \
|
|
DV_COPY="$W/played.wav" DV_OMPCONFIG=/dev/null DANKVOICE_CONFIG="$W/settings.json" \
|
|
DV_MODELS="$W/models.yml" DV_WPCTL=x DV_SELECT=""
|
|
for ext in /tmp/old-dist.js "$PWD/dist/index.js"; do
|
|
rm -f "$W/player.log" "$DANKVOICE_CONFIG"
|
|
DV_EXT="$ext" bun "$W/driver.ts" <scenario> 2>&1 | grep -E '^PLAYS|^CALLS|^NOTIFY|^SETTINGS'
|
|
done
|
|
```
|
|
|
|
The scenario name is the driver's third argv (`speak`, `auto`, `repeat`, `humanizecycle`, `badurl`, …); the bats `-f` test body's env (`DV_PLAYER_BIN`, `DV_SETTINGS_JSON`, `DANKVOICE_VERBOSITY`, …) is passed the same way. `DV_SELECT` holds the menu answers, `|`-separated, consumed in order.
|
|
|
|
## Traps, each one cost a turn
|
|
|
|
- **The scratch directory must be pinned by name.** `ls -dt /tmp/tmp.*` picks up *other sessions'* temp dirs, and then `player.sh` and `driver.ts` live in different directories — the run silently does the wrong thing.
|
|
- **The stub must append to `$DV_STUB_LOG`.** The driver counts player invocations from that file; a stub that only `sleep`s reports `PLAYS 0` for *both* bundles and the whole proof reads as "fix does nothing".
|
|
- **`DV_EXT` is required.** Missing it yields `Cannot find package 'undefined'` from the driver, which looks like a broken driver, not a missing env var.
|
|
- **`DV_SETTINGS_JSON` supports `__PORT__`** (the driver substitutes the fixture port), so a preseed can name a prefixed route — needed whenever the test is about *which* endpoint got resolved.
|
|
- **Never run this while a `bats` run is in flight** in the same repo: `setup()` runs `bun run build`, so two runs clobber `dist/` and the pin test.
|
|
|
|
## Reading the result
|
|
|
|
Red side must show the *defect* (`PLAYS 0`, `644`, a chat `CALL` with the wrong prefix, `Invalid URL`), green side the fix — assert on printed markers only (`PLAYS`, `CALLS`, `CALL <url>`, `NOTIFY`, `SETTINGS`). `CALLS` counts `/audio/speech` calls only; the rewrite call appears as its own `CALL /…/chat/completions … sys=<full system prompt>` line, which is how prompt-level knobs (verbosity, heckle) are observed.
|
|
|
|
Prefer this over a synthetic leak: if the check already caught a real leftover/failure once, that event *is* the sensitivity proof — say so in the commit message instead of faking one.
|