Skip to content

Commit 4e17942

Browse files
authoredFeb 10, 2024··
feat(vitest): add new CLI options (#5163)
1 parent e4e93df commit 4e17942

File tree

4 files changed

+143
-22
lines changed

4 files changed

+143
-22
lines changed
 

‎docs/config/index.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -965,21 +965,23 @@ Minimum number of workers to run tests in. `poolOptions.{threads,vmThreads}.minT
965965

966966
- **Type:** `number`
967967
- **Default:** `5000`
968-
- **CLI:** `--test-timeout=5000`
968+
- **CLI:** `--test-timeout=5000`, `--testTimeout=5000`
969969

970970
Default timeout of a test in milliseconds
971971

972972
### hookTimeout
973973

974974
- **Type:** `number`
975975
- **Default:** `10000`
976+
- **CLI:** `--hook-timeout=10000`, `--hookTimeout=10000`
976977

977978
Default timeout of a hook in milliseconds
978979

979980
### teardownTimeout<NonProjectOption />
980981

981982
- **Type:** `number`
982983
- **Default:** `10000`
984+
- **CLI:** `--teardown-timeout=5000`, `--teardownTimeout=5000`
983985

984986
Default timeout to wait for close when Vitest shuts down, in milliseconds
985987

@@ -1419,6 +1421,7 @@ See [istanbul documentation](https://github.com/istanbuljs/nyc#ignoring-methods)
14191421
```
14201422

14211423
- **Available for providers:** `'v8' | 'istanbul'`
1424+
- **CLI:** `--coverage.watermarks.statements=50,80`, `--coverage.watermarks.branches=50,80`
14221425

14231426
Watermarks for statements, lines, branches and functions. See [istanbul documentation](https://github.com/istanbuljs/nyc#high-and-low-watermarks) for more information.
14241427

@@ -1791,6 +1794,7 @@ By default, Vitest exports a proxy, bypassing CSS Modules processing. If you rel
17911794

17921795
- **Type**: `number`
17931796
- **Default**: `5`
1797+
- **CLI**: `--max-concurrency=10`, `--maxConcurrency=10`
17941798

17951799
A number of tests that are allowed to run at the same time marked with `test.concurrent`.
17961800

@@ -1799,13 +1803,15 @@ Test above this limit will be queued to run when available slot appears.
17991803
### cache<NonProjectOption />
18001804

18011805
- **Type**: `false | { dir? }`
1806+
- **CLI**: `--no-cache`, `--cache=false`
18021807

18031808
Options to configure Vitest cache policy. At the moment Vitest stores cache for test results to run the longer and failed tests first.
18041809

18051810
#### cache.dir
18061811

18071812
- **Type**: `string`
18081813
- **Default**: `node_modules/.vitest`
1814+
- **CLI**: `--cache.dir=./cache`
18091815

18101816
Path to cache directory.
18111817

@@ -1954,6 +1960,7 @@ Path to custom tsconfig, relative to the project root.
19541960

19551961
- **Type**: `number`
19561962
- **Default**: `300`
1963+
- **CLI**: `--slow-test-threshold=<number>`, `--slowTestThreshold=<number>`
19571964

19581965
The number of milliseconds after which a test is considered slow and reported as such in the results.
19591966

‎packages/vitest/src/node/cli/cac.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@ function addCommand(cli: CAC, name: string, option: CLIOption<any>) {
1717
command += ` ${option.argument}`
1818

1919
function transform(value: unknown) {
20-
if (!option.array && Array.isArray(value))
21-
throw new Error(`Expected a single value for option "${command}"`)
20+
if (!option.array && Array.isArray(value)) {
21+
const received = value.map(s => typeof s === 'string' ? `"${s}"` : s).join(', ')
22+
throw new Error(
23+
`Expected a single value for option "${command}", received [${received}]`,
24+
)
25+
}
2226
if (option.transform)
2327
return option.transform(value)
2428
if (option.array)

‎packages/vitest/src/node/cli/cli-config.ts

+66-17
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ const poolForksCommands: CLIOptions<ForksOptions & WorkerContextOptions> = {
8181
execArgv: null,
8282
}
8383

84+
function watermarkTransform(value: unknown) {
85+
if (typeof value === 'string')
86+
return value.split(',').map(Number)
87+
return value
88+
}
89+
8490
function transformNestedBoolean(value: unknown) {
8591
if (typeof value === 'boolean')
8692
return { enabled: value }
@@ -249,9 +255,32 @@ export const cliOptionsConfig: VitestCLIOptions = {
249255
argument: '<path>',
250256
normalize: true,
251257
},
252-
// TODO: suport watermarks via a special command?
253-
// CAC requires --watermarks.statements=50 --watermarks.statements=80 for "statements:[50,80]" which looks rediculous
254-
watermarks: null,
258+
watermarks: {
259+
description: null,
260+
argument: '', // no displayed
261+
subcommands: {
262+
statements: {
263+
description: 'High and low watermarks for statements in the format of <high>,<low>',
264+
argument: '<watermarks>',
265+
transform: watermarkTransform,
266+
},
267+
lines: {
268+
description: 'High and low watermarks for lines in the format of <high>,<low>',
269+
argument: '<watermarks>',
270+
transform: watermarkTransform,
271+
},
272+
branches: {
273+
description: 'High and low watermarks for branches in the format of <high>,<low>',
274+
argument: '<watermarks>',
275+
transform: watermarkTransform,
276+
},
277+
functions: {
278+
description: 'High and low watermarks for functions in the format of <high>,<low>',
279+
argument: '<watermarks>',
280+
transform: watermarkTransform,
281+
},
282+
},
283+
},
255284
},
256285
},
257286
mode: {
@@ -434,6 +463,10 @@ export const cliOptionsConfig: VitestCLIOptions = {
434463
description: 'Default timeout of a test in milliseconds (default: 5000)',
435464
argument: '<timeout>',
436465
},
466+
hookTimeout: {
467+
description: 'Default hook timeout in milliseconds (default: 10000)',
468+
argument: '<timeout>',
469+
},
437470
bail: {
438471
description: 'Stop test execution when given number of tests have failed (default: 0)',
439472
argument: '<number>',
@@ -492,14 +525,35 @@ export const cliOptionsConfig: VitestCLIOptions = {
492525
description: 'The name of the project to run if you are using Vitest workspace feature. This can be repeated for multiple projects: --project=1 --project=2',
493526
argument: '<name>',
494527
},
495-
// slowTestThreshold: {
496-
// description: 'Threshold in milliseconds for a test to be considered slow (default: 300)',
497-
// argument: '<threshold>',
498-
// },
499-
// teardownTimeout: {
500-
// description: 'Default timeout of a teardown function in milliseconds (default: 10000)',
501-
// argument: '<timeout>',
502-
// },
528+
slowTestThreshold: {
529+
description: 'Threshold in milliseconds for a test to be considered slow (default: 300)',
530+
argument: '<threshold>',
531+
},
532+
teardownTimeout: {
533+
description: 'Default timeout of a teardown function in milliseconds (default: 10000)',
534+
argument: '<timeout>',
535+
},
536+
cache: {
537+
description: 'Enable cache',
538+
argument: '', // allow only boolean
539+
subcommands: {
540+
dir: {
541+
description: 'Path to the cache directory',
542+
argument: '<path>',
543+
normalize: true,
544+
},
545+
},
546+
// cache can only be "false" or an object
547+
transform(cache) {
548+
if (cache)
549+
return {}
550+
return cache
551+
},
552+
},
553+
maxConcurrency: {
554+
description: 'Maximum number of concurrent tests in a suite (default: 5)',
555+
argument: '<number>',
556+
},
503557

504558
// CLI only options
505559
run: {
@@ -537,18 +591,13 @@ export const cliOptionsConfig: VitestCLIOptions = {
537591
unstubGlobals: null,
538592
uiBase: null,
539593
benchmark: null,
540-
name: null,
541594
include: null,
542595
testTransformMode: null,
543-
hookTimeout: null,
544596
fakeTimers: null,
545-
cache: null,
546597
chaiConfig: null,
547598
clearMocks: null,
548599
css: null,
549-
maxConcurrency: null,
550600
poolMatchGlobs: null,
551601
deps: null,
552-
slowTestThreshold: null,
553-
teardownTimeout: null,
602+
name: null,
554603
}

‎test/core/test/cli-test.test.ts

+63-2
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ test('nested coverage options have correct types', async () => {
6262
--coverage.thresholds.lines 100
6363
--coverage.thresholds.functions 30
6464
--coverage.thresholds.branches 25
65+
66+
--coverage.watermarks.statements 50,80
67+
--coverage.watermarks.lines=30,40
68+
--coverage.watermarks.branches=70,80
69+
--coverage.watermarks.functions 20,60
6570
`).coverage).toEqual({
6671
enabled: true,
6772
reporter: ['text'],
@@ -85,6 +90,12 @@ test('nested coverage options have correct types', async () => {
8590
autoUpdate: true,
8691
100: true,
8792
},
93+
watermarks: {
94+
statements: [50, 80],
95+
lines: [30, 40],
96+
branches: [70, 80],
97+
functions: [20, 60],
98+
},
8899
})
89100
})
90101

@@ -110,7 +121,7 @@ test('all coverage enable options are working correctly', () => {
110121

111122
test('fails when an array is passed down for a single value', async () => {
112123
expect(() => parseArguments('--coverage.provider v8 --coverage.provider istanbul'))
113-
.toThrowErrorMatchingInlineSnapshot(`[Error: Expected a single value for option "--coverage.provider <name>"]`)
124+
.toThrowErrorMatchingInlineSnapshot(`[Error: Expected a single value for option "--coverage.provider <name>", received ["v8", "istanbul"]]`)
114125
})
115126

116127
test('even if coverage is boolean, don\'t fail', () => {
@@ -137,7 +148,14 @@ test('array options', () => {
137148
}
138149
`)
139150

140-
expect(parseArguments('--reporter json --reporter=default --coverage.reporter=json --coverage.reporter html --coverage.extension=ts --coverage.extension=tsx')).toMatchInlineSnapshot(`
151+
expect(parseArguments(`
152+
--reporter json
153+
--reporter=default
154+
--coverage.reporter=json
155+
--coverage.reporter html
156+
--coverage.extension=ts
157+
--coverage.extension=tsx
158+
`)).toMatchInlineSnapshot(`
141159
{
142160
"coverage": {
143161
"extension": [
@@ -156,3 +174,46 @@ test('array options', () => {
156174
}
157175
`)
158176
})
177+
178+
test('hookTimeout is parsed correctly', () => {
179+
expect(parseArguments('--hookTimeout 1000')).toEqual({ hookTimeout: 1000 })
180+
expect(parseArguments('--hook-timeout 1000')).toEqual({ hookTimeout: 1000 })
181+
expect(parseArguments('--hook-timeout=1000')).toEqual({ hookTimeout: 1000 })
182+
expect(parseArguments('--hookTimeout=1000')).toEqual({ hookTimeout: 1000 })
183+
})
184+
185+
test('teardownTimeout is parsed correctly', () => {
186+
expect(parseArguments('--teardownTimeout 1000')).toEqual({ teardownTimeout: 1000 })
187+
expect(parseArguments('--teardown-timeout 1000')).toEqual({ teardownTimeout: 1000 })
188+
expect(parseArguments('--teardownTimeout=1000')).toEqual({ teardownTimeout: 1000 })
189+
expect(parseArguments('--teardown-timeout=1000')).toEqual({ teardownTimeout: 1000 })
190+
})
191+
192+
test('slowTestThreshold is parsed correctly', () => {
193+
expect(parseArguments('--slowTestThreshold 1000')).toEqual({ slowTestThreshold: 1000 })
194+
expect(parseArguments('--slow-test-threshold 1000')).toEqual({ slowTestThreshold: 1000 })
195+
expect(parseArguments('--slowTestThreshold=1000')).toEqual({ slowTestThreshold: 1000 })
196+
expect(parseArguments('--slow-test-threshold=1000')).toEqual({ slowTestThreshold: 1000 })
197+
})
198+
199+
test('maxConcurrency is parsed correctly', () => {
200+
expect(parseArguments('--maxConcurrency 1000')).toEqual({ maxConcurrency: 1000 })
201+
expect(parseArguments('--max-concurrency 1000')).toEqual({ maxConcurrency: 1000 })
202+
expect(parseArguments('--maxConcurrency=1000')).toEqual({ maxConcurrency: 1000 })
203+
expect(parseArguments('--max-concurrency=1000')).toEqual({ maxConcurrency: 1000 })
204+
})
205+
206+
test('cache is parsed correctly', () => {
207+
expect(parseArguments('--cache')).toEqual({ cache: {} })
208+
expect(parseArguments('--no-cache')).toEqual({ cache: false })
209+
210+
expect(parseArguments('--cache.dir=./test/cache.json')).toEqual({
211+
cache: { dir: 'test/cache.json' },
212+
})
213+
expect(parseArguments('--cache.dir ./test/cache.json')).toEqual({
214+
cache: { dir: 'test/cache.json' },
215+
})
216+
expect(parseArguments('--cache.dir .\\test\\cache.json')).toEqual({
217+
cache: { dir: 'test/cache.json' },
218+
})
219+
})

0 commit comments

Comments
 (0)
Please sign in to comment.