1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.updateConfigsJest29 = void 0;
|
4 | const tslib_1 = require("tslib");
|
5 | const devkit_1 = require("@nrwl/devkit");
|
6 | const ast_utils_1 = require("../../utils/ast-utils");
|
7 | const tsquery_1 = require("@phenomnomnominal/tsquery");
|
8 | const ts = require("typescript");
|
9 | const executor_options_utils_1 = require("@nrwl/workspace/src/utilities/executor-options-utils");
|
10 | const find_root_jest_files_1 = require("../../utils/config/find-root-jest-files");
|
11 | function updateConfigsJest29(tree) {
|
12 | return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
13 | const rootPreset = (0, find_root_jest_files_1.findRootJestPreset)(tree);
|
14 | const targetsWithJest = new Set();
|
15 |
|
16 | const graph = yield (0, devkit_1.createProjectGraphAsync)();
|
17 | (0, executor_options_utils_1.forEachExecutorOptionsInGraph)(graph, '@nrwl/jest:jest', (options, projectName, targetName) => {
|
18 | if (options.jestConfig && tree.exists(options.jestConfig)) {
|
19 | targetsWithJest.add(targetName);
|
20 |
|
21 |
|
22 | if (!rootPreset || !hasPresetConfigured(tree, options.jestConfig)) {
|
23 | addSnapshotOptionsToConfig(tree, options.jestConfig, `From within the project directory, run "nx test --update-snapshot"`);
|
24 | }
|
25 | updateTsJestOptions(tree, options.jestConfig);
|
26 | updateNgJestOptions(tree, options.jestConfig);
|
27 | }
|
28 | });
|
29 | if (rootPreset && tree.exists(rootPreset)) {
|
30 | const cmd = `"nx affected --targets=${Array.from(targetsWithJest).join(',')} --update-snapshot"`;
|
31 | addSnapshotOptionsToConfig(tree, rootPreset, cmd);
|
32 | updateTsJestOptions(tree, rootPreset);
|
33 | updateNgJestOptions(tree, rootPreset);
|
34 | }
|
35 | yield (0, devkit_1.formatFiles)(tree);
|
36 | devkit_1.logger.info((0, devkit_1.stripIndents) `NX Jest Snapshot format changed in v29.
|
37 | By default Nx kept the older style to prevent breaking of existing tests with snapshots.
|
38 | It's recommend you update to the latest format.
|
39 | You can do this in your project's jest config file.
|
40 | Remove the snapshotFormat property and re-run tests with the --update-snapshot flag.
|
41 | More info: https://jestjs.io/docs/upgrading-to-jest29#snapshot-format`);
|
42 | });
|
43 | }
|
44 | exports.updateConfigsJest29 = updateConfigsJest29;
|
45 | function addSnapshotOptionsToConfig(tree, configPath, updateSnapshotExample) {
|
46 | const config = tree.read(configPath, 'utf-8');
|
47 | const hasSnapshotOptions = tsquery_1.tsquery.query(config, `${ast_utils_1.TS_QUERY_JEST_CONFIG_PREFIX} > ObjectLiteralExpression PropertyAssignment:has(Identifier[name="snapshotFormat"])`);
|
48 | if (hasSnapshotOptions.length > 0) {
|
49 | return;
|
50 | }
|
51 | const updatedConfig = tsquery_1.tsquery.replace(config, `${ast_utils_1.TS_QUERY_JEST_CONFIG_PREFIX} > ObjectLiteralExpression`, (node) => {
|
52 | return `{
|
53 | ${node.properties.map((p) => getNodeWithComments(config, p)).join(',\n')},
|
54 | /* TODO: Update to latest Jest snapshotFormat
|
55 | * By default Nx has kept the older style of Jest Snapshot formats
|
56 | * to prevent breaking of any existing tests with snapshots.
|
57 | * It's recommend you update to the latest format.
|
58 | * You can do this by removing snapshotFormat property
|
59 | * and running tests with --update-snapshot flag.
|
60 | * Example: ${updateSnapshotExample}
|
61 | * More info: https://jestjs.io/docs/upgrading-to-jest29#snapshot-format
|
62 | */
|
63 | snapshotFormat: { escapeString: true, printBasicPrototype: true }
|
64 | }`;
|
65 | }, { visitAllChildren: false });
|
66 | tree.write(configPath, updatedConfig);
|
67 | }
|
68 | function hasPresetConfigured(tree, configPath) {
|
69 | var _a;
|
70 | const contents = tree.read(configPath, 'utf-8');
|
71 | return (((_a = tsquery_1.tsquery.query(contents, `${ast_utils_1.TS_QUERY_JEST_CONFIG_PREFIX} > ObjectLiteralExpression PropertyAssignment:has(Identifier[name="preset"])`)) === null || _a === void 0 ? void 0 : _a.length) > 0);
|
72 | }
|
73 | function updateTsJestOptions(tree, configPath) {
|
74 |
|
75 | const contents = tree.read(configPath, 'utf-8');
|
76 | let tsJestGlobalsConfig;
|
77 | const noTsJestGlobals = tsquery_1.tsquery.replace(contents, `${ast_utils_1.TS_QUERY_JEST_CONFIG_PREFIX} > ObjectLiteralExpression PropertyAssignment:has(Identifier[name="globals"])`, (node) => {
|
78 | if (tsJestGlobalsConfig) {
|
79 | devkit_1.logger.warn((0, devkit_1.stripIndents) `Found more than one "globals" object in the jest config, ${configPath}
|
80 | Will use the first one`);
|
81 | return;
|
82 | }
|
83 | tsJestGlobalsConfig = getGlobalTsJestConfig(node);
|
84 | return getGlobalConfigWithoutTsJest(node);
|
85 | });
|
86 | if (!tsJestGlobalsConfig) {
|
87 | return;
|
88 | }
|
89 | const updatedTsJestTransformer = tsquery_1.tsquery.replace(noTsJestGlobals, `${ast_utils_1.TS_QUERY_JEST_CONFIG_PREFIX}> ObjectLiteralExpression PropertyAssignment:has(Identifier[name="transform"]) PropertyAssignment > :has(StringLiteral[value="ts-jest"], StringLiteral[value="jest-preset-angular"])`, (node) => {
|
90 | return `[${node.getText()}, ${tsJestGlobalsConfig}]`;
|
91 | });
|
92 | tree.write(configPath, updatedTsJestTransformer);
|
93 | }
|
94 | function updateNgJestOptions(tree, configPath) {
|
95 | const contents = tree.read(configPath, 'utf-8');
|
96 | let ngJestTeardownConfig;
|
97 | const noTeardownConfig = tsquery_1.tsquery.replace(contents, 'BinaryExpression:has(PropertyAccessExpression:has(Identifier[name=ngJest])) PropertyAssignment:has(Identifier[name=teardown])', (node) => {
|
98 | ngJestTeardownConfig = node.initializer.getText();
|
99 | return ' ';
|
100 | });
|
101 | if (!ngJestTeardownConfig) {
|
102 | return;
|
103 | }
|
104 | let maybeUpdatedTestEnvOpts = tsquery_1.tsquery.replace(noTeardownConfig, `${ast_utils_1.TS_QUERY_JEST_CONFIG_PREFIX} > ObjectLiteralExpression PropertyAssignment:has(Identifier[name="testEnvironmentOptions"]) ObjectLiteralExpression`, (node) => {
|
105 | return `{
|
106 | ${node.properties
|
107 | .map((p) => getNodeWithComments(noTeardownConfig, p))
|
108 | .join(',\n')},
|
109 | teardown: ${ngJestTeardownConfig}
|
110 | }`;
|
111 | });
|
112 | if (maybeUpdatedTestEnvOpts !== noTeardownConfig) {
|
113 | tree.write(configPath, maybeUpdatedTestEnvOpts);
|
114 | return;
|
115 | }
|
116 |
|
117 | const updatedConfig = tsquery_1.tsquery.replace(maybeUpdatedTestEnvOpts, `${ast_utils_1.TS_QUERY_JEST_CONFIG_PREFIX} > ObjectLiteralExpression`, (node) => {
|
118 | return `{
|
119 | ${node.properties
|
120 | .map((p) => getNodeWithComments(maybeUpdatedTestEnvOpts, p))
|
121 | .join(',\n')},
|
122 | testEnvironmentOptions: { teardown: ${ngJestTeardownConfig} },
|
123 | }`;
|
124 | }, { visitAllChildren: false });
|
125 | tree.write(configPath, updatedConfig);
|
126 | }
|
127 | function getGlobalTsJestConfig(node) {
|
128 | var _a;
|
129 | const globalObject = node.initializer;
|
130 | const foundConfig = globalObject.properties.find((p) => ts.isPropertyAssignment(p) && p.name.getText().includes('ts-jest'));
|
131 | return ((_a = foundConfig === null || foundConfig === void 0 ? void 0 : foundConfig.initializer) === null || _a === void 0 ? void 0 : _a.getText()) || '';
|
132 | }
|
133 | function getGlobalConfigWithoutTsJest(node) {
|
134 | var _a;
|
135 | const globalObject = node === null || node === void 0 ? void 0 : node.initializer;
|
136 | const withoutTsJest = (_a = globalObject === null || globalObject === void 0 ? void 0 : globalObject.properties) === null || _a === void 0 ? void 0 : _a.filter((p) => {
|
137 | return !(ts.isPropertyAssignment(p) && p.name.getText().includes('ts-jest'));
|
138 | });
|
139 | const globalConfigs = withoutTsJest.map((c) => c.getText()).join(',\n');
|
140 | return `globals: { ${globalConfigs} }`;
|
141 | }
|
142 | function getNodeWithComments(fullText, node) {
|
143 | const commentRanges = ts.getLeadingCommentRanges(fullText, node.getFullStart());
|
144 | if ((commentRanges === null || commentRanges === void 0 ? void 0 : commentRanges.length) > 0) {
|
145 | const withComments = `${commentRanges
|
146 | .map((r) => fullText.slice(r.pos, r.end))
|
147 | .join('\n')}\n${node.getText()}`;
|
148 | return withComments;
|
149 | }
|
150 | return node.getText();
|
151 | }
|
152 | exports.default = updateConfigsJest29;
|
153 |
|
\ | No newline at end of file |