@nx/jest 24.0.0-beta.1 → 24.0.0-beta.3

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.
Files changed (27) hide show
  1. package/dist/internal.d.ts +1 -0
  2. package/dist/internal.js +3 -1
  3. package/dist/src/generators/configuration/configuration.js +23 -22
  4. package/dist/src/generators/configuration/lib/create-jest-config.d.ts +1 -0
  5. package/dist/src/generators/configuration/lib/create-jest-config.js +5 -1
  6. package/dist/src/generators/configuration/lib/ensure-root-jest.d.ts +6 -0
  7. package/dist/src/generators/configuration/lib/ensure-root-jest.js +23 -0
  8. package/dist/src/generators/configuration/schema.d.ts +0 -2
  9. package/dist/src/generators/init/init.js +5 -53
  10. package/dist/src/generators/init/schema.d.ts +0 -2
  11. package/dist/src/migrations/update-24-0-0/finish-inferred-conversion.md +12 -0
  12. package/dist/src/migrations/update-24-0-0/remove-deprecated-executors.d.ts +6 -0
  13. package/dist/src/migrations/update-24-0-0/remove-deprecated-executors.js +10 -0
  14. package/dist/src/migrations/update-24-0-0/remove-deprecated-executors.md +38 -0
  15. package/dist/src/plugins/plugin.js +4 -4
  16. package/executors.json +1 -8
  17. package/migrations.json +7 -0
  18. package/package.json +5 -9
  19. package/dist/src/executors/jest/jest.impl.d.ts +0 -10
  20. package/dist/src/executors/jest/jest.impl.js +0 -181
  21. package/dist/src/executors/jest/schema.json +0 -227
  22. package/dist/src/executors/jest/summary.d.ts +0 -7
  23. package/dist/src/executors/jest/summary.js +0 -155
  24. package/dist/src/generators/configuration/lib/update-workspace.d.ts +0 -3
  25. package/dist/src/generators/configuration/lib/update-workspace.js +0 -32
  26. package/dist/src/utils/deprecation.d.ts +0 -3
  27. package/dist/src/utils/deprecation.js +0 -15
@@ -1,5 +1,6 @@
1
1
  export { versions, getInstalledJestMajorVersion } from './src/utils/versions';
2
2
  export { findRootJestPreset } from './src/utils/config/config-file';
