Skip to content

Commit

Permalink
fix missing console.log messages (jestjs#3895)
Browse files Browse the repository at this point in the history
* Ensure that console output is not lost in concurrent reporter

* console.log integration test + naming
  • Loading branch information
aaronabramov committed Jun 23, 2017
1 parent 14c138f commit 4ab702b
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`prints console.logs when run with forceExit 1`] = `
" PASS __tests__/a-banana.js
✓ banana
"
`;

exports[`prints console.logs when run with forceExit 2`] = `
"Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: <<REPLACED>>
Ran all test suites.
"
`;
exports[`prints console.logs when run with forceExit 3`] = `
" console.log __tests__/a-banana.js:2
Hey
"
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* 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, '../console_log_output_when_run_in_band');

skipOnWindows.suite();

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

test('prints console.logs when run with forceExit', () => {
writeFiles(DIR, {
'__tests__/a-banana.js': `
test('banana', () => console.log('Hey'));
`,
'package.json': '{}',
});

const {stderr, stdout, status} = runJest(DIR, [
'-i',
'--ci=false',
'--forceExit',
]);
const {rest, summary} = extractSummary(stderr);
expect(status).toBe(0);
expect(rest).toMatchSnapshot();
expect(summary).toMatchSnapshot();
expect(stdout).toMatchSnapshot();
});
25 changes: 20 additions & 5 deletions packages/jest-cli/src/reporters/DefaultReporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import getConsoleOutput from './getConsoleOutput';
import getResultHeader from './getResultHeader';

type write = (chunk: string, enc?: any, cb?: () => void) => boolean;
type FlushBufferedOutput = () => void;

const TITLE_BULLET = chalk.bold('\u25cf ');

Expand All @@ -35,6 +36,7 @@ class DefaultReporter extends BaseReporter {
_globalConfig: GlobalConfig;
_out: write;
_status: Status;
_bufferedOutput: Set<FlushBufferedOutput>;

constructor(globalConfig: GlobalConfig) {
super();
Expand All @@ -43,6 +45,7 @@ class DefaultReporter extends BaseReporter {
this._out = process.stdout.write.bind(process.stdout);
this._err = process.stderr.write.bind(process.stderr);
this._status = new Status();
this._bufferedOutput = new Set();
this._wrapStdio(process.stdout);
this._wrapStdio(process.stderr);
this._status.onChange(() => {
Expand All @@ -57,25 +60,28 @@ class DefaultReporter extends BaseReporter {
let buffer = [];
let timeout = null;

const doFlush = () => {
const flushBufferedOutput = () => {
const string = buffer.join('');
buffer = [];
// This is to avoid conflicts between random output and status text
this._clearStatus();
originalWrite.call(stream, string);
this._printStatus();
this._bufferedOutput.delete(flushBufferedOutput);
};

const flush = () => {
this._bufferedOutput.add(flushBufferedOutput);

const debouncedFlush = () => {
// If the process blows up no errors would be printed.
// There should be a smart way to buffer stderr, but for now
// we just won't buffer it.
if (stream === process.stderr) {
doFlush();
flushBufferedOutput();
} else {
if (!timeout) {
timeout = setTimeout(() => {
doFlush();
flushBufferedOutput();
timeout = null;
}, 100);
}
Expand All @@ -85,11 +91,18 @@ class DefaultReporter extends BaseReporter {
// $FlowFixMe
stream.write = chunk => {
buffer.push(chunk);
flush();
debouncedFlush();
return true;
};
}

// Don't wait for the debounced call and flush all output immediately.
forceFlushBufferedOutput() {
for (const flushBufferedOutput of this._bufferedOutput) {
flushBufferedOutput();
}
}

_clearStatus() {
if (isInteractive) {
this._out(this._clear);
Expand All @@ -116,6 +129,7 @@ class DefaultReporter extends BaseReporter {
}

onRunComplete() {
this.forceFlushBufferedOutput();
this._status.runFinished();
// $FlowFixMe
process.stdout.write = this._out;
Expand All @@ -139,6 +153,7 @@ class DefaultReporter extends BaseReporter {
test.context.config,
testResult,
);
this.forceFlushBufferedOutput();
}

_printTestFileSummary(
Expand Down

0 comments on commit 4ab702b

Please sign in to comment.