@nx/jest 17.0.2 → 17.0.4
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/LICENSE +1 -1
- package/README.md +9 -4
- package/generators.json +2 -2
- package/index.d.ts +1 -1
- package/index.js +2 -1
- package/migrations.json +14 -0
- package/package.json +6 -4
- package/plugin.d.ts +1 -0
- package/plugin.js +6 -0
- package/src/generators/configuration/configuration.d.ts +1 -0
- package/src/generators/configuration/configuration.js +42 -7
- package/src/generators/configuration/files/jest.config.ts__tmpl__ +1 -1
- package/src/generators/configuration/files-angular/jest.config.ts__tmpl__ +1 -1
- package/src/generators/configuration/lib/create-files.d.ts +1 -1
- package/src/generators/configuration/lib/create-files.js +2 -1
- package/src/generators/configuration/lib/create-jest-config.d.ts +3 -0
- package/src/generators/configuration/lib/create-jest-config.js +102 -0
- package/src/generators/configuration/lib/ensure-dependencies.d.ts +3 -0
- package/src/generators/configuration/lib/ensure-dependencies.js +34 -0
- package/src/generators/configuration/lib/update-jestconfig.js +6 -1
- package/src/generators/configuration/lib/update-vscode-recommended-extensions.d.ts +2 -0
- package/src/generators/configuration/lib/update-vscode-recommended-extensions.js +18 -0
- package/src/generators/configuration/lib/update-workspace.js +1 -8
- package/src/generators/configuration/schema.d.ts +8 -0
- package/src/generators/configuration/schema.json +1 -1
- package/src/generators/init/init.d.ts +4 -3
- package/src/generators/init/init.js +66 -130
- package/src/generators/init/schema.d.ts +5 -8
- package/src/generators/init/schema.json +13 -20
- package/src/migrations/update-17-1-0/move-options-to-target-defaults.d.ts +2 -0
- package/src/migrations/update-17-1-0/move-options-to-target-defaults.js +117 -0
- package/src/plugins/plugin.d.ts +6 -0
- package/src/plugins/plugin.js +130 -0
- package/src/utils/config/find-root-jest-files.js +3 -0
- package/src/utils/config/get-jest-projects.d.ts +16 -1
- package/src/utils/config/get-jest-projects.js +98 -3
- package/src/utils/config/is-preset-cjs.d.ts +2 -0
- package/src/utils/config/is-preset-cjs.js +15 -0
- package/src/utils/versions.d.ts +1 -1
- package/src/utils/versions.js +1 -1
|
@@ -1,79 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.jestInitGenerator = void 0;
|
|
3
|
+
exports.jestInitGeneratorInternal = exports.jestInitGenerator = void 0;
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
|
-
const
|
|
6
|
-
const
|
|
5
|
+
const update_package_scripts_1 = require("@nx/devkit/src/utils/update-package-scripts");
|
|
6
|
+
const plugin_1 = require("../../plugins/plugin");
|
|
7
7
|
const versions_1 = require("../../utils/versions");
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
};`
|
|
22
|
-
: (0, devkit_1.stripIndents) `
|
|
23
|
-
import { getJestProjects } from '@nx/jest';
|
|
24
|
-
|
|
25
|
-
export default {
|
|
26
|
-
projects: getJestProjects()
|
|
27
|
-
};`;
|
|
28
|
-
tree.write(`jest.config.${isJS ? 'js' : 'ts'}`, contents);
|
|
29
|
-
}
|
|
30
|
-
function createJestConfig(tree, options) {
|
|
31
|
-
if (!tree.exists('jest.preset.js')) {
|
|
32
|
-
// preset is always js file.
|
|
33
|
-
tree.write(`jest.preset.js`, `
|
|
34
|
-
const nxPreset = require('@nx/jest/preset').default;
|
|
35
|
-
|
|
36
|
-
module.exports = { ...nxPreset }`);
|
|
37
|
-
addTestInputs(tree);
|
|
38
|
-
}
|
|
39
|
-
if (options.rootProject) {
|
|
40
|
-
// we don't want any config to be made because the `configurationGenerator` will do it.
|
|
41
|
-
// will copy the template config file
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
const rootJestPath = (0, find_root_jest_files_1.findRootJestConfig)(tree);
|
|
45
|
-
if (!rootJestPath) {
|
|
46
|
-
// if there's not root jest config, we will create one and return
|
|
47
|
-
// this can happen when:
|
|
48
|
-
// - root jest config was renamed => in which case there is migration needed
|
|
49
|
-
// - root project didn't have jest setup => again, no migration is needed
|
|
50
|
-
generateGlobalConfig(tree, options.js);
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
if (tree.exists(rootJestPath)) {
|
|
54
|
-
// moving from root project config to monorepo-style config
|
|
55
|
-
const projects = (0, devkit_1.getProjects)(tree);
|
|
56
|
-
const projectNames = Array.from(projects.keys());
|
|
57
|
-
const rootProject = projectNames.find((projectName) => projects.get(projectName)?.root === '.');
|
|
58
|
-
// root project might have been removed,
|
|
59
|
-
// if it's missing there's nothing to migrate
|
|
60
|
-
if (rootProject) {
|
|
61
|
-
const rootProjectConfig = projects.get(rootProject);
|
|
62
|
-
const jestTarget = Object.values(rootProjectConfig.targets || {}).find((t) => t?.executor === '@nx/jest:jest' || t?.executor === '@nrwl/jest:jest');
|
|
63
|
-
const isProjectConfig = jestTarget?.options?.jestConfig === rootJestPath;
|
|
64
|
-
// if root project doesn't have jest target, there's nothing to migrate
|
|
65
|
-
if (isProjectConfig) {
|
|
66
|
-
const jestProjectConfig = `jest.config.${rootProjectConfig.projectType === 'application' ? 'app' : 'lib'}.${options.js ? 'js' : 'ts'}`;
|
|
67
|
-
tree.rename(rootJestPath, jestProjectConfig);
|
|
68
|
-
jestTarget.options.jestConfig = jestProjectConfig;
|
|
69
|
-
(0, devkit_1.updateProjectConfiguration)(tree, rootProject, rootProjectConfig);
|
|
70
|
-
}
|
|
71
|
-
// generate new global config as it was move to project config or is missing
|
|
72
|
-
generateGlobalConfig(tree, options.js);
|
|
73
|
-
}
|
|
8
|
+
const is_preset_cjs_1 = require("../../utils/config/is-preset-cjs");
|
|
9
|
+
function addPlugin(tree) {
|
|
10
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
11
|
+
nxJson.plugins ??= [];
|
|
12
|
+
if (!nxJson.plugins.some((p) => typeof p === 'string'
|
|
13
|
+
? p === '@nx/jest/plugin'
|
|
14
|
+
: p.plugin === '@nx/jest/plugin')) {
|
|
15
|
+
nxJson.plugins.push({
|
|
16
|
+
plugin: '@nx/jest/plugin',
|
|
17
|
+
options: {
|
|
18
|
+
targetName: 'test',
|
|
19
|
+
},
|
|
20
|
+
});
|
|
74
21
|
}
|
|
22
|
+
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
75
23
|
}
|
|
76
|
-
function
|
|
24
|
+
function updateProductionFileSet(tree, presetExt) {
|
|
77
25
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
78
26
|
const productionFileSet = nxJson.namedInputs?.production;
|
|
79
27
|
if (productionFileSet) {
|
|
@@ -91,80 +39,68 @@ function addTestInputs(tree) {
|
|
|
91
39
|
// Dedupe and set
|
|
92
40
|
nxJson.namedInputs.production = Array.from(new Set(productionFileSet));
|
|
93
41
|
}
|
|
94
|
-
|
|
42
|
+
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
43
|
+
}
|
|
44
|
+
function addJestTargetDefaults(tree, presetEnv) {
|
|
45
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
95
46
|
nxJson.targetDefaults ??= {};
|
|
96
|
-
nxJson.targetDefaults
|
|
97
|
-
nxJson.
|
|
47
|
+
nxJson.targetDefaults['@nx/jest:jest'] ??= {};
|
|
48
|
+
const productionFileSet = nxJson.namedInputs?.production;
|
|
49
|
+
nxJson.targetDefaults['@nx/jest:jest'].cache ??= true;
|
|
50
|
+
// Test targets depend on all their project's sources + production sources of dependencies
|
|
51
|
+
nxJson.targetDefaults['@nx/jest:jest'].inputs ??= [
|
|
98
52
|
'default',
|
|
99
53
|
productionFileSet ? '^production' : '^default',
|
|
54
|
+
`{workspaceRoot}/jest.preset.${presetEnv}`,
|
|
100
55
|
];
|
|
101
|
-
nxJson.targetDefaults
|
|
56
|
+
nxJson.targetDefaults['@nx/jest:jest'].options ??= {
|
|
57
|
+
passWithNoTests: true,
|
|
58
|
+
};
|
|
59
|
+
nxJson.targetDefaults['@nx/jest:jest'].configurations ??= {
|
|
60
|
+
ci: {
|
|
61
|
+
ci: true,
|
|
62
|
+
codeCoverage: true,
|
|
63
|
+
},
|
|
64
|
+
};
|
|
102
65
|
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
103
66
|
}
|
|
104
67
|
function updateDependencies(tree, options) {
|
|
105
|
-
|
|
106
|
-
tslib: versions_1.tslibVersion,
|
|
107
|
-
};
|
|
108
|
-
const devDeps = {
|
|
68
|
+
return (0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
|
|
109
69
|
'@nx/jest': versions_1.nxVersion,
|
|
110
70
|
jest: versions_1.jestVersion,
|
|
111
|
-
|
|
112
|
-
// jest will throw an error if it's not installed
|
|
113
|
-
// even if not using it in overriding transformers
|
|
114
|
-
'ts-jest': versions_1.tsJestVersion,
|
|
115
|
-
};
|
|
116
|
-
if (options.testEnvironment !== 'none') {
|
|
117
|
-
devDeps[`jest-environment-${options.testEnvironment}`] = versions_1.jestVersion;
|
|
118
|
-
}
|
|
119
|
-
if (!options.js) {
|
|
120
|
-
devDeps['ts-node'] = versions_1.tsNodeVersion;
|
|
121
|
-
devDeps['@types/jest'] = versions_1.jestTypesVersion;
|
|
122
|
-
devDeps['@types/node'] = versions_1.typesNodeVersion;
|
|
123
|
-
}
|
|
124
|
-
if (options.compiler === 'babel' || options.babelJest) {
|
|
125
|
-
devDeps['babel-jest'] = versions_1.babelJestVersion;
|
|
126
|
-
// in some cases @nx/js will not already be present i.e. node only projects
|
|
127
|
-
devDeps['@nx/js'] = versions_1.nxVersion;
|
|
128
|
-
}
|
|
129
|
-
else if (options.compiler === 'swc') {
|
|
130
|
-
devDeps['@swc/jest'] = versions_1.swcJestVersion;
|
|
131
|
-
}
|
|
132
|
-
return (0, devkit_1.addDependenciesToPackageJson)(tree, dependencies, devDeps);
|
|
71
|
+
}, undefined, options.keepExistingVersions);
|
|
133
72
|
}
|
|
134
|
-
function
|
|
135
|
-
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
(0, devkit_1.updateJson)(host, '.vscode/extensions.json', (json) => {
|
|
139
|
-
json.recommendations = json.recommendations || [];
|
|
140
|
-
const extension = 'firsttris.vscode-jest-runner';
|
|
141
|
-
if (!json.recommendations.includes(extension)) {
|
|
142
|
-
json.recommendations.push(extension);
|
|
143
|
-
}
|
|
144
|
-
return json;
|
|
145
|
-
});
|
|
73
|
+
function jestInitGenerator(tree, options) {
|
|
74
|
+
return jestInitGeneratorInternal(tree, { addPlugin: false, ...options });
|
|
146
75
|
}
|
|
147
|
-
|
|
148
|
-
|
|
76
|
+
exports.jestInitGenerator = jestInitGenerator;
|
|
77
|
+
async function jestInitGeneratorInternal(tree, options) {
|
|
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;
|
|
82
|
+
const presetExt = (0, is_preset_cjs_1.isPresetCjs)(tree) ? 'cjs' : 'js';
|
|
83
|
+
if (!tree.exists('jest.preset.js') && !tree.exists('jest.preset.cjs')) {
|
|
84
|
+
updateProductionFileSet(tree, presetExt);
|
|
85
|
+
if (options.addPlugin) {
|
|
86
|
+
addPlugin(tree);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
addJestTargetDefaults(tree, presetExt);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
149
92
|
const tasks = [];
|
|
150
|
-
tasks.push(await (0, js_1.initGenerator)(tree, {
|
|
151
|
-
...schema,
|
|
152
|
-
skipFormat: true,
|
|
153
|
-
}));
|
|
154
|
-
createJestConfig(tree, options);
|
|
155
93
|
if (!options.skipPackageJson) {
|
|
156
|
-
(0, devkit_1.removeDependenciesFromPackageJson)(tree, ['@nx/jest'], []);
|
|
157
|
-
|
|
158
|
-
|
|
94
|
+
tasks.push((0, devkit_1.removeDependenciesFromPackageJson)(tree, ['@nx/jest'], []));
|
|
95
|
+
tasks.push(updateDependencies(tree, options));
|
|
96
|
+
}
|
|
97
|
+
if (options.updatePackageScripts) {
|
|
98
|
+
await (0, update_package_scripts_1.updatePackageScripts)(tree, plugin_1.createNodes);
|
|
99
|
+
}
|
|
100
|
+
if (!options.skipFormat) {
|
|
101
|
+
await (0, devkit_1.formatFiles)(tree);
|
|
159
102
|
}
|
|
160
|
-
updateExtensions(tree);
|
|
161
103
|
return (0, devkit_1.runTasksInSerial)(...tasks);
|
|
162
104
|
}
|
|
163
|
-
exports.
|
|
164
|
-
function normalizeOptions(options) {
|
|
165
|
-
return {
|
|
166
|
-
...schemaDefaults,
|
|
167
|
-
...options,
|
|
168
|
-
};
|
|
169
|
-
}
|
|
105
|
+
exports.jestInitGeneratorInternal = jestInitGeneratorInternal;
|
|
170
106
|
exports.default = jestInitGenerator;
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
export interface JestInitSchema {
|
|
2
|
-
|
|
3
|
-
js?: boolean;
|
|
2
|
+
skipFormat?: boolean;
|
|
4
3
|
skipPackageJson?: boolean;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
babelJest?: boolean;
|
|
10
|
-
rootProject?: boolean;
|
|
4
|
+
keepExistingVersions?: boolean;
|
|
5
|
+
updatePackageScripts?: boolean;
|
|
6
|
+
|
|
7
|
+
addPlugin?: boolean;
|
|
11
8
|
}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$schema": "
|
|
2
|
+
"$schema": "https://json-schema.org/schema",
|
|
3
3
|
"$id": "NxJestInit",
|
|
4
4
|
"cli": "nx",
|
|
5
5
|
"title": "Jest init",
|
|
6
6
|
"description": "Add Jest Configuration to a workspace.",
|
|
7
7
|
"type": "object",
|
|
8
8
|
"properties": {
|
|
9
|
-
"
|
|
9
|
+
"skipFormat": {
|
|
10
|
+
"description": "Skip formatting files.",
|
|
10
11
|
"type": "boolean",
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"default": false
|
|
12
|
+
"default": false,
|
|
13
|
+
"x-priority": "internal"
|
|
14
14
|
},
|
|
15
15
|
"skipPackageJson": {
|
|
16
16
|
"type": "boolean",
|
|
@@ -18,24 +18,17 @@
|
|
|
18
18
|
"description": "Do not add dependencies to `package.json`.",
|
|
19
19
|
"x-priority": "internal"
|
|
20
20
|
},
|
|
21
|
-
"
|
|
22
|
-
"type": "string",
|
|
23
|
-
"enum": ["jsdom", "node", "none"],
|
|
24
|
-
"description": "The test environment for jest. This controls which jest-environment-* package is installed",
|
|
25
|
-
"default": "jsdom",
|
|
26
|
-
"x-priority": "important"
|
|
27
|
-
},
|
|
28
|
-
"js": {
|
|
21
|
+
"keepExistingVersions": {
|
|
29
22
|
"type": "boolean",
|
|
30
|
-
"
|
|
31
|
-
"description": "
|
|
23
|
+
"x-priority": "internal",
|
|
24
|
+
"description": "Keep existing dependencies versions",
|
|
25
|
+
"default": false
|
|
32
26
|
},
|
|
33
|
-
"
|
|
34
|
-
"description": "initialize Jest for an application at the root of the workspace",
|
|
27
|
+
"updatePackageScripts": {
|
|
35
28
|
"type": "boolean",
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
29
|
+
"x-priority": "internal",
|
|
30
|
+
"description": "Update `package.json` scripts with inferred targets",
|
|
31
|
+
"default": false
|
|
39
32
|
}
|
|
40
33
|
},
|
|
41
34
|
"required": []
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const devkit_1 = require("@nx/devkit");
|
|
4
|
+
const executor_options_utils_1 = require("@nx/devkit/src/generators/executor-options-utils");
|
|
5
|
+
const project_configuration_utils_1 = require("nx/src/project-graph/utils/project-configuration-utils");
|
|
6
|
+
async function update(tree) {
|
|
7
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
8
|
+
// Don't override anything if there are already target defaults for jest
|
|
9
|
+
if (nxJson.targetDefaults?.['@nx/jest:jest']) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
nxJson.targetDefaults ??= {};
|
|
13
|
+
/**
|
|
14
|
+
* A set of targets which does not use any other executors
|
|
15
|
+
*/
|
|
16
|
+
const jestTargets = new Set();
|
|
17
|
+
const graph = await (0, devkit_1.createProjectGraphAsync)();
|
|
18
|
+
(0, executor_options_utils_1.forEachExecutorOptionsInGraph)(graph, '@nx/jest:jest', (value, proj, targetName) => {
|
|
19
|
+
jestTargets.add(targetName);
|
|
20
|
+
});
|
|
21
|
+
// Workspace does not use jest?
|
|
22
|
+
if (jestTargets.size === 0) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
// Use the project graph so targets which are inferred are considered
|
|
26
|
+
const projects = graph.nodes;
|
|
27
|
+
const projectMap = (0, devkit_1.getProjects)(tree);
|
|
28
|
+
const jestDefaults = (nxJson.targetDefaults['@nx/jest:jest'] = {});
|
|
29
|
+
// All jest targets have the same name
|
|
30
|
+
if (jestTargets.size === 1) {
|
|
31
|
+
const targetName = Array.from(jestTargets)[0];
|
|
32
|
+
if (nxJson.targetDefaults[targetName]) {
|
|
33
|
+
Object.assign(jestDefaults, nxJson.targetDefaults[targetName]);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
jestDefaults.cache ??= true;
|
|
37
|
+
const inputs = ['default'];
|
|
38
|
+
inputs.push(nxJson.namedInputs?.production ? '^production' : '^default');
|
|
39
|
+
if (tree.exists('jest.preset.js')) {
|
|
40
|
+
inputs.push('{workspaceRoot}/jest.preset.js');
|
|
41
|
+
}
|
|
42
|
+
jestDefaults.inputs ??= inputs;
|
|
43
|
+
// Remember if there were already defaults so we don't assume the executor default
|
|
44
|
+
const passWithNoTestsPreviouslyInDefaults = jestDefaults.options?.passWithNoTests !== undefined;
|
|
45
|
+
const ciCiPreviouslyInDefaults = jestDefaults.configurations?.ci?.ci !== undefined;
|
|
46
|
+
const ciCodeCoveragePreviouslyInDefaults = jestDefaults.configurations?.ci?.codeCoverage !== undefined;
|
|
47
|
+
jestDefaults.options ??= {};
|
|
48
|
+
jestDefaults.options.passWithNoTests ??= true;
|
|
49
|
+
jestDefaults.configurations ??= {};
|
|
50
|
+
jestDefaults.configurations.ci ??= {};
|
|
51
|
+
jestDefaults.configurations.ci.ci ??= true;
|
|
52
|
+
jestDefaults.configurations.ci.codeCoverage ??= true;
|
|
53
|
+
// Cleanup old target defaults
|
|
54
|
+
for (const [targetDefaultKey, targetDefault] of Object.entries(nxJson.targetDefaults)) {
|
|
55
|
+
if (!isTargetDefaultUsed(targetDefault, nxJson.targetDefaults, projects, projectMap)) {
|
|
56
|
+
delete nxJson.targetDefaults[targetDefaultKey];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
60
|
+
(0, executor_options_utils_1.forEachExecutorOptions)(tree, '@nx/jest:jest', (value, proj, targetName, configuration) => {
|
|
61
|
+
const projConfig = projectMap.get(proj);
|
|
62
|
+
if (!configuration) {
|
|
63
|
+
// Options
|
|
64
|
+
if (value.passWithNoTests === jestDefaults.options.passWithNoTests) {
|
|
65
|
+
delete projConfig.targets[targetName].options.passWithNoTests;
|
|
66
|
+
}
|
|
67
|
+
else if (!passWithNoTestsPreviouslyInDefaults) {
|
|
68
|
+
projConfig.targets[targetName].options.passWithNoTests ??= false;
|
|
69
|
+
}
|
|
70
|
+
if (Object.keys(projConfig.targets[targetName].options).length === 0) {
|
|
71
|
+
delete projConfig.targets[targetName].options;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else if (configuration === 'ci') {
|
|
75
|
+
// CI Config
|
|
76
|
+
if (value.ci === jestDefaults.configurations.ci.ci) {
|
|
77
|
+
delete projConfig.targets[targetName].configurations.ci.ci;
|
|
78
|
+
}
|
|
79
|
+
else if (ciCiPreviouslyInDefaults) {
|
|
80
|
+
projConfig.targets[targetName].configurations.ci.ci ??= false;
|
|
81
|
+
}
|
|
82
|
+
if (value.codeCoverage === jestDefaults.configurations.ci.codeCoverage) {
|
|
83
|
+
delete projConfig.targets[targetName].configurations.ci.codeCoverage;
|
|
84
|
+
}
|
|
85
|
+
else if (ciCodeCoveragePreviouslyInDefaults) {
|
|
86
|
+
projConfig.targets[targetName].configurations.ci.codeCoverage ??=
|
|
87
|
+
false;
|
|
88
|
+
}
|
|
89
|
+
if (Object.keys(projConfig.targets[targetName].configurations.ci)
|
|
90
|
+
.length === 0) {
|
|
91
|
+
delete projConfig.targets[targetName].configurations.ci;
|
|
92
|
+
}
|
|
93
|
+
if (Object.keys(projConfig.targets[targetName].configurations).length ===
|
|
94
|
+
0) {
|
|
95
|
+
delete projConfig.targets[targetName].configurations;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
(0, devkit_1.updateProjectConfiguration)(tree, proj, projConfig);
|
|
99
|
+
});
|
|
100
|
+
await (0, devkit_1.formatFiles)(tree);
|
|
101
|
+
}
|
|
102
|
+
exports.default = update;
|
|
103
|
+
/**
|
|
104
|
+
* Checks every target on every project to see if one of them uses the target default
|
|
105
|
+
*/
|
|
106
|
+
function isTargetDefaultUsed(targetDefault, targetDefaults, projects, projectMap) {
|
|
107
|
+
for (const p of Object.values(projects)) {
|
|
108
|
+
for (const targetName in p.data?.targets ?? {}) {
|
|
109
|
+
if ((0, project_configuration_utils_1.readTargetDefaultsForTarget)(targetName, targetDefaults,
|
|
110
|
+
// It might seem like we should use the graph here too but we don't want to pass an executor which was processed in the graph
|
|
111
|
+
projectMap.get(p.name)?.targets?.[targetName]?.executor) === targetDefault) {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createNodes = exports.createDependencies = void 0;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const project_configuration_utils_1 = require("nx/src/project-graph/utils/project-configuration-utils");
|
|
7
|
+
const get_named_inputs_1 = require("@nx/devkit/src/utils/get-named-inputs");
|
|
8
|
+
const fs_1 = require("fs");
|
|
9
|
+
const jest_config_1 = require("jest-config");
|
|
10
|
+
const cache_directory_1 = require("nx/src/utils/cache-directory");
|
|
11
|
+
const calculate_hash_for_create_nodes_1 = require("@nx/devkit/src/utils/calculate-hash-for-create-nodes");
|
|
12
|
+
const package_json_workspaces_1 = require("nx/src/plugins/package-json-workspaces");
|
|
13
|
+
const globs_1 = require("nx/src/utils/globs");
|
|
14
|
+
const minimatch_1 = require("minimatch");
|
|
15
|
+
const cachePath = (0, path_1.join)(cache_directory_1.projectGraphCacheDirectory, 'jest.hash');
|
|
16
|
+
const targetsCache = (0, fs_1.existsSync)(cachePath) ? readTargetsCache() : {};
|
|
17
|
+
const calculatedTargets = {};
|
|
18
|
+
function readTargetsCache() {
|
|
19
|
+
return (0, devkit_1.readJsonFile)(cachePath);
|
|
20
|
+
}
|
|
21
|
+
function writeTargetsToCache(targets) {
|
|
22
|
+
(0, devkit_1.writeJsonFile)(cachePath, targets);
|
|
23
|
+
}
|
|
24
|
+
const createDependencies = () => {
|
|
25
|
+
writeTargetsToCache(calculatedTargets);
|
|
26
|
+
return [];
|
|
27
|
+
};
|
|
28
|
+
exports.createDependencies = createDependencies;
|
|
29
|
+
exports.createNodes = [
|
|
30
|
+
'**/jest.config.{cjs,mjs,js,cts,mts,ts}',
|
|
31
|
+
async (configFilePath, options, context) => {
|
|
32
|
+
const projectRoot = (0, path_1.dirname)(configFilePath);
|
|
33
|
+
const packageManagerWorkspacesGlob = (0, globs_1.combineGlobPatterns)((0, package_json_workspaces_1.getGlobPatternsFromPackageManagerWorkspaces)(context.workspaceRoot));
|
|
34
|
+
// Do not create a project if package.json and project.json isn't there.
|
|
35
|
+
const siblingFiles = (0, fs_1.readdirSync)((0, path_1.join)(context.workspaceRoot, projectRoot));
|
|
36
|
+
if (!siblingFiles.includes('package.json') &&
|
|
37
|
+
!siblingFiles.includes('project.json')) {
|
|
38
|
+
return {};
|
|
39
|
+
}
|
|
40
|
+
else if (!siblingFiles.includes('project.json') &&
|
|
41
|
+
siblingFiles.includes('package.json')) {
|
|
42
|
+
const path = (0, devkit_1.joinPathFragments)(projectRoot, 'package.json');
|
|
43
|
+
const isPackageJsonProject = (0, minimatch_1.minimatch)(path, packageManagerWorkspacesGlob);
|
|
44
|
+
if (!isPackageJsonProject) {
|
|
45
|
+
return {};
|
|
46
|
+
}
|
|
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
|
+
}
|
|
55
|
+
options = normalizeOptions(options);
|
|
56
|
+
const hash = (0, calculate_hash_for_create_nodes_1.calculateHashForCreateNodes)(projectRoot, options, context);
|
|
57
|
+
const targets = targetsCache[hash] ??
|
|
58
|
+
(await buildJestTargets(configFilePath, projectRoot, options, context));
|
|
59
|
+
calculatedTargets[hash] = targets;
|
|
60
|
+
return {
|
|
61
|
+
projects: {
|
|
62
|
+
[projectRoot]: {
|
|
63
|
+
root: projectRoot,
|
|
64
|
+
targets: targets,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
},
|
|
69
|
+
];
|
|
70
|
+
async function buildJestTargets(configFilePath, projectRoot, options, context) {
|
|
71
|
+
const config = await (0, jest_config_1.readConfig)({
|
|
72
|
+
_: [],
|
|
73
|
+
$0: undefined,
|
|
74
|
+
}, (0, path_1.resolve)(context.workspaceRoot, configFilePath));
|
|
75
|
+
const targetDefaults = (0, project_configuration_utils_1.readTargetDefaultsForTarget)(options.targetName, context.nxJsonConfiguration.targetDefaults, 'nx:run-commands');
|
|
76
|
+
const namedInputs = (0, get_named_inputs_1.getNamedInputs)(projectRoot, context);
|
|
77
|
+
const targets = {};
|
|
78
|
+
const target = (targets[options.targetName] = {
|
|
79
|
+
command: 'jest',
|
|
80
|
+
options: {
|
|
81
|
+
cwd: projectRoot,
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
if (!targetDefaults?.cache) {
|
|
85
|
+
target.cache = true;
|
|
86
|
+
}
|
|
87
|
+
if (!targetDefaults?.inputs) {
|
|
88
|
+
target.inputs = getInputs(namedInputs);
|
|
89
|
+
}
|
|
90
|
+
if (!targetDefaults?.outputs) {
|
|
91
|
+
target.outputs = getOutputs(projectRoot, config, context);
|
|
92
|
+
}
|
|
93
|
+
return targets;
|
|
94
|
+
}
|
|
95
|
+
function getInputs(namedInputs) {
|
|
96
|
+
return [
|
|
97
|
+
...('production' in namedInputs
|
|
98
|
+
? ['default', '^production']
|
|
99
|
+
: ['default', '^default']),
|
|
100
|
+
{
|
|
101
|
+
externalDependencies: ['jest'],
|
|
102
|
+
},
|
|
103
|
+
];
|
|
104
|
+
}
|
|
105
|
+
function getOutputs(projectRoot, { globalConfig }, context) {
|
|
106
|
+
function getOutput(path) {
|
|
107
|
+
const relativePath = (0, path_1.relative)((0, path_1.join)(context.workspaceRoot, projectRoot), path);
|
|
108
|
+
if (relativePath.startsWith('..')) {
|
|
109
|
+
return (0, path_1.join)('{workspaceRoot}', (0, path_1.join)(projectRoot, relativePath));
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
return (0, path_1.join)('{projectRoot}', relativePath);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const outputs = [];
|
|
116
|
+
for (const outputOption of [
|
|
117
|
+
globalConfig.coverageDirectory,
|
|
118
|
+
globalConfig.outputFile,
|
|
119
|
+
]) {
|
|
120
|
+
if (outputOption) {
|
|
121
|
+
outputs.push(getOutput(outputOption));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return outputs;
|
|
125
|
+
}
|
|
126
|
+
function normalizeOptions(options) {
|
|
127
|
+
options ??= {};
|
|
128
|
+
options.targetName ??= 'test';
|
|
129
|
+
return options;
|
|
130
|
+
}
|
|
@@ -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[]>;
|