From 606fe8c01005b8081c0ce892b6e95ec95739cd0b Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 1 May 2024 09:31:18 +0900 Subject: [PATCH 1/7] fix: use `resolve.resolve('vitest')` instead of `resolveId` during initialization --- packages/vitest/src/node/core.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/vitest/src/node/core.ts b/packages/vitest/src/node/core.ts index 4cfed6786c2f..164cea69d028 100644 --- a/packages/vitest/src/node/core.ts +++ b/packages/vitest/src/node/core.ts @@ -1,6 +1,7 @@ import { existsSync, promises as fs } from 'node:fs' import type { Writable } from 'node:stream' import { isMainThread } from 'node:worker_threads' +import { createRequire } from 'node:module' import type { ViteDevServer } from 'vite' import { mergeConfig } from 'vite' import { basename, dirname, join, normalize, relative, resolve } from 'pathe' @@ -111,8 +112,16 @@ export class Vitest { this.vitenode = new ViteNodeServer(server, this.config.server) // if Vitest is running globally, then we should still import local vitest if possible - const projectVitestPath = await this.vitenode.resolveId('vitest') - const vitestDir = projectVitestPath ? resolve(projectVitestPath.id, '../..') : rootDir + function getVitestDir(configRoot: string) { + const require = createRequire(import.meta.url) + try { + const vitestCjsPath = require.resolve('vitest', { paths: [configRoot, rootDir] }) + return resolve(vitestCjsPath, '..') + } + catch {} + return rootDir + } + const vitestDir = getVitestDir(resolved.root) this.distPath = join(vitestDir, 'dist') const node = this.vitenode From 0db44864244e23e23f96055825a2424077b8abff Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 1 May 2024 10:35:00 +0900 Subject: [PATCH 2/7] test: add test --- test/cli/fixtures/plugin/basic.test.ts | 5 +++ test/cli/fixtures/plugin/vitest.config.ts | 41 +++++++++++++++++++++++ test/cli/test/plugin.test.ts | 28 ++++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 test/cli/fixtures/plugin/basic.test.ts create mode 100644 test/cli/fixtures/plugin/vitest.config.ts create mode 100644 test/cli/test/plugin.test.ts diff --git a/test/cli/fixtures/plugin/basic.test.ts b/test/cli/fixtures/plugin/basic.test.ts new file mode 100644 index 000000000000..9bb0283e10c6 --- /dev/null +++ b/test/cli/fixtures/plugin/basic.test.ts @@ -0,0 +1,5 @@ +import { expect, test } from "vitest"; + +test("basic", () => { + expect(1).toBe(1); +}) diff --git a/test/cli/fixtures/plugin/vitest.config.ts b/test/cli/fixtures/plugin/vitest.config.ts new file mode 100644 index 000000000000..eb61df6dc200 --- /dev/null +++ b/test/cli/fixtures/plugin/vitest.config.ts @@ -0,0 +1,41 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + plugins: [ + { + name: "test-default", + configureServer() { + console.log("##test## configureServer(default)") + }, + buildStart() { + console.log("##test## buildStart(default)") + }, + resolveId(source) { + console.log("##test## resolveId(default)") + console.log({ source }) + }, + transform(_code, id) { + console.log("##test## transform(default)") + console.log({ id }) + }, + }, + { + name: "test-pre", + enforce: "pre", + configureServer() { + console.log("##test## configureServer(pre)") + }, + buildStart() { + console.log("##test## buildStart(pre)") + }, + resolveId(source) { + console.log("##test## resolveId(pre)") + console.log({ source }) + }, + transform(_code, id) { + console.log("##test## transform(pre)") + console.log({ id }) + }, + } + ] +}) diff --git a/test/cli/test/plugin.test.ts b/test/cli/test/plugin.test.ts new file mode 100644 index 000000000000..8b7e19f535d3 --- /dev/null +++ b/test/cli/test/plugin.test.ts @@ -0,0 +1,28 @@ +import { Console } from 'node:console' +import { Writable } from 'node:stream' +import { expect, it, vi } from 'vitest' +import { runVitest } from '../../test-utils' + +it('plugin hooks', async () => { + // capture console on main process + let stdout = '' + vi.stubGlobal('console', new Console({ + stdout: new Writable({ + write: (data, _, callback) => { + stdout += String(data) + callback() + }, + }), + })) + await runVitest({ root: './fixtures/plugin' }) + vi.unstubAllGlobals() + + const lines = stdout.split('\n').filter(line => line.startsWith('##test##')) + expect(lines.slice(0, 5)).toEqual([ + '##test## configureServer(pre)', + '##test## configureServer(default)', + '##test## buildStart(pre)', + '##test## buildStart(default)', + '##test## resolveId(pre)', + ]) +}) From 10375119948a856ec62ac1adf73ea140cab27e8c Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 1 May 2024 10:45:11 +0900 Subject: [PATCH 3/7] wip: just delay til `Vitest.start`? --- packages/vitest/src/node/core.ts | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/packages/vitest/src/node/core.ts b/packages/vitest/src/node/core.ts index 164cea69d028..685c1c4b5a6d 100644 --- a/packages/vitest/src/node/core.ts +++ b/packages/vitest/src/node/core.ts @@ -1,7 +1,6 @@ import { existsSync, promises as fs } from 'node:fs' import type { Writable } from 'node:stream' import { isMainThread } from 'node:worker_threads' -import { createRequire } from 'node:module' import type { ViteDevServer } from 'vite' import { mergeConfig } from 'vite' import { basename, dirname, join, normalize, relative, resolve } from 'pathe' @@ -111,19 +110,6 @@ export class Vitest { this.vitenode = new ViteNodeServer(server, this.config.server) - // if Vitest is running globally, then we should still import local vitest if possible - function getVitestDir(configRoot: string) { - const require = createRequire(import.meta.url) - try { - const vitestCjsPath = require.resolve('vitest', { paths: [configRoot, rootDir] }) - return resolve(vitestCjsPath, '..') - } - catch {} - return rootDir - } - const vitestDir = getVitestDir(resolved.root) - this.distPath = join(vitestDir, 'dist') - const node = this.vitenode this.runner = new ViteNodeRunner({ root: server.config.root, @@ -395,6 +381,11 @@ export class Vitest { async start(filters?: string[]) { this._onClose = [] + // if Vitest is running globally, then we should still import local vitest if possible + const projectVitestPath = await this.vitenode.resolveId('vitest') + const vitestDir = projectVitestPath ? resolve(projectVitestPath.id, '../..') : rootDir + this.distPath = join(vitestDir, 'dist') + try { await this.initCoverageProvider() await this.coverageProvider?.clean(this.config.coverage.clean) From 04df286ee3e88db328148122face9e4a01fee084 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 1 May 2024 18:52:20 +0900 Subject: [PATCH 4/7] fix: delay initializeDistPath + test createVitest --- packages/vitest/src/node/core.ts | 17 +++++++---- test/cli/fixtures/create-vitest/basic.test.ts | 5 ++++ .../fixtures/create-vitest/vitest.config.ts | 3 ++ test/cli/test/create-vitest.test.ts | 28 +++++++++++++++++++ 4 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 test/cli/fixtures/create-vitest/basic.test.ts create mode 100644 test/cli/fixtures/create-vitest/vitest.config.ts create mode 100644 test/cli/test/create-vitest.test.ts diff --git a/packages/vitest/src/node/core.ts b/packages/vitest/src/node/core.ts index 685c1c4b5a6d..0b97619c4a80 100644 --- a/packages/vitest/src/node/core.ts +++ b/packages/vitest/src/node/core.ts @@ -381,11 +381,6 @@ export class Vitest { async start(filters?: string[]) { this._onClose = [] - // if Vitest is running globally, then we should still import local vitest if possible - const projectVitestPath = await this.vitenode.resolveId('vitest') - const vitestDir = projectVitestPath ? resolve(projectVitestPath.id, '../..') : rootDir - this.distPath = join(vitestDir, 'dist') - try { await this.initCoverageProvider() await this.coverageProvider?.clean(this.config.coverage.clean) @@ -508,7 +503,19 @@ export class Vitest { await project.initializeGlobalSetup() } + private async initializeDistPath() { + if (this.distPath) + return + + // if Vitest is running globally, then we should still import local vitest if possible + const projectVitestPath = await this.vitenode.resolveId('vitest') + const vitestDir = projectVitestPath ? resolve(projectVitestPath.id, '../..') : rootDir + this.distPath = join(vitestDir, 'dist') + } + async runFiles(paths: WorkspaceSpec[], allTestsRun: boolean) { + await this.initializeDistPath() + const filepaths = paths.map(([, file]) => file) this.state.collectPaths(filepaths) diff --git a/test/cli/fixtures/create-vitest/basic.test.ts b/test/cli/fixtures/create-vitest/basic.test.ts new file mode 100644 index 000000000000..9bb0283e10c6 --- /dev/null +++ b/test/cli/fixtures/create-vitest/basic.test.ts @@ -0,0 +1,5 @@ +import { expect, test } from "vitest"; + +test("basic", () => { + expect(1).toBe(1); +}) diff --git a/test/cli/fixtures/create-vitest/vitest.config.ts b/test/cli/fixtures/create-vitest/vitest.config.ts new file mode 100644 index 000000000000..abed6b2116e1 --- /dev/null +++ b/test/cli/fixtures/create-vitest/vitest.config.ts @@ -0,0 +1,3 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({}) diff --git a/test/cli/test/create-vitest.test.ts b/test/cli/test/create-vitest.test.ts new file mode 100644 index 000000000000..ff24ea211a43 --- /dev/null +++ b/test/cli/test/create-vitest.test.ts @@ -0,0 +1,28 @@ +import { expect, it, vi } from 'vitest' +import { createVitest } from 'vitest/node' + +it(createVitest, async () => { + const onFinished = vi.fn() + const ctx = await createVitest('test', { + watch: false, + root: 'fixtures/create-vitest', + reporters: [ + { + onFinished, + }, + ], + }) + const testFiles = await ctx.globTestFiles() + await ctx.runFiles(testFiles, false) + expect(onFinished.mock.calls[0]).toMatchObject([ + [ + { + name: 'basic.test.ts', + result: { + state: 'pass', + }, + }, + ], + [], + ]) +}) From 997566ac56bdf53928d2a756a835f4609a9125e7 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Wed, 1 May 2024 19:12:51 +0900 Subject: [PATCH 5/7] test: simplify --- test/cli/fixtures/plugin/vitest.config.ts | 30 ++++++++++++--------- test/cli/test/plugin.test.ts | 33 +++++++---------------- 2 files changed, 28 insertions(+), 35 deletions(-) diff --git a/test/cli/fixtures/plugin/vitest.config.ts b/test/cli/fixtures/plugin/vitest.config.ts index eb61df6dc200..41333ca6b905 100644 --- a/test/cli/fixtures/plugin/vitest.config.ts +++ b/test/cli/fixtures/plugin/vitest.config.ts @@ -1,40 +1,46 @@ import { defineConfig } from 'vitest/config' +const testHooks: string[] = (globalThis as any).__testHooks ??= []; + export default defineConfig({ plugins: [ { name: "test-default", configureServer() { - console.log("##test## configureServer(default)") + testHooks.push("configureServer(default)") + console.log("configureServer(default)") }, buildStart() { - console.log("##test## buildStart(default)") + testHooks.push("buildStart(default)") + console.log("buildStart(default)") }, resolveId(source) { - console.log("##test## resolveId(default)") - console.log({ source }) + testHooks.push("resolveId(default)") + console.log("resolveId(default)", source) }, transform(_code, id) { - console.log("##test## transform(default)") - console.log({ id }) + testHooks.push("transform(default)") + console.log("transform(default)", id) }, }, { name: "test-pre", enforce: "pre", configureServer() { - console.log("##test## configureServer(pre)") + testHooks.push("configureServer(pre)") + console.log("configureServer(pre)") }, buildStart() { - console.log("##test## buildStart(pre)") + testHooks.push("buildStart(pre)") + console.log("buildStart(pre)") }, resolveId(source) { - console.log("##test## resolveId(pre)") - console.log({ source }) + testHooks.push("resolveId(pre)") + console.log("resolveId(pre)", source) }, transform(_code, id) { - console.log("##test## transform(pre)") - console.log({ id }) + testHooks.push("transform(pre)") + console.log("transform(pre)", id) }, } ] diff --git a/test/cli/test/plugin.test.ts b/test/cli/test/plugin.test.ts index 8b7e19f535d3..63f72c9a3464 100644 --- a/test/cli/test/plugin.test.ts +++ b/test/cli/test/plugin.test.ts @@ -1,28 +1,15 @@ -import { Console } from 'node:console' -import { Writable } from 'node:stream' -import { expect, it, vi } from 'vitest' +import { expect, it } from 'vitest' import { runVitest } from '../../test-utils' it('plugin hooks', async () => { - // capture console on main process - let stdout = '' - vi.stubGlobal('console', new Console({ - stdout: new Writable({ - write: (data, _, callback) => { - stdout += String(data) - callback() - }, - }), - })) await runVitest({ root: './fixtures/plugin' }) - vi.unstubAllGlobals() - - const lines = stdout.split('\n').filter(line => line.startsWith('##test##')) - expect(lines.slice(0, 5)).toEqual([ - '##test## configureServer(pre)', - '##test## configureServer(default)', - '##test## buildStart(pre)', - '##test## buildStart(default)', - '##test## resolveId(pre)', - ]) + expect((globalThis as any).__testHooks.slice(0, 5)).toEqual( + [ + 'configureServer(pre)', + 'configureServer(default)', + 'buildStart(pre)', + 'buildStart(default)', + 'resolveId(pre)', + ], + ) }) From 32ded4017cdb2c80c5adf7bfa9f9cfcc58db1ea6 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 2 May 2024 08:22:28 +0900 Subject: [PATCH 6/7] refactor: minor --- test/cli/fixtures/plugin/vitest.config.ts | 32 +++++++++++------------ 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/test/cli/fixtures/plugin/vitest.config.ts b/test/cli/fixtures/plugin/vitest.config.ts index 41333ca6b905..3659e85fbe47 100644 --- a/test/cli/fixtures/plugin/vitest.config.ts +++ b/test/cli/fixtures/plugin/vitest.config.ts @@ -1,46 +1,44 @@ import { defineConfig } from 'vitest/config' -const testHooks: string[] = (globalThis as any).__testHooks ??= []; +function logHook(...args: unknown[]) { + ((globalThis as any).__testHooks ??= []).push(args[0]); + + if (process.env["LOG_HOOK"]) { + console.log(...args); + } +} export default defineConfig({ plugins: [ { name: "test-default", configureServer() { - testHooks.push("configureServer(default)") - console.log("configureServer(default)") + logHook("configureServer(default)") }, buildStart() { - testHooks.push("buildStart(default)") - console.log("buildStart(default)") + logHook("buildStart(default)") }, resolveId(source) { - testHooks.push("resolveId(default)") - console.log("resolveId(default)", source) + logHook("resolveId(default)", source) }, transform(_code, id) { - testHooks.push("transform(default)") - console.log("transform(default)", id) + logHook("transform(default)", id) }, }, { name: "test-pre", enforce: "pre", configureServer() { - testHooks.push("configureServer(pre)") - console.log("configureServer(pre)") + logHook("configureServer(pre)") }, buildStart() { - testHooks.push("buildStart(pre)") - console.log("buildStart(pre)") + logHook("buildStart(pre)") }, resolveId(source) { - testHooks.push("resolveId(pre)") - console.log("resolveId(pre)", source) + logHook("resolveId(pre)", source) }, transform(_code, id) { - testHooks.push("transform(pre)") - console.log("transform(pre)", id) + logHook("transform(pre)", id) }, } ] From 4296dea0e6b3cc1ffcfa0ad79a99b496b00c6d8e Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 2 May 2024 08:25:26 +0900 Subject: [PATCH 7/7] fix: reset distPath --- packages/vitest/src/node/core.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/vitest/src/node/core.ts b/packages/vitest/src/node/core.ts index 0b97619c4a80..2ca7acc68c4a 100644 --- a/packages/vitest/src/node/core.ts +++ b/packages/vitest/src/node/core.ts @@ -95,6 +95,7 @@ export class Vitest { this.pool = undefined this.coverageProvider = undefined this.runningPromise = undefined + this.distPath = undefined! this.projectsTestFiles.clear() const resolved = resolveConfig(this.mode, options, server.config, this.logger)