Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/bombshell-dev/playground.
Something went wrong. Try again.
2.3 kB · 62 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263import { expect, test } from 'bun:test';import { expectTerminal, withTerminalAsync } from '../src/index.ts';
test('user Control-C travels through PTY line discipline', async () => { await withTerminalAsync( { command: '/bin/sh', args: [ '-c', `trap 'printf INTERRUPTED; exit 0' INT; printf READY; while :; do sleep 1; done`, ], trace: 'off', }, async (terminal) => { await expectTerminal(terminal.getByText('READY')).toBePresent(); await terminal.keyboard.press({ key: 'c', control: true }); await expectTerminal(terminal.getByText('INTERRUPTED')).toBePresent(); expect((await terminal.process.waitForExit()).exitCode).toBe(0); }, );});
test('raw Control-C remains input while administrative signals target the OS process', async () => { await withTerminalAsync( { command: process.execPath, args: [ '-e', `process.stdin.setRawMode(true); process.stdout.write("READY"); process.stdin.once("data", data => { process.stdout.write("\\r\\nRAW:" + data.toString("hex")); setInterval(()=>{}, 1000) }); process.on("SIGTERM", () => { process.stdout.write("\\r\\nTERM"); process.exit(0) })`, ], trace: 'off', }, async (terminal) => { await expectTerminal(terminal.getByText('READY')).toBePresent(); await terminal.keyboard.press({ key: 'c', control: true }); await expectTerminal(terminal.getByText('RAW:03')).toBePresent(); expect(terminal.process.status().state).toBe('running'); await terminal.process.signal('SIGTERM', 'child'); await expectTerminal(terminal.getByText('TERM')).toBePresent(); expect((await terminal.process.waitForExit()).exitCode).toBe(0); }, );});
test('natural direct-child exit drains and then owns a PTY-holding descendant', async () => { const started = performance.now(); await withTerminalAsync( { command: '/bin/sh', args: ['-c', `node -e 'setInterval(()=>{}, 1000)' & child=$!; printf FINAL; exit 0`], cleanup: { hangupGraceMs: 10, terminateGraceMs: 10, postExitDrainMs: 50 }, trace: 'off', }, async (terminal) => { await expectTerminal(terminal.getByText('FINAL')).toBePresent(); const status = await terminal.process.waitForExit({ timeoutMs: 1_000 }); expect(status.exitCode).toBe(0); expect(status.ptyEof).toBe(true); }, ); expect(performance.now() - started).toBeLessThan(1_000);});