@@ -6,7 +6,6 @@ import { Location, TestItem, TestMessage, TestRun, TestRunProfileKind } from 'vs
6
6
import { traceError , traceInfo } from '../../../common/logger' ;
7
7
import * as internalScripts from '../../../common/process/internal/scripts' ;
8
8
import { IOutputChannel } from '../../../common/types' ;
9
- import { createDeferred , Deferred } from '../../../common/utils/async' ;
10
9
import { noop } from '../../../common/utils/misc' ;
11
10
import { UNITTEST_PROVIDER } from '../../common/constants' ;
12
11
import { ITestRunner , ITestDebugLauncher , IUnitTestSocketServer , LaunchOptions , Options } from '../../common/types' ;
@@ -57,7 +56,23 @@ export class UnittestRunner implements ITestsRunner {
57
56
) : Promise < void > {
58
57
runInstance . appendOutput ( `Running tests (unittest): ${ testNodes . map ( ( t ) => t . id ) . join ( ' ; ' ) } \r\n` ) ;
59
58
const testCaseNodes : TestItem [ ] = [ ] ;
60
- testNodes . forEach ( ( t ) => testCaseNodes . push ( ...getTestCaseNodes ( t ) ) ) ;
59
+ const fileToTestCases : Map < string , TestItem [ ] > = new Map ( ) ;
60
+
61
+ testNodes . forEach ( ( t ) => {
62
+ const nodes = getTestCaseNodes ( t ) ;
63
+ nodes . forEach ( ( n ) => {
64
+ if ( n . uri ) {
65
+ const fsRunIds = fileToTestCases . get ( n . uri . fsPath ) ;
66
+ if ( fsRunIds ) {
67
+ fsRunIds . push ( n ) ;
68
+ } else {
69
+ fileToTestCases . set ( n . uri . fsPath , [ n ] ) ;
70
+ }
71
+ }
72
+ } ) ;
73
+ testCaseNodes . push ( ...nodes ) ;
74
+ } ) ;
75
+
61
76
const tested : string [ ] = [ ] ;
62
77
63
78
const counts = {
@@ -70,18 +85,15 @@ export class UnittestRunner implements ITestsRunner {
70
85
71
86
let failFast = false ;
72
87
let stopTesting = false ;
73
- let testCasePromise : Deferred < void > ;
74
88
this . server . on ( 'error' , ( message : string , ...data : string [ ] ) => {
75
89
traceError ( `${ message } ${ data . join ( ' ' ) } ` ) ;
76
- testCasePromise . reject ( ) ;
77
90
} ) ;
78
91
this . server . on ( 'log' , ( message : string , ...data : string [ ] ) => {
79
92
traceInfo ( `${ message } ${ data . join ( ' ' ) } ` ) ;
80
93
} ) ;
81
94
this . server . on ( 'connect' , noop ) ;
82
95
this . server . on ( 'start' , noop ) ;
83
96
this . server . on ( 'result' , ( data : ITestData ) => {
84
- testCasePromise . resolve ( ) ;
85
97
const testCase = testCaseNodes . find ( ( node ) => idToRawData . get ( node . id ) ?. runId === data . test ) ;
86
98
const rawTestCase = idToRawData . get ( testCase ?. id ?? '' ) ;
87
99
if ( testCase && rawTestCase ) {
@@ -147,18 +159,15 @@ export class UnittestRunner implements ITestsRunner {
147
159
} ) ;
148
160
149
161
const port = await this . server . start ( ) ;
150
- const runTestInternal = async ( testFile = '' , testId = '' ) : Promise < void > => {
162
+ const runTestInternal = async ( testFilePath : string , testRunIds : string [ ] ) : Promise < void > => {
151
163
let testArgs = getTestRunArgs ( options . args ) ;
152
164
failFast = testArgs . indexOf ( '--uf' ) >= 0 ;
153
165
testArgs = testArgs . filter ( ( arg ) => arg !== '--uf' ) ;
154
166
155
167
testArgs . push ( `--result-port=${ port } ` ) ;
156
- if ( testId . length > 0 ) {
157
- testArgs . push ( `-t${ testId } ` ) ;
158
- }
159
- if ( testFile . length > 0 ) {
160
- testArgs . push ( `--testFile=${ testFile } ` ) ;
161
- }
168
+ testRunIds . forEach ( ( i ) => testArgs . push ( `-t${ i } ` ) ) ;
169
+ testArgs . push ( `--testFile=${ testFilePath } ` ) ;
170
+
162
171
if ( options . debug === true ) {
163
172
testArgs . push ( '--debug' ) ;
164
173
const launchOptions : LaunchOptions = {
@@ -179,23 +188,30 @@ export class UnittestRunner implements ITestsRunner {
179
188
token : options . token ,
180
189
workspaceFolder : options . workspaceFolder ,
181
190
} ;
182
- testCasePromise = createDeferred ( ) ;
183
191
await this . runner . run ( UNITTEST_PROVIDER , runOptions ) ;
184
- return testCasePromise . promise ;
192
+ return Promise . resolve ( ) ;
185
193
} ;
186
194
187
195
try {
188
- for ( const testCaseNode of testCaseNodes ) {
196
+ for ( const testFile of fileToTestCases . keys ( ) ) {
189
197
if ( stopTesting || options . token . isCancellationRequested ) {
190
198
break ;
191
199
}
192
- runInstance . appendOutput ( `Running tests: ${ testCaseNode . id } \r\n` ) ;
193
- const rawTestCaseNode = idToRawData . get ( testCaseNode . id ) ;
194
- if ( rawTestCaseNode ) {
195
- // VS Code API requires that we set the run state on the leaf nodes. The state of the
196
- // parent nodes are computed based on the state of child nodes.
197
- runInstance . started ( testCaseNode ) ;
198
- await runTestInternal ( testCaseNode . uri ?. fsPath , rawTestCaseNode . runId ) ;
200
+
201
+ const nodes = fileToTestCases . get ( testFile ) ;
202
+ if ( nodes ) {
203
+ runInstance . appendOutput ( `Running tests: ${ nodes . join ( '\r\n' ) } \r\n` ) ;
204
+ const runIds : string [ ] = [ ] ;
205
+ nodes . forEach ( ( n ) => {
206
+ const rawNode = idToRawData . get ( n . id ) ;
207
+ if ( rawNode ) {
208
+ // VS Code API requires that we set the run state on the leaf nodes. The state of the
209
+ // parent nodes are computed based on the state of child nodes.
210
+ runInstance . started ( n ) ;
211
+ runIds . push ( rawNode . runId ) ;
212
+ }
213
+ } ) ;
214
+ await runTestInternal ( testFile , runIds ) ;
199
215
}
200
216
}
201
217
} catch ( ex ) {
0 commit comments