@naturalcycles/dev-lib 20.64.0 → 20.65.1
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 +119 -108
- 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
|
@@ -9,7 +9,7 @@ export { CollectReporter } from './collectReporter.js'
|
|
|
9
9
|
|
|
10
10
|
const runsInIDE = doesItRunInIDE()
|
|
11
11
|
const testType = getTestType(runsInIDE)
|
|
12
|
-
const silent =
|
|
12
|
+
const silent = getSilent(runsInIDE)
|
|
13
13
|
const { include, exclude } = getIncludeAndExclude(testType)
|
|
14
14
|
const isCI = !!process.env.CI
|
|
15
15
|
const coverageEnabled = isCI && testType === 'unit'
|
|
@@ -27,6 +27,9 @@ if (testType === 'unit') {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
if (silent) {
|
|
30
|
+
// Tells the tests that vitest is suppressing console output, so they keep the output vitest
|
|
31
|
+
// can't intercept quiet too: child process stdio (see exec2.test.ts) and dev-lib's testLogger,
|
|
32
|
+
// which writes to process.stdout directly.
|
|
30
33
|
process.env.TEST_SILENT = 'true'
|
|
31
34
|
}
|
|
32
35
|
|
|
@@ -37,6 +40,9 @@ if (silent) {
|
|
|
37
40
|
* // overrides here, e.g:
|
|
38
41
|
* // bail: 1,
|
|
39
42
|
* })
|
|
43
|
+
*
|
|
44
|
+
* In a monorepo: use it in the vitest.config.ts of each package (passing `import.meta.dirname`
|
|
45
|
+
* as cwd), and defineVitestMonorepoConfig in the root vitest.config.ts.
|
|
40
46
|
*/
|
|
41
47
|
export function defineVitestConfig(config, cwd) {
|
|
42
48
|
const mergedConfig = defineConfig({
|
|
@@ -67,26 +73,84 @@ export function defineVitestConfig(config, cwd) {
|
|
|
67
73
|
}
|
|
68
74
|
|
|
69
75
|
/**
|
|
70
|
-
*
|
|
76
|
+
* Use it in the ROOT vitest.config.ts of a monorepo (Vitest `projects` mode):
|
|
77
|
+
*
|
|
78
|
+
* export default defineVitestMonorepoConfig({
|
|
79
|
+
* test: {
|
|
80
|
+
* projects: ['./packages/*'],
|
|
81
|
+
* // overrides here, e.g:
|
|
82
|
+
* // coverage: { enabled: false },
|
|
83
|
+
* },
|
|
84
|
+
* })
|
|
85
|
+
*
|
|
86
|
+
* In `projects` mode Vitest has two kinds of config: the root config (this one) and the
|
|
87
|
+
* per-project configs (defineVitestConfig in each package). A set of options is root-only:
|
|
88
|
+
* Vitest reads them from the root config only and silently IGNORES the per-project values
|
|
89
|
+
* (see `NonProjectOptions` in Vitest's types): `reporters`, `outputFile`, `coverage`, `silent`,
|
|
90
|
+
* `watch`, `slowTestThreshold`, `sequence.sequencer`, etc.
|
|
91
|
+
*
|
|
92
|
+
* This helper sets the root-only part of the shared config (see getRootConfig) on the root
|
|
93
|
+
* config, where it takes effect. So the junit/json/coverage reports are written, the
|
|
94
|
+
* SummaryReporter reports the slowest tests across ALL projects, and the
|
|
95
|
+
* VitestAlphabeticSequencer is actually used, monorepo-wide.
|
|
96
|
+
*/
|
|
97
|
+
export function defineVitestMonorepoConfig(config) {
|
|
98
|
+
return defineConfig({
|
|
99
|
+
...config,
|
|
100
|
+
test: {
|
|
101
|
+
...getRootConfig(),
|
|
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
|
+
// Per-project options
|
|
74
118
|
pool,
|
|
75
119
|
maxWorkers,
|
|
76
120
|
isolate: false,
|
|
77
|
-
watch: false,
|
|
78
121
|
// dir: 'src',
|
|
79
122
|
restoreMocks: true,
|
|
80
123
|
// restoreMocks does not cover vi.stubEnv/vi.stubGlobal
|
|
81
124
|
unstubEnvs: true,
|
|
82
125
|
unstubGlobals: true,
|
|
83
|
-
silent,
|
|
84
126
|
setupFiles: getSetupFiles(testType, cwd),
|
|
85
127
|
logHeapUsage: true,
|
|
86
128
|
testTimeout: 60_000,
|
|
87
129
|
hookTimeout: 60_000,
|
|
88
|
-
slowTestThreshold: isCI ? 500 : 300, // higher threshold in CI
|
|
89
130
|
injectCjsGlobals: false,
|
|
131
|
+
deps: {
|
|
132
|
+
// Disable CJS/ESM interop to match production Node.js behavior.
|
|
133
|
+
// Without this, vitest auto-promotes default exports to named exports,
|
|
134
|
+
// which can mask import bugs (e.g., ejs v4 renderFile issue).
|
|
135
|
+
// Vitest's own default is `true`.
|
|
136
|
+
interopDefault: false,
|
|
137
|
+
},
|
|
138
|
+
include,
|
|
139
|
+
exclude,
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* The root-only subset of the shared config: the options Vitest reads from the root config
|
|
145
|
+
* only (`NonProjectOptions` in Vitest's types, plus `sequence.sequencer`), hence the ones that
|
|
146
|
+
* must be set on the root config of a monorepo to take effect there. Shared by getSharedConfig
|
|
147
|
+
* (where they apply in a single-package repo) and defineVitestMonorepoConfig.
|
|
148
|
+
*/
|
|
149
|
+
function getRootConfig() {
|
|
150
|
+
return {
|
|
151
|
+
watch: false,
|
|
152
|
+
silent,
|
|
153
|
+
slowTestThreshold: isCI ? 500 : 300, // higher threshold in CI
|
|
90
154
|
sequence: {
|
|
91
155
|
sequencer: VitestAlphabeticSequencer,
|
|
92
156
|
// shuffle: {
|
|
@@ -95,46 +159,46 @@ export function getSharedConfig(cwd) {
|
|
|
95
159
|
// },
|
|
96
160
|
// seed: 1, // this makes the order of tests deterministic (but still not alphabetic)
|
|
97
161
|
},
|
|
98
|
-
include,
|
|
99
|
-
exclude,
|
|
100
162
|
reporters: getReporters(junitReporterEnabled, testType),
|
|
101
163
|
outputFile: getOutputFile(),
|
|
102
164
|
coverage: getCoverageConfig(),
|
|
103
165
|
}
|
|
104
166
|
}
|
|
105
167
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
168
|
+
/**
|
|
169
|
+
* @deprecated Use defineVitestMonorepoConfig for the monorepo root config instead. It sets
|
|
170
|
+
* `reporters` together with all the other root-only options (see getRootConfig).
|
|
171
|
+
*/
|
|
172
|
+
export function getRootReporters() {
|
|
173
|
+
return getReporters(junitReporterEnabled, testType)
|
|
174
|
+
}
|
|
109
175
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
].filter(Boolean)
|
|
176
|
+
/**
|
|
177
|
+
* @deprecated Use defineVitestMonorepoConfig for the monorepo root config instead. It sets
|
|
178
|
+
* `outputFile` together with all the other root-only options (see getRootConfig).
|
|
179
|
+
*/
|
|
180
|
+
export function getRootOutputFile() {
|
|
181
|
+
return getOutputFile()
|
|
117
182
|
}
|
|
118
183
|
|
|
119
184
|
/**
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
*
|
|
185
|
+
* @deprecated Use defineVitestMonorepoConfig for the monorepo root config instead. It sets
|
|
186
|
+
* `coverage` together with all the other root-only options (see getRootConfig).
|
|
187
|
+
*/
|
|
188
|
+
export function getRootCoverage() {
|
|
189
|
+
return getCoverageConfig()
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* The reporters, shared by the per-package (getSharedConfig) and the monorepo root
|
|
194
|
+
* (defineVitestMonorepoConfig) configs.
|
|
129
195
|
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* },
|
|
135
|
-
* })
|
|
196
|
+
* In a monorepo (`projects` mode) `reporters` is root-only: per-project reporters are ignored.
|
|
197
|
+
* So the per-package SummaryReporter never runs in the aggregate root run, and - crucially -
|
|
198
|
+
* a root-level SummaryReporter sees the test modules of ALL projects at once, letting it report
|
|
199
|
+
* the slowest tests across the entire monorepo.
|
|
136
200
|
*/
|
|
137
|
-
|
|
201
|
+
function getReporters(junitReporterEnabled, testType) {
|
|
138
202
|
const override = getReporterOverride()
|
|
139
203
|
if (override) return override
|
|
140
204
|
|
|
@@ -148,60 +212,19 @@ export function getRootReporters() {
|
|
|
148
212
|
}
|
|
149
213
|
|
|
150
214
|
/**
|
|
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).
|
|
215
|
+
* The coverage config, shared by the per-package (getSharedConfig) and the monorepo root
|
|
216
|
+
* (defineVitestMonorepoConfig) configs. Only enabled for CI unit-test runs.
|
|
174
217
|
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
* getSharedConfig is IGNORED when running via `projects`. Without this on the
|
|
218
|
+
* In a monorepo (`projects` mode) `coverage` is root-only: it is read from the root project
|
|
219
|
+
* only (see Vitest's `getRootProject().serializedConfig.coverage`), so the per-package
|
|
220
|
+
* `coverage` set in getSharedConfig is IGNORED when running via `projects`. Without it on the
|
|
179
221
|
* root config no coverage report is produced at all (e.g. the CI upload of
|
|
180
222
|
* ./coverage/coverage-summary.json finds nothing).
|
|
181
223
|
*
|
|
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.
|
|
224
|
+
* The report is a single, unified one spanning all projects: Vitest tracks coverage per-project
|
|
225
|
+
* internally but emits one report under `./coverage`. Per-project coverage `include` globs are
|
|
226
|
+
* matched unanchored against absolute paths, so executed files under `packages/<pkg>/src/**`
|
|
227
|
+
* are still included.
|
|
205
228
|
*/
|
|
206
229
|
function getCoverageConfig() {
|
|
207
230
|
return {
|
|
@@ -240,7 +263,7 @@ function getCoverageConfig() {
|
|
|
240
263
|
|
|
241
264
|
/**
|
|
242
265
|
* The junit + json reporters, enabled in CI (except for manual tests).
|
|
243
|
-
*
|
|
266
|
+
* Used (via getReporters) by both the per-package and the monorepo root configs.
|
|
244
267
|
*/
|
|
245
268
|
function getJunitReporters(junitReporterEnabled, testType) {
|
|
246
269
|
if (!junitReporterEnabled) return []
|
|
@@ -310,32 +333,20 @@ function getTestType(runsInIDE) {
|
|
|
310
333
|
return process.env.TEST_TYPE || 'unit'
|
|
311
334
|
}
|
|
312
335
|
|
|
313
|
-
function shouldBeSilent(runsInIDE) {
|
|
314
|
-
if (runsInIDE) {
|
|
315
|
-
return false
|
|
316
|
-
}
|
|
317
|
-
return isRunningAllTests()
|
|
318
|
-
}
|
|
319
|
-
|
|
320
336
|
/**
|
|
321
|
-
*
|
|
337
|
+
* Console output of failed tests only, in every CLI run - whether it runs all tests or a single
|
|
338
|
+
* file. Pass `--silent=false` to see the output of passing tests too.
|
|
339
|
+
* In the IDE everything is printed, as IDE runs are interactive debugging.
|
|
322
340
|
*/
|
|
323
|
-
function
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
if (!a.startsWith('-')) {
|
|
333
|
-
hasPositionalArgs = true
|
|
334
|
-
}
|
|
335
|
-
})
|
|
336
|
-
// console.log({vitestArg, hasPositionalArgs}, process.argv)
|
|
337
|
-
|
|
338
|
-
return !hasPositionalArgs
|
|
341
|
+
function getSilent(runsInIDE) {
|
|
342
|
+
if (runsInIDE) return false
|
|
343
|
+
// Vitest applies `--silent=false` to `silent` by itself; mirroring it here keeps TEST_SILENT
|
|
344
|
+
// (see above) in sync, so the output vitest can't intercept is shown as well.
|
|
345
|
+
const silentFalse = process.argv.some(
|
|
346
|
+
(a, i) => a === '--silent=false' || (a === '--silent' && process.argv[i + 1] === 'false'),
|
|
347
|
+
)
|
|
348
|
+
if (silentFalse) return false
|
|
349
|
+
return 'passed-only'
|
|
339
350
|
}
|
|
340
351
|
|
|
341
352
|
function getSetupFiles(testType, cwd = process.cwd()) {
|