@nx/jest 18.1.0-beta.1 → 18.1.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.
package/index.d.ts CHANGED
@@ -5,4 +5,4 @@ export declare const jestProjectGenerator: typeof configurationGenerator;
5
5
  export { addPropertyToJestConfig, removePropertyFromJestConfig, } from './src/utils/config/update-config';
6
6
  export { jestConfigObjectAst } from './src/utils/config/functions';
7
7
  export { jestInitGenerator } from './src/generators/init/init';
8
- export { getJestProjects, getNestedJestProjects, } from './src/utils/config/get-jest-projects';
8
+ export { getJestProjects, getJestProjectsAsync, getNestedJestProjects, } from './src/utils/config/get-jest-projects';
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getNestedJestProjects = exports.getJestProjects = exports.jestInitGenerator = exports.jestConfigObjectAst = exports.removePropertyFromJestConfig = exports.addPropertyToJestConfig = exports.jestProjectGenerator = exports.configurationGenerator = void 0;
3
+ exports.getNestedJestProjects = exports.getJestProjectsAsync = exports.getJestProjects = exports.jestInitGenerator = exports.jestConfigObjectAst = exports.removePropertyFromJestConfig = exports.addPropertyToJestConfig = exports.jestProjectGenerator = exports.configurationGenerator = void 0;
4
4
  const configuration_1 = require("./src/generators/configuration/configuration");
5
5
  Object.defineProperty(exports, "configurationGenerator", { enumerable: true, get: function () { return configuration_1.configurationGenerator; } });
6
6
  // Exported for backwards compatibility in case a plugin is using the old name.
@@ -15,4 +15,5 @@ var init_1 = require("./src/generators/init/init");
15
15
  Object.defineProperty(exports, "jestInitGenerator", { enumerable: true, get: function () { return init_1.jestInitGenerator; } });
16
16
  var get_jest_projects_1 = require("./src/utils/config/get-jest-projects");
17
17
  Object.defineProperty(exports, "getJestProjects", { enumerable: true, get: function () { return get_jest_projects_1.getJestProjects; } });
