@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-beta.3",
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-beta.3",
41
- "@nx/js": "20.5.0-beta.3",
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 parseJestConfig(options: JestExecutorOptions, context: ExecutorContext, multiProjects?: boolean): Promise<Config.Argv>;
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.parseJestConfig = parseJestConfig;
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 parseJestConfig(options, context);
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 parseJestConfig(options, context, multiProjects = false) {
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 parseJestConfig(overrides, context, true);
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,
@@ -7,7 +7,7 @@ export interface JestPluginOptions {
7
7
  */
8
8
  ciGroupName?: string;
9
9
  /**
10
- * Whether to use jest-config and jest-runtime are used to load Jest configuration and context.
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
  */
@@ -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)(async (configFilePath, options, context, idx) => {
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
- async (configFilePath, options, context) => {
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
- const projectRoot = (0, path_1.dirname)(configFilePath);
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 checkIfConfigFileShouldBeProject(configFilePath, projectRoot, packageManagerWorkspacesGlob, context) {
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 false;
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 false;
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 false;
75
+ return {};
117
76
  }
118
- return true;
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
- let config;
227
- try {
228
- config = await readConfig({
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
- ? await source.getTestPaths(config.globalConfig, config.projectConfig)
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
- let paths = await (0, workspace_context_1.globWithWorkspaceContext)(context.workspaceRoot, (testMatch || [
442
- // Default copied from https://github.com/jestjs/jest/blob/d1a2ed7/packages/jest-config/src/Defaults.ts#L84
443
- '**/__tests__/**/*.?([mc])[jt]s?(x)',
444
- '**/?(*.)+(spec|test).?([mc])[jt]s?(x)',
445
- ]).map((pattern) => (0, path_1.join)(projectRoot, pattern)), []);
446
- const testRegex = await getJestOption(rawConfig, absConfigFilePath, 'testRegex', presetCache);
447
- if (testRegex) {
448
- const testRegexes = Array.isArray(rawConfig.testRegex)
449
- ? rawConfig.testRegex.map((r) => new RegExp(r))
450
- : [new RegExp(rawConfig.testRegex)];
451
- paths = paths.filter((path) => testRegexes.some((r) => r.test(path)));
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])