@zgeoff/testing
v0.3.0
Published
Drive a real program from a Bun test, in a pseudo-terminal or as a process with a ready check
Readme
Drive a real program from a Bun test: type into it in a terminal, or run it as a process and wait for it to be ready.
A test passes the program's command, a readonly string[], and gets back a handle that cleans up
after the test. The package knows nothing about how the command was found. In a repo that uses
@zgeoff/rig, resolveProgram from @zgeoff/rig/e2e supplies it.
Install
bun add -d @zgeoff/testingThe package runs under Bun and needs bun:test.
Use
An interactive program runs in a pseudo-terminal. screen reads what a person would see, and user
types:
import { spawnCLI } from '@zgeoff/testing/cli';
const cli = await spawnCLI(['bun', 'src/cli.ts', 'init']);
await cli.screen.findByText('Project name?');
await cli.user.type('ledger');
await cli.user.pressEnter();
expect(await cli.result).toBe(0);A server or a program with no terminal runs as a process in its own process group:
import { run, start } from '@zgeoff/testing/process';
const { exitCode, stdout } = await run(command, { args: ['--version'] });
await using ledger = await start(command, { ready: { url: '/health' } });
await fetch(`${ledger.url}/entries`);Small helpers for any Bun test live in @zgeoff/testing/helpers. waitFor retries a check until it
stops throwing, and updateEnv overrides an environment variable that a hook restores:
import { updateEnv, waitFor } from '@zgeoff/testing/helpers';
updateEnv('LEDGER_REGION', 'north');
await waitFor(() => expect(readEntries()).toHaveLength(2), { label: 'two entries' });Call removeEnvOverrides in an afterEach hook of the test preload, so no override outlives its
test:
import { afterEach } from 'bun:test';
import { removeEnvOverrides } from '@zgeoff/testing/helpers';
afterEach(removeEnvOverrides);Features
spawnCLIruns a program in a pseudo-terminal, withscreenqueries,userkeystrokes,resizeand OSC 8 links.runruns a program to its exit, withinputon stdin and a time limit.startpicks a free port, waits until the program is ready, and stops the whole process group.- Each handle kills its program when the test ends.
@zgeoff/testing/helpersholds the stubs, git fixtures, run-folder names,waitForand the env helpers that tests in several repos share.- An exit code is 128 plus the signal number when a signal killed the program.
Documentation
See Testing programs, and the docs index.
