From 31cad209cdfa70c3227ab212c6f4fdb736cf4689 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 20 Sep 2021 15:03:23 +0200 Subject: [PATCH] fix: include path to test file in "after teardown" error (#11885) --- CHANGELOG.md | 2 ++ .../environmentAfterTeardown.test.ts.snap | 2 +- .../requireAfterTeardown.test.ts.snap | 2 +- .../environmentAfterTeardown.test.ts | 2 +- packages/jest-runner/src/runTest.ts | 3 +- packages/jest-runtime/src/index.ts | 34 ++++++++++++++++++- 6 files changed, 39 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 516cad9be717..0542b5913cfe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ ### Fixes - `[jest-runtime]` Fix regression when using `jest.isolateModules` and mocks ([#11882](https://github.com/facebook/jest/pull/11882)) +- `[jest-runtime]` Include test name when importing modules after test has completed ([#11885](https://github.com/facebook/jest/pull/11885)) +- `[jest-runtime]` Error when ESM import is used after test is torn down ([#11885](https://github.com/facebook/jest/pull/11885)) ### Chore & Maintenance diff --git a/e2e/__tests__/__snapshots__/environmentAfterTeardown.test.ts.snap b/e2e/__tests__/__snapshots__/environmentAfterTeardown.test.ts.snap index 73b0b7d45db6..23d77f190aff 100644 --- a/e2e/__tests__/__snapshots__/environmentAfterTeardown.test.ts.snap +++ b/e2e/__tests__/__snapshots__/environmentAfterTeardown.test.ts.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`prints useful error for environment methods after test is done 1`] = ` -ReferenceError: You are trying to access a property or method of the Jest environment after it has been torn down. +ReferenceError: You are trying to access a property or method of the Jest environment after it has been torn down. From __tests__/afterTeardown.test.js. 9 | test('access environment methods after done', () => { 10 | setTimeout(() => { diff --git a/e2e/__tests__/__snapshots__/requireAfterTeardown.test.ts.snap b/e2e/__tests__/__snapshots__/requireAfterTeardown.test.ts.snap index 2d1c9bcc2b9e..67eae2c94852 100644 --- a/e2e/__tests__/__snapshots__/requireAfterTeardown.test.ts.snap +++ b/e2e/__tests__/__snapshots__/requireAfterTeardown.test.ts.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`prints useful error for requires after test is done 1`] = ` -ReferenceError: You are trying to \`import\` a file after the Jest environment has been torn down. +ReferenceError: You are trying to \`import\` a file after the Jest environment has been torn down. From __tests__/lateRequire.test.js. 9 | test('require after done', () => { 10 | setTimeout(() => { diff --git a/e2e/__tests__/environmentAfterTeardown.test.ts b/e2e/__tests__/environmentAfterTeardown.test.ts index 5b1c0a63ee2e..2056db34491c 100644 --- a/e2e/__tests__/environmentAfterTeardown.test.ts +++ b/e2e/__tests__/environmentAfterTeardown.test.ts @@ -14,6 +14,6 @@ test('prints useful error for environment methods after test is done', () => { expect(wrap(interestingLines)).toMatchSnapshot(); expect(stderr.split('\n')[9]).toBe( - 'ReferenceError: You are trying to access a property or method of the Jest environment after it has been torn down.', + 'ReferenceError: You are trying to access a property or method of the Jest environment after it has been torn down. From __tests__/afterTeardown.test.js.', ); }); diff --git a/packages/jest-runner/src/runTest.ts b/packages/jest-runner/src/runTest.ts index cd855860a98a..f787d3eda309 100644 --- a/packages/jest-runner/src/runTest.ts +++ b/packages/jest-runner/src/runTest.ts @@ -329,9 +329,8 @@ async function runTestInternal( setImmediate(() => resolve({leakDetector, result})); }); } finally { + runtime.teardown(); await environment.teardown(); - // TODO: this function might be missing, remove ? in Jest 26 - runtime.teardown?.(); sourcemapSupport.resetRetrieveHandlers(); } diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index 1eb74389022c..436c9a916d16 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -22,6 +22,7 @@ import {parse as parseCjs} from 'cjs-module-lexer'; import {CoverageInstrumenter, V8Coverage} from 'collect-v8-coverage'; import execa = require('execa'); import * as fs from 'graceful-fs'; +import slash = require('slash'); import stripBOM = require('strip-bom'); import type { Jest, @@ -226,6 +227,7 @@ export default class Runtime { private jestGlobals?: JestGlobals; private readonly esmConditions: Array; private readonly cjsConditions: Array; + private isTornDown = false; constructor( config: Config.ProjectConfig, @@ -531,6 +533,14 @@ export default class Runtime { referencingIdentifier: string, context: VMContext, ) { + if (this.isTornDown) { + this._logFormattedReferenceError( + 'You are trying to `import` a file after the Jest environment has been torn down.', + ); + process.exitCode = 1; + return; + } + if (specifier === '@jest/globals') { const fromCache = this._esmoduleRegistry.get('@jest/globals'); @@ -575,6 +585,14 @@ export default class Runtime { } private async linkAndEvaluateModule(module: VMModule) { + if (this.isTornDown) { + this._logFormattedReferenceError( + 'You are trying to `import` a file after the Jest environment has been torn down.', + ); + process.exitCode = 1; + return; + } + if (module.status === 'unlinked') { // since we might attempt to link the same module in parallel, stick the promise in a weak map so every call to // this method can await it @@ -1199,6 +1217,8 @@ export default class Runtime { this._v8CoverageResult = []; this._v8CoverageInstrumenter = undefined; this._moduleImplementation = undefined; + + this.isTornDown = true; } private _resolveModule( @@ -1284,6 +1304,14 @@ export default class Runtime { moduleRegistry: ModuleRegistry, from: Config.Path | null, ) { + if (this.isTornDown) { + this._logFormattedReferenceError( + 'You are trying to `import` a file after the Jest environment has been torn down.', + ); + process.exitCode = 1; + return; + } + // If the environment was disposed, prevent this module from being executed. if (!this._environment.global) { return; @@ -1847,6 +1875,7 @@ export default class Runtime { }; const _getFakeTimers = () => { if ( + this.isTornDown || !(this._environment.fakeTimers || this._environment.fakeTimersModern) ) { this._logFormattedReferenceError( @@ -1975,7 +2004,10 @@ export default class Runtime { } private _logFormattedReferenceError(errorMessage: string) { - const originalStack = new ReferenceError(errorMessage) + const testPath = this._testPath + ? ` From ${slash(path.relative(this._config.rootDir, this._testPath))}.` + : ''; + const originalStack = new ReferenceError(`${errorMessage}${testPath}`) .stack!.split('\n') // Remove this file from the stack (jest-message-utils will keep one line) .filter(line => line.indexOf(__filename) === -1)