@nx/jest 20.5.0-beta.3 → 20.5.0-canary.20250128-e0c49d3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/jest",
|
|
3
|
-
"version": "20.5.0-
|
|
3
|
+
"version": "20.5.0-canary.20250128-e0c49d3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "The Nx Plugin for Jest contains executors and generators allowing your workspace to use the powerful Jest testing capabilities.",
|
|
6
6
|
"repository": {
|
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@jest/reporters": "^29.4.1",
|
|
39
39
|
"@jest/test-result": "^29.4.1",
|
|
40
|
-
"@nx/devkit": "20.5.0-
|
|
41
|
-
"@nx/js": "20.5.0-
|
|
40
|
+
"@nx/devkit": "20.5.0-canary.20250128-e0c49d3",
|
|
41
|
+
"@nx/js": "20.5.0-canary.20250128-e0c49d3",
|
|
42
42
|
"@phenomnomnominal/tsquery": "~5.0.1",
|
|
43
43
|
"identity-obj-proxy": "3.0.0",
|
|
44
44
|
"jest-config": "^29.4.1",
|
|
@@ -5,6 +5,6 @@ import type { BatchResults } from 'nx/src/tasks-runner/batch/batch-messages';
|
|
|
5
5
|
export declare function jestExecutor(options: JestExecutorOptions, context: ExecutorContext): Promise<{
|
|
6
6
|
success: boolean;
|
|
7
7
|
}>;
|
|
8
|
-
export declare function
|
|
8
|
+
export declare function jestConfigParser(options: JestExecutorOptions, context: ExecutorContext, multiProjects?: boolean): Promise<Config.Argv>;
|
|
9
9
|
export default jestExecutor;
|
|
10
10
|
export declare function batchJest(taskGraph: TaskGraph, inputs: Record<string, JestExecutorOptions>, overrides: JestExecutorOptions, context: ExecutorContext): Promise<BatchResults>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.jestExecutor = jestExecutor;
|
|
4
|
-
exports.
|
|
4
|
+
exports.jestConfigParser = jestConfigParser;
|
|
5
5
|
exports.batchJest = batchJest;
|
|
6
6
|
const jest_1 = require("jest");
|
|
7
7
|
const jest_config_1 = require("jest-config");
|
|
@@ -17,7 +17,7 @@ async function jestExecutor(options, context) {
|
|
|
17
17
|
// Jest registers ts-node with module CJS https://github.com/SimenB/jest/blob/v29.6.4/packages/jest-config/src/readConfigFileAndSetRootDir.ts#L117-L119
|
|
18
18
|
// We want to support of ESM via 'module':'nodenext', we need to override the resolution until Jest supports it.
|
|
19
19
|
process.env.TS_NODE_COMPILER_OPTIONS ??= '{"moduleResolution":"node10"}';
|
|
20
|
-
const config = await
|
|
20
|
+
const config = await jestConfigParser(options, context);
|
|
21
21
|
const { results } = await (0, jest_1.runCLI)(config, [options.jestConfig]);
|
|
22
22
|
return { success: results.success };
|
|
23
23
|
}
|
|
@@ -26,12 +26,11 @@ function getExtraArgs(options, schema) {
|
|
|
26
26
|
for (const key of Object.keys(options)) {
|
|
27
27
|
if (!schema.properties[key]) {
|
|
28
28
|
extraArgs[key] = options[key];
|
|
29
|
-
process.argv.push(`--${key}=${options[key]}`);
|
|
30
29
|
}
|
|
31
30
|
}
|
|
32
31
|
return extraArgs;
|
|
33
32
|
}
|
|
34
|
-
async function
|
|
33
|
+
async function jestConfigParser(options, context, multiProjects = false) {
|
|
35
34
|
let jestConfig;
|
|
36
35
|
// support passing extra args to jest cli supporting 3rd party plugins
|
|
37
36
|
// like 'jest-runner-groups' --group arg
|
|
@@ -140,7 +139,7 @@ async function batchJest(taskGraph, inputs, overrides, context) {
|
|
|
140
139
|
${projectsWithNoName.map(([project, configPath]) => ` - ${project} - ${configPath}\r\n`)}
|
|
141
140
|
You can learn more about this requirement from Jest here: https://jestjs.io/docs/cli#--selectprojects-project1--projectn`);
|
|
142
141
|
}
|
|
143
|
-
const parsedConfigs = await
|
|
142
|
+
const parsedConfigs = await jestConfigParser(overrides, context, true);
|
|
144
143
|
const { globalConfig, results } = await (0, jest_1.runCLI)({
|
|
145
144
|
...parsedConfigs,
|
|
146
145
|
selectProjects: selectedProjects,
|
package/src/plugins/plugin.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export interface JestPluginOptions {
|
|
|
7
7
|
*/
|
|
8
8
|
ciGroupName?: string;
|
|
9
9
|
/**
|
|
10
|
-
* Whether to use jest-config and jest-runtime
|
|
10
|
+
* Whether to use jest-config and jest-runtime to load Jest configuration and context.
|
|
11
11
|
* Disabling this is much faster but could be less correct since we are using our own config loader
|
|
12
12
|
* and test matcher instead of Jest's.
|
|
13
13
|
*/
|
package/src/plugins/plugin.js
CHANGED
|
@@ -31,36 +31,8 @@ exports.createNodesV2 = [
|
|
|
31
31
|
const targetsCache = readTargetsCache(cachePath);
|
|
32
32
|
// Cache jest preset(s) to avoid penalties of module load times. Most of jest configs will use the same preset.
|
|
33
33
|
const presetCache = {};
|
|
34
|
-
const packageManagerWorkspacesGlob = (0, globs_1.combineGlobPatterns)((0, package_json_1.getGlobPatternsFromPackageManagerWorkspaces)(context.workspaceRoot));
|
|
35
|
-
options = normalizeOptions(options);
|
|
36
|
-
const { roots: projectRoots, configFiles: validConfigFiles } = configFiles.reduce((acc, configFile) => {
|
|
37
|
-
const potentialRoot = (0, path_1.dirname)(configFile);
|
|
38
|
-
if (checkIfConfigFileShouldBeProject(configFile, potentialRoot, packageManagerWorkspacesGlob, context)) {
|
|
39
|
-
acc.roots.push(potentialRoot);
|
|
40
|
-
acc.configFiles.push(configFile);
|
|
41
|
-
}
|
|
42
|
-
return acc;
|
|
43
|
-
}, {
|
|
44
|
-
roots: [],
|
|
45
|
-
configFiles: [],
|
|
46
|
-
});
|
|
47
|
-
const hashes = await (0, calculate_hash_for_create_nodes_1.calculateHashesForCreateNodes)(projectRoots, options, context);
|
|
48
34
|
try {
|
|
49
|
-
return await (0, devkit_1.createNodesFromFiles)(
|
|
50
|
-
const projectRoot = projectRoots[idx];
|
|
51
|
-
const hash = hashes[idx];
|
|
52
|
-
targetsCache[hash] ??= await buildJestTargets(configFilePath, projectRoot, options, context, presetCache);
|
|
53
|
-
const { targets, metadata } = targetsCache[hash];
|
|
54
|
-
return {
|
|
55
|
-
projects: {
|
|
56
|
-
[projectRoot]: {
|
|
57
|
-
root: projectRoot,
|
|
58
|
-
targets,
|
|
59
|
-
metadata,
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
};
|
|
63
|
-
}, validConfigFiles, options, context);
|
|
35
|
+
return await (0, devkit_1.createNodesFromFiles)((configFile, options, context) => createNodesInternal(configFile, options, context, targetsCache, presetCache), configFiles, options, context);
|
|
64
36
|
}
|
|
65
37
|
finally {
|
|
66
38
|
writeTargetsToCache(cachePath, targetsCache);
|
|
@@ -73,39 +45,26 @@ exports.createNodesV2 = [
|
|
|
73
45
|
*/
|
|
74
46
|
exports.createNodes = [
|
|
75
47
|
jestConfigGlob,
|
|
76
|
-
|
|
48
|
+
(...args) => {
|
|
77
49
|
devkit_1.logger.warn('`createNodes` is deprecated. Update your plugin to utilize createNodesV2 instead. In Nx 20, this will change to the createNodesV2 API.');
|
|
78
|
-
|
|
79
|
-
const packageManagerWorkspacesGlob = (0, globs_1.combineGlobPatterns)((0, package_json_1.getGlobPatternsFromPackageManagerWorkspaces)(context.workspaceRoot));
|
|
80
|
-
if (!checkIfConfigFileShouldBeProject(configFilePath, projectRoot, packageManagerWorkspacesGlob, context)) {
|
|
81
|
-
return {};
|
|
82
|
-
}
|
|
83
|
-
options = normalizeOptions(options);
|
|
84
|
-
const { targets, metadata } = await buildJestTargets(configFilePath, projectRoot, options, context, {});
|
|
85
|
-
return {
|
|
86
|
-
projects: {
|
|
87
|
-
[projectRoot]: {
|
|
88
|
-
root: projectRoot,
|
|
89
|
-
targets,
|
|
90
|
-
metadata,
|
|
91
|
-
},
|
|
92
|
-
},
|
|
93
|
-
};
|
|
50
|
+
return createNodesInternal(...args, {}, {});
|
|
94
51
|
},
|
|
95
52
|
];
|
|
96
|
-
function
|
|
53
|
+
async function createNodesInternal(configFilePath, options, context, targetsCache, presetCache) {
|
|
54
|
+
const projectRoot = (0, path_1.dirname)(configFilePath);
|
|
55
|
+
const packageManagerWorkspacesGlob = (0, globs_1.combineGlobPatterns)((0, package_json_1.getGlobPatternsFromPackageManagerWorkspaces)(context.workspaceRoot));
|
|
97
56
|
// Do not create a project if package.json and project.json isn't there.
|
|
98
57
|
const siblingFiles = (0, fs_1.readdirSync)((0, path_1.join)(context.workspaceRoot, projectRoot));
|
|
99
58
|
if (!siblingFiles.includes('package.json') &&
|
|
100
59
|
!siblingFiles.includes('project.json')) {
|
|
101
|
-
return
|
|
60
|
+
return {};
|
|
102
61
|
}
|
|
103
62
|
else if (!siblingFiles.includes('project.json') &&
|
|
104
63
|
siblingFiles.includes('package.json')) {
|
|
105
64
|
const path = (0, devkit_1.joinPathFragments)(projectRoot, 'package.json');
|
|
106
65
|
const isPackageJsonProject = (0, minimatch_1.minimatch)(path, packageManagerWorkspacesGlob);
|
|
107
66
|
if (!isPackageJsonProject) {
|
|
108
|
-
return
|
|
67
|
+
return {};
|
|
109
68
|
}
|
|
110
69
|
}
|
|
111
70
|
const jestConfigContent = (0, fs_1.readFileSync)((0, path_1.resolve)(context.workspaceRoot, configFilePath), 'utf-8');
|
|
@@ -113,9 +72,21 @@ function checkIfConfigFileShouldBeProject(configFilePath, projectRoot, packageMa
|
|
|
113
72
|
// The `getJestProjectsAsync` function uses the project graph, which leads to a
|
|
114
73
|
// circular dependency. We can skip this since it's no intended to be used for
|
|
115
74
|
// an Nx project.
|
|
116
|
-
return
|
|
75
|
+
return {};
|
|
117
76
|
}
|
|
118
|
-
|
|
77
|
+
options = normalizeOptions(options);
|
|
78
|
+
const hash = await (0, calculate_hash_for_create_nodes_1.calculateHashForCreateNodes)(projectRoot, options, context);
|
|
79
|
+
targetsCache[hash] ??= await buildJestTargets(configFilePath, projectRoot, options, context, presetCache);
|
|
80
|
+
const { targets, metadata } = targetsCache[hash];
|
|
81
|
+
return {
|
|
82
|
+
projects: {
|
|
83
|
+
[projectRoot]: {
|
|
84
|
+
root: projectRoot,
|
|
85
|
+
targets,
|
|
86
|
+
metadata,
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
};
|
|
119
90
|
}
|
|
120
91
|
async function buildJestTargets(configFilePath, projectRoot, options, context, presetCache) {
|
|
121
92
|
const absConfigFilePath = (0, path_1.resolve)(context.workspaceRoot, configFilePath);
|
|
@@ -145,13 +116,11 @@ async function buildJestTargets(configFilePath, projectRoot, options, context, p
|
|
|
145
116
|
},
|
|
146
117
|
},
|
|
147
118
|
});
|
|
148
|
-
// Not normalizing it here since also affects options for convert-to-inferred.
|
|
149
|
-
const disableJestRuntime = options.disableJestRuntime !== false;
|
|
150
119
|
const cache = (target.cache = true);
|
|
151
|
-
const inputs = (target.inputs = getInputs(namedInputs, rawConfig.preset, projectRoot, context.workspaceRoot, disableJestRuntime));
|
|
120
|
+
const inputs = (target.inputs = getInputs(namedInputs, rawConfig.preset, projectRoot, context.workspaceRoot, options.disableJestRuntime));
|
|
152
121
|
let metadata;
|
|
153
122
|
const groupName = options?.ciGroupName ?? deductGroupNameFromTarget(options?.ciTargetName);
|
|
154
|
-
if (disableJestRuntime) {
|
|
123
|
+
if (options.disableJestRuntime) {
|
|
155
124
|
const outputs = (target.outputs = getOutputs(projectRoot, rawConfig.coverageDirectory
|
|
156
125
|
? (0, path_1.join)(context.workspaceRoot, projectRoot, rawConfig.coverageDirectory)
|
|
157
126
|
: undefined, undefined, context));
|
|
@@ -223,17 +192,10 @@ async function buildJestTargets(configFilePath, projectRoot, options, context, p
|
|
|
223
192
|
}
|
|
224
193
|
else {
|
|
225
194
|
const { readConfig } = requireJestUtil('jest-config', projectRoot, context.workspaceRoot);
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
$0: undefined,
|
|
231
|
-
}, rawConfig, undefined, (0, path_1.dirname)(absConfigFilePath));
|
|
232
|
-
}
|
|
233
|
-
catch (e) {
|
|
234
|
-
console.error(e);
|
|
235
|
-
throw e;
|
|
236
|
-
}
|
|
195
|
+
const config = await readConfig({
|
|
196
|
+
_: [],
|
|
197
|
+
$0: undefined,
|
|
198
|
+
}, rawConfig, undefined, (0, path_1.dirname)(absConfigFilePath));
|
|
237
199
|
const outputs = (target.outputs = getOutputs(projectRoot, config.globalConfig?.coverageDirectory, config.globalConfig?.outputFile, context));
|
|
238
200
|
if (options?.ciTargetName) {
|
|
239
201
|
// nx-ignore-next-line
|
|
@@ -246,7 +208,8 @@ async function buildJestTargets(configFilePath, projectRoot, options, context, p
|
|
|
246
208
|
const source = new jest.SearchSource(jestContext);
|
|
247
209
|
const jestVersion = (0, version_utils_1.getInstalledJestMajorVersion)();
|
|
248
210
|
const specs = jestVersion >= 30
|
|
249
|
-
?
|
|
211
|
+
? // @ts-expect-error Jest 30+ expects the project config as the second argument
|
|
212
|
+
await source.getTestPaths(config.globalConfig, config.projectConfig)
|
|
250
213
|
: await source.getTestPaths(config.globalConfig);
|
|
251
214
|
const testPaths = new Set(specs.tests.map(({ path }) => path));
|
|
252
215
|
if (testPaths.size > 0) {
|
|
@@ -438,19 +401,32 @@ function requireJestUtil(packageName, projectRoot, workspaceRoot) {
|
|
|
438
401
|
}
|
|
439
402
|
async function getTestPaths(projectRoot, rawConfig, absConfigFilePath, context, presetCache) {
|
|
440
403
|
const testMatch = await getJestOption(rawConfig, absConfigFilePath, 'testMatch', presetCache);
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
404
|
+
if (testMatch) {
|
|
405
|
+
return await (0, workspace_context_1.globWithWorkspaceContext)(context.workspaceRoot, testMatch.map((pattern) => (0, path_1.join)(projectRoot, pattern)), []);
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
const testRegex = await getJestOption(rawConfig, absConfigFilePath, 'testRegex', presetCache);
|
|
409
|
+
if (testRegex) {
|
|
410
|
+
const files = [];
|
|
411
|
+
const testRegexes = Array.isArray(rawConfig.testRegex)
|
|
412
|
+
? rawConfig.testRegex.map((r) => new RegExp(r))
|
|
413
|
+
: [new RegExp(rawConfig.testRegex)];
|
|
414
|
+
const projectFiles = await (0, workspace_context_1.getFilesInDirectoryUsingContext)(context.workspaceRoot, projectRoot);
|
|
415
|
+
for (const file of projectFiles) {
|
|
416
|
+
if (testRegexes.some((r) => r.test(file)))
|
|
417
|
+
files.push(file);
|
|
418
|
+
}
|
|
419
|
+
return files;
|
|
420
|
+
}
|
|
421
|
+
else {
|
|
422
|
+
// Default copied from https://github.com/jestjs/jest/blob/d1a2ed7/packages/jest-config/src/Defaults.ts#L84
|
|
423
|
+
const defaultTestMatch = [
|
|
424
|
+
'**/__tests__/**/*.?([mc])[jt]s?(x)',
|
|
425
|
+
'**/?(*.)+(spec|test).?([mc])[jt]s?(x)',
|
|
426
|
+
];
|
|
427
|
+
return await (0, workspace_context_1.globWithWorkspaceContext)(context.workspaceRoot, defaultTestMatch.map((pattern) => (0, path_1.join)(projectRoot, pattern)), []);
|
|
428
|
+
}
|
|
452
429
|
}
|
|
453
|
-
return paths;
|
|
454
430
|
}
|
|
455
431
|
async function getJestOption(rawConfig, absConfigFilePath, optionName, presetCache) {
|
|
456
432
|
if (rawConfig[optionName])
|