Skip to content

Commit aaa6e65

Browse files
authored
feat(api): expose Vitest watcher (#8413)
1 parent fdeb2f4 commit aaa6e65

File tree

3 files changed

+24
-15
lines changed

3 files changed

+24
-15
lines changed

docs/advanced/api/vitest.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ You can get the latest summary of snapshots via the `vitest.snapshot.summary` pr
9999

100100
Cache manager that stores information about latest test results and test file stats. In Vitest itself this is only used by the default sequencer to sort tests.
101101

102+
## watcher <Version>4.0.0</Version> {#watcher}
103+
104+
The instance of a Vitest watcher with useful methods to track file changes and rerun tests. You can use `onFileChange`, `onFileDelete` or `onFileCreate` with your own watcher, if the built-in watcher is disabled.
105+
102106
## projects
103107

104108
An array of [test projects](/advanced/api/test-project) that belong to user's projects. If the user did not specify a them, this array will only contain a [root project](#getrootproject).

packages/vitest/src/node/core.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,14 @@ export class Vitest {
8484
* If projects were filtered with `--project` flag, they won't appear here.
8585
*/
8686
public projects: TestProject[] = []
87+
/**
88+
* A watcher handler. This is not the file system watcher. The handler only
89+
* exposes methods to handle changed files.
90+
*
91+
* If you have your own watcher, you can use these methods to replicate
92+
* Vitest behaviour.
93+
*/
94+
public readonly watcher: VitestWatcher
8795

8896
/** @internal */ configOverride: Partial<ResolvedConfig> = {}
8997
/** @internal */ coverageProvider: CoverageProvider | null | undefined
@@ -103,7 +111,6 @@ export class Vitest {
103111
private restartsCount = 0
104112

105113
private readonly specifications: VitestSpecifications
106-
private readonly watcher: VitestWatcher
107114
private pool: ProcessPool | undefined
108115
private _config?: ResolvedConfig
109116
private _vite?: ViteDevServer
@@ -121,7 +128,7 @@ export class Vitest {
121128
this.packageInstaller = options.packageInstaller || new VitestPackageInstaller()
122129
this.specifications = new VitestSpecifications(this)
123130
this.watcher = new VitestWatcher(this).onWatcherRerun(file =>
124-
this.scheduleRerun([file]), // TODO: error handling
131+
this.scheduleRerun(file), // TODO: error handling
125132
)
126133
}
127134

@@ -1013,8 +1020,7 @@ export class Vitest {
10131020
}
10141021

10151022
private _rerunTimer: any
1016-
// we can't use a single `triggerId` yet because vscode extension relies on this
1017-
private async scheduleRerun(triggerId: string[]): Promise<void> {
1023+
private async scheduleRerun(triggerId: string): Promise<void> {
10181024
const currentCount = this.restartsCount
10191025
clearTimeout(this._rerunTimer)
10201026
await this.runningPromise
@@ -1053,8 +1059,7 @@ export class Vitest {
10531059

10541060
this.watcher.changedTests.clear()
10551061

1056-
const triggerIds = new Set(triggerId.map(id => relative(this.config.root, id)))
1057-
const triggerLabel = Array.from(triggerIds).join(', ')
1062+
const triggerLabel = relative(this.config.root, triggerId)
10581063
// get file specifications and filter them if needed
10591064
const specifications = files.flatMap(file => this.getModuleSpecifications(file)).filter((specification) => {
10601065
if (this._onFilterWatchedSpecification.length === 0) {

packages/vitest/src/node/watcher.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,14 @@ export class VitestWatcher {
3838
watcher.add(this.vitest.config.forceRerunTriggers)
3939
}
4040

41-
watcher.on('change', this.onChange)
42-
watcher.on('unlink', this.onUnlink)
43-
watcher.on('add', this.onAdd)
41+
watcher.on('change', this.onFileChange)
42+
watcher.on('unlink', this.onFileDelete)
43+
watcher.on('add', this.onFileCreate)
4444

4545
this.unregisterWatcher = () => {
46-
watcher.off('change', this.onChange)
47-
watcher.off('unlink', this.onUnlink)
48-
watcher.off('add', this.onAdd)
46+
watcher.off('change', this.onFileChange)
47+
watcher.off('unlink', this.onFileDelete)
48+
watcher.off('add', this.onFileCreate)
4949
this.unregisterWatcher = noop
5050
}
5151
return this
@@ -77,7 +77,7 @@ export class VitestWatcher {
7777
return triggered
7878
}
7979

80-
private onChange = (id: string): void => {
80+
public onFileChange = (id: string): void => {
8181
id = slash(id)
8282
this.vitest.logger.clearHighlightCache(id)
8383
this.vitest.invalidateFile(id)
@@ -93,7 +93,7 @@ export class VitestWatcher {
9393
}
9494
}
9595

96-
private onUnlink = (id: string): void => {
96+
public onFileDelete = (id: string): void => {
9797
id = slash(id)
9898
this.vitest.logger.clearHighlightCache(id)
9999
this.invalidates.add(id)
@@ -108,7 +108,7 @@ export class VitestWatcher {
108108
}
109109
}
110110

111-
private onAdd = (id: string): void => {
111+
public onFileCreate = (id: string): void => {
112112
id = slash(id)
113113
this.vitest.invalidateFile(id)
114114

0 commit comments

Comments
 (0)