@nx/jest 22.7.0 → 22.7.2
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/migrations.json +28 -0
- package/package.json +6 -6
- package/preset/jest-preset.d.ts.map +1 -1
- package/preset/jest-preset.js +1 -0
- package/src/migrations/update-22-2-0/convert-jest-config-to-cjs.d.ts +2 -4
- package/src/migrations/update-22-2-0/convert-jest-config-to-cjs.d.ts.map +1 -1
- package/src/migrations/update-22-2-0/convert-jest-config-to-cjs.js +36 -40
- package/src/migrations/update-23-0-0/update-snapshot-guide-link.d.ts +3 -0
- package/src/migrations/update-23-0-0/update-snapshot-guide-link.d.ts.map +1 -0
- package/src/migrations/update-23-0-0/update-snapshot-guide-link.js +28 -0
- package/src/utils/versions.d.ts.map +1 -1
- package/src/utils/versions.js +8 -3
package/migrations.json
CHANGED
|
@@ -42,6 +42,14 @@
|
|
|
42
42
|
},
|
|
43
43
|
"description": "Replace removed matcher aliases in Jest v30 with their corresponding matcher",
|
|
44
44
|
"implementation": "./src/migrations/update-21-3-0/replace-removed-matcher-aliases"
|
|
45
|
+
},
|
|
46
|
+
"update-snapshot-guide-link": {
|
|
47
|
+
"version": "23.0.0-beta.6",
|
|
48
|
+
"requires": {
|
|
49
|
+
"jest": ">=30.0.0"
|
|
50
|
+
},
|
|
51
|
+
"description": "Update the Jest snapshot guide link in `.snap` files from the legacy `https://goo.gl/fbAQLP` URL to `https://jestjs.io/docs/snapshot-testing`, which Jest v30 now requires.",
|
|
52
|
+
"implementation": "./src/migrations/update-23-0-0/update-snapshot-guide-link"
|
|
45
53
|
}
|
|
46
54
|
},
|
|
47
55
|
"packageJsonUpdates": {
|
|
@@ -171,6 +179,26 @@
|
|
|
171
179
|
"alwaysAddToPackageJson": false
|
|
172
180
|
}
|
|
173
181
|
}
|
|
182
|
+
},
|
|
183
|
+
"23.0.0-pin-jest-30-3-for-rn-compat": {
|
|
184
|
+
"version": "23.0.0-beta.9",
|
|
185
|
+
"requires": {
|
|
186
|
+
"jest": ">=30.0.0"
|
|
187
|
+
},
|
|
188
|
+
"packages": {
|
|
189
|
+
"jest": {
|
|
190
|
+
"version": "~30.3.0",
|
|
191
|
+
"alwaysAddToPackageJson": false
|
|
192
|
+
},
|
|
193
|
+
"babel-jest": {
|
|
194
|
+
"version": "~30.3.0",
|
|
195
|
+
"alwaysAddToPackageJson": false
|
|
196
|
+
},
|
|
197
|
+
"@types/jest": {
|
|
198
|
+
"version": "~30.0.0",
|
|
199
|
+
"alwaysAddToPackageJson": false
|
|
200
|
+
}
|
|
201
|
+
}
|
|
174
202
|
}
|
|
175
203
|
}
|
|
176
204
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/jest",
|
|
3
|
-
"version": "22.7.
|
|
3
|
+
"version": "22.7.2",
|
|
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": {
|
|
@@ -38,14 +38,14 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@jest/reporters": "^30.0.2",
|
|
40
40
|
"@jest/test-result": "^30.0.2",
|
|
41
|
-
"@nx/devkit": "22.7.
|
|
42
|
-
"@nx/js": "22.7.
|
|
43
|
-
"@phenomnomnominal/tsquery": "~6.
|
|
41
|
+
"@nx/devkit": "22.7.2",
|
|
42
|
+
"@nx/js": "22.7.2",
|
|
43
|
+
"@phenomnomnominal/tsquery": "~6.2.0",
|
|
44
44
|
"identity-obj-proxy": "3.0.0",
|
|
45
45
|
"jest-config": "^30.0.2",
|
|
46
46
|
"jest-resolve": "^30.0.2",
|
|
47
47
|
"jest-util": "^30.0.2",
|
|
48
|
-
"minimatch": "10.2.
|
|
48
|
+
"minimatch": "10.2.5",
|
|
49
49
|
"picocolors": "^1.1.0",
|
|
50
50
|
"resolve.exports": "2.0.3",
|
|
51
51
|
"semver": "^7.6.3",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"yargs-parser": "21.1.1"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"nx": "22.7.
|
|
56
|
+
"nx": "22.7.2"
|
|
57
57
|
},
|
|
58
58
|
"publishConfig": {
|
|
59
59
|
"access": "public"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jest-preset.d.ts","sourceRoot":"","sources":["../../../../packages/jest/preset/jest-preset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAc,MAAM,MAAM,CAAC;AAK1C,eAAO,MAAM,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"jest-preset.d.ts","sourceRoot":"","sources":["../../../../packages/jest/preset/jest-preset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAc,MAAM,MAAM,CAAC;AAK1C,eAAO,MAAM,QAAQ,EAAE,MAuCtB,CAAC"}
|
package/preset/jest-preset.js
CHANGED
|
@@ -25,6 +25,7 @@ exports.nxPreset = {
|
|
|
25
25
|
],
|
|
26
26
|
},
|
|
27
27
|
testEnvironment: 'jsdom',
|
|
28
|
+
modulePathIgnorePatterns: ['<rootDir>/dist/', '<rootDir>/out-tsc/'],
|
|
28
29
|
/**
|
|
29
30
|
* manually set the exports names to load in common js, to mimic the behaviors of jest 27
|
|
30
31
|
* before jest didn't fully support package exports and would load in common js code (typically via main field). now jest 28+ will load in the browser esm code, but jest esm support is not fully supported.
|
|
@@ -5,8 +5,6 @@ import { Tree } from '@nx/devkit';
|
|
|
5
5
|
* in newer versions (22+, 24+) can cause issues with ESM syntax in .ts files
|
|
6
6
|
* when the project is configured for CommonJS.
|
|
7
7
|
*
|
|
8
|
-
* This migration only runs if @nx/jest/plugin is registered in nx.json.
|
|
9
|
-
*
|
|
10
8
|
* Conversions:
|
|
11
9
|
* - `export default { ... }` -> `module.exports = { ... }`
|
|
12
10
|
* - `import { x } from 'y'` -> `const { x } = require('y')`
|
|
@@ -16,8 +14,8 @@ import { Tree } from '@nx/devkit';
|
|
|
16
14
|
* - `import.meta`
|
|
17
15
|
* - top-level `await`
|
|
18
16
|
*
|
|
19
|
-
* Projects with `type: module` in package.json
|
|
20
|
-
*
|
|
17
|
+
* Projects with `type: module` in package.json are skipped and warned about,
|
|
18
|
+
* as they use ESM semantics and don't need the CJS conversion.
|
|
21
19
|
*/
|
|
22
20
|
export default function convertJestConfigToCjs(tree: Tree): Promise<() => void>;
|
|
23
21
|
//# sourceMappingURL=convert-jest-config-to-cjs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convert-jest-config-to-cjs.d.ts","sourceRoot":"","sources":["../../../../../../packages/jest/src/migrations/update-22-2-0/convert-jest-config-to-cjs.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"convert-jest-config-to-cjs.d.ts","sourceRoot":"","sources":["../../../../../../packages/jest/src/migrations/update-22-2-0/convert-jest-config-to-cjs.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,IAAI,EACL,MAAM,YAAY,CAAC;AAGpB;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAA8B,sBAAsB,CAAC,IAAI,EAAE,IAAI,uBAmF9D"}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.default = convertJestConfigToCjs;
|
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
|
5
|
-
const find_plugin_for_config_file_1 = require("@nx/devkit/src/utils/find-plugin-for-config-file");
|
|
6
5
|
const path_1 = require("path");
|
|
7
6
|
/**
|
|
8
7
|
* Migration to convert jest.config.ts files from ESM to CJS syntax for projects
|
|
@@ -10,8 +9,6 @@ const path_1 = require("path");
|
|
|
10
9
|
* in newer versions (22+, 24+) can cause issues with ESM syntax in .ts files
|
|
11
10
|
* when the project is configured for CommonJS.
|
|
12
11
|
*
|
|
13
|
-
* This migration only runs if @nx/jest/plugin is registered in nx.json.
|
|
14
|
-
*
|
|
15
12
|
* Conversions:
|
|
16
13
|
* - `export default { ... }` -> `module.exports = { ... }`
|
|
17
14
|
* - `import { x } from 'y'` -> `const { x } = require('y')`
|
|
@@ -21,24 +18,16 @@ const path_1 = require("path");
|
|
|
21
18
|
* - `import.meta`
|
|
22
19
|
* - top-level `await`
|
|
23
20
|
*
|
|
24
|
-
* Projects with `type: module` in package.json
|
|
25
|
-
*
|
|
21
|
+
* Projects with `type: module` in package.json are skipped and warned about,
|
|
22
|
+
* as they use ESM semantics and don't need the CJS conversion.
|
|
26
23
|
*/
|
|
27
24
|
async function convertJestConfigToCjs(tree) {
|
|
28
|
-
// If @nx/jest/plugin not used, then there will not be any problems with graph construction, which
|
|
29
|
-
// is what we're trying to address.
|
|
30
|
-
if (!isJestPluginRegistered(tree))
|
|
31
|
-
return;
|
|
32
25
|
const { ast: parseAst, query } = require('@phenomnomnominal/tsquery');
|
|
33
26
|
const jestConfigPaths = await (0, devkit_1.globAsync)(tree, ['**/jest.config.ts']);
|
|
34
27
|
const projectsWithEsmOnlyFeatures = [];
|
|
35
28
|
const projectsWithTypeModule = [];
|
|
36
29
|
const modifiedFiles = [];
|
|
37
30
|
for (const configPath of jestConfigPaths) {
|
|
38
|
-
// Skip config files that are excluded from the plugin via include/exclude patterns
|
|
39
|
-
const pluginRegistration = await (0, find_plugin_for_config_file_1.findPluginForConfigFile)(tree, '@nx/jest/plugin', configPath);
|
|
40
|
-
if (!pluginRegistration)
|
|
41
|
-
continue;
|
|
42
31
|
const projectRoot = (0, path_1.dirname)(configPath);
|
|
43
32
|
const packageJsonPath = (0, devkit_1.joinPathFragments)(projectRoot, 'package.json');
|
|
44
33
|
const rootPackageJsonPath = 'package.json';
|
|
@@ -52,8 +41,8 @@ async function convertJestConfigToCjs(tree) {
|
|
|
52
41
|
rootPackageJson = (0, devkit_1.readJson)(tree, rootPackageJsonPath);
|
|
53
42
|
}
|
|
54
43
|
const effectiveType = projectPackageJson?.type ?? rootPackageJson?.type ?? 'commonjs'; // CJS is default if missing
|
|
55
|
-
// If type is "module",
|
|
56
|
-
//
|
|
44
|
+
// If type is "module", skip conversion: the file already runs under ESM
|
|
45
|
+
// semantics and does not need the CJS rewrite.
|
|
57
46
|
if (effectiveType === 'module') {
|
|
58
47
|
projectsWithTypeModule.push(configPath);
|
|
59
48
|
continue;
|
|
@@ -79,9 +68,9 @@ async function convertJestConfigToCjs(tree) {
|
|
|
79
68
|
if (hasWarnings) {
|
|
80
69
|
return () => {
|
|
81
70
|
if (projectsWithTypeModule.length > 0) {
|
|
82
|
-
devkit_1.logger.warn(`The following projects
|
|
83
|
-
`
|
|
84
|
-
`or using a different Jest configuration approach:\n` +
|
|
71
|
+
devkit_1.logger.warn(`The following jest.config.ts files belong to projects with "type": "module" in their package.json ` +
|
|
72
|
+
`and were left as-is. If you use @nx/jest/plugin, it forces CommonJS resolution, so consider ` +
|
|
73
|
+
`removing "type": "module" or using a different Jest configuration approach:\n` +
|
|
85
74
|
projectsWithTypeModule.map((p) => ` - ${p}`).join('\n'));
|
|
86
75
|
}
|
|
87
76
|
if (projectsWithEsmOnlyFeatures.length > 0) {
|
|
@@ -134,26 +123,36 @@ function convertImportsToRequire(content, parseAst, query) {
|
|
|
134
123
|
content = replaceNode(content, importDecl, requireStatement);
|
|
135
124
|
continue;
|
|
136
125
|
}
|
|
126
|
+
// `import type ...` is erased by Node's type-stripping at runtime, so it
|
|
127
|
+
// can remain in the file untouched — this preserves editor/tsc type safety.
|
|
128
|
+
if (importClause.isTypeOnly) {
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
137
131
|
const parts = [];
|
|
132
|
+
const typeOnlySpecifiers = [];
|
|
138
133
|
// Default import: import x from 'module'
|
|
139
134
|
if (importClause.name) {
|
|
140
135
|
const defaultName = importClause.name.getText();
|
|
141
136
|
parts.push(`const ${defaultName} = require('${moduleSpecifier}').default ?? require('${moduleSpecifier}')`);
|
|
142
137
|
}
|
|
143
|
-
// Named imports: import { a, b } from 'module'
|
|
144
138
|
if (importClause.namedBindings) {
|
|
145
139
|
if (ts.isNamedImports(importClause.namedBindings)) {
|
|
146
|
-
const
|
|
147
|
-
|
|
140
|
+
const valueSpecifiers = [];
|
|
141
|
+
for (const element of importClause.namedBindings.elements) {
|
|
148
142
|
const name = element.name.getText();
|
|
149
143
|
const propertyName = element.propertyName?.getText();
|
|
150
|
-
if (
|
|
151
|
-
|
|
144
|
+
if (element.isTypeOnly) {
|
|
145
|
+
// Inline `type` modifier: `import { type Foo, bar } from 'x'`.
|
|
146
|
+
// Preserve the type-only portion so type references still resolve.
|
|
147
|
+
typeOnlySpecifiers.push(propertyName ? `${propertyName} as ${name}` : name);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
valueSpecifiers.push(propertyName ? `${propertyName}: ${name}` : name);
|
|
152
151
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
.join(', ');
|
|
156
|
-
|
|
152
|
+
}
|
|
153
|
+
if (valueSpecifiers.length) {
|
|
154
|
+
parts.push(`const { ${valueSpecifiers.join(', ')} } = require('${moduleSpecifier}')`);
|
|
155
|
+
}
|
|
157
156
|
}
|
|
158
157
|
else if (ts.isNamespaceImport(importClause.namedBindings)) {
|
|
159
158
|
// Namespace import: import * as x from 'module'
|
|
@@ -161,8 +160,16 @@ function convertImportsToRequire(content, parseAst, query) {
|
|
|
161
160
|
parts.push(`const ${namespaceName} = require('${moduleSpecifier}')`);
|
|
162
161
|
}
|
|
163
162
|
}
|
|
164
|
-
const
|
|
165
|
-
|
|
163
|
+
const replacementParts = [];
|
|
164
|
+
if (typeOnlySpecifiers.length) {
|
|
165
|
+
replacementParts.push(`import type { ${typeOnlySpecifiers.join(', ')} } from '${moduleSpecifier}'`);
|
|
166
|
+
}
|
|
167
|
+
replacementParts.push(...parts);
|
|
168
|
+
if (replacementParts.length === 0) {
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
const replacement = replacementParts.join(';\n');
|
|
172
|
+
content = replaceNode(content, importDecl, replacement);
|
|
166
173
|
}
|
|
167
174
|
return content;
|
|
168
175
|
}
|
|
@@ -191,14 +198,3 @@ function replaceNode(content, node, replacement) {
|
|
|
191
198
|
}
|
|
192
199
|
return content.slice(0, start) + replacement + ';' + content.slice(endPos);
|
|
193
200
|
}
|
|
194
|
-
function isJestPluginRegistered(tree) {
|
|
195
|
-
if (!tree.exists('nx.json')) {
|
|
196
|
-
return false;
|
|
197
|
-
}
|
|
198
|
-
const nxJson = (0, devkit_1.readJson)(tree, 'nx.json');
|
|
199
|
-
const plugins = nxJson.plugins ?? [];
|
|
200
|
-
return plugins.some((plugin) => {
|
|
201
|
-
const pluginName = typeof plugin === 'string' ? plugin : plugin.plugin;
|
|
202
|
-
return pluginName === '@nx/jest/plugin' || pluginName === '@nx/jest';
|
|
203
|
-
});
|
|
204
|
-
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-snapshot-guide-link.d.ts","sourceRoot":"","sources":["../../../../../../packages/jest/src/migrations/update-23-0-0/update-snapshot-guide-link.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAM/D,wBAA8B,uBAAuB,CAAC,IAAI,EAAE,IAAI,iBA2B/D"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = updateSnapshotGuideLink;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const OLD_HEADER = '// Jest Snapshot v1, https://goo.gl/fbAQLP';
|
|
6
|
+
const NEW_HEADER = '// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing';
|
|
7
|
+
async function updateSnapshotGuideLink(tree) {
|
|
8
|
+
const snapshotFiles = await (0, devkit_1.globAsync)(tree, ['**/__snapshots__/*.snap']);
|
|
9
|
+
for (const snapshotFile of snapshotFiles) {
|
|
10
|
+
const content = tree.read(snapshotFile, 'utf-8');
|
|
11
|
+
if (!content) {
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
const newlineMatch = content.match(/\r?\n/);
|
|
15
|
+
if (!newlineMatch) {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
const newline = newlineMatch[0];
|
|
19
|
+
const firstNewlineIndex = content.indexOf(newline);
|
|
20
|
+
const firstLine = content.slice(0, firstNewlineIndex);
|
|
21
|
+
if (firstLine !== OLD_HEADER) {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
const updated = NEW_HEADER + content.slice(firstNewlineIndex);
|
|
25
|
+
tree.write(snapshotFile, updated);
|
|
26
|
+
}
|
|
27
|
+
await (0, devkit_1.formatFiles)(tree);
|
|
28
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"versions.d.ts","sourceRoot":"","sources":["../../../../../packages/jest/src/utils/versions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuC,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"versions.d.ts","sourceRoot":"","sources":["../../../../../packages/jest/src/utils/versions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuC,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAU5E,eAAO,MAAM,cAAc;;;;;;;;;;CAU1B,CAAC;AAEF,QAAA,MAAM,sBAAsB,mBAAoB,CAAC;AAIjD,KAAK,iBAAiB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AACjE,KAAK,mBAAmB,GAAG,MAAM,OAAO,cAAc,CAAC;AACvD,MAAM,MAAM,UAAU,GAAG;KACtB,GAAG,IAAI,iBAAiB,GAAG,MAAM,CAAC,mBAAmB,EAAE,MAAM,CAAC;CAChE,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,UAaxB,CAAC;AAEF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,OAiBlC;AAED,wBAAgB,uBAAuB,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAclE;AAED,wBAAgB,2BAA2B,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG;IACxD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAMA;AAED,wBAAgB,4BAA4B,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAIvE;AAED,wBAAgB,4BAA4B,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAc9D"}
|
package/src/utils/versions.js
CHANGED
|
@@ -9,11 +9,16 @@ exports.validateInstalledJestVersion = validateInstalledJestVersion;
|
|
|
9
9
|
const devkit_1 = require("@nx/devkit");
|
|
10
10
|
const semver_1 = require("semver");
|
|
11
11
|
const nxVersion = require('../../package.json').version;
|
|
12
|
+
// Jest is pinned to 30.3.x because jest-runtime@30.4.0 added a call to
|
|
13
|
+
// `_moduleMocker.clearMocksOnScope()`, which doesn't exist on the
|
|
14
|
+
// jest-mock@29 ModuleMocker that React Native's preset still feeds in
|
|
15
|
+
// (via `@react-native/jest-preset`'s pinned `jest-environment-node@^29.7.0`).
|
|
16
|
+
// Lift this once Meta ships a Jest-30-aware preset on react-native.
|
|
12
17
|
exports.latestVersions = {
|
|
13
18
|
nxVersion,
|
|
14
|
-
jestVersion: '
|
|
15
|
-
babelJestVersion: '
|
|
16
|
-
jestTypesVersion: '
|
|
19
|
+
jestVersion: '~30.3.0',
|
|
20
|
+
babelJestVersion: '~30.3.0',
|
|
21
|
+
jestTypesVersion: '~30.0.0',
|
|
17
22
|
tsJestVersion: '^29.4.0',
|
|
18
23
|
tslibVersion: '^2.3.0',
|
|
19
24
|
swcJestVersion: '~0.2.38',
|