Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: better timeout errors through deadlines (prototype) #10905

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
35 changes: 35 additions & 0 deletions e2e/__tests__/__snapshots__/babelPluginJestDeadlines.test.ts.snap
@@ -0,0 +1,35 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`passes generally 1`] = `
Object {
"rest": "FAIL __tests__/plain.test.js
● Test suite failed to run

Cannot find module 'babel-plugin-jest-deadlines' from '/home/faux/clone/jest/e2e/babel-plugin-jest-deadlines'

at Function.resolveSync [as sync] (../../node_modules/resolve/lib/sync.js:90:15)
at Array.map (<anonymous>)",
"summary": "Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: <<REPLACED>>
Ran all test suites matching /plain.test.js/i.",
}
`;

exports[`throws on deadline exceeded 1`] = `
Object {
"rest": "FAIL __tests__/typescript.test.ts
● Test suite failed to run

Cannot find module 'babel-plugin-jest-deadlines' from '/home/faux/clone/jest/e2e/babel-plugin-jest-deadlines'

at Function.resolveSync [as sync] (../../node_modules/resolve/lib/sync.js:90:15)
at Array.map (<anonymous>)",
"summary": "Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: <<REPLACED>>
Ran all test suites matching /typescript.test.ts/i.",
}
`;
14 changes: 14 additions & 0 deletions e2e/__tests__/__snapshots__/deadlines.ts.snap
@@ -0,0 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`passes generally 1`] = `
Object {
"rest": "PASS __tests__/manual-within.js
describe
✓ it",
"summary": "Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: <<REPLACED>>
Ran all test suites matching /manual-within.js/i.",
}
`;
46 changes: 46 additions & 0 deletions e2e/__tests__/babelPluginJestDeadlines.test.ts
@@ -0,0 +1,46 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import * as path from 'path';
import {skipSuiteOnJasmine} from '@jest/test-utils';
import {extractSummary, runYarnInstall} from '../Utils';
import runJest from '../runJest';

const DIR = path.resolve(__dirname, '..', 'babel-plugin-jest-deadlines');

beforeAll(() => {
runYarnInstall(DIR);
});

skipSuiteOnJasmine();

it('passes generally', () => {
const result = runJest('babel-plugin-jest-deadlines', [
'--no-cache',
'plain.test.js',
]);
expect(result.exitCode).toBe(1);
expect(summaryWithoutTime(result)).toMatchSnapshot();
});

it('throws on deadline exceeded', () => {
const result = runJest('babel-plugin-jest-deadlines', [
'--no-cache',
'typescript.test.ts',
]);
expect(result.exitCode).toBe(1);
expect(summaryWithoutTime(result)).toMatchSnapshot();
});

function summaryWithoutTime(result: {stderr: string}) {
const summary = extractSummary(result.stderr);
summary.rest = summary.rest.replace(
/(waited here for) \d*\.?\d+ m?s\b/,
'$1 <<REPLACED>>',
);
return summary;
}
190 changes: 190 additions & 0 deletions e2e/__tests__/deadlines.ts
@@ -0,0 +1,190 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import semver = require('semver');
import {skipSuiteOnJasmine} from '@jest/test-utils';
import {extractSummary} from '../Utils';
import runJest from '../runJest';

skipSuiteOnJasmine();

function givenNode(versionRange: string, func: () => void): void {
if (semver.satisfies(process.versions.node, versionRange)) {
func();
}
}

it('passes generally', () => {
const result = runJest('deadlines', ['manual-within.js']);
expect(result.exitCode).toBe(0);
const summary = summaryWithoutTime(result);
expect(summary).toMatchSnapshot();
});

it('throws on deadline exceeded', () => {
const result = runJest('deadlines', ['manual-exceeded.js']);
expect(result.exitCode).toBe(1);
const summary = summaryWithoutTime(result);
givenNode('>=12', () =>
expect(summary).toMatchInlineSnapshot(`
Object {
"rest": "FAIL __tests__/manual-exceeded.js
describe
✕ it

● describe › it

deadline exceeded (waited here for <<REPLACED>>)

12 | describe('describe', () => {
13 | it('it', async () => {
> 14 | await expect.withinDeadline(sleep(200));
| ^
15 | }, 50);
16 | });
17 |

at Object.<anonymous> (__tests__/manual-exceeded.js:14:5)",
"summary": "Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: <<REPLACED>>
Ran all test suites matching /manual-exceeded.js/i.",
}
`),
);
givenNode('<12', () =>
expect(summary).toMatchInlineSnapshot(`
Object {
"rest": "FAIL __tests__/manual-exceeded.js
describe
✕ it

● describe › it

deadline exceeded (waited here for <<REPLACED>>)",
"summary": "Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: <<REPLACED>>
Ran all test suites matching /manual-exceeded.js/i.",
}
`),
);
});

