feat(smartshell): add cwd-aware execution options, structured strict-mode errors, and safer process tree termination
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
||||
import * as smartshell from '../ts/index.js';
|
||||
|
||||
const getErrorMessage = (error: unknown): string => error instanceof Error ? error.message : String(error);
|
||||
|
||||
tap.test('should handle EPIPE errors gracefully', async () => {
|
||||
const testSmartshell = new smartshell.Smartshell({
|
||||
executor: 'bash',
|
||||
@@ -40,7 +42,7 @@ tap.test('should handle strict mode with non-zero exit codes', async () => {
|
||||
await testSmartshell.execStrict('exit 42');
|
||||
} catch (error) {
|
||||
errorThrown = true;
|
||||
errorMessage = error.message;
|
||||
errorMessage = getErrorMessage(error);
|
||||
}
|
||||
|
||||
expect(errorThrown).toBeTrue();
|
||||
@@ -65,13 +67,39 @@ tap.test('should handle strict mode with signal termination', async () => {
|
||||
await result;
|
||||
} catch (error) {
|
||||
errorThrown = true;
|
||||
errorMessage = error.message;
|
||||
errorMessage = getErrorMessage(error);
|
||||
}
|
||||
|
||||
expect(errorThrown).toBeTrue();
|
||||
expect(errorMessage).toContain('terminated by signal');
|
||||
});
|
||||
|
||||
tap.test('strict mode errors should expose command result details', async () => {
|
||||
const testSmartshell = new smartshell.Smartshell({
|
||||
executor: 'bash',
|
||||
sourceFilePaths: [],
|
||||
});
|
||||
|
||||
let caughtError: smartshell.SmartshellError | null = null;
|
||||
|
||||
try {
|
||||
await testSmartshell.execSpawn('bash', ['-c', 'echo stdout-value; echo stderr-value >&2; exit 7'], {
|
||||
strict: true,
|
||||
silent: true,
|
||||
});
|
||||
} catch (error) {
|
||||
caughtError = error as smartshell.SmartshellError;
|
||||
}
|
||||
|
||||
expect(caughtError).toBeInstanceOf(smartshell.SmartshellError);
|
||||
expect(caughtError!.command).toEqual('bash');
|
||||
expect(caughtError!.exitCode).toEqual(7);
|
||||
expect(caughtError!.stdout).toContain('stdout-value');
|
||||
expect(caughtError!.combinedOutput).toContain('stderr-value');
|
||||
expect(caughtError!.stderr).toContain('stderr-value');
|
||||
expect(caughtError!.result.exitCode).toEqual(7);
|
||||
});
|
||||
|
||||
tap.test('execAndWaitForLine with timeout should reject properly', async () => {
|
||||
const testSmartshell = new smartshell.Smartshell({
|
||||
executor: 'bash',
|
||||
@@ -90,7 +118,7 @@ tap.test('execAndWaitForLine with timeout should reject properly', async () => {
|
||||
);
|
||||
} catch (error) {
|
||||
errorThrown = true;
|
||||
errorMessage = error.message;
|
||||
errorMessage = getErrorMessage(error);
|
||||
}
|
||||
|
||||
expect(errorThrown).toBeTrue();
|
||||
@@ -133,7 +161,7 @@ tap.test('should handle process ending without matching pattern', async () => {
|
||||
);
|
||||
} catch (error) {
|
||||
errorThrown = true;
|
||||
errorMessage = error.message;
|
||||
errorMessage = getErrorMessage(error);
|
||||
}
|
||||
|
||||
expect(errorThrown).toBeTrue();
|
||||
@@ -169,7 +197,7 @@ tap.test('should handle write after stream destroyed', async () => {
|
||||
await interactive.sendLine('This should fail');
|
||||
} catch (error) {
|
||||
errorThrown = true;
|
||||
expect(error.message).toContain('destroyed');
|
||||
expect(getErrorMessage(error)).toContain('destroyed');
|
||||
}
|
||||
|
||||
expect(errorThrown).toBeTrue();
|
||||
@@ -219,4 +247,4 @@ tap.test('custom environment variables should be passed correctly', async () =>
|
||||
expect(result.stdout).toContain('test_value_123');
|
||||
});
|
||||
|
||||
export default tap.start();
|
||||
export default tap.start();
|
||||
|
||||
Reference in New Issue
Block a user