Files

2.9 KiB

name, description
name description
dankvoice-bats-serialization Run dankvoice bats suites without hangs or false failures: serialize dist rebuilds, never edit src mid-run, and rebuild before committing the tracked bundle.

Use when running the dankvoice bats tests/ suite on the shared box, when a suite run hangs or times out, or when the "committed dist is byte-identical to a fresh build" pin test fails after a commit.

The two serialization hazards

1. setup() rebuilds dist/ from src/

Every test runs cd "$REPO" && bun run build in setup(). Consequences:

  • Never edit src/ while a suite is running. The next test's setup() compiles whatever is on disk at that instant, so an in-flight edit gets attributed to the run and produces a failure with no owner. Finish the gate, then write.
  • Two suites on the same checkout race on dist/. Serialize: run one, wait for its report, then start the next. Multiple worktrees of the repo each build their own dist/ and do not collide.
  • Suite runtime is ~85 s for 55 tests; a backgrounded job with a 600 s deadline is the right shape (timeout: 600, async: true). Never poll it — setup() output lands in the conversation when the job ends.

2. dist/ is tracked, and a pin test enforces it

One test rebuilds and compares against the committed bundle. Therefore the commit order is:

bun run build          # BEFORE staging
git add -A && git commit -m '…'
bats tests/            # gate AFTER the commit

Committing src/ changes without rebuilding first fails the pin test (not ok … byte-identical to a fresh build) — the tracked bundle is the previous state. If that happens on an unpushed branch, fix it by amend rather than a follow-up commit:

bun run build && git add dist && git commit --amend --no-edit

Verify freshness any time the pin is in doubt:

bun run build >/dev/null 2>&1 && git status --porcelain dist   # empty = committed == fresh build

If a backgrounded gate job vanishes

A crash can kill the job before its report; read proc://bg_N returning "not found" means it is gone, not that it failed. Reconstruct what landed before resuming — git log --oneline -3, git status --porcelain, then the freshness check above — and rerun the suite; the commit may well have succeeded while the gate never ran.

Gotchas

  • DV_HOLD is seconds (sleep "${DV_HOLD:-0.1}"), so DV_HOLD=3 really holds the stub for three seconds.
  • Isolation tests must not count shared state: any assertion that sweeps $TMPDIR or ~/.omp/cache observes every other live session on the box (each narrating session creates dankvoice-* scratch dirs). Point TMPDIR at a private directory instead — see the cutting off mid-utterance leaves no orphaned audio behind test.
  • bun run build does not typecheck. Run bunx tsc --noEmit separately when moving code between modules; the bundler happily emits a bundle that references a deleted identifier.