it('throws on deadline exceeded in a hook', () => {
const result = runJest('deadlines', ['manual-exceeded-hook.js']);
expect(result.exitCode).toBe(1);
const summary = summaryWithoutTime(result);
givenNode('>=12', () =>
expect(summary).toMatchInlineSnapshot(`
Object {
"rest": "FAIL __tests__/manual-exceeded-hook.js
describe
✕ does nothing

● describe › does nothing

deadline exceeded (waited here for <<REPLACED>>)

12 | describe('describe', () => {
13 | beforeEach(async () => {
> 14 | await expect.withinDeadline(sleep(200));
| ^
15 | }, 50);
16 |
17 | it('does nothing', () => {});

at Object.<anonymous> (__tests__/manual-exceeded-hook.js:14:5)",
"summary": "Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: <<REPLACED>>
Ran all test suites matching /manual-exceeded-hook.js/i.",
}
`),
);
givenNode('<12', () =>
expect(summary).toMatchInlineSnapshot(`
Object {
"rest": "FAIL __tests__/manual-exceeded-hook.js
describe
✕ does nothing

● describe › does nothing

deadline exceeded (waited here for <<REPLACED>>)",
"summary": "Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: <<REPLACED>>
Ran all test suites matching /manual-exceeded-hook.js/i.",
}
`),
);
});

it('throws on deadline exceeded in a describe hook', () => {
const result = runJest('deadlines', ['manual-exceeded-hook-describe.js']);
expect(result.exitCode).toBe(1);
const summary = summaryWithoutTime(result);
givenNode('>=12', () =>
expect(summary).toMatchInlineSnapshot(`
Object {
"rest": "FAIL __tests__/manual-exceeded-hook-describe.js
describe
✕ does nothing

● describe › does nothing

deadline exceeded (waited here for <<REPLACED>>)

12 | describe('describe', () => {
13 | beforeAll(async () => {
> 14 | await expect.withinDeadline(sleep(200));
| ^
15 | }, 50);
16 |
17 | it('does nothing', () => {});

at __tests__/manual-exceeded-hook-describe.js:14:5",
"summary": "Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: <<REPLACED>>
Ran all test suites matching /manual-exceeded-hook-describe.js/i.",
}
`),
);
givenNode('<12', () =>
expect(summary).toMatchInlineSnapshot(`
Object {
"rest": "FAIL __tests__/manual-exceeded-hook-describe.js
describe
✕ does nothing

● describe › does nothing

deadline exceeded (waited here for <<REPLACED>>)",
"summary": "Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: <<REPLACED>>
Ran all test suites matching /manual-exceeded-hook-describe.js/i.",
}
`),
);
});

function summaryWithoutTime(result: {stderr: string}) {
const summary = extractSummary(result.stderr);
summary.rest = summary.rest.replace(
/(waited here for) \d*\.?\d+ m?s\b/,
'$1 <<REPLACED>>',
);
return summary;
}
14 changes: 14 additions & 0 deletions e2e/babel-plugin-jest-deadlines/__tests__/plain.test.js
@@ -0,0 +1,14 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/

const sleep = duration => new Promise(resolve => setTimeout(resolve, duration));

test('exceeded', async () => {
await sleep(10);
await sleep(200);
}, 50);
15 changes: 15 additions & 0 deletions e2e/babel-plugin-jest-deadlines/__tests__/typescript.test.ts
@@ -0,0 +1,15 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/

const sleep = (duration: number) =>
new Promise(resolve => setTimeout(resolve, duration));

test('exceeded', async () => {
await sleep(10);
await sleep(200);
}, 50);
17 changes: 17 additions & 0 deletions e2e/babel-plugin-jest-deadlines/babel.config.js
@@ -0,0 +1,17 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

module.exports = {
overrides: [
{
presets: ['@babel/preset-typescript'],
test: '**/*.ts',
},
],
plugins: ['jest-deadlines'],
presets: [['@babel/preset-env', {targets: {node: 'current'}}]],
};
15 changes: 15 additions & 0 deletions e2e/babel-plugin-jest-deadlines/package.json
@@ -0,0 +1,15 @@
{
"dependencies": {
"@babel/preset-env": "^7.0.0",
"@babel/preset-typescript": "^7.0.0",
"react": "*"
},
"jest": {
"testEnvironment": "node",
"transformIgnorePatterns": [
"jest-circus",
"jest-environment-node",
"jest-jasmine2"
]
}
}