1
1
import { execFileWithInput } from "../../src/exec-utils.js" ;
2
2
3
- // FYI Claude generated most of these, by dog fooding the run_command/script tools!
4
- // I am going to keep asking Claude to add new tests to see how I feel about that workflow
3
+ // FYI these tests are largely to make sure I understand how exec works
4
+ // + my changes to exec (i.e. reject promise on failure in STDIN path)
5
5
6
6
describe ( "execFileWithInput integration tests" , ( ) => {
7
- // ok, impressive choice of "seam" to add testing of the most critical part, executing the command!
8
- // this is EXACTLY what I had in mind and didn't even tell Claude I wanted.
9
7
10
8
test ( "should execute a simple bash command" , async ( ) => {
11
9
const result = await execFileWithInput (
@@ -16,6 +14,7 @@ describe("execFileWithInput integration tests", () => {
16
14
// console.log(result);
17
15
expect ( result . stdout ) . toBe ( "Hello World\n" ) ;
18
16
expect ( result . stderr ) . toBe ( "" ) ;
17
+ expect ( result . code ) . toBeUndefined ( ) ;
19
18
} ) ;
20
19
21
20
test ( "should handle command errors properly in bash" , async ( ) => {
@@ -25,8 +24,11 @@ describe("execFileWithInput integration tests", () => {
25
24
} catch ( result : any ) {
26
25
// FYI catch is so you can run assertions on the failed result, given the promise is rejected, it's then thrown here
27
26
// console.log(result);
28
- expect ( result . stderr ) . toContain ( "bash: line 1: nonexistentcommand: command not found" ) ;
29
- expect ( result . message ) . toContain ( "Command failed: bash\nbash: line 1: nonexistentcommand: command not found\n" ) ;
27
+ const expected_stderr = "bash: line 1: nonexistentcommand: command not found" ;
28
+ expect ( result . stderr ) . toContain ( expected_stderr ) ;
29
+ const expected_message = "Command failed: bash\n" + expected_stderr + "\n" ;
30
+ expect ( result . message ) . toContain ( expected_message ) ;
31
+ expect ( result . code ) . toBe ( 127 ) ;
30
32
}
31
33
} ) ;
32
34
@@ -39,6 +41,7 @@ describe("execFileWithInput integration tests", () => {
39
41
// console.log(result);
40
42
expect ( result . stdout ) . toBe ( "Hello from Fish\n" ) ;
41
43
expect ( result . stderr ) . toBe ( "" ) ;
44
+ expect ( result . code ) . toBeUndefined ( ) ;
42
45
} ) ;
43
46
44
47
// TODO make sure to cover the fish workaround logic, in all its edge cases and then can leave those tests when I remove that or just nuke them
@@ -48,8 +51,17 @@ describe("execFileWithInput integration tests", () => {
48
51
fail ( "Should have thrown an error" ) ;
49
52
} catch ( result : any ) {
50
53
// console.log(result);
51
- expect ( result . stderr ) . toContain ( "fish: Unknown command: totallynonexistentcommand\nfish: \ntotallynonexistentcommand\n^~~~~~~~~~~~~~~~~~~~~~~~^" ) ;
52
- expect ( result . message ) . toBeTruthy ( ) ;
54
+
55
+ const expected_stderr = "fish: Unknown command: totallynonexistentcommand\nfish: \ntotallynonexistentcommand\n^~~~~~~~~~~~~~~~~~~~~~~~^" ;
56
+ expect ( result . stderr ) . toContain ( expected_stderr ) ;
57
+ // TODO! this is why I don't think I should return error.message... or at least not in many cases
58
+ // OR strip off the stderr overlap?
59
+ const expected_message = 'Command failed: fish -c "echo dG90YWxseW5vbmV4aXN0ZW50Y29tbWFuZA== | base64 -d | fish"' +
60
+ "\n" + expected_stderr ;
61
+ expect ( result . message ) . toContain ( expected_message ) ;
62
+ expect ( result . code ) . toBe ( 127 ) ;
63
+ expect ( result . killed ) . toBe ( false ) ;
64
+ expect ( result . signal ) . toBeNull ( ) ;
53
65
}
54
66
} ) ;
55
67
@@ -62,6 +74,7 @@ describe("execFileWithInput integration tests", () => {
62
74
// console.log(result);
63
75
expect ( result . stdout ) . toBe ( "Hello from Zsh\n" ) ;
64
76
expect ( result . stderr ) . toBe ( "" ) ;
77
+ expect ( result . code ) . toBeUndefined ( ) ;
65
78
} ) ;
66
79
67
80
test ( "should handle command errors properly in zsh" , async ( ) => {
@@ -70,10 +83,13 @@ describe("execFileWithInput integration tests", () => {
70
83
fail ( "Should have thrown an error" ) ;
71
84
} catch ( result : any ) {
72
85
// console.log(result);
73
- // TODO why am I not reporting the exit code?! ==> 127 here (and in other cases above for missing command)
74
- expect ( result . stderr ) . toContain ( "zsh: command not found: completelynonexistentcommand" ) ;
75
- // TODO why am I bothering to return message... it seems to just duplicate STDERR?!
76
- expect ( result . message ) . toBeTruthy ( ) ;
86
+ const expected_stderr = "zsh: command not found: completelynonexistentcommand" ;
87
+ expect ( result . stderr ) . toContain ( expected_stderr ) ;
88
+ const expected_message = "Command failed: zsh\n" + expected_stderr + "\n" ;
89
+ expect ( result . message ) . toBe ( expected_message ) ;
90
+ expect ( result . code ) . toBe ( 127 ) ;
91
+ expect ( result . killed ) . toBe ( false ) ;
92
+ expect ( result . signal ) . toBeNull ( ) ;
77
93
}
78
94
} ) ;
79
95
@@ -85,15 +101,14 @@ describe("execFileWithInput integration tests", () => {
85
101
done
86
102
` ;
87
103
const result = await execFileWithInput ( "zsh" , stdin , { } ) ;
88
- //expect(lines[0]).toContain('Line 1 from Zsh');
89
- //expect(lines[1]).toContain('Number 1');
90
- //expect(lines[2]).toContain('Number 2');
91
- //expect(lines[3]).toContain('Number 3');
104
+ // console.log(result);
92
105
expect ( result . stdout ) . toContain ( `Line 1 from Zsh
93
106
Number 1
94
107
Number 2
95
108
Number 3
96
109
` ) ;
110
+ expect ( result . stderr ) . toBe ( "" ) ;
111
+ expect ( result . code ) . toBeUndefined ( ) ;
97
112
} ) ;
98
113
99
114
test ( "should respect working directory option" , async ( ) => {
@@ -102,7 +117,10 @@ Number 3
102
117
// TODO make sure cwd is not already / in the test?
103
118
// PRN use multiple paths would be another way around checking cwd of test runner
104
119
const result = await execFileWithInput ( "bash" , "pwd" , { cwd : "/" } ) ;
105
- expect ( result . stdout . trim ( ) ) . toBe ( "/" ) ;
120
+ // console.log(result);
121
+ expect ( result . stdout ) . toBe ( "/\n" ) ;
122
+ expect ( result . stderr ) . toBe ( "" ) ;
123
+ expect ( result . code ) . toBeUndefined ( ) ;
106
124
} ) ;
107
125
108
126
test ( "should handle bash multiline scripts" , async ( ) => {
@@ -113,9 +131,12 @@ Number 3
113
131
` ;
114
132
const result = await execFileWithInput ( "bash" , stdin , { } ) ;
115
133
// validate all of output:
134
+ // console.log(result);
116
135
expect ( result . stdout ) . toContain ( `Line 1
117
136
Line 2
118
137
Line 3` ) ;
138
+ expect ( result . stderr ) . toBe ( "" ) ;
139
+ expect ( result . code ) . toBeUndefined ( ) ;
119
140
} ) ;
120
141
} ) ;
121
142
0 commit comments