@naturalcycles/dev-lib 20.63.1 → 20.65.0
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/cfg/vitest.config.d.ts +23 -10
- package/cfg/vitest.config.js +108 -83
- package/dist/testing/testing.util.js +3 -7
- package/package.json +1 -1
package/cfg/vitest.config.d.ts
CHANGED
|
@@ -15,30 +15,43 @@ import type { InlineConfig } from 'vitest/node'
|
|
|
15
15
|
*/
|
|
16
16
|
export function defineVitestConfig(config?: Partial<ViteUserConfig>, cwd?: string): ViteUserConfig
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* For the ROOT vitest.config.ts of a monorepo (Vitest `projects` mode):
|
|
20
|
+
*
|
|
21
|
+
* export default defineVitestMonorepoConfig({
|
|
22
|
+
* test: {
|
|
23
|
+
* projects: ['./packages/*'],
|
|
24
|
+
* // overrides here, e.g:
|
|
25
|
+
* // coverage: { enabled: false },
|
|
26
|
+
* },
|
|
27
|
+
* })
|
|
28
|
+
*
|
|
29
|
+
* Sets the root-only options (reporters, outputFile, coverage, silent, watch,
|
|
30
|
+
* slowTestThreshold, sequence.sequencer), which Vitest reads from the root config only and
|
|
31
|
+
* ignores on the per-project configs (defineVitestConfig in each package).
|
|
32
|
+
*/
|
|
33
|
+
export function defineVitestMonorepoConfig(config: Partial<ViteUserConfig>): ViteUserConfig
|
|
34
|
+
|
|
18
35
|
/**
|
|
19
36
|
* Pass `import.meta.dirname` as cwd if running from a monorepo.
|
|
20
37
|
*/
|
|
21
38
|
export function getSharedConfig(cwd?: string): InlineConfig
|
|
22
39
|
|
|
23
40
|
/**
|
|
24
|
-
*
|
|
25
|
-
* `reporters`
|
|
26
|
-
* agents, otherwise the default reporters plus a monorepo-wide SummaryReporter.
|
|
41
|
+
* @deprecated Use defineVitestMonorepoConfig for the monorepo root config instead. It sets
|
|
42
|
+
* `reporters` together with all the other root-only options.
|
|
27
43
|
*/
|
|
28
44
|
export function getRootReporters(): InlineConfig['reporters']
|
|
29
45
|
|
|
30
46
|
/**
|
|
31
|
-
*
|
|
32
|
-
* `
|
|
33
|
-
* getRootReporters so the junit/json report is written in the aggregate root run.
|
|
47
|
+
* @deprecated Use defineVitestMonorepoConfig for the monorepo root config instead. It sets
|
|
48
|
+
* `outputFile` together with all the other root-only options.
|
|
34
49
|
*/
|
|
35
50
|
export function getRootOutputFile(): InlineConfig['outputFile']
|
|
36
51
|
|
|
37
52
|
/**
|
|
38
|
-
*
|
|
39
|
-
* `coverage`
|
|
40
|
-
* report is produced when running via `projects`. Produces a single unified
|
|
41
|
-
* report spanning all projects.
|
|
53
|
+
* @deprecated Use defineVitestMonorepoConfig for the monorepo root config instead. It sets
|
|
54
|
+
* `coverage` together with all the other root-only options.
|
|
42
55
|
*/
|
|
43
56
|
export function getRootCoverage(): InlineConfig['coverage']
|
|
44
57
|
|
package/cfg/vitest.config.js
CHANGED
|
@@ -37,6 +37,9 @@ if (silent) {
|
|
|
37
37
|
* // overrides here, e.g:
|
|
38
38
|
* // bail: 1,
|
|
39
39
|
* })
|
|
40
|
+
*
|
|
41
|
+
* In a monorepo: use it in the vitest.config.ts of each package (passing `import.meta.dirname`
|
|
42
|
+
* as cwd), and defineVitestMonorepoConfig in the root vitest.config.ts.
|
|
40
43
|
*/
|
|
41
44
|
export function defineVitestConfig(config, cwd) {
|
|
42
45
|
const mergedConfig = defineConfig({
|
|
@@ -67,26 +70,89 @@ export function defineVitestConfig(config, cwd) {
|
|
|
67
70
|
}
|
|
68
71
|
|
|
69
72
|
/**
|
|
70
|
-
*
|
|
73
|
+
* Use it in the ROOT vitest.config.ts of a monorepo (Vitest `projects` mode):
|
|
74
|
+
*
|
|
75
|
+
* export default defineVitestMonorepoConfig({
|
|
76
|
+
* test: {
|
|
77
|
+
* projects: ['./packages/*'],
|
|
78
|
+
* // overrides here, e.g:
|
|
79
|
+
* // coverage: { enabled: false },
|
|
80
|
+
* },
|
|
81
|
+
* })
|
|
82
|
+
*
|
|
83
|
+
* In `projects` mode Vitest has two kinds of config: the root config (this one) and the
|
|
84
|
+
* per-project configs (defineVitestConfig in each package). A set of options is root-only:
|
|
85
|
+
* Vitest reads them from the root config only and silently IGNORES the per-project values
|
|
86
|
+
* (see `NonProjectOptions` in Vitest's types): `reporters`, `outputFile`, `coverage`, `silent`,
|
|
87
|
+
* `watch`, `slowTestThreshold`, `sequence.sequencer`, etc.
|
|
88
|
+
*
|
|
89
|
+
* This helper sets the root-only part of the shared config (see getRootConfig) on the root
|
|
90
|
+
* config, where it takes effect. So the junit/json/coverage reports are written, the
|
|
91
|
+
* SummaryReporter reports the slowest tests across ALL projects, and the
|
|
92
|
+
* VitestAlphabeticSequencer is actually used, monorepo-wide.
|
|
93
|
+
*/
|
|
94
|
+
export function defineVitestMonorepoConfig(config) {
|
|
95
|
+
return defineConfig({
|
|
96
|
+
...config,
|
|
97
|
+
test: {
|
|
98
|
+
...getRootConfig(),
|
|
99
|
+
// Console output of failed tests only. Not the all-or-nothing boolean `silent` of
|
|
100
|
+
// getSharedConfig, which is kept there for backwards compatibility.
|
|
101
|
+
silent: 'passed-only',
|
|
102
|
+
...config?.test,
|
|
103
|
+
},
|
|
104
|
+
})
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Shared config for Vitest: for a single-package repo, or for one project (package) of a
|
|
109
|
+
* monorepo (pass `import.meta.dirname` as cwd).
|
|
71
110
|
*/
|
|
72
111
|
export function getSharedConfig(cwd) {
|
|
73
112
|
return {
|
|
113
|
+
// Root-only options. In a single-package repo this config IS the root, so they apply.
|
|
114
|
+
// In a monorepo they are IGNORED here (Vitest reads them from the root config only), so
|
|
115
|
+
// defineVitestMonorepoConfig sets them on the root config instead.
|
|
116
|
+
...getRootConfig(),
|
|
117
|
+
silent,
|
|
118
|
+
// Per-project options
|
|
74
119
|
pool,
|
|
75
120
|
maxWorkers,
|
|
76
121
|
isolate: false,
|
|
77
|
-
watch: false,
|
|
78
122
|
// dir: 'src',
|
|
79
123
|
restoreMocks: true,
|
|
80
124
|
// restoreMocks does not cover vi.stubEnv/vi.stubGlobal
|
|
81
125
|
unstubEnvs: true,
|
|
82
126
|
unstubGlobals: true,
|
|
83
|
-
silent,
|
|
84
127
|
setupFiles: getSetupFiles(testType, cwd),
|
|
85
128
|
logHeapUsage: true,
|
|
86
129
|
testTimeout: 60_000,
|
|
87
130
|
hookTimeout: 60_000,
|
|
88
|
-
slowTestThreshold: isCI ? 500 : 300, // higher threshold in CI
|
|
89
131
|
injectCjsGlobals: false,
|
|
132
|
+
deps: {
|
|
133
|
+
// Disable CJS/ESM interop to match production Node.js behavior.
|
|
134
|
+
// Without this, vitest auto-promotes default exports to named exports,
|
|
135
|
+
// which can mask import bugs (e.g., ejs v4 renderFile issue).
|
|
136
|
+
// Vitest's own default is `true`.
|
|
137
|
+
interopDefault: false,
|
|
138
|
+
},
|
|
139
|
+
include,
|
|
140
|
+
exclude,
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* The root-only subset of the shared config: the options Vitest reads from the root config
|
|
146
|
+
* only (`NonProjectOptions` in Vitest's types, plus `sequence.sequencer`), hence the ones that
|
|
147
|
+
* must be set on the root config of a monorepo to take effect there. Shared by getSharedConfig
|
|
148
|
+
* (where they apply in a single-package repo) and defineVitestMonorepoConfig.
|
|
149
|
+
*
|
|
150
|
+
* `silent` is root-only too, but is set by the callers, as they differ in it.
|
|
151
|
+
*/
|
|
152
|
+
function getRootConfig() {
|
|
153
|
+
return {
|
|
154
|
+
watch: false,
|
|
155
|
+
slowTestThreshold: isCI ? 500 : 300, // higher threshold in CI
|
|
90
156
|
sequence: {
|
|
91
157
|
sequencer: VitestAlphabeticSequencer,
|
|
92
158
|
// shuffle: {
|
|
@@ -95,46 +161,46 @@ export function getSharedConfig(cwd) {
|
|
|
95
161
|
// },
|
|
96
162
|
// seed: 1, // this makes the order of tests deterministic (but still not alphabetic)
|
|
97
163
|
},
|
|
98
|
-
include,
|
|
99
|
-
exclude,
|
|
100
164
|
reporters: getReporters(junitReporterEnabled, testType),
|
|
101
165
|
outputFile: getOutputFile(),
|
|
102
166
|
coverage: getCoverageConfig(),
|
|
103
167
|
}
|
|
104
168
|
}
|
|
105
169
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
170
|
+
/**
|
|
171
|
+
* @deprecated Use defineVitestMonorepoConfig for the monorepo root config instead. It sets
|
|
172
|
+
* `reporters` together with all the other root-only options (see getRootConfig).
|
|
173
|
+
*/
|
|
174
|
+
export function getRootReporters() {
|
|
175
|
+
return getReporters(junitReporterEnabled, testType)
|
|
176
|
+
}
|
|
109
177
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
].filter(Boolean)
|
|
178
|
+
/**
|
|
179
|
+
* @deprecated Use defineVitestMonorepoConfig for the monorepo root config instead. It sets
|
|
180
|
+
* `outputFile` together with all the other root-only options (see getRootConfig).
|
|
181
|
+
*/
|
|
182
|
+
export function getRootOutputFile() {
|
|
183
|
+
return getOutputFile()
|
|
117
184
|
}
|
|
118
185
|
|
|
119
186
|
/**
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
*
|
|
187
|
+
* @deprecated Use defineVitestMonorepoConfig for the monorepo root config instead. It sets
|
|
188
|
+
* `coverage` together with all the other root-only options (see getRootConfig).
|
|
189
|
+
*/
|
|
190
|
+
export function getRootCoverage() {
|
|
191
|
+
return getCoverageConfig()
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* The reporters, shared by the per-package (getSharedConfig) and the monorepo root
|
|
196
|
+
* (defineVitestMonorepoConfig) configs.
|
|
129
197
|
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* },
|
|
135
|
-
* })
|
|
198
|
+
* In a monorepo (`projects` mode) `reporters` is root-only: per-project reporters are ignored.
|
|
199
|
+
* So the per-package SummaryReporter never runs in the aggregate root run, and - crucially -
|
|
200
|
+
* a root-level SummaryReporter sees the test modules of ALL projects at once, letting it report
|
|
201
|
+
* the slowest tests across the entire monorepo.
|
|
136
202
|
*/
|
|
137
|
-
|
|
203
|
+
function getReporters(junitReporterEnabled, testType) {
|
|
138
204
|
const override = getReporterOverride()
|
|
139
205
|
if (override) return override
|
|
140
206
|
|
|
@@ -148,60 +214,19 @@ export function getRootReporters() {
|
|
|
148
214
|
}
|
|
149
215
|
|
|
150
216
|
/**
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
* Like `reporters`, `outputFile` is a root-only Vitest option: per-project
|
|
154
|
-
* `outputFile` is ignored when running via `projects`. So the root config must
|
|
155
|
-
* set it (alongside getRootReporters) for the junit/json report to be written
|
|
156
|
-
* in the aggregate root run.
|
|
157
|
-
*
|
|
158
|
-
* Use it in the root vitest.config.ts:
|
|
159
|
-
*
|
|
160
|
-
* export default defineConfig({
|
|
161
|
-
* test: {
|
|
162
|
-
* projects: ['./packages/*'],
|
|
163
|
-
* reporters: getRootReporters(),
|
|
164
|
-
* outputFile: getRootOutputFile(),
|
|
165
|
-
* },
|
|
166
|
-
* })
|
|
167
|
-
*/
|
|
168
|
-
export function getRootOutputFile() {
|
|
169
|
-
return getOutputFile()
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* `coverage` config for the monorepo root config (Vitest `projects` mode).
|
|
217
|
+
* The coverage config, shared by the per-package (getSharedConfig) and the monorepo root
|
|
218
|
+
* (defineVitestMonorepoConfig) configs. Only enabled for CI unit-test runs.
|
|
174
219
|
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
* getSharedConfig is IGNORED when running via `projects`. Without this on the
|
|
220
|
+
* In a monorepo (`projects` mode) `coverage` is root-only: it is read from the root project
|
|
221
|
+
* only (see Vitest's `getRootProject().serializedConfig.coverage`), so the per-package
|
|
222
|
+
* `coverage` set in getSharedConfig is IGNORED when running via `projects`. Without it on the
|
|
179
223
|
* root config no coverage report is produced at all (e.g. the CI upload of
|
|
180
224
|
* ./coverage/coverage-summary.json finds nothing).
|
|
181
225
|
*
|
|
182
|
-
* The report is a single, unified one spanning all projects: Vitest tracks
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
* Use it in the root vitest.config.ts:
|
|
188
|
-
*
|
|
189
|
-
* export default defineConfig({
|
|
190
|
-
* test: {
|
|
191
|
-
* projects: ['./packages/*'],
|
|
192
|
-
* reporters: getRootReporters(),
|
|
193
|
-
* outputFile: getRootOutputFile(),
|
|
194
|
-
* coverage: getRootCoverage(),
|
|
195
|
-
* },
|
|
196
|
-
* })
|
|
197
|
-
*/
|
|
198
|
-
export function getRootCoverage() {
|
|
199
|
-
return getCoverageConfig()
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* The coverage config, shared by the per-package (getSharedConfig) and root
|
|
204
|
-
* (getRootCoverage) configs. Only enabled for CI unit-test runs.
|
|
226
|
+
* The report is a single, unified one spanning all projects: Vitest tracks coverage per-project
|
|
227
|
+
* internally but emits one report under `./coverage`. Per-project coverage `include` globs are
|
|
228
|
+
* matched unanchored against absolute paths, so executed files under `packages/<pkg>/src/**`
|
|
229
|
+
* are still included.
|
|
205
230
|
*/
|
|
206
231
|
function getCoverageConfig() {
|
|
207
232
|
return {
|
|
@@ -240,7 +265,7 @@ function getCoverageConfig() {
|
|
|
240
265
|
|
|
241
266
|
/**
|
|
242
267
|
* The junit + json reporters, enabled in CI (except for manual tests).
|
|
243
|
-
*
|
|
268
|
+
* Used (via getReporters) by both the per-package and the monorepo root configs.
|
|
244
269
|
*/
|
|
245
270
|
function getJunitReporters(junitReporterEnabled, testType) {
|
|
246
271
|
if (!junitReporterEnabled) return []
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { commonLoggerCreate } from '@naturalcycles/js-lib/log';
|
|
2
|
-
import {
|
|
2
|
+
import { logEntryToString } from '@naturalcycles/nodejs-lib';
|
|
3
3
|
export function silentConsole() {
|
|
4
4
|
console.log = () => { };
|
|
5
5
|
console.debug = () => { };
|
|
@@ -9,13 +9,9 @@ export function silentConsole() {
|
|
|
9
9
|
console.time = () => { };
|
|
10
10
|
console.table = () => { };
|
|
11
11
|
}
|
|
12
|
-
export const testLogger = commonLoggerCreate(
|
|
12
|
+
export const testLogger = commonLoggerCreate(entry => {
|
|
13
13
|
if (process.env['TEST_SILENT'])
|
|
14
14
|
return; // no-op
|
|
15
|
-
process.stdout.write(
|
|
16
|
-
.map(a => _inspect(a, {
|
|
17
|
-
includeErrorStack: true,
|
|
18
|
-
}))
|
|
19
|
-
.join(' ') + '\n');
|
|
15
|
+
process.stdout.write(logEntryToString(entry) + '\n');
|
|
20
16
|
});
|
|
21
17
|
export const testLog = testLogger.log.bind(testLogger);
|