ty
This commit is contained in:
parent
edce909525
commit
56d982db17
189
SPEC.md
189
SPEC.md
|
|
@ -1,189 +0,0 @@
|
|||
# shout
|
||||
|
||||
A transcript-based shell integration test runner.
|
||||
|
||||
## Format
|
||||
|
||||
A `.shout` file is a plain text transcript of a shell session. Lines starting
|
||||
with `$ ` are commands. Everything after — until the next `$` or end of file
|
||||
— is the expected output (stdout and stderr combined).
|
||||
|
||||
```
|
||||
$ dev new "add auth"
|
||||
created draft 1 "add auth"
|
||||
|
||||
$ dev save
|
||||
saved draft 1 (v1)
|
||||
```
|
||||
|
||||
Blank lines within expected output are significant. Trailing newline on the
|
||||
file is ignored.
|
||||
|
||||
### Comments
|
||||
|
||||
`#` after a command is a comment and is stripped before execution. Comments
|
||||
in expected output are matched literally.
|
||||
|
||||
```
|
||||
$ dev new "add auth" # create a draft from timeline HEAD
|
||||
created draft 1 "add auth"
|
||||
```
|
||||
|
||||
### Wildcards
|
||||
|
||||
A `...` on its own line in expected output matches any number of lines
|
||||
(including zero).
|
||||
|
||||
```
|
||||
$ dev log
|
||||
...
|
||||
draft 1 "add auth"
|
||||
```
|
||||
|
||||
A `...` inline matches any sequence of characters on that line.
|
||||
|
||||
```
|
||||
$ dev status
|
||||
draft 1 "add auth" (v...)
|
||||
```
|
||||
|
||||
### Environment
|
||||
|
||||
Each `.shout` file runs in a fresh temporary directory. The directory is
|
||||
created before the first command and removed after the last (unless
|
||||
`--keep` is passed).
|
||||
|
||||
All commands in a file run in a single shell session (`/bin/sh`), so `cd`,
|
||||
`export`, and other shell state persists between commands.
|
||||
|
||||
The following environment variables are set for every command:
|
||||
|
||||
| Variable | Value |
|
||||
|---|---|
|
||||
| `HOME` | the temp directory |
|
||||
| `PATH` | inherited from host (or prepended via `--path`) |
|
||||
| `CUE_DIR` | the temp directory |
|
||||
|
||||
All other environment variables are inherited from the host unless explicitly
|
||||
cleared with `--clean-env`.
|
||||
|
||||
### Exit codes
|
||||
|
||||
By default, a non-zero exit code fails the test regardless of output. To
|
||||
assert a specific exit code, append `[N]` on the last line of expected output:
|
||||
|
||||
```
|
||||
$ dev rm
|
||||
error: draft 1 has children. use dev rm -f to cascade.
|
||||
[1]
|
||||
```
|
||||
|
||||
`[*]` accepts any non-zero exit code without asserting the value.
|
||||
|
||||
---
|
||||
|
||||
## CLI
|
||||
|
||||
```
|
||||
shout [options] [files|dirs...]
|
||||
```
|
||||
|
||||
If no files are given, shout runs all `*.shout` files in the current directory
|
||||
and subdirectories. Each command in each shout file is run sequentially
|
||||
(unless `--parallel` is passed).
|
||||
|
||||
### Options
|
||||
|
||||
| Flag | Description |
|
||||
|---|---|
|
||||
| `--update` / `-u` | Rewrite expected output in-place with actual output |
|
||||
| `--keep` / `-k` | Keep temp directories after run (printed to stderr) |
|
||||
| `--clean-env` | Start with empty environment (only `PATH` and `CUE_DIR` set) |
|
||||
| `--path <path>` | Prepend `<path>` to `PATH` (repeatable) |
|
||||
| `--timeout <dur>` | Per-command timeout, e.g. `500ms`, `10s`, `1m` (default: `10s`) |
|
||||
| `--verbose` / `-v` | Print each command as it runs |
|
||||
| `--parallel` | Run files in parallel (implies all files run regardless of failures) |
|
||||
|
||||
### Output
|
||||
|
||||
Passing files print a single `.` per file. Failing files print a unified diff:
|
||||
|
||||
```
|
||||
FAIL tests/auth.shout
|
||||
|
||||
$ dev rm
|
||||
- error: draft 1 has children. use dev rm -f to cascade.
|
||||
+ error: draft 1 has dependents. use dev rm -f to cascade.
|
||||
[1]
|
||||
```
|
||||
|
||||
Summary line at the end:
|
||||
|
||||
```
|
||||
12 passed, 1 failed in 340ms
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Update mode
|
||||
|
||||
`--update` rewrites the expected output sections of each `.shout` file with the
|
||||
actual output from the run. Commands, comments, and whitespace are preserved.
|
||||
Wildcard lines are left in place if the actual output matches them; they are
|
||||
only replaced if the match fails.
|
||||
|
||||
This makes it safe to run `shout --update` routinely after intentional output
|
||||
changes — review the diff, commit if correct.
|
||||
|
||||
---
|
||||
|
||||
## File layout
|
||||
|
||||
```
|
||||
tests/
|
||||
auth.shout
|
||||
drafts.shout
|
||||
stack.shout
|
||||
```
|
||||
|
||||
No special directory structure is required. `.shout` files can live anywhere.
|
||||
|
||||
---
|
||||
|
||||
## Implementation notes
|
||||
|
||||
- Bun + TypeScript
|
||||
- Each file runs in a single `/bin/sh` session via `Bun.spawn`
|
||||
- Stdout and stderr merged (same as a terminal)
|
||||
- Shell state (`cd`, `export`, etc.) persists across commands within a file
|
||||
- Commands are fed to the shell sequentially; output between commands is
|
||||
captured by delimiting with sentinel `echo` statements
|
||||
- shout exits `0` if all tests pass, `1` if any fail
|
||||
|
||||
---
|
||||
|
||||
## Example
|
||||
|
||||
```
|
||||
$ dev new "add auth"
|
||||
created draft 1 "add auth"
|
||||
|
||||
$ echo 'export function auth() {}' > auth.ts
|
||||
$ dev save
|
||||
saved draft 1 (v1)
|
||||
|
||||
$ echo 'export function auth(token: string) {}' > auth.ts
|
||||
$ dev save
|
||||
saved draft 1 (v2)
|
||||
|
||||
$ dev status
|
||||
draft 1 "add auth" (v2)
|
||||
modified: (none)
|
||||
|
||||
$ dev new "add db"
|
||||
created draft 2 "add db"
|
||||
|
||||
$ dev rm 1
|
||||
error: draft 1 has children. use dev rm -f to cascade.
|
||||
[1]
|
||||
```
|
||||
Loading…
Reference in New Issue
Block a user