From 8c6276def64092b46f17b3f2e66b2ffb9f4ccebc Mon Sep 17 00:00:00 2001 From: Rob Brackett Date: Thu, 6 May 2021 11:06:02 -0700 Subject: [PATCH 01/13] Add failing tests for open handles with `done` This adds a unit test and two new integration tests to assert that hanging async handles created in test or lifecycle functions with `done` callbacks are correctly detected and logged when using `--detectOpenHandles`. They all fail when used with the Jasmine runner right now (things work fine with Circus; yay!). --- e2e/__tests__/detectOpenHandles.ts | 22 +++++++++++++++++++ .../__tests__/in-done-function.js | 9 ++++++++ .../__tests__/in-done-lifecycle.js | 12 ++++++++++ .../src/__tests__/collectHandles.test.js | 17 ++++++++++++++ 4 files changed, 60 insertions(+) create mode 100644 e2e/detect-open-handles/__tests__/in-done-function.js create mode 100644 e2e/detect-open-handles/__tests__/in-done-lifecycle.js diff --git a/e2e/__tests__/detectOpenHandles.ts b/e2e/__tests__/detectOpenHandles.ts index 977434965a3f..0f2095f07875 100644 --- a/e2e/__tests__/detectOpenHandles.ts +++ b/e2e/__tests__/detectOpenHandles.ts @@ -123,3 +123,25 @@ it('prints out info about open handlers from inside tests', async () => { expect(wrap(textAfterTest)).toMatchSnapshot(); }); + +it('prints out info about open handlers from tests with a `done` callback', async () => { + const {stderr} = runJest('detect-open-handles', [ + 'in-done-function', + '--detectOpenHandles', + '--forceExit', + ]); + const textAfterTest = getTextAfterTest(stderr); + + expect(textAfterTest).toContain('TCPSERVERWRAP'); +}); + +it('prints out info about open handlers from lifecycle functions with a `done` callback', async () => { + const {stderr} = runJest('detect-open-handles', [ + 'in-done-lifecycle', + '--detectOpenHandles', + '--forceExit', + ]); + const textAfterTest = getTextAfterTest(stderr); + + expect(textAfterTest).toContain('TCPSERVERWRAP'); +}); diff --git a/e2e/detect-open-handles/__tests__/in-done-function.js b/e2e/detect-open-handles/__tests__/in-done-function.js new file mode 100644 index 000000000000..b5490935119c --- /dev/null +++ b/e2e/detect-open-handles/__tests__/in-done-function.js @@ -0,0 +1,9 @@ +const http = require('http'); + +test('something', done => { + const server = http.createServer((_, response) => response.end('ok')); + server.listen(0, () => { + expect(true).toBe(true); + done(); + }); +}); diff --git a/e2e/detect-open-handles/__tests__/in-done-lifecycle.js b/e2e/detect-open-handles/__tests__/in-done-lifecycle.js new file mode 100644 index 000000000000..cb8aef8d67a1 --- /dev/null +++ b/e2e/detect-open-handles/__tests__/in-done-lifecycle.js @@ -0,0 +1,12 @@ +const http = require('http'); + +beforeAll(done => { + const server = http.createServer((_, response) => response.end('ok')); + server.listen(0, () => { + done(); + }); +}); + +test('something', () => { + expect(true).toBe(true); +}); diff --git a/packages/jest-core/src/__tests__/collectHandles.test.js b/packages/jest-core/src/__tests__/collectHandles.test.js index 24644ef39215..7192709d9350 100644 --- a/packages/jest-core/src/__tests__/collectHandles.test.js +++ b/packages/jest-core/src/__tests__/collectHandles.test.js @@ -6,6 +6,7 @@ * */ +import http from 'http'; import {PerformanceObserver} from 'perf_hooks'; import collectHandles from '../collectHandles'; @@ -33,4 +34,20 @@ describe('collectHandles', () => { expect(openHandles).toHaveLength(0); obs.disconnect(); }); + + it('should collect handles opened in test functions with `done` callbacks', done => { + const handleCollector = collectHandles(); + const server = http.createServer((_, response) => response.end('ok')); + server.listen(0, () => { + // Collect results while server is still open. + const openHandles = handleCollector(); + + server.close(() => { + expect(openHandles).toContainEqual( + expect.objectContaining({message: 'TCPSERVERWRAP'}), + ); + done(); + }); + }); + }); }); From 125d47b7ae1f05c68ea8d86cc2eb145dc4aea20c Mon Sep 17 00:00:00 2001 From: Rob Brackett Date: Thu, 6 May 2021 22:20:22 -0700 Subject: [PATCH 02/13] Wrap functions w/ a callback in a named function Wrap test and lifecycle functions that take a `done` callback in a named function so that they can be detected as user code in the call stack. This lets the `collectHandles` module in jest-core know to track async resources created in those functions. Fixes #11377. --- packages/jest-jasmine2/src/jasmineAsyncInstall.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts index 30748c0461a6..658b591785d4 100644 --- a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts +++ b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts @@ -47,8 +47,10 @@ function promisifyLifeCycleFunction( const hasDoneCallback = typeof fn === 'function' && fn.length > 0; if (hasDoneCallback) { - // Jasmine will handle it - return originalFn.call(env, fn, timeout); + // Give the function a name so it can be detected in call stacks, but + // otherwise Jasmine will handle it. + const asyncJestLifecycleWithCallback = (done: DoneFn) => fn(done); + return originalFn.call(env, asyncJestLifecycleWithCallback, timeout); } const extraError = new Error(); @@ -109,7 +111,10 @@ function promisifyIt( const hasDoneCallback = fn.length > 0; if (hasDoneCallback) { - return originalFn.call(env, specName, fn, timeout); + // Give the function a name so it can be detected in call stacks, but + // otherwise Jasmine will handle it. + const asyncJestTestWithCallback = (done: DoneFn) => fn(done); + return originalFn.call(env, specName, asyncJestTestWithCallback, timeout); } const extraError = new Error(); From 799399e44d6c93f61fd2cef9076e4522b4b77a6f Mon Sep 17 00:00:00 2001 From: Rob Brackett Date: Fri, 7 May 2021 09:41:34 -0700 Subject: [PATCH 03/13] Add missing copyright headers --- e2e/detect-open-handles/__tests__/in-done-function.js | 6 ++++++ e2e/detect-open-handles/__tests__/in-done-lifecycle.js | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/e2e/detect-open-handles/__tests__/in-done-function.js b/e2e/detect-open-handles/__tests__/in-done-function.js index b5490935119c..db6e9bd903b2 100644 --- a/e2e/detect-open-handles/__tests__/in-done-function.js +++ b/e2e/detect-open-handles/__tests__/in-done-function.js @@ -1,3 +1,9 @@ +/** + * 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. + */ const http = require('http'); test('something', done => { diff --git a/e2e/detect-open-handles/__tests__/in-done-lifecycle.js b/e2e/detect-open-handles/__tests__/in-done-lifecycle.js index cb8aef8d67a1..096f727eca8f 100644 --- a/e2e/detect-open-handles/__tests__/in-done-lifecycle.js +++ b/e2e/detect-open-handles/__tests__/in-done-lifecycle.js @@ -1,3 +1,9 @@ +/** + * 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. + */ const http = require('http'); beforeAll(done => { From 6d47be863af29bec28d87a1738d138fd735d0f2d Mon Sep 17 00:00:00 2001 From: Rob Brackett Date: Fri, 7 May 2021 10:16:48 -0700 Subject: [PATCH 04/13] Fix runtime type-checking for non-functions --- packages/jest-jasmine2/src/jasmineAsyncInstall.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts index 658b591785d4..745b55a57bd2 100644 --- a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts +++ b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts @@ -42,9 +42,12 @@ function promisifyLifeCycleFunction( if (!fn) { // @ts-expect-error: missing fn arg is handled by originalFn return originalFn.call(env); + } else if (typeof fn !== 'function') { + // Pass non-functions to Jest, which throws a nice error. + return originalFn.call(env, fn, timeout); } - const hasDoneCallback = typeof fn === 'function' && fn.length > 0; + const hasDoneCallback = fn.length > 0; if (hasDoneCallback) { // Give the function a name so it can be detected in call stacks, but @@ -106,6 +109,9 @@ function promisifyIt( const spec = originalFn.call(env, specName); spec.pend('not implemented'); return spec; + } else if (typeof fn !== 'function') { + // Pass non-functions to Jest, which throws a nice error. + return originalFn.call(env, specName, fn, timeout); } const hasDoneCallback = fn.length > 0; From 944f969dbbbc4479fa70f92f563abe7e09ebe456 Mon Sep 17 00:00:00 2001 From: Rob Brackett Date: Fri, 7 May 2021 11:00:47 -0700 Subject: [PATCH 05/13] Update snapshot tests with new callstacks --- e2e/__tests__/__snapshots__/failures.test.ts.snap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/__tests__/__snapshots__/failures.test.ts.snap b/e2e/__tests__/__snapshots__/failures.test.ts.snap index 87f8497721ae..f22b0181f482 100644 --- a/e2e/__tests__/__snapshots__/failures.test.ts.snap +++ b/e2e/__tests__/__snapshots__/failures.test.ts.snap @@ -228,7 +228,7 @@ FAIL __tests__/duringTests.test.js 45 | 46 | test('done(non-error)', done => { - at Object. (__tests__/duringTests.test.js:43:8) + at __tests__/duringTests.test.js:43:8 ● done(non-error) @@ -249,7 +249,7 @@ FAIL __tests__/duringTests.test.js 49 | 50 | test('returned promise rejection', () => Promise.reject(deepObject)); - at Object.done (__tests__/duringTests.test.js:47:3) + at done (__tests__/duringTests.test.js:47:3) ● returned promise rejection From bdb38fde570ec015aa79433d357e331ce7abae56 Mon Sep 17 00:00:00 2001 From: Rob Brackett Date: Fri, 7 May 2021 13:38:54 -0700 Subject: [PATCH 06/13] Keep correct `this` for wrapped test functions --- e2e/__tests__/__snapshots__/failures.test.ts.snap | 4 ++-- packages/jest-jasmine2/src/jasmineAsyncInstall.ts | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/e2e/__tests__/__snapshots__/failures.test.ts.snap b/e2e/__tests__/__snapshots__/failures.test.ts.snap index f22b0181f482..87f8497721ae 100644 --- a/e2e/__tests__/__snapshots__/failures.test.ts.snap +++ b/e2e/__tests__/__snapshots__/failures.test.ts.snap @@ -228,7 +228,7 @@ FAIL __tests__/duringTests.test.js 45 | 46 | test('done(non-error)', done => { - at __tests__/duringTests.test.js:43:8 + at Object. (__tests__/duringTests.test.js:43:8) ● done(non-error) @@ -249,7 +249,7 @@ FAIL __tests__/duringTests.test.js 49 | 50 | test('returned promise rejection', () => Promise.reject(deepObject)); - at done (__tests__/duringTests.test.js:47:3) + at Object.done (__tests__/duringTests.test.js:47:3) ● returned promise rejection diff --git a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts index 745b55a57bd2..f7274a3955af 100644 --- a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts +++ b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts @@ -52,7 +52,11 @@ function promisifyLifeCycleFunction( if (hasDoneCallback) { // Give the function a name so it can be detected in call stacks, but // otherwise Jasmine will handle it. - const asyncJestLifecycleWithCallback = (done: DoneFn) => fn(done); + // @ts-expect-error: Support possible extra args at runtime + const asyncJestLifecycleWithCallback = function (this: any, ...args) { + // @ts-expect-error: Support possible extra args at runtime + return fn.apply(this, args); + }; return originalFn.call(env, asyncJestLifecycleWithCallback, timeout); } @@ -119,7 +123,11 @@ function promisifyIt( if (hasDoneCallback) { // Give the function a name so it can be detected in call stacks, but // otherwise Jasmine will handle it. - const asyncJestTestWithCallback = (done: DoneFn) => fn(done); + // @ts-expect-error: Support possible extra args at runtime + const asyncJestTestWithCallback = function (this: any, ...args) { + // @ts-expect-error: Support possible extra args at runtime + return fn.apply(this, args); + }; return originalFn.call(env, specName, asyncJestTestWithCallback, timeout); } From 2088443829adb0aea0d6be06f218e67e4e411dce Mon Sep 17 00:00:00 2001 From: Rob Brackett Date: Sat, 8 May 2021 09:02:17 -0700 Subject: [PATCH 07/13] Update packages/jest-jasmine2/src/jasmineAsyncInstall.ts Co-authored-by: Simen Bekkhus --- packages/jest-jasmine2/src/jasmineAsyncInstall.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts index f7274a3955af..b03e4380d5e1 100644 --- a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts +++ b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts @@ -42,7 +42,9 @@ function promisifyLifeCycleFunction( if (!fn) { // @ts-expect-error: missing fn arg is handled by originalFn return originalFn.call(env); - } else if (typeof fn !== 'function') { + } + + if (typeof fn !== 'function') { // Pass non-functions to Jest, which throws a nice error. return originalFn.call(env, fn, timeout); } From 2adf035e3909808edae4d34967072f572df14784 Mon Sep 17 00:00:00 2001 From: Rob Brackett Date: Sat, 8 May 2021 09:02:32 -0700 Subject: [PATCH 08/13] Update packages/jest-jasmine2/src/jasmineAsyncInstall.ts Co-authored-by: Simen Bekkhus --- packages/jest-jasmine2/src/jasmineAsyncInstall.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts index b03e4380d5e1..d7b43f14b19c 100644 --- a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts +++ b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts @@ -115,7 +115,9 @@ function promisifyIt( const spec = originalFn.call(env, specName); spec.pend('not implemented'); return spec; - } else if (typeof fn !== 'function') { + } + + if (typeof fn !== 'function') { // Pass non-functions to Jest, which throws a nice error. return originalFn.call(env, specName, fn, timeout); } From ca185cae074596ca8629adf330840a6e862d0b6d Mon Sep 17 00:00:00 2001 From: Rob Brackett Date: Sat, 8 May 2021 21:00:50 -0700 Subject: [PATCH 09/13] Use correct type for `this` in test functions --- packages/jest-jasmine2/src/jasmineAsyncInstall.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts index d7b43f14b19c..be33f5b41bbc 100644 --- a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts +++ b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts @@ -54,8 +54,10 @@ function promisifyLifeCycleFunction( if (hasDoneCallback) { // Give the function a name so it can be detected in call stacks, but // otherwise Jasmine will handle it. - // @ts-expect-error: Support possible extra args at runtime - const asyncJestLifecycleWithCallback = function (this: any, ...args) { + const asyncJestLifecycleWithCallback = function ( + this: Global.TestContext, + ...args: Array + ) { // @ts-expect-error: Support possible extra args at runtime return fn.apply(this, args); }; @@ -127,8 +129,10 @@ function promisifyIt( if (hasDoneCallback) { // Give the function a name so it can be detected in call stacks, but // otherwise Jasmine will handle it. - // @ts-expect-error: Support possible extra args at runtime - const asyncJestTestWithCallback = function (this: any, ...args) { + const asyncJestTestWithCallback = function ( + this: Global.TestContext, + ...args: Array + ) { // @ts-expect-error: Support possible extra args at runtime return fn.apply(this, args); }; From 439018f3048f7c3ba775cd835e3a0f05b32af45b Mon Sep 17 00:00:00 2001 From: Rob Brackett Date: Sat, 8 May 2021 21:01:19 -0700 Subject: [PATCH 10/13] Add changelog entries for #11382 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca4d6e15dc12..46c79f2fd8c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,7 @@ - `[jest-console]` `console.dir` now respects the second argument correctly ([#10638](https://github.com/facebook/jest/pull/10638)) - `[jest-core]` Don't report PerformanceObserver as open handle ([#11123](https://github.com/facebook/jest/pull/11123)) - `[jest-core]` Use `WeakRef` to hold timers when detecting open handles ([#11277](https://github.com/facebook/jest/pull/11277)) +- `[jest-core]` Correctly detect open handles that were created in test functions using `done` callbacks ([#11382](https://github.com/facebook/jest/pull/11382)) - `[jest-diff]` [**BREAKING**] Use only named exports ([#11371](https://github.com/facebook/jest/pull/11371)) - `[jest-each]` [**BREAKING**] Ignore excess words in headings ([#8766](https://github.com/facebook/jest/pull/8766)) - `[jest-each]` Support array index with template strings ([#10763](https://github.com/facebook/jest/pull/10763)) @@ -79,6 +80,7 @@ - `[jest-haste-map]` Vendor `NodeWatcher` from `sane` ([#10919](https://github.com/facebook/jest/pull/10919)) - `[jest-jasmine2]` Fixed the issue of `beforeAll` & `afterAll` hooks getting executed even if it is inside a skipped `describe` block when it has child `tests` marked as either `only` or `todo` [#10451](https://github.com/facebook/jest/issues/10451) - `[jest-jasmine2]` Fixed the issues of child `tests` marked with `only` or `todo` getting executed even if it is inside a skipped parent `describe` block [#10451](https://github.com/facebook/jest/issues/10451) +- `[jest-jasmine2]` Wrap all test functions so they open handles that were created in test functions using `done` callbacks can be detected ([#11382](https://github.com/facebook/jest/pull/11382)) - `[jest-reporter]` Handle empty files when reporting code coverage with V8 ([#10819](https://github.com/facebook/jest/pull/10819)) - `[jest-resolve]` Replace read-pkg-up with escalade package ([#10781](https://github.com/facebook/jest/pull/10781)) - `[jest-resolve]` Disable `jest-pnp-resolver` for Yarn 2 ([#10847](https://github.com/facebook/jest/pull/10847)) From b144f11275aacc3ef0a3bd371aa5a851cdeb4010 Mon Sep 17 00:00:00 2001 From: Rob Brackett Date: Tue, 18 May 2021 23:23:11 -0700 Subject: [PATCH 11/13] Follow existing test style without `--forceExit` --- .../__snapshots__/detectOpenHandles.ts.snap | 32 +++++++++++++++++++ e2e/__tests__/detectOpenHandles.ts | 13 +++++--- .../__tests__/in-done-function.js | 9 ++---- .../__tests__/in-done-lifecycle.js | 7 ++-- 4 files changed, 45 insertions(+), 16 deletions(-) diff --git a/e2e/__tests__/__snapshots__/detectOpenHandles.ts.snap b/e2e/__tests__/__snapshots__/detectOpenHandles.ts.snap index 54666f5a111c..c81ba25f9773 100644 --- a/e2e/__tests__/__snapshots__/detectOpenHandles.ts.snap +++ b/e2e/__tests__/__snapshots__/detectOpenHandles.ts.snap @@ -38,3 +38,35 @@ Jest has detected the following 1 open handle potentially keeping Jest from exit at Object.setTimeout (__tests__/inside.js:9:3) `; + +exports[`prints out info about open handlers from lifecycle functions with a \`done\` callback 1`] = ` +Jest has detected the following 1 open handle potentially keeping Jest from exiting: + + ● Timeout + + 7 | + 8 | beforeAll(done => { + > 9 | setTimeout(() => {}, 10000); + | ^ + 10 | done(); + 11 | }); + 12 | + + at Object.setTimeout (__tests__/in-done-lifecycle.js:9:3) +`; + +exports[`prints out info about open handlers from tests with a \`done\` callback 1`] = ` +Jest has detected the following 1 open handle potentially keeping Jest from exiting: + + ● Timeout + + 7 | + 8 | test('something', done => { + > 9 | setTimeout(() => {}, 10000); + | ^ + 10 | expect(true).toBe(true); + 11 | done(); + 12 | }); + + at Object.setTimeout (__tests__/in-done-function.js:9:3) +`; diff --git a/e2e/__tests__/detectOpenHandles.ts b/e2e/__tests__/detectOpenHandles.ts index 0f2095f07875..98c2d20cb915 100644 --- a/e2e/__tests__/detectOpenHandles.ts +++ b/e2e/__tests__/detectOpenHandles.ts @@ -125,23 +125,26 @@ it('prints out info about open handlers from inside tests', async () => { }); it('prints out info about open handlers from tests with a `done` callback', async () => { - const {stderr} = runJest('detect-open-handles', [ + const run = runContinuous('detect-open-handles', [ 'in-done-function', '--detectOpenHandles', - '--forceExit', ]); + await run.waitUntil(({stderr}) => stderr.includes('Jest has detected')); + const {stderr} = await run.end(); const textAfterTest = getTextAfterTest(stderr); - expect(textAfterTest).toContain('TCPSERVERWRAP'); + expect(wrap(textAfterTest)).toMatchSnapshot(); }); it('prints out info about open handlers from lifecycle functions with a `done` callback', async () => { - const {stderr} = runJest('detect-open-handles', [ + const run = runContinuous('detect-open-handles', [ 'in-done-lifecycle', '--detectOpenHandles', '--forceExit', ]); + await run.waitUntil(({stderr}) => stderr.includes('Jest has detected')); + const {stderr} = await run.end(); const textAfterTest = getTextAfterTest(stderr); - expect(textAfterTest).toContain('TCPSERVERWRAP'); + expect(wrap(textAfterTest)).toMatchSnapshot(); }); diff --git a/e2e/detect-open-handles/__tests__/in-done-function.js b/e2e/detect-open-handles/__tests__/in-done-function.js index db6e9bd903b2..655a5c93ad80 100644 --- a/e2e/detect-open-handles/__tests__/in-done-function.js +++ b/e2e/detect-open-handles/__tests__/in-done-function.js @@ -4,12 +4,9 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ -const http = require('http'); test('something', done => { - const server = http.createServer((_, response) => response.end('ok')); - server.listen(0, () => { - expect(true).toBe(true); - done(); - }); + setTimeout(() => {}, 10000); + expect(true).toBe(true); + done(); }); diff --git a/e2e/detect-open-handles/__tests__/in-done-lifecycle.js b/e2e/detect-open-handles/__tests__/in-done-lifecycle.js index 096f727eca8f..1c4f2456491c 100644 --- a/e2e/detect-open-handles/__tests__/in-done-lifecycle.js +++ b/e2e/detect-open-handles/__tests__/in-done-lifecycle.js @@ -4,13 +4,10 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ -const http = require('http'); beforeAll(done => { - const server = http.createServer((_, response) => response.end('ok')); - server.listen(0, () => { - done(); - }); + setTimeout(() => {}, 10000); + done(); }); test('something', () => { From 6eb3969f014d5fb9295e0f4f480b65ea212954aa Mon Sep 17 00:00:00 2001 From: Rob Brackett Date: Wed, 19 May 2021 01:15:53 -0700 Subject: [PATCH 12/13] Tweak implementation to pass both Jasmine & Circus --- e2e/__tests__/__snapshots__/detectOpenHandles.ts.snap | 2 +- packages/jest-jasmine2/src/jasmineAsyncInstall.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/__tests__/__snapshots__/detectOpenHandles.ts.snap b/e2e/__tests__/__snapshots__/detectOpenHandles.ts.snap index c81ba25f9773..f679a6e076f5 100644 --- a/e2e/__tests__/__snapshots__/detectOpenHandles.ts.snap +++ b/e2e/__tests__/__snapshots__/detectOpenHandles.ts.snap @@ -52,7 +52,7 @@ Jest has detected the following 1 open handle potentially keeping Jest from exit 11 | }); 12 | - at Object.setTimeout (__tests__/in-done-lifecycle.js:9:3) + at setTimeout (__tests__/in-done-lifecycle.js:9:3) `; exports[`prints out info about open handlers from tests with a \`done\` callback 1`] = ` diff --git a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts index be33f5b41bbc..90e5fe0fe0ae 100644 --- a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts +++ b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts @@ -59,7 +59,7 @@ function promisifyLifeCycleFunction( ...args: Array ) { // @ts-expect-error: Support possible extra args at runtime - return fn.apply(this, args); + return fn(...args); }; return originalFn.call(env, asyncJestLifecycleWithCallback, timeout); } From 4803a6ce6a96109007a7970e00ea71e7ef482036 Mon Sep 17 00:00:00 2001 From: Rob Brackett Date: Wed, 19 May 2021 01:38:13 -0700 Subject: [PATCH 13/13] Revert to previous implementation and tweak test --- e2e/__tests__/detectOpenHandles.ts | 11 +++++++++-- packages/jest-jasmine2/src/jasmineAsyncInstall.ts | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/e2e/__tests__/detectOpenHandles.ts b/e2e/__tests__/detectOpenHandles.ts index 98c2d20cb915..f070f4b9e25b 100644 --- a/e2e/__tests__/detectOpenHandles.ts +++ b/e2e/__tests__/detectOpenHandles.ts @@ -140,11 +140,18 @@ it('prints out info about open handlers from lifecycle functions with a `done` c const run = runContinuous('detect-open-handles', [ 'in-done-lifecycle', '--detectOpenHandles', - '--forceExit', ]); await run.waitUntil(({stderr}) => stderr.includes('Jest has detected')); const {stderr} = await run.end(); - const textAfterTest = getTextAfterTest(stderr); + let textAfterTest = getTextAfterTest(stderr); + + // Circus and Jasmine have different contexts, leading to slightly different + // names for call stack functions. The difference shouldn't be problematic + // for users, so this normalizes them so the test works in both environments. + textAfterTest = textAfterTest.replace( + 'at Object.setTimeout', + 'at setTimeout', + ); expect(wrap(textAfterTest)).toMatchSnapshot(); }); diff --git a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts index 90e5fe0fe0ae..be33f5b41bbc 100644 --- a/packages/jest-jasmine2/src/jasmineAsyncInstall.ts +++ b/packages/jest-jasmine2/src/jasmineAsyncInstall.ts @@ -59,7 +59,7 @@ function promisifyLifeCycleFunction( ...args: Array ) { // @ts-expect-error: Support possible extra args at runtime - return fn(...args); + return fn.apply(this, args); }; return originalFn.call(env, asyncJestLifecycleWithCallback, timeout); }