@@ -17,7 +17,7 @@ import { WebSocketReporter } from '../api/setup'
1717import type { SerializedCoverageConfig } from '../runtime/config'
1818import type { SerializedSpec } from '../runtime/types/utils'
1919import type { ArgumentsType , OnServerRestartHandler , ProvidedContext , UserConsoleLog } from '../types/general'
20- import { createPool } from './pool'
20+ import { createPool , getFilePoolName } from './pool'
2121import type { ProcessPool , WorkspaceSpec } from './pool'
2222import { createBenchmarkReporters , createReporters } from './reporters/utils'
2323import { StateManager } from './state'
@@ -77,10 +77,14 @@ export class Vitest {
7777
7878 private resolvedProjects : WorkspaceProject [ ] = [ ]
7979 public projects : WorkspaceProject [ ] = [ ]
80- private projectsTestFiles = new Map < string , Set < WorkspaceProject > > ( )
8180
8281 public distPath ! : string
8382
83+ private _cachedSpecs = new Map < string , WorkspaceSpec [ ] > ( )
84+
85+ /** @deprecated use `_cachedSpecs` */
86+ projectTestFiles = this . _cachedSpecs
87+
8488 constructor (
8589 public readonly mode : VitestRunMode ,
8690 options : VitestOptions = { } ,
@@ -103,7 +107,7 @@ export class Vitest {
103107 this . coverageProvider = undefined
104108 this . runningPromise = undefined
105109 this . distPath = undefined !
106- this . projectsTestFiles . clear ( )
110+ this . _cachedSpecs . clear ( )
107111
108112 const resolved = resolveConfig ( this . mode , options , server . config , this . logger )
109113
@@ -202,6 +206,9 @@ export class Vitest {
202206 return this . coreWorkspaceProject
203207 }
204208
209+ /**
210+ * @deprecated use Reported Task API instead
211+ */
205212 public getProjectByTaskId ( taskId : string ) : WorkspaceProject {
206213 const task = this . state . idMap . get ( taskId )
207214 const projectName = ( task as File ) . projectName || task ?. file ?. projectName || ''
@@ -216,7 +223,7 @@ export class Vitest {
216223 || this . projects [ 0 ]
217224 }
218225
219- private async getWorkspaceConfigPath ( ) {
226+ private async getWorkspaceConfigPath ( ) : Promise < string | null > {
220227 if ( this . config . workspace ) {
221228 return this . config . workspace
222229 }
@@ -423,8 +430,8 @@ export class Vitest {
423430 }
424431 }
425432
426- private async getTestDependencies ( filepath : WorkspaceSpec , deps = new Set < string > ( ) ) {
427- const addImports = async ( [ project , filepath ] : WorkspaceSpec ) => {
433+ private async getTestDependencies ( [ project , filepath ] : WorkspaceSpec , deps = new Set < string > ( ) ) {
434+ const addImports = async ( project : WorkspaceProject , filepath : string ) => {
428435 if ( deps . has ( filepath ) ) {
429436 return
430437 }
@@ -440,13 +447,13 @@ export class Vitest {
440447 const path = await project . server . pluginContainer . resolveId ( dep , filepath , { ssr : true } )
441448 const fsPath = path && ! path . external && path . id . split ( '?' ) [ 0 ]
442449 if ( fsPath && ! fsPath . includes ( 'node_modules' ) && ! deps . has ( fsPath ) && existsSync ( fsPath ) ) {
443- await addImports ( [ project , fsPath ] )
450+ await addImports ( project , fsPath )
444451 }
445452 } ) )
446453 }
447454
448- await addImports ( filepath )
449- deps . delete ( filepath [ 1 ] )
455+ await addImports ( project , filepath )
456+ deps . delete ( filepath )
450457
451458 return deps
452459 }
@@ -500,12 +507,31 @@ export class Vitest {
500507 return runningTests
501508 }
502509
510+ /**
511+ * @deprecated remove when vscode extension supports "getFileWorkspaceSpecs"
512+ */
503513 getProjectsByTestFile ( file : string ) {
504- const projects = this . projectsTestFiles . get ( file )
505- if ( ! projects ) {
506- return [ ]
514+ return this . getFileWorkspaceSpecs ( file )
515+ }
516+
517+ getFileWorkspaceSpecs ( file : string ) {
518+ const _cached = this . _cachedSpecs . get ( file )
519+ if ( _cached ) {
520+ return _cached
507521 }
508- return Array . from ( projects ) . map ( project => [ project , file ] as WorkspaceSpec )
522+
523+ const specs : WorkspaceSpec [ ] = [ ]
524+ for ( const project of this . projects ) {
525+ if ( project . isTestFile ( file ) ) {
526+ const pool = getFilePoolName ( project , file )
527+ specs . push ( [ project , file , { pool } ] )
528+ }
529+ if ( project . isTypecheckFile ( file ) ) {
530+ specs . push ( [ project , file , { pool : 'typescript' } ] )
531+ }
532+ }
533+ specs . forEach ( spec => this . ensureSpecCached ( spec ) )
534+ return specs
509535 }
510536
511537 async initializeGlobalSetup ( paths : WorkspaceSpec [ ] ) {
@@ -538,8 +564,11 @@ export class Vitest {
538564
539565 await this . report ( 'onPathsCollected' , filepaths )
540566 await this . report ( 'onSpecsCollected' , specs . map (
541- ( [ project , file ] ) =>
542- [ { name : project . config . name , root : project . config . root } , file ] as SerializedSpec ,
567+ ( [ project , file , options ] ) =>
568+ [ {
569+ name : project . config . name ,
570+ root : project . config . root ,
571+ } , file , options ] satisfies SerializedSpec ,
543572 ) )
544573
545574 // previous run
@@ -856,7 +885,6 @@ export class Vitest {
856885 } ) )
857886
858887 if ( matchingProjects . length > 0 ) {
859- this . projectsTestFiles . set ( id , new Set ( matchingProjects ) )
860888 this . changedTests . add ( id )
861889 this . scheduleRerun ( [ id ] )
862890 }
@@ -1054,17 +1082,32 @@ export class Vitest {
10541082 public async globTestFiles ( filters : string [ ] = [ ] ) {
10551083 const files : WorkspaceSpec [ ] = [ ]
10561084 await Promise . all ( this . projects . map ( async ( project ) => {
1057- const specs = await project . globTestFiles ( filters )
1058- specs . forEach ( ( file ) => {
1059- files . push ( [ project , file ] )
1060- const projects = this . projectsTestFiles . get ( file ) || new Set ( )
1061- projects . add ( project )
1062- this . projectsTestFiles . set ( file , projects )
1085+ const { testFiles, typecheckTestFiles } = await project . globTestFiles ( filters )
1086+ testFiles . forEach ( ( file ) => {
1087+ const pool = getFilePoolName ( project , file )
1088+ const spec : WorkspaceSpec = [ project , file , { pool } ]
1089+ this . ensureSpecCached ( spec )
1090+ files . push ( spec )
1091+ } )
1092+ typecheckTestFiles . forEach ( ( file ) => {
1093+ const spec : WorkspaceSpec = [ project , file , { pool : 'typecheck' } ]
1094+ this . ensureSpecCached ( spec )
1095+ files . push ( spec )
10631096 } )
10641097 } ) )
10651098 return files
10661099 }
10671100
1101+ private ensureSpecCached ( spec : WorkspaceSpec ) {
1102+ const file = spec [ 1 ]
1103+ const specs = this . _cachedSpecs . get ( file ) || [ ]
1104+ const included = specs . some ( _s => _s [ 0 ] === spec [ 0 ] && _s [ 2 ] . pool === spec [ 2 ] . pool )
1105+ if ( ! included ) {
1106+ specs . push ( spec )
1107+ this . _cachedSpecs . set ( file , specs )
1108+ }
1109+ }
1110+
10681111 // The server needs to be running for communication
10691112 shouldKeepServer ( ) {
10701113 return ! ! this . config ?. watch
0 commit comments