3.6 KiB
3.6 KiB
shout
Transcript-based shell integration test runner. Bun + TypeScript.
Commands
bun test— run unit testsbunx tsc --noEmit— type checkbun run src/cli/index.ts test [files...]— run shout CLI-u, --update— rewrite.shoutfiles with actual output-k, --keep— keep temp directories after run--clean-env— start with empty environment--path <path>— prepend to$PATH(repeatable)--timeout <dur>— per-command timeout (default10s)-v, --verbose— print each command as it runs--port-from <n>— auto-assign$PORTstarting from n (default5400)--parallel— run files in parallel
Architecture
src/parse.ts— parses.shoutfiles intoShoutFile(list ofCommand)src/run.ts— executes commands viaBun.spawn(["/bin/sh"], { detached: true }), captures output with sentinelssrc/match.ts— wildcard-aware output matching and diff generationsrc/format.ts— evaluates pass/fail, formats failures and summarysrc/update.ts— rewrites.shoutfiles with actual output (--updatemode)src/duration.ts— parses duration strings (10s,500ms,1m)src/cli/index.ts— CLI entry point viacommandersrc/index.ts— barrel exportsweb/index.html— web documentation page
.shout file format
$prefix = command to execute- Lines between commands = expected output (stdout+stderr merged)
...on its own line = multi-line wildcard (matches zero or more lines)...inline = matches any characters on that line[N]on last line of expected output = assert exit code N[*]= assert any non-zero exit code; default expects 0$#comment line = not executed, no output expected (e.g.$# start the server)#after a command = comment (stripped);#in expected output is literal@env KEY=VALUEbefore first command = set environment variable@teardown <command>before first command = run command after all test commands- Runs regardless of pass/fail
- Teardown failures produce warnings but don't affect test results
- Can appear in both
.shoutfiles and setup files
@setup path.shoutbefore first command = prepend commands (and@env) from another file- Setup files use a plain format: each line is a command (no
$prefix),#lines are comments, blank lines ignored - Setup files can contain
@envand@teardowndirectives but not@setup(no nesting) - User file
@envoverrides setup file@env - Setup command failures abort the test with an error
- Setup files use a plain format: each line is a command (no
- Each file runs in a fresh temp dir with a single
/bin/shsession $HOMEand$SHOUT_DIRare set to the temp dir automatically$SHOUT_SOURCE_DIRis set to the directory containing the.shoutfile$SHOUT_PROJECT_DIRis set tocwdwhereshoutwas invoked- stdout and stderr are merged (
exec 2>&1)
New feature checklist
src/parse.ts— update types (Directive,ShoutFile,Command) and both parsers (parse+parseSetup)src/parse.test.ts— unit tests for parsing the new syntax in both.shoutand setup file contextssrc/cli/index.ts— wire up the parsed result inrunOne(directive resolution, command merging, result handling)test/*.shout— integration test file exercising the feature end-to-endCLAUDE.md— update.shout file formatsectionREADME.md— update Directives sectionweb/index.html— add or update a section on the website- Run
bun testandbun run src/cli/index.ts test test/to verify
Style
- Strict TypeScript, Bun runtime
- No classes — plain functions and types
- Tests in
src/*.test.ts, example.shoutfiles intest/