Skip to content

Commit d454f25

Browse files
authored
feat(testing): update test generators to exclude test files from the runtime tsconfig file (#27991)
<!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior <!-- This is the behavior we have today --> ## Expected Behavior <!-- This is the behavior we should expect with the changes in this PR --> ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #
1 parent c92528f commit d454f25

File tree

18 files changed

+185
-93
lines changed

18 files changed

+185
-93
lines changed

docs/generated/packages/jest/generators/configuration.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@
7575
"type": "boolean",
7676
"default": false,
7777
"description": "Use JavaScript instead of TypeScript for config files"
78+
},
79+
"runtimeTsconfigFileName": {
80+
"type": "string",
81+
"description": "The name of the project's tsconfig file that includes the runtime source files. If not provided, it will default to `tsconfig.lib.json` for libraries and `tsconfig.app.json` for applications."
7882
}
7983
},
8084
"required": [],

docs/generated/packages/vite/generators/vitest.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@
5151
"description": "The vitest environment to use. See https://vitest.dev/config/#environment.",
5252
"type": "string",
5353
"enum": ["node", "jsdom", "happy-dom", "edge-runtime"]
54+
},
55+
"runtimeTsconfigFileName": {
56+
"type": "string",
57+
"description": "The name of the project's tsconfig file that includes the runtime source files. If not provided, it will default to `tsconfig.lib.json` for libraries and `tsconfig.app.json` for applications."
5458
}
5559
},
5660
"required": ["project"],

