diff --git a/package.json b/package.json index 0a8fcc8d..ae33ad99 100644 --- a/package.json +++ b/package.json @@ -231,5 +231,10 @@ "*.{js,ts,tsx,vue,md}": [ "eslint --fix" ] + }, + "pnpm": { + "patchedDependencies": { + "birpc@0.2.17": "patches/birpc@0.2.17.patch" + } } } diff --git a/patches/birpc@0.2.17.patch b/patches/birpc@0.2.17.patch new file mode 100644 index 00000000..65ff5ee2 --- /dev/null +++ b/patches/birpc@0.2.17.patch @@ -0,0 +1,13 @@ +diff --git a/dist/index.mjs b/dist/index.mjs +index 8396fdbfbd7e1df8935c0806af9e7b31f8ccc261..7fcc87a89d7ca21cbf3a3e97ddedec0c51a7ef2a 100644 +--- a/dist/index.mjs ++++ b/dist/index.mjs +@@ -66,7 +66,7 @@ function createBirpc(functions, options) { + error = new Error(`[birpc] function "${method}" not found`); + } else { + try { +- result = await fn.apply(rpc, args); ++ result = await fn.apply(functions, args); + } catch (e) { + error = e; + } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 612d653b..a57eb15d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,11 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +patchedDependencies: + birpc@0.2.17: + hash: 76ascauag252sgpxpwh3k26eya + path: patches/birpc@0.2.17.patch + devDependencies: '@antfu/eslint-config': specifier: ^2.6.4 @@ -67,7 +72,7 @@ devDependencies: version: 3.4.19 birpc: specifier: ^0.2.17 - version: 0.2.17 + version: 0.2.17(patch_hash=76ascauag252sgpxpwh3k26eya) bumpp: specifier: ^9.3.0 version: 9.3.0 @@ -1377,9 +1382,10 @@ packages: resolution: {integrity: sha512-LuZgWLW6DB1zenkfJuF4/kfSZdazOR2xaMSzeqgvfbNIwECwV1AJso9wpNje79uaRU86Obbujv4qtDnwoOLQww==} dev: true - /birpc@0.2.17: + /birpc@0.2.17(patch_hash=76ascauag252sgpxpwh3k26eya): resolution: {integrity: sha512-+hkTxhot+dWsLpp3gia5AkVHIsKlZybNT5gIYiDlNzJrmYPcTM9k5/w2uaj3IPpd7LlEYpmCj4Jj1nC41VhDFg==} dev: true + patched: true /boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} diff --git a/samples/basic/test/add.test.ts b/samples/basic/test/add.test.ts index 480d43b5..2517c278 100644 --- a/samples/basic/test/add.test.ts +++ b/samples/basic/test/add.test.ts @@ -47,6 +47,6 @@ describe('testing', () => { }) it("mul fail", () => { - expect(5 * 5).toBe(26) + expect(5 * 5).toBe(25) }) }) diff --git a/samples/monorepo/packages/react/test/__snapshots__/basic.test.tsx.snap b/samples/monorepo/packages/react/test/__snapshots__/basic.test.tsx.snap index 40bdee66..77bed4dc 100644 --- a/samples/monorepo/packages/react/test/__snapshots__/basic.test.tsx.snap +++ b/samples/monorepo/packages/react/test/__snapshots__/basic.test.tsx.snap @@ -1,4 +1,4 @@ -// Vitest Snapshot v1 +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`Link changes the class when hovered 1`] = ` >(name: K) { return (callback: VitestEvents[K]) => { - this.handlers[name]((id, ...args) => { - if (id === this.id) - (callback as any)(...args) - }) + this.handlers[name](callback as any) } } } @@ -140,15 +137,15 @@ export class VitestFolderAPI extends VitestReporter { } async runFiles(files?: string[], testNamePatern?: string) { - await this.meta.rpc.runTests(this.id, files?.map(normalize), testNamePatern) + await this.meta.rpc.runTests(files?.map(normalize), testNamePatern) } async updateSnapshots(files?: string[], testNamePatern?: string) { - await this.meta.rpc.updateSnapshots(this.id, files?.map(normalize), testNamePatern) + await this.meta.rpc.updateSnapshots(files?.map(normalize), testNamePatern) } getFiles() { - return this.meta.rpc.getFiles(this.id) + return this.meta.rpc.getFiles() } private testsQueue = new Set() @@ -167,7 +164,7 @@ export class VitestFolderAPI extends VitestReporter { const root = this.workspaceFolder.uri.fsPath this.testsQueue.clear() log.info('[API]', `Collecting tests: ${tests.map(t => relative(root, t)).join(', ')}`) - this.collectPromise = this.meta.rpc.collectTests(this.id, tests).finally(() => { + this.collectPromise = this.meta.rpc.collectTests(tests).finally(() => { this.collectPromise = null }) }, 50) @@ -177,9 +174,7 @@ export class VitestFolderAPI extends VitestReporter { async dispose() { WEAKMAP_API_FOLDER.delete(this) this.handlers.clearListeners() - this.meta.packages.forEach((pkg) => { - delete require.cache[pkg.vitestPackageJsonPath] - }) + delete require.cache[this.meta.pkg.vitestPackageJsonPath] if (!this.meta.process.closed) { try { await this.meta.rpc.close() @@ -197,33 +192,33 @@ export class VitestFolderAPI extends VitestReporter { } async cancelRun() { - await this.meta.rpc.cancelRun(this.id) + await this.meta.rpc.cancelRun() } waitForCoverageReport() { - return this.meta.rpc.waitForCoverageReport(this.id) + return this.meta.rpc.waitForCoverageReport() } async enableCoverage() { - await this.meta.rpc.enableCoverage(this.id) + await this.meta.rpc.enableCoverage() } async disableCoverage() { - await this.meta.rpc.disableCoverage(this.id) + await this.meta.rpc.disableCoverage() } async watchTests(files?: string[], testNamePattern?: string) { - await this.meta.rpc.watchTests(this.id, files?.map(normalize), testNamePattern) + await this.meta.rpc.watchTests(files?.map(normalize), testNamePattern) } async unwatchTests() { - await this.meta.rpc.unwatchTests(this.id) + await this.meta.rpc.unwatchTests() } } -export async function resolveVitestAPI(showWarning: boolean, packages: VitestPackage[]) { +export async function resolveVitestAPI(packages: VitestPackage[]) { const promises = packages.map(async (pkg) => { - const vitest = await createVitestProcess(showWarning, [pkg]) + const vitest = await createVitestProcess(pkg) return new VitestFolderAPI(pkg, vitest) }) const apis = await Promise.all(promises) @@ -233,39 +228,39 @@ export async function resolveVitestAPI(showWarning: boolean, packages: VitestPac export interface ResolvedMeta { rpc: VitestRPC process: VitestProcess - packages: VitestPackage[] + pkg: VitestPackage handlers: { - onConsoleLog: (listener: BirpcEvents['onConsoleLog']) => void - onTaskUpdate: (listener: BirpcEvents['onTaskUpdate']) => void - onFinished: (listener: BirpcEvents['onFinished']) => void - onCollected: (listener: BirpcEvents['onCollected']) => void - onWatcherStart: (listener: BirpcEvents['onWatcherStart']) => void - onWatcherRerun: (listener: BirpcEvents['onWatcherRerun']) => void + onConsoleLog: (listener: VitestEvents['onConsoleLog']) => void + onTaskUpdate: (listener: VitestEvents['onTaskUpdate']) => void + onFinished: (listener: VitestEvents['onFinished']) => void + onCollected: (listener: VitestEvents['onCollected']) => void + onWatcherStart: (listener: VitestEvents['onWatcherStart']) => void + onWatcherRerun: (listener: VitestEvents['onWatcherRerun']) => void clearListeners: () => void removeListener: (name: string, listener: any) => void } } -async function createChildVitestProcess(showWarning: boolean, meta: VitestPackage[]) { - const pnpLoaders = [ - ...new Set(meta.map(meta => meta.loader).filter(Boolean) as string[]), - ] - const pnp = meta.find(meta => meta.pnp)?.pnp as string - if (pnpLoaders.length > 1) - throw new Error(`Multiple loaders are not supported: ${pnpLoaders.join(', ')}`) - if (pnpLoaders.length && !pnp) +function formapPkg(pkg: VitestPackage) { + return `Vitest v${pkg.version} (${relative(dirname(pkg.cwd), pkg.id)})` +} + +async function createChildVitestProcess(pkg: VitestPackage) { + const pnpLoader = pkg.loader + const pnp = pkg.pnp + if (pnpLoader && !pnp) throw new Error('pnp file is required if loader option is used') - const execArgv = pnpLoaders[0] && !gte(process.version, '18.19.0') + const execArgv = pnpLoader && pnp && !gte(process.version, '18.19.0') ? [ '--require', pnp, '--experimental-loader', - pathToFileURL(pnpLoaders[0]).toString(), + pathToFileURL(pnpLoader).toString(), ] : undefined const env = getConfig().env || {} const execPath = getConfig().nodeExecutable || await findNode(vscode.workspace.workspaceFile?.fsPath || vscode.workspace.workspaceFolders![0].uri.fsPath) - log.info('[API]', `Running Vitest: ${meta.map(x => `v${x.version} (${relative(dirname(x.cwd), x.id)})`).join(', ')} with Node.js: ${execPath}`) + log.info('[API]', `Running ${formapPkg(pkg)} with Node.js: ${execPath}`) const vitest = fork( workerPath, { @@ -282,7 +277,7 @@ async function createChildVitestProcess(showWarning: boolean, meta: VitestPackag NODE_ENV: env.NODE_ENV ?? process.env.NODE_ENV ?? 'test', }, stdio: 'overlapped', - cwd: pnp ? dirname(pnp) : meta[0].cwd, + cwd: pnp ? dirname(pnp) : pkg.cwd, }, ) @@ -297,24 +292,24 @@ async function createChildVitestProcess(showWarning: boolean, meta: VitestPackag if (message.type === 'ready') { vitest.off('message', ready) // started _some_ projects, but some failed - log them, this can only happen if there are multiple projects - if (message.errors.length) { - message.errors.forEach(([id, error]: [string, string]) => { - const metaIndex = meta.findIndex(m => m.id === id) - meta.splice(metaIndex, 1) - log.error('[API]', `Vitest failed to start for ${id}: \n${error}`) - }) - if (showWarning) { - const errorsNumber = message.errors.length - const resultButton = errorsNumber > 1 ? 'See errors' : 'See error' - vscode.window.showWarningMessage( - `There ${errorsNumber > 1 ? 'were' : 'was'} ${pluralize(message.errors.length, 'error')} during Vitest startup. Check the output for more details.`, - resultButton, - ).then((result) => { - if (result === resultButton) - vscode.commands.executeCommand('vitest.openOutput') - }) - } - } + // if (message.errors.length) { + // message.errors.forEach(([id, error]: [string, string]) => { + // const metaIndex = pkg.findIndex(m => m.id === id) + // pkg.splice(metaIndex, 1) + // log.error('[API]', `Vitest failed to start for ${id}: \n${error}`) + // }) + // if (showWarning) { + // const errorsNumber = message.errors.length + // const resultButton = errorsNumber > 1 ? 'See errors' : 'See error' + // vscode.window.showWarningMessage( + // `There ${errorsNumber > 1 ? 'were' : 'was'} ${pluralize(message.errors.length, 'error')} during Vitest startup. Check the output for more details.`, + // resultButton, + // ).then((result) => { + // if (result === resultButton) + // vscode.commands.executeCommand('vitest.openOutput') + // }) + // } + // } resolve(vitest) } if (message.type === 'error') { @@ -345,16 +340,16 @@ async function createChildVitestProcess(showWarning: boolean, meta: VitestPackag vitest.once('spawn', () => { const runnerOptions: WorkerRunnerOptions = { type: 'init', - meta: meta.map(m => ({ - vitestNodePath: m.vitestNodePath, - env: getConfig(m.folder).env || undefined, - configFile: m.configFile, - cwd: m.cwd, - arguments: m.arguments, - workspaceFile: m.workspaceFile, - id: m.id, - })), - loader: pnpLoaders[0] && gte(process.version, '18.19.0') ? pnpLoaders[0] : undefined, + meta: { + vitestNodePath: pkg.vitestNodePath, + env: getConfig(pkg.folder).env || undefined, + configFile: pkg.configFile, + cwd: pkg.cwd, + arguments: pkg.arguments, + workspaceFile: pkg.workspaceFile, + id: pkg.id, + }, + loader: pnpLoader && gte(process.version, '18.19.0') ? pnpLoader : undefined, } vitest.send(runnerOptions) @@ -362,11 +357,10 @@ async function createChildVitestProcess(showWarning: boolean, meta: VitestPackag }) } -// TODO: packages should be a single package -export async function createVitestProcess(showWarning: boolean, packages: VitestPackage[]): Promise { - const vitest = await createChildVitestProcess(showWarning, packages) +export async function createVitestProcess(pkg: VitestPackage): Promise { + const vitest = await createChildVitestProcess(pkg) - log.info('[API]', `Vitest ${packages.map(x => `v${x.version} (${relative(dirname(x.cwd), x.id)})`).join(', ')} process ${vitest.pid} created`) + log.info('[API]', `${formapPkg(pkg)} process ${vitest.pid} created`) const { handlers, api } = createVitestRpc({ on: listener => vitest.on('message', listener), @@ -377,7 +371,7 @@ export async function createVitestProcess(showWarning: boolean, packages: Vitest rpc: api, process: new VitestChildProvess(vitest), handlers, - packages, + pkg, } } diff --git a/src/api/rpc.ts b/src/api/rpc.ts index 0219ff72..b5936f1e 100644 --- a/src/api/rpc.ts +++ b/src/api/rpc.ts @@ -15,13 +15,6 @@ export interface VitestMethods { enableCoverage: () => void disableCoverage: () => void waitForCoverageReport: () => Promise -} - -type VitestPoolMethods = { - [K in keyof VitestMethods]: (id: string, ...args: Parameters) => ReturnType -} - -export interface VitestPool extends VitestPoolMethods { close: () => void } @@ -34,11 +27,7 @@ export interface VitestEvents { onWatcherRerun: (files: string[], trigger?: string, collecting?: boolean) => void } -export type BirpcEvents = { - [K in keyof VitestEvents]: (folder: string, ...args: Parameters) => void -} - -export type VitestRPC = BirpcReturn +export type VitestRPC = BirpcReturn function createHandler any>() { const handlers: T[] = [] @@ -57,15 +46,15 @@ function createHandler any>() { export function createRpcOptions() { const handlers = { - onConsoleLog: createHandler(), - onTaskUpdate: createHandler(), - onFinished: createHandler(), - onCollected: createHandler(), - onWatcherRerun: createHandler(), - onWatcherStart: createHandler(), + onConsoleLog: createHandler(), + onTaskUpdate: createHandler(), + onFinished: createHandler(), + onCollected: createHandler(), + onWatcherRerun: createHandler(), + onWatcherStart: createHandler(), } - const events: Omit = { + const events: Omit = { onConsoleLog: handlers.onConsoleLog.trigger, onFinished: handlers.onFinished.trigger, onTaskUpdate: handlers.onTaskUpdate.trigger, @@ -100,7 +89,7 @@ export function createVitestRpc(options: { }) { const { events, handlers } = createRpcOptions() - const api = createBirpc( + const api = createBirpc( events, { timeout: -1, diff --git a/src/extension.ts b/src/extension.ts index 19722dc2..b72ad7d6 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -68,7 +68,7 @@ class VitestExtension { const maximumConfigs = getConfig().maximumConfigs ?? 3 if (configFiles.length > maximumConfigs) { - const warningMessage = `Vitest found multiple config files. The extension will use only the first ${maximumConfigs} due to performance concerns. Consider using a workspace configuration to group your configs.` + const warningMessage = `Vitest found multiple config files. The extension will use only the first ${maximumConfigs} due to performance concerns. Consider using a workspace configuration to group your configs or increase the limit via "vitest.maximumConfigs" option.` // remove all but the first 3 const discardedConfigs = configFiles.splice(maximumConfigs) @@ -104,7 +104,7 @@ class VitestExtension { try { await this.api?.dispose() - this.api = await resolveVitestAPI(showWarning, vitest) + this.api = await resolveVitestAPI(vitest) this.api.onUnexpectedExit((code) => { if (code) { diff --git a/src/worker/debug.ts b/src/worker/debug.ts index 1e3595df..caa535fa 100644 --- a/src/worker/debug.ts +++ b/src/worker/debug.ts @@ -6,7 +6,6 @@ import { Vitest } from './vitest' import { createWorkerRPC } from './rpc' const ws = new WebSocket(process.env.VITEST_WS_ADDRESS!) -const cwd = process.cwd() ws.on('message', async function init(_data) { const message = JSON.parse(_data.toString()) @@ -17,23 +16,19 @@ ws.on('message', async function init(_data) { try { let vitest - const pkg = data.meta[0] + const pkg = data.meta - process.chdir(pkg.cwd) try { vitest = await initVitest(pkg, { fileParallelism: false, }) - process.chdir(cwd) } catch (err: any) { ws.send(JSON.stringify({ type: 'error', errors: [pkg.id, err.stack] })) return } - const rpc = createWorkerRPC({ - [pkg.id]: new Vitest(pkg.cwd, vitest.vitest, true), - }, { + const rpc = createWorkerRPC(new Vitest(vitest.vitest, true), { on(listener) { ws.on('message', listener) }, diff --git a/src/worker/init.ts b/src/worker/init.ts index e580398d..ca997a50 100644 --- a/src/worker/init.ts +++ b/src/worker/init.ts @@ -4,7 +4,7 @@ import type { WorkerMeta } from './types' export async function initVitest(meta: WorkerMeta, options?: UserConfig) { const vitestModule = await import(meta.vitestNodePath) as typeof import('vitest/node') - const reporter = new VSCodeReporter(meta) + const reporter = new VSCodeReporter() const vitest = await vitestModule.createVitest( 'test', { diff --git a/src/worker/pool.ts b/src/worker/pool.ts deleted file mode 100644 index d730c904..00000000 --- a/src/worker/pool.ts +++ /dev/null @@ -1,34 +0,0 @@ -import type { VitestPool } from '../api/rpc' -import type { Vitest } from './vitest' - -export function createVitestPool(vitestById: Record): VitestPool { - return new Proxy({ - async close() { - for (const vitest in vitestById) { - try { - await vitestById[vitest].dispose() - } - catch { - // ignore - } - } - }, - }, { - // because we don't want to copy-past the same VitestPool for every vitestById - // we use a Proxy to dynamically call these methods on the correct Vitest instance - get(target, prop) { - if (prop === 'close') - return Reflect.get(target, prop) - - return function (id: string, ...args: any[]) { - const vitest = vitestById[id] - if (!vitest) - throw new Error(`Vitest instance not found with id: ${id} (calling method: ${String(prop)})`) - if (prop in vitest) - return vitest[prop as 'collectTests'](...args as [any]) - else - throw new Error(`Method not found: ${String(prop)}`) - } - }, - }) -} diff --git a/src/worker/reporter.ts b/src/worker/reporter.ts index a59999ad..830e3845 100644 --- a/src/worker/reporter.ts +++ b/src/worker/reporter.ts @@ -4,17 +4,14 @@ import { Console } from 'node:console' import { parseErrorStacktrace } from '@vitest/utils/source-map' import type { BirpcReturn } from 'birpc' import type { File, Reporter, TaskResultPack, UserConsoleLog, Vitest as VitestCore } from 'vitest' -import type { BirpcEvents, VitestPool } from '../api/rpc' +import type { VitestEvents, VitestMethods } from '../api/rpc' import { setupFilePath } from '../constants' -import type { WorkerMeta } from './types' import { Vitest } from './vitest' export class VSCodeReporter implements Reporter { - private rpc!: BirpcReturn + private rpc!: BirpcReturn private ctx!: VitestCore - constructor(private meta: WorkerMeta) {} - private get collecting(): boolean { return this.ctx.configOverride.testNamePattern?.toString() === `/${Vitest.COLLECT_NAME_PATTERN}/` } @@ -35,12 +32,12 @@ export class VSCodeReporter implements Reporter { }) } - initRpc(rpc: BirpcReturn) { + initRpc(rpc: BirpcReturn) { this.rpc = rpc } onUserConsoleLog(log: UserConsoleLog) { - this.rpc.onConsoleLog(this.meta.id, log) + this.rpc.onConsoleLog(log) } onTaskUpdate(packs: TaskResultPack[]) { @@ -56,7 +53,7 @@ export class VSCodeReporter implements Reporter { }) }) - this.rpc.onTaskUpdate(this.meta.id, packs) + this.rpc.onTaskUpdate(packs) } async onFinished(files?: File[], errors: unknown[] = this.ctx.state.getUnhandledErrors()) { @@ -82,19 +79,19 @@ export class VSCodeReporter implements Reporter { this.ctx.logger.outputStream = outputStream } nextTick(() => { - this.rpc.onFinished(this.meta.id, files || [], output, collecting) + this.rpc.onFinished(files || [], output, collecting) }) } onCollected(files?: File[]) { - this.rpc.onCollected(this.meta.id, files, this.collecting) + this.rpc.onCollected(files, this.collecting) } onWatcherStart(files?: File[], errors?: unknown[]) { - this.rpc.onWatcherStart(this.meta.id, files, errors, this.collecting) + this.rpc.onWatcherStart(files, errors, this.collecting) } onWatcherRerun(files: string[], trigger?: string) { - this.rpc.onWatcherRerun(this.meta.id, files, trigger, this.collecting) + this.rpc.onWatcherRerun(files, trigger, this.collecting) } } diff --git a/src/worker/rpc.ts b/src/worker/rpc.ts index ae9e2e98..f9303ed9 100644 --- a/src/worker/rpc.ts +++ b/src/worker/rpc.ts @@ -1,17 +1,18 @@ import type { ChannelOptions } from 'birpc' import { createBirpc } from 'birpc' -import type { BirpcEvents, VitestPool } from '../api/rpc' -import { createVitestPool } from './pool' +import type { VitestEvents, VitestMethods } from '../api/rpc' import type { Vitest } from './vitest' -export function createWorkerRPC(vitestById: Record, channel: ChannelOptions) { - const rpc = createBirpc(createVitestPool(vitestById), { +export function createWorkerRPC(vitest: Vitest, channel: ChannelOptions) { + const rpc = createBirpc(vitest, { timeout: -1, eventNames: [ 'onConsoleLog', 'onTaskUpdate', 'onFinished', 'onCollected', + 'onWatcherRerun', + 'onWatcherStart', ], ...channel, }) diff --git a/src/worker/types.ts b/src/worker/types.ts index b3df88ff..901c64d8 100644 --- a/src/worker/types.ts +++ b/src/worker/types.ts @@ -10,7 +10,7 @@ export interface WorkerMeta { export interface WorkerRunnerOptions { type: 'init' - meta: WorkerMeta[] + meta: WorkerMeta loader?: string } diff --git a/src/worker/vitest.ts b/src/worker/vitest.ts index f3007404..c1dc5ad7 100644 --- a/src/worker/vitest.ts +++ b/src/worker/vitest.ts @@ -3,8 +3,6 @@ import type { VitestMethods } from '../api/rpc' import { VitestWatcher } from './watcher' import { VitestCoverage } from './coverage' -const cwd = process.cwd() - export class Vitest implements VitestMethods { private readonly watcher: VitestWatcher private readonly coverage: VitestCoverage @@ -12,7 +10,6 @@ export class Vitest implements VitestMethods { public static COLLECT_NAME_PATTERN = '$a' constructor( - private readonly cwd: string, private readonly ctx: VitestCore, private readonly debug = false, ) { @@ -74,29 +71,20 @@ export class Vitest implements VitestMethods { } private async globTestFiles(filters?: string[]) { - process.chdir(this.cwd) - const files = await this.ctx.globTestFiles(filters) - process.chdir(cwd) - return files + return await this.ctx.globTestFiles(filters) } private async runTestFiles(files: string[], testNamePattern?: string | undefined, runAllFiles = false) { await this.ctx.runningPromise this.watcher.markRerun(false) - process.chdir(this.cwd) - try { - this.setTestNamePattern(testNamePattern) + this.setTestNamePattern(testNamePattern) - // populate cache so it can find test files - if (this.debug) - await this.globTestFiles(files) + // populate cache so it can find test files + if (this.debug) + await this.globTestFiles(files) - await this.rerunTests(files, runAllFiles) - } - finally { - process.chdir(cwd) - } + await this.rerunTests(files, runAllFiles) } private setTestNamePattern(pattern: string | undefined) { @@ -138,4 +126,8 @@ export class Vitest implements VitestMethods { this.watcher.stopTracking() return this.ctx.close() } + + close() { + return this.dispose() + } } diff --git a/src/worker/worker.ts b/src/worker/worker.ts index 362525f1..8c3627fb 100644 --- a/src/worker/worker.ts +++ b/src/worker/worker.ts @@ -5,8 +5,6 @@ import type { WorkerRunnerOptions } from './types' import { Vitest } from './vitest' import { initVitest } from './init' -const cwd = process.cwd() - process.on('message', async function init(message: any) { if (message.type === 'init') { process.off('message', init) @@ -15,29 +13,10 @@ process.on('message', async function init(message: any) { try { if (data.loader) register(data.loader) - const errors = [] - - const vitest = [] - for (const meta of data.meta) { - process.chdir(meta.cwd) - try { - vitest.push(await initVitest(meta)) - } - catch (err: any) { - errors.push([meta.id, err.stack]) - } - } - process.chdir(cwd) - if (!vitest.length) { - process.send!({ type: 'error', errors }) - return - } + const { reporter, vitest } = await initVitest(data.meta) - const vitestById = Object.fromEntries(vitest.map(v => - [v.meta.id, new Vitest(v.meta.cwd, v.vitest)], - )) - const rpc = createWorkerRPC(vitestById, { + const rpc = createWorkerRPC(new Vitest(vitest), { on(listener) { process.on('message', listener) }, @@ -47,8 +26,8 @@ process.on('message', async function init(message: any) { serialize: v8.serialize, deserialize: v => v8.deserialize(Buffer.from(v)), }) - vitest.forEach(v => v.reporter.initRpc(rpc)) - process.send!({ type: 'ready', errors }) + reporter.initRpc(rpc) + process.send!({ type: 'ready' }) } catch (err: any) { error(err)