Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support for transforming runner #8854

Merged
merged 11 commits into from Nov 15, 2020
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -6,6 +6,7 @@
- `[jest-runner]` [**BREAKING**] set exit code to 1 if test logs after teardown ([#10728](https://github.com/facebook/jest/pull/10728))
- `[jest-snapshot]`: [**BREAKING**] Make prettier optional for inline snapshots - fall back to string replacement ([#7792](https://github.com/facebook/jest/pull/7792))
- `[jest-repl, jest-runner]` [**BREAKING**] Run transforms over environment ([#8751](https://github.com/facebook/jest/pull/8751))
- `[jest-runner]` [**BREAKING**] Run transforms over `runnner` ([#8823](https://github.com/facebook/jest/pull/8823))

### Fixes

Expand Down
11 changes: 11 additions & 0 deletions e2e/__tests__/transform.test.ts
Expand Up @@ -216,3 +216,14 @@ describe('transform-environment', () => {
expect(json.numPassedTests).toBe(1);
});
});

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

it('should transform runner', () => {
const {json, stderr} = runWithJson(dir, ['--no-cache']);
expect(stderr).toMatch(/PASS/);
expect(json.success).toBe(true);
expect(json.numPassedTests).toBe(1);
});
});
2 changes: 1 addition & 1 deletion e2e/transform/transform-environment/package.json
Expand Up @@ -9,6 +9,6 @@
"dependencies": {
"@babel/preset-env": "^7.0.0",
"@babel/preset-typescript": "^7.0.0",
"jest-environment-node": "^26.6.2"
"jest-environment-node": "file:../../../packages/jest-environment-node"
}
}
10 changes: 10 additions & 0 deletions e2e/transform/transform-runner/__tests__/add.test.js
@@ -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.
*/

it('should add two numbers', () => {
expect(1 + 1).toBe(2);
});
13 changes: 13 additions & 0 deletions e2e/transform/transform-runner/babel.config.js
@@ -0,0 +1,13 @@
/**
* 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 = {
presets: [
['@babel/preset-env', {targets: {node: 'current'}}],
'@babel/preset-typescript',
],
};
11 changes: 11 additions & 0 deletions e2e/transform/transform-runner/package.json
@@ -0,0 +1,11 @@
{
"jest": {
"rootDir": "./",
"runner": "<rootDir>/runner.ts"
},
"dependencies": {
"@babel/preset-env": "^7.0.0",
"@babel/preset-typescript": "^7.0.0",
"jest-environment-node": "file:../../../packages/jest-environment-node"
}
}
69 changes: 69 additions & 0 deletions e2e/transform/transform-runner/runner.ts
@@ -0,0 +1,69 @@
/**
* 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 throat from 'throat';
import {TestResult, createEmptyTestResult} from '@jest/test-result';
import type {Config} from '@jest/types';
import {
OnTestFailure,
OnTestStart,
OnTestSuccess,
Test,
TestRunnerContext,
TestWatcher,
} from 'jest-runner';

export default class BaseTestRunner {
private _globalConfig: Config.GlobalConfig;
private _context: TestRunnerContext;

constructor(globalConfig: Config.GlobalConfig, context?: TestRunnerContext) {
this._globalConfig = globalConfig;
this._context = context || {};
}

async runTests(
tests: Array<Test>,
watcher: TestWatcher,
onStart: OnTestStart,
onResult: OnTestSuccess,
onFailure: OnTestFailure,
): Promise<void> {
const mutex = throat(1);
return tests.reduce(
(promise, test) =>
mutex(() =>
promise
.then(
async (): Promise<TestResult> => {
await onStart(test);
return {
...createEmptyTestResult(),
numPassingTests: 1,
testFilePath: test.path,
testResults: [
{
ancestorTitles: [],
duration: 2,
failureMessages: [],
fullName: 'sample test',
location: null,
numPassingAsserts: 1,
status: 'passed',
title: 'sample test',
},
],
};
},
)
.then(result => onResult(test, result))
.catch(err => onFailure(test, err)),
),
Promise.resolve(),
);
}
}
6 changes: 6 additions & 0 deletions e2e/transform/transform-runner/tsconfig.json
@@ -0,0 +1,6 @@
{
"compilerOptions": {
"esModuleInterop": true,
"module": "commonjs",
}
}
6 changes: 5 additions & 1 deletion packages/jest-core/src/TestScheduler.ts
Expand Up @@ -25,6 +25,7 @@ import {
buildFailureTestResult,
makeEmptyAggregatedTestResult,
} from '@jest/test-result';
import {ScriptTransformer} from '@jest/transform';
import type {Config} from '@jest/types';
import {formatExecError} from 'jest-message-util';
import TestRunner = require('jest-runner');
Expand Down Expand Up @@ -193,7 +194,10 @@ export default class TestScheduler {
contexts.forEach(context => {
const {config} = context;
if (!testRunners[config.runner]) {
const Runner: typeof TestRunner = require(config.runner);
const transformer = new ScriptTransformer(config);
const Runner: typeof TestRunner = interopRequireDefault(
Mark1626 marked this conversation as resolved.
Show resolved Hide resolved
transformer.requireAndTranspileModule(config.runner),
).default;
const runner = new Runner(this._globalConfig, {
changedFiles: this._context?.changedFiles,
sourcesRelatedToTestsInChangedFiles: this._context
Expand Down
12 changes: 12 additions & 0 deletions packages/jest-core/src/__tests__/TestScheduler.test.js
Expand Up @@ -88,7 +88,9 @@ test('schedule tests run in parallel per default', async () => {
const test = {
context: {
config: makeProjectConfig({
moduleFileExtensions: ['.js'],
runner: 'jest-runner-parallel',
transform: [],
}),
hasteFS: {
matchFiles: jest.fn(() => []),
Expand All @@ -109,7 +111,9 @@ test('schedule tests run in serial if the runner flags them', async () => {
const test = {
context: {
config: makeProjectConfig({
moduleFileExtensions: ['.js'],
runner: 'jest-runner-serial',
transform: [],
}),
hasteFS: {
matchFiles: jest.fn(() => []),
Expand All @@ -130,8 +134,10 @@ test('should bail after `n` failures', async () => {
const test = {
context: {
config: makeProjectConfig({
moduleFileExtensions: ['.js'],
rootDir: './',
runner: 'jest-runner-serial',
transform: [],
}),
hasteFS: {
matchFiles: jest.fn(() => []),
Expand Down Expand Up @@ -160,8 +166,10 @@ test('should not bail if less than `n` failures', async () => {
const test = {
context: {
config: makeProjectConfig({
moduleFileExtensions: ['.js'],
rootDir: './',
runner: 'jest-runner-serial',
transform: [],
}),
hasteFS: {
matchFiles: jest.fn(() => []),
Expand Down Expand Up @@ -190,7 +198,9 @@ test('should set runInBand to run in serial', async () => {
const test = {
context: {
config: makeProjectConfig({
moduleFileExtensions: ['.js'],
runner: 'jest-runner-parallel',
transform: [],
}),
hasteFS: {
matchFiles: jest.fn(() => []),
Expand All @@ -214,7 +224,9 @@ test('should set runInBand to not run in serial', async () => {
const test = {
context: {
config: makeProjectConfig({
moduleFileExtensions: ['.js'],
runner: 'jest-runner-parallel',
transform: [],
}),
hasteFS: {
matchFiles: jest.fn(() => []),
Expand Down