Skip to content

Commit

Permalink
fix: print log entries if logging happens after teardown (#7731)
Browse files Browse the repository at this point in the history
  • Loading branch information
SimenB authored Jan 29, 2019
1 parent 31b81ba commit 0633a61
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 4 deletions.
1 change: 1 addition & 0 deletions .flowconfig
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[ignore]
.*/examples/.*
.*/node_modules/metro-bundler/.*
.*/node_modules/metro-config/.*
.*/node_modules/metro/.*
.*/node_modules/module-deps/.*

Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- `[jest-config]` Extract setupFilesAfterEnv from preset ([#7724](https://github.com/facebook/jest/pull/7724))
- `[jest-cli]` Do not execute any `globalSetup` or `globalTeardown` if there are no tests to execute ([#7745](https://github.com/facebook/jest/pull/7745))
- `[jest-runtime]` Lock down version of `write-file-atomic` ([#7725](https://github.com/facebook/jest/pull/7725))
- `[jest-cli]` Print log entries when logging happens after test environment is torn down ([#7731](https://github.com/facebook/jest/pull/7731))

### Chore & Maintenance

Expand Down
20 changes: 20 additions & 0 deletions e2e/__tests__/__snapshots__/consoleAfterTeardown.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`console printing 1`] = `
PASS __tests__/console.test.js
● Cannot log after tests are done. Did you forget to wait for something async in your test?
Attempted to log "hello!".
11 | // eslint-disable-next-line prefer-arrow-callback
12 | new Promise(resolve => setTimeout(resolve, 500)).then(function log() {
> 13 | console.log('hello!');
| ^
14 | });
15 | });
16 |
at BufferedConsole.log (../../packages/jest-util/build/BufferedConsole.js:169:10)
at log (__tests__/console.test.js:13:13)
`;
20 changes: 20 additions & 0 deletions e2e/__tests__/consoleAfterTeardown.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* 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.
*
* @flow
*/

import {extractSummary} from '../Utils';
import runJest from '../runJest';
import {wrap} from 'jest-snapshot-serializer-raw';

test('console printing', () => {
const {stderr, status} = runJest('console-after-teardown');
const {rest} = extractSummary(stderr);

expect(status).toBe(0);
expect(wrap(rest)).toMatchSnapshot();
});
15 changes: 11 additions & 4 deletions e2e/__tests__/forceExit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,25 @@ test('exits the process after test are done but before timers complete', () => {
'package.json': JSON.stringify({jest: {testEnvironment: 'node'}}),
});

let output;
let stdout;
let stderr;
({stdout, stderr} = runJest(DIR));
expect(stderr).toMatch(/PASS.*test\.test\.js/);
expect(stdout).toMatch(/TIMER_DONE/);

output = `${stdout}\n${stderr}`;

expect(output).toMatch(/PASS.*test\.test\.js/);
expect(output).toMatch(/TIMER_DONE/);
writeFiles(DIR, {
'package.json': JSON.stringify({
jest: {forceExit: true, testEnvironment: 'node'},
}),
});

({stdout, stderr} = runJest(DIR));
expect(stderr).toMatch(/PASS.*test\.test\.js/);
expect(stdout).not.toMatch(/TIMER_DONE/);

output = `${stdout}\n${stderr}`;

expect(output).toMatch(/PASS.*test\.test\.js/);
expect(output).not.toMatch(/TIMER_DONE/);
});
15 changes: 15 additions & 0 deletions e2e/console-after-teardown/__tests__/console.test.js
Original file line number Diff line number Diff line change
@@ -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.
*/
'use strict';

test('throws error', () => {
// To have the function be named the same in jasmine and circus
// eslint-disable-next-line prefer-arrow-callback
new Promise(resolve => setTimeout(resolve, 500)).then(function log() {
console.log('hello!');
});
});
6 changes: 6 additions & 0 deletions e2e/console-after-teardown/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"jest": {
"testEnvironment": "node",
"verbose": false
}
}
1 change: 1 addition & 0 deletions packages/jest-runner/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"license": "MIT",
"main": "build/index.js",
"dependencies": {
"chalk": "^2.4.2",
"exit": "^0.1.2",
"graceful-fs": "^4.1.15",
"jest-config": "^24.0.0",
Expand Down
32 changes: 32 additions & 0 deletions packages/jest-runner/src/runTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,42 @@ import {getTestEnvironment} from 'jest-config';
import * as docblock from 'jest-docblock';
import {formatExecError} from 'jest-message-util';
import sourcemapSupport from 'source-map-support';
import chalk from 'chalk';

type RunTestInternalResult = {
leakDetector: ?LeakDetector,
result: TestResult,
};

function freezeConsole(
testConsole: BufferedConsole | Console | NullConsole,
config: ProjectConfig,
) {
// $FlowFixMe: overwrite it for pretty errors
testConsole._log = function fakeConsolePush(_type, message) {
const error = new ErrorWithStack(
`${chalk.red(
`${chalk.bold(
'Cannot log after tests are done.',
)} Did you forget to wait for something async in your test?`,
)}\nAttempted to log "${message}".`,
fakeConsolePush,
);

const formattedError = formatExecError(
error,
config,
{noStackTrace: false},
undefined,
true,
);

process.stderr.write('\n' + formattedError + '\n');
// TODO: set exit code in Jest 25
// process.exitCode = 1;
};
}

// Keeping the core of "runTest" as a separate function (as "runTestInternal")
// is key to be able to detect memory leaks. Since all variables are local to
// the function, when "runTestInternal" finishes its execution, they can all be
Expand Down Expand Up @@ -197,6 +227,8 @@ async function runTestInternal(
throw err;
}

freezeConsole(testConsole, config);

const testCount =
result.numPassingTests +
result.numFailingTests +
Expand Down

0 comments on commit 0633a61

Please sign in to comment.