Skip to content

Commit 62dfcc9

Browse files
authored
chore: replace until test helper with a continuous (#9156)
1 parent 17f6fb7 commit 62dfcc9

File tree

2 files changed

+84
-31
lines changed

2 files changed

+84
-31
lines changed

e2e/__tests__/detectOpenHandles.ts

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import {wrap} from 'jest-snapshot-serializer-raw';
99
import {onNodeVersions} from '@jest/test-utils';
10-
import runJest, {until} from '../runJest';
10+
import runJest, {runContinuous} from '../runJest';
1111

1212
try {
1313
require('async_hooks');
@@ -27,33 +27,34 @@ function getTextAfterTest(stderr: string) {
2727
}
2828

2929
it('prints message about flag on slow tests', async () => {
30-
const {stderr} = await until(
31-
'detect-open-handles',
32-
['outside'],
33-
'Jest did not exit one second after the test run has completed.',
30+
const run = runContinuous('detect-open-handles', ['outside']);
31+
await run.waitUntil(({stderr}) =>
32+
stderr.includes(
33+
'Jest did not exit one second after the test run has completed.',
34+
),
3435
);
36+
const {stderr} = await run.end();
3537
const textAfterTest = getTextAfterTest(stderr);
3638

3739
expect(wrap(textAfterTest)).toMatchSnapshot();
3840
});
3941

4042
it('prints message about flag on forceExit', async () => {
41-
const {stderr} = await until(
42-
'detect-open-handles',
43-
['outside', '--forceExit'],
44-
'Force exiting Jest',
45-
);
43+
const run = runContinuous('detect-open-handles', ['outside', '--forceExit']);
44+
await run.waitUntil(({stderr}) => stderr.includes('Force exiting Jest'));
45+
const {stderr} = await run.end();
4646
const textAfterTest = getTextAfterTest(stderr);
4747

4848
expect(wrap(textAfterTest)).toMatchSnapshot();
4949
});
5050

5151
it('prints out info about open handlers', async () => {
52-
const {stderr} = await until(
53-
'detect-open-handles',
54-
['outside', '--detectOpenHandles'],
55-
'Jest has detected',
56-
);
52+
const run = runContinuous('detect-open-handles', [
53+
'outside',
54+
'--detectOpenHandles',
55+
]);
56+
await run.waitUntil(({stderr}) => stderr.includes('Jest has detected'));
57+
const {stderr} = await run.end();
5758
const textAfterTest = getTextAfterTest(stderr);
5859

5960
expect(wrap(textAfterTest)).toMatchSnapshot();
@@ -84,11 +85,12 @@ onNodeVersions('>=11', () => {
8485
});
8586

8687
it('prints out info about open handlers from inside tests', async () => {
87-
const {stderr} = await until(
88-
'detect-open-handles',
89-
['inside', '--detectOpenHandles'],
90-
'Jest has detected',
91-
);
88+
const run = runContinuous('detect-open-handles', [
89+
'inside',
90+
'--detectOpenHandles',
91+
]);
92+
await run.waitUntil(({stderr}) => stderr.includes('Jest has detected'));
93+
const {stderr} = await run.end();
9294
const textAfterTest = getTextAfterTest(stderr);
9395

9496
expect(wrap(textAfterTest)).toMatchSnapshot();

e2e/runJest.ts

Lines changed: 62 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -136,28 +136,79 @@ export const json = function(
136136
}
137137
};
138138

139-
// Runs `jest` until a given output is achieved, then kills it with `SIGTERM`
140-
export const until = async function(
139+
type StdErrAndOutString = {stderr: string; stdout: string};
140+
type ConditionFunction = (arg: StdErrAndOutString) => boolean;
141+
142+
// Runs `jest` continously (watch mode) and allows the caller to wait for
143+
// conditions on stdout and stderr and to end the process.
144+
export const runContinuous = function(
141145
dir: string,
142-
args: Array<string> | undefined,
143-
text: string,
146+
args?: Array<string>,
144147
options: RunJestOptions = {},
145148
) {
146149
const jestPromise = spawnJest(dir, args, {timeout: 30000, ...options}, true);
147150

148-
jestPromise.stderr!.pipe(
151+
let stderr = '';
152+
let stdout = '';
153+
const pending = new Set<(arg: StdErrAndOutString) => void>();
154+
155+
const dispatch = () => {
156+
for (const fn of pending) {
157+
fn({stderr, stdout});
158+
}
159+
};
160+
161+
jestPromise.stdout!.pipe(
149162
new Writable({
150163
write(chunk, _encoding, callback) {
151-
const output = chunk.toString('utf8');
152-
153-
if (output.includes(text)) {
154-
jestPromise.kill();
155-
}
164+
stdout += chunk.toString('utf8');
165+
dispatch();
166+
callback();
167+
},
168+
}),
169+
);
156170

171+
jestPromise.stderr!.pipe(
172+
new Writable({
173+
write(chunk, _encoding, callback) {
174+
stderr += chunk.toString('utf8');
175+
dispatch();
157176
callback();
158177
},
159178
}),
160179
);
161180

162-
return normalizeStdoutAndStderr(await jestPromise, options);
181+
return {
182+
async end() {
183+
jestPromise.kill();
184+
185+
const result = await jestPromise;
186+
187+
// Not sure why we have to assign here... The ones on `result` are empty strings
188+
result.stdout = stdout;
189+
result.stderr = stderr;
190+
191+
return normalizeStdoutAndStderr(result, options);
192+
},
193+
194+
getCurrentOutput(): StdErrAndOutString {
195+
return {stderr, stdout};
196+
},
197+
198+
getInput() {
199+
return jestPromise.stdin;
200+
},
201+
202+
async waitUntil(fn: ConditionFunction) {
203+
await new Promise(resolve => {
204+
const check = (state: StdErrAndOutString) => {
205+
if (fn(state)) {
206+
pending.delete(check);
207+
resolve();
208+
}
209+
};
210+
pending.add(check);
211+
});
212+
},
213+
};
163214
};

0 commit comments

Comments
 (0)