@nx/jest 17.3.0-beta.1 → 17.3.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/package.json +5 -4
- package/plugin.d.ts +1 -0
- package/plugin.js +6 -0
- package/src/generators/configuration/configuration.js +7 -1
- package/src/generators/init/init.js +81 -23
- package/src/plugins/plugin.d.ts +6 -0
- package/src/plugins/plugin.js +123 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/jest",
|
|
3
|
-
"version": "17.3.0-beta.
|
|
3
|
+
"version": "17.3.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": {
|
|
@@ -42,11 +42,12 @@
|
|
|
42
42
|
"jest-config": "^29.4.1",
|
|
43
43
|
"jest-resolve": "^29.4.1",
|
|
44
44
|
"jest-util": "^29.4.1",
|
|
45
|
+
"minimatch": "3.0.5",
|
|
45
46
|
"resolve.exports": "1.1.0",
|
|
46
47
|
"tslib": "^2.3.0",
|
|
47
|
-
"@nx/devkit": "17.3.0-beta.
|
|
48
|
-
"@nx/js": "17.3.0-beta.
|
|
49
|
-
"@nrwl/jest": "17.3.0-beta.
|
|
48
|
+
"@nx/devkit": "17.3.0-beta.3",
|
|
49
|
+
"@nx/js": "17.3.0-beta.3",
|
|
50
|
+
"@nrwl/jest": "17.3.0-beta.3"
|
|
50
51
|
},
|
|
51
52
|
"publishConfig": {
|
|
52
53
|
"access": "public"
|
package/plugin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createNodes, createDependencies, JestPluginOptions, } from './src/plugins/plugin';
|
package/plugin.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createDependencies = exports.createNodes = void 0;
|
|
4
|
+
var plugin_1 = require("./src/plugins/plugin");
|
|
5
|
+
Object.defineProperty(exports, "createNodes", { enumerable: true, get: function () { return plugin_1.createNodes; } });
|
|
6
|
+
Object.defineProperty(exports, "createDependencies", { enumerable: true, get: function () { return plugin_1.createDependencies; } });
|
|
@@ -45,7 +45,13 @@ async function configurationGenerator(tree, schema) {
|
|
|
45
45
|
(0, check_for_test_target_1.checkForTestTarget)(tree, options);
|
|
46
46
|
(0, create_files_1.createFiles)(tree, options);
|
|
47
47
|
(0, update_tsconfig_1.updateTsConfig)(tree, options);
|
|
48
|
-
(0,
|
|
48
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
49
|
+
const hasPlugin = nxJson.plugins?.some((p) => typeof p === 'string'
|
|
50
|
+
? p === '@nx/jest/plugin'
|
|
51
|
+
: p.plugin === '@nx/jest/plugin');
|
|
52
|
+
if (!hasPlugin) {
|
|
53
|
+
(0, update_workspace_1.updateWorkspace)(tree, options);
|
|
54
|
+
}
|
|
49
55
|
if (!schema.skipFormat) {
|
|
50
56
|
await (0, devkit_1.formatFiles)(tree);
|
|
51
57
|
}
|
|
@@ -5,6 +5,7 @@ const devkit_1 = require("@nx/devkit");
|
|
|
5
5
|
const js_1 = require("@nx/js");
|
|
6
6
|
const find_root_jest_files_1 = require("../../utils/config/find-root-jest-files");
|
|
7
7
|
const versions_1 = require("../../utils/versions");
|
|
8
|
+
const project_configuration_utils_1 = require("nx/src/project-graph/utils/project-configuration-utils");
|
|
8
9
|
const schemaDefaults = {
|
|
9
10
|
compiler: 'tsc',
|
|
10
11
|
js: false,
|
|
@@ -27,15 +28,36 @@ function generateGlobalConfig(tree, isJS) {
|
|
|
27
28
|
};`;
|
|
28
29
|
tree.write(`jest.config.${isJS ? 'js' : 'ts'}`, contents);
|
|
29
30
|
}
|
|
30
|
-
function
|
|
31
|
+
function addPlugin(tree) {
|
|
32
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
33
|
+
nxJson.plugins ??= [];
|
|
34
|
+
if (!nxJson.plugins.some((p) => typeof p === 'string'
|
|
35
|
+
? p === '@nx/jest/plugin'
|
|
36
|
+
: p.plugin === '@nx/jest/plugin')) {
|
|
37
|
+
nxJson.plugins.push({
|
|
38
|
+
plugin: '@nx/jest/plugin',
|
|
39
|
+
options: {
|
|
40
|
+
targetName: 'test',
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
45
|
+
}
|
|
46
|
+
async function createJestConfig(tree, options) {
|
|
31
47
|
if (!tree.exists('jest.preset.js')) {
|
|
32
48
|
// preset is always js file.
|
|
33
49
|
tree.write(`jest.preset.js`, `
|
|
34
50
|
const nxPreset = require('@nx/jest/preset').default;
|
|
35
51
|
|
|
36
52
|
module.exports = { ...nxPreset }`);
|
|
53
|
+
const shouldAddPlugin = process.env.NX_PCV3 === 'true';
|
|
54
|
+
if (shouldAddPlugin) {
|
|
55
|
+
addPlugin(tree);
|
|
56
|
+
}
|
|
37
57
|
updateProductionFileSet(tree);
|
|
38
|
-
|
|
58
|
+
if (!shouldAddPlugin) {
|
|
59
|
+
addJestTargetDefaults(tree, shouldAddPlugin);
|
|
60
|
+
}
|
|
39
61
|
}
|
|
40
62
|
if (options.rootProject) {
|
|
41
63
|
// we don't want any config to be made because the `configurationGenerator` will do it.
|
|
@@ -53,22 +75,56 @@ function createJestConfig(tree, options) {
|
|
|
53
75
|
}
|
|
54
76
|
if (tree.exists(rootJestPath)) {
|
|
55
77
|
// moving from root project config to monorepo-style config
|
|
56
|
-
const projects = (0, devkit_1.
|
|
57
|
-
const
|
|
58
|
-
const rootProject =
|
|
78
|
+
const { nodes: projects } = await (0, devkit_1.createProjectGraphAsync)();
|
|
79
|
+
const projectConfigurations = Object.values(projects);
|
|
80
|
+
const rootProject = projectConfigurations.find((projectNode) => projectNode.data?.root === '.');
|
|
59
81
|
// root project might have been removed,
|
|
60
82
|
// if it's missing there's nothing to migrate
|
|
61
83
|
if (rootProject) {
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
84
|
+
const jestTarget = Object.entries(rootProject.data?.targets ?? {}).find(([_, t]) => ((t?.executor === '@nx/jest:jest' ||
|
|
85
|
+
t?.executor === '@nrwl/jest:jest') &&
|
|
86
|
+
t?.options?.jestConfig === rootJestPath) ||
|
|
87
|
+
(t?.executor === 'nx:run-commands' && t?.options?.command === 'jest'));
|
|
88
|
+
if (!jestTarget) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const [jestTargetName, jestTargetConfigInGraph] = jestTarget;
|
|
65
92
|
// if root project doesn't have jest target, there's nothing to migrate
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
93
|
+
const rootProjectConfig = (0, devkit_1.readProjectConfiguration)(tree, rootProject.name);
|
|
94
|
+
if (rootProjectConfig.targets['test']?.executor === 'nx:run-commands'
|
|
95
|
+
? rootProjectConfig.targets['test']?.command !== 'jest'
|
|
96
|
+
: rootProjectConfig.targets['test']?.options?.jestConfig !==
|
|
97
|
+
rootJestPath) {
|
|
98
|
+
// Jest target has already been updated
|
|
99
|
+
return;
|
|
71
100
|
}
|
|
101
|
+
const jestProjectConfig = `jest.config.${rootProjectConfig.projectType === 'application' ? 'app' : 'lib'}.${options.js ? 'js' : 'ts'}`;
|
|
102
|
+
tree.rename(rootJestPath, jestProjectConfig);
|
|
103
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
104
|
+
const targetDefaults = (0, project_configuration_utils_1.readTargetDefaultsForTarget)(jestTargetName, nxJson.targetDefaults, jestTargetConfigInGraph.executor);
|
|
105
|
+
const target = (rootProjectConfig.targets[jestTargetName] ??=
|
|
106
|
+
jestTargetConfigInGraph.executor === 'nx:run-commands'
|
|
107
|
+
? { command: `jest --config ${jestProjectConfig}` }
|
|
108
|
+
: {
|
|
109
|
+
executor: jestTargetConfigInGraph.executor,
|
|
110
|
+
options: {},
|
|
111
|
+
});
|
|
112
|
+
if (target.executor === '@nx/jest:jest') {
|
|
113
|
+
target.options.jestConfig = jestProjectConfig;
|
|
114
|
+
}
|
|
115
|
+
if (targetDefaults?.cache === undefined) {
|
|
116
|
+
target.cache = jestTargetConfigInGraph.cache;
|
|
117
|
+
}
|
|
118
|
+
if (targetDefaults?.inputs === undefined) {
|
|
119
|
+
target.inputs = jestTargetConfigInGraph.inputs;
|
|
120
|
+
}
|
|
121
|
+
if (targetDefaults?.outputs === undefined) {
|
|
122
|
+
target.outputs = jestTargetConfigInGraph.outputs;
|
|
123
|
+
}
|
|
124
|
+
if (targetDefaults?.dependsOn === undefined) {
|
|
125
|
+
target.dependsOn = jestTargetConfigInGraph.dependsOn;
|
|
126
|
+
}
|
|
127
|
+
(0, devkit_1.updateProjectConfiguration)(tree, rootProject.name, rootProjectConfig);
|
|
72
128
|
// generate new global config as it was move to project config or is missing
|
|
73
129
|
generateGlobalConfig(tree, options.js);
|
|
74
130
|
}
|
|
@@ -94,18 +150,20 @@ function updateProductionFileSet(tree) {
|
|
|
94
150
|
}
|
|
95
151
|
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
96
152
|
}
|
|
97
|
-
function addJestTargetDefaults(tree) {
|
|
153
|
+
function addJestTargetDefaults(tree, hasPlugin) {
|
|
98
154
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
99
|
-
const productionFileSet = nxJson.namedInputs?.production;
|
|
100
155
|
nxJson.targetDefaults ??= {};
|
|
101
156
|
nxJson.targetDefaults['@nx/jest:jest'] ??= {};
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
'
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
157
|
+
if (!hasPlugin) {
|
|
158
|
+
const productionFileSet = nxJson.namedInputs?.production;
|
|
159
|
+
nxJson.targetDefaults['@nx/jest:jest'].cache ??= true;
|
|
160
|
+
// Test targets depend on all their project's sources + production sources of dependencies
|
|
161
|
+
nxJson.targetDefaults['@nx/jest:jest'].inputs ??= [
|
|
162
|
+
'default',
|
|
163
|
+
productionFileSet ? '^production' : '^default',
|
|
164
|
+
'{workspaceRoot}/jest.preset.js',
|
|
165
|
+
];
|
|
166
|
+
}
|
|
109
167
|
nxJson.targetDefaults['@nx/jest:jest'].options ??= {
|
|
110
168
|
passWithNoTests: true,
|
|
111
169
|
};
|
|
@@ -167,7 +225,7 @@ async function jestInitGenerator(tree, schema) {
|
|
|
167
225
|
...schema,
|
|
168
226
|
skipFormat: true,
|
|
169
227
|
}));
|
|
170
|
-
createJestConfig(tree, options);
|
|
228
|
+
await createJestConfig(tree, options);
|
|
171
229
|
if (!options.skipPackageJson) {
|
|
172
230
|
(0, devkit_1.removeDependenciesFromPackageJson)(tree, ['@nx/jest'], []);
|
|
173
231
|
const installTask = updateDependencies(tree, options);
|
|
@@ -0,0 +1,123 @@
|
|
|
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/plugins/package-json-workspaces");
|
|
13
|
+
const globs_1 = require("nx/src/utils/globs");
|
|
14
|
+
const minimatch = 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 = minimatch(path, packageManagerWorkspacesGlob);
|
|
44
|
+
if (!isPackageJsonProject) {
|
|
45
|
+
return {};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
options = normalizeOptions(options);
|
|
49
|
+
const hash = (0, calculate_hash_for_create_nodes_1.calculateHashForCreateNodes)(projectRoot, options, context);
|
|
50
|
+
const targets = targetsCache[hash] ??
|
|
51
|
+
(await buildJestTargets(configFilePath, projectRoot, options, context));
|
|
52
|
+
calculatedTargets[hash] = targets;
|
|
53
|
+
return {
|
|
54
|
+
projects: {
|
|
55
|
+
[projectRoot]: {
|
|
56
|
+
root: projectRoot,
|
|
57
|
+
targets: targets,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
async function buildJestTargets(configFilePath, projectRoot, options, context) {
|
|
64
|
+
const config = await (0, jest_config_1.readConfig)({
|
|
65
|
+
_: [],
|
|
66
|
+
$0: undefined,
|
|
67
|
+
}, (0, path_1.resolve)(context.workspaceRoot, configFilePath), true, null, undefined, true);
|
|
68
|
+
const targetDefaults = (0, project_configuration_utils_1.readTargetDefaultsForTarget)(options.targetName, context.nxJsonConfiguration.targetDefaults, 'nx:run-commands');
|
|
69
|
+
const namedInputs = (0, get_named_inputs_1.getNamedInputs)(projectRoot, context);
|
|
70
|
+
const targets = {};
|
|
71
|
+
const target = (targets[options.targetName] = {
|
|
72
|
+
command: 'jest',
|
|
73
|
+
options: {
|
|
74
|
+
cwd: projectRoot,
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
if (!targetDefaults?.cache) {
|
|
78
|
+
target.cache = true;
|
|
79
|
+
}
|
|
80
|
+
if (!targetDefaults?.inputs) {
|
|
81
|
+
target.inputs = getInputs(namedInputs);
|
|
82
|
+
}
|
|
83
|
+
if (!targetDefaults?.outputs) {
|
|
84
|
+
target.outputs = getOutputs(projectRoot, config, context);
|
|
85
|
+
}
|
|
86
|
+
return targets;
|
|
87
|
+
}
|
|
88
|
+
function getInputs(namedInputs) {
|
|
89
|
+
return [
|
|
90
|
+
...('production' in namedInputs
|
|
91
|
+
? ['default', '^production']
|
|
92
|
+
: ['default', '^default']),
|
|
93
|
+
{
|
|
94
|
+
externalDependencies: ['jest'],
|
|
95
|
+
},
|
|
96
|
+
];
|
|
97
|
+
}
|
|
98
|
+
function getOutputs(projectRoot, { globalConfig }, context) {
|
|
99
|
+
function getOutput(path) {
|
|
100
|
+
const relativePath = (0, path_1.relative)((0, path_1.join)(context.workspaceRoot, projectRoot), path);
|
|
101
|
+
if (relativePath.startsWith('..')) {
|
|
102
|
+
return (0, path_1.join)('{workspaceRoot}', (0, path_1.join)(projectRoot, relativePath));
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
return (0, path_1.join)('{projectRoot}', relativePath);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const outputs = [];
|
|
109
|
+
for (const outputOption of [
|
|
110
|
+
globalConfig.coverageDirectory,
|
|
111
|
+
globalConfig.outputFile,
|
|
112
|
+
]) {
|
|
113
|
+
if (outputOption) {
|
|
114
|
+
outputs.push(getOutput(outputOption));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return outputs;
|
|
118
|
+
}
|
|
119
|
+
function normalizeOptions(options) {
|
|
120
|
+
options ??= {};
|
|
121
|
+
options.targetName ??= 'test';
|
|
122
|
+
return options;
|
|
123
|
+
}
|