packages/express/src/generators/application/application.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ describe('app', () => {
129129
const tsConfigApp = readJson(appTree, 'my-node-app/tsconfig.app.json');
130130
expect(tsConfigApp.include).toEqual(['src/**/*.ts', 'src/**/*.js']);
131131
expect(tsConfigApp.exclude).toEqual([
132-
'jest.config.ts',
132+
'jest.config.js',
133133
'src/**/*.spec.ts',
134134
'src/**/*.test.ts',
135135
'src/**/*.spec.js',
Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
1-
import { join } from 'path';
2-
import { NormalizedJestProjectSchema } from '../schema';
3-
import { readProjectConfiguration, Tree, updateJson } from '@nx/devkit';
1+
import {
2+
joinPathFragments,
3+
logger,
4+
readProjectConfiguration,
5+
updateJson,
6+
type Tree,
7+
} from '@nx/devkit';
8+
import type { NormalizedJestProjectSchema } from '../schema';
49

510
export function updateTsConfig(
611
host: Tree,
712
options: NormalizedJestProjectSchema
813
) {
9-
const projectConfig = readProjectConfiguration(host, options.project);
10-
if (!host.exists(join(projectConfig.root, 'tsconfig.json'))) {
14+
const { root, projectType } = readProjectConfiguration(host, options.project);
15+
if (!host.exists(joinPathFragments(root, 'tsconfig.json'))) {
1116
throw new Error(
12-
`Expected ${join(
13-
projectConfig.root,
17+
`Expected ${joinPathFragments(
18+
root,
1419
'tsconfig.json'
1520
)} to exist. Please create one.`
1621
);
1722
}
18-
updateJson(host, join(projectConfig.root, 'tsconfig.json'), (json) => {
23+
updateJson(host, joinPathFragments(root, 'tsconfig.json'), (json) => {
1924
if (
2025
json.references &&
2126
!json.references.some((r) => r.path === './tsconfig.spec.json')
@@ -26,4 +31,41 @@ export function updateTsConfig(
2631
}
2732
return json;
2833
});
34+
35+
// fall-back runtime tsconfig file path in case the user didn't provide one
36+
let runtimeTsconfigPath = joinPathFragments(
37+
root,
38+
projectType === 'application' ? 'tsconfig.app.json' : 'tsconfig.lib.json'
39+
);
40+
if (options.runtimeTsconfigFileName) {
41+
runtimeTsconfigPath = joinPathFragments(
42+
root,
43+
options.runtimeTsconfigFileName
44+
);
45+
if (!host.exists(runtimeTsconfigPath)) {
46+
// the user provided a runtimeTsconfigFileName that doesn't exist, so we throw an error
47+
throw new Error(
48+
`Cannot find the provided runtimeTsConfigFileName ("${options.runtimeTsconfigFileName}") at the project root "${root}".`
49+
);
50+
}
51+
}
52+
53+
if (host.exists(runtimeTsconfigPath)) {
54+
updateJson(host, runtimeTsconfigPath, (json) => {
55+
const uniqueExclude = new Set([
56+
...(json.exclude || []),
57+
options.js ? 'jest.config.js' : 'jest.config.ts',
58+
'src/**/*.spec.ts',
59+
'src/**/*.test.ts',
60+
...(options.js ? ['src/**/*.spec.js', 'src/**/*.test.js'] : []),
61+
]);
62+
json.exclude = [...uniqueExclude];
63+
return json;
64+
});
65+
} else {
66+
logger.warn(
67+
`Couldn't find a runtime tsconfig file at ${runtimeTsconfigPath} to exclude the test files from. ` +
68+
`If you're using a different filename for your runtime tsconfig, please provide it with the '--runtimeTsconfigFileName' flag.`
69+
);
70+
}
2971
}

packages/jest/src/generators/configuration/schema.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export interface JestProjectSchema {
1919
compiler?: 'tsc' | 'babel' | 'swc';
2020
skipPackageJson?: boolean;
2121
js?: boolean;
22+
runtimeTsconfigFileName?: string;
2223

2324
/**
2425
* @internal

packages/jest/src/generators/configuration/schema.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@
7474
"type": "boolean",
7575
"default": false,
7676
"description": "Use JavaScript instead of TypeScript for config files"
77+
},
78+
"runtimeTsconfigFileName": {
79+
"type": "string",
80+
"description": "The name of the project's tsconfig file that includes the runtime source files. If not provided, it will default to `tsconfig.lib.json` for libraries and `tsconfig.app.json` for applications."
7781
}
7882
},
7983
"required": []

packages/js/src/generators/library/files/lib/tsconfig.lib.json__tmpl__

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,5 @@
55
"declaration": true,
66
"types": ["node"]
77
},
8-
"include": ["src/**/*.ts"<% if (js) { %>, "src/**/*.js"<% } %>],
9-
"exclude": [
10-
<% if (hasUnitTestRunner && unitTestRunner === 'jest') { %>"jest.config.ts",
11-
<% } else if (hasUnitTestRunner) { %>"vite.config.ts",
12-
<% } %>"src/**/*.spec.ts", "src/**/*.test.ts"<% if (js) { %>, "src/**/*.spec.js", "src/**/*.test.js"<% } %>
13-
]
8+
"include": ["src/**/*.ts"<% if (js) { %>, "src/**/*.js"<% } %>]
149
}

packages/js/src/generators/library/library.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ export async function libraryGeneratorInternal(
145145
coverageProvider: 'v8',
146146
skipFormat: true,
147147
testEnvironment: options.testEnvironment,
148+
runtimeTsconfigFileName: 'tsconfig.lib.json',
148149
});
149150
tasks.push(vitestTask);
150151
createOrEditViteConfig(
@@ -601,6 +602,7 @@ async function addJest(
601602
: options.bundler === 'rollup'
602603
? 'swc'
603604
: undefined,
605+
runtimeTsconfigFileName: 'tsconfig.lib.json',
604606
});
605607
}
606608

packages/node/src/generators/application/application.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ describe('app', () => {
477477
const tsConfigApp = readJson(tree, 'my-node-app/tsconfig.app.json');
478478
expect(tsConfigApp.include).toEqual(['src/**/*.ts', 'src/**/*.js']);
479479
expect(tsConfigApp.exclude).toEqual([
480-
'jest.config.ts',
480+
'jest.config.js',
481481
'src/**/*.spec.ts',
482482
'src/**/*.test.ts',
483483
'src/**/*.spec.js',

packages/node/src/generators/application/files/common/tsconfig.app.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,5 @@
55
"module": "commonjs",
66
"types": ["node"]
77
},
8-
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
98
"include": ["src/**/*.ts"]
109
}

packages/vite/src/generators/configuration/__snapshots__/configuration.spec.ts.snap

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -90,23 +90,38 @@ exports[`@nx/vite:configuration js library with --bundler=vite should add build
9090
"types": ["node", "vite/client"]
9191
},
9292
"include": ["src/**/*.ts"],
93-
"exclude": ["vite.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]
93+
"exclude": [
94+
"vite.config.ts",
95+
"vitest.config.ts",
96+
"src/**/*.test.ts",
97+
"src/**/*.spec.ts",
98+
"src/**/*.test.tsx",
99+
"src/**/*.spec.tsx",
100+
"src/**/*.test.js",
101+
"src/**/*.spec.js",
102+
"src/**/*.test.jsx",
103+
"src/**/*.spec.jsx"
104+
]
94105
}
95106
"
96107
`;
97108

98-
exports[`@nx/vite:configuration js library with --bundler=vite should respect unitTestRunner if passed 1`] = `
109+
exports[`@nx/vite:configuration js library with --bundler=vite should respect provided unitTestRunner="jest" 1`] = `
99110
"# my-lib
100111
101112
This library was generated with [Nx](https://nx.dev).
102113
103114
## Building
104115
105116
Run \`nx build my-lib\` to build the library.
117+
118+
## Running unit tests
119+
120+
Run \`nx test my-lib\` to execute the unit tests via [Jest](https://jestjs.io).
106121
"
107122
`;
108123

109-
exports[`@nx/vite:configuration js library with --bundler=vite should respect unitTestRunner if passed 2`] = `
124+
exports[`@nx/vite:configuration js library with --bundler=vite should respect provided unitTestRunner="jest" 2`] = `
110125
"{
111126
"extends": "./tsconfig.json",
112127
"compilerOptions": {
@@ -115,53 +130,48 @@ exports[`@nx/vite:configuration js library with --bundler=vite should respect un
115130
"types": ["node", "vite/client"]
116131
},
117132
"include": ["src/**/*.ts"],
118-
"exclude": ["src/**/*.spec.ts", "src/**/*.test.ts"]
133+
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]
119134
}
120135
"
121136
`;
122137

123-
exports[`@nx/vite:configuration js library with --bundler=vite should respect unitTestRunner if passed 3`] = `
138+
exports[`@nx/vite:configuration js library with --bundler=vite should respect provided unitTestRunner="jest" 3`] = `
139+
"export default {
140+
displayName: 'my-lib',
141+
preset: '../jest.preset.js',
142+
transform: {
143+
'^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
144+
},
145+
moduleFileExtensions: ['ts', 'js', 'html'],
146+
coverageDirectory: '../coverage/my-lib',
147+
};
148+
"
149+
`;
150+
151+
exports[`@nx/vite:configuration js library with --bundler=vite should respect provided unitTestRunner="none" 1`] = `
124152
"# my-lib
125153
126154
This library was generated with [Nx](https://nx.dev).
127155
128156
## Building
129157
130158
Run \`nx build my-lib\` to build the library.
131-
132-
## Running unit tests
133-
134-
Run \`nx test my-lib\` to execute the unit tests via [Jest](https://jestjs.io).
135159
"
136160
`;
137161

138-
exports[`@nx/vite:configuration js library with --bundler=vite should respect unitTestRunner if passed 4`] = `
162+
exports[`@nx/vite:configuration js library with --bundler=vite should respect provided unitTestRunner="none" 2`] = `
139163
"{
140164
"extends": "./tsconfig.json",
141165
"compilerOptions": {
142166
"outDir": "../dist/out-tsc",
143167
"declaration": true,
144168
"types": ["node", "vite/client"]
145169
},
146-
"include": ["src/**/*.ts"],
147-
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]
170+
"include": ["src/**/*.ts"]
148171
}
149172
"
150173
`;
151174

152-
exports[`@nx/vite:configuration js library with --bundler=vite should respect unitTestRunner if passed 5`] = `
153-
"export default {
154-
displayName: 'my-lib',
155-
preset: '../jest.preset.js',
156-
transform: {
157-
'^.+\\\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
158-
},
159-
moduleFileExtensions: ['ts', 'js', 'html'],
160-
coverageDirectory: '../coverage/my-lib',
161-
};
162-
"
163-
`;
164-
165175
exports[`@nx/vite:configuration library mode should add config for building library 1`] = `
166176
"/// <reference types='vitest' />
167177
import { defineConfig } from 'vite';

packages/vite/src/generators/configuration/configuration.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ describe('@nx/vite:configuration', () => {
303303
${'none'} | ${undefined}
304304
${'jest'} | ${'my-lib/jest.config.ts'}
305305
`(
306-
'should respect unitTestRunner if passed',
306+
'should respect provided unitTestRunner="$unitTestRunner"',
307307
async ({ unitTestRunner, configPath }) => {
308308
await jsLibraryGenerator(tree, {
309309
...defaultOptions,

packages/vite/src/generators/vitest/schema.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ export interface VitestGeneratorSchema {
88
skipFormat?: boolean;
99
testEnvironment?: 'node' | 'jsdom' | 'happy-dom' | 'edge-runtime' | string;
1010
addPlugin?: boolean;
11+
runtimeTsconfigFileName?: string;
1112
}

packages/vite/src/generators/vitest/schema.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@
5050
"description": "The vitest environment to use. See https://vitest.dev/config/#environment.",
5151
"type": "string",
5252
"enum": ["node", "jsdom", "happy-dom", "edge-runtime"]
53+
},
54+
"runtimeTsconfigFileName": {
55+
"type": "string",
56+
"description": "The name of the project's tsconfig file that includes the runtime source files. If not provided, it will default to `tsconfig.lib.json` for libraries and `tsconfig.app.json` for applications."
5357
}
5458
},
5559
"required": ["project"]

0 commit comments

Comments
 (0)