@@ -52,7 +52,7 @@ import { ITestDebugLauncher } from '../common/types';
5252import { PythonResultResolver } from './common/resultResolver' ;
5353import { onDidSaveTextDocument } from '../../common/vscodeApis/workspaceApis' ;
5454import { IEnvironmentVariablesProvider } from '../../common/variables/types' ;
55- import { ProjectAdapter , WorkspaceDiscoveryState } from './common/projectAdapter' ;
55+ import { ProjectAdapter } from './common/projectAdapter' ;
5656import { generateProjectId , createProjectDisplayName } from './common/projectUtils' ;
5757import { PythonProject , PythonEnvironment } from '../../envExt/types' ;
5858import { getEnvExtApi , useEnvExtension } from '../../envExt/api.internal' ;
@@ -73,17 +73,11 @@ export class PythonTestController implements ITestController, IExtensionSingleAc
7373 // Map of workspace URI -> Map of project ID -> ProjectAdapter
7474 private readonly workspaceProjects : Map < Uri , Map < string , ProjectAdapter > > = new Map ( ) ;
7575
76- // Fast lookup maps for execution
77- // @ts -expect-error - used when useProjectBasedTesting=true
78- private readonly vsIdToProject : Map < string , ProjectAdapter > = new Map ( ) ;
79- // @ts -expect-error - used when useProjectBasedTesting=true
80- private readonly fileUriToProject : Map < string , ProjectAdapter > = new Map ( ) ;
81- // @ts -expect-error - used when useProjectBasedTesting=true
82- private readonly projectToVsIds : Map < string , Set < string > > = new Map ( ) ;
83-
84- // Temporary discovery state (created during discovery, cleared after)
85- // @ts -expect-error - used when useProjectBasedTesting=true
86- private readonly workspaceDiscoveryState : Map < Uri , WorkspaceDiscoveryState > = new Map ( ) ;
76+ // TODO: Phase 3-4 - Add these maps when implementing discovery and execution:
77+ // - vsIdToProject: Map<string, ProjectAdapter> - Fast lookup for test execution
78+ // - fileUriToProject: Map<string, ProjectAdapter> - File watching and change detection
79+ // - projectToVsIds: Map<string, Set<string>> - Project cleanup and refresh
80+ // - workspaceDiscoveryState: Map<Uri, WorkspaceDiscoveryState> - Temporary overlap detection
8781
8882 private readonly triggerTypes : TriggerType [ ] = [ ] ;
8983
@@ -236,51 +230,49 @@ export class PythonTestController implements ITestController, IExtensionSingleAc
236230 // Try to use project-based testing if environment extension is enabled
237231 if ( useEnvExtension ( ) ) {
238232 traceInfo ( '[test-by-project] Activating project-based testing mode' ) ;
239- try {
240- await Promise . all (
241- Array . from ( workspaces ) . map ( async ( workspace ) => {
242- traceInfo ( `[test-by-project] Processing workspace: ${ workspace . uri . fsPath } ` ) ;
243- try {
244- // Discover projects in this workspace
245- const projects = await this . discoverWorkspaceProjects ( workspace . uri ) ;
246-
247- // Create map for this workspace
248- const projectsMap = new Map < string , ProjectAdapter > ( ) ;
249- projects . forEach ( ( project ) => {
250- projectsMap . set ( project . projectId , project ) ;
251- } ) ;
252-
253- this . workspaceProjects . set ( workspace . uri , projectsMap ) ;
254-
255- traceInfo (
256- `[test-by-project] Discovered ${ projects . length } project(s) for workspace ${ workspace . uri . fsPath } ` ,
257- ) ;
258-
259- // Set up file watchers if auto-discovery is enabled
260- const settings = this . configSettings . getSettings ( workspace . uri ) ;
261- if ( settings . testing . autoTestDiscoverOnSaveEnabled ) {
262- traceVerbose ( `Testing: Setting up watcher for ${ workspace . uri . fsPath } ` ) ;
263- this . watchForSettingsChanges ( workspace ) ;
264- this . watchForTestContentChangeOnSave ( ) ;
265- }
266- } catch ( error ) {
267- traceError (
268- `[test-by-project] Failed to activate project-based testing for ${ workspace . uri . fsPath } :` ,
269- error ,
270- ) ;
271- traceInfo ( '[test-by-project] Falling back to legacy mode for this workspace' ) ;
272- // Fall back to legacy mode for this workspace
273- await this . activateLegacyWorkspace ( workspace ) ;
274- }
275- } ) ,
276- ) ;
277- return ;
278- } catch ( error ) {
279- traceError (
280- '[test-by-project] Failed to activate project-based testing, falling back to legacy mode:' ,
281- error ,
282- ) ;
283- }
233+
234+ // Use Promise.allSettled to allow partial success in multi-root workspaces
235+ const results = await Promise . allSettled (
236+ Array . from ( workspaces ) . map ( async ( workspace ) => {
237+ traceInfo ( `[test-by-project] Processing workspace: ${ workspace . uri . fsPath } ` ) ;
238+
239+ // Discover projects in this workspace
240+ const projects = await this . discoverWorkspaceProjects ( workspace . uri ) ;
241+
242+ // Create map for this workspace
243+ const projectsMap = new Map < string , ProjectAdapter > ( ) ;
244+ projects . forEach ( ( project ) => {
245+ projectsMap . set ( project . projectId , project ) ;
246+ } ) ;
247+
248+ traceInfo (
249+ `[test-by-project] Discovered ${ projects . length } project(s) for workspace ${ workspace . uri . fsPath } ` ,
250+ ) ;
251+
252+ return { workspace, projectsMap } ;
253+ } ) ,
254+ ) ;
255+
256+ // Handle results individually - allows partial success
257+ results . forEach ( ( result , index ) => {
258+ const workspace = workspaces [ index ] ;
259+ if ( result . status === 'fulfilled' ) {
260+ this . workspaceProjects . set ( workspace . uri , result . value . projectsMap ) ;
261+ traceInfo (
262+ `[test-by-project] Successfully activated ${ result . value . projectsMap . size } project(s) for ${ workspace . uri . fsPath } ` ,
263+ ) ;
264+ this . setupFileWatchers ( workspace ) ;
265+ } else {
266+ traceError (
267+ `[test-by-project] Failed to activate project-based testing for ${ workspace . uri . fsPath } :` ,
268+ result . reason ,
269+ ) ;
270+ traceInfo ( '[test-by-project] Falling back to legacy mode for this workspace' ) ;
271+ // Fall back to legacy mode for this workspace only
272+ this . activateLegacyWorkspace ( workspace ) ;
273+ }
274+ } ) ;
275+ return ;
284276 }
285277
286278 // Legacy activation (backward compatibility)
0 commit comments