@@ -52,20 +52,28 @@ export class TestRunProxy {
52
52
private runStarted : boolean = false ;
53
53
private queuedOutput : string [ ] = [ ] ;
54
54
private _testItems : vscode . TestItem [ ] ;
55
+ private iteration : number | undefined ;
55
56
public coverage : TestCoverage ;
56
57
58
+ public testRunCompleteEmitter = new vscode . EventEmitter < void > ( ) ;
59
+ public onTestRunComplete : vscode . Event < void > ;
60
+
57
61
// Allows for introspection on the state of TestItems after a test run.
58
- public runState = {
59
- failed : [ ] as {
60
- test : vscode . TestItem ;
61
- message : vscode . TestMessage | readonly vscode . TestMessage [ ] ;
62
- } [ ] ,
63
- passed : [ ] as vscode . TestItem [ ] ,
64
- skipped : [ ] as vscode . TestItem [ ] ,
65
- errored : [ ] as vscode . TestItem [ ] ,
66
- unknown : 0 ,
67
- output : [ ] as string [ ] ,
68
- } ;
62
+ public runState = TestRunProxy . initialTestRunState ( ) ;
63
+
64
+ private static initialTestRunState ( ) {
65
+ return {
66
+ failed : [ ] as {
67
+ test : vscode . TestItem ;
68
+ message : vscode . TestMessage | readonly vscode . TestMessage [ ] ;
69
+ } [ ] ,
70
+ passed : [ ] as vscode . TestItem [ ] ,
71
+ skipped : [ ] as vscode . TestItem [ ] ,
72
+ errored : [ ] as vscode . TestItem [ ] ,
73
+ unknown : 0 ,
74
+ output : [ ] as string [ ] ,
75
+ } ;
76
+ }
69
77
70
78
public get testItems ( ) : vscode . TestItem [ ] {
71
79
return this . _testItems ;
@@ -79,6 +87,7 @@ export class TestRunProxy {
79
87
) {
80
88
this . _testItems = args . testItems ;
81
89
this . coverage = new TestCoverage ( folderContext ) ;
90
+ this . onTestRunComplete = this . testRunCompleteEmitter . event ;
82
91
}
83
92
84
93
public testRunStarted = ( ) => {
@@ -194,20 +203,37 @@ export class TestRunProxy {
194
203
195
204
public async end ( ) {
196
205
this . testRun ?. end ( ) ;
206
+ this . testRunCompleteEmitter . fire ( ) ;
207
+ }
208
+
209
+ public setIteration ( iteration : number ) {
210
+ this . runState = TestRunProxy . initialTestRunState ( ) ;
211
+ this . iteration = iteration ;
197
212
}
198
213
199
214
public appendOutput ( output : string ) {
215
+ const tranformedOutput = this . prependIterationToOutput ( output ) ;
200
216
if ( this . testRun ) {
201
- this . testRun . appendOutput ( output ) ;
202
- this . runState . output . push ( output ) ;
217
+ this . testRun . appendOutput ( tranformedOutput ) ;
218
+ this . runState . output . push ( tranformedOutput ) ;
203
219
} else {
204
- this . queuedOutput . push ( output ) ;
220
+ this . queuedOutput . push ( tranformedOutput ) ;
205
221
}
206
222
}
207
223
208
224
public appendOutputToTest ( output : string , test : vscode . TestItem , location ?: vscode . Location ) {
209
- this . testRun ?. appendOutput ( output , location , test ) ;
210
- this . runState . output . push ( output ) ;
225
+ const tranformedOutput = this . prependIterationToOutput ( output ) ;
226
+ this . testRun ?. appendOutput ( tranformedOutput , location , test ) ;
227
+ this . runState . output . push ( tranformedOutput ) ;
228
+ }
229
+
230
+ private prependIterationToOutput ( output : string ) : string {
231
+ if ( this . iteration === undefined ) {
232
+ return output ;
233
+ }
234
+ const itr = this . iteration + 1 ;
235
+ const lines = output . match ( / [ ^ \r \n ] * [ \r \n ] * / g) ;
236
+ return lines ?. map ( line => ( line ? `\x1b[34mRun ${ itr } \x1b[0m ${ line } ` : "" ) ) . join ( "" ) ?? "" ;
211
237
}
212
238
213
239
public async computeCoverage ( ) {
@@ -222,7 +248,7 @@ export class TestRunProxy {
222
248
223
249
/** Class used to run tests */
224
250
export class TestRunner {
225
- private testRun : TestRunProxy ;
251
+ public testRun : TestRunProxy ;
226
252
private testArgs : TestRunArguments ;
227
253
private xcTestOutputParser : IXCTestOutputParser ;
228
254
private swiftTestOutputParser : SwiftTestingOutputParser ;
@@ -256,6 +282,20 @@ export class TestRunner {
256
282
) ;
257
283
}
258
284
285
+ /**
286
+ * When performing a "Run test multiple times" run set the iteration
287
+ * so it can be shown in the logs.
288
+ * @param iteration The iteration counter
289
+ */
290
+ public setIteration ( iteration : number ) {
291
+ // The SwiftTestingOutputParser holds state and needs to be reset between iterations.
292
+ this . swiftTestOutputParser = new SwiftTestingOutputParser (
293
+ this . testRun . testRunStarted ,
294
+ this . testRun . addParameterizedTestCase
295
+ ) ;
296
+ this . testRun . setIteration ( iteration ) ;
297
+ }
298
+
259
299
/**
260
300
* If the request has no test items to include in the run,
261
301
* default to usig all the items in the `TestController`.
@@ -587,6 +627,7 @@ export class TestRunner {
587
627
task . execution . onDidWrite ( str => {
588
628
const replaced = str
589
629
. replace ( "[1/1] Planning build" , "" ) // Work around SPM still emitting progress when doing --no-build.
630
+ . replace ( / \[ 1 \/ 1 \] W r i t e s w i f t - v e r s i o n - .* / gm, "" )
590
631
. replace (
591
632
/ L L V M P r o f i l e E r r o r : F a i l e d t o w r i t e f i l e " d e f a u l t .p r o f r a w " : O p e r a t i o n n o t p e r m i t t e d \r \n / gm,
592
633
""
@@ -1023,6 +1064,7 @@ export class TestRunnerTestRunState implements ITestRunState {
1023
1064
return ;
1024
1065
}
1025
1066
const testItem = this . testRun . testItems [ index ] ;
1067
+ this . issues . delete ( index ) ;
1026
1068
this . testRun . started ( testItem ) ;
1027
1069
this . currentTestItem = testItem ;
1028
1070
this . startTimes . set ( index , startTime ) ;
0 commit comments