fix(pty): fix tmux absolute-path test to pass in CI#1473
Conversation
The test added in #1470 had two issues preventing it from passing: 1. process.env.PATH did not include /opt/homebrew/bin, so resolveCommandPath('tmux') never found the mocked binary and returned null — silently skipping tmux wrapping entirely. 2. vi.mock('node-pty') does not intercept dynamic require() calls inside startPty, so the real node-pty module was loaded instead of the mock. Changed to await import() which vitest can intercept. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR fixes the tmux absolute-path test that was silently broken in CI. It makes two targeted changes: (1) replaces
Confidence Score: 4/5
|
| Filename | Overview |
|---|---|
| src/main/services/ptyManager.ts | Replaces synchronous require('node-pty') with await import('node-pty') so Vitest's ESM mock interception works; also removes the now-redundant eslint-disable comment. No behavioural change in production — the import is still lazy (called at invocation time), startPty was already async, and the try/catch error path is preserved. |
| src/test/main/ptyManager.test.ts | Prepends /opt/homebrew/bin to process.env.PATH before calling startPty so resolveCommandPath('tmux') finds the mocked binary. The PATH is restored after the call, but the restore is not guarded by try/finally, so a failure in startPty would leave the PATH mutation in place for subsequent tests. |
Sequence Diagram
sequenceDiagram
participant Test as ptyManager.test.ts
participant VI as Vitest (mock engine)
participant PM as ptyManager.ts (startPty)
participant NodePty as node-pty (mocked)
Note over Test: beforeEach → vi.resetModules()<br/>clears module registry + resolvedCommandPathCache
Test->>Test: process.env.PATH = "/opt/homebrew/bin:..."
Test->>PM: await import('../../main/services/ptyManager')
Test->>PM: startPty({ id, cwd, shell, tmux:true })
PM->>PM: resolveCommandPathCached('tmux')<br/>reads process.env.PATH → finds /opt/homebrew/bin/tmux
PM->>VI: await import('node-pty')
VI-->>PM: { spawn: nodePtySpawnMock } [mock intercepted ✓]
PM->>NodePty: pty.spawn('/opt/homebrew/bin/tmux', [...], opts)
NodePty-->>PM: mockProc
PM-->>Test: IPty
Test->>Test: process.env.PATH = origPath ⚠️ not in finally
Test->>Test: expect(nodePtySpawnMock).toHaveBeenCalledWith('/opt/homebrew/bin/tmux', ...)
Comments Outside Diff (1)
-
src/test/main/ptyManager.test.ts, line 352-359 (link)PATH not restored on
startPtyfailureprocess.env.PATH = origPathis only reached whenstartPty()resolves successfully. If the call throws or rejects — e.g., a mock is misconfigured, a CI environment differs — the mutation leaks into every subsequent test in the suite. Sincevi.resetModules()only resets the module registry andresolveCommandPathreadsprocess.env.PATHdynamically at call time, a leaked/opt/homebrew/binprefix could silently affect other tests that rely on tmux-resolution or PATH-sensitive logic.Use
try/finallyto guarantee cleanup regardless of outcome, or use Vitest's built-invi.stubEnvwhich restores the original value automatically:// Option A – try/finally try { await startPty({ id: 'claude-main-task-tmux', cwd: '/tmp/task', shell: '/bin/zsh', tmux: true, }); } finally { process.env.PATH = origPath; } // Option B – vi.stubEnv (auto-restored after the test) vi.stubEnv('PATH', `/opt/homebrew/bin${process.env.PATH ? ':' + process.env.PATH : ''}`);
Last reviewed commit: 572cf02
Summary
process.env.PATHsetup in the tmux spawn test soresolveCommandPath('tmux')finds the mocked/opt/homebrew/bin/tmuxbinaryrequire('node-pty')toawait import('node-pty')instartPtyso vitest can intercept the mock (vitest does not intercept CJSrequire()calls)Test plan
pnpm exec vitest run— all 655 tests pass (including the previously failing tmux test)pnpm run type-check— cleanpnpm run lint— no new warningspnpm run format— no changes🤖 Generated with Claude Code