@@ -52,20 +52,28 @@ export class TestRunProxy {
5252 private runStarted : boolean = false ;
5353 private queuedOutput : string [ ] = [ ] ;
5454 private _testItems : vscode . TestItem [ ] ;
55+ private iteration : number | undefined ;
5556 public coverage : TestCoverage ;
5657
58+ public testRunCompleteEmitter = new vscode . EventEmitter < void > ( ) ;
59+ public onTestRunComplete : vscode . Event < void > ;
60+
5761 // 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+ }
6977
7078 public get testItems ( ) : vscode . TestItem [ ] {
7179 return this . _testItems ;
@@ -79,6 +87,7 @@ export class TestRunProxy {
7987 ) {
8088 this . _testItems = args . testItems ;
8189 this . coverage = new TestCoverage ( folderContext ) ;
90+ this . onTestRunComplete = this . testRunCompleteEmitter . event ;
8291 }
8392
8493 public testRunStarted = ( ) => {
@@ -194,20 +203,37 @@ export class TestRunProxy {
194203
195204 public async end ( ) {
196205 this . testRun ?. end ( ) ;
206+ this . testRunCompleteEmitter . fire ( ) ;
207+ }
208+
209+ public setIteration ( iteration : number ) {
210+ this . runState = TestRunProxy . initialTestRunState ( ) ;
211+ this . iteration = iteration ;
197212 }
198213
199214 public appendOutput ( output : string ) {
215+ const tranformedOutput = this . prependIterationToOutput ( output ) ;
200216 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 ) ;
203219 } else {
204- this . queuedOutput . push ( output ) ;
220+ this . queuedOutput . push ( tranformedOutput ) ;
205221 }
206222 }
207223
208224 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 ( "" ) ?? "" ;
211237 }
212238
213239 public async computeCoverage ( ) {
@@ -222,7 +248,7 @@ export class TestRunProxy {
222248
223249/** Class used to run tests */
224250export class TestRunner {
225- private testRun : TestRunProxy ;
251+ public testRun : TestRunProxy ;
226252 private testArgs : TestRunArguments ;
227253 private xcTestOutputParser : IXCTestOutputParser ;
228254 private swiftTestOutputParser : SwiftTestingOutputParser ;
@@ -256,6 +282,20 @@ export class TestRunner {
256282 ) ;
257283 }
258284
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+
259299 /**
260300 * If the request has no test items to include in the run,
261301 * default to usig all the items in the `TestController`.
@@ -587,6 +627,7 @@ export class TestRunner {
587627 task . execution . onDidWrite ( str => {
588628 const replaced = str
589629 . 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, "" )
590631 . replace (
591632 / 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,
592633 ""
@@ -1051,7 +1092,7 @@ export class TestRunnerTestRunState implements ITestRunState {
10511092 }
10521093
10531094 const isSuite = test . children . size > 0 ;
1054- const issues = isSuite ? this . childrensIssues ( test ) : this . issues . get ( index ) ?? [ ] ;
1095+ const issues = isSuite ? this . childrensIssues ( test ) : this . pluckIssues ( index ) ?? [ ] ;
10551096 if ( issues . length > 0 ) {
10561097 const allUnknownIssues = issues . filter ( ( { isKnown } ) => ! isKnown ) ;
10571098 if ( allUnknownIssues . length === 0 ) {
@@ -1076,14 +1117,24 @@ export class TestRunnerTestRunState implements ITestRunState {
10761117 this . currentTestItem = undefined ;
10771118 }
10781119
1120+ // Removes and returns the issues at the supplied test index.
1121+ private pluckIssues ( index : number ) : {
1122+ isKnown : boolean ;
1123+ message : vscode . TestMessage ;
1124+ } [ ] {
1125+ const issues = this . issues . get ( index ) ?? [ ] ;
1126+ this . issues . delete ( index ) ;
1127+ return issues ;
1128+ }
1129+
10791130 // Gather the issues of test children into a flat collection.
10801131 private childrensIssues ( test : vscode . TestItem ) : {
10811132 isKnown : boolean ;
10821133 message : vscode . TestMessage ;
10831134 } [ ] {
10841135 const index = this . getTestItemIndex ( test . id ) ;
10851136 return [
1086- ...( this . issues . get ( index ) ?? [ ] ) ,
1137+ ...( this . pluckIssues ( index ) ?? [ ] ) ,
10871138 ...reduceTestItemChildren (
10881139 test . children ,
10891140 ( acc , test ) => [
0 commit comments