Created
July 27, 2026 23:52
-
-
Save arikon/6320e04deed123d4a1042a4752c072b7 to your computer and use it in GitHub Desktop.
oh-my-codex #3328: portable BSD/GNU script(1) PTY test fixture
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| From 63cc1aa664b3c08e4ddd798fcf27c71acc4a5839 Mon Sep 17 00:00:00 2001 | |
| From: Sergey Belov <peimei@ya.ru> | |
| Date: Tue, 28 Jul 2026 01:50:38 +0200 | |
| Subject: [PATCH] test: support BSD script PTY fixtures | |
| --- | |
| src/cli/__tests__/launch-fallback.test.ts | 5 +++-- | |
| src/team/__tests__/tmux-test-fixture.test.ts | 18 +++++++++++++++++- | |
| src/team/__tests__/tmux-test-fixture.ts | 8 +++++++- | |
| 3 files changed, 27 insertions(+), 4 deletions(-) | |
| diff --git a/src/cli/__tests__/launch-fallback.test.ts b/src/cli/__tests__/launch-fallback.test.ts | |
| index 051a93ed..6b5d7ce1 100644 | |
| --- a/src/cli/__tests__/launch-fallback.test.ts | |
| +++ b/src/cli/__tests__/launch-fallback.test.ts | |
| @@ -15,7 +15,7 @@ import { | |
| writeSessionStart, | |
| type LaunchSessionBinding, | |
| } from '../../hooks/session.js'; | |
| -import { isRealTmuxAvailable, withTempTmuxSession } from '../../team/__tests__/tmux-test-fixture.js'; | |
| +import { buildPtyScriptArgs, isRealTmuxAvailable, withTempTmuxSession } from '../../team/__tests__/tmux-test-fixture.js'; | |
| const CLI_SPAWN_TIMEOUT_MS = 60_000; | |
| function buildRunOmxEnv(envOverrides: Record<string, string>): NodeJS.ProcessEnv { | |
| @@ -2714,9 +2714,10 @@ exit 0 | |
| ].map((kv) => `export ${kv}`).join('; '); | |
| const result = spawnSync( | |
| 'script', | |
| - ['-q', '-e', '-c', `${envPrefix}; cd ${JSON.stringify(wd)} && exec ${JSON.stringify(process.execPath)} ${JSON.stringify(omxBin)} --tmux ${JSON.stringify('e2e prompt')}`, '/dev/null'], | |
| + buildPtyScriptArgs(`${envPrefix}; cd ${JSON.stringify(wd)} && exec ${JSON.stringify(process.execPath)} ${JSON.stringify(omxBin)} --tmux ${JSON.stringify('e2e prompt')}`), | |
| { | |
| encoding: 'utf-8', | |
| + stdio: ['ignore', 'pipe', 'pipe'], | |
| timeout: 120_000, | |
| killSignal: 'SIGKILL', | |
| env: buildRunOmxEnv({ TMUX: '', TMUX_PANE: '' }), | |
| diff --git a/src/team/__tests__/tmux-test-fixture.test.ts b/src/team/__tests__/tmux-test-fixture.test.ts | |
| index e5d2f1c5..8c545102 100644 | |
| --- a/src/team/__tests__/tmux-test-fixture.test.ts | |
| +++ b/src/team/__tests__/tmux-test-fixture.test.ts | |
| @@ -1,7 +1,23 @@ | |
| import { execFileSync } from 'node:child_process'; | |
| import assert from 'node:assert/strict'; | |
| import { describe, it, type TestContext } from 'node:test'; | |
| -import { isRealTmuxAvailable, tmuxSessionExists, withTempTmuxSession } from './tmux-test-fixture.js'; | |
| +import { buildPtyScriptArgs, isRealTmuxAvailable, tmuxSessionExists, withTempTmuxSession } from './tmux-test-fixture.js'; | |
| + | |
| +describe('buildPtyScriptArgs', () => { | |
| + it('uses the BSD command-after-file form on macOS', () => { | |
| + assert.deepEqual( | |
| + buildPtyScriptArgs('exit 7', 'darwin'), | |
| + ['-q', '/dev/null', '/bin/sh', '-c', 'exit 7'], | |
| + ); | |
| + }); | |
| + | |
| + it('uses the util-linux command option and exit-status propagation on Linux', () => { | |
| + assert.deepEqual( | |
| + buildPtyScriptArgs('exit 7', 'linux'), | |
| + ['-q', '-e', '-c', 'exit 7', '/dev/null'], | |
| + ); | |
| + }); | |
| +}); | |
| function skipUnlessTmux(t: TestContext): void { | |
| if (!isRealTmuxAvailable()) { | |
| diff --git a/src/team/__tests__/tmux-test-fixture.ts b/src/team/__tests__/tmux-test-fixture.ts | |
| index 0fda8500..26f196ca 100644 | |
| --- a/src/team/__tests__/tmux-test-fixture.ts | |
| +++ b/src/team/__tests__/tmux-test-fixture.ts | |
| @@ -153,6 +153,12 @@ function uniqueTmuxIdentifier(prefix: string): string { | |
| return `${prefix}-${process.pid}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`; | |
| } | |
| +export function buildPtyScriptArgs(command: string, platform: NodeJS.Platform = process.platform): string[] { | |
| + return platform === 'darwin' | |
| + ? ['-q', '/dev/null', '/bin/sh', '-c', command] | |
| + : ['-q', '-e', '-c', command, '/dev/null']; | |
| +} | |
| + | |
| export async function withTempTmuxSession<T>( | |
| optionsOrFn: TempTmuxSessionOptions | ((fixture: TempTmuxSessionFixture) => Promise<T> | T), | |
| maybeFn?: (fixture: TempTmuxSessionFixture) => Promise<T> | T, | |
| @@ -207,7 +213,7 @@ export async function withTempTmuxSession<T>( | |
| throw new Error(`invalid trigger cols: ${cols}`); | |
| } | |
| const script = `(sleep 0.1; stty rows ${rows} cols ${cols}) & exec env TERM=xterm timeout 1 tmux -f ${JSON.stringify(NULL_TMUX_CONFIG)} -L ${JSON.stringify(serverName)} attach-session -t ${JSON.stringify(targetSession)}`; | |
| - const result = spawnSync('script', ['-q', '-e', '-c', script, '/dev/null'], { | |
| + const result = spawnSync('script', buildPtyScriptArgs(script), { | |
| encoding: 'utf-8', | |
| env: { ...process.env, TMUX: undefined, TMUX_PANE: undefined }, | |
| stdio: ['ignore', 'pipe', 'pipe'], | |
| -- | |
| 2.50.1 (Apple Git-155) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment