Files
gstack/test/helpers/run-bin.test.ts
T
Garry TanandClaude Fable 5 d87e73fa55 feat(test): shared runBin helper for bin-script unit tests
~36 free test files each carry a near-identical local run() (spawnSync
+ utf-8 + {status, stdout, stderr}) differing only in env composition,
cwd, and timeout. runBin absorbs the invariant core; options carry the
variance (gstackHome sets BOTH GSTACK_HOME and GSTACK_STATE_DIR — the
config-precedence trap several locals rediscovered independently; home
for $HOME-anchored bins; input/trim/timeout/maxBuffer). Free-test-only
by design so it never becomes a de facto global touchfile. Migration of
the 36 call sites lands separately (mechanical batches).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-29 05:12:06 +00:00

39 lines
1.3 KiB
TypeScript

import { describe, expect, test } from 'bun:test';
import * as fs from 'node:fs';
import * as os from 'node:os';
import * as path from 'node:path';
import { runBin } from './run-bin';
describe('runBin', () => {
test('captures status/stdout/stderr with utf-8 shaping', () => {
const r = runBin('sh', ['-c', 'printf out; printf err >&2; exit 3']);
expect(r).toEqual({ status: 3, stdout: 'out', stderr: 'err' });
});
test('gstackHome sets both GSTACK_HOME and GSTACK_STATE_DIR (config precedence)', () => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'run-bin-'));
try {
const r = runBin('sh', ['-c', 'printf "%s|%s" "$GSTACK_HOME" "$GSTACK_STATE_DIR"'], { gstackHome: dir });
expect(r.stdout).toBe(`${dir}|${dir}`);
} finally {
fs.rmSync(dir, { recursive: true, force: true });
}
});
test('env undefined deletes a key; input feeds stdin; trim shapes output', () => {
const r = runBin('sh', ['-c', 'cat; printf " padded "; test -z "$LANG" && printf noLANG >&2'], {
env: { LANG: undefined },
input: 'piped|',
trim: true,
});
expect(r.stdout).toBe('piped|padded');
expect(r.stderr).toBe('noLANG');
});
test('spawn failure yields -1, never a fake success', () => {
const r = runBin('/definitely/not/a/binary');
expect(r.status).toBe(-1);
});
});