Skip to content

Commit a1aadd7

Browse files
authored
feat(vitest): run typecheck during tests (#4324)
1 parent df4606d commit a1aadd7

File tree

32 files changed

+330
-148
lines changed

32 files changed

+330
-148
lines changed

docs/advanced/api.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ Vitest instance requires the current test mode. It can be either:
5252
5353
- `test` when running runtime tests
5454
- `benchmark` when running benchmarks
55-
- `typecheck` when running type tests
5655
5756
### mode
5857
@@ -64,10 +63,6 @@ Test mode will only call functions inside `test` or `it`, and throws an error wh
6463
6564
Benchmark mode calls `bench` functions and throws an error, when it encounters `test` or `it`. This mode uses `benchmark.include` and `benchmark.exclude` options in the config to find benchmark files.
6665
67-
#### typecheck
68-
69-
Typecheck mode doesn't _run_ tests. It only analyses types and gives a summary. This mode uses `typecheck.include` and `typecheck.exclude` options in the config to find files to analyze.
70-
7166
### start
7267
7368
You can start running tests or benchmarks with `start` method. You can pass an array of strings to filter test files.

docs/config/index.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ export default defineConfig({
547547

548548
### poolMatchGlobs
549549

550-
- **Type:** `[string, 'threads' | 'forks' | 'vmThreads'][]`
550+
- **Type:** `[string, 'threads' | 'forks' | 'vmThreads' | 'typescript'][]`
551551
- **Default:** `[]`
552552
- **Version:** Since Vitest 0.29.4
553553

@@ -1637,6 +1637,24 @@ Changes the order in which setup files are executed.
16371637

16381638
Options for configuring [typechecking](/guide/testing-types) test environment.
16391639

1640+
#### typecheck.enabled
1641+
1642+
- **Type**: `boolean`
1643+
- **Default**: `false`
1644+
- **CLI**: `--typecheck`, `--typecheck.enabled`
1645+
- **Version**: Since Vitest 1.0.0-beta.3
1646+
1647+
Enable typechecking alongside your regular tests.
1648+
1649+
#### typecheck.only
1650+
1651+
- **Type**: `boolean`
1652+
- **Default**: `false`
1653+
- **CLI**: `--typecheck.only`
1654+
- **Version**: Since Vitest 1.0.0-beta.3
1655+
1656+
Run only typecheck tests, when typechecking is enabled. When using CLI, this option will automatically enable typechecking.
1657+
16401658
#### typecheck.checker
16411659

16421660
- **Type**: `'tsc' | 'vue-tsc' | string`

docs/guide/cli.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ Run only [benchmark](https://vitest.dev/guide/features.html#benchmarking-experim
9696
| `--inspect-brk` | Enables Node.js inspector with break |
9797
| `--bail <number>` | Stop test execution when given number of tests have failed |
9898
| `--retry <times>` | Retry the test specific number of times if it fails |
99+
| `--typecheck [options]` | Custom options for typecheck pool. If passed without options, enables typechecking |
100+
| `--typecheck.enabled` | Enable typechecking alongside tests (default: `false`) |
101+
| `--typecheck.only` | Run only typecheck tests. This automatically enables typecheck (default: `false`) |
99102
| `-h, --help` | Display available CLI options |
100103

101104
::: tip

docs/guide/testing-types.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,12 @@ assertType<string>(answr) //
6666

6767
## Run typechecking
6868

69-
Add this command to your `scripts` section in `package.json`:
69+
To enabled typechecking, just add `--typecheck` flag to your Vitest command in `package.json`:
7070

7171
```json
7272
{
7373
"scripts": {
74-
"typecheck": "vitest typecheck"
74+
"test": "vitest --typecheck"
7575
}
7676
}
7777
```
@@ -80,13 +80,13 @@ Now you can run typecheck:
8080

8181
```sh
8282
# npm
83-
npm run typecheck
83+
npm run test
8484

8585
# yarn
86-
yarn typecheck
86+
yarn test
8787

8888
# pnpm
89-
pnpm run typecheck
89+
pnpm run test
9090
```
9191

9292
Vitest uses `tsc --noEmit` or `vue-tsc --noEmit`, depending on your configuration, so you can remove these scripts from your pipeline.

packages/runner/src/utils/tasks.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ function isAtomTest(s: Task): s is Test | Custom {
77

88
export function getTests(suite: Arrayable<Task>): (Test | Custom)[] {
99
const tests: (Test | Custom)[] = []
10-
const suite_arr = toArray(suite)
11-
for (const s of suite_arr) {
10+
const arraySuites = toArray(suite)
11+
for (const s of arraySuites) {
1212
if (isAtomTest(s)) {
1313
tests.push(s)
1414
}

packages/ui/client/components/Suites.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ async function onRunCurrent() {
2323
<TasksList :tasks="current.tasks" :nested="true">
2424
<template #header>
2525
<StatusIcon mx-1 :task="current" />
26+
<div v-if="current.type === 'suite' && current.meta.typecheck" i-logos:typescript-icon flex-shrink-0 mr-1 />
2627
<span data-testid="filenames" font-bold text-sm flex-auto ws-nowrap overflow-hidden truncate>{{ name }}</span>
2728
<div class="flex text-lg">
2829
<IconButton

packages/ui/client/components/TaskItem.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const duration = computed(() => {
2222
hover="bg-active"
2323
>
2424
<StatusIcon :task="task" mr-2 />
25+
<div v-if="task.type === 'suite' && task.meta.typecheck" i-logos:typescript-icon flex-shrink-0 mr-2 />
2526
<div flex items-end gap-2 :text="task?.result?.state === 'fail' ? 'red-500' : ''">
2627
<span text-sm truncate font-light>{{ task.name }}</span>
2728
<span v-if="typeof duration === 'number'" text="xs" op20 style="white-space: nowrap">

packages/ui/client/components/views/ViewEditor.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ function createErrorElement(e: ErrorWithDiff) {
7272
div.className = 'op80 flex gap-x-2 items-center'
7373
const pre = document.createElement('pre')
7474
pre.className = 'c-red-600 dark:c-red-400'
75-
pre.textContent = `${' '.repeat(stack.column)}^ ${e?.nameStr}: ${e?.message}`
75+
pre.textContent = `${' '.repeat(stack.column)}^ ${e?.nameStr || e.name}: ${e?.message || ''}`
7676
div.appendChild(pre)
7777
const span = document.createElement('span')
7878
span.className = 'i-carbon-launch c-red-600 dark:c-red-400 hover:cursor-pointer min-w-1em min-h-1em'

packages/ui/client/composables/summary.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { hasFailedSnapshot } from '@vitest/ws-client'
2-
import type { Benchmark, Task, Test, TypeCheck } from 'vitest/src'
2+
import type { Custom, Task, Test } from 'vitest/src'
33
import { files, testRunState } from '~/composables/client'
44

55
type Nullable<T> = T | null | undefined
@@ -33,7 +33,7 @@ export const testsSkipped = computed(() => testsIgnore.value.filter(f => f.mode
3333
export const testsTodo = computed(() => testsIgnore.value.filter(f => f.mode === 'todo'))
3434
export const totalTests = computed(() => testsFailed.value.length + testsSuccess.value.length)
3535
export const time = computed(() => {
36-
const t = getTests(tests.value).reduce((acc, t) => {
36+
const t = files.value.reduce((acc, t) => {
3737
acc += Math.max(0, t.collectDuration || 0)
3838
acc += Math.max(0, t.setupDuration || 0)
3939
acc += Math.max(0, t.result?.duration || 0)
@@ -53,10 +53,25 @@ function toArray<T>(array?: Nullable<Arrayable<T>>): Array<T> {
5353
return [array]
5454
}
5555

56-
function isAtomTest(s: Task): s is Test | Benchmark | TypeCheck {
57-
return (s.type === 'test' || s.type === 'benchmark' || s.type === 'typecheck')
56+
function isAtomTest(s: Task): s is Test | Custom {
57+
return (s.type === 'test' || s.type === 'custom')
5858
}
5959

60-
function getTests(suite: Arrayable<Task>): (Test | Benchmark | TypeCheck)[] {
61-
return toArray(suite).flatMap(s => isAtomTest(s) ? [s] : s.tasks.flatMap(c => isAtomTest(c) ? [c] : getTests(c)))
60+
function getTests(suite: Arrayable<Task>): (Test | Custom)[] {
61+
const tests: (Test | Custom)[] = []
62+
const arraySuites = toArray(suite)
63+
for (const s of arraySuites) {
64+
if (isAtomTest(s)) {
65+
tests.push(s)
66+
}
67+
else {
68+
for (const task of s.tasks) {
69+
if (isAtomTest(task))
70+
tests.push(task)
71+
else
72+
tests.push(...getTests(task))
73+
}
74+
}
75+
}
76+
return tests
6277
}

packages/ui/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
},
5858
"devDependencies": {
5959
"@faker-js/faker": "^8.0.2",
60+
"@iconify-json/logos": "^1.1.37",
6061
"@testing-library/cypress": "^9.0.0",
6162
"@types/codemirror": "^5.60.8",
6263
"@types/d3-force": "^3.0.4",

0 commit comments

Comments
 (0)