@@ -39,10 +39,86 @@ export class TestResolver implements OnModuleInit, vscode.Disposable {
3939
4040 onModuleInit ( ) {
4141 this . ctx . subscriptions . push ( this )
42+ this . restorePriorTests ( )
43+ . catch ( e => {
44+ this . outputChannel . appendLine ( `Error restoring prior tests: ${ e } ` )
45+ } )
46+ . finally ( ( ) => {
47+ this . registerHandlers ( )
48+ } )
49+ }
50+
51+ registerHandlers ( ) {
4252 this . store . testController . resolveHandler = this . resolveHandler . bind ( this )
4353 this . store . testController . refreshHandler = this . refreshHandler . bind ( this )
4454 }
4555
56+ private async restorePriorTests ( ) {
57+ await this . resolveRoot ( )
58+ const cachedBuildTargetsResult = this . store . getCachedBuildTargetsResult ( )
59+
60+ // Restore the root test item and build targets.
61+ let addedTargets = false
62+ if ( cachedBuildTargetsResult ) {
63+ this . outputChannel . appendLine ( 'Restoring prior test cases' )
64+ const root = this . store . testController . items . get ( 'root' )
65+ if ( root ) {
66+ try {
67+ this . outputChannel . appendLine ( 'Restoring Source Files for Root' )
68+ await this . processWorkspaceBuildTargetsResult (
69+ root ,
70+ cachedBuildTargetsResult
71+ )
72+ root . canResolveChildren = false
73+ addedTargets = true
74+ } catch ( e ) {
75+ this . outputChannel . appendLine (
76+ `Error restoring source files for root: ${ e } `
77+ )
78+ }
79+ }
80+ }
81+
82+ // Restore cached source files for targets that have them.
83+ const promises : Promise < void > [ ] = [ ]
84+ for ( const [ key , testItem ] of this . store . targetIdentifiers . entries ( ) ) {
85+ let cachedSourceFiles : bsp . SourcesResult | undefined
86+ try {
87+ const target : bsp . BuildTargetIdentifier = JSON . parse ( key )
88+ const sourceParams : bsp . SourcesParams = {
89+ targets : [ target ] ,
90+ }
91+ cachedSourceFiles = this . store . getCachedSourcesResult ( sourceParams )
92+ } catch ( e ) {
93+ this . outputChannel . appendLine (
94+ `Invalid key '${ key } ' when restoring source files: ${ e } `
95+ )
96+ }
97+
98+ if ( cachedSourceFiles ) {
99+ this . outputChannel . appendLine (
100+ `Restoring source files for target: ${ key } `
101+ )
102+ try {
103+ testItem . canResolveChildren = false
104+ const promise = this . processTargetSourcesResult (
105+ testItem ,
106+ cachedSourceFiles
107+ )
108+ promises . push ( promise )
109+ } catch ( e ) {
110+ this . outputChannel . appendLine (
111+ `Error restoring source files for target: ${ key } `
112+ )
113+ }
114+ }
115+ }
116+ await Promise . all ( promises )
117+
118+ // Kick off discovery of test cases in other open files that may not have been discovered yet.
119+ if ( addedTargets ) await this . resolveOpenSourceFiles ( )
120+ }
121+
46122 dispose ( ) { }
47123
48124 private async resolveHandler (
@@ -74,7 +150,6 @@ export class TestResolver implements OnModuleInit, vscode.Disposable {
74150 if ( parentTest === undefined ) {
75151 try {
76152 await this . buildServer . getConnection ( )
77- this . resolveRoot ( )
78153 } catch ( e ) {
79154 this . outputChannel . appendLine (
80155 'Test explorer disabled due to lack of available build server.'
@@ -102,6 +177,7 @@ export class TestResolver implements OnModuleInit, vscode.Disposable {
102177 'Fetching test targets from build server ([progress](command:bazelbsp.showServerOutput))' ,
103178 } )
104179 await this . resolveTargets ( parentTest , combinedToken )
180+ await this . resolveOpenSourceFiles ( )
105181 break
106182 case TestItemType . BazelTarget :
107183 progress . report ( {
@@ -124,6 +200,7 @@ export class TestResolver implements OnModuleInit, vscode.Disposable {
124200 * @param token Cancellation token tied to the refresh button on the VS Code UI.
125201 */
126202 private async refreshHandler ( token : vscode . CancellationToken ) {
203+ this . store . clearCache ( )
127204 const promises : Promise < void > [ ] = [ ]
128205 this . store . testController . items . forEach ( async item => {
129206 promises . push ( this . resolveHandler ( item , token ) )
@@ -173,6 +250,7 @@ export class TestResolver implements OnModuleInit, vscode.Disposable {
173250 bsp . WorkspaceBuildTargets . type ,
174251 cancellationToken
175252 )
253+ this . store . cacheBuildTargetsResult ( result )
176254 } catch ( e ) {
177255 if ( e . code === CANCEL_ERROR_CODE ) {
178256 updateDescription (
@@ -184,7 +262,13 @@ export class TestResolver implements OnModuleInit, vscode.Disposable {
184262 updateDescription ( parentTest , 'Error: unable to fetch targets' )
185263 throw e
186264 }
265+ await this . processWorkspaceBuildTargetsResult ( parentTest , result )
266+ }
187267
268+ private async processWorkspaceBuildTargetsResult (
269+ parentTest : vscode . TestItem ,
270+ result : bsp . WorkspaceBuildTargetsResult
271+ ) {
188272 updateDescription ( parentTest , 'Loading: processing target results' )
189273
190274 // Process the returned targets, create new test items, and store their metadata.
@@ -243,8 +327,6 @@ export class TestResolver implements OnModuleInit, vscode.Disposable {
243327 // Replace all children with the newly returned test cases.
244328 this . condenseTestItems ( parentTest )
245329 updateDescription ( parentTest )
246-
247- await this . resolveOpenSourceFiles ( )
248330 }
249331
250332 /**
@@ -357,6 +439,17 @@ export class TestResolver implements OnModuleInit, vscode.Disposable {
357439 params ,
358440 cancellationToken
359441 )
442+ this . store . cacheSourcesResult ( params , result )
443+ await this . processTargetSourcesResult ( parentTest , result )
444+ }
445+
446+ private async processTargetSourcesResult (
447+ parentTest : vscode . TestItem ,
448+ result : bsp . SourcesResult ,
449+ cancellationToken ?: vscode . CancellationToken
450+ ) {
451+ const parentTarget = this . store . testCaseMetadata . get ( parentTest ) ?. target
452+ if ( ! parentTarget ) return
360453
361454 const directories = new Map < string , vscode . TestItem > ( )
362455 parentTest . children . replace ( [ ] )
0 commit comments