diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b346bd6d0d5..1d92c000154a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## master +### Features + +- `[jest-runner]` print stack trace when `process.exit` is called from user code ([#6714](https://github.com/facebook/jest/pull/6714)) + ### Fixes - `[babel-jest]` Make `getCacheKey()` take into account `createTransformer` options ([#6699](https://github.com/facebook/jest/pull/6699)) diff --git a/e2e/__tests__/__snapshots__/process_exit.test.js.snap b/e2e/__tests__/__snapshots__/process_exit.test.js.snap new file mode 100644 index 000000000000..8d64215ccb0d --- /dev/null +++ b/e2e/__tests__/__snapshots__/process_exit.test.js.snap @@ -0,0 +1,14 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`prints stack trace pointing to process.exit call 1`] = ` +" ● process.exit called with \\"1\\" + + > 1 | process.exit(1); + | ^ + 2 | + 3 | test('something', () => { + 4 | expect(true).toBe(true); + + at Object. (__tests__/test.js:1:9) +" +`; diff --git a/e2e/__tests__/process_exit.test.js b/e2e/__tests__/process_exit.test.js new file mode 100644 index 000000000000..93397d67608e --- /dev/null +++ b/e2e/__tests__/process_exit.test.js @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. 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 + */ +'use strict'; + +const runJest = require('../runJest'); + +it('prints stack trace pointing to process.exit call', async () => { + const {stderr} = await runJest('process-exit'); + + expect(stderr).toMatchSnapshot(); +}); diff --git a/e2e/process-exit/__tests__/test.js b/e2e/process-exit/__tests__/test.js new file mode 100644 index 000000000000..59b91b79e98d --- /dev/null +++ b/e2e/process-exit/__tests__/test.js @@ -0,0 +1,5 @@ +process.exit(1); + +test('something', () => { + expect(true).toBe(true); +}); diff --git a/e2e/process-exit/package.json b/e2e/process-exit/package.json new file mode 100644 index 000000000000..148788b25446 --- /dev/null +++ b/e2e/process-exit/package.json @@ -0,0 +1,5 @@ +{ + "jest": { + "testEnvironment": "node" + } +} diff --git a/packages/jest-runner/src/run_test.js b/packages/jest-runner/src/run_test.js index 1efcc5ce2916..64ed00bb9261 100644 --- a/packages/jest-runner/src/run_test.js +++ b/packages/jest-runner/src/run_test.js @@ -25,6 +25,7 @@ import { import LeakDetector from 'jest-leak-detector'; import {getTestEnvironment} from 'jest-config'; import * as docblock from 'jest-docblock'; +import {formatExecError} from 'jest-message-util'; import sourcemapSupport from 'source-map-support'; type RunTestInternalResult = { @@ -145,6 +146,34 @@ async function runTestInternal( // For runtime errors sourcemapSupport.install(sourcemapOptions); + if ( + environment.global && + environment.global.process && + environment.global.process.exit + ) { + const realExit = environment.global.process.exit; + + environment.global.process.exit = function exit(...args) { + const error = new Error(`process.exit called with "${args.join(', ')}"`); + + if (Error.captureStackTrace) { + Error.captureStackTrace(error, exit); + } + + const formattedError = formatExecError( + error, + config, + {noStackTrace: false}, + undefined, + true, + ); + + process.stderr.write(formattedError); + + return realExit(...args); + }; + } + try { await environment.setup();