Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
- `[jest-reporters]` Add static filepath property to all reporters ([#11015](https://github.com/facebook/jest/pull/11015))
- `[jest-snapshot]` [**BREAKING**] Make prettier optional for inline snapshots - fall back to string replacement ([#7792](https://github.com/facebook/jest/pull/7792))
- `[jest-transform]` Pass config options defined in Jest's config to transformer's `process` and `getCacheKey` functions ([#10926](https://github.com/facebook/jest/pull/10926))
- `[jest-transform]` Add support for transformers written in ESM ([#11163](https://github.com/facebook/jest/pull/7792))
- `[jest-transform]` [**BREAKING**] Do not export `ScriptTransformer` class, instead export the async function `createScriptTransformer` ([#11163](https://github.com/facebook/jest/pull/11163))
- `[jest-worker]` Add support for custom task queues and adds a `PriorityQueue` implementation. ([#10921](https://github.com/facebook/jest/pull/10921))
- `[jest-worker]` Add in-order scheduling policy to jest worker ([10902](https://github.com/facebook/jest/pull/10902))

Expand Down
18 changes: 2 additions & 16 deletions babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,6 @@ module.exports = {
],
test: /\.tsx?$/,
},
// we want this file to keep `import()`, so exclude the transform for it
{
plugins: ['@babel/plugin-syntax-dynamic-import'],
presets: [
'@babel/preset-typescript',
[
'@babel/preset-env',
{
exclude: ['@babel/plugin-proposal-dynamic-import'],
shippedProposals: true,
targets: {node: supportedNodeVersion},
},
],
],
test: 'packages/jest-config/src/readConfigFileAndSetRootDir.ts',
},
],
plugins: [
['@babel/plugin-transform-modules-commonjs', {allowTopLevelThis: true}],
Expand All @@ -63,6 +47,8 @@ module.exports = {
'@babel/preset-env',
{
bugfixes: true,
// a runtime error is preferable, and we need a real `import`
exclude: ['@babel/plugin-proposal-dynamic-import'],
shippedProposals: true,
targets: {node: supportedNodeVersion},
},
Expand Down
11 changes: 11 additions & 0 deletions e2e/__tests__/transform.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,3 +238,14 @@ describe('transform-testrunner', () => {
expect(json.numPassedTests).toBe(1);
});
});

describe('esm-transformer', () => {
const dir = path.resolve(__dirname, '../transform/esm-transformer');

it('should transform with transformer written in ESM', () => {
const {json, stderr} = runWithJson(dir, ['--no-cache']);
expect(stderr).toMatch(/PASS/);
expect(json.success).toBe(true);
expect(json.numPassedTests).toBe(1);
});
});
12 changes: 12 additions & 0 deletions e2e/transform/esm-transformer/__tests__/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* 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 m = require('../module');

test('ESM transformer intercepts', () => {
expect(m).toEqual(42);
});
8 changes: 8 additions & 0 deletions e2e/transform/esm-transformer/module.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* 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.
*/

module.exports = 'It was not transformed!!';
22 changes: 22 additions & 0 deletions e2e/transform/esm-transformer/my-transform.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* 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 {createRequire} from 'module';

const require = createRequire(import.meta.url);

const fileToTransform = require.resolve('./module');

export default {
process(src, filepath) {
if (filepath === fileToTransform) {
return 'module.exports = 42;';
}

return src;
},
};
8 changes: 8 additions & 0 deletions e2e/transform/esm-transformer/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"jest": {
"testEnvironment": "node",
"transform": {
"\\.js$": "<rootDir>/my-transform.mjs"
}
}
}
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
"devDependencies": {
"@babel/core": "^7.3.4",
"@babel/plugin-proposal-class-properties": "^7.3.4",
"@babel/plugin-proposal-dynamic-import": "^7.8.3",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-transform-modules-commonjs": "^7.1.0",
"@babel/plugin-transform-strict-mode": "^7.0.0",
"@babel/preset-env": "^7.1.0",
Expand Down
36 changes: 19 additions & 17 deletions packages/jest-core/src/TestScheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
buildFailureTestResult,
makeEmptyAggregatedTestResult,
} from '@jest/test-result';
import {ScriptTransformer} from '@jest/transform';
import {createScriptTransformer} from '@jest/transform';
import type {Config} from '@jest/types';
import {formatExecError} from 'jest-message-util';
import TestRunner, {Test} from 'jest-runner';
Expand Down Expand Up @@ -188,22 +188,24 @@ export default class TestScheduler {

const testRunners: {[key: string]: TestRunner} = Object.create(null);
const contextsByTestRunner = new WeakMap<TestRunner, Context>();
contexts.forEach(context => {
const {config} = context;
if (!testRunners[config.runner]) {
const transformer = new ScriptTransformer(config);
const Runner: typeof TestRunner = interopRequireDefault(
transformer.requireAndTranspileModule(config.runner),
).default;
const runner = new Runner(this._globalConfig, {
changedFiles: this._context?.changedFiles,
sourcesRelatedToTestsInChangedFiles: this._context
?.sourcesRelatedToTestsInChangedFiles,
});
testRunners[config.runner] = runner;
contextsByTestRunner.set(runner, context);
}
});
await Promise.all(
Array.from(contexts).map(async context => {
const {config} = context;
if (!testRunners[config.runner]) {
const transformer = await createScriptTransformer(config);
const Runner: typeof TestRunner = interopRequireDefault(
transformer.requireAndTranspileModule(config.runner),
).default;
const runner = new Runner(this._globalConfig, {
changedFiles: this._context?.changedFiles,
sourcesRelatedToTestsInChangedFiles: this._context
?.sourcesRelatedToTestsInChangedFiles,
});
testRunners[config.runner] = runner;
contextsByTestRunner.set(runner, context);
}
}),
);

const testsByRunner = this._partitionTests(testRunners, tests);

Expand Down
5 changes: 3 additions & 2 deletions packages/jest-core/src/__tests__/watchFileChanges.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import type {AggregatedResult} from '@jest/test-result';
import {normalize} from 'jest-config';
import type HasteMap from 'jest-haste-map';
import Runtime from 'jest-runtime';
import {interopRequireDefault} from 'jest-util';
import {JestHook} from 'jest-watcher';

describe('Watch mode flows with changed files', () => {
Expand All @@ -31,8 +32,8 @@ describe('Watch mode flows with changed files', () => {
const cacheDirectory = path.resolve(tmpdir(), `tmp${Math.random()}`);
let hasteMapInstance: HasteMap;

beforeEach(async () => {
watch = (await import('../watch')).default;
beforeEach(() => {
watch = interopRequireDefault(require('../watch')).default;
pipe = {write: jest.fn()} as unknown;
stdin = new MockStdin();
rimraf.sync(cacheDirectory);
Expand Down
4 changes: 2 additions & 2 deletions packages/jest-core/src/runGlobalHook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import * as util from 'util';
import pEachSeries = require('p-each-series');
import {ScriptTransformer} from '@jest/transform';
import {createScriptTransformer} from '@jest/transform';
import type {Config} from '@jest/types';
import type {Test} from 'jest-runner';
import {interopRequireDefault} from 'jest-util';
Expand Down Expand Up @@ -45,7 +45,7 @@ export default async ({
: // Fallback to first config
allTests[0].context.config;

const transformer = new ScriptTransformer(projectConfig);
const transformer = await createScriptTransformer(projectConfig);

try {
await transformer.requireAndTranspileModule(modulePath, async m => {
Expand Down
5 changes: 3 additions & 2 deletions packages/jest-repl/src/cli/runtime-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import chalk = require('chalk');
import yargs = require('yargs');
import {CustomConsole} from '@jest/console';
import type {JestEnvironment} from '@jest/environment';
import {ScriptTransformer} from '@jest/transform';
import {createScriptTransformer} from '@jest/transform';
import type {Config} from '@jest/types';
import {deprecationEntries, readConfig} from 'jest-config';
import Runtime from 'jest-runtime';
Expand Down Expand Up @@ -74,7 +74,7 @@ export async function run(
watchman: globalConfig.watchman,
});

const transformer = new ScriptTransformer(config);
const transformer = await createScriptTransformer(config);
const Environment: typeof JestEnvironment = interopRequireDefault(
transformer.requireAndTranspileModule(config.testEnvironment),
).default;
Expand All @@ -91,6 +91,7 @@ export async function run(
config,
environment,
hasteMap.resolver,
transformer,
new Map(),
{
changedFiles: undefined,
Expand Down
2 changes: 1 addition & 1 deletion packages/jest-reporters/src/CoverageWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export function worker({
globalConfig,
path,
options,
}: CoverageWorkerData): CoverageWorkerResult | null {
}: CoverageWorkerData): Promise<CoverageWorkerResult | null> {
return generateEmptyCoverage(
fs.readFileSync(path, 'utf8'),
path,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('generateEmptyCoverage', () => {
const rootDir = __dirname;
const filepath = path.join(rootDir, './sum.js');

it('generates an empty coverage object for a file without running it', () => {
it('generates an empty coverage object for a file without running it', async () => {
const src = `
throw new Error('this should not be thrown');

Expand All @@ -42,7 +42,7 @@ describe('generateEmptyCoverage', () => {

shouldInstrument.mockReturnValueOnce(true);

const emptyCoverage = generateEmptyCoverage(
const emptyCoverage = await generateEmptyCoverage(
src,
filepath,
makeGlobalConfig(),
Expand Down Expand Up @@ -71,7 +71,7 @@ describe('generateEmptyCoverage', () => {
});
});

it('generates a null coverage result when using /* istanbul ignore file */', () => {
it('generates a null coverage result when using /* istanbul ignore file */', async () => {
const src = `
/* istanbul ignore file */
const a = (b, c) => {
Expand All @@ -86,7 +86,7 @@ describe('generateEmptyCoverage', () => {

shouldInstrument.mockReturnValueOnce(true);

const nullCoverage = generateEmptyCoverage(
const nullCoverage = await generateEmptyCoverage(
src,
filepath,
makeGlobalConfig(),
Expand All @@ -101,7 +101,7 @@ describe('generateEmptyCoverage', () => {
expect(nullCoverage).toBeNull();
});

it('generates a null coverage result when collectCoverage global config is false', () => {
it('generates a null coverage result when collectCoverage global config is false', async () => {
const src = `
const a = (b, c) => {
if (b) {
Expand All @@ -115,7 +115,7 @@ describe('generateEmptyCoverage', () => {

shouldInstrument.mockReturnValueOnce(false);

const nullCoverage = generateEmptyCoverage(
const nullCoverage = await generateEmptyCoverage(
src,
filepath,
makeGlobalConfig(),
Expand Down
26 changes: 12 additions & 14 deletions packages/jest-reporters/src/generateEmptyCoverage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type {V8Coverage} from 'collect-v8-coverage';
import * as fs from 'graceful-fs';
import {FileCoverage, createFileCoverage} from 'istanbul-lib-coverage';
import {readInitialCoverage} from 'istanbul-lib-instrument';
import {ScriptTransformer, shouldInstrument} from '@jest/transform';
import {createScriptTransformer, shouldInstrument} from '@jest/transform';
import type {Config} from '@jest/types';

type SingleV8Coverage = V8Coverage[number];
Expand All @@ -24,14 +24,14 @@ export type CoverageWorkerResult =
result: SingleV8Coverage;
};

export default function (
export default async function (
source: string,
filename: Config.Path,
globalConfig: Config.GlobalConfig,
config: Config.ProjectConfig,
changedFiles?: Set<Config.Path>,
sourcesRelatedToTestsInChangedFiles?: Set<Config.Path>,
): CoverageWorkerResult | null {
): Promise<CoverageWorkerResult | null> {
const coverageOptions = {
changedFiles,
collectCoverage: globalConfig.collectCoverage,
Expand Down Expand Up @@ -66,18 +66,16 @@ export default function (
};
}

const scriptTransformer = await createScriptTransformer(config);

// Transform file with instrumentation to make sure initial coverage data is well mapped to original code.
const {code} = new ScriptTransformer(config).transformSource(
filename,
source,
{
instrument: true,
supportsDynamicImport: true,
supportsExportNamespaceFrom: true,
supportsStaticESM: true,
supportsTopLevelAwait: true,
},
);
const {code} = scriptTransformer.transformSource(filename, source, {
instrument: true,
supportsDynamicImport: true,
supportsExportNamespaceFrom: true,
supportsStaticESM: true,
supportsTopLevelAwait: true,
});
// TODO: consider passing AST
const extracted = readInitialCoverage(code);
// Check extracted initial coverage is not null, this can happen when using /* istanbul ignore file */
Expand Down
8 changes: 5 additions & 3 deletions packages/jest-runner/src/runTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
} from '@jest/console';
import type {JestEnvironment} from '@jest/environment';
import type {TestResult} from '@jest/test-result';
import {ScriptTransformer} from '@jest/transform';
import {createScriptTransformer} from '@jest/transform';
import type {Config} from '@jest/types';
import {getTestEnvironment} from 'jest-config';
import * as docblock from 'jest-docblock';
Expand Down Expand Up @@ -103,7 +103,9 @@ async function runTestInternal(
});
}

const transformer = new ScriptTransformer(config);
const cacheFS = new Map([[path, testSource]]);
const transformer = await createScriptTransformer(config, cacheFS);

const TestEnvironment: typeof JestEnvironment = interopRequireDefault(
transformer.requireAndTranspileModule(testEnvironment),
).default;
Expand Down Expand Up @@ -146,13 +148,13 @@ async function runTestInternal(
? new LeakDetector(environment)
: null;

const cacheFS = new Map([[path, testSource]]);
setGlobal(environment.global, 'console', testConsole);

const runtime = new Runtime(
config,
environment,
resolver,
transformer,
cacheFS,
{
changedFiles: context?.changedFiles,
Expand Down
Loading