Skip to content

Commit

Permalink
feat: experimental ES Modules support
Browse files Browse the repository at this point in the history
  • Loading branch information
SimenB committed Apr 10, 2020
1 parent 4caa7b5 commit f82910e
Show file tree
Hide file tree
Showing 15 changed files with 380 additions and 26 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

### Features

- `[jest-runtime, jest-jasmine2, jest-circus]` Experimental, limited ECMAScript Modules support ([#9772](https://github.com/facebook/jest/pull/9772))

### Fixes

### Chore & Maintenance
Expand Down
9 changes: 9 additions & 0 deletions e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`on node ^12.16.0 || >=13.0.0 runs test with native ESM 1`] = `
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: <<REPLACED>>
Ran all test suites.
`;
36 changes: 36 additions & 0 deletions e2e/__tests__/nativeEsm.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* 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.
*/

import {resolve} from 'path';
import wrap from 'jest-snapshot-serializer-raw';
import {onNodeVersions} from '@jest/test-utils';
import runJest, {getConfig} from '../runJest';
import {extractSummary} from '../Utils';

const DIR = resolve(__dirname, '../native-esm');

test('test config is without transform', () => {
const {configs} = getConfig(DIR);

expect(configs).toHaveLength(1);
expect(configs[0].transform).toEqual([]);
});

// The versions vm.Module was introduced
onNodeVersions('^12.16.0 || >=13.0.0', () => {
test('runs test with native ESM', () => {
const {exitCode, stderr, stdout} = runJest(DIR, [], {
nodeOptions: '--experimental-vm-modules',
});

const {summary} = extractSummary(stderr);

expect(wrap(summary)).toMatchSnapshot();
expect(stdout).toBe('');
expect(exitCode).toBe(0);
});
});
23 changes: 23 additions & 0 deletions e2e/native-esm/__tests__/native-esm.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* 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.
*/

import {double} from '../index';

test('should have correct import.meta', () => {
expect(typeof jest).toBe('undefined');
expect(import.meta).toEqual({
jest: expect.anything(),
url: expect.any(String),
});
expect(
import.meta.url.endsWith('/e2e/native-esm/__tests__/native-esm.test.js')
).toBe(true);
});

test('should double stuff', () => {
expect(double(1)).toBe(2);
});
10 changes: 10 additions & 0 deletions e2e/native-esm/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* 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.
*/

export function double(num) {
return num * 2;
}
7 changes: 7 additions & 0 deletions e2e/native-esm/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "module",
"jest": {
"testEnvironment": "node",
"transform": {}
}
}
21 changes: 19 additions & 2 deletions packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,26 @@ const jestAdapter = async (
}
});

config.setupFilesAfterEnv.forEach(path => runtime.requireModule(path));
await Promise.all(
config.setupFilesAfterEnv.map(async path => {
const esm = runtime.unstable_shouldLoadAsEsm(path);

if (esm) {
await runtime.unstable_importModule(path);
} else {
runtime.requireModule(path);
}
}),
);

const esm = runtime.unstable_shouldLoadAsEsm(testPath);

if (esm) {
await runtime.unstable_importModule(testPath);
} else {
runtime.requireModule(testPath);
}

runtime.requireModule(testPath);
const results = await runAndTransformResultsToJestFormat({
config,
globalConfig,
Expand Down
21 changes: 19 additions & 2 deletions packages/jest-jasmine2/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,17 @@ async function jasmine2(
testPath,
});

config.setupFilesAfterEnv.forEach(path => runtime.requireModule(path));
await Promise.all(
config.setupFilesAfterEnv.map(async path => {
const esm = runtime.unstable_shouldLoadAsEsm(path);

if (esm) {
await runtime.unstable_importModule(path);
} else {
runtime.requireModule(path);
}
}),
);

if (globalConfig.enabledTestsMap) {
env.specFilter = (spec: Spec) => {
Expand All @@ -169,7 +179,14 @@ async function jasmine2(
env.specFilter = (spec: Spec) => testNameRegex.test(spec.getFullName());
}

runtime.requireModule(testPath);
const esm = runtime.unstable_shouldLoadAsEsm(testPath);

if (esm) {
await runtime.unstable_importModule(testPath);
} else {
runtime.requireModule(testPath);
}

await env.execute();

const results = await reporter.getResults();
Expand Down
20 changes: 19 additions & 1 deletion packages/jest-runner/src/runTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ function freezeConsole(
};
}

function invariant(condition: unknown, message?: string): asserts condition {
if (!condition) {
throw new Error(message);
}
}

// Keeping the core of "runTest" as a separate function (as "runTestInternal")
// is key to be able to detect memory leaks. Since all variables are local to
// the function, when "runTestInternal" finishes its execution, they can all be
Expand Down Expand Up @@ -163,7 +169,19 @@ async function runTestInternal(

const start = Date.now();

config.setupFiles.forEach(path => runtime!.requireModule(path));
await Promise.all(
config.setupFiles.map(async path => {
invariant(runtime, 'TS is being difficult');

const esm = runtime.unstable_shouldLoadAsEsm(path);

if (esm) {
await runtime.unstable_importModule(path);
} else {
runtime.requireModule(path);
}
}),
);

const sourcemapOptions: sourcemapSupport.Options = {
environment: 'node',
Expand Down
1 change: 1 addition & 0 deletions packages/jest-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"jest-snapshot": "^25.3.0",
"jest-util": "^25.3.0",
"jest-validate": "^25.3.0",
"read-pkg-up": "^7.0.1",
"realpath-native": "^2.0.0",
"slash": "^3.0.0",
"strip-bom": "^4.0.0",
Expand Down
12 changes: 11 additions & 1 deletion packages/jest-runtime/src/__mocks__/createRuntime.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,17 @@ module.exports = async function createRuntime(filename, config) {
Runtime.createResolver(config, hasteMap.moduleMap),
);

config.setupFiles.forEach(path => runtime.requireModule(path));
await Promise.all(
config.setupFiles.map(async path => {
const esm = runtime.unstable_shouldLoadAsEsm(path);

if (esm) {
await runtime.unstable_importModule(path);
} else {
runtime.requireModule(path);
}
}),
);

runtime.__mockRootPath = path.join(config.rootDir, 'root.js');
runtime.__mockSubdirPath = path.join(
Expand Down
19 changes: 17 additions & 2 deletions packages/jest-runtime/src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,24 @@ export async function run(

const runtime = new Runtime(config, environment, hasteMap.resolver);

config.setupFiles.forEach(path => runtime.requireModule(path));
await Promise.all(
config.setupFiles.map(async path => {
const esm = runtime.unstable_shouldLoadAsEsm(path);

runtime.requireModule(filePath);
if (esm) {
await runtime.unstable_importModule(path);
} else {
runtime.requireModule(path);
}
}),
);
const esm = runtime.unstable_shouldLoadAsEsm(filePath);

if (esm) {
await runtime.unstable_importModule(filePath);
} else {
runtime.requireModule(filePath);
}
} catch (e) {
console.error(chalk.red(e.stack || e));
process.on('exit', () => (process.exitCode = 1));
Expand Down
Loading

0 comments on commit f82910e

Please sign in to comment.