From c0e975efad8f7176b5cada396a588acdb526331f Mon Sep 17 00:00:00 2001 From: CircleCI Date: Fri, 16 Dec 2022 23:24:36 +0100 Subject: [PATCH 01/13] feat: add isolateModulesAsync Introduce `jest.isolateModulesAsync`, the async equivalent of `jest.isolateModules`. --- packages/jest-environment/src/index.ts | 6 + .../runtime_require_module_or_mock.test.js | 132 +++++++++++++++++- .../__tests__/test_root/ModuleWithState.js | 4 + packages/jest-runtime/src/index.ts | 25 +++- .../jest-types/__typetests__/jest.test.ts | 3 + 5 files changed, 167 insertions(+), 3 deletions(-) diff --git a/packages/jest-environment/src/index.ts b/packages/jest-environment/src/index.ts index df50111e37f5..ca9b067a4c96 100644 --- a/packages/jest-environment/src/index.ts +++ b/packages/jest-environment/src/index.ts @@ -172,6 +172,12 @@ export interface Jest { * local module state doesn't conflict between tests. */ isolateModules(fn: () => void): Jest; + /** + * `jest.isolateModulesAsync()` is the equivalent of `jest.isolateModules()`, but for + * async functions to be wrapped. The caller is expected to `await` the completion of + * `isolateModulesAsync`. + */ + isolateModulesAsync(fn: () => void): Promise; /** * Mocks a module with an auto-mocked version when it is being required. */ diff --git a/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js b/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js index 8e28832c9d6a..f9417f49d3ad 100644 --- a/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js +++ b/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js @@ -214,7 +214,7 @@ describe('resetModules', () => { }); describe('isolateModules', () => { - it("keeps it's registry isolated from global one", async () => { + it("keeps its registry isolated from global one", async () => { const runtime = await createRuntime(__filename, { moduleNameMapper, }); @@ -287,7 +287,7 @@ describe('isolateModules', () => { runtime.isolateModules(() => {}); }); }).toThrow( - 'isolateModules cannot be nested inside another isolateModules.', + 'isolateModules cannot be nested inside another isolateModules or isolateModulesAsync.', ); }); @@ -325,6 +325,7 @@ describe('isolateModules', () => { beforeEach(() => { jest.isolateModules(() => { exports = require('./test_root/ModuleWithState'); + exports.set(1); // Ensure idempotency with the isolateModulesAsync test }); }); @@ -340,3 +341,130 @@ describe('isolateModules', () => { }); }); }); + +describe('isolateModulesAsync', () => { + it("keeps its registry isolated from global one", async () => { + const runtime = await createRuntime(__filename, { + moduleNameMapper, + }); + let exports; + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + exports.increment(); + expect(exports.getState()).toBe(2); + + await runtime.isolateModulesAsync(() => { + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + expect(exports.getState()).toBe(1); + }); + + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + expect(exports.getState()).toBe(2); + }); + + it('resets all modules after the block', async () => { + const runtime = await createRuntime(__filename, { + moduleNameMapper, + }); + let exports; + await runtime.isolateModulesAsync(() => { + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + expect(exports.getState()).toBe(1); + exports.increment(); + expect(exports.getState()).toBe(2); + }); + + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + expect(exports.getState()).toBe(1); + }); + + it('resets module after failing', async () => { + const runtime = await createRuntime(__filename, { + moduleNameMapper, + }); + await expect(runtime.isolateModulesAsync(async () => { + throw new Error('Error from isolated module'); + })).rejects.toThrow('Error from isolated module'); + + await runtime.isolateModulesAsync(async () => { + expect(true).toBe(true); + }); + }); + + it('cannot nest isolateModulesAsync blocks', async () => { + const runtime = await createRuntime(__filename, { + moduleNameMapper, + }); + await expect(async () => { + await runtime.isolateModulesAsync(async () => { + await runtime.isolateModulesAsync(() => {}); + }); + }).rejects.toThrow( + 'isolateModulesAsync cannot be nested inside another isolateModules or isolateModulesAsync.', + ); + }); + + it('can call resetModules within a isolateModules block', async () => { + const runtime = await createRuntime(__filename, { + moduleNameMapper, + }); + let exports; + await runtime.isolateModulesAsync(() => { + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + expect(exports.getState()).toBe(1); + + exports.increment(); + runtime.resetModules(); + + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + expect(exports.getState()).toBe(1); + }); + + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + expect(exports.getState()).toBe(1); + }); + + describe('can use isolateModulesAsync from a beforeEach block', () => { + let exports; + beforeEach(async () => { + await jest.isolateModulesAsync(async () => { + exports = require('./test_root/ModuleWithState'); + exports.set(1); // Ensure idempotency with the isolateModules test + }); + }); + + it('can use the required module from beforeEach and re-require it', () => { + expect(exports.getState()).toBe(1); + exports.increment(); + expect(exports.getState()).toBe(2); + + exports = require('./test_root/ModuleWithState'); + expect(exports.getState()).toBe(2); + exports.increment(); + expect(exports.getState()).toBe(3); + }); + }); +}); \ No newline at end of file diff --git a/packages/jest-runtime/src/__tests__/test_root/ModuleWithState.js b/packages/jest-runtime/src/__tests__/test_root/ModuleWithState.js index 220e11d1b0fe..caf5ce103b25 100644 --- a/packages/jest-runtime/src/__tests__/test_root/ModuleWithState.js +++ b/packages/jest-runtime/src/__tests__/test_root/ModuleWithState.js @@ -8,6 +8,10 @@ let state = 1; +export const set = (i) => { + state = i; +}; + export const increment = () => { state += 1; }; diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index c278d77052c5..c8ad7b6fa144 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -1125,7 +1125,7 @@ export default class Runtime { isolateModules(fn: () => void): void { if (this._isolatedModuleRegistry || this._isolatedMockRegistry) { throw new Error( - 'isolateModules cannot be nested inside another isolateModules.', + 'isolateModules cannot be nested inside another isolateModules or isolateModulesAsync.', ); } this._isolatedModuleRegistry = new Map(); @@ -1141,6 +1141,25 @@ export default class Runtime { } } + async isolateModulesAsync(fn: () => void): Promise { + if (this._isolatedModuleRegistry || this._isolatedMockRegistry) { + throw new Error( + 'isolateModulesAsync cannot be nested inside another isolateModules or isolateModulesAsync.', + ); + } + this._isolatedModuleRegistry = new Map(); + this._isolatedMockRegistry = new Map(); + try { + await fn(); + } finally { + // might be cleared within the callback + this._isolatedModuleRegistry?.clear(); + this._isolatedMockRegistry?.clear(); + this._isolatedModuleRegistry = null; + this._isolatedMockRegistry = null; + } + } + resetModules(): void { this._isolatedModuleRegistry?.clear(); this._isolatedMockRegistry?.clear(); @@ -2161,6 +2180,9 @@ export default class Runtime { this.isolateModules(fn); return jestObject; }; + const isolateModulesAsync = async(fn: () => void) => { + return this.isolateModulesAsync(fn); + } const fn = this._moduleMocker.fn.bind(this._moduleMocker); const spyOn = this._moduleMocker.spyOn.bind(this._moduleMocker); const mocked = @@ -2226,6 +2248,7 @@ export default class Runtime { getTimerCount: () => _getFakeTimers().getTimerCount(), isMockFunction: this._moduleMocker.isMockFunction, isolateModules, + isolateModulesAsync, mock, mocked, now: () => _getFakeTimers().now(), diff --git a/packages/jest-types/__typetests__/jest.test.ts b/packages/jest-types/__typetests__/jest.test.ts index ad5717d43645..1f19a185fc59 100644 --- a/packages/jest-types/__typetests__/jest.test.ts +++ b/packages/jest-types/__typetests__/jest.test.ts @@ -98,6 +98,9 @@ expectError(jest.enableAutomock('moduleName')); expectType(jest.isolateModules(() => {})); expectError(jest.isolateModules()); +expectType(jest.isolateModulesAsync(() => {})); +expectError(jest.isolateModulesAsync()); + expectType(jest.mock('moduleName')); expectType(jest.mock('moduleName', jest.fn())); expectType( From e688b0ed370cd34af39a042932add1292d9310cf Mon Sep 17 00:00:00 2001 From: CircleCI Date: Fri, 16 Dec 2022 23:39:32 +0100 Subject: [PATCH 02/13] chore: update CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07f7984aa970..111b77f7b430 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ### Features +- `[jest-runtime]` Add `jest.isolateModulesAsync` for scoped module initialization of asynchronous functions ([#13680](https://github.com/facebook/jest/pull/13680)) + + ### Fixes - `[jest-resolve]` add global paths to `require.resolve.paths` ([#13633](https://github.com/facebook/jest/pull/13633)) From c45aaa9ea4e79728c920031618bddf7f96eaaac6 Mon Sep 17 00:00:00 2001 From: Michele Mancioppi Date: Mon, 19 Dec 2022 08:02:49 +0100 Subject: [PATCH 03/13] Update packages/jest-runtime/src/index.ts Co-authored-by: Tom Mrazauskas --- packages/jest-runtime/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index c8ad7b6fa144..b4a01c05312e 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -1144,7 +1144,7 @@ export default class Runtime { async isolateModulesAsync(fn: () => void): Promise { if (this._isolatedModuleRegistry || this._isolatedMockRegistry) { throw new Error( - 'isolateModulesAsync cannot be nested inside another isolateModules or isolateModulesAsync.', + 'isolateModulesAsync cannot be nested inside another isolateModulesAsync or isolateModules.', ); } this._isolatedModuleRegistry = new Map(); From b53d9dada967ccffab1a95730b1a263f9cee4fb5 Mon Sep 17 00:00:00 2001 From: CircleCI Date: Mon, 19 Dec 2022 08:12:11 +0100 Subject: [PATCH 04/13] change return type of isolateModulesAsync to returning a Promise of Jest --- packages/jest-environment/src/index.ts | 2 +- packages/jest-runtime/src/index.ts | 3 ++- packages/jest-types/__typetests__/jest.test.ts | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/jest-environment/src/index.ts b/packages/jest-environment/src/index.ts index ca9b067a4c96..f5c1eddadbf5 100644 --- a/packages/jest-environment/src/index.ts +++ b/packages/jest-environment/src/index.ts @@ -177,7 +177,7 @@ export interface Jest { * async functions to be wrapped. The caller is expected to `await` the completion of * `isolateModulesAsync`. */ - isolateModulesAsync(fn: () => void): Promise; + isolateModulesAsync(fn: () => void): Promise; /** * Mocks a module with an auto-mocked version when it is being required. */ diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index b4a01c05312e..9c91a9508fd9 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -2181,7 +2181,8 @@ export default class Runtime { return jestObject; }; const isolateModulesAsync = async(fn: () => void) => { - return this.isolateModulesAsync(fn); + await this.isolateModulesAsync(fn); + return Promise.resolve(jestObject); } const fn = this._moduleMocker.fn.bind(this._moduleMocker); const spyOn = this._moduleMocker.spyOn.bind(this._moduleMocker); diff --git a/packages/jest-types/__typetests__/jest.test.ts b/packages/jest-types/__typetests__/jest.test.ts index 1f19a185fc59..30a3a36297e9 100644 --- a/packages/jest-types/__typetests__/jest.test.ts +++ b/packages/jest-types/__typetests__/jest.test.ts @@ -98,7 +98,7 @@ expectError(jest.enableAutomock('moduleName')); expectType(jest.isolateModules(() => {})); expectError(jest.isolateModules()); -expectType(jest.isolateModulesAsync(() => {})); +expectType(jest.isolateModulesAsync(() => Promise.resolve(jest.fn()))); expectError(jest.isolateModulesAsync()); expectType(jest.mock('moduleName')); From 442588b77eedf913588f0a4d738c28a3eaad1385 Mon Sep 17 00:00:00 2001 From: Michele Mancioppi Date: Mon, 19 Dec 2022 10:31:15 +0100 Subject: [PATCH 05/13] Update packages/jest-types/__typetests__/jest.test.ts Co-authored-by: Tom Mrazauskas --- packages/jest-types/__typetests__/jest.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jest-types/__typetests__/jest.test.ts b/packages/jest-types/__typetests__/jest.test.ts index 30a3a36297e9..ec4d779d86ca 100644 --- a/packages/jest-types/__typetests__/jest.test.ts +++ b/packages/jest-types/__typetests__/jest.test.ts @@ -98,7 +98,7 @@ expectError(jest.enableAutomock('moduleName')); expectType(jest.isolateModules(() => {})); expectError(jest.isolateModules()); -expectType(jest.isolateModulesAsync(() => Promise.resolve(jest.fn()))); +expectType>(jest.isolateModulesAsync(async () => {})); expectError(jest.isolateModulesAsync()); expectType(jest.mock('moduleName')); From 5810116f02db4f5b0ca78a0f49be40de0f925a1d Mon Sep 17 00:00:00 2001 From: CircleCI Date: Mon, 19 Dec 2022 11:43:20 +0100 Subject: [PATCH 06/13] change isolateModulesAsync to return Promise --- packages/jest-environment/src/index.ts | 2 +- .../src/__tests__/runtime_require_module_or_mock.test.js | 8 ++++---- packages/jest-runtime/src/index.ts | 5 ++--- packages/jest-types/__typetests__/jest.test.ts | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/packages/jest-environment/src/index.ts b/packages/jest-environment/src/index.ts index f5c1eddadbf5..f2b3bf4ee961 100644 --- a/packages/jest-environment/src/index.ts +++ b/packages/jest-environment/src/index.ts @@ -177,7 +177,7 @@ export interface Jest { * async functions to be wrapped. The caller is expected to `await` the completion of * `isolateModulesAsync`. */ - isolateModulesAsync(fn: () => void): Promise; + isolateModulesAsync(fn: () => Promise): Promise; /** * Mocks a module with an auto-mocked version when it is being required. */ diff --git a/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js b/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js index f9417f49d3ad..679114597f7b 100644 --- a/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js +++ b/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js @@ -355,7 +355,7 @@ describe('isolateModulesAsync', () => { exports.increment(); expect(exports.getState()).toBe(2); - await runtime.isolateModulesAsync(() => { + await runtime.isolateModulesAsync(async () => { exports = runtime.requireModuleOrMock( runtime.__mockRootPath, 'ModuleWithState', @@ -375,7 +375,7 @@ describe('isolateModulesAsync', () => { moduleNameMapper, }); let exports; - await runtime.isolateModulesAsync(() => { + await runtime.isolateModulesAsync(async () => { exports = runtime.requireModuleOrMock( runtime.__mockRootPath, 'ModuleWithState', @@ -411,7 +411,7 @@ describe('isolateModulesAsync', () => { }); await expect(async () => { await runtime.isolateModulesAsync(async () => { - await runtime.isolateModulesAsync(() => {}); + await runtime.isolateModulesAsync(() => Promise.resolve()); }); }).rejects.toThrow( 'isolateModulesAsync cannot be nested inside another isolateModules or isolateModulesAsync.', @@ -423,7 +423,7 @@ describe('isolateModulesAsync', () => { moduleNameMapper, }); let exports; - await runtime.isolateModulesAsync(() => { + await runtime.isolateModulesAsync(async () => { exports = runtime.requireModuleOrMock( runtime.__mockRootPath, 'ModuleWithState', diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index 9c91a9508fd9..f5ad694b2772 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -1141,7 +1141,7 @@ export default class Runtime { } } - async isolateModulesAsync(fn: () => void): Promise { + async isolateModulesAsync(fn: () => Promise): Promise { if (this._isolatedModuleRegistry || this._isolatedMockRegistry) { throw new Error( 'isolateModulesAsync cannot be nested inside another isolateModulesAsync or isolateModules.', @@ -2180,9 +2180,8 @@ export default class Runtime { this.isolateModules(fn); return jestObject; }; - const isolateModulesAsync = async(fn: () => void) => { + const isolateModulesAsync = async(fn: () => Promise) => { await this.isolateModulesAsync(fn); - return Promise.resolve(jestObject); } const fn = this._moduleMocker.fn.bind(this._moduleMocker); const spyOn = this._moduleMocker.spyOn.bind(this._moduleMocker); diff --git a/packages/jest-types/__typetests__/jest.test.ts b/packages/jest-types/__typetests__/jest.test.ts index ec4d779d86ca..05f3562c43bf 100644 --- a/packages/jest-types/__typetests__/jest.test.ts +++ b/packages/jest-types/__typetests__/jest.test.ts @@ -98,7 +98,7 @@ expectError(jest.enableAutomock('moduleName')); expectType(jest.isolateModules(() => {})); expectError(jest.isolateModules()); -expectType>(jest.isolateModulesAsync(async () => {})); +expectType>(jest.isolateModulesAsync(async () => {})); expectError(jest.isolateModulesAsync()); expectType(jest.mock('moduleName')); From de40383575abff51b860326256b11ec851164efc Mon Sep 17 00:00:00 2001 From: CircleCI Date: Mon, 19 Dec 2022 11:43:26 +0100 Subject: [PATCH 07/13] lint --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 111b77f7b430..884f8501b0a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,6 @@ - `[jest-runtime]` Add `jest.isolateModulesAsync` for scoped module initialization of asynchronous functions ([#13680](https://github.com/facebook/jest/pull/13680)) - ### Fixes - `[jest-resolve]` add global paths to `require.resolve.paths` ([#13633](https://github.com/facebook/jest/pull/13633)) From f88db2b8edd2e604483729f675dcdfad99806451 Mon Sep 17 00:00:00 2001 From: CircleCI Date: Mon, 19 Dec 2022 11:43:43 +0100 Subject: [PATCH 08/13] add website docs for isolateModulesAsync --- docs/JestObjectAPI.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/JestObjectAPI.md b/docs/JestObjectAPI.md index a961dab0fd0d..8f52dbb28403 100644 --- a/docs/JestObjectAPI.md +++ b/docs/JestObjectAPI.md @@ -568,6 +568,20 @@ jest.isolateModules(() => { const otherCopyOfMyModule = require('myModule'); ``` +### `jest.isolateModulesAsync(fn)` + +`jest.isolateModulesAsync()` is the equivalent of `jest.isolateModules()`, but for async functions that need to be wrapped. The caller is expected to `await` the completion of `isolateModulesAsync`. + +```js +let myModule; +await jest.isolateModulesAsync(async () => { + constmyModule = require('myModule'); + // do async stuff here +}); + +const otherCopyOfMyModule = require('myModule'); +``` + ## Mock Functions ### `jest.fn(implementation?)` From 18405a8dcad6e9da6e932102c803796a08011ce8 Mon Sep 17 00:00:00 2001 From: CircleCI Date: Mon, 19 Dec 2022 11:53:54 +0100 Subject: [PATCH 09/13] fix unit test to accept new error message --- .../src/__tests__/runtime_require_module_or_mock.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js b/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js index 679114597f7b..2fde6b8e0ee0 100644 --- a/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js +++ b/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js @@ -414,7 +414,7 @@ describe('isolateModulesAsync', () => { await runtime.isolateModulesAsync(() => Promise.resolve()); }); }).rejects.toThrow( - 'isolateModulesAsync cannot be nested inside another isolateModules or isolateModulesAsync.', + 'isolateModulesAsync cannot be nested inside another isolateModulesAsync or isolateModules.', ); }); From 4045eb7db50e9c2a6e8f21273b93088be2f8bbb0 Mon Sep 17 00:00:00 2001 From: CircleCI Date: Mon, 19 Dec 2022 11:58:25 +0100 Subject: [PATCH 10/13] lint --- .../runtime_require_module_or_mock.test.js | 18 ++++++++++-------- .../src/__tests__/test_root/ModuleWithState.js | 2 +- packages/jest-runtime/src/index.ts | 4 ++-- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js b/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js index 2fde6b8e0ee0..e49457ed67eb 100644 --- a/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js +++ b/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js @@ -214,7 +214,7 @@ describe('resetModules', () => { }); describe('isolateModules', () => { - it("keeps its registry isolated from global one", async () => { + it('keeps its registry isolated from global one', async () => { const runtime = await createRuntime(__filename, { moduleNameMapper, }); @@ -325,7 +325,7 @@ describe('isolateModules', () => { beforeEach(() => { jest.isolateModules(() => { exports = require('./test_root/ModuleWithState'); - exports.set(1); // Ensure idempotency with the isolateModulesAsync test + exports.set(1); // Ensure idempotency with the isolateModulesAsync test }); }); @@ -343,7 +343,7 @@ describe('isolateModules', () => { }); describe('isolateModulesAsync', () => { - it("keeps its registry isolated from global one", async () => { + it('keeps its registry isolated from global one', async () => { const runtime = await createRuntime(__filename, { moduleNameMapper, }); @@ -396,9 +396,11 @@ describe('isolateModulesAsync', () => { const runtime = await createRuntime(__filename, { moduleNameMapper, }); - await expect(runtime.isolateModulesAsync(async () => { - throw new Error('Error from isolated module'); - })).rejects.toThrow('Error from isolated module'); + await expect( + runtime.isolateModulesAsync(async () => { + throw new Error('Error from isolated module'); + }), + ).rejects.toThrow('Error from isolated module'); await runtime.isolateModulesAsync(async () => { expect(true).toBe(true); @@ -452,7 +454,7 @@ describe('isolateModulesAsync', () => { beforeEach(async () => { await jest.isolateModulesAsync(async () => { exports = require('./test_root/ModuleWithState'); - exports.set(1); // Ensure idempotency with the isolateModules test + exports.set(1); // Ensure idempotency with the isolateModules test }); }); @@ -467,4 +469,4 @@ describe('isolateModulesAsync', () => { expect(exports.getState()).toBe(3); }); }); -}); \ No newline at end of file +}); diff --git a/packages/jest-runtime/src/__tests__/test_root/ModuleWithState.js b/packages/jest-runtime/src/__tests__/test_root/ModuleWithState.js index caf5ce103b25..b8c0236109be 100644 --- a/packages/jest-runtime/src/__tests__/test_root/ModuleWithState.js +++ b/packages/jest-runtime/src/__tests__/test_root/ModuleWithState.js @@ -8,7 +8,7 @@ let state = 1; -export const set = (i) => { +export const set = i => { state = i; }; diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index f5ad694b2772..44b68ebf5adc 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -2180,9 +2180,9 @@ export default class Runtime { this.isolateModules(fn); return jestObject; }; - const isolateModulesAsync = async(fn: () => Promise) => { + const isolateModulesAsync = async (fn: () => Promise) => { await this.isolateModulesAsync(fn); - } + }; const fn = this._moduleMocker.fn.bind(this._moduleMocker); const spyOn = this._moduleMocker.spyOn.bind(this._moduleMocker); const mocked = From 36c138e2a5cd8796f67a78ae624e5d581ee93d0e Mon Sep 17 00:00:00 2001 From: CircleCI Date: Mon, 19 Dec 2022 14:14:55 +0100 Subject: [PATCH 11/13] test sync callbacks, add docu and type test --- docs/JestObjectAPI.md | 14 +- .../runtime_require_module_or_mock.test.js | 242 +++++++++++++----- packages/jest-runtime/src/index.ts | 7 +- .../jest-types/__typetests__/jest.test.ts | 1 + 4 files changed, 192 insertions(+), 72 deletions(-) diff --git a/docs/JestObjectAPI.md b/docs/JestObjectAPI.md index 8f52dbb28403..5c056c51f72e 100644 --- a/docs/JestObjectAPI.md +++ b/docs/JestObjectAPI.md @@ -575,13 +575,25 @@ const otherCopyOfMyModule = require('myModule'); ```js let myModule; await jest.isolateModulesAsync(async () => { - constmyModule = require('myModule'); + myModule = await import('myModule'); // do async stuff here }); const otherCopyOfMyModule = require('myModule'); ``` +`jest.isolateModulesAsync()` can also run synchronous callbacks: + +```js +let myModule; +await jest.isolateModulesAsync(() => { + myModule = require('myModule'); + // do sync stuff here +}); + +const otherCopyOfMyModule = require('myModule'); +``` + ## Mock Functions ### `jest.fn(implementation?)` diff --git a/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js b/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js index e49457ed67eb..34a748933577 100644 --- a/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js +++ b/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js @@ -343,97 +343,213 @@ describe('isolateModules', () => { }); describe('isolateModulesAsync', () => { - it('keeps its registry isolated from global one', async () => { - const runtime = await createRuntime(__filename, { - moduleNameMapper, - }); - let exports; - exports = runtime.requireModuleOrMock( - runtime.__mockRootPath, - 'ModuleWithState', - ); - exports.increment(); - expect(exports.getState()).toBe(2); + describe('with sync callback', () => { + it('keeps its registry isolated from global one', async () => { + const runtime = await createRuntime(__filename, { + moduleNameMapper, + }); + let exports; + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + exports.increment(); + expect(exports.getState()).toBe(2); + + await runtime.isolateModulesAsync(() => { + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + expect(exports.getState()).toBe(1); + }); - await runtime.isolateModulesAsync(async () => { exports = runtime.requireModuleOrMock( runtime.__mockRootPath, 'ModuleWithState', ); - expect(exports.getState()).toBe(1); + expect(exports.getState()).toBe(2); }); - exports = runtime.requireModuleOrMock( - runtime.__mockRootPath, - 'ModuleWithState', - ); - expect(exports.getState()).toBe(2); - }); + it('resets all modules after the block', async () => { + const runtime = await createRuntime(__filename, { + moduleNameMapper, + }); + let exports; + await runtime.isolateModulesAsync(() => { + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + expect(exports.getState()).toBe(1); + exports.increment(); + expect(exports.getState()).toBe(2); + }); - it('resets all modules after the block', async () => { - const runtime = await createRuntime(__filename, { - moduleNameMapper, - }); - let exports; - await runtime.isolateModulesAsync(async () => { exports = runtime.requireModuleOrMock( runtime.__mockRootPath, 'ModuleWithState', ); expect(exports.getState()).toBe(1); - exports.increment(); - expect(exports.getState()).toBe(2); }); - exports = runtime.requireModuleOrMock( - runtime.__mockRootPath, - 'ModuleWithState', - ); - expect(exports.getState()).toBe(1); - }); + it('resets module after failing', async () => { + const runtime = await createRuntime(__filename, { + moduleNameMapper, + }); + await expect( + runtime.isolateModulesAsync(() => { + throw new Error('Error from isolated module'); + }), + ).rejects.toThrow('Error from isolated module'); + + await runtime.isolateModulesAsync(() => { + expect(true).toBe(true); + }); + }); - it('resets module after failing', async () => { - const runtime = await createRuntime(__filename, { - moduleNameMapper, + it('cannot nest isolateModulesAsync blocks', async () => { + const runtime = await createRuntime(__filename, { + moduleNameMapper, + }); + await expect(async () => { + await runtime.isolateModulesAsync(async () => { + await runtime.isolateModulesAsync(() => {}); + }); + }).rejects.toThrow( + 'isolateModulesAsync cannot be nested inside another isolateModulesAsync or isolateModules.', + ); }); - await expect( - runtime.isolateModulesAsync(async () => { - throw new Error('Error from isolated module'); - }), - ).rejects.toThrow('Error from isolated module'); - await runtime.isolateModulesAsync(async () => { - expect(true).toBe(true); + it('can call resetModules within a isolateModules block', async () => { + const runtime = await createRuntime(__filename, { + moduleNameMapper, + }); + let exports; + await runtime.isolateModulesAsync(() => { + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + expect(exports.getState()).toBe(1); + + exports.increment(); + runtime.resetModules(); + + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + expect(exports.getState()).toBe(1); + }); + + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + expect(exports.getState()).toBe(1); }); }); - it('cannot nest isolateModulesAsync blocks', async () => { - const runtime = await createRuntime(__filename, { - moduleNameMapper, - }); - await expect(async () => { + describe('with async callback', () => { + it('keeps its registry isolated from global one', async () => { + const runtime = await createRuntime(__filename, { + moduleNameMapper, + }); + let exports; + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + exports.increment(); + expect(exports.getState()).toBe(2); + await runtime.isolateModulesAsync(async () => { - await runtime.isolateModulesAsync(() => Promise.resolve()); + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + expect(exports.getState()).toBe(1); }); - }).rejects.toThrow( - 'isolateModulesAsync cannot be nested inside another isolateModulesAsync or isolateModules.', - ); - }); - it('can call resetModules within a isolateModules block', async () => { - const runtime = await createRuntime(__filename, { - moduleNameMapper, + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + expect(exports.getState()).toBe(2); }); - let exports; - await runtime.isolateModulesAsync(async () => { + + it('resets all modules after the block', async () => { + const runtime = await createRuntime(__filename, { + moduleNameMapper, + }); + let exports; + await runtime.isolateModulesAsync(async () => { + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + expect(exports.getState()).toBe(1); + exports.increment(); + expect(exports.getState()).toBe(2); + }); + exports = runtime.requireModuleOrMock( runtime.__mockRootPath, 'ModuleWithState', ); expect(exports.getState()).toBe(1); + }); - exports.increment(); - runtime.resetModules(); + it('resets module after failing', async () => { + const runtime = await createRuntime(__filename, { + moduleNameMapper, + }); + await expect( + runtime.isolateModulesAsync(async () => { + throw new Error('Error from isolated module'); + }), + ).rejects.toThrow('Error from isolated module'); + + await runtime.isolateModulesAsync(async () => { + expect(true).toBe(true); + }); + }); + + it('cannot nest isolateModulesAsync blocks', async () => { + const runtime = await createRuntime(__filename, { + moduleNameMapper, + }); + await expect(async () => { + await runtime.isolateModulesAsync(async () => { + await runtime.isolateModulesAsync(() => Promise.resolve()); + }); + }).rejects.toThrow( + 'isolateModulesAsync cannot be nested inside another isolateModulesAsync or isolateModules.', + ); + }); + + it('can call resetModules within a isolateModules block', async () => { + const runtime = await createRuntime(__filename, { + moduleNameMapper, + }); + let exports; + await runtime.isolateModulesAsync(async () => { + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + expect(exports.getState()).toBe(1); + + exports.increment(); + runtime.resetModules(); + + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + expect(exports.getState()).toBe(1); + }); exports = runtime.requireModuleOrMock( runtime.__mockRootPath, @@ -441,12 +557,6 @@ describe('isolateModulesAsync', () => { ); expect(exports.getState()).toBe(1); }); - - exports = runtime.requireModuleOrMock( - runtime.__mockRootPath, - 'ModuleWithState', - ); - expect(exports.getState()).toBe(1); }); describe('can use isolateModulesAsync from a beforeEach block', () => { diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index 44b68ebf5adc..7cebee192704 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -1141,7 +1141,7 @@ export default class Runtime { } } - async isolateModulesAsync(fn: () => Promise): Promise { + async isolateModulesAsync(fn: () => Promise | void): Promise { if (this._isolatedModuleRegistry || this._isolatedMockRegistry) { throw new Error( 'isolateModulesAsync cannot be nested inside another isolateModulesAsync or isolateModules.', @@ -2180,9 +2180,6 @@ export default class Runtime { this.isolateModules(fn); return jestObject; }; - const isolateModulesAsync = async (fn: () => Promise) => { - await this.isolateModulesAsync(fn); - }; const fn = this._moduleMocker.fn.bind(this._moduleMocker); const spyOn = this._moduleMocker.spyOn.bind(this._moduleMocker); const mocked = @@ -2248,7 +2245,7 @@ export default class Runtime { getTimerCount: () => _getFakeTimers().getTimerCount(), isMockFunction: this._moduleMocker.isMockFunction, isolateModules, - isolateModulesAsync, + isolateModulesAsync: this.isolateModulesAsync, mock, mocked, now: () => _getFakeTimers().now(), diff --git a/packages/jest-types/__typetests__/jest.test.ts b/packages/jest-types/__typetests__/jest.test.ts index 05f3562c43bf..d93dcd995f5d 100644 --- a/packages/jest-types/__typetests__/jest.test.ts +++ b/packages/jest-types/__typetests__/jest.test.ts @@ -99,6 +99,7 @@ expectType(jest.isolateModules(() => {})); expectError(jest.isolateModules()); expectType>(jest.isolateModulesAsync(async () => {})); +expectType>(jest.isolateModulesAsync(() => {})); expectError(jest.isolateModulesAsync()); expectType(jest.mock('moduleName')); From 326fa103e224d53f7a2998c2571996c8792f15fb Mon Sep 17 00:00:00 2001 From: Michele Mancioppi Date: Mon, 19 Dec 2022 14:50:12 +0100 Subject: [PATCH 12/13] Update docs/JestObjectAPI.md Co-authored-by: Tom Mrazauskas --- docs/JestObjectAPI.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/JestObjectAPI.md b/docs/JestObjectAPI.md index 5c056c51f72e..0d14c80aeed1 100644 --- a/docs/JestObjectAPI.md +++ b/docs/JestObjectAPI.md @@ -579,7 +579,7 @@ await jest.isolateModulesAsync(async () => { // do async stuff here }); -const otherCopyOfMyModule = require('myModule'); +const otherCopyOfMyModule = await import('myModule'); ``` `jest.isolateModulesAsync()` can also run synchronous callbacks: From f85df7f7a756408e68c8ab0208962b329adebb2c Mon Sep 17 00:00:00 2001 From: CircleCI Date: Mon, 19 Dec 2022 14:59:41 +0100 Subject: [PATCH 13/13] remove support for synchronous callbacks --- docs/JestObjectAPI.md | 14 +- .../runtime_require_module_or_mock.test.js | 242 +++++------------- packages/jest-runtime/src/index.ts | 2 +- .../jest-types/__typetests__/jest.test.ts | 2 +- 4 files changed, 69 insertions(+), 191 deletions(-) diff --git a/docs/JestObjectAPI.md b/docs/JestObjectAPI.md index 0d14c80aeed1..58634a135c85 100644 --- a/docs/JestObjectAPI.md +++ b/docs/JestObjectAPI.md @@ -570,7 +570,7 @@ const otherCopyOfMyModule = require('myModule'); ### `jest.isolateModulesAsync(fn)` -`jest.isolateModulesAsync()` is the equivalent of `jest.isolateModules()`, but for async functions that need to be wrapped. The caller is expected to `await` the completion of `isolateModulesAsync`. +`jest.isolateModulesAsync()` is the equivalent of `jest.isolateModules()`, but for async callbacks. The caller is expected to `await` the completion of `isolateModulesAsync`. ```js let myModule; @@ -582,18 +582,6 @@ await jest.isolateModulesAsync(async () => { const otherCopyOfMyModule = await import('myModule'); ``` -`jest.isolateModulesAsync()` can also run synchronous callbacks: - -```js -let myModule; -await jest.isolateModulesAsync(() => { - myModule = require('myModule'); - // do sync stuff here -}); - -const otherCopyOfMyModule = require('myModule'); -``` - ## Mock Functions ### `jest.fn(implementation?)` diff --git a/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js b/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js index 34a748933577..e49457ed67eb 100644 --- a/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js +++ b/packages/jest-runtime/src/__tests__/runtime_require_module_or_mock.test.js @@ -343,49 +343,19 @@ describe('isolateModules', () => { }); describe('isolateModulesAsync', () => { - describe('with sync callback', () => { - it('keeps its registry isolated from global one', async () => { - const runtime = await createRuntime(__filename, { - moduleNameMapper, - }); - let exports; - exports = runtime.requireModuleOrMock( - runtime.__mockRootPath, - 'ModuleWithState', - ); - exports.increment(); - expect(exports.getState()).toBe(2); - - await runtime.isolateModulesAsync(() => { - exports = runtime.requireModuleOrMock( - runtime.__mockRootPath, - 'ModuleWithState', - ); - expect(exports.getState()).toBe(1); - }); - - exports = runtime.requireModuleOrMock( - runtime.__mockRootPath, - 'ModuleWithState', - ); - expect(exports.getState()).toBe(2); + it('keeps its registry isolated from global one', async () => { + const runtime = await createRuntime(__filename, { + moduleNameMapper, }); + let exports; + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + exports.increment(); + expect(exports.getState()).toBe(2); - it('resets all modules after the block', async () => { - const runtime = await createRuntime(__filename, { - moduleNameMapper, - }); - let exports; - await runtime.isolateModulesAsync(() => { - exports = runtime.requireModuleOrMock( - runtime.__mockRootPath, - 'ModuleWithState', - ); - expect(exports.getState()).toBe(1); - exports.increment(); - expect(exports.getState()).toBe(2); - }); - + await runtime.isolateModulesAsync(async () => { exports = runtime.requireModuleOrMock( runtime.__mockRootPath, 'ModuleWithState', @@ -393,163 +363,77 @@ describe('isolateModulesAsync', () => { expect(exports.getState()).toBe(1); }); - it('resets module after failing', async () => { - const runtime = await createRuntime(__filename, { - moduleNameMapper, - }); - await expect( - runtime.isolateModulesAsync(() => { - throw new Error('Error from isolated module'); - }), - ).rejects.toThrow('Error from isolated module'); - - await runtime.isolateModulesAsync(() => { - expect(true).toBe(true); - }); - }); + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + expect(exports.getState()).toBe(2); + }); - it('cannot nest isolateModulesAsync blocks', async () => { - const runtime = await createRuntime(__filename, { - moduleNameMapper, - }); - await expect(async () => { - await runtime.isolateModulesAsync(async () => { - await runtime.isolateModulesAsync(() => {}); - }); - }).rejects.toThrow( - 'isolateModulesAsync cannot be nested inside another isolateModulesAsync or isolateModules.', - ); + it('resets all modules after the block', async () => { + const runtime = await createRuntime(__filename, { + moduleNameMapper, }); - - it('can call resetModules within a isolateModules block', async () => { - const runtime = await createRuntime(__filename, { - moduleNameMapper, - }); - let exports; - await runtime.isolateModulesAsync(() => { - exports = runtime.requireModuleOrMock( - runtime.__mockRootPath, - 'ModuleWithState', - ); - expect(exports.getState()).toBe(1); - - exports.increment(); - runtime.resetModules(); - - exports = runtime.requireModuleOrMock( - runtime.__mockRootPath, - 'ModuleWithState', - ); - expect(exports.getState()).toBe(1); - }); - + let exports; + await runtime.isolateModulesAsync(async () => { exports = runtime.requireModuleOrMock( runtime.__mockRootPath, 'ModuleWithState', ); expect(exports.getState()).toBe(1); - }); - }); - - describe('with async callback', () => { - it('keeps its registry isolated from global one', async () => { - const runtime = await createRuntime(__filename, { - moduleNameMapper, - }); - let exports; - exports = runtime.requireModuleOrMock( - runtime.__mockRootPath, - 'ModuleWithState', - ); exports.increment(); expect(exports.getState()).toBe(2); + }); - await runtime.isolateModulesAsync(async () => { - exports = runtime.requireModuleOrMock( - runtime.__mockRootPath, - 'ModuleWithState', - ); - expect(exports.getState()).toBe(1); - }); + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + expect(exports.getState()).toBe(1); + }); - exports = runtime.requireModuleOrMock( - runtime.__mockRootPath, - 'ModuleWithState', - ); - expect(exports.getState()).toBe(2); + it('resets module after failing', async () => { + const runtime = await createRuntime(__filename, { + moduleNameMapper, }); + await expect( + runtime.isolateModulesAsync(async () => { + throw new Error('Error from isolated module'); + }), + ).rejects.toThrow('Error from isolated module'); - it('resets all modules after the block', async () => { - const runtime = await createRuntime(__filename, { - moduleNameMapper, - }); - let exports; + await runtime.isolateModulesAsync(async () => { + expect(true).toBe(true); + }); + }); + + it('cannot nest isolateModulesAsync blocks', async () => { + const runtime = await createRuntime(__filename, { + moduleNameMapper, + }); + await expect(async () => { await runtime.isolateModulesAsync(async () => { - exports = runtime.requireModuleOrMock( - runtime.__mockRootPath, - 'ModuleWithState', - ); - expect(exports.getState()).toBe(1); - exports.increment(); - expect(exports.getState()).toBe(2); + await runtime.isolateModulesAsync(() => Promise.resolve()); }); + }).rejects.toThrow( + 'isolateModulesAsync cannot be nested inside another isolateModulesAsync or isolateModules.', + ); + }); + it('can call resetModules within a isolateModules block', async () => { + const runtime = await createRuntime(__filename, { + moduleNameMapper, + }); + let exports; + await runtime.isolateModulesAsync(async () => { exports = runtime.requireModuleOrMock( runtime.__mockRootPath, 'ModuleWithState', ); expect(exports.getState()).toBe(1); - }); - - it('resets module after failing', async () => { - const runtime = await createRuntime(__filename, { - moduleNameMapper, - }); - await expect( - runtime.isolateModulesAsync(async () => { - throw new Error('Error from isolated module'); - }), - ).rejects.toThrow('Error from isolated module'); - await runtime.isolateModulesAsync(async () => { - expect(true).toBe(true); - }); - }); - - it('cannot nest isolateModulesAsync blocks', async () => { - const runtime = await createRuntime(__filename, { - moduleNameMapper, - }); - await expect(async () => { - await runtime.isolateModulesAsync(async () => { - await runtime.isolateModulesAsync(() => Promise.resolve()); - }); - }).rejects.toThrow( - 'isolateModulesAsync cannot be nested inside another isolateModulesAsync or isolateModules.', - ); - }); - - it('can call resetModules within a isolateModules block', async () => { - const runtime = await createRuntime(__filename, { - moduleNameMapper, - }); - let exports; - await runtime.isolateModulesAsync(async () => { - exports = runtime.requireModuleOrMock( - runtime.__mockRootPath, - 'ModuleWithState', - ); - expect(exports.getState()).toBe(1); - - exports.increment(); - runtime.resetModules(); - - exports = runtime.requireModuleOrMock( - runtime.__mockRootPath, - 'ModuleWithState', - ); - expect(exports.getState()).toBe(1); - }); + exports.increment(); + runtime.resetModules(); exports = runtime.requireModuleOrMock( runtime.__mockRootPath, @@ -557,6 +441,12 @@ describe('isolateModulesAsync', () => { ); expect(exports.getState()).toBe(1); }); + + exports = runtime.requireModuleOrMock( + runtime.__mockRootPath, + 'ModuleWithState', + ); + expect(exports.getState()).toBe(1); }); describe('can use isolateModulesAsync from a beforeEach block', () => { diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index 7cebee192704..b9250afcd3bd 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -1141,7 +1141,7 @@ export default class Runtime { } } - async isolateModulesAsync(fn: () => Promise | void): Promise { + async isolateModulesAsync(fn: () => Promise): Promise { if (this._isolatedModuleRegistry || this._isolatedMockRegistry) { throw new Error( 'isolateModulesAsync cannot be nested inside another isolateModulesAsync or isolateModules.', diff --git a/packages/jest-types/__typetests__/jest.test.ts b/packages/jest-types/__typetests__/jest.test.ts index d93dcd995f5d..691bcd330f9a 100644 --- a/packages/jest-types/__typetests__/jest.test.ts +++ b/packages/jest-types/__typetests__/jest.test.ts @@ -99,7 +99,7 @@ expectType(jest.isolateModules(() => {})); expectError(jest.isolateModules()); expectType>(jest.isolateModulesAsync(async () => {})); -expectType>(jest.isolateModulesAsync(() => {})); +expectError(jest.isolateModulesAsync(() => {})); expectError(jest.isolateModulesAsync()); expectType(jest.mock('moduleName'));