prool 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/_lib/exports/index.d.ts +1 -1
- package/_lib/exports/processes.d.ts +2 -0
- package/_lib/exports/processes.d.ts.map +1 -0
- package/_lib/exports/processes.js +2 -0
- package/_lib/exports/processes.js.map +1 -0
- package/_lib/instance.d.ts +4 -4
- package/_lib/instance.d.ts.map +1 -1
- package/_lib/instance.js +3 -2
- package/_lib/instance.js.map +1 -1
- package/_lib/instances/anvil.d.ts +1 -5
- package/_lib/instances/anvil.d.ts.map +1 -1
- package/_lib/instances/anvil.js +18 -44
- package/_lib/instances/anvil.js.map +1 -1
- package/_lib/instances/stackup.d.ts +86 -0
- package/_lib/instances/stackup.d.ts.map +1 -0
- package/_lib/instances/stackup.js +89 -0
- package/_lib/instances/stackup.js.map +1 -0
- package/_lib/pool.d.ts +6 -6
- package/_lib/pool.d.ts.map +1 -1
- package/_lib/pool.js +5 -2
- package/_lib/pool.js.map +1 -1
- package/_lib/processes/execa.d.ts +27 -0
- package/_lib/processes/execa.d.ts.map +1 -0
- package/_lib/processes/execa.js +63 -0
- package/_lib/processes/execa.js.map +1 -0
- package/_lib/server.d.ts +3 -3
- package/_lib/server.d.ts.map +1 -1
- package/_lib/utils.d.ts +4 -3
- package/_lib/utils.d.ts.map +1 -1
- package/_lib/utils.js +2 -2
- package/_lib/utils.js.map +1 -1
- package/exports/index.ts +2 -2
- package/exports/processes.test.ts +10 -0
- package/exports/processes.ts +8 -0
- package/instance.test.ts +2 -2
- package/instance.ts +15 -10
- package/instances/anvil.test.ts +5 -3
- package/instances/anvil.ts +21 -49
- package/instances/stackup.test.ts +106 -0
- package/instances/stackup.ts +162 -0
- package/package.json +6 -2
- package/pool.test.ts +195 -171
- package/pool.ts +18 -9
- package/processes/execa.test.ts +143 -0
- package/processes/execa.ts +100 -0
- package/server.test.ts +91 -97
- package/server.ts +4 -4
- package/tsconfig.build.tsbuildinfo +1 -1
- package/utils.ts +11 -9
package/pool.test.ts
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import getPort from 'get-port'
|
|
2
|
-
import { afterEach, describe, expect, test } from 'vitest'
|
|
2
|
+
import { afterEach, beforeAll, describe, expect, test } from 'vitest'
|
|
3
|
+
|
|
4
|
+
import { stackupOptions } from '../test/utils.js'
|
|
3
5
|
import { anvil } from './instances/anvil.js'
|
|
6
|
+
import { stackup } from './instances/stackup.js'
|
|
4
7
|
import { definePool } from './pool.js'
|
|
5
8
|
|
|
6
9
|
let pool: ReturnType<typeof definePool>
|
|
10
|
+
const port = await getPort()
|
|
11
|
+
|
|
12
|
+
beforeAll(() => anvil({ port }).start())
|
|
7
13
|
|
|
8
14
|
afterEach(async () => {
|
|
9
15
|
try {
|
|
@@ -13,238 +19,256 @@ afterEach(async () => {
|
|
|
13
19
|
}
|
|
14
20
|
})
|
|
15
21
|
|
|
16
|
-
describe.each([
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
describe.each([
|
|
23
|
+
{ instance: anvil() },
|
|
24
|
+
{
|
|
25
|
+
instance: stackup(stackupOptions({ port })),
|
|
26
|
+
},
|
|
27
|
+
])('instance: $instance.name', ({ instance }) => {
|
|
28
|
+
test('default', async () => {
|
|
29
|
+
pool = definePool({
|
|
30
|
+
instance,
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
expect(pool).toBeDefined()
|
|
34
|
+
})
|
|
23
35
|
|
|
24
|
-
|
|
36
|
+
test('start', async () => {
|
|
37
|
+
pool = definePool({
|
|
38
|
+
instance,
|
|
25
39
|
})
|
|
26
40
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
41
|
+
expect(pool.size).toEqual(0)
|
|
42
|
+
|
|
43
|
+
const instance_1 = await pool.start(1)
|
|
44
|
+
expect(instance_1.status).toBe('started')
|
|
45
|
+
expect(pool.size).toEqual(1)
|
|
46
|
+
|
|
47
|
+
const instance_2 = await pool.start(2)
|
|
48
|
+
expect(instance_2.status).toBe('started')
|
|
49
|
+
expect(pool.size).toEqual(2)
|
|
50
|
+
|
|
51
|
+
const instance_3 = await pool.start(1337)
|
|
52
|
+
expect(instance_3.status).toBe('started')
|
|
53
|
+
expect(pool.size).toEqual(3)
|
|
54
|
+
})
|
|
31
55
|
|
|
32
|
-
|
|
56
|
+
test('callback instance', async () => {
|
|
57
|
+
const keys: (number | string)[] = []
|
|
58
|
+
pool = definePool({
|
|
59
|
+
instance(key) {
|
|
60
|
+
keys.push(key)
|
|
61
|
+
return instance
|
|
62
|
+
},
|
|
63
|
+
})
|
|
33
64
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
65
|
+
await pool.start(1)
|
|
66
|
+
await pool.start(2)
|
|
67
|
+
await pool.start(1337)
|
|
37
68
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
expect(pool.size).toEqual(2)
|
|
69
|
+
expect(keys).toStrictEqual([1, 2, 1337])
|
|
70
|
+
})
|
|
41
71
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
72
|
+
test('stop / destroy', async () => {
|
|
73
|
+
pool = definePool({
|
|
74
|
+
instance,
|
|
45
75
|
})
|
|
46
76
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
})
|
|
77
|
+
const instance_1 = await pool.start(1)
|
|
78
|
+
const instance_2 = await pool.start(2)
|
|
79
|
+
const instance_3 = await pool.start(3)
|
|
51
80
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
81
|
+
expect(instance_1.status).toBe('started')
|
|
82
|
+
expect(instance_2.status).toBe('started')
|
|
83
|
+
expect(instance_3.status).toBe('started')
|
|
84
|
+
expect(pool.size).toEqual(3)
|
|
55
85
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
expect(instance_3.status).toBe('started')
|
|
59
|
-
expect(pool.size).toEqual(3)
|
|
86
|
+
await pool.stop(1)
|
|
87
|
+
expect(instance_1.status).toBe('stopped')
|
|
60
88
|
|
|
61
|
-
|
|
62
|
-
|
|
89
|
+
await pool.stop(2)
|
|
90
|
+
expect(instance_2.status).toBe('stopped')
|
|
63
91
|
|
|
64
|
-
|
|
65
|
-
|
|
92
|
+
await pool.stop(3)
|
|
93
|
+
expect(instance_3.status).toBe('stopped')
|
|
66
94
|
|
|
67
|
-
|
|
68
|
-
|
|
95
|
+
await pool.stop(1)
|
|
96
|
+
await pool.stop(2)
|
|
97
|
+
await pool.stop(3)
|
|
98
|
+
await pool.stop(4)
|
|
69
99
|
|
|
70
|
-
|
|
71
|
-
await pool.stop(2)
|
|
72
|
-
await pool.stop(3)
|
|
73
|
-
await pool.stop(4)
|
|
100
|
+
expect(pool.size).toEqual(3)
|
|
74
101
|
|
|
75
|
-
|
|
102
|
+
await pool.destroy(1)
|
|
103
|
+
expect(pool.size).toEqual(2)
|
|
104
|
+
await pool.destroy(2)
|
|
105
|
+
expect(pool.size).toEqual(1)
|
|
106
|
+
await pool.destroy(3)
|
|
107
|
+
expect(pool.size).toEqual(0)
|
|
108
|
+
})
|
|
76
109
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
expect(pool.size).toEqual(1)
|
|
81
|
-
await pool.destroy(3)
|
|
82
|
-
expect(pool.size).toEqual(0)
|
|
110
|
+
test('restart', async () => {
|
|
111
|
+
pool = definePool({
|
|
112
|
+
instance,
|
|
83
113
|
})
|
|
84
114
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
})
|
|
115
|
+
const instance_1 = await pool.start(1)
|
|
116
|
+
const instance_2 = await pool.start(2)
|
|
117
|
+
const instance_3 = await pool.start(3)
|
|
89
118
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
119
|
+
expect(instance_1.status).toBe('started')
|
|
120
|
+
expect(instance_2.status).toBe('started')
|
|
121
|
+
expect(instance_3.status).toBe('started')
|
|
122
|
+
expect(pool.size).toEqual(3)
|
|
93
123
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
124
|
+
const promise_1 = pool.restart(1)
|
|
125
|
+
expect(instance_1.status).toBe('restarting')
|
|
126
|
+
await promise_1
|
|
127
|
+
expect(instance_1.status).toBe('started')
|
|
128
|
+
})
|
|
98
129
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
expect(instance_1.status).toBe('started')
|
|
130
|
+
test('start > stop > start', async () => {
|
|
131
|
+
pool = definePool({
|
|
132
|
+
instance,
|
|
103
133
|
})
|
|
104
134
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
instance,
|
|
108
|
-
})
|
|
135
|
+
const instance_1 = await pool.start(1)
|
|
136
|
+
expect(instance_1.status).toBe('started')
|
|
109
137
|
|
|
110
|
-
|
|
111
|
-
|
|
138
|
+
await pool.stop(1)
|
|
139
|
+
expect(instance_1.status).toBe('stopped')
|
|
112
140
|
|
|
113
|
-
|
|
114
|
-
|
|
141
|
+
await pool.start(1)
|
|
142
|
+
expect(instance_1.status).toBe('started')
|
|
143
|
+
})
|
|
115
144
|
|
|
116
|
-
|
|
117
|
-
|
|
145
|
+
test('stopAll / destroyAll', async () => {
|
|
146
|
+
pool = definePool({
|
|
147
|
+
instance,
|
|
118
148
|
})
|
|
119
149
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
})
|
|
150
|
+
await pool.start(1)
|
|
151
|
+
await pool.start(2)
|
|
152
|
+
await pool.start(3)
|
|
124
153
|
|
|
125
|
-
|
|
126
|
-
await pool.start(2)
|
|
127
|
-
await pool.start(3)
|
|
154
|
+
expect(pool.size).toEqual(3)
|
|
128
155
|
|
|
129
|
-
|
|
156
|
+
await pool.stopAll()
|
|
157
|
+
expect(pool.size).toEqual(3)
|
|
130
158
|
|
|
131
|
-
|
|
132
|
-
|
|
159
|
+
await pool.destroyAll()
|
|
160
|
+
expect(pool.size).toEqual(0)
|
|
161
|
+
})
|
|
133
162
|
|
|
134
|
-
|
|
135
|
-
|
|
163
|
+
test('get', async () => {
|
|
164
|
+
pool = definePool({
|
|
165
|
+
instance,
|
|
136
166
|
})
|
|
137
167
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
})
|
|
168
|
+
const instance_1 = await pool.start(1)
|
|
169
|
+
const instance_2 = await pool.start(2)
|
|
170
|
+
const instance_3 = await pool.start(3)
|
|
142
171
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
172
|
+
expect(pool.get(1)).toStrictEqual(instance_1)
|
|
173
|
+
expect(pool.get(2)).toStrictEqual(instance_2)
|
|
174
|
+
expect(pool.get(3)).toStrictEqual(instance_3)
|
|
175
|
+
})
|
|
146
176
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
177
|
+
test('behavior: start more than once', async () => {
|
|
178
|
+
pool = definePool({
|
|
179
|
+
instance,
|
|
150
180
|
})
|
|
151
181
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
})
|
|
182
|
+
const promise_1 = pool.start(1)
|
|
183
|
+
const promise_2 = pool.start(1)
|
|
184
|
+
expect(promise_1).toStrictEqual(promise_2)
|
|
156
185
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
186
|
+
const instance_1 = await promise_1
|
|
187
|
+
const instance_2 = await promise_2
|
|
188
|
+
expect(instance_1).toStrictEqual(instance_2)
|
|
189
|
+
})
|
|
160
190
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
191
|
+
test('behavior: clear more than once', async () => {
|
|
192
|
+
pool = definePool({
|
|
193
|
+
instance,
|
|
164
194
|
})
|
|
165
195
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
})
|
|
196
|
+
await pool.start(1)
|
|
197
|
+
await pool.start(2)
|
|
198
|
+
await pool.start(3)
|
|
170
199
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
200
|
+
const promise_1 = pool.stopAll()
|
|
201
|
+
const promise_2 = pool.stopAll()
|
|
202
|
+
expect(promise_1).toStrictEqual(promise_2)
|
|
174
203
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
204
|
+
await promise_1
|
|
205
|
+
await promise_2
|
|
206
|
+
})
|
|
178
207
|
|
|
179
|
-
|
|
180
|
-
|
|
208
|
+
test('behavior: restart more than once', async () => {
|
|
209
|
+
pool = definePool({
|
|
210
|
+
instance,
|
|
181
211
|
})
|
|
182
212
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
instance,
|
|
186
|
-
})
|
|
213
|
+
const instance_1 = await pool.start(1)
|
|
214
|
+
expect(instance_1.status).toBe('started')
|
|
187
215
|
|
|
188
|
-
|
|
189
|
-
|
|
216
|
+
const promise_1 = pool.restart(1)
|
|
217
|
+
expect(instance_1.status).toBe('restarting')
|
|
218
|
+
const promise_2 = pool.restart(1)
|
|
219
|
+
expect(instance_1.status).toBe('restarting')
|
|
190
220
|
|
|
191
|
-
|
|
192
|
-
expect(instance_1.status).toBe('restarting')
|
|
193
|
-
const promise_2 = pool.restart(1)
|
|
194
|
-
expect(instance_1.status).toBe('restarting')
|
|
221
|
+
expect(promise_1).toStrictEqual(promise_2)
|
|
195
222
|
|
|
196
|
-
|
|
223
|
+
await promise_1
|
|
224
|
+
expect(instance_1.status).toBe('started')
|
|
225
|
+
await promise_2
|
|
226
|
+
expect(instance_1.status).toBe('started')
|
|
227
|
+
})
|
|
197
228
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
expect(instance_1.status).toBe('started')
|
|
229
|
+
test('behavior: stop more than once', async () => {
|
|
230
|
+
pool = definePool({
|
|
231
|
+
instance,
|
|
202
232
|
})
|
|
203
233
|
|
|
204
|
-
|
|
205
|
-
pool = definePool({
|
|
206
|
-
instance,
|
|
207
|
-
})
|
|
234
|
+
await pool.start(1)
|
|
208
235
|
|
|
209
|
-
|
|
236
|
+
const promise_1 = pool.stop(1)
|
|
237
|
+
const promise_2 = pool.stop(1)
|
|
238
|
+
expect(promise_1).toStrictEqual(promise_2)
|
|
210
239
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
240
|
+
await promise_1
|
|
241
|
+
await promise_2
|
|
242
|
+
})
|
|
214
243
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
})
|
|
244
|
+
test('error: start more than once on same port', async () => {
|
|
245
|
+
const port = await getPort()
|
|
218
246
|
|
|
219
|
-
|
|
220
|
-
|
|
247
|
+
pool = definePool({
|
|
248
|
+
instance,
|
|
249
|
+
})
|
|
221
250
|
|
|
222
|
-
|
|
223
|
-
instance,
|
|
224
|
-
})
|
|
251
|
+
await pool.start(1, { port })
|
|
225
252
|
|
|
226
|
-
|
|
253
|
+
const promise_1 = pool.start(2, { port })
|
|
254
|
+
const promise_2 = pool.start(2, { port })
|
|
255
|
+
expect(promise_1).toStrictEqual(promise_2)
|
|
227
256
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
257
|
+
await expect(() => promise_1).rejects.toThrowError()
|
|
258
|
+
await expect(() => promise_2).rejects.toThrowError()
|
|
259
|
+
})
|
|
231
260
|
|
|
232
|
-
|
|
233
|
-
|
|
261
|
+
test('error: instance limit reached', async () => {
|
|
262
|
+
pool = definePool({
|
|
263
|
+
instance,
|
|
264
|
+
limit: 2,
|
|
234
265
|
})
|
|
235
266
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
instance,
|
|
239
|
-
limit: 2,
|
|
240
|
-
})
|
|
267
|
+
await pool.start(1)
|
|
268
|
+
await pool.start(2)
|
|
241
269
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
)
|
|
248
|
-
})
|
|
249
|
-
},
|
|
250
|
-
)
|
|
270
|
+
await expect(() => pool.start(3)).rejects.toThrowError(
|
|
271
|
+
'Instance limit of 2 reached.',
|
|
272
|
+
)
|
|
273
|
+
})
|
|
274
|
+
})
|
package/pool.ts
CHANGED
|
@@ -4,12 +4,12 @@ import type { Instance } from './instance.js'
|
|
|
4
4
|
|
|
5
5
|
type Instance_ = Omit<Instance, 'create'>
|
|
6
6
|
|
|
7
|
-
export type Pool<key = number> = Pick<
|
|
7
|
+
export type Pool<key extends number | string = number | string> = Pick<
|
|
8
8
|
Map<key, Instance_>,
|
|
9
9
|
'entries' | 'keys' | 'forEach' | 'get' | 'has' | 'size' | 'values'
|
|
10
10
|
> & {
|
|
11
11
|
_internal: {
|
|
12
|
-
instance: Instance_
|
|
12
|
+
instance: Instance_ | ((key: key) => Instance_)
|
|
13
13
|
}
|
|
14
14
|
destroy(key: key): Promise<void>
|
|
15
15
|
destroyAll(): Promise<void>
|
|
@@ -19,14 +19,18 @@ export type Pool<key = number> = Pick<
|
|
|
19
19
|
stopAll(): Promise<void>
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export type DefinePoolParameters
|
|
22
|
+
export type DefinePoolParameters<
|
|
23
|
+
key extends number | string = number | string,
|
|
24
|
+
> = {
|
|
23
25
|
/** Instance for the pool. */
|
|
24
|
-
instance: Instance
|
|
26
|
+
instance: Instance | ((key: key) => Instance)
|
|
25
27
|
/** The maximum number of instances that can be started. */
|
|
26
28
|
limit?: number | number
|
|
27
29
|
}
|
|
28
30
|
|
|
29
|
-
export type DefinePoolReturnType<
|
|
31
|
+
export type DefinePoolReturnType<
|
|
32
|
+
key extends number | string = number | string,
|
|
33
|
+
> = Pool<key>
|
|
30
34
|
|
|
31
35
|
/**
|
|
32
36
|
* Defines an instance pool. Instances can be started, cached, and stopped against an identifier.
|
|
@@ -42,10 +46,10 @@ export type DefinePoolReturnType<key = number> = Pool<key>
|
|
|
42
46
|
* const instance_3 = await pool.start(3)
|
|
43
47
|
* ```
|
|
44
48
|
*/
|
|
45
|
-
export function definePool<key = number>(
|
|
46
|
-
parameters: DefinePoolParameters
|
|
49
|
+
export function definePool<key extends number | string = number>(
|
|
50
|
+
parameters: DefinePoolParameters<key>,
|
|
47
51
|
): DefinePoolReturnType<key> {
|
|
48
|
-
const {
|
|
52
|
+
const { limit } = parameters
|
|
49
53
|
|
|
50
54
|
type Instance_ = Omit<Instance, 'create'>
|
|
51
55
|
const instances = new Map<key, Instance_>()
|
|
@@ -65,7 +69,7 @@ export function definePool<key = number>(
|
|
|
65
69
|
|
|
66
70
|
return {
|
|
67
71
|
_internal: {
|
|
68
|
-
instance,
|
|
72
|
+
instance: parameters.instance,
|
|
69
73
|
},
|
|
70
74
|
async destroy(key) {
|
|
71
75
|
const destroyPromise = promises.destroy.get(key)
|
|
@@ -130,7 +134,12 @@ export function definePool<key = number>(
|
|
|
130
134
|
|
|
131
135
|
promises.start.set(key, resolver.promise)
|
|
132
136
|
|
|
137
|
+
const instance =
|
|
138
|
+
typeof parameters.instance === 'function'
|
|
139
|
+
? parameters.instance(key)
|
|
140
|
+
: parameters.instance
|
|
133
141
|
const { port = await getPort() } = options
|
|
142
|
+
|
|
134
143
|
const instance_ = instances.get(key) || instance.create({ port })
|
|
135
144
|
instance_
|
|
136
145
|
.start()
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { EventEmitter } from 'eventemitter3'
|
|
2
|
+
import { afterEach, expect, test } from 'vitest'
|
|
3
|
+
import { type ExecaProcess, execa } from './execa.js'
|
|
4
|
+
|
|
5
|
+
const processes: ExecaProcess[] = []
|
|
6
|
+
function createProcess() {
|
|
7
|
+
const process = execa({ name: 'foo' })
|
|
8
|
+
processes.push(process)
|
|
9
|
+
return process
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
afterEach(async () => {
|
|
13
|
+
for (const process of processes) await process.stop().catch(() => {})
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
test('default', async () => {
|
|
17
|
+
const process = createProcess()
|
|
18
|
+
expect(process).toMatchInlineSnapshot(`
|
|
19
|
+
{
|
|
20
|
+
"_internal": {
|
|
21
|
+
"process": undefined,
|
|
22
|
+
},
|
|
23
|
+
"name": "foo",
|
|
24
|
+
"start": [Function],
|
|
25
|
+
"stop": [Function],
|
|
26
|
+
}
|
|
27
|
+
`)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
test('start', async () => {
|
|
31
|
+
const emitter = new EventEmitter<any>()
|
|
32
|
+
const process = createProcess()
|
|
33
|
+
|
|
34
|
+
const resolvers = {
|
|
35
|
+
listening: Promise.withResolvers<void>(),
|
|
36
|
+
message: Promise.withResolvers<void>(),
|
|
37
|
+
stdout: Promise.withResolvers<void>(),
|
|
38
|
+
}
|
|
39
|
+
emitter.on('listening', resolvers.listening.resolve)
|
|
40
|
+
emitter.on('message', resolvers.message.resolve)
|
|
41
|
+
emitter.on('stdout', resolvers.stdout.resolve)
|
|
42
|
+
|
|
43
|
+
await process.start(($) => $`anvil --port 1337`, {
|
|
44
|
+
emitter,
|
|
45
|
+
status: 'idle',
|
|
46
|
+
resolver({ process, resolve }) {
|
|
47
|
+
process.stdout.on('data', (data) => {
|
|
48
|
+
const message = data.toString()
|
|
49
|
+
if (message.includes('Listening on')) resolve()
|
|
50
|
+
})
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
expect(process._internal.process).toBeDefined()
|
|
54
|
+
await expect(resolvers.listening.promise).resolves.toBeUndefined()
|
|
55
|
+
await expect(resolvers.message.promise).resolves.toBeDefined()
|
|
56
|
+
await expect(resolvers.stdout.promise).resolves.toBeDefined()
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
test('start (error)', async () => {
|
|
60
|
+
const emitter = new EventEmitter<any>()
|
|
61
|
+
const process = createProcess()
|
|
62
|
+
|
|
63
|
+
const resolvers = {
|
|
64
|
+
listening: Promise.withResolvers<void>(),
|
|
65
|
+
message: Promise.withResolvers<void>(),
|
|
66
|
+
stderr: Promise.withResolvers<void>(),
|
|
67
|
+
}
|
|
68
|
+
emitter.on('listening', resolvers.listening.resolve)
|
|
69
|
+
emitter.on('message', resolvers.message.resolve)
|
|
70
|
+
emitter.on('stderr', resolvers.stderr.resolve)
|
|
71
|
+
|
|
72
|
+
// Invalid argument
|
|
73
|
+
await expect(() =>
|
|
74
|
+
process.start(($) => $`anvil --lol`, {
|
|
75
|
+
emitter,
|
|
76
|
+
status: 'idle',
|
|
77
|
+
resolver({ process, reject, resolve }) {
|
|
78
|
+
process.stdout.on('data', (data) => {
|
|
79
|
+
const message = data.toString()
|
|
80
|
+
if (message.includes('Listening on')) resolve()
|
|
81
|
+
})
|
|
82
|
+
process.stderr.on('data', reject)
|
|
83
|
+
},
|
|
84
|
+
}),
|
|
85
|
+
).rejects.toThrowErrorMatchingInlineSnapshot(`
|
|
86
|
+
[Error: Failed to start process "foo": error: unexpected argument '--lol' found
|
|
87
|
+
|
|
88
|
+
Usage: anvil [OPTIONS] [COMMAND]
|
|
89
|
+
|
|
90
|
+
For more information, try '--help'.
|
|
91
|
+
]
|
|
92
|
+
`)
|
|
93
|
+
await expect(resolvers.message.promise).resolves.toBeDefined()
|
|
94
|
+
await expect(resolvers.stderr.promise).resolves.toBeDefined()
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
test('behavior: exit', async () => {
|
|
98
|
+
const emitter = new EventEmitter<any>()
|
|
99
|
+
const process = createProcess()
|
|
100
|
+
|
|
101
|
+
const resolvers = {
|
|
102
|
+
exit: Promise.withResolvers<void>(),
|
|
103
|
+
}
|
|
104
|
+
emitter.on('exit', resolvers.exit.resolve)
|
|
105
|
+
|
|
106
|
+
// Invalid argument
|
|
107
|
+
await process.start(($) => $`anvil --port 1338`, {
|
|
108
|
+
emitter,
|
|
109
|
+
status: 'idle',
|
|
110
|
+
resolver({ process, resolve }) {
|
|
111
|
+
process.stdout.on('data', (data) => {
|
|
112
|
+
const message = data.toString()
|
|
113
|
+
if (message.includes('Listening on')) resolve()
|
|
114
|
+
})
|
|
115
|
+
},
|
|
116
|
+
})
|
|
117
|
+
process._internal.process.kill()
|
|
118
|
+
await expect(resolvers.exit.promise).resolves.toBeDefined()
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
test('behavior: exit when status is starting', async () => {
|
|
122
|
+
const emitter = new EventEmitter<any>()
|
|
123
|
+
const process = createProcess()
|
|
124
|
+
|
|
125
|
+
const resolvers = {
|
|
126
|
+
exit: Promise.withResolvers<void>(),
|
|
127
|
+
}
|
|
128
|
+
emitter.on('exit', resolvers.exit.resolve)
|
|
129
|
+
|
|
130
|
+
// Invalid argument
|
|
131
|
+
await process.start(($) => $`anvil`, {
|
|
132
|
+
emitter,
|
|
133
|
+
status: 'starting',
|
|
134
|
+
resolver({ process, resolve }) {
|
|
135
|
+
process.stdout.on('data', (data) => {
|
|
136
|
+
const message = data.toString()
|
|
137
|
+
if (message.includes('Listening on')) resolve()
|
|
138
|
+
})
|
|
139
|
+
},
|
|
140
|
+
})
|
|
141
|
+
process._internal.process.kill()
|
|
142
|
+
await expect(resolvers.exit.promise).resolves.toBeDefined()
|
|
143
|
+
})
|