fix: isolate esm async import bug (#14397)

This commit is contained in:
cin
2023-08-21 14:08:55 +02:00
committed by GitHub
parent 966e9c2d57
commit 98fde7818d
7 changed files with 92 additions and 10 deletions
+1
View File
@@ -12,6 +12,7 @@
- `[jest-mock]` Revert [#13866](https://github.com/jestjs/jest/pull/13866) as it was a breaking change ([#14429](https://github.com/jestjs/jest/pull/14429))
- `[jest-mock]` Revert [#13867](https://github.com/jestjs/jest/pull/13867) as it was a breaking change ([#14429](https://github.com/jestjs/jest/pull/14429))
- `[@jest/reporters]` Marks Reporter's hooks as optional ([#14433](https://github.com/jestjs/jest/pull/14433))
- `[jest-runtime]` Fix dynamic ESM import module bug when loaded module through `jest.isolateModulesAsync` ([14397](https://github.com/jestjs/jest/pull/14397))
### Chore & Maintenance
@@ -0,0 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`runs test with isolate modules async import 1`] = `
"Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: <<REPLACED>>
Ran all test suites."
`;
+20
View File
@@ -0,0 +1,20 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {extractSummary} from '../Utils';
import runJest from '../runJest';
test('runs test with isolate modules async import', () => {
const {exitCode, stderr} = runJest('isolate-modules-async', [], {
nodeOptions: '--experimental-vm-modules --no-warnings',
});
const {summary} = extractSummary(stderr);
expect(summary).toMatchSnapshot();
expect(exitCode).toBe(0);
});
@@ -0,0 +1,22 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {jest} from '@jest/globals';
test('should have a fresh module state in each isolateModulesAsync context', async () => {
await jest.isolateModulesAsync(async () => {
const {getState, incState} = await import('../main.js');
expect(getState()).toBe(0);
incState();
expect(getState()).toBe(1);
});
await jest.isolateModulesAsync(async () => {
const {getState, incState} = await import('../main.js');
expect(getState()).toBe(0);
incState();
expect(getState()).toBe(1);
});
});
+15
View File
@@ -0,0 +1,15 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
let myState = 0;
export function incState() {
myState += 1;
}
export function getState() {
return myState;
}
+8
View File
@@ -0,0 +1,8 @@
{
"name": "isolate-modules-async",
"type": "module",
"jest": {
"transform": {},
"testEnvironment": "node"
}
}
+17 -10
View File
@@ -416,12 +416,15 @@ export default class Runtime {
query = '',
): Promise<VMModule> {
const cacheKey = modulePath + query;
const registry = this._isolatedModuleRegistry
? this._isolatedModuleRegistry
: this._esmoduleRegistry;
if (this._fileTransformsMutex.has(cacheKey)) {
await this._fileTransformsMutex.get(cacheKey);
}
if (!this._esmoduleRegistry.has(cacheKey)) {
if (!registry.has(cacheKey)) {
invariant(
typeof this._environment.getVmContext === 'function',
'ES Modules are only supported if your test environment has the `getVmContext` function',
@@ -454,7 +457,7 @@ export default class Runtime {
context,
);
this._esmoduleRegistry.set(cacheKey, wasm);
registry.set(cacheKey, wasm);
transformResolve();
return wasm;
@@ -462,7 +465,7 @@ export default class Runtime {
if (this._resolver.isCoreModule(modulePath)) {
const core = this._importCoreModule(modulePath, context);
this._esmoduleRegistry.set(cacheKey, core);
registry.set(cacheKey, core);
transformResolve();
@@ -526,11 +529,11 @@ export default class Runtime {
}
invariant(
!this._esmoduleRegistry.has(cacheKey),
!registry.has(cacheKey),
`Module cache already has entry ${cacheKey}. This is a bug in Jest, please report it!`,
);
this._esmoduleRegistry.set(cacheKey, module);
registry.set(cacheKey, module);
transformResolve();
} catch (error) {
@@ -539,7 +542,7 @@ export default class Runtime {
}
}
const module = this._esmoduleRegistry.get(cacheKey);
const module = registry.get(cacheKey);
invariant(
module,
@@ -563,14 +566,18 @@ export default class Runtime {
return;
}
const registry = this._isolatedModuleRegistry
? this._isolatedModuleRegistry
: this._esmoduleRegistry;
if (specifier === '@jest/globals') {
const fromCache = this._esmoduleRegistry.get('@jest/globals');
const fromCache = registry.get('@jest/globals');
if (fromCache) {
return fromCache;
}
const globals = this.getGlobalsForEsm(referencingIdentifier, context);
this._esmoduleRegistry.set('@jest/globals', globals);
registry.set('@jest/globals', globals);
return globals;
}
@@ -586,7 +593,7 @@ export default class Runtime {
return this.importMock(referencingIdentifier, specifier, context);
}
const fromCache = this._esmoduleRegistry.get(specifier);
const fromCache = registry.get(specifier);
if (fromCache) {
return fromCache;
@@ -662,7 +669,7 @@ export default class Runtime {
}
}
this._esmoduleRegistry.set(specifier, module);
registry.set(specifier, module);
return module;
}