3
+ export { ensureRootJest } from './src/generators/configuration/lib/ensure-root-jest';
3
4
  /**
4
5
  * The Oxlint plugins a Jest-tested project needs. Declared here so the linter
5
6
  * does not have to know what a test runner requires; `@nx/js`'s
package/dist/internal.js CHANGED
@@ -5,12 +5,14 @@
5
5
  // internal consumers and may change without semver protection. Mirrors
6
6
  // `@nx/devkit/internal`.
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.oxlintPlugins = exports.findRootJestPreset = exports.getInstalledJestMajorVersion = exports.versions = void 0;
8
+ exports.oxlintPlugins = exports.ensureRootJest = exports.findRootJestPreset = exports.getInstalledJestMajorVersion = exports.versions = void 0;
9
9
  var versions_1 = require("./src/utils/versions");
10
10
  Object.defineProperty(exports, "versions", { enumerable: true, get: function () { return versions_1.versions; } });
11
11
  Object.defineProperty(exports, "getInstalledJestMajorVersion", { enumerable: true, get: function () { return versions_1.getInstalledJestMajorVersion; } });
12
12
  var config_file_1 = require("./src/utils/config/config-file");
13
13
  Object.defineProperty(exports, "findRootJestPreset", { enumerable: true, get: function () { return config_file_1.findRootJestPreset; } });
14
+ var ensure_root_jest_1 = require("./src/generators/configuration/lib/ensure-root-jest");
15
+ Object.defineProperty(exports, "ensureRootJest", { enumerable: true, get: function () { return ensure_root_jest_1.ensureRootJest; } });
14
16
  /**
15
17
  * The Oxlint plugins a Jest-tested project needs. Declared here so the linter
16
18
  * does not have to know what a test runner requires; `@nx/js`'s
@@ -9,14 +9,12 @@ const internal_2 = require("@nx/js/internal");
9
9
  const config_file_1 = require("../../utils/config/config-file");
10
10
  const init_1 = require("../init/init");
11
11
  const assert_supported_jest_version_1 = require("../../utils/assert-supported-jest-version");
12
- const deprecation_1 = require("../../utils/deprecation");
13
12
  const check_for_test_target_1 = require("./lib/check-for-test-target");
14
13
  const create_files_1 = require("./lib/create-files");
15
14
  const create_jest_config_1 = require("./lib/create-jest-config");
16
15
  const ensure_dependencies_1 = require("./lib/ensure-dependencies");
17
16
  const update_tsconfig_1 = require("./lib/update-tsconfig");
18
17
  const update_vscode_recommended_extensions_1 = require("./lib/update-vscode-recommended-extensions");
19
- const update_workspace_1 = require("./lib/update-workspace");
20
18
  const schemaDefaults = {
21
19
  setupFile: 'none',
22
20
  babelJest: false,
@@ -28,10 +26,6 @@ function normalizeOptions(tree, options) {
28
26
  if (!options.testEnvironment) {
29
27
  options.testEnvironment = 'jsdom';
30
28
  }
31
- const nxJson = (0, devkit_1.readNxJson)(tree);
32
- const addPlugin = process.env.NX_ADD_PLUGINS !== 'false' &&
33
- nxJson.useInferencePlugins !== false;
34
- options.addPlugin ??= addPlugin;
35
29
  options.targetName ??= 'test';
36
30
  if (!options.hasOwnProperty('supportTsx')) {
37
31
  options.supportTsx = false;
@@ -52,7 +46,7 @@ function normalizeOptions(tree, options) {
52
46
  };
53
47
  }
54
48
  function configurationGenerator(tree, schema) {
55
- return configurationGeneratorInternal(tree, { addPlugin: false, ...schema });
49
+ return configurationGeneratorInternal(tree, schema);
56
50
  }
57
51
  async function configurationGeneratorInternal(tree, schema) {
58
52
  (0, assert_supported_jest_version_1.assertSupportedJestVersion)(tree);
@@ -75,21 +69,7 @@ async function configurationGeneratorInternal(tree, schema) {
75
69
  if (shouldAddVsCodeRecommendations) {
76
70
  (0, update_vscode_recommended_extensions_1.updateVsCodeRecommendedExtensions)(tree);
77
71
  }
78
- const nxJson = (0, devkit_1.readNxJson)(tree);
79
- const hasPlugin = nxJson.plugins?.some((p) => {
80
- if (typeof p === 'string') {
81
- return p === '@nx/jest/plugin' && options.targetName === 'test';
82
- }
83
- else {
84
- return (p.plugin === '@nx/jest/plugin' &&
85
- (p.options?.targetName ?? 'test') ===
86
- options.targetName);
87
- }
88
- });
89
- if (!hasPlugin || options.addExplicitTargets) {
90
- (0, deprecation_1.warnJestExecutorGenerating)();
91
- (0, update_workspace_1.updateWorkspace)(tree, options);
92
- }
72
+ addPluginForTargetName(tree, options);
93
73
  if (options.isTsSolutionSetup) {
94
74
  ignoreTestOutput(tree);
95
75
  // in the TS solution setup, the test target depends on the build outputs
@@ -112,6 +92,27 @@ async function configurationGeneratorInternal(tree, schema) {
112
92
  }
113
93
  return (0, devkit_1.runTasksInSerial)(...tasks);
114
94
  }
95
+ // The plugin only infers the target names it is registered for, so any other
96
+ // name needs a registration scoped to this project.
97
+ function addPluginForTargetName(tree, options) {
98
+ const nxJson = (0, devkit_1.readNxJson)(tree) ?? {};
99
+ const hasPlugin = nxJson.plugins?.some((p) => typeof p === 'string'
100
+ ? p === '@nx/jest/plugin' && options.targetName === 'test'
101
+ : p.plugin === '@nx/jest/plugin' &&
102
+ (p.options?.targetName ?? 'test') ===
103
+ options.targetName);
104
+ if (hasPlugin) {
105
+ return;
106
+ }
107
+ const { root } = (0, devkit_1.readProjectConfiguration)(tree, options.project);
108
+ nxJson.plugins ??= [];
109
+ nxJson.plugins.push({
110
+ plugin: '@nx/jest/plugin',
111
+ include: [root === '.' ? '**/*' : `${root}/**/*`],
112
+ options: { targetName: options.targetName },
113
+ });
114
+ (0, devkit_1.updateNxJson)(tree, nxJson);
115
+ }
115
116
  function ignoreTestOutput(tree) {
116
117
  if (!tree.exists('.gitignore')) {
117
118
  devkit_1.logger.warn(`Couldn't find a root .gitignore file to update.`);
@@ -1,4 +1,5 @@
1
1
  import { type Tree } from '@nx/devkit';
2
2
  import { type JestPresetExtension } from '../../../utils/config/config-file';
3
3
  import type { NormalizedJestProjectSchema } from '../schema';
4
+ export declare function writeRootJestPreset(tree: Tree, presetExt: JestPresetExtension): void;
4
5
  export declare function createJestConfig(tree: Tree, options: Partial<NormalizedJestProjectSchema>, presetExt: JestPresetExtension): Promise<void>;
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.writeRootJestPreset = writeRootJestPreset;
3
4
  exports.createJestConfig = createJestConfig;
4
5
  const devkit_1 = require("@nx/devkit");
5
6
  const config_file_1 = require("../../../utils/config/config-file");
6
7
  const internal_1 = require("@nx/js/internal");
7
8
  const internal_2 = require("@nx/devkit/internal");
8
- async function createJestConfig(tree, options, presetExt) {
9
+ function writeRootJestPreset(tree, presetExt) {
9
10
  if (!tree.exists(`jest.preset.${presetExt}`)) {
10
11
  if (presetExt === 'mjs') {
11
12
  tree.write(`jest.preset.${presetExt}`, `import { nxPreset } from '@nx/jest/preset.js';
@@ -19,6 +20,9 @@ export default { ...nxPreset };`);
19
20
  module.exports = { ...nxPreset };`);
20
21
  }
21
22
  }
23
+ }
24
+ async function createJestConfig(tree, options, presetExt) {
25
+ writeRootJestPreset(tree, presetExt);
22
26
  if (options.rootProject) {
23
27
  // we don't want any config to be made because the `configurationGenerator` will do it.
24
28
  // will copy the template config file
@@ -0,0 +1,6 @@
1
+ import { type GeneratorCallback, type Tree } from '@nx/devkit';
2
+ /**
3
+ * Sets up the root preset and swc dependencies for a project that ships its
4
+ * own jest config, such as an e2e project in a workspace without Jest.
5
+ */
6
+ export declare function ensureRootJest(tree: Tree): Promise<GeneratorCallback>;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ensureRootJest = ensureRootJest;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const config_file_1 = require("../../../utils/config/config-file");
6
+ const init_1 = require("../../init/init");
7
+ const create_jest_config_1 = require("./create-jest-config");
8
+ const ensure_dependencies_1 = require("./ensure-dependencies");
9
+ /**
10
+ * Sets up the root preset and swc dependencies for a project that ships its
11
+ * own jest config, such as an e2e project in a workspace without Jest.
12
+ */
13
+ async function ensureRootJest(tree) {
14
+ const initTask = await (0, init_1.jestInitGenerator)(tree, {
15
+ skipFormat: true,
16
+ });
17
+ (0, create_jest_config_1.writeRootJestPreset)(tree, (0, config_file_1.getPresetExt)(tree));
18
+ const depsTask = (0, ensure_dependencies_1.ensureDependencies)(tree, {
19
+ compiler: 'swc',
20
+ testEnvironment: 'node',
21
+ });
22
+ return (0, devkit_1.runTasksInSerial)(initTask, depsTask);
23
+ }
@@ -11,7 +11,6 @@ export interface JestProjectSchema {
11
11
  skipSerializers?: boolean;
12
12
  testEnvironment?: 'node' | 'jsdom' | 'none';
13
13
  skipFormat?: boolean;
14
- addPlugin?: boolean;
15
14
  compiler?: 'tsc' | 'babel' | 'swc';
16
15
  skipPackageJson?: boolean;
17
16
  js?: boolean;
@@ -20,7 +19,6 @@ export interface JestProjectSchema {
20
19
  /**
21
20
  * @internal
22
21
  */
23
- addExplicitTargets?: boolean;
24
22
 
25
23
  /**
26
24
  * @deprecated Use the `compiler` option instead. It will be removed in Nx v22.
@@ -28,46 +28,6 @@ function updateProductionFileSet(tree) {
28
28
  }
29
29
  (0, devkit_1.updateNxJson)(tree, nxJson);
30
30
  }
31
- function addJestTargetDefaults(tree, presetExt) {
32
- const nxJson = (0, devkit_1.readNxJson)(tree) ?? {};
33
- const productionFileSet = nxJson.namedInputs?.production;
34
- // Manage the workspace-wide `@nx/jest:jest` default; `upsertTargetDefault`
35
- // updates the unfiltered entry (or creates one), leaving any project- or
36
- // plugin-scoped jest overrides the user authored untouched.
37
- const existing = (0, internal_1.findTargetDefault)(nxJson.targetDefaults, {
38
- executor: '@nx/jest:jest',
39
- });
40
- const patch = createJestDefaultPatch(existing, productionFileSet, presetExt);
41
- if (Object.keys(patch).length > 0) {
42
- (0, internal_1.upsertTargetDefault)(tree, nxJson, { executor: '@nx/jest:jest', ...patch });
43
- (0, devkit_1.updateNxJson)(tree, nxJson);
44
- }
45
- }
46
- function createJestDefaultPatch(existing, productionFileSet, presetExt) {
47
- const patch = {};
48
- if (existing?.cache === undefined)
49
- patch.cache = true;
50
- // Test targets depend on all their project's sources + production sources of dependencies
51
- if (existing?.inputs === undefined) {
52
- patch.inputs = [
53
- 'default',
54
- productionFileSet ? '^production' : '^default',
55
- `{workspaceRoot}/jest.preset.${presetExt}`,
56
- ];
57
- }
58
- if (existing?.options === undefined) {
59
- patch.options = { passWithNoTests: true };
60
- }
61
- if (existing?.configurations === undefined) {
62
- patch.configurations = {
63
- ci: {
64
- ci: true,
65
- codeCoverage: true,
66
- },
67
- };
68
- }
69
- return patch;
70
- }
71
31
  function updateDependencies(tree, options) {
72
32
  const { jestVersion, nxVersion } = (0, versions_1.versions)(tree);
73
33
  // jest-resolve depends on unrs-resolver, and from jest 30.5.0 it pins a
@@ -83,26 +43,18 @@ function updateDependencies(tree, options) {
83
43
  }, undefined, options.keepExistingVersions ?? true);
84
44
  }
85
45
  function jestInitGenerator(tree, options) {
86
- return jestInitGeneratorInternal(tree, { addPlugin: false, ...options });
46
+ return jestInitGeneratorInternal(tree, options);
87
47
  }
88
48
  async function jestInitGeneratorInternal(tree, options) {
89
49
  (0, assert_supported_jest_version_1.assertSupportedJestVersion)(tree);
90
- const nxJson = (0, devkit_1.readNxJson)(tree);
91
- const addPluginDefault = process.env.NX_ADD_PLUGINS !== 'false' &&
92
- nxJson.useInferencePlugins !== false;
93
- options.addPlugin ??= addPluginDefault;
94
50
  const presetExt = (0, config_file_1.getPresetExt)(tree);
95
51
  if (!tree.exists(`jest.preset.${presetExt}`)) {
96
52
  updateProductionFileSet(tree);
97
- if (options.addPlugin) {
98
- await (0, internal_1.addPlugin)(tree, await (0, devkit_1.createProjectGraphAsync)(), '@nx/jest/plugin', plugin_1.createNodesV2, {
99
- targetName: ['test', 'jest:test', 'jest-test'],
100
- }, options.updatePackageScripts);
101
- }
102
- else {
103
- addJestTargetDefaults(tree, presetExt);
104
- }
105
53
  }
54
+ // Outside the preset gate: executor-era workspaces have a preset but no plugin.
55
+ await (0, internal_1.addPlugin)(tree, await (0, devkit_1.createProjectGraphAsync)(), '@nx/jest/plugin', plugin_1.createNodesV2, {
56
+ targetName: ['test', 'jest:test', 'jest-test'],
57
+ }, options.updatePackageScripts);
106
58
  const tasks = [];
107
59
  if (!options.skipPackageJson) {
108
60
  tasks.push((0, devkit_1.removeDependenciesFromPackageJson)(tree, ['@nx/jest'], []));
@@ -3,6 +3,4 @@ export interface JestInitSchema {
3
3
  skipPackageJson?: boolean;
4
4
  keepExistingVersions?: boolean;
5
5
  updatePackageScripts?: boolean;
6
-
7
- addPlugin?: boolean;
8
6
  }
@@ -0,0 +1,12 @@
1
+ # Replace removed @nx/jest executors with inferred tasks
2
+
3
+ Nx 24 removed `@nx/jest:jest` (including old `@nrwl` aliases).
4
+
5
+ Before changing anything, check for leftover work: a project target, a package.json target or a `targetDefaults` entry still uses a removed executor, or the advisory context reports a conversion error. If none applies, make no changes and stop. Treat each advisory-context item as pending work.
6
+
7
+ 1. Inspect all affected projects and workspace defaults. Repair config-loading errors first. Do not restore executor registrations or install older Nx packages.
8
+ 2. Preserve Jest config paths, setup files, coverage settings and CI configurations. Ensure inferred targets run the same test suites.
9
+ 3. Register `@nx/jest/plugin` with options/includes that preserve custom target names and mixed inferred/explicit projects. Replace remaining removed-executor targets, including those in package.json and filtered targetDefaults. Transfer their behavior before removing obsolete defaults. Preserve configurations, dependencies, cache inputs/outputs and environment behavior. Do not silently delete unsupported options or unrelated targets. Migrate old @nrwl aliases too.
10
+ 4. Run project graph creation with the daemon and graph cache disabled (`NX_DAEMON=false NX_CACHE_PROJECT_GRAPH=false`), using the workspace package manager. Inspect resolved project targets and verify each migrated entrypoint exists and is inferred (a thin alias to an inferred target is acceptable). Resolve graph errors before completing this migration, even if task validation was skipped. Configs must load for subsequent migrations.
11
+ 5. By default run relevant real builds/tests with task cache disabled, including alternate configurations. Honor an existing preference to skip expensive task validation; otherwise offer that option when validation is slow. Skipping expensive tasks never skips conversion or the graph check. Report each skipped task as unverified. Never weaken assertions or change application behavior to make checks pass.
12
+ 6. Report converted projects, graph validation, task results and any skipped checks. Unconverted targets or a broken graph mean the migration is incomplete. Investigate task failures and distinguish missing environment prerequisites from conversion regressions; do not claim a working workspace with unresolved regressions.
@@ -0,0 +1,6 @@
1
+ import type { Tree } from '@nx/devkit';
2
+ export default function update(tree: Tree): Promise<{
3
+ nextSteps?: string[];
4
+ agentContext?: string[];
5
+ skipAgentic?: boolean;
6
+ }>;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = update;
4
+ const internal_1 = require("@nx/devkit/internal");
5
+ function update(tree) {
6
+ return (0, internal_1.migrateRemovedExecutors)(tree, ['@nx/jest:jest', '@nrwl/jest:jest'], async (tree, options) => {
7
+ const { convertToInferred } = require('../../generators/convert-to-inferred/convert-to-inferred');
8
+ return convertToInferred(tree, options);
9
+ });
10
+ }
@@ -0,0 +1,38 @@
1
+ #### Convert `@nx/jest:jest` targets to inferred tasks
2
+
3
+ Nx 24 removes the `@nx/jest:jest` executor and its `@nrwl/jest:jest` alias. The migration registers `@nx/jest/plugin` in `nx.json` and converts the targets that use those executors to inferred tasks. Options the plugin does not infer stay on the target. A target with nothing left to override is removed from project configuration. When several projects share the same remaining options, those options move to a `targetDefaults` entry scoped to the plugin. `targetDefaults` entries keyed by a removed executor are removed once no target uses that executor.
4
+
5
+ The migration lists the targets the converter cannot convert safely. In agentic runs, an AI prompt finishes them and validates the project graph.
6
+
7
+ #### Sample code changes
8
+
9
+ ##### Before
10
+
11
+ ```json title="apps/app1/project.json"
12
+ {
13
+ "name": "app1",
14
+ "targets": {
15
+ "test": {
16
+ "executor": "@nx/jest:jest",
17
+ "options": {
18
+ "jestConfig": "apps/app1/jest.config.js"
19
+ }
20
+ }
21
+ }
22
+ }
23
+ ```
24
+
25
+ ##### After
26
+
27
+ ```json title="nx.json"
28
+ {
29
+ "plugins": [
30
+ {
31
+ "plugin": "@nx/jest/plugin",
32
+ "options": {
33
+ "targetName": "test"
34
+ }
35
+ }
36
+ ]
37
+ }
38
+ ```
@@ -217,7 +217,7 @@ async function buildJestTargets(rawConfig, needsDtsInputs, configFilePath, proje
217
217
  params: 'forward',
218
218
  options: 'forward',
219
219
  });
220
- targets[targetName] = {
220
+ targets[targetName] = (0, internal_1.applyTestFileDirectives)({
221
221
  command: `jest ${relativePath}`,
222
222
  cache,
223
223
  inputs,
@@ -238,7 +238,7 @@ async function buildJestTargets(rawConfig, needsDtsInputs, configFilePath, proje
238
238
  },
239
239
  },
240
240
  },
241
- };
241
+ }, context.workspaceRoot, (0, devkit_1.joinPathFragments)(projectRoot, relativePath), { ignoreServerInputs: false });
242
242
  targetGroup.push(targetName);
243
243
  }
244
244
  if (targetGroup.length > 0) {
@@ -327,7 +327,7 @@ async function buildJestTargets(rawConfig, needsDtsInputs, configFilePath, proje
327
327
  params: 'forward',
328
328
  options: 'forward',
329
329
  });
330
- targets[targetName] = {
330
+ targets[targetName] = (0, internal_1.applyTestFileDirectives)({
331
331
  command: `jest ${relativePath}`,
332
332
  cache,
333
333
  inputs,
@@ -348,7 +348,7 @@ async function buildJestTargets(rawConfig, needsDtsInputs, configFilePath, proje
348
348
  },
349
349
  },
350
350
  },
351
- };
351
+ }, context.workspaceRoot, (0, devkit_1.joinPathFragments)(projectRoot, relativePath), { ignoreServerInputs: false });
352
352
  targetGroup.push(targetName);
353
353
  }
354
354
  targets[options.ciTargetName] = {
package/executors.json CHANGED
@@ -1,10 +1,3 @@
1
1
  {
2
- "executors": {
3
- "jest": {
4
- "implementation": "./dist/src/executors/jest/jest.impl",
5
- "batchImplementation": "./dist/src/executors/jest/jest.impl#batchJest",
6
- "schema": "./dist/src/executors/jest/schema.json",
7
- "description": "Run Jest unit tests."
8
- }
9
- }
2
+ "executors": {}
10
3
  }
package/migrations.json CHANGED
@@ -89,6 +89,13 @@
89
89
  "implementation": "./dist/src/migrations/update-23-1-0/set-ts-jest-isolated-modules",
90
90
  "prompt": "./dist/src/migrations/update-23-1-0/verify-typecheck.md",
91
91
  "documentation": "./dist/src/migrations/update-23-1-0/set-ts-jest-isolated-modules.md"
92
+ },
93
+ "remove-deprecated-executors": {
94
+ "version": "24.0.0-beta.3",
95
+ "description": "Converts targets using the removed `@nx/jest` executors to inferred tasks; an AI prompt finishes the targets the converter cannot convert safely and validates the project graph.",
96
+ "implementation": "./dist/src/migrations/update-24-0-0/remove-deprecated-executors",
97
+ "prompt": "./dist/src/migrations/update-24-0-0/finish-inferred-conversion.md",
98
+ "documentation": "./dist/src/migrations/update-24-0-0/remove-deprecated-executors.md"
92
99
  }
93
100
  },
94
101
  "packageJsonUpdates": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/jest",
3
- "version": "24.0.0-beta.1",
3
+ "version": "24.0.0-beta.3",
4
4
  "private": false,
5
5
  "type": "commonjs",
6
6
  "files": [
@@ -10,7 +10,7 @@
10
10
  "executors.json",
11
11
  "generators.json"
12
12
  ],
13
- "description": "The Nx Plugin for Jest contains executors and generators allowing your workspace to use the powerful Jest testing capabilities.",
13
+ "description": "The Nx Plugin for Jest infers tasks and provides generators allowing your workspace to use the powerful Jest testing capabilities.",
14
14
  "repository": {
15
15
  "type": "git",
16
16
  "url": "https://github.com/nrwl/nx.git",
@@ -103,25 +103,21 @@
103
103
  }
104
104
  },
105
105
  "dependencies": {
106
- "@jest/reporters": "^30.0.2",
107
- "@jest/test-result": "^30.0.2",
108
- "@nx/devkit": "24.0.0-beta.1",
109
- "@nx/js": "24.0.0-beta.1",
106
+ "@nx/devkit": "24.0.0-beta.3",
107
+ "@nx/js": "24.0.0-beta.3",
110
108
  "@phenomnomnominal/tsquery": "~6.2.0",
111
109
  "identity-obj-proxy": "3.0.0",
112
110
  "jest-config": "^30.0.2",
113
111
  "jest-resolve": "^30.0.2",
114
- "jest-util": "^30.0.2",
115
112
  "jsonc-parser": "^3.2.0",
116
113
  "minimatch": "10.2.5",
117
- "picocolors": "^1.1.0",
118
114
  "resolve.exports": "2.0.3",
119
115
  "semver": "^7.6.3",
120
116
  "tslib": "^2.3.0",
121
117
  "yargs-parser": "21.1.1"
122
118
  },
123
119
  "devDependencies": {
124
- "nx": "24.0.0-beta.1"
120
+ "nx": "24.0.0-beta.3"
125
121
  },
126
122
  "publishConfig": {
127
123
  "access": "public"
@@ -1,10 +0,0 @@
1
- import { JestExecutorOptions } from './schema';
2
- import { Config } from '@jest/types';
3
- import { ExecutorContext, TaskGraph } from '@nx/devkit';
4
- import { type BatchResults } from '@nx/devkit/internal';
5
- export declare function jestExecutor(options: JestExecutorOptions, context: ExecutorContext): Promise<{
6
- success: boolean;
7
- }>;
8
- export declare function parseJestConfig(options: JestExecutorOptions, context: ExecutorContext, multiProjects?: boolean): Promise<Config.Argv>;
9
- export default jestExecutor;
10
- export declare function batchJest(taskGraph: TaskGraph, inputs: Record<string, JestExecutorOptions>, overrides: JestExecutorOptions, context: ExecutorContext): Promise<BatchResults>;
@@ -1,181 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.jestExecutor = jestExecutor;
4
- exports.parseJestConfig = parseJestConfig;
5
- exports.batchJest = batchJest;
6
- const tslib_1 = require("tslib");
7
- const jest_1 = require("jest");
8
- const jest_config_1 = require("jest-config");
9
- const reporters_1 = require("@jest/reporters");
10
- const test_result_1 = require("@jest/test-result");
11
- const path = tslib_1.__importStar(require("path"));
12
- const path_1 = require("path");
13
- const schema_json_1 = tslib_1.__importDefault(require("./schema.json"));
14
- const devkit_1 = require("@nx/devkit");
15
- const summary_1 = require("./summary");
16
- const fs_1 = require("fs");
17
- const deprecation_1 = require("../../utils/deprecation");
18
- process.env.NODE_ENV ??= 'test';
19
- async function jestExecutor(options, context) {
20
- (0, deprecation_1.warnJestExecutorDeprecation)();
21
- // Jest registers ts-node with module CJS https://github.com/SimenB/jest/blob/v29.6.4/packages/jest-config/src/readConfigFileAndSetRootDir.ts#L117-L119
22
- // We want to support of ESM via 'module':'nodenext', we need to override the resolution until Jest supports it.
23
- const existingValue = process.env['TS_NODE_COMPILER_OPTIONS'];
24
- process.env['TS_NODE_COMPILER_OPTIONS'] = JSON.stringify({
25
- ...(existingValue ? JSON.parse(existingValue) : {}),
26
- moduleResolution: 'Node10',
27
- module: 'commonjs',
28
- customConditions: null,
29
- });
30
- const config = await parseJestConfig(options, context);
31
- const { results } = await (0, jest_1.runCLI)(config, [options.jestConfig]);
32
- return { success: results.success };
33
- }
34
- function getExtraArgs(options, schema) {
35
- const extraArgs = {};
36
- for (const key of Object.keys(options)) {
37
- if (!schema.properties[key]) {
38
- extraArgs[key] = options[key];
39
- process.argv.push(`--${key}=${options[key]}`);
40
- }
41
- }
42
- return extraArgs;
43
- }
44
- async function parseJestConfig(options, context, multiProjects = false) {
45
- // support passing extra args to jest cli supporting 3rd party plugins
46
- // like 'jest-runner-groups' --group arg
47
- const extraArgs = getExtraArgs(options, schema_json_1.default);
48
- const config = {
49
- ...extraArgs,
50
- $0: undefined,
51
- _: [],
52
- config: options.config,
53
- coverage: options.codeCoverage,
54
- bail: options.bail,
55
- ci: options.ci,
56
- color: options.color,
57
- detectOpenHandles: options.detectOpenHandles,
58
- forceExit: options.forceExit,
59
- logHeapUsage: options.logHeapUsage,
60
- detectLeaks: options.detectLeaks,
61
- json: options.json,
62
- maxWorkers: options.maxWorkers,
63
- onlyChanged: options.onlyChanged,
64
- changedSince: options.changedSince,
65
- outputFile: options.outputFile,
66
- passWithNoTests: options.passWithNoTests,
67
- runInBand: options.runInBand,
68
- showConfig: options.showConfig,
69
- silent: options.silent,
70
- testLocationInResults: options.testLocationInResults,
71
- testNamePattern: options.testNamePattern,
72
- testPathPatterns: options.testPathPatterns,
73
- testPathIgnorePatterns: options.testPathIgnorePatterns,
74
- testTimeout: options.testTimeout,
75
- colors: options.colors,
76
- verbose: options.verbose,
77
- testResultsProcessor: options.testResultsProcessor,
78
- updateSnapshot: options.updateSnapshot,
79
- useStderr: options.useStderr,
80
- watch: options.watch,
81
- watchAll: options.watchAll,
82
- randomize: options.randomize,
83
- };
84
- if (!multiProjects) {
85
- options.jestConfig = path.resolve(context.root, options.jestConfig);
86
- }
87
- if (options.testFile) {
88
- config._.push(options.testFile);
89
- }
90
- if (options.findRelatedTests) {
91
- const parsedTests = options.findRelatedTests
92
- .split(',')
93
- .map((s) => s.trim());
94
- config._.push(...parsedTests);
95
- config.findRelatedTests = true;
96
- }
97
- if (options.coverageDirectory) {
98
- config.coverageDirectory = path.join(context.root, options.coverageDirectory);
99
- }
100
- if (options.clearCache) {
101
- config.clearCache = true;
102
- }
103
- if (options.reporters && options.reporters.length > 0) {
104
- config.reporters = options.reporters;
105
- }
106
- if (Array.isArray(options.coverageReporters) &&
107
- options.coverageReporters.length > 0) {
108
- config.coverageReporters = options.coverageReporters;
109
- }
110
- return config;
111
- }
112
- exports.default = jestExecutor;
113
- async function batchJest(taskGraph, inputs, overrides, context) {
114
- let configPaths = [];
115
- let selectedProjects = [];
116
- let projectsWithNoName = [];
117
- for (const task of taskGraph.roots) {
118
- let configPath = path.resolve(context.root, inputs[task].jestConfig);
119
- configPaths.push(configPath);
120
- /* The display name in the jest.config.js is the correct project name jest
121
- * uses to determine projects. It is usually the same as the Nx projectName
122
- * but it can be changed. The safest method is to extract the displayName
123
- * from the config file, but skip the project if it does not exist. */
124
- const displayNameValueRegex = new RegExp(/(['"]+.*['"])(?<=displayName+.*)/, 'g');
125
- const fileContents = (0, fs_1.readFileSync)(configPath, { encoding: 'utf-8' });
126
- if (!displayNameValueRegex.test(fileContents)) {
127
- projectsWithNoName.push([task.split(':')[0], configPath]);
128
- continue;
129
- }
130
- const displayName = fileContents
131
- .match(displayNameValueRegex)
132
- .map((value) => value.substring(1, value.length - 1))[0];
133
- selectedProjects.push(displayName);
134
- }
135
- if (projectsWithNoName.length > 0) {
136
- throw new Error((0, devkit_1.stripIndents) `Some projects do not have a "displayName" property. Jest Batch Mode requires this to be set. Please ensure this value is set.
137
-
138
- Projects missing "displayName":
139
- ${projectsWithNoName.map(([project, configPath]) => ` - ${project} - ${configPath}\r\n`)}
140
- You can learn more about this requirement from Jest here: https://jestjs.io/docs/cli#--selectprojects-project1--projectn`);
141
- }
142
- const parsedConfigs = await parseJestConfig(overrides, context, true);
143
- const { globalConfig, results } = await (0, jest_1.runCLI)({
144
- ...parsedConfigs,
145
- selectProjects: selectedProjects,
146
- }, [devkit_1.workspaceRoot]);
147
- const { configs } = await (0, jest_config_1.readConfigs)({ $0: undefined, _: [] }, configPaths);
148
- const jestTaskExecutionResults = {};
149
- for (let i = 0; i < taskGraph.roots.length; i++) {
150
- let root = taskGraph.roots[i];
151
- const aggregatedResults = (0, test_result_1.makeEmptyAggregatedTestResult)();
152
- aggregatedResults.startTime = results.startTime;
153
- let endTime;
154
- const projectRoot = (0, path_1.join)(context.root, taskGraph.tasks[root].projectRoot);
155
- let resultOutput = '';
156
- for (const testResult of results.testResults) {
157
- if (testResult.testFilePath.startsWith(projectRoot)) {
158
- aggregatedResults.startTime = aggregatedResults.startTime
159
- ? Math.min(aggregatedResults.startTime, testResult.perfStats.start)
160
- : testResult.perfStats.start;
161
- endTime = endTime
162
- ? Math.max(testResult.perfStats.end, endTime)
163
- : testResult.perfStats.end;
164
- (0, test_result_1.addResult)(aggregatedResults, testResult);
165
- resultOutput +=
166
- '\n\r' +
167
- reporters_1.utils.getResultHeader(testResult, globalConfig, configs[i]);
168
- }
169
- }
170
- aggregatedResults.numTotalTestSuites = aggregatedResults.testResults.length;
171
- jestTaskExecutionResults[root] = {
172
- startTime: aggregatedResults.startTime,
173
- endTime,
174
- success: aggregatedResults.numFailedTests === 0,
175
- // TODO(caleb): getSummary assumed endTime is Date.now().
176
- // might need to make own method to correctly set the endtime base on tests instead of _now_
177
- terminalOutput: resultOutput + '\n\r\n\r' + (0, summary_1.getSummary)(aggregatedResults),
178
- };
179
- }
180
- return jestTaskExecutionResults;
181
- }
@@ -1,227 +0,0 @@
1
- {
2
- "version": 2,
3
- "outputCapture": "direct-nodejs",
4
- "title": "Jest Builder",
5
- "description": "Jest target options for Build Facade.",
6
- "cli": "nx",
7
- "type": "object",
8
- "x-deprecated": "The `@nx/jest:jest` executor is deprecated and will be removed in Nx v24. Run `nx g @nx/jest:convert-to-inferred` to migrate to the `@nx/jest/plugin` inferred plugin. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.",
9
- "presets": [
10
- {
11
- "name": "Pass Without Tests",
12
- "keys": ["jestConfig", "passWithNoTests"]
13
- },
14
- {
15
- "name": "Code Coverage",
16
- "keys": ["jestConfig", "coverageReporters"]
17
- },
18
- {
19
- "name": "Stop After 'n' Failed",
20
- "keys": ["jestConfig", "bail"]
21
- }
22
- ],
23
- "properties": {
24
- "codeCoverage": {
25
- "description": "Indicates that test coverage information should be collected and reported in the output. (https://jestjs.io/docs/cli#--coverageboolean)",
26
- "type": "boolean",
27
- "aliases": ["coverage"]
28
- },
29
- "config": {
30
- "description": "The path to a Jest config file specifying how to find and execute tests. If no `rootDir` is set in the config, the directory containing the config file is assumed to be the `rootDir` for the project. This can also be a JSON-encoded value which Jest will use as configuration.",
31
- "type": "string"
32
- },
33
- "clearCache": {
34
- "description": "Deletes the Jest cache directory and then exits without running tests. Will delete Jest's default cache directory. _Note: clearing the cache will reduce performance_.",
35
- "type": "boolean"
36
- },
37
- "detectOpenHandles": {
38
- "description": "Attempt to collect and print open handles preventing Jest from exiting cleanly (https://jestjs.io/docs/cli#--detectopenhandles)",
39
- "type": "boolean"
40
- },
41
- "logHeapUsage": {
42
- "description": "Logs the heap usage after every test. Useful to debug memory leaks. Use together with --runInBand and --expose-gc in node.",
43
- "type": "boolean"
44
- },
45
- "detectLeaks": {
46
- "description": "**EXPERIMENTAL**: Detect memory leaks in tests. After executing a test, it will try to garbage collect the global object used, and fail if it was leaked",
47
- "type": "boolean"
48
- },
49
- "jestConfig": {
50
- "description": "The path of the Jest configuration. (https://jestjs.io/docs/en/configuration)",
51
- "type": "string",
52
- "x-completion-type": "file",
53
- "x-completion-glob": "jest.config@(.js|.ts)"
54
- },
55
- "testFile": {
56
- "description": "The name of the file to test.",
57
- "type": "string",
58
- "$default": {
59
- "$source": "argv",
60
- "index": 0
61
- }
62
- },
63
- "tsConfig": {
64
- "description": "The path to the TypeScript configuration file, relative to the workspace root. Note this is only metadata used by Angular migrations. This executor does not use it.",
65
- "type": "string",
66
- "x-completion-type": "file",
67
- "x-completion-glob": "tsconfig.*.json"
68
- },
69
- "bail": {
70
- "alias": "b",
71
- "description": "Exit the test suite immediately after `n` number of failing tests. (https://jestjs.io/docs/cli#--bail)",
72
- "oneOf": [
73
- {
74
- "type": "number"
75
- },
76
- {
77
- "type": "boolean"
78
- }
79
- ]
80
- },
81
- "ci": {
82
- "description": "Whether to run Jest in continuous integration (CI) mode. This option is on by default in most popular CI environments. It will prevent snapshots from being written unless explicitly requested. (https://jestjs.io/docs/cli#--ci)",
83
- "type": "boolean"
84
- },
85
- "color": {
86
- "alias": "colors",
87
- "description": "Forces test results output color highlighting (even if `stdout` is not a TTY). Set to false if you would like to have no colors. (https://jestjs.io/docs/cli#--colors)",
88
- "type": "boolean"
89
- },
90
- "findRelatedTests": {
91
- "description": "Find and run the tests that cover a comma separated list of source files that were passed in as arguments. (https://jestjs.io/docs/cli#--findrelatedtests-spaceseparatedlistofsourcefiles)",
92
- "type": "string"
93
- },
94
- "forceExit": {
95
- "description": "Force Jest to exit after all tests have completed running. This is useful when resources set up by test code cannot be adequately cleaned up.This feature is an escape-hatch. If Jest doesn't exit at the end of a test run, it means external resources are still being held on to or timers are still pending in your code. It is advised to tear down external resources after each test to make sure Jest can shut down cleanly. You can use --detectOpenHandles to help track it down.",
96
- "type": "boolean"
97
- },
98
- "json": {
99
- "description": "Prints the test results in `JSON`. This mode will send all other test output and user messages to `stderr`. (https://jestjs.io/docs/cli#--json)",
100
- "type": "boolean"
101
- },
102
- "maxWorkers": {
103
- "alias": "w",
104
- "description": "Specifies the maximum number of workers the worker-pool will spawn for running tests. This defaults to the number of the cores available on your machine. Useful for CI. (its usually best not to override this default) (https://jestjs.io/docs/cli#--maxworkersnumstring)",
105
- "oneOf": [
106
- {
107
- "type": "number"
108
- },
109
- {
110
- "type": "string"
111
- }
112
- ]
113
- },
114
- "onlyChanged": {
115
- "alias": "o",
116
- "description": "Attempts to identify which tests to run based on which files have changed in the current repository. Only works if you're running tests in a `git` or `hg` repository at the moment. (https://jestjs.io/docs/cli#--onlychanged)",
117
- "type": "boolean"
118
- },
119
- "changedSince": {
120
- "description": "Runs tests related to the changes since the provided branch or commit hash. If the current branch has diverged from the given branch, then only changes made locally will be tested. (https://jestjs.io/docs/cli#--changedsince)",
121
- "type": "string"
122
- },
123
- "outputFile": {
124
- "description": "Write test results to a file when the `--json` option is also specified. (https://jestjs.io/docs/cli#--outputfilefilename)",
125
- "type": "string"
126
- },
127
- "passWithNoTests": {
128
- "description": "Will not fail if no tests are found (for example while using `--testPathPatterns`.) (https://jestjs.io/docs/cli#--passwithnotests)",
129
- "type": "boolean"
130
- },
131
- "randomize": {
132
- "description": "Shuffle the order of the tests within a file. The shuffling is based on the seed. This option is only supported using the default jest-circus test runner.",
133
- "type": "boolean"
134
- },
135
- "runInBand": {
136
- "alias": "i",
137
- "description": "Run all tests serially in the current process (rather than creating a worker pool of child processes that run tests). This is sometimes useful for debugging, but such use cases are pretty rare. Useful for CI. (https://jestjs.io/docs/cli#--runinband)",
138
- "type": "boolean"
139
- },
140
- "showConfig": {
141
- "description": "Print your Jest config and then exits. (https://jestjs.io/docs/en/cli#--showconfig)",
142
- "type": "boolean"
143
- },
144
- "silent": {
145
- "description": "Prevent tests from printing messages through the console. (https://jestjs.io/docs/cli#--silent)",
146
- "type": "boolean"
147
- },
148
- "testNamePattern": {
149
- "alias": "t",
150
- "description": "Run only tests with a name that matches the regex pattern. (https://jestjs.io/docs/cli#--testnamepatternregex)",
151
- "type": "string"
152
- },
153
- "testPathIgnorePatterns": {
154
- "description": "An array of regexp pattern strings that is matched against all tests paths before executing the test. Only run those tests with a path that does not match with the provided regexp expressions. (https://jestjs.io/docs/cli#--testpathignorepatternsregexarray)",
155
- "type": "array",
156
- "items": {
157
- "type": "string"
158
- }
159
- },
160
- "testPathPatterns": {
161
- "description": "An array of regexp pattern strings that is matched against all tests paths before executing the test. (https://jestjs.io/docs/cli#--testpathpatternsregex)",
162
- "type": "array",
163
- "items": {
164
- "type": "string"
165
- },
166
- "default": []
167
- },
168
- "colors": {
169
- "description": "Forces test results output highlighting even if stdout is not a TTY. (https://jestjs.io/docs/cli#--colors)",
170
- "type": "boolean"
171
- },
172
- "reporters": {
173
- "description": "Run tests with specified reporters. Reporter options are not available via CLI. Example with multiple reporters: `jest --reporters=\"default\" --reporters=\"jest-junit\"`. (https://jestjs.io/docs/cli#--reporters)",
174
- "type": "array",
175
- "items": {
176
- "type": "string"
177
- }
178
- },
179
- "verbose": {
180
- "description": "Display individual test results with the test suite hierarchy. (https://jestjs.io/docs/cli#--verbose)",
181
- "type": "boolean"
182
- },
183
- "coverageReporters": {
184
- "description": "A list of reporter names that Jest uses when writing coverage reports. Any istanbul reporter.",
185
- "type": "array",
186
- "items": {
187
- "type": "string"
188
- }
189
- },
190
- "coverageDirectory": {
191
- "description": "The directory where Jest should output its coverage files.",
192
- "type": "string",
193
- "x-completion-type": "directory"
194
- },
195
- "testResultsProcessor": {
196
- "description": "Node module that implements a custom results processor. (https://jestjs.io/docs/en/configuration#testresultsprocessor-string)",
197
- "type": "string"
198
- },
199
- "updateSnapshot": {
200
- "alias": "u",
201
- "description": "Use this flag to re-record snapshots. Can be used together with a test suite pattern or with `--testNamePattern` to re-record snapshot for test matching the pattern. (https://jestjs.io/docs/cli#--updatesnapshot)",
202
- "type": "boolean"
203
- },
204
- "useStderr": {
205
- "description": "Divert all output to stderr.",
206
- "type": "boolean"
207
- },
208
- "watch": {
209
- "description": "Watch files for changes and rerun tests related to changed files. If you want to re-run all tests when a file has changed, use the `--watchAll` option. (https://jestjs.io/docs/cli#--watch)",
210
- "type": "boolean"
211
- },
212
- "watchAll": {
213
- "description": "Watch files for changes and rerun all tests when something changes. If you want to re-run only the tests that depend on the changed files, use the `--watch` option. (https://jestjs.io/docs/cli#--watchall)",
214
- "type": "boolean"
215
- },
216
- "testLocationInResults": {
217
- "description": "Adds a location field to test results. Used to report location of a test in a reporter. { \"column\": 4, \"line\": 5 } (https://jestjs.io/docs/cli#--testlocationinresults)",
218
- "type": "boolean"
219
- },
220
- "testTimeout": {
221
- "description": "Default timeout of a test in milliseconds. Default value: `5000`. (https://jestjs.io/docs/cli#--testtimeoutnumber)",
222
- "type": "number"
223
- }
224
- },
225
- "required": ["jestConfig"],
226
- "examplesFile": "../../../docs/jest-examples.md"
227
- }
@@ -1,7 +0,0 @@
1
- import { AggregatedResult } from '@jest/reporters';
2
- export declare const getSummary: (aggregatedResults: AggregatedResult, options?: {
3
- currentTestCases?: any;
4
- estimatedTime?: number;
5
- roundTime?: boolean;
6
- width?: number;
7
- }) => string;
@@ -1,155 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getSummary = void 0;
4
- const tslib_1 = require("tslib");
5
- const jest_util_1 = require("jest-util");
6
- const pc = tslib_1.__importStar(require("picocolors"));
7
- /**
8
- * Copied from the jest repo because these utility functions are not exposed through the package
9
- * https://github.com/facebook/jest/blob/7a64ede2163eba4ecc725f448cd92102cd8c14aa/packages/jest-reporters/src/utils.ts
10
- */
11
- const PROGRESS_BAR_WIDTH = 40;
12
- const getValuesCurrentTestCases = (currentTestCases = []) => {
13
- let numFailingTests = 0;
14
- let numPassingTests = 0;
15
- let numPendingTests = 0;
16
- let numTodoTests = 0;
17
- let numTotalTests = 0;
18
- currentTestCases.forEach((testCase) => {
19
- switch (testCase.testCaseResult.status) {
20
- case 'failed': {
21
- numFailingTests++;
22
- break;
23
- }
24
- case 'passed': {
25
- numPassingTests++;
26
- break;
27
- }
28
- case 'skipped': {
29
- numPendingTests++;
30
- break;
31
- }
32
- case 'todo': {
33
- numTodoTests++;
34
- break;
35
- }
36
- }
37
- numTotalTests++;
38
- });
39
- return {
40
- numFailingTests,
41
- numPassingTests,
42
- numPendingTests,
43
- numTodoTests,
44
- numTotalTests,
45
- };
46
- };
47
- const renderTime = (runTime, estimatedTime, width) => {
48
- // If we are more than one second over the estimated time, highlight it.
49
- const renderedTime = estimatedTime && runTime >= estimatedTime + 1
50
- ? pc.bold(pc.yellow((0, jest_util_1.formatTime)(runTime, 0)))
51
- : (0, jest_util_1.formatTime)(runTime, 0);
52
- let time = pc.bold(`Time:`) + ` ${renderedTime}`;
53
- if (runTime < estimatedTime) {
54
- time += `, estimated ${(0, jest_util_1.formatTime)(estimatedTime, 0)}`;
55
- }
56
- // Only show a progress bar if the test run is actually going to take
57
- // some time.
58
- if (estimatedTime > 2 && runTime < estimatedTime && width) {
59
- const availableWidth = Math.min(PROGRESS_BAR_WIDTH, width);
60
- const length = Math.min(Math.floor((runTime / estimatedTime) * availableWidth), availableWidth);
61
- if (availableWidth >= 2) {
62
- time +=
63
- '\n' +
64
- pc.green('█').repeat(length) +
65
- pc.white('█').repeat(availableWidth - length);
66
- }
67
- }
68
- return time;
69
- };
70
- const getSummary = (aggregatedResults, options) => {
71
- let runTime = (Date.now() - aggregatedResults.startTime) / 1000;
72
- if (options?.roundTime) {
73
- runTime = Math.floor(runTime);
74
- }
75
- const { numFailingTests, numPendingTests, numTodoTests, numPassingTests, numTotalTests, } = getValuesCurrentTestCases(options?.currentTestCases);
76
- const estimatedTime = options?.estimatedTime || 0;
77
- const snapshotResults = aggregatedResults.snapshot;
78
- const snapshotsAdded = snapshotResults.added;
79
- const snapshotsFailed = snapshotResults.unmatched;
80
- const snapshotsOutdated = snapshotResults.unchecked;
81
- const snapshotsFilesRemoved = snapshotResults.filesRemoved;
82
- const snapshotsDidUpdate = snapshotResults.didUpdate;
83
- const snapshotsPassed = snapshotResults.matched;
84
- const snapshotsTotal = snapshotResults.total;
85
- const snapshotsUpdated = snapshotResults.updated;
86
- const suitesFailed = aggregatedResults.numFailedTestSuites;
87
- const suitesPassed = aggregatedResults.numPassedTestSuites;
88
- const suitesPending = aggregatedResults.numPendingTestSuites;
89
- const suitesRun = suitesFailed + suitesPassed;
90
- const suitesTotal = aggregatedResults.numTotalTestSuites;
91
- const testsFailed = aggregatedResults.numFailedTests;
92
- const testsPassed = aggregatedResults.numPassedTests;
93
- const testsPending = aggregatedResults.numPendingTests;
94
- const testsTodo = aggregatedResults.numTodoTests;
95
- const testsTotal = aggregatedResults.numTotalTests;
96
- const width = options?.width || 0;
97
- const suites = pc.bold('Test Suites: ') +
98
- (suitesFailed ? pc.bold(pc.red(`${suitesFailed} failed`)) + ', ' : '') +
99
- (suitesPending
100
- ? pc.bold(pc.yellow(`${suitesPending} skipped`)) + ', '
101
- : '') +
102
- (suitesPassed ? pc.bold(pc.green(`${suitesPassed} passed`)) + ', ' : '') +
103
- (suitesRun !== suitesTotal
104
- ? suitesRun + ' of ' + suitesTotal
105
- : suitesTotal) +
106
- ` total`;
107
- const updatedTestsFailed = testsFailed + numFailingTests;
108
- const updatedTestsPending = testsPending + numPendingTests;
109
- const updatedTestsTodo = testsTodo + numTodoTests;
110
- const updatedTestsPassed = testsPassed + numPassingTests;
111
- const updatedTestsTotal = testsTotal + numTotalTests;
112
- const tests = pc.bold('Tests: ') +
113
- (updatedTestsFailed > 0
114
- ? pc.bold(pc.red(`${updatedTestsFailed} failed`)) + ', '
115
- : '') +
116
- (updatedTestsPending > 0
117
- ? pc.bold(pc.yellow(`${updatedTestsPending} skipped`)) + ', '
118
- : '') +
119
- (updatedTestsTodo > 0
120
- ? pc.bold(pc.magenta(`${updatedTestsTodo} todo`)) + ', '
121
- : '') +
122
- (updatedTestsPassed > 0
123
- ? pc.bold(pc.green(`${updatedTestsPassed} passed`)) + ', '
124
- : '') +
125
- `${updatedTestsTotal} total`;
126
- const snapshots = pc.bold('Snapshots: ') +
127
- (snapshotsFailed
128
- ? pc.bold(pc.red(`${snapshotsFailed} failed`)) + ', '
129
- : '') +
130
- (snapshotsOutdated && !snapshotsDidUpdate
131
- ? pc.bold(pc.yellow(`${snapshotsOutdated} obsolete`)) + ', '
132
- : '') +
133
- (snapshotsOutdated && snapshotsDidUpdate
134
- ? pc.bold(pc.green(`${snapshotsOutdated} removed`)) + ', '
135
- : '') +
136
- (snapshotsFilesRemoved && !snapshotsDidUpdate
137
- ? pc.bold(pc.yellow((0, jest_util_1.pluralize)('file', snapshotsFilesRemoved) + ' obsolete')) + ', '
138
- : '') +
139
- (snapshotsFilesRemoved && snapshotsDidUpdate
140
- ? pc.bold(pc.green((0, jest_util_1.pluralize)('file', snapshotsFilesRemoved) + ' removed')) + ', '
141
- : '') +
142
- (snapshotsUpdated
143
- ? pc.bold(pc.green(`${snapshotsUpdated} updated`)) + ', '
144
- : '') +
145
- (snapshotsAdded
146
- ? pc.bold(pc.green(`${snapshotsAdded} written`)) + ', '
147
- : '') +
148
- (snapshotsPassed
149
- ? pc.bold(pc.green(`${snapshotsPassed} passed`)) + ', '
150
- : '') +
151
- `${snapshotsTotal} total`;
152
- const time = renderTime(runTime, estimatedTime, width);
153
- return [suites, tests, snapshots, time].join('\n');
154
- };
155
- exports.getSummary = getSummary;
@@ -1,3 +0,0 @@
1
- import { type Tree } from '@nx/devkit';
2
- import type { NormalizedJestProjectSchema } from '../schema';
3
- export declare function updateWorkspace(tree: Tree, options: NormalizedJestProjectSchema): void;
@@ -1,32 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.updateWorkspace = updateWorkspace;
4
- const devkit_1 = require("@nx/devkit");
5
- const versions_1 = require("../../../utils/versions");
6
- function updateWorkspace(tree, options) {
7
- const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.project);
8
- if (!projectConfig.targets) {
9
- projectConfig.targets = {};
10
- }
11
- // Detect Jest 30+ to use .cts config files (CommonJS TypeScript)
12
- const jestMajorVersion = (0, versions_1.getInstalledJestMajorVersion)(tree);
13
- const useCommonJsConfig = jestMajorVersion === null || jestMajorVersion >= 30;
14
- const jestConfigExt = options.js ? 'js' : useCommonJsConfig ? 'cts' : 'ts';
15
- projectConfig.targets[options.targetName] = {
16
- executor: '@nx/jest:jest',
17
- outputs: [
18
- options.isTsSolutionSetup
19
- ? '{projectRoot}/test-output/jest/coverage'
20
- : (0, devkit_1.joinPathFragments)('{workspaceRoot}', 'coverage', options.rootProject ? '{projectName}' : '{projectRoot}'),
21
- ],
22
- options: {
23
- jestConfig: (0, devkit_1.joinPathFragments)(projectConfig.root, `jest.config.${jestConfigExt}`),
24
- },
25
- };
26
- if (options.setupFile === 'angular') {
27
- // We set the tsConfig in the target options so Angular migrations can discover it
28
- projectConfig.targets[options.targetName].options.tsConfig =
29
- (0, devkit_1.joinPathFragments)(projectConfig.root, 'tsconfig.spec.json');
30
- }
31
- (0, devkit_1.updateProjectConfiguration)(tree, options.project, projectConfig);
32
- }
@@ -1,3 +0,0 @@
1
- export declare const JEST_EXECUTOR_DEPRECATION_MESSAGE = "The `@nx/jest:jest` executor is deprecated and will be removed in Nx v24. Run `nx g @nx/jest:convert-to-inferred` to migrate to the `@nx/jest/plugin` inferred targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.";
2
- export declare function warnJestExecutorDeprecation(): void;
3
- export declare function warnJestExecutorGenerating(): void;
@@ -1,15 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.JEST_EXECUTOR_DEPRECATION_MESSAGE = void 0;
4
- exports.warnJestExecutorDeprecation = warnJestExecutorDeprecation;
5
- exports.warnJestExecutorGenerating = warnJestExecutorGenerating;
6
- const devkit_1 = require("@nx/devkit");
7
- // TODO(v24): Remove the @nx/jest:jest executor. The inferred plugin
8
- // (@nx/jest/plugin) and the convert-to-inferred generator stay supported.
9
- exports.JEST_EXECUTOR_DEPRECATION_MESSAGE = 'The `@nx/jest:jest` executor is deprecated and will be removed in Nx v24. Run `nx g @nx/jest:convert-to-inferred` to migrate to the `@nx/jest/plugin` inferred targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.';
10
- function warnJestExecutorDeprecation() {
11
- devkit_1.logger.warn(exports.JEST_EXECUTOR_DEPRECATION_MESSAGE);
12
- }
13
- function warnJestExecutorGenerating() {
14
- devkit_1.logger.warn('Generating a target that uses the deprecated `@nx/jest:jest` executor. The executor will be removed in Nx v24. Run `nx g @nx/jest:convert-to-inferred` next to migrate this target to the `@nx/jest/plugin` inferred plugin and prevent future generators from emitting executor targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.');
15
- }