Skip to content

Commit

Permalink
chore: replace until test helper with a continuous (#9156)
Browse files Browse the repository at this point in the history
  • Loading branch information
SimenB committed Nov 9, 2019
1 parent 17f6fb7 commit 62dfcc9
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 31 deletions.
42 changes: 22 additions & 20 deletions e2e/__tests__/detectOpenHandles.ts
Expand Up @@ -7,7 +7,7 @@

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

try {
require('async_hooks');
Expand All @@ -27,33 +27,34 @@ function getTextAfterTest(stderr: string) {
}

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

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

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

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

it('prints out info about open handlers', async () => {
const {stderr} = await until(
'detect-open-handles',
['outside', '--detectOpenHandles'],
'Jest has detected',
);
const run = runContinuous('detect-open-handles', [
'outside',
'--detectOpenHandles',
]);
await run.waitUntil(({stderr}) => stderr.includes('Jest has detected'));
const {stderr} = await run.end();
const textAfterTest = getTextAfterTest(stderr);

expect(wrap(textAfterTest)).toMatchSnapshot();
Expand Down Expand Up @@ -84,11 +85,12 @@ onNodeVersions('>=11', () => {
});

it('prints out info about open handlers from inside tests', async () => {
const {stderr} = await until(
'detect-open-handles',
['inside', '--detectOpenHandles'],
'Jest has detected',
);
const run = runContinuous('detect-open-handles', [
'inside',
'--detectOpenHandles',
]);
await run.waitUntil(({stderr}) => stderr.includes('Jest has detected'));
const {stderr} = await run.end();
const textAfterTest = getTextAfterTest(stderr);

expect(wrap(textAfterTest)).toMatchSnapshot();
Expand Down
73 changes: 62 additions & 11 deletions e2e/runJest.ts
Expand Up @@ -136,28 +136,79 @@ export const json = function(
}
};

// Runs `jest` until a given output is achieved, then kills it with `SIGTERM`
export const until = async function(
type StdErrAndOutString = {stderr: string; stdout: string};
type ConditionFunction = (arg: StdErrAndOutString) => boolean;

// Runs `jest` continously (watch mode) and allows the caller to wait for
// conditions on stdout and stderr and to end the process.
export const runContinuous = function(
dir: string,
args: Array<string> | undefined,
text: string,
args?: Array<string>,
options: RunJestOptions = {},
) {
const jestPromise = spawnJest(dir, args, {timeout: 30000, ...options}, true);

jestPromise.stderr!.pipe(
let stderr = '';
let stdout = '';
const pending = new Set<(arg: StdErrAndOutString) => void>();

const dispatch = () => {
for (const fn of pending) {
fn({stderr, stdout});
}
};

jestPromise.stdout!.pipe(
new Writable({
write(chunk, _encoding, callback) {
const output = chunk.toString('utf8');

if (output.includes(text)) {
jestPromise.kill();
}
stdout += chunk.toString('utf8');
dispatch();
callback();
},
}),
);

jestPromise.stderr!.pipe(
new Writable({
write(chunk, _encoding, callback) {
stderr += chunk.toString('utf8');
dispatch();
callback();
},
}),
);

return normalizeStdoutAndStderr(await jestPromise, options);
return {
async end() {
jestPromise.kill();

const result = await jestPromise;

// Not sure why we have to assign here... The ones on `result` are empty strings
result.stdout = stdout;
result.stderr = stderr;

return normalizeStdoutAndStderr(result, options);
},

getCurrentOutput(): StdErrAndOutString {
return {stderr, stdout};
},

getInput() {
return jestPromise.stdin;
},

async waitUntil(fn: ConditionFunction) {
await new Promise(resolve => {
const check = (state: StdErrAndOutString) => {
if (fn(state)) {
pending.delete(check);
resolve();
}
};
pending.add(check);
});
},
};
};

0 comments on commit 62dfcc9

Please sign in to comment.