Skip to content

jest-circus async tests #3819

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

Closed
wants to merge 1 commit 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions integration_tests/__tests__/jasmine_async-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ describe('async jasmine', () => {
expect(json.numPendingTests).toBe(0);

const {message} = json.testResults[0];
expect(message).toMatch('with failing timeout');
expect(message).toMatch('Async callback was not invoked within timeout');
expect(message).toMatch('with failing async');
expect(message).toMatch('timeout');
});

it('works with beforeEach', () => {
Expand Down
42 changes: 42 additions & 0 deletions integration_tests/__tests__/test-hooks-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

'use strict';

const path = require('path');
const skipOnWindows = require('skipOnWindows');
const {extractSummary, cleanup, writeFiles} = require('../utils');
const runJest = require('../runJest');

const DIR = path.resolve(__dirname, '../test-hooks');

skipOnWindows.suite();

beforeEach(() => cleanup(DIR));
afterAll(() => cleanup(DIR));

// Blocked by https://github.com/facebook/jest/issues/3785
test.skip('fails because of the error in afterAll hook', () => {
writeFiles(DIR, {
'__tests__/hooks-test.js': `
// keep the counter to make sure we execute the hook only once.
let count = 0;
beforeAll(() => { throw new Error('afterAll error ' + count++); });

test('one', () => {});
test('two', () => {});
`,
'package.json': '{}',
});

const {stderr, status} = runJest(DIR, ['-w=1', '--ci=false']);
const {rest, summary} = extractSummary(stderr);
expect(rest).toMatchSnapshot();
expect(summary).toMatchSnapshot();
expect(status).toBe(1);
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
'use strict';

describe('promise beforeAll', () => {
let flag;

beforeAll(() => {
return new Promise(resolve => {
process.nextTick(resolve);
}).then(() => {
this.flag = 1;
flag = 1;
});
});

Expand All @@ -23,14 +25,14 @@ describe('promise beforeAll', () => {

// passing tests
it('runs tests after beforeAll asynchronously completes', () => {
expect(this.flag).toBe(1);
expect(flag).toBe(1);
});

describe('with failing timeout', () => {
describe('with failing async', () => {
// failing before hook
beforeAll(() => {
return new Promise(resolve => setTimeout(resolve, 100));
}, 10);
}, 11);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is it 11 now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

easier to find in the console :)


it('fails', () => {});
});
Expand Down
66 changes: 66 additions & 0 deletions packages/jest-circus/src/__mocks__/test_event_handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @noflow
*/

'use strict';

const testEventHandler = (event, state) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really nice, I love how you are testing this. Could we make it a bit more generic somehow so that we don't have to keep this file in sync, though?

switch (event.name) {
case 'start_describe_definition':
case 'finish_describe_definition': {
console.log(event.name + ':', event.blockName);
break;
}
case 'run_describe_start':
case 'run_describe_finish': {
console.log(event.name + ':', event.describeBlock.name);
break;
}
case 'test_start':
case 'test_done': {
console.log(event.name + ':', event.test.name);
break;
}

case 'add_test': {
console.log(event.name + ':', event.testName);
break;
}

case 'test_fn_start':
case 'test_fn_success':
case 'test_fn_failure': {
console.log(event.name + ':', event.test.name);
break;
}

case 'add_hook': {
console.log(event.name + ':', event.hookType);
break;
}

case 'hook_start':
case 'hook_success':
case 'hook_failure': {
console.log(event.name + ':', event.hook.type);
break;
}

default: {
console.log(event.name);
}
}

if (event.name === 'run_finish') {
console.log('');
console.log(`unhandledErrors: ${String(state.unhandledErrors.length)}`);
}
};

module.exports = testEventHandler;
75 changes: 75 additions & 0 deletions packages/jest-circus/src/__mocks__/test_utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really nice!

* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @flow
*/

'use strict';

import os from 'os';
import path from 'path';
import {spawnSync} from 'child_process';
import fs from 'fs';

const CIRCUS_PATH = path.resolve(__dirname, '../../build/index');
const CIRCUS_RUN_PATH = path.resolve(__dirname, '../../build/run');
const CIRCUS_STATE_PATH = path.resolve(__dirname, '../../build/state');
const TEST_EVENT_HANDLER_PATH = path.resolve(__dirname, './test_event_handler');

const runTest = (source: string) => {
const tmpFilename = path.join(os.tmpdir(), 'circus-test-file.js');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we write this into tmp?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the safest, but not the most pleasant way of writing files.
I was thinking about creating a gitignored directory (files_for_integration_tests) and write everything there, so it's easy to cd into the dir and see what's up in there


const content = `
const circus = require('${CIRCUS_PATH}');
global.test = circus.test;
global.describe = circus.describe;
global.beforeEach = circus.beforeEach;
global.afterEach = circus.afterEach;
global.beforeAll = circus.beforeAll;
global.afterAll = circus.afterAll;

const testEventHandler = require('${TEST_EVENT_HANDLER_PATH}');
const addEventHandler = require('${CIRCUS_STATE_PATH}').addEventHandler;
addEventHandler(testEventHandler);

${source};

const run = require('${CIRCUS_RUN_PATH}');

run();
`;

fs.writeFileSync(tmpFilename, content);
const result = spawnSync('node', [tmpFilename], {cwd: process.cwd()});

if (result.status !== 0) {
const message = `
STDOUT: ${result.stdout && result.stdout.toString()}
STDERR: ${result.stderr && result.stderr.toString()}
STATUS: ${result.status}
ERROR: ${String(result.error)}
`;
throw new Error(message);
}

result.stdout = String(result.stdout);
result.stderr = String(result.stderr);

if (result.stderr) {
throw new Error(
`
Unexpected stderr:
${result.stderr}
`,
);
}
return result;
};

module.exports = {
runTest,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`tests are not marked done until their parent afterAll runs 1`] = `
"start_describe_definition: describe
add_hook: afterAll
add_test: one
add_test: two
start_describe_definition: 2nd level describe
add_hook: afterAll
add_test: 2nd level test
start_describe_definition: 3rd level describe
add_test: 3rd level test
add_test: 3rd level test#2
finish_describe_definition: 3rd level describe
finish_describe_definition: 2nd level describe
finish_describe_definition: describe
start_describe_definition: 2nd describe
add_hook: afterAll
add_test: 2nd describe test
finish_describe_definition: 2nd describe
run_start
run_describe_start: ROOT_DESCRIBE_BLOCK
run_describe_start: describe
test_start: one
test_fn_start: one
test_fn_success: one
test_done: one
test_start: two
test_fn_start: two
test_fn_success: two
test_done: two
run_describe_start: 2nd level describe
test_start: 2nd level test
test_fn_start: 2nd level test
test_fn_success: 2nd level test
test_done: 2nd level test
run_describe_start: 3rd level describe
test_start: 3rd level test
test_fn_start: 3rd level test
test_fn_success: 3rd level test
test_done: 3rd level test
test_start: 3rd level test#2
test_fn_start: 3rd level test#2
test_fn_success: 3rd level test#2
test_done: 3rd level test#2
run_describe_finish: 3rd level describe
hook_start: afterAll
hook_success: afterAll
run_describe_finish: 2nd level describe
hook_start: afterAll
hook_success: afterAll
run_describe_finish: describe
run_describe_start: 2nd describe
test_start: 2nd describe test
test_fn_start: 2nd describe test
test_fn_success: 2nd describe test
test_done: 2nd describe test
hook_start: afterAll
hook_failure: afterAll
run_describe_finish: 2nd describe
run_describe_finish: ROOT_DESCRIBE_BLOCK
run_finish

unhandledErrors: 1
"
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`failures 1`] = `
"start_describe_definition: describe
add_hook: beforeEach
add_hook: afterEach
add_test: one
add_test: two
finish_describe_definition: describe
run_start
run_describe_start: ROOT_DESCRIBE_BLOCK
run_describe_start: describe
test_start: one
hook_start: beforeEach
hook_success: beforeEach
test_fn_start: one
test_fn_failure: one
hook_start: afterEach
hook_failure: afterEach
test_done: one
test_start: two
hook_start: beforeEach
hook_success: beforeEach
test_fn_start: two
test_fn_success: two
hook_start: afterEach
hook_failure: afterEach
test_done: two
run_describe_finish: describe
run_describe_finish: ROOT_DESCRIBE_BLOCK
run_finish

unhandledErrors: 0
"
`;

exports[`simple test 1`] = `
"start_describe_definition: describe
add_hook: beforeEach
add_hook: afterEach
add_test: one
add_test: two
finish_describe_definition: describe
run_start
run_describe_start: ROOT_DESCRIBE_BLOCK
run_describe_start: describe
test_start: one
hook_start: beforeEach
hook_success: beforeEach
test_fn_start: one
test_fn_success: one
hook_start: afterEach
hook_success: afterEach
test_done: one
test_start: two
hook_start: beforeEach
hook_success: beforeEach
test_fn_start: two
test_fn_success: two
hook_start: afterEach
hook_success: afterEach
test_done: two
run_describe_finish: describe
run_describe_finish: ROOT_DESCRIBE_BLOCK
run_finish

unhandledErrors: 0
"
`;
Loading