@@ -24,186 +24,249 @@ const createController = (successCondition?: SuccessCondition) =>
2424const emitFakeCloseEvent = ( command : FakeCommand , event ?: Partial < CloseEvent > ) =>
2525 command . close . next ( createFakeCloseEvent ( { ...event , command, index : command . index } ) ) ;
2626
27- describe ( 'with default success condition set' , ( ) => {
28- it ( 'succeeds if all processes exited with code 0' , ( ) => {
29- const result = createController ( ) . listen ( commands ) ;
27+ const flushPromises = ( ) => new Promise ( ( resolve ) => setTimeout ( resolve , 0 ) ) ;
28+
29+ describe ( 'listen' , ( ) => {
30+ it ( 'check for success once all commands have emitted at least a single close event' , async ( ) => {
31+ const finallyCallback = jest . fn ( ) ;
32+ const result = createController ( ) . listen ( commands ) . finally ( finallyCallback ) ;
33+
34+ // Emitting multiple close events to mimic calling command `kill/start` APIs.
35+ emitFakeCloseEvent ( commands [ 0 ] ) ;
36+ emitFakeCloseEvent ( commands [ 0 ] ) ;
37+ emitFakeCloseEvent ( commands [ 0 ] ) ;
38+
39+ scheduler . flush ( ) ;
40+ // A broken implementantion will have called finallyCallback only after flushing promises
41+ await flushPromises ( ) ;
42+ expect ( finallyCallback ) . not . toHaveBeenCalled ( ) ;
3043
31- commands [ 0 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
32- commands [ 1 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
33- commands [ 2 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
44+ emitFakeCloseEvent ( commands [ 1 ] ) ;
45+ emitFakeCloseEvent ( commands [ 2 ] ) ;
3446
3547 scheduler . flush ( ) ;
3648
37- return expect ( result ) . resolves . toEqual ( expect . anything ( ) ) ;
49+ await expect ( result ) . resolves . toEqual ( expect . anything ( ) ) ;
50+ expect ( finallyCallback ) . toHaveBeenCalled ( ) ;
3851 } ) ;
3952
40- it ( 'fails if one of the processes exited with non-0 code' , ( ) => {
53+ it ( 'takes last event emitted from each command' , async ( ) => {
4154 const result = createController ( ) . listen ( commands ) ;
4255
43- commands [ 0 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
44- commands [ 1 ] . close . next ( createFakeCloseEvent ( { exitCode : 1 } ) ) ;
45- commands [ 2 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
56+ emitFakeCloseEvent ( commands [ 0 ] , { exitCode : 0 } ) ;
57+ emitFakeCloseEvent ( commands [ 0 ] , { exitCode : 1 } ) ;
58+ emitFakeCloseEvent ( commands [ 1 ] , { exitCode : 0 } ) ;
59+ emitFakeCloseEvent ( commands [ 2 ] , { exitCode : 0 } ) ;
4660
4761 scheduler . flush ( ) ;
4862
49- return expect ( result ) . rejects . toEqual ( expect . anything ( ) ) ;
63+ await expect ( result ) . rejects . toEqual ( expect . anything ( ) ) ;
5064 } ) ;
51- } ) ;
5265
53- describe ( 'with success condition set to first' , ( ) => {
54- it ( 'succeeds if first process to exit has code 0' , ( ) => {
55- const result = createController ( 'first' ) . listen ( commands ) ;
66+ it ( 'waits for manually restarted events to close' , async ( ) => {
67+ const finallyCallback = jest . fn ( ) ;
68+ const result = createController ( ) . listen ( commands ) . finally ( finallyCallback ) ;
5669
57- commands [ 1 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
58- commands [ 0 ] . close . next ( createFakeCloseEvent ( { exitCode : 1 } ) ) ;
59- commands [ 2 ] . close . next ( createFakeCloseEvent ( { exitCode : 1 } ) ) ;
70+ emitFakeCloseEvent ( commands [ 0 ] ) ;
71+ commands [ 0 ] . state = 'started' ;
72+ emitFakeCloseEvent ( commands [ 1 ] ) ;
73+ emitFakeCloseEvent ( commands [ 2 ] ) ;
74+
75+ scheduler . flush ( ) ;
76+ // A broken implementantion will have called finallyCallback only after flushing promises
77+ await flushPromises ( ) ;
78+ expect ( finallyCallback ) . not . toHaveBeenCalled ( ) ;
6079
80+ commands [ 0 ] . state = 'exited' ;
81+ emitFakeCloseEvent ( commands [ 0 ] ) ;
6182 scheduler . flush ( ) ;
6283
63- return expect ( result ) . resolves . toEqual ( expect . anything ( ) ) ;
84+ await expect ( result ) . resolves . toEqual ( expect . anything ( ) ) ;
85+ expect ( finallyCallback ) . toHaveBeenCalled ( ) ;
6486 } ) ;
87+ } ) ;
6588
66- it ( 'fails if first process to exit has non-0 code' , ( ) => {
67- const result = createController ( 'first' ) . listen ( commands ) ;
89+ describe ( 'Detect commands exit conditions' , ( ) => {
90+ describe ( 'with default success condition set' , ( ) => {
91+ it ( 'succeeds if all processes exited with code 0' , ( ) => {
92+ const result = createController ( ) . listen ( commands ) ;
6893
69- commands [ 1 ] . close . next ( createFakeCloseEvent ( { exitCode : 1 } ) ) ;
70- commands [ 0 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
71- commands [ 2 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
94+ commands [ 0 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
95+ commands [ 1 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
96+ commands [ 2 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
7297
73- scheduler . flush ( ) ;
98+ scheduler . flush ( ) ;
7499
75- return expect ( result ) . rejects . toEqual ( expect . anything ( ) ) ;
76- } ) ;
77- } ) ;
100+ return expect ( result ) . resolves . toEqual ( expect . anything ( ) ) ;
101+ } ) ;
78102
79- describe ( 'with success condition set to last' , ( ) => {
80- it ( 'succeeds if last process to exit has code 0' , ( ) => {
81- const result = createController ( 'last' ) . listen ( commands ) ;
103+ it ( 'fails if one of the processes exited with non-0 code' , ( ) => {
104+ const result = createController ( ) . listen ( commands ) ;
82105
83- commands [ 1 ] . close . next ( createFakeCloseEvent ( { exitCode : 1 } ) ) ;
84- commands [ 0 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
85- commands [ 2 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
106+ commands [ 0 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
107+ commands [ 1 ] . close . next ( createFakeCloseEvent ( { exitCode : 1 } ) ) ;
108+ commands [ 2 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
86109
87- scheduler . flush ( ) ;
110+ scheduler . flush ( ) ;
88111
89- return expect ( result ) . resolves . toEqual ( expect . anything ( ) ) ;
112+ return expect ( result ) . rejects . toEqual ( expect . anything ( ) ) ;
113+ } ) ;
90114 } ) ;
91115
92- it ( 'fails if last process to exit has non-0 code' , ( ) => {
93- const result = createController ( 'last' ) . listen ( commands ) ;
116+ describe ( 'with success condition set to first' , ( ) => {
117+ it ( 'succeeds if first process to exit has code 0' , ( ) => {
118+ const result = createController ( 'first' ) . listen ( commands ) ;
94119
95- commands [ 1 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
96- commands [ 0 ] . close . next ( createFakeCloseEvent ( { exitCode : 1 } ) ) ;
97- commands [ 2 ] . close . next ( createFakeCloseEvent ( { exitCode : 1 } ) ) ;
120+ commands [ 1 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
121+ commands [ 0 ] . close . next ( createFakeCloseEvent ( { exitCode : 1 } ) ) ;
122+ commands [ 2 ] . close . next ( createFakeCloseEvent ( { exitCode : 1 } ) ) ;
98123
99- scheduler . flush ( ) ;
124+ scheduler . flush ( ) ;
100125
101- return expect ( result ) . rejects . toEqual ( expect . anything ( ) ) ;
102- } ) ;
103- } ) ;
126+ return expect ( result ) . resolves . toEqual ( expect . anything ( ) ) ;
127+ } ) ;
104128
105- describe . each ( [
106- // Use the middle command for both cases to make it more difficult to make a mess up
107- // in the implementation cause false passes.
108- [ 'command-bar' as const , 'bar' ] ,
109- [ 'command-1' as const , 1 ] ,
110- ] ) ( 'with success condition set to %s' , ( condition , nameOrIndex ) => {
111- it ( `succeeds if command ${ nameOrIndex } exits with code 0` , ( ) => {
112- const result = createController ( condition ) . listen ( commands ) ;
129+ it ( 'fails if first process to exit has non-0 code' , ( ) => {
130+ const result = createController ( 'first' ) . listen ( commands ) ;
113131
114- emitFakeCloseEvent ( commands [ 0 ] , { exitCode : 1 } ) ;
115- emitFakeCloseEvent ( commands [ 1 ] , { exitCode : 0 } ) ;
116- emitFakeCloseEvent ( commands [ 2 ] , { exitCode : 1 } ) ;
132+ commands [ 1 ] . close . next ( createFakeCloseEvent ( { exitCode : 1 } ) ) ;
133+ commands [ 0 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
134+ commands [ 2 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
117135
118- scheduler . flush ( ) ;
136+ scheduler . flush ( ) ;
119137
120- return expect ( result ) . resolves . toEqual ( expect . anything ( ) ) ;
138+ return expect ( result ) . rejects . toEqual ( expect . anything ( ) ) ;
139+ } ) ;
121140 } ) ;
122141
123- it ( `succeeds if all commands ${ nameOrIndex } exit with code 0` , ( ) => {
124- commands = [ commands [ 0 ] , commands [ 1 ] , commands [ 1 ] ] ;
125- const result = createController ( condition ) . listen ( commands ) ;
142+ describe ( 'with success condition set to last' , ( ) => {
143+ it ( 'succeeds if last process to exit has code 0' , ( ) => {
144+ const result = createController ( 'last' ) . listen ( commands ) ;
126145
127- emitFakeCloseEvent ( commands [ 0 ] , { exitCode : 1 } ) ;
128- emitFakeCloseEvent ( commands [ 1 ] , { exitCode : 0 } ) ;
129- emitFakeCloseEvent ( commands [ 2 ] , { exitCode : 0 } ) ;
146+ commands [ 1 ] . close . next ( createFakeCloseEvent ( { exitCode : 1 } ) ) ;
147+ commands [ 0 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
148+ commands [ 2 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
130149
131- scheduler . flush ( ) ;
150+ scheduler . flush ( ) ;
132151
133- return expect ( result ) . resolves . toEqual ( expect . anything ( ) ) ;
134- } ) ;
152+ return expect ( result ) . resolves . toEqual ( expect . anything ( ) ) ;
153+ } ) ;
135154
136- it ( ` fails if command ${ nameOrIndex } exits with non-0 code` , ( ) => {
137- const result = createController ( condition ) . listen ( commands ) ;
155+ it ( ' fails if last process to exit has non-0 code' , ( ) => {
156+ const result = createController ( 'last' ) . listen ( commands ) ;
138157
139- emitFakeCloseEvent ( commands [ 0 ] , { exitCode : 0 } ) ;
140- emitFakeCloseEvent ( commands [ 1 ] , { exitCode : 1 } ) ;
141- emitFakeCloseEvent ( commands [ 2 ] , { exitCode : 0 } ) ;
158+ commands [ 1 ] . close . next ( createFakeCloseEvent ( { exitCode : 0 } ) ) ;
159+ commands [ 0 ] . close . next ( createFakeCloseEvent ( { exitCode : 1 } ) ) ;
160+ commands [ 2 ] . close . next ( createFakeCloseEvent ( { exitCode : 1 } ) ) ;
142161
143- scheduler . flush ( ) ;
162+ scheduler . flush ( ) ;
144163
145- return expect ( result ) . rejects . toEqual ( expect . anything ( ) ) ;
164+ return expect ( result ) . rejects . toEqual ( expect . anything ( ) ) ;
165+ } ) ;
146166 } ) ;
147167
148- it ( `fails if some commands ${ nameOrIndex } exit with non-0 code` , ( ) => {
149- commands = [ commands [ 0 ] , commands [ 1 ] , commands [ 1 ] ] ;
150- const result = createController ( condition ) . listen ( commands ) ;
168+ describe . each ( [
169+ // Use the middle command for both cases to make it more difficult to make a mess up
170+ // in the implementation cause false passes.
171+ [ 'command-bar' as const , 'bar' ] ,
172+ [ 'command-1' as const , 1 ] ,
173+ ] ) ( 'with success condition set to %s' , ( condition , nameOrIndex ) => {
174+ it ( `succeeds if command ${ nameOrIndex } exits with code 0` , ( ) => {
175+ const result = createController ( condition ) . listen ( commands ) ;
151176
152- emitFakeCloseEvent ( commands [ 0 ] , { exitCode : 1 } ) ;
153- emitFakeCloseEvent ( commands [ 1 ] , { exitCode : 0 } ) ;
154- emitFakeCloseEvent ( commands [ 2 ] , { exitCode : 1 } ) ;
177+ emitFakeCloseEvent ( commands [ 0 ] , { exitCode : 1 } ) ;
178+ emitFakeCloseEvent ( commands [ 1 ] , { exitCode : 0 } ) ;
179+ emitFakeCloseEvent ( commands [ 2 ] , { exitCode : 1 } ) ;
155180
156- scheduler . flush ( ) ;
181+ scheduler . flush ( ) ;
157182
158- return expect ( result ) . resolves . toEqual ( expect . anything ( ) ) ;
159- } ) ;
183+ return expect ( result ) . resolves . toEqual ( expect . anything ( ) ) ;
184+ } ) ;
160185
161- it ( `fails if command ${ nameOrIndex } doesn't exist` , ( ) => {
162- const result = createController ( condition ) . listen ( [ commands [ 0 ] ] ) ;
186+ it ( `succeeds if all commands ${ nameOrIndex } exit with code 0` , ( ) => {
187+ commands = [ commands [ 0 ] , commands [ 1 ] , commands [ 1 ] ] ;
188+ const result = createController ( condition ) . listen ( commands ) ;
163189
164- emitFakeCloseEvent ( commands [ 0 ] , { exitCode : 0 } ) ;
165- scheduler . flush ( ) ;
190+ emitFakeCloseEvent ( commands [ 0 ] , { exitCode : 1 } ) ;
191+ emitFakeCloseEvent ( commands [ 1 ] , { exitCode : 0 } ) ;
192+ emitFakeCloseEvent ( commands [ 2 ] , { exitCode : 0 } ) ;
166193
167- return expect ( result ) . rejects . toEqual ( expect . anything ( ) ) ;
168- } ) ;
169- } ) ;
194+ scheduler . flush ( ) ;
170195
171- describe . each ( [
172- // Use the middle command for both cases to make it more difficult to make a mess up
173- // in the implementation cause false passes.
174- [ '!command-bar' as const , 'bar' ] ,
175- [ '!command-1' as const , 1 ] ,
176- ] ) ( 'with success condition set to %s' , ( condition , nameOrIndex ) => {
177- it ( `succeeds if all commands but ${ nameOrIndex } exit with code 0` , ( ) => {
178- const result = createController ( condition ) . listen ( commands ) ;
196+ return expect ( result ) . resolves . toEqual ( expect . anything ( ) ) ;
197+ } ) ;
179198
180- emitFakeCloseEvent ( commands [ 0 ] , { exitCode : 0 } ) ;
181- emitFakeCloseEvent ( commands [ 1 ] , { exitCode : 1 } ) ;
182- emitFakeCloseEvent ( commands [ 2 ] , { exitCode : 0 } ) ;
199+ it ( `fails if command ${ nameOrIndex } exits with non-0 code` , ( ) => {
200+ const result = createController ( condition ) . listen ( commands ) ;
183201
184- scheduler . flush ( ) ;
202+ emitFakeCloseEvent ( commands [ 0 ] , { exitCode : 0 } ) ;
203+ emitFakeCloseEvent ( commands [ 1 ] , { exitCode : 1 } ) ;
204+ emitFakeCloseEvent ( commands [ 2 ] , { exitCode : 0 } ) ;
185205
186- return expect ( result ) . resolves . toEqual ( expect . anything ( ) ) ;
187- } ) ;
206+ scheduler . flush ( ) ;
188207
189- it ( `fails if any commands but ${ nameOrIndex } exit with non-0 code` , ( ) => {
190- const result = createController ( condition ) . listen ( commands ) ;
208+ return expect ( result ) . rejects . toEqual ( expect . anything ( ) ) ;
209+ } ) ;
191210
192- emitFakeCloseEvent ( commands [ 0 ] , { exitCode : 1 } ) ;
193- emitFakeCloseEvent ( commands [ 1 ] , { exitCode : 1 } ) ;
194- emitFakeCloseEvent ( commands [ 2 ] , { exitCode : 0 } ) ;
211+ it ( `fails if some commands ${ nameOrIndex } exit with non-0 code` , ( ) => {
212+ const result = createController ( condition ) . listen ( commands ) ;
195213
196- scheduler . flush ( ) ;
214+ emitFakeCloseEvent ( commands [ 0 ] , { exitCode : 1 } ) ;
215+ emitFakeCloseEvent ( commands [ 1 ] , { exitCode : 0 } ) ;
216+ emitFakeCloseEvent ( commands [ 2 ] , { exitCode : 1 } ) ;
217+
218+ scheduler . flush ( ) ;
219+
220+ return expect ( result ) . resolves . toEqual ( expect . anything ( ) ) ;
221+ } ) ;
222+
223+ it ( `fails if command ${ nameOrIndex } doesn't exist` , ( ) => {
224+ const result = createController ( condition ) . listen ( [ commands [ 0 ] ] ) ;
197225
198- return expect ( result ) . rejects . toEqual ( expect . anything ( ) ) ;
226+ emitFakeCloseEvent ( commands [ 0 ] , { exitCode : 0 } ) ;
227+ scheduler . flush ( ) ;
228+
229+ return expect ( result ) . rejects . toEqual ( expect . anything ( ) ) ;
230+ } ) ;
199231 } ) ;
200232
201- it ( `succeeds if command ${ nameOrIndex } doesn't exist` , ( ) => {
202- const result = createController ( condition ) . listen ( [ commands [ 0 ] ] ) ;
233+ describe . each ( [
234+ // Use the middle command for both cases to make it more difficult to make a mess up
235+ // in the implementation cause false passes.
236+ [ '!command-bar' as const , 'bar' ] ,
237+ [ '!command-1' as const , 1 ] ,
238+ ] ) ( 'with success condition set to %s' , ( condition , nameOrIndex ) => {
239+ it ( `succeeds if all commands but ${ nameOrIndex } exit with code 0` , ( ) => {
240+ const result = createController ( condition ) . listen ( commands ) ;
203241
204- emitFakeCloseEvent ( commands [ 0 ] , { exitCode : 0 } ) ;
205- scheduler . flush ( ) ;
242+ emitFakeCloseEvent ( commands [ 0 ] , { exitCode : 0 } ) ;
243+ emitFakeCloseEvent ( commands [ 1 ] , { exitCode : 1 } ) ;
244+ emitFakeCloseEvent ( commands [ 2 ] , { exitCode : 0 } ) ;
245+
246+ scheduler . flush ( ) ;
247+
248+ return expect ( result ) . resolves . toEqual ( expect . anything ( ) ) ;
249+ } ) ;
250+
251+ it ( `fails if any commands but ${ nameOrIndex } exit with non-0 code` , ( ) => {
252+ const result = createController ( condition ) . listen ( commands ) ;
253+
254+ emitFakeCloseEvent ( commands [ 0 ] , { exitCode : 1 } ) ;
255+ emitFakeCloseEvent ( commands [ 1 ] , { exitCode : 1 } ) ;
256+ emitFakeCloseEvent ( commands [ 2 ] , { exitCode : 0 } ) ;
257+
258+ scheduler . flush ( ) ;
259+
260+ return expect ( result ) . rejects . toEqual ( expect . anything ( ) ) ;
261+ } ) ;
262+
263+ it ( `succeeds if command ${ nameOrIndex } doesn't exist` , ( ) => {
264+ const result = createController ( condition ) . listen ( [ commands [ 0 ] ] ) ;
265+
266+ emitFakeCloseEvent ( commands [ 0 ] , { exitCode : 0 } ) ;
267+ scheduler . flush ( ) ;
206268
207- return expect ( result ) . resolves . toEqual ( expect . anything ( ) ) ;
269+ return expect ( result ) . resolves . toEqual ( expect . anything ( ) ) ;
270+ } ) ;
208271 } ) ;
209272} ) ;
0 commit comments