[READ-ONLY] Mirror of https://github.com/vitest-dev/vitest. Next generation testing framework powered by Vite. vitest.dev
test testing-tools vite
12

Configure Feed

Select the types of activity you want to include in your feed.

fix: resolve cwd correctly when initiating projects (#5582)

authored by

Vladimir and committed by
GitHub
(Apr 22, 2024, 2:13 PM +0200) ec9d7c93 e40f9924

+55 -48
+3
test/workspaces/cwdPlugin.d.ts
··· 1 + import type { Plugin } from 'vite' 2 + 3 + export function cwdPlugin(name: string): Plugin
+13
test/workspaces/cwdPlugin.js
··· 1 + // @ts-check 2 + 3 + export function cwdPlugin(name) { 4 + return { 5 + name: `vitest:test:workspace-${name}`, 6 + configResolved() { 7 + process.env[`${name}_CWD_CONFIG`] = process.cwd() 8 + }, 9 + configureServer() { 10 + process.env[`${name}_CWD_SERVER`] = process.cwd() 11 + }, 12 + } 13 + }
+2 -2
test/workspaces/globalTest.ts
··· 33 33 try { 34 34 assert.ok(results.success) 35 35 assert.equal(results.numTotalTestSuites, 28) 36 - assert.equal(results.numTotalTests, 30) 37 - assert.equal(results.numPassedTests, 30) 36 + assert.equal(results.numTotalTests, 31) 37 + assert.equal(results.numPassedTests, 31) 38 38 39 39 const shared = results.testResults.filter((r: any) => r.name.includes('space_shared/test.spec.ts')) 40 40
+2
test/workspaces/vitest.config.ts
··· 1 1 import { defineConfig } from 'vitest/config' 2 + import { cwdPlugin } from './cwdPlugin.js' 2 3 3 4 if (process.env.TEST_WATCH) { 4 5 // Patch stdin on the process so that we can fake it to seem like a real interactive terminal and pass the TTY checks ··· 8 9 9 10 export default defineConfig({ 10 11 envPrefix: ['VITE_', 'CUSTOM_', 'ROOT_'], 12 + plugins: [cwdPlugin('ROOT')], 11 13 test: { 12 14 coverage: { 13 15 enabled: true,
+2
test/workspaces/space_1/vite.config.ts
··· 1 1 import { defineProject } from 'vitest/config' 2 + import { cwdPlugin } from '../cwdPlugin' 2 3 3 4 export default defineProject({ 4 5 envPrefix: ['VITE_', 'CUSTOM_'], 6 + plugins: [cwdPlugin('SPACE_2')], 5 7 define: { 6 8 __DEV__: 'true', 7 9 },
+8 -13
packages/vitest/src/node/core.ts
··· 315 315 316 316 const cwd = process.cwd() 317 317 318 - const projects: (() => Promise<WorkspaceProject>)[] = [] 318 + const projects: WorkspaceProject[] = [] 319 319 320 320 try { 321 321 // we have to resolve them one by one because CWD should depend on the project 322 322 for (const filepath of filteredWorkspaces) { 323 323 if (this.server.config.configFile === filepath) { 324 324 const project = await this.createCoreProject() 325 - projects.push(() => Promise.resolve(project)) 325 + projects.push(project) 326 326 continue 327 327 } 328 328 const dir = filepath.endsWith('/') ? filepath.slice(0, -1) : dirname(filepath) 329 329 if (isMainThread) 330 330 process.chdir(dir) 331 - // this just resolves the config, later we also wait when the server is resolved, 332 - // but we can do that in parallel because it doesn't depend on process.cwd() 333 - // this is strictly a performance optimization so we don't need to wait for server to start 334 - projects.push(await initializeProject(filepath, this, { workspaceConfigPath, test: cliOverrides })) 331 + projects.push( 332 + await initializeProject(filepath, this, { workspaceConfigPath, test: cliOverrides }), 333 + ) 335 334 } 336 335 } 337 336 finally { ··· 339 338 process.chdir(cwd) 340 339 } 341 340 342 - const projectPromises: Promise<() => Promise<WorkspaceProject>>[] = [] 341 + const projectPromises: Promise<WorkspaceProject>[] = [] 343 342 344 343 projectsOptions.forEach((options, index) => { 345 344 // we can resolve these in parallel because process.cwd() is not changed ··· 349 348 if (!projects.length && !projectPromises.length) 350 349 return [await this.createCoreProject()] 351 350 352 - const resolvedProjectsReceivers = [ 351 + const resolvedProjects = await Promise.all([ 353 352 ...projects, 354 353 ...await Promise.all(projectPromises), 355 - ] 356 - // we need to wait when the server is resolved, we can do that in parallel 357 - const resolvedProjects = await Promise.all( 358 - resolvedProjectsReceivers.map(receiver => receiver()), 359 - ) 354 + ]) 360 355 const names = new Set<string>() 361 356 362 357 for (const project of resolvedProjects) {
+14 -33
packages/vitest/src/node/workspace.ts
··· 12 12 import type { Typechecker } from '../typecheck/typechecker' 13 13 import type { BrowserProvider } from '../types/browser' 14 14 import { getBrowserProvider } from '../integrations/browser' 15 - import { createDefer } from '../public/utils' 16 15 import { isBrowserEnabled, resolveConfig } from './config' 17 16 import { WorkspaceVitestPlugin } from './plugins/workspace' 18 17 import { createViteServer } from './vite' ··· 40 39 : workspacePath.endsWith('/') ? workspacePath : dirname(workspacePath) 41 40 ) 42 41 43 - return new Promise<() => Promise<WorkspaceProject>>((resolve, reject) => { 44 - const resolution = createDefer<WorkspaceProject>() 45 - let configResolved = false 46 - const config: ViteInlineConfig = { 47 - ...options, 48 - root, 49 - logLevel: 'error', 50 - configFile, 51 - // this will make "mode": "test" | "benchmark" inside defineConfig 52 - mode: options.test?.mode || options.mode || ctx.config.mode, 53 - plugins: [ 54 - { 55 - name: 'vitest:workspace:resolve', 56 - configResolved() { 57 - configResolved = true 58 - resolve(() => resolution) 59 - }, 60 - }, 61 - ...options.plugins || [], 62 - WorkspaceVitestPlugin(project, { ...options, root, workspacePath }), 63 - ], 64 - } 42 + const config: ViteInlineConfig = { 43 + ...options, 44 + root, 45 + logLevel: 'error', 46 + configFile, 47 + // this will make "mode": "test" | "benchmark" inside defineConfig 48 + mode: options.test?.mode || options.mode || ctx.config.mode, 49 + plugins: [ 50 + ...options.plugins || [], 51 + WorkspaceVitestPlugin(project, { ...options, root, workspacePath }), 52 + ], 53 + } 65 54 66 - createViteServer(config) 67 - .then(() => resolution.resolve(project)) 68 - .catch((err) => { 69 - if (configResolved) 70 - resolution.reject(err) 71 - else 72 - reject(err) 73 - }) 55 + await createViteServer(config) 74 56 75 - return project 76 - }) 57 + return project 77 58 } 78 59 79 60 export class WorkspaceProject {
+11
test/workspaces/space_1/test/env-injected.spec.ts
··· 1 + import { resolve } from 'node:path' 1 2 import { expect, test } from 'vitest' 2 3 3 4 declare global { ··· 22 23 expect(process.env.CONFIG_VAR).toBe('root') 23 24 expect(process.env.CONFIG_LOCAL).toBe('local') 24 25 expect(process.env.CONFIG_OVERRIDE).toBe('local') 26 + }) 27 + 28 + test('cwd is resolved correctly', () => { 29 + const spaceRoot = resolve(import.meta.dirname, '..') 30 + const rootPath = resolve(spaceRoot, '..') 31 + 32 + expect(process.env.ROOT_CWD_CONFIG).toBe(rootPath) 33 + expect(process.env.ROOT_CWD_SERVER).toBe(rootPath) 34 + expect(process.env.SPACE_2_CWD_CONFIG).toBe(spaceRoot) 35 + expect(process.env.SPACE_2_CWD_SERVER).toBe(spaceRoot) 25 36 })