18
+ Object.defineProperty(exports, "getJestProjectsAsync", { enumerable: true, get: function () { return get_jest_projects_1.getJestProjectsAsync; } });
18
19
  Object.defineProperty(exports, "getNestedJestProjects", { enumerable: true, get: function () { return get_jest_projects_1.getNestedJestProjects; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/jest",
3
- "version": "18.1.0-beta.1",
3
+ "version": "18.1.0-beta.3",
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": {
@@ -36,6 +36,8 @@
36
36
  "dependencies": {
37
37
  "@jest/reporters": "^29.4.1",
38
38
  "@jest/test-result": "^29.4.1",
39
+ "@nx/devkit": "18.1.0-beta.3",
40
+ "@nx/js": "18.1.0-beta.3",
39
41
  "@phenomnomnominal/tsquery": "~5.0.1",
40
42
  "chalk": "^4.1.0",
41
43
  "identity-obj-proxy": "3.0.0",
@@ -45,9 +47,8 @@
45
47
  "minimatch": "9.0.3",
46
48
  "resolve.exports": "1.1.0",
47
49
  "tslib": "^2.3.0",
48
- "@nx/devkit": "18.1.0-beta.1",
49
- "@nx/js": "18.1.0-beta.1",
50
- "@nrwl/jest": "18.1.0-beta.1"
50
+ "yargs-parser": "21.1.1",
51
+ "@nrwl/jest": "18.1.0-beta.3"
51
52
  },
52
53
  "publishConfig": {
53
54
  "access": "public"
@@ -24,7 +24,10 @@ function normalizeOptions(tree, options) {
24
24
  if (!options.testEnvironment) {
25
25
  options.testEnvironment = 'jsdom';
26
26
  }
27
- options.addPlugin ??= process.env.NX_ADD_PLUGINS !== 'false';
27
+ const nxJson = (0, devkit_1.readNxJson)(tree);
28
+ const addPlugin = process.env.NX_ADD_PLUGINS !== 'false' &&
29
+ nxJson.useInferencePlugins !== false;
30
+ options.addPlugin ??= addPlugin;
28
31
  options.targetName ??= 'test';
29
32
  if (!options.hasOwnProperty('supportTsx')) {
30
33
  options.supportTsx = false;
@@ -44,9 +44,9 @@ async function createJestConfig(tree, options, presetExt) {
44
44
  const [jestTargetName, jestTargetConfigInGraph] = jestTarget;
45
45
  // if root project doesn't have jest target, there's nothing to migrate
46
46
  const rootProjectConfig = (0, devkit_1.readProjectConfiguration)(tree, rootProject.name);
47
- if (rootProjectConfig.targets['test']?.executor === 'nx:run-commands'
48
- ? rootProjectConfig.targets['test']?.command !== 'jest'
49
- : rootProjectConfig.targets['test']?.options?.jestConfig !==
47
+ if (rootProjectConfig.targets?.['test']?.executor === 'nx:run-commands'
48
+ ? rootProjectConfig.targets?.['test']?.command !== 'jest'
49
+ : rootProjectConfig.targets?.['test']?.options?.jestConfig !==
50
50
  rootJestPath) {
51
51
  // Jest target has already been updated
52
52
  return;
@@ -87,16 +87,16 @@ exports.createJestConfig = createJestConfig;
87
87
  function generateGlobalConfig(tree, isJS) {
88
88
  const contents = isJS
89
89
  ? (0, devkit_1.stripIndents) `
90
- const { getJestProjects } = require('@nx/jest');
90
+ const { getJestProjectsAsync } = require('@nx/jest');
91
91
 
92
- module.exports = {
93
- projects: getJestProjects()
94
- };`
92
+ module.exports = async () => ({
93
+ projects: await getJestProjectsAsync()
94
+ });`
95
95
  : (0, devkit_1.stripIndents) `
96
- import { getJestProjects } from '@nx/jest';
96
+ import { getJestProjectsAsync } from '@nx/jest';
97
97
 
98
- export default {
99
- projects: getJestProjects()
100
- };`;
98
+ export default async () => ({
99
+ projects: await getJestProjectsAsync()
100
+ });`;
101
101
  tree.write(`jest.config.${isJS ? 'js' : 'ts'}`, contents);
102
102
  }
@@ -6,7 +6,12 @@ const update_config_1 = require("../../../utils/config/update-config");
6
6
  const devkit_1 = require("@nx/devkit");
7
7
  function isUsingUtilityFunction(host) {
8
8
  const rootConfig = (0, find_root_jest_files_1.findRootJestConfig)(host);
9
- return (rootConfig && host.read(rootConfig).toString().includes('getJestProjects()'));
9
+ if (!rootConfig) {
10
+ return false;
11
+ }
12
+ const rootConfigContent = host.read(rootConfig, 'utf-8');
13
+ return (rootConfigContent.includes('getJestProjects()') ||
14
+ rootConfigContent.includes('getJestProjectsAsync()'));
10
15
  }
11
16
  function updateJestConfig(host, options) {
12
17
  if (isUsingUtilityFunction(host)) {
@@ -75,7 +75,10 @@ function jestInitGenerator(tree, options) {
75
75
  }
76
76
  exports.jestInitGenerator = jestInitGenerator;
77
77
  async function jestInitGeneratorInternal(tree, options) {
78
- options.addPlugin ??= process.env.NX_ADD_PLUGINS !== 'false';
78
+ const nxJson = (0, devkit_1.readNxJson)(tree);
79
+ const addPluginDefault = process.env.NX_ADD_PLUGINS !== 'false' &&
80
+ nxJson.useInferencePlugins !== false;
81
+ options.addPlugin ??= addPluginDefault;
79
82
  const presetExt = (0, is_preset_cjs_1.isPresetCjs)(tree) ? 'cjs' : 'js';
80
83
  if (!tree.exists('jest.preset.js') && !tree.exists('jest.preset.cjs')) {
81
84
  updateProductionFileSet(tree, presetExt);
@@ -45,6 +45,13 @@ exports.createNodes = [
45
45
  return {};
46
46
  }
47
47
  }
48
+ const jestConfigContent = (0, fs_1.readFileSync)((0, path_1.resolve)(context.workspaceRoot, configFilePath), 'utf-8');
49
+ if (jestConfigContent.includes('getJestProjectsAsync()')) {
50
+ // The `getJestProjectsAsync` function uses the project graph, which leads to a
51
+ // circular dependency. We can skip this since it's no intended to be used for
52
+ // an Nx project.
53
+ return {};
54
+ }
48
55
  options = normalizeOptions(options);
49
56
  const hash = (0, calculate_hash_for_create_nodes_1.calculateHashForCreateNodes)(projectRoot, options, context);
50
57
  const targets = targetsCache[hash] ??
@@ -2,7 +2,8 @@
2
2
  * Get a list of paths to all the jest config files
3
3
  * using the Nx Jest executor.
4
4
  *
5
- * This is used to configure Jest multi-project support.
5
+ * This is used to configure Jest multi-project support. To support projects
6
+ * using inferred targets @see getJestProjectsAsync
6
7
  *
7
8
  * To add a project not using the Nx Jest executor:
8
9
  * export default {
@@ -17,3 +18,17 @@ export declare function getJestProjects(): string[];
17
18
  * https://jestjs.io/docs/configuration#testpathignorepatterns-arraystring
18
19
  * */
19
20
  export declare function getNestedJestProjects(): string[];
21
+ /**
22
+ * Get a list of paths to all the jest config files
23
+ * using the Nx Jest executor and `@nx/run:commands`
24
+ * running `jest`.
25
+ *
26
+ * This is used to configure Jest multi-project support.
27
+ *
28
+ * To add a project not using the Nx Jest executor:
29
+ * export default async () => ({
30
+ * projects: [...(await getJestProjectsAsync()), '<rootDir>/path/to/jest.config.ts'];
31
+ * });
32
+ *
33
+ **/
34
+ export declare function getJestProjectsAsync(): Promise<string[]>;
@@ -1,8 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getNestedJestProjects = exports.getJestProjects = void 0;
4
- const path_1 = require("path");
3
+ exports.getJestProjectsAsync = exports.getNestedJestProjects = exports.getJestProjects = void 0;
4
+ const devkit_1 = require("@nx/devkit");
5
5
  const file_utils_1 = require("nx/src/project-graph/file-utils");
6
+ const path_1 = require("path");
7
+ const yargs = require("yargs-parser");
6
8
  function getJestConfigProjectPath(projectJestConfigPath) {
7
9
  return (0, path_1.join)('<rootDir>', projectJestConfigPath);
8
10
  }
@@ -10,7 +12,8 @@ function getJestConfigProjectPath(projectJestConfigPath) {
10
12
  * Get a list of paths to all the jest config files
11
13
  * using the Nx Jest executor.
12
14
  *
13
- * This is used to configure Jest multi-project support.
15
+ * This is used to configure Jest multi-project support. To support projects
16
+ * using inferred targets @see getJestProjectsAsync
14
17
  *
15
18
  * To add a project not using the Nx Jest executor:
16
19
  * export default {
@@ -60,3 +63,95 @@ function getNestedJestProjects() {
60
63
  return ['/node_modules/'];
61
64
  }
62
65
  exports.getNestedJestProjects = getNestedJestProjects;
66
+ /**
67
+ * Get a list of paths to all the jest config files
68
+ * using the Nx Jest executor and `@nx/run:commands`
69
+ * running `jest`.
70
+ *
71
+ * This is used to configure Jest multi-project support.
72
+ *
73
+ * To add a project not using the Nx Jest executor:
74
+ * export default async () => ({
75
+ * projects: [...(await getJestProjectsAsync()), '<rootDir>/path/to/jest.config.ts'];
76
+ * });
77
+ *
78
+ **/
79
+ async function getJestProjectsAsync() {
80
+ const graph = await (0, devkit_1.createProjectGraphAsync)({
81
+ exitOnError: false,
82
+ resetDaemonClient: true,
83
+ });
84
+ const jestConfigurations = new Set();
85
+ for (const node of Object.values(graph.nodes)) {
86
+ const projectConfig = node.data;
87
+ if (!projectConfig.targets) {
88
+ continue;
89
+ }
90
+ for (const targetConfiguration of Object.values(projectConfig.targets)) {
91
+ if (targetConfiguration.executor === '@nx/jest:jest' ||
92
+ targetConfiguration.executor === '@nrwl/jest:jest') {
93
+ collectJestConfigFromJestExecutor(targetConfiguration, jestConfigurations);
94
+ }
95
+ else if (targetConfiguration.executor === 'nx:run-commands') {
96
+ collectJestConfigFromRunCommandsExecutor(targetConfiguration, projectConfig.root, jestConfigurations);
97
+ }
98
+ }
99
+ }
100
+ return Array.from(jestConfigurations);
101
+ }
102
+ exports.getJestProjectsAsync = getJestProjectsAsync;
103
+ function collectJestConfigFromJestExecutor(targetConfiguration, jestConfigurations) {
104
+ if (targetConfiguration.options?.jestConfig) {
105
+ jestConfigurations.add(getJestConfigProjectPath(targetConfiguration.options.jestConfig));
106
+ }
107
+ if (targetConfiguration.configurations) {
108
+ for (const configurationObject of Object.values(targetConfiguration.configurations)) {
109
+ if (configurationObject.jestConfig) {
110
+ jestConfigurations.add(getJestConfigProjectPath(configurationObject.jestConfig));
111
+ }
112
+ }
113
+ }
114
+ }
115
+ function collectJestConfigFromRunCommandsExecutor(targetConfiguration, projectRoot, jestConfigurations) {
116
+ if (targetConfiguration.options?.command) {
117
+ collectJestConfigFromCommand(targetConfiguration.options.command, targetConfiguration.options.cwd ?? projectRoot, jestConfigurations);
118
+ }
119
+ else if (targetConfiguration.options?.commands) {
120
+ for (const command of targetConfiguration.options.commands) {
121
+ const commandScript = typeof command === 'string' ? command : command.command;
122
+ collectJestConfigFromCommand(commandScript, targetConfiguration.options.cwd ?? projectRoot, jestConfigurations);
123
+ }
124
+ }
125
+ if (targetConfiguration.configurations) {
126
+ for (const configurationObject of Object.values(targetConfiguration.configurations)) {
127
+ if (configurationObject.command) {
128
+ collectJestConfigFromCommand(configurationObject.command, configurationObject.cwd ?? projectRoot, jestConfigurations);
129
+ }
130
+ else if (configurationObject.commands) {
131
+ for (const command of configurationObject.commands) {
132
+ const commandScript = typeof command === 'string' ? command : command.command;
133
+ collectJestConfigFromCommand(commandScript, configurationObject.cwd ?? projectRoot, jestConfigurations);
134
+ }
135
+ }
136
+ }
137
+ }
138
+ }
139
+ function collectJestConfigFromCommand(command, cwd, jestConfigurations) {
140
+ const jestCommandRegex = /(?<=^|&)(?:[^&\r\n\s]* )*jest(?: [^&\r\n\s]*)*(?=$|&)/g;
141
+ const matches = command.match(jestCommandRegex);
142
+ if (!matches) {
143
+ return;
144
+ }
145
+ for (const match of matches) {
146
+ const parsed = yargs(match, {
147
+ configuration: { 'strip-dashed': true },
148
+ string: ['config'],
149
+ });
150
+ if (parsed.config) {
151
+ jestConfigurations.add(getJestConfigProjectPath((0, path_1.join)(cwd, parsed.config)));
152
+ }
153
+ else {
154
+ jestConfigurations.add(getJestConfigProjectPath(cwd));
155
+ }
156
+ }
157
+ }