@@ -14,6 +14,7 @@ import {
14
14
import { ICommandManager , IWorkspaceService } from '../../../common/application/types' ;
15
15
import '../../../common/extensions' ;
16
16
import { isNotInstalledError } from '../../../common/helpers' ;
17
+ import { traceError } from '../../../common/logger' ;
17
18
import { IFileSystem } from '../../../common/platform/types' ;
18
19
import { IConfigurationService , IDisposableRegistry , IInstaller , IOutputChannel , IPythonSettings , Product } from '../../../common/types' ;
19
20
import { getNamesAndValues } from '../../../common/utils/enum' ;
@@ -23,14 +24,15 @@ import { EventName } from '../../../telemetry/constants';
23
24
import { sendTelemetryEvent } from '../../../telemetry/index' ;
24
25
import { TestDiscoverytTelemetry , TestRunTelemetry } from '../../../telemetry/types' ;
25
26
import { IPythonUnitTestMessage , IUnitTestDiagnosticService , WorkspaceTestStatus } from '../../types' ;
26
- import { ITestsStatusUpdaterService } from '../types ' ;
27
+ import { copyTestResults } from '../testUtils ' ;
27
28
import { CANCELLATION_REASON , CommandSource , TEST_OUTPUT_CHANNEL } from './../constants' ;
28
29
import {
29
30
ITestCollectionStorageService ,
30
31
ITestDiscoveryService ,
31
32
ITestManager ,
32
33
ITestResultsService ,
33
34
ITestsHelper ,
35
+ ITestsStatusUpdaterService ,
34
36
TestDiscoveryOptions ,
35
37
TestProvider ,
36
38
Tests ,
@@ -56,19 +58,19 @@ export abstract class BaseTestManager implements ITestManager {
56
58
protected get testResultsService ( ) {
57
59
return this . _testResultsService ;
58
60
}
59
- private testCollectionStorage : ITestCollectionStorageService ;
60
- private _testResultsService : ITestResultsService ;
61
- private commandManager : ICommandManager ;
62
- private workspaceService : IWorkspaceService ;
63
- private _outputChannel : OutputChannel ;
61
+ private readonly testCollectionStorage : ITestCollectionStorageService ;
62
+ private readonly _testResultsService : ITestResultsService ;
63
+ private readonly commandManager : ICommandManager ;
64
+ private readonly workspaceService : IWorkspaceService ;
65
+ private readonly _outputChannel : OutputChannel ;
64
66
protected tests ?: Tests ;
65
67
private _status : TestStatus = TestStatus . Unknown ;
66
68
private testDiscoveryCancellationTokenSource ?: CancellationTokenSource ;
67
69
private testRunnerCancellationTokenSource ?: CancellationTokenSource ;
68
70
private _installer ! : IInstaller ;
69
- private testsStatusUpdaterService : ITestsStatusUpdaterService ;
71
+ private readonly testsStatusUpdaterService : ITestsStatusUpdaterService ;
70
72
private discoverTestsPromise ?: Promise < Tests > ;
71
- private _onDidStatusChange = new EventEmitter < WorkspaceTestStatus > ( ) ;
73
+ private readonly _onDidStatusChange = new EventEmitter < WorkspaceTestStatus > ( ) ;
72
74
private get installer ( ) : IInstaller {
73
75
if ( ! this . _installer ) {
74
76
this . _installer = this . serviceContainer . get < IInstaller > ( IInstaller ) ;
@@ -77,7 +79,7 @@ export abstract class BaseTestManager implements ITestManager {
77
79
}
78
80
constructor (
79
81
public readonly testProvider : TestProvider ,
80
- private product : Product ,
82
+ private readonly product : Product ,
81
83
public readonly workspaceFolder : Uri ,
82
84
protected rootDirectory : string ,
83
85
protected serviceContainer : IServiceContainer
@@ -133,15 +135,15 @@ export abstract class BaseTestManager implements ITestManager {
133
135
134
136
this . testResultsService . resetResults ( this . tests ! ) ;
135
137
}
136
- public async discoverTests ( cmdSource : CommandSource , ignoreCache : boolean = false , quietMode : boolean = false , userInitiated : boolean = false ) : Promise < Tests > {
138
+ public async discoverTests ( cmdSource : CommandSource , ignoreCache : boolean = false , quietMode : boolean = false , userInitiated : boolean = false , clearTestStatus : boolean = false ) : Promise < Tests > {
137
139
if ( this . discoverTestsPromise ) {
138
140
return this . discoverTestsPromise ;
139
141
}
140
- this . discoverTestsPromise = this . _discoverTests ( cmdSource , ignoreCache , quietMode , userInitiated ) ;
142
+ this . discoverTestsPromise = this . _discoverTests ( cmdSource , ignoreCache , quietMode , userInitiated , clearTestStatus ) ;
141
143
this . discoverTestsPromise . catch ( noop ) . then ( ( ) => this . discoverTestsPromise = undefined ) . ignoreErrors ( ) ;
142
144
return this . discoverTestsPromise ;
143
145
}
144
- private async _discoverTests ( cmdSource : CommandSource , ignoreCache : boolean = false , quietMode : boolean = false , userInitiated : boolean = false ) : Promise < Tests > {
146
+ private async _discoverTests ( cmdSource : CommandSource , ignoreCache : boolean = false , quietMode : boolean = false , userInitiated : boolean = false , clearTestStatus : boolean = false ) : Promise < Tests > {
145
147
if ( ! ignoreCache && this . tests ! && this . tests ! . testFunctions . length > 0 ) {
146
148
this . updateStatus ( TestStatus . Idle ) ;
147
149
return Promise . resolve ( this . tests ! ) ;
@@ -168,8 +170,16 @@ export abstract class BaseTestManager implements ITestManager {
168
170
return discoveryService
169
171
. discoverTests ( discoveryOptions )
170
172
. then ( tests => {
173
+ const wkspace = this . workspaceService . getWorkspaceFolder ( Uri . file ( this . rootDirectory ) ) ! . uri ;
174
+ const existingTests = this . testCollectionStorage . getTests ( wkspace ) ! ;
175
+ if ( clearTestStatus ) {
176
+ this . resetTestResults ( ) ;
177
+ } else if ( existingTests ) {
178
+ copyTestResults ( existingTests , tests ) ;
179
+ this . _testResultsService . updateResults ( tests ) ;
180
+ }
181
+ this . testCollectionStorage . storeTests ( wkspace , tests ) ;
171
182
this . tests = tests ;
172
- this . resetTestResults ( ) ;
173
183
this . updateStatus ( TestStatus . Idle ) ;
174
184
this . discoverTestsPromise = undefined ;
175
185
@@ -188,8 +198,6 @@ export abstract class BaseTestManager implements ITestManager {
188
198
const testsHelper = this . serviceContainer . get < ITestsHelper > ( ITestsHelper ) ;
189
199
testsHelper . displayTestErrorMessage ( 'There were some errors in discovering unit tests' ) ;
190
200
}
191
- const wkspace = this . workspaceService . getWorkspaceFolder ( Uri . file ( this . rootDirectory ) ) ! . uri ;
192
- this . testCollectionStorage . storeTests ( wkspace , tests ) ;
193
201
this . disposeCancellationToken ( CancellationTokenType . testDiscovery ) ;
194
202
sendTelemetryEvent ( EventName . UNITTEST_DISCOVER , undefined , telementryProperties ) ;
195
203
return tests ;
@@ -200,7 +208,7 @@ export abstract class BaseTestManager implements ITestManager {
200
208
}
201
209
if ( isNotInstalledError ( reason as Error ) && ! quietMode ) {
202
210
this . installer . promptToInstall ( this . product , this . workspaceFolder )
203
- . catch ( ex => console . error ( 'Python Extension: isNotInstalledError', ex ) ) ;
211
+ . catch ( ex => traceError ( ' isNotInstalledError', ex ) ) ;
204
212
}
205
213
206
214
this . tests = undefined ;
@@ -216,7 +224,7 @@ export abstract class BaseTestManager implements ITestManager {
216
224
this . outputChannel . appendLine ( reason . toString ( ) ) ;
217
225
}
218
226
const wkspace = this . workspaceService . getWorkspaceFolder ( Uri . file ( this . rootDirectory ) ) ! . uri ;
219
- this . testCollectionStorage . storeTests ( wkspace , null ) ;
227
+ this . testCollectionStorage . storeTests ( wkspace , undefined ) ;
220
228
this . disposeCancellationToken ( CancellationTokenType . testDiscovery ) ;
221
229
return Promise . reject ( reason ) ;
222
230
} ) ;
@@ -240,7 +248,6 @@ export abstract class BaseTestManager implements ITestManager {
240
248
} ;
241
249
242
250
if ( ! runFailedTests && ! testsToRun ) {
243
- this . resetTestResults ( ) ;
244
251
this . testsStatusUpdaterService . updateStatusAsRunning ( this . workspaceFolder , this . tests ) ;
245
252
}
246
253
@@ -419,7 +426,7 @@ export abstract class BaseTestManager implements ITestManager {
419
426
const stackStart = message . locationStack ! [ 0 ] ;
420
427
const diagPrefix = this . unitTestDiagnosticService . getMessagePrefix ( message . status ! ) ;
421
428
const severity = this . unitTestDiagnosticService . getSeverity ( message . severity ) ! ;
422
- const diagMsg = message . message ! . split ( '\n' ) [ 0 ] ;
429
+ const diagMsg = message . message ? message . message . split ( '\n' ) [ 0 ] : '' ;
423
430
const diagnostic = new Diagnostic ( stackStart . location . range , `${ diagPrefix ? `${ diagPrefix } : ` : '' } ${ diagMsg } ` , severity ) ;
424
431
diagnostic . code = message . code ;
425
432
diagnostic . source = message . provider ;
0 commit comments