diff --git a/packages/vitest/src/node/cli.ts b/packages/vitest/src/node/cli.ts index b970ab256..b546d599e 100644 --- a/packages/vitest/src/node/cli.ts +++ b/packages/vitest/src/node/cli.ts @@ -74,8 +74,16 @@ async function run(cliFilters: string[], options: UserConfig) { process.exit(1) } + ctx.onServerRestarted(() => { + ctx.start(cliFilters) + }) + try { await ctx.start(cliFilters) + + if (ctx.config.watch) + // never resolves to keep the process running + await new Promise(() => {}) } catch (e) { process.exitCode = 1 diff --git a/packages/vitest/src/node/index.ts b/packages/vitest/src/node/index.ts index c2e955f68..2b834b50e 100644 --- a/packages/vitest/src/node/index.ts +++ b/packages/vitest/src/node/index.ts @@ -30,11 +30,16 @@ class Vitest { runningPromise?: Promise isFirstRun = true + restartsCount = 0 + + private _onRestartListeners: Array<() => void> = [] + constructor() { this.console = globalThis.console } setServer(options: UserConfig, server: ViteDevServer) { + this.restartsCount += 1 this.pool?.close() this.pool = undefined @@ -52,6 +57,8 @@ class Vitest { this.registerWatcher() this.runningPromise = undefined + + this._onRestartListeners.forEach(fn => fn()) } async start(filters?: string[]) { @@ -64,11 +71,8 @@ class Vitest { await this.runFiles(files) - if (this.config.watch) { + if (this.config.watch) await this.report('onWatcherStart') - // never resolves to keep the process running - await new Promise(() => {}) - } } async runFiles(files: string[]) { @@ -96,15 +100,24 @@ class Vitest { private registerWatcher() { let timer: any - const scheduleRerun = async(id: string) => { + const scheduleRerun = async(id: string, count: number) => { await this.runningPromise clearTimeout(timer) + + // server restarted + if (this.restartsCount !== count) + return + timer = setTimeout(async() => { if (this.changedTests.size === 0) { this.invalidates.clear() return } + // server restarted + if (this.restartsCount !== count) + return + this.isFirstRun = false // add previously failed files @@ -128,7 +141,7 @@ class Vitest { id = slash(id) this.handleFileChanged(id) if (this.changedTests.size) - scheduleRerun(id) + scheduleRerun(id, this.restartsCount) }) this.server.watcher.on('unlink', (id) => { id = slash(id) @@ -143,7 +156,7 @@ class Vitest { id = slash(id) if (this.isTargetFile(id)) { this.changedTests.add(id) - scheduleRerun(id) + scheduleRerun(id, this.restartsCount) } }) } @@ -202,6 +215,10 @@ class Vitest { return false return mm.isMatch(id, this.config.include) } + + onServerRestarted(fn: () => void) { + this._onRestartListeners.push(fn) + } } export type { Vitest }