Files
deepseek-harness/packages/util/native-command/tests/native-command.spec.ts
T
creatixchu 51402ac7af refactor(util): extract the shared no-shell native-command runner to dsh-native-command
master's toolcall-open extracted runNativeCommand inside apiproxy for the
openPath opener while the picker seam had moved the native chooser (its other
consumer) into directory-picker-native; after the merge the two packages each
carried a verbatim copy. The runner now lives in packages/util/native-command
(zero-dependency library, per the util-group contract) and both native
integrations depend on it.
2026-07-28 21:25:19 +08:00

44 lines
1.8 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { runNativeCommand } from '@deepseek-ai/dsh-native-command'
const node = process.execPath
describe('runNativeCommand', () => {
it('captures utf8 stdout and stderr on exit 0', async () => {
const result = await runNativeCommand(
node,
['-e', 'process.stdout.write("out✓"); process.stderr.write("err")'],
new AbortController().signal,
)
expect(result).toEqual({ stdout: 'out✓', stderr: 'err' })
})
it('rejects a non-zero exit with code, stdout, and stderr attached', async () => {
const failure = await runNativeCommand(
node,
['-e', 'process.stdout.write("partial"); process.stderr.write("boom"); process.exit(3)'],
new AbortController().signal,
).then(() => { throw new Error('unexpected resolve') }, (error: unknown) => error)
expect(failure).toMatchObject({ code: 3, stdout: 'partial', stderr: 'boom' })
expect((failure as Error).cause).toBeInstanceOf(Error)
})
it('rejects a missing executable with the spawn ENOENT code', async () => {
const failure = await runNativeCommand(
'dsh-definitely-missing-command',
[],
new AbortController().signal,
).then(() => { throw new Error('unexpected resolve') }, (error: unknown) => error)
expect(failure).toMatchObject({ code: 'ENOENT' })
})
it('terminates the child when the signal aborts', async () => {
const abort = new AbortController()
const pending = runNativeCommand(node, ['-e', 'setTimeout(() => {}, 60_000)'], abort.signal)
abort.abort()
const failure = await pending.then(() => { throw new Error('unexpected resolve') }, (error: unknown) => error)
expect(failure).toBeInstanceOf(Error)
expect((failure as { code?: unknown }).code).toBe('ABORT_ERR')
})
})