From 77d993c269f513fa7bb56c11e91a7c66bebb644a Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Thu, 19 Jul 2018 11:01:00 +0200 Subject: [PATCH 1/5] print stack trace on calls to process.exit --- CHANGELOG.md | 4 ++++ .../__snapshots__/process_exit.test.js.snap | 15 ++++++++++++ e2e/__tests__/process_exit.test.js | 17 ++++++++++++++ e2e/process-exit/__tests__/test.js | 5 ++++ e2e/process-exit/package.json | 5 ++++ packages/jest-runner/src/run_test.js | 23 +++++++++++++++++++ 6 files changed, 69 insertions(+) create mode 100644 e2e/__tests__/__snapshots__/process_exit.test.js.snap create mode 100644 e2e/__tests__/process_exit.test.js create mode 100644 e2e/process-exit/__tests__/test.js create mode 100644 e2e/process-exit/package.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b346bd6d0d5..0a79f5f5b9d1 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 + ### 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..fbaed9899382 --- /dev/null +++ b/e2e/__tests__/__snapshots__/process_exit.test.js.snap @@ -0,0 +1,15 @@ +// 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..3931865155bb 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,28 @@ async function runTestInternal( // For runtime errors sourcemapSupport.install(sourcemapOptions); + 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, + ); + + global.process.stderr.write(formattedError + '\n'); + + return realExit(...args); + }; + try { await environment.setup(); From 5fe0955c148b735eace7d498b7a8459ad5d47ad5 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Thu, 19 Jul 2018 11:10:53 +0200 Subject: [PATCH 2/5] link PR in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a79f5f5b9d1..1d92c000154a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ### Features -- `[jest-runner]` print stack trace when `process.exit` is called from user code +- `[jest-runner]` print stack trace when `process.exit` is called from user code ([#6714](https://github.com/facebook/jest/pull/6714)) ### Fixes From 584ad487646497a125fe378e9329dca6d91b16b4 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Thu, 19 Jul 2018 11:20:29 +0200 Subject: [PATCH 3/5] guard exit handler against missing global process --- packages/jest-runner/src/run_test.js | 34 +++++++++++++++------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/packages/jest-runner/src/run_test.js b/packages/jest-runner/src/run_test.js index 3931865155bb..e7623476b5c0 100644 --- a/packages/jest-runner/src/run_test.js +++ b/packages/jest-runner/src/run_test.js @@ -146,27 +146,29 @@ async function runTestInternal( // For runtime errors sourcemapSupport.install(sourcemapOptions); - const realExit = environment.global.process.exit; + if (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(', ')}"`); + environment.global.process.exit = function exit(...args) { + const error = new Error(`process.exit called with "${args.join(', ')}"`); - if (Error.captureStackTrace) { - Error.captureStackTrace(error, exit); - } + if (Error.captureStackTrace) { + Error.captureStackTrace(error, exit); + } - const formattedError = formatExecError( - error, - config, - {noStackTrace: false}, - undefined, - true, - ); + const formattedError = formatExecError( + error, + config, + {noStackTrace: false}, + undefined, + true, + ); - global.process.stderr.write(formattedError + '\n'); + global.process.stderr.write(formattedError + '\n'); - return realExit(...args); - }; + return realExit(...args); + }; + } try { await environment.setup(); From dc0a2afd6076112eb1cb10c3a5ad707b66aa2d57 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Thu, 19 Jul 2018 11:23:02 +0200 Subject: [PATCH 4/5] moar guard --- packages/jest-runner/src/run_test.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/jest-runner/src/run_test.js b/packages/jest-runner/src/run_test.js index e7623476b5c0..9514c723fc66 100644 --- a/packages/jest-runner/src/run_test.js +++ b/packages/jest-runner/src/run_test.js @@ -146,7 +146,11 @@ async function runTestInternal( // For runtime errors sourcemapSupport.install(sourcemapOptions); - if (environment.global.process && environment.global.process.exit) { + if ( + environment.global && + environment.global.process && + environment.global.process.exit + ) { const realExit = environment.global.process.exit; environment.global.process.exit = function exit(...args) { From 3b80f4aa8c9505ffc985675400ce14f206013528 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Thu, 19 Jul 2018 11:25:09 +0200 Subject: [PATCH 5/5] remove unnecessary newline --- e2e/__tests__/__snapshots__/process_exit.test.js.snap | 1 - packages/jest-runner/src/run_test.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/e2e/__tests__/__snapshots__/process_exit.test.js.snap b/e2e/__tests__/__snapshots__/process_exit.test.js.snap index fbaed9899382..8d64215ccb0d 100644 --- a/e2e/__tests__/__snapshots__/process_exit.test.js.snap +++ b/e2e/__tests__/__snapshots__/process_exit.test.js.snap @@ -10,6 +10,5 @@ exports[`prints stack trace pointing to process.exit call 1`] = ` 4 | expect(true).toBe(true); at Object. (__tests__/test.js:1:9) - " `; diff --git a/packages/jest-runner/src/run_test.js b/packages/jest-runner/src/run_test.js index 9514c723fc66..64ed00bb9261 100644 --- a/packages/jest-runner/src/run_test.js +++ b/packages/jest-runner/src/run_test.js @@ -168,7 +168,7 @@ async function runTestInternal( true, ); - global.process.stderr.write(formattedError + '\n'); + process.stderr.write(formattedError); return realExit(...args); };