feat(testing): disable jest runtime by default when inferring targets (#29917)
This PR updates `@nx/jest/plugin` such that `disableJestRuntime` option is true by default. Users will need to set it to false to bring in `jest-config` and `jest-runtime` to compute atomized targets. We're leaving it as an option if anyone runs into discrepancies between our calculation and what jest-runtime calculates for test files within a project. ## Current Behavior Jest runtime is used by default and is potentially slow if you use many transforms, presets, etc. in the jest config. ## Expected Behavior Jest runtime is not used by default, and users have to option of enabling it. ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #
This commit is contained in:
parent
a7c8c1021e
commit
9bc63177df
@ -1,166 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`@nx/jest/plugin should add package as externalDependencies to the inputs when specified as preset and containing a jest-preset.cjs file 1`] = `
|
||||
[
|
||||
[
|
||||
"proj/jest.config.js",
|
||||
{
|
||||
"projects": {
|
||||
"proj": {
|
||||
"metadata": undefined,
|
||||
"root": "proj",
|
||||
"targets": {
|
||||
"test": {
|
||||
"cache": true,
|
||||
"command": "jest",
|
||||
"inputs": [
|
||||
"default",
|
||||
"^production",
|
||||
{
|
||||
"externalDependencies": [
|
||||
"jest",
|
||||
"some-package",
|
||||
],
|
||||
},
|
||||
],
|
||||
"metadata": {
|
||||
"description": "Run Jest Tests",
|
||||
"help": {
|
||||
"command": "npx jest --help",
|
||||
"example": {
|
||||
"options": {
|
||||
"coverage": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
"technologies": [
|
||||
"jest",
|
||||
],
|
||||
},
|
||||
"options": {
|
||||
"cwd": "proj",
|
||||
"env": {
|
||||
"TS_NODE_COMPILER_OPTIONS": "{"moduleResolution":"node10"}",
|
||||
},
|
||||
},
|
||||
"outputs": [
|
||||
"{workspaceRoot}/coverage",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`@nx/jest/plugin should add package as externalDependencies to the inputs when specified as preset and containing a jest-preset.js file 1`] = `
|
||||
[
|
||||
[
|
||||
"proj/jest.config.js",
|
||||
{
|
||||
"projects": {
|
||||
"proj": {
|
||||
"metadata": undefined,
|
||||
"root": "proj",
|
||||
"targets": {
|
||||
"test": {
|
||||
"cache": true,
|
||||
"command": "jest",
|
||||
"inputs": [
|
||||
"default",
|
||||
"^production",
|
||||
{
|
||||
"externalDependencies": [
|
||||
"jest",
|
||||
"some-package",
|
||||
],
|
||||
},
|
||||
],
|
||||
"metadata": {
|
||||
"description": "Run Jest Tests",
|
||||
"help": {
|
||||
"command": "npx jest --help",
|
||||
"example": {
|
||||
"options": {
|
||||
"coverage": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
"technologies": [
|
||||
"jest",
|
||||
],
|
||||
},
|
||||
"options": {
|
||||
"cwd": "proj",
|
||||
"env": {
|
||||
"TS_NODE_COMPILER_OPTIONS": "{"moduleResolution":"node10"}",
|
||||
},
|
||||
},
|
||||
"outputs": [
|
||||
"{workspaceRoot}/coverage",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`@nx/jest/plugin should add package as externalDependencies to the inputs when specified as preset and containing a jest-preset.json file 1`] = `
|
||||
[
|
||||
[
|
||||
"proj/jest.config.js",
|
||||
{
|
||||
"projects": {
|
||||
"proj": {
|
||||
"metadata": undefined,
|
||||
"root": "proj",
|
||||
"targets": {
|
||||
"test": {
|
||||
"cache": true,
|
||||
"command": "jest",
|
||||
"inputs": [
|
||||
"default",
|
||||
"^production",
|
||||
{
|
||||
"externalDependencies": [
|
||||
"jest",
|
||||
"some-package",
|
||||
],
|
||||
},
|
||||
],
|
||||
"metadata": {
|
||||
"description": "Run Jest Tests",
|
||||
"help": {
|
||||
"command": "npx jest --help",
|
||||
"example": {
|
||||
"options": {
|
||||
"coverage": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
"technologies": [
|
||||
"jest",
|
||||
],
|
||||
},
|
||||
"options": {
|
||||
"cwd": "proj",
|
||||
"env": {
|
||||
"TS_NODE_COMPILER_OPTIONS": "{"moduleResolution":"node10"}",
|
||||
},
|
||||
},
|
||||
"outputs": [
|
||||
"{workspaceRoot}/coverage",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
]
|
||||
`;
|
||||
@ -8,7 +8,7 @@ jest.mock('nx/src/utils/cache-directory', () => ({
|
||||
workspaceDataDirectory: 'tmp/project-graph-cache',
|
||||
}));
|
||||
|
||||
describe('@nx/jest/plugin', () => {
|
||||
describe.each([true, false])('@nx/jest/plugin', (disableJestRuntime) => {
|
||||
let createNodesFunction = createNodesV2[1];
|
||||
let context: CreateNodesContext;
|
||||
let tempFs: TempFs;
|
||||
@ -54,6 +54,7 @@ describe('@nx/jest/plugin', () => {
|
||||
['proj/jest.config.js'],
|
||||
{
|
||||
targetName: 'test',
|
||||
disableJestRuntime,
|
||||
},
|
||||
context
|
||||
);
|
||||
@ -127,6 +128,7 @@ describe('@nx/jest/plugin', () => {
|
||||
{
|
||||
targetName: 'test',
|
||||
ciTargetName: 'test-ci',
|
||||
disableJestRuntime,
|
||||
},
|
||||
context
|
||||
);
|
||||
@ -272,7 +274,7 @@ describe('@nx/jest/plugin', () => {
|
||||
|
||||
const results = await createNodesFunction(
|
||||
['proj/jest.config.js'],
|
||||
{ targetName: 'test' },
|
||||
{ targetName: 'test', disableJestRuntime },
|
||||
context
|
||||
);
|
||||
|
||||
@ -352,49 +354,18 @@ describe('@nx/jest/plugin', () => {
|
||||
|
||||
const results = await createNodesFunction(
|
||||
['proj/jest.config.js'],
|
||||
{ targetName: 'test' },
|
||||
{ targetName: 'test', disableJestRuntime },
|
||||
context
|
||||
);
|
||||
|
||||
expect(results).toMatchSnapshot();
|
||||
}
|
||||
);
|
||||
|
||||
describe('disableJestRuntime', () => {
|
||||
it('should create test and test-ci targets based on jest.config.ts', async () => {
|
||||
mockJestConfig(
|
||||
{
|
||||
coverageDirectory: '../coverage',
|
||||
testMatch: ['**/*.spec.ts'],
|
||||
testPathIgnorePatterns: ['ignore.spec.ts'],
|
||||
},
|
||||
context
|
||||
);
|
||||
const results = await createNodesFunction(
|
||||
['proj/jest.config.js'],
|
||||
{
|
||||
targetName: 'test',
|
||||
ciTargetName: 'test-ci',
|
||||
disableJestRuntime: true,
|
||||
},
|
||||
context
|
||||
);
|
||||
|
||||
expect(results).toMatchInlineSnapshot(`
|
||||
const snapshot = `
|
||||
[
|
||||
[
|
||||
"proj/jest.config.js",
|
||||
{
|
||||
"projects": {
|
||||
"proj": {
|
||||
"metadata": {
|
||||
"targetGroups": {
|
||||
"TEST (CI)": [
|
||||
"test-ci",
|
||||
"test-ci--src/unit.spec.ts",
|
||||
],
|
||||
},
|
||||
},
|
||||
"metadata": undefined,
|
||||
"root": "proj",
|
||||
"targets": {
|
||||
"test": {
|
||||
@ -406,6 +377,7 @@ describe('@nx/jest/plugin', () => {
|
||||
{
|
||||
"externalDependencies": [
|
||||
"jest",
|
||||
"some-package",
|
||||
],
|
||||
},
|
||||
],
|
||||
@ -433,272 +405,16 @@ describe('@nx/jest/plugin', () => {
|
||||
"{workspaceRoot}/coverage",
|
||||
],
|
||||
},
|
||||
"test-ci": {
|
||||
"cache": true,
|
||||
"dependsOn": [
|
||||
"test-ci--src/unit.spec.ts",
|
||||
],
|
||||
"executor": "nx:noop",
|
||||
"inputs": [
|
||||
"default",
|
||||
"^production",
|
||||
{
|
||||
"externalDependencies": [
|
||||
"jest",
|
||||
],
|
||||
},
|
||||
],
|
||||
"metadata": {
|
||||
"description": "Run Jest Tests in CI",
|
||||
"help": {
|
||||
"command": "npx jest --help",
|
||||
"example": {
|
||||
"options": {
|
||||
"coverage": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
"nonAtomizedTarget": "test",
|
||||
"technologies": [
|
||||
"jest",
|
||||
],
|
||||
},
|
||||
"outputs": [
|
||||
"{workspaceRoot}/coverage",
|
||||
],
|
||||
},
|
||||
"test-ci--src/unit.spec.ts": {
|
||||
"cache": true,
|
||||
"command": "jest src/unit.spec.ts",
|
||||
"inputs": [
|
||||
"default",
|
||||
"^production",
|
||||
{
|
||||
"externalDependencies": [
|
||||
"jest",
|
||||
],
|
||||
},
|
||||
],
|
||||
"metadata": {
|
||||
"description": "Run Jest Tests in src/unit.spec.ts",
|
||||
"help": {
|
||||
"command": "npx jest --help",
|
||||
"example": {
|
||||
"options": {
|
||||
"coverage": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
"technologies": [
|
||||
"jest",
|
||||
],
|
||||
},
|
||||
"options": {
|
||||
"cwd": "proj",
|
||||
"env": {
|
||||
"TS_NODE_COMPILER_OPTIONS": "{"moduleResolution":"node10"}",
|
||||
},
|
||||
},
|
||||
"outputs": [
|
||||
"{workspaceRoot}/coverage",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it.each`
|
||||
preset | expectedInput
|
||||
${'<rootDir>/jest.preset.js'} | ${'{projectRoot}/jest.preset.js'}
|
||||
${'../jest.preset.js'} | ${'{workspaceRoot}/jest.preset.js'}
|
||||
`('should correct input from preset', async ({ preset, expectedInput }) => {
|
||||
mockJestConfig(
|
||||
{
|
||||
preset,
|
||||
coverageDirectory: '../coverage',
|
||||
testMatch: ['**/*.spec.ts'],
|
||||
testPathIgnorePatterns: ['ignore.spec.ts'],
|
||||
},
|
||||
context
|
||||
);
|
||||
const results = await createNodesFunction(
|
||||
['proj/jest.config.js'],
|
||||
{
|
||||
targetName: 'test',
|
||||
ciTargetName: 'test-ci',
|
||||
disableJestRuntime: true,
|
||||
},
|
||||
context
|
||||
);
|
||||
|
||||
expect(results[0][1].projects['proj'].targets['test'].inputs).toContain(
|
||||
expectedInput
|
||||
);
|
||||
});
|
||||
|
||||
it.each`
|
||||
testRegex
|
||||
${'\\.*\\.spec\\.ts'}
|
||||
${['\\.*\\.spec\\.ts']}
|
||||
`(
|
||||
'should create test-ci targets from testRegex config option',
|
||||
async ({ testRegex }) => {
|
||||
mockJestConfig(
|
||||
{
|
||||
coverageDirectory: '../coverage',
|
||||
testRegex,
|
||||
testPathIgnorePatterns: ['ignore.spec.ts'],
|
||||
},
|
||||
context
|
||||
);
|
||||
const results = await createNodesFunction(
|
||||
['proj/jest.config.js'],
|
||||
{
|
||||
targetName: 'test',
|
||||
ciTargetName: 'test-ci',
|
||||
disableJestRuntime: true,
|
||||
},
|
||||
context
|
||||
);
|
||||
|
||||
expect(results).toMatchInlineSnapshot(`
|
||||
[
|
||||
[
|
||||
"proj/jest.config.js",
|
||||
{
|
||||
"projects": {
|
||||
"proj": {
|
||||
"metadata": {
|
||||
"targetGroups": {
|
||||
"TEST (CI)": [
|
||||
"test-ci",
|
||||
"test-ci--src/unit.spec.ts",
|
||||
],
|
||||
},
|
||||
},
|
||||
"root": "proj",
|
||||
"targets": {
|
||||
"test": {
|
||||
"cache": true,
|
||||
"command": "jest",
|
||||
"inputs": [
|
||||
"default",
|
||||
"^production",
|
||||
{
|
||||
"externalDependencies": [
|
||||
"jest",
|
||||
],
|
||||
},
|
||||
],
|
||||
"metadata": {
|
||||
"description": "Run Jest Tests",
|
||||
"help": {
|
||||
"command": "npx jest --help",
|
||||
"example": {
|
||||
"options": {
|
||||
"coverage": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
"technologies": [
|
||||
"jest",
|
||||
],
|
||||
},
|
||||
"options": {
|
||||
"cwd": "proj",
|
||||
"env": {
|
||||
"TS_NODE_COMPILER_OPTIONS": "{"moduleResolution":"node10"}",
|
||||
},
|
||||
},
|
||||
"outputs": [
|
||||
"{workspaceRoot}/coverage",
|
||||
],
|
||||
},
|
||||
"test-ci": {
|
||||
"cache": true,
|
||||
"dependsOn": [
|
||||
"test-ci--src/unit.spec.ts",
|
||||
],
|
||||
"executor": "nx:noop",
|
||||
"inputs": [
|
||||
"default",
|
||||
"^production",
|
||||
{
|
||||
"externalDependencies": [
|
||||
"jest",
|
||||
],
|
||||
},
|
||||
],
|
||||
"metadata": {
|
||||
"description": "Run Jest Tests in CI",
|
||||
"help": {
|
||||
"command": "npx jest --help",
|
||||
"example": {
|
||||
"options": {
|
||||
"coverage": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
"nonAtomizedTarget": "test",
|
||||
"technologies": [
|
||||
"jest",
|
||||
],
|
||||
},
|
||||
"outputs": [
|
||||
"{workspaceRoot}/coverage",
|
||||
],
|
||||
},
|
||||
"test-ci--src/unit.spec.ts": {
|
||||
"cache": true,
|
||||
"command": "jest src/unit.spec.ts",
|
||||
"inputs": [
|
||||
"default",
|
||||
"^production",
|
||||
{
|
||||
"externalDependencies": [
|
||||
"jest",
|
||||
],
|
||||
},
|
||||
],
|
||||
"metadata": {
|
||||
"description": "Run Jest Tests in src/unit.spec.ts",
|
||||
"help": {
|
||||
"command": "npx jest --help",
|
||||
"example": {
|
||||
"options": {
|
||||
"coverage": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
"technologies": [
|
||||
"jest",
|
||||
],
|
||||
},
|
||||
"options": {
|
||||
"cwd": "proj",
|
||||
"env": {
|
||||
"TS_NODE_COMPILER_OPTIONS": "{"moduleResolution":"node10"}",
|
||||
},
|
||||
},
|
||||
"outputs": [
|
||||
"{workspaceRoot}/coverage",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
]
|
||||
`);
|
||||
`;
|
||||
expect(results).toMatchInlineSnapshot(snapshot);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
describe('ciGroupName', () => {
|
||||
it('should name atomized tasks group using provided group name', async () => {
|
||||
@ -715,6 +431,7 @@ describe('@nx/jest/plugin', () => {
|
||||
{
|
||||
ciTargetName: 'test-ci',
|
||||
ciGroupName: 'MY ATOMIZED TEST TASKS (CI)',
|
||||
disableJestRuntime,
|
||||
},
|
||||
context
|
||||
);
|
||||
@ -864,6 +581,7 @@ describe('@nx/jest/plugin', () => {
|
||||
['proj/jest.config.js'],
|
||||
{
|
||||
ciTargetName: 'test-ci',
|
||||
disableJestRuntime,
|
||||
},
|
||||
context
|
||||
);
|
||||
@ -1013,6 +731,7 @@ describe('@nx/jest/plugin', () => {
|
||||
['proj/jest.config.js'],
|
||||
{
|
||||
ciTargetName: 'testci', // missing "-ci" suffix or similar construct, so group name cannot reliably be deducted from ci target name
|
||||
disableJestRuntime,
|
||||
},
|
||||
context
|
||||
);
|
||||
|
||||
@ -27,11 +27,8 @@ import { workspaceDataDirectory } from 'nx/src/utils/cache-directory';
|
||||
import { combineGlobPatterns } from 'nx/src/utils/globs';
|
||||
import { dirname, isAbsolute, join, relative, resolve } from 'path';
|
||||
import { getInstalledJestMajorVersion } from '../utils/version-utils';
|
||||
import {
|
||||
getFilesInDirectoryUsingContext,
|
||||
globWithWorkspaceContext,
|
||||
} from 'nx/src/utils/workspace-context';
|
||||
import { normalize } from 'node:path';
|
||||
import { globWithWorkspaceContext } from 'nx/src/utils/workspace-context';
|
||||
import { normalize, sep } from 'node:path';
|
||||
|
||||
const pmc = getPackageManagerCommand();
|
||||
|
||||
@ -44,7 +41,7 @@ export interface JestPluginOptions {
|
||||
*/
|
||||
ciGroupName?: string;
|
||||
/**
|
||||
* Whether to use jest-config and jest-runtime to load Jest configuration and context.
|
||||
* Whether to use jest-config and jest-runtime are used to load Jest configuration and context.
|
||||
* Disabling this is much faster but could be less correct since we are using our own config loader
|
||||
* and test matcher instead of Jest's.
|
||||
*/
|
||||
@ -215,13 +212,16 @@ async function buildJestTargets(
|
||||
},
|
||||
});
|
||||
|
||||
// Not normalizing it here since also affects options for convert-to-inferred.
|
||||
const disableJestRuntime = options.disableJestRuntime !== false;
|
||||
|
||||
const cache = (target.cache = true);
|
||||
const inputs = (target.inputs = getInputs(
|
||||
namedInputs,
|
||||
rawConfig.preset,
|
||||
projectRoot,
|
||||
context.workspaceRoot,
|
||||
options.disableJestRuntime
|
||||
disableJestRuntime
|
||||
));
|
||||
|
||||
let metadata: ProjectConfiguration['metadata'];
|
||||
@ -229,7 +229,7 @@ async function buildJestTargets(
|
||||
const groupName =
|
||||
options?.ciGroupName ?? deductGroupNameFromTarget(options?.ciTargetName);
|
||||
|
||||
if (options.disableJestRuntime) {
|
||||
if (disableJestRuntime) {
|
||||
const outputs = (target.outputs = getOutputs(
|
||||
projectRoot,
|
||||
rawConfig.coverageDirectory
|
||||
@ -326,7 +326,9 @@ async function buildJestTargets(
|
||||
projectRoot,
|
||||
context.workspaceRoot
|
||||
);
|
||||
const config = await readConfig(
|
||||
let config;
|
||||
try {
|
||||
config = await readConfig(
|
||||
{
|
||||
_: [],
|
||||
$0: undefined,
|
||||
@ -335,6 +337,10 @@ async function buildJestTargets(
|
||||
undefined,
|
||||
dirname(absConfigFilePath)
|
||||
);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
const outputs = (target.outputs = getOutputs(
|
||||
projectRoot,
|
||||
@ -363,8 +369,7 @@ async function buildJestTargets(
|
||||
const jestVersion = getInstalledJestMajorVersion()!;
|
||||
const specs =
|
||||
jestVersion >= 30
|
||||
? // @ts-expect-error Jest 30+ expects the project config as the second argument
|
||||
await source.getTestPaths(config.globalConfig, config.projectConfig)
|
||||
? await source.getTestPaths(config.globalConfig, config.projectConfig)
|
||||
: await source.getTestPaths(config.globalConfig);
|
||||
|
||||
const testPaths = new Set(specs.tests.map(({ path }) => path));
|
||||
@ -627,13 +632,19 @@ async function getTestPaths(
|
||||
'testMatch',
|
||||
presetCache
|
||||
);
|
||||
if (testMatch) {
|
||||
return await globWithWorkspaceContext(
|
||||
|
||||
let paths = await globWithWorkspaceContext(
|
||||
context.workspaceRoot,
|
||||
testMatch.map((pattern) => join(projectRoot, pattern)),
|
||||
(
|
||||
testMatch || [
|
||||
// Default copied from https://github.com/jestjs/jest/blob/d1a2ed7/packages/jest-config/src/Defaults.ts#L84
|
||||
'**/__tests__/**/*.?([mc])[jt]s?(x)',
|
||||
'**/?(*.)+(spec|test).?([mc])[jt]s?(x)',
|
||||
]
|
||||
).map((pattern) => join(projectRoot, pattern)),
|
||||
[]
|
||||
);
|
||||
} else {
|
||||
|
||||
const testRegex = await getJestOption<string[]>(
|
||||
rawConfig,
|
||||
absConfigFilePath,
|
||||
@ -641,31 +652,15 @@ async function getTestPaths(
|
||||
presetCache
|
||||
);
|
||||
if (testRegex) {
|
||||
const files: string[] = [];
|
||||
const testRegexes = Array.isArray(rawConfig.testRegex)
|
||||
? rawConfig.testRegex.map((r: string) => new RegExp(r))
|
||||
: [new RegExp(rawConfig.testRegex)];
|
||||
const projectFiles = await getFilesInDirectoryUsingContext(
|
||||
context.workspaceRoot,
|
||||
projectRoot
|
||||
);
|
||||
for (const file of projectFiles) {
|
||||
if (testRegexes.some((r: RegExp) => r.test(file))) files.push(file);
|
||||
}
|
||||
return files;
|
||||
} else {
|
||||
// Default copied from https://github.com/jestjs/jest/blob/d1a2ed7/packages/jest-config/src/Defaults.ts#L84
|
||||
const defaultTestMatch = [
|
||||
'**/__tests__/**/*.?([mc])[jt]s?(x)',
|
||||
'**/?(*.)+(spec|test).?([mc])[jt]s?(x)',
|
||||
];
|
||||
return await globWithWorkspaceContext(
|
||||
context.workspaceRoot,
|
||||
defaultTestMatch.map((pattern) => join(projectRoot, pattern)),
|
||||
[]
|
||||
paths = paths.filter((path: string) =>
|
||||
testRegexes.some((r: RegExp) => r.test(path))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return paths;
|
||||
}
|
||||
|
||||
async function getJestOption<T = any>(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user