fix(terminal): resolve Windows custom shell executables (#487)
This commit is contained in:
@@ -13,7 +13,13 @@ vi.mock('node:os', async (importOriginal) => {
|
||||
})
|
||||
|
||||
import { resolveSidebarConfig } from '../src/config.ts'
|
||||
import { defaultShell, ensureSpawnHelper, shellDisplayName, shellSpawnArgs } from '../src/pty-manager.ts'
|
||||
import {
|
||||
defaultShell,
|
||||
ensureSpawnHelper,
|
||||
resolveShellExecutable,
|
||||
shellDisplayName,
|
||||
shellSpawnArgs,
|
||||
} from '../src/pty-manager.ts'
|
||||
|
||||
describe('pty helpers', () => {
|
||||
it('prefers an explicit shell, then SHELL, then the account login shell on POSIX', () => {
|
||||
@@ -66,6 +72,47 @@ describe('pty helpers', () => {
|
||||
expect(defaultShell({ platform: 'win32', env: {}, exists: () => false })).toBe('powershell.exe')
|
||||
})
|
||||
|
||||
it('Windows: resolves bare custom shells through PATH/PATHEXT before node-pty spawn', () => {
|
||||
const files = new Set([
|
||||
'C:/Tools/PowerShell/pwsh.exe',
|
||||
'C:/Windows/System32/cmd.exe',
|
||||
])
|
||||
const options = {
|
||||
platform: 'win32' as const,
|
||||
// Mixed-case Path/PATHEXT pins the case-insensitive environment lookup
|
||||
// that real Windows process.env provides but plain test objects do not.
|
||||
env: {
|
||||
Path: 'C:\\Tools\\PowerShell',
|
||||
PathExt: '.COM;.EXE;.BAT;.CMD',
|
||||
SystemRoot: 'C:\\Windows',
|
||||
},
|
||||
exists: (path: string) => files.has(path.replaceAll('\\', '/')),
|
||||
}
|
||||
expect(resolveShellExecutable('pwsh', options).replaceAll('\\', '/'))
|
||||
.toBe('C:/Tools/PowerShell/pwsh.exe')
|
||||
expect(resolveShellExecutable('cmd', options).replaceAll('\\', '/'))
|
||||
.toBe('C:/Windows/System32/cmd.exe')
|
||||
})
|
||||
|
||||
it('Windows: accepts .exe names and absolute paths, and names a missing configured shell', () => {
|
||||
const options = {
|
||||
platform: 'win32' as const,
|
||||
env: { PATH: 'C:\\Tools' },
|
||||
exists: (path: string) => path.replaceAll('\\', '/') === 'C:/Tools/pwsh.exe'
|
||||
|| path.replaceAll('\\', '/') === 'D:/Portable Shell/custom.exe',
|
||||
}
|
||||
expect(resolveShellExecutable('pwsh.exe', options).replaceAll('\\', '/'))
|
||||
.toBe('C:/Tools/pwsh.exe')
|
||||
expect(resolveShellExecutable('D:\\Portable Shell\\custom.exe', options).replaceAll('\\', '/'))
|
||||
.toBe('D:/Portable Shell/custom.exe')
|
||||
expect(() => resolveShellExecutable('missing-shell', options))
|
||||
.toThrow('shell executable not found: "missing-shell"')
|
||||
})
|
||||
|
||||
it('keeps POSIX bare shell resolution delegated to execvp', () => {
|
||||
expect(resolveShellExecutable(' zsh ', { platform: 'linux', env: {}, exists: () => false })).toBe('zsh')
|
||||
})
|
||||
|
||||
it('trims the configured shell and defaults it to auto for old documents', () => {
|
||||
expect(resolveSidebarConfig(undefined).shell).toBe('')
|
||||
expect(resolveSidebarConfig({ shell: ' pwsh.exe ' }).shell).toBe('pwsh.exe')
|
||||
|
||||
Reference in New Issue
Block a user