Compare commits

..

No commits in common. "59246fb460960edb215184cb0e7d49d04c10fd38" and "7578b73f6331c1ed681d67e909249b31ed92b236" have entirely different histories.

2 changed files with 6 additions and 51 deletions

View File

@ -44,32 +44,6 @@ $ shout test
Each line in a `.shout` file is run sequentially, unless `--parallel` is passed.
## Directives
Directives go at the top of a `.shout` file, before any commands.
### `@env`
Set environment variables for the test:
```
@env GREETING=hello
@env TARGET=world
$ echo "$GREETING $TARGET"
hello world
```
### `@setup`
Prepend commands (and `@env` directives) from another `.shout` file:
```
@setup setup-shared.shout
```
Setup commands run first and their failures abort the test. Setup files cannot themselves contain `@setup` — no nesting. If both the setup file and the user file define the same `@env`, the user file wins.
```
Usage: shout test [options] [files...]

View File

@ -12,26 +12,8 @@ import type { TestResult } from "../format.ts"
import { parseDuration } from "../duration.ts"
import { rewriteFile } from "../update.ts"
async function filterGitignored(files: string[]): Promise<string[]> {
if (files.length === 0) return files
try {
const proc = Bun.spawn(["git", "check-ignore", "--stdin"], {
stdin: new Blob([files.join("\n")]),
stdout: "pipe",
stderr: "ignore",
})
const output = await new Response(proc.stdout).text()
await proc.exited
const ignored = new Set(output.trim().split("\n").filter(Boolean))
return files.filter(f => !ignored.has(f))
} catch {
return files
}
}
async function findShoutFiles(paths: string[]): Promise<string[]> {
const explicit: string[] = []
const discovered: string[] = []
const files: string[] = []
for (const p of paths) {
const abs = resolve(p)
@ -40,7 +22,7 @@ async function findShoutFiles(paths: string[]): Promise<string[]> {
: null
if (stat && abs.endsWith(".shout")) {
explicit.push(abs)
files.push(abs)
continue
}
@ -49,17 +31,16 @@ async function findShoutFiles(paths: string[]): Promise<string[]> {
const entries = await readdir(abs, { recursive: true })
for (const entry of entries) {
if (entry.endsWith(".shout")) {
discovered.push(resolve(abs, entry))
files.push(resolve(abs, entry))
}
}
} catch {
// If not a directory, try as file anyway
if (abs.endsWith(".shout")) explicit.push(abs)
if (abs.endsWith(".shout")) files.push(abs)
}
}
const filtered = await filterGitignored(discovered)
return [...explicit, ...filtered].sort()
return files.sort()
}
import pkg from "../../package.json"
@ -76,7 +57,7 @@ program
.option("-u, --update", "Rewrite expected output in-place with actual output")
.option("-k, --keep", "Keep temp directories after run")
.option("--clean-env", "Start with empty environment")
.option("--path <path>", "Prepend <path> to PATH (repeatable)", (val: string, acc: string[]) => [...acc, val], [])
.option("--path <path>", "Prepend <path> to PATH (repeatable)", (val: string, acc: string[]) => [...acc, val])
.option("--timeout <dur>", "Per-command timeout", "10s")
.option("-v, --verbose", "Print each command as it runs")
.option("--port-from <n>", "Auto-assign $PORT starting from <n>")