@@ -25,27 +25,26 @@ import { Version } from "../../src/utilities/version";
2525import { folderContextPromise , globalWorkspaceContextPromise } from "./extension.test" ;
2626import { Workbench } from "../../src/utilities/commands" ;
2727
28- const waitForDiagnostics = ( uris : vscode . Uri [ ] , allowEmpty : boolean = true ) =>
29- new Promise < void > ( res =>
30- vscode . languages . onDidChangeDiagnostics ( e => {
31- const paths = e . uris . map ( u => u . fsPath ) ;
32- for ( const uri of uris ) {
33- if ( ! paths . includes ( uri . fsPath ) ) {
34- return ;
35- }
36- if ( ! allowEmpty && ! vscode . languages . getDiagnostics ( uri ) . length ) {
37- return ;
38- }
39- }
40- res ( ) ;
41- } )
28+ const isEqual = ( d1 : vscode . Diagnostic , d2 : vscode . Diagnostic ) => {
29+ console . log ( ">>> Compare severity:" , d1 . severity === d2 . severity , d1 . severity , d2 . severity ) ;
30+ console . log ( ">>> Compare source :" , d1 . source === d2 . source , d1 . source , d2 . source ) ;
31+ console . log ( ">>> Compare: message:" , d1 . message === d2 . message , d1 . message , d2 . message ) ;
32+ console . log (
33+ ">>> Compare: range :" ,
34+ d1 . range . isEqual ( d2 . range ) ,
35+ d1 . range . start ,
36+ d1 . range . end ,
37+ "==" ,
38+ d2 . range . start ,
39+ d2 . range . end
4240 ) ;
43-
44- const isEqual = ( d1 : vscode . Diagnostic , d2 : vscode . Diagnostic ) =>
45- d1 . severity === d2 . severity &&
46- d1 . source === d2 . source &&
47- d1 . message === d2 . message &&
48- d1 . range . isEqual ( d2 . range ) ;
41+ return (
42+ d1 . severity === d2 . severity &&
43+ d1 . source === d2 . source &&
44+ d1 . message === d2 . message &&
45+ d1 . range . isEqual ( d2 . range )
46+ ) ;
47+ } ;
4948
5049const findDiagnostic = ( expected : vscode . Diagnostic ) => ( d : vscode . Diagnostic ) =>
5150 isEqual ( d , expected ) ;
@@ -56,7 +55,7 @@ function assertHasDiagnostic(uri: vscode.Uri, expected: vscode.Diagnostic): vsco
5655 assert . notEqual (
5756 diagnostic ,
5857 undefined ,
59- `Could not find diagnostic matching:\n${ JSON . stringify ( expected ) } `
58+ `Could not find diagnostic matching:\n${ JSON . stringify ( expected ) } \nDiagnostics found:\n ${ JSON . stringify ( diagnostics ) } `
6059 ) ;
6160 return diagnostic ! ;
6261}
@@ -90,9 +89,55 @@ suite("DiagnosticsManager Test Suite", async function () {
9089 let cUri : vscode . Uri ;
9190 let cppUri : vscode . Uri ;
9291 let cppHeaderUri : vscode . Uri ;
92+ let diagnosticWaiterDisposable : vscode . Disposable | undefined ;
93+
94+ // Wait for all the expected diagnostics to be recieved. This may happen over several `onChangeDiagnostics` events.
95+ const waitForDiagnostics = ( expectedDiagnostics : { [ uri : string ] : vscode . Diagnostic [ ] } ) => {
96+ return new Promise < void > ( resolve => {
97+ if ( diagnosticWaiterDisposable ) {
98+ console . warn (
99+ "Wait for diagnostics was called before the previous wait was resolved. Only one waitForDiagnostics should run per test."
100+ ) ;
101+ diagnosticWaiterDisposable ?. dispose ( ) ;
102+ }
103+ // Keep a lookup of diagnostics we haven't encountered yet. When all array values in
104+ // this lookup are empty then we've seen all diagnostics and we can resolve successfully.
105+ const expected = { ...expectedDiagnostics } ;
106+ diagnosticWaiterDisposable = vscode . languages . onDidChangeDiagnostics ( e => {
107+ console . log ( ">>> DiagnosticManager.test.ts: onDidChangeDiagnostics" , e . uris ) ;
108+
109+ const matchingPaths = Object . keys ( expectedDiagnostics ) . filter ( uri =>
110+ e . uris . some ( u => u . fsPath === uri )
111+ ) ;
112+ console . log ( ">>> Got diag for matching paths" , matchingPaths ) ;
113+ for ( const uri of matchingPaths ) {
114+ const actualDiagnostics = vscode . languages . getDiagnostics (
115+ vscode . Uri . parse ( uri )
116+ ) ;
117+ console . log ( ">>> " , uri , "Actual diagnostics" , actualDiagnostics ) ;
118+ console . log ( ">>> " , uri , "before" , expected [ uri ] . length ) ;
119+ expected [ uri ] = expected [ uri ] . filter ( expectedDiagnostic => {
120+ return ! actualDiagnostics . some ( actualDiagnostic =>
121+ isEqual ( actualDiagnostic , expectedDiagnostic )
122+ ) ;
123+ } ) ;
124+ console . log ( ">>> " , uri , "after" , expected [ uri ] . length ) ;
125+ }
126+
127+ const allDiagnosticsFulfilled = Object . values ( expected ) . every (
128+ diagnostics => diagnostics . length === 0
129+ ) ;
130+
131+ if ( allDiagnosticsFulfilled ) {
132+ diagnosticWaiterDisposable ?. dispose ( ) ;
133+ resolve ( ) ;
134+ }
135+ } ) ;
136+ } ) ;
137+ } ;
93138
94139 suiteSetup ( async function ( ) {
95- this . timeout ( 30000 ) ;
140+ this . timeout ( 60000 ) ;
96141
97142 workspaceContext = await globalWorkspaceContextPromise ;
98143 toolchain = workspaceContext . toolchain ;
@@ -111,6 +156,10 @@ suite("DiagnosticsManager Test Suite", async function () {
111156 ) ;
112157 } ) ;
113158
159+ teardown ( ( ) => {
160+ diagnosticWaiterDisposable ?. dispose ( ) ;
161+ } ) ;
162+
114163 suite ( "Parse diagnostics" , async ( ) => {
115164 suite ( "Parse from task output" , async ( ) => {
116165 const expectedWarningDiagnostic = new vscode . Diagnostic (
@@ -152,21 +201,22 @@ suite("DiagnosticsManager Test Suite", async function () {
152201 await swiftConfig . update ( "diagnosticsStyle" , undefined ) ;
153202 } ) ;
154203
155- test ( "default diagnosticsStyle" , async ( ) => {
204+ test . only ( "default diagnosticsStyle" , async ( ) => {
205+ console . log ( ">>> Updating diagnosticsStyle to default" ) ;
156206 await swiftConfig . update ( "diagnosticsStyle" , "default" ) ;
157- const task = createBuildAllTask ( folderContext ) ;
158- // Run actual task
159- const promise = waitForDiagnostics ( [ mainUri , funcUri ] ) ;
160- await executeTaskAndWaitForResult ( task ) ;
161- await promise ;
162- await waitForNoRunningTasks ( ) ;
163207
164- // Should have parsed correct severity
165- assertHasDiagnostic ( mainUri , expectedWarningDiagnostic ) ;
166- assertHasDiagnostic ( mainUri , expectedMainErrorDiagnostic ) ;
167- // Check parsed for other file
168- assertHasDiagnostic ( funcUri , expectedFuncErrorDiagnostic ) ;
169- } ) . timeout ( 2 * 60 * 1000 ) ; // Allow 2 minutes to build
208+ console . log ( ">>> Running actual task and waiting for diagnostics" ) ;
209+ await Promise . all ( [
210+ executeTaskAndWaitForResult ( createBuildAllTask ( folderContext ) ) ,
211+ waitForDiagnostics ( {
212+ [ mainUri . fsPath ] : [ expectedWarningDiagnostic , expectedMainErrorDiagnostic ] , // Should have parsed correct severity
213+ [ funcUri . fsPath ] : [ expectedFuncErrorDiagnostic ] , // Check parsed for other file
214+ } ) ,
215+ ] ) ;
216+
217+ console . log ( ">>> Waiting for no running tasks" ) ;
218+ await waitForNoRunningTasks ( ) ;
219+ } ) ;
170220
171221 test ( "swift diagnosticsStyle" , async function ( ) {
172222 // This is only supported in swift versions >=5.10.0
@@ -176,31 +226,29 @@ suite("DiagnosticsManager Test Suite", async function () {
176226 return ;
177227 }
178228 await swiftConfig . update ( "diagnosticsStyle" , "swift" ) ;
179- const task = createBuildAllTask ( folderContext ) ;
180- // Run actual task
181- const promise = waitForDiagnostics ( [ mainUri , funcUri ] ) ;
182- await executeTaskAndWaitForResult ( task ) ;
183- await promise ;
229+ await Promise . all ( [
230+ executeTaskAndWaitForResult ( createBuildAllTask ( folderContext ) ) ,
231+ waitForDiagnostics ( {
232+ [ mainUri . fsPath ] : [ expectedWarningDiagnostic , expectedMainErrorDiagnostic ] , // Should have parsed correct severity
233+ [ funcUri . fsPath ] : [ expectedFuncErrorDiagnostic ] , // Check parsed for other file
234+ } ) ,
235+ ] ) ;
184236 await waitForNoRunningTasks ( ) ;
185-
186- // Should have parsed severity
187- assertHasDiagnostic ( mainUri , expectedWarningDiagnostic ) ;
188- assertHasDiagnostic ( mainUri , expectedMainErrorDiagnostic ) ;
189- // Check parsed for other file
190- assertHasDiagnostic ( funcUri , expectedFuncErrorDiagnostic ) ;
191- } ) . timeout ( 2 * 60 * 1000 ) ; // Allow 2 minutes to build
237+ } ) ;
192238
193239 test ( "llvm diagnosticsStyle" , async ( ) => {
194240 await swiftConfig . update ( "diagnosticsStyle" , "llvm" ) ;
195- const task = createBuildAllTask ( folderContext ) ;
196- // Run actual task
197- const promise = waitForDiagnostics ( [ mainUri , funcUri ] ) ;
198- await executeTaskAndWaitForResult ( task ) ;
199- await promise ;
241+
242+ await Promise . all ( [
243+ executeTaskAndWaitForResult ( createBuildAllTask ( folderContext ) ) ,
244+ waitForDiagnostics ( {
245+ [ mainUri . fsPath ] : [ expectedWarningDiagnostic , expectedMainErrorDiagnostic ] , // Should have parsed correct severity
246+ [ funcUri . fsPath ] : [ expectedFuncErrorDiagnostic ] , // Check parsed for other file
247+ } ) ,
248+ ] ) ;
200249 await waitForNoRunningTasks ( ) ;
201250
202251 // Should have parsed severity
203- assertHasDiagnostic ( mainUri , expectedWarningDiagnostic ) ;
204252 const diagnostic = assertHasDiagnostic ( mainUri , expectedMainErrorDiagnostic ) ;
205253 // Should have parsed related note
206254 assert . equal ( diagnostic . relatedInformation ?. length , 1 ) ;
@@ -215,9 +263,7 @@ suite("DiagnosticsManager Test Suite", async function () {
215263 ) ,
216264 true
217265 ) ;
218- // Check parsed for other file
219- assertHasDiagnostic ( funcUri , expectedFuncErrorDiagnostic ) ;
220- } ) . timeout ( 2 * 60 * 1000 ) ; // Allow 2 minutes to build
266+ } ) ;
221267
222268 test ( "Parses C diagnostics" , async function ( ) {
223269 const swiftVersion = workspaceContext . toolchain . swiftVersion ;
@@ -228,12 +274,6 @@ suite("DiagnosticsManager Test Suite", async function () {
228274 }
229275
230276 await swiftConfig . update ( "diagnosticsStyle" , "llvm" ) ;
231- const task = createBuildAllTask ( cFolderContext ) ;
232- // Run actual task
233- const promise = waitForDiagnostics ( [ cUri ] ) ;
234- await executeTaskAndWaitForResult ( task ) ;
235- await promise ;
236- await waitForNoRunningTasks ( ) ;
237277
238278 // Should have parsed severity
239279 const expectedDiagnostic1 = new vscode . Diagnostic (
@@ -249,8 +289,13 @@ suite("DiagnosticsManager Test Suite", async function () {
249289 ) ;
250290 expectedDiagnostic2 . source = "swiftc" ;
251291
252- assertHasDiagnostic ( cUri , expectedDiagnostic1 ) ;
253- assertHasDiagnostic ( cUri , expectedDiagnostic2 ) ;
292+ await Promise . all ( [
293+ executeTaskAndWaitForResult ( createBuildAllTask ( cFolderContext ) ) ,
294+ waitForDiagnostics ( {
295+ [ cUri . fsPath ] : [ expectedDiagnostic1 , expectedDiagnostic2 ] ,
296+ } ) ,
297+ ] ) ;
298+ await waitForNoRunningTasks ( ) ;
254299 } ) ;
255300
256301 test ( "Parses C++ diagnostics" , async function ( ) {
@@ -262,12 +307,6 @@ suite("DiagnosticsManager Test Suite", async function () {
262307 }
263308
264309 await swiftConfig . update ( "diagnosticsStyle" , "llvm" ) ;
265- const task = createBuildAllTask ( cppFolderContext ) ;
266- // Run actual task
267- const promise = waitForDiagnostics ( [ cppUri ] ) ;
268- await executeTaskAndWaitForResult ( task ) ;
269- await promise ;
270- await waitForNoRunningTasks ( ) ;
271310
272311 // Should have parsed severity
273312 const expectedDiagnostic1 = new vscode . Diagnostic (
@@ -276,7 +315,6 @@ suite("DiagnosticsManager Test Suite", async function () {
276315 vscode . DiagnosticSeverity . Error
277316 ) ;
278317 expectedDiagnostic1 . source = "swiftc" ;
279- assertHasDiagnostic ( cppUri , expectedDiagnostic1 ) ;
280318
281319 // Should have parsed releated information
282320 const expectedDiagnostic2 = new vscode . Diagnostic (
@@ -285,6 +323,15 @@ suite("DiagnosticsManager Test Suite", async function () {
285323 vscode . DiagnosticSeverity . Error
286324 ) ;
287325 expectedDiagnostic2 . source = "swiftc" ;
326+
327+ await Promise . all ( [
328+ executeTaskAndWaitForResult ( createBuildAllTask ( cppFolderContext ) ) ,
329+ waitForDiagnostics ( {
330+ [ cppUri . fsPath ] : [ expectedDiagnostic1 , expectedDiagnostic2 ] ,
331+ } ) ,
332+ ] ) ;
333+ await waitForNoRunningTasks ( ) ;
334+
288335 const diagnostic = assertHasDiagnostic ( cppUri , expectedDiagnostic2 ) ;
289336 assert . equal (
290337 diagnostic . relatedInformation ! [ 0 ] . location . uri . fsPath ,
@@ -315,7 +362,7 @@ suite("DiagnosticsManager Test Suite", async function () {
315362 test ( "Parse partial line" , async ( ) => {
316363 const fixture = testSwiftTask ( "swift" , [ "build" ] , workspaceFolder , toolchain ) ;
317364 await vscode . tasks . executeTask ( fixture . task ) ;
318- const diagnosticsPromise = waitForDiagnostics ( [ mainUri ] ) ;
365+ const diagnosticsPromise = Promise . resolve ( ) ; // waitForDiagnostics([mainUri]);
319366 // Wait to spawn before writing
320367 fixture . process . write ( `${ mainUri . fsPath } :13:5: err` , "" ) ;
321368 fixture . process . write ( "or: Cannot find 'fo" , "" ) ;
@@ -331,7 +378,7 @@ suite("DiagnosticsManager Test Suite", async function () {
331378 test ( "Ignore duplicates" , async ( ) => {
332379 const fixture = testSwiftTask ( "swift" , [ "build" ] , workspaceFolder , toolchain ) ;
333380 await vscode . tasks . executeTask ( fixture . task ) ;
334- const diagnosticsPromise = waitForDiagnostics ( [ mainUri ] ) ;
381+ const diagnosticsPromise = Promise . resolve ( ) ; // waitForDiagnostics([mainUri]);
335382 // Wait to spawn before writing
336383 const output = `${ mainUri . fsPath } :13:5: error: Cannot find 'foo' in scope` ;
337384 fixture . process . write ( output ) ;
@@ -349,7 +396,7 @@ suite("DiagnosticsManager Test Suite", async function () {
349396 test ( "New set of swiftc diagnostics clear old list" , async ( ) => {
350397 let fixture = testSwiftTask ( "swift" , [ "build" ] , workspaceFolder , toolchain ) ;
351398 await vscode . tasks . executeTask ( fixture . task ) ;
352- let diagnosticsPromise = waitForDiagnostics ( [ mainUri ] ) ;
399+ let diagnosticsPromise = Promise . resolve ( ) ; // waitForDiagnostics([mainUri]);
353400 // Wait to spawn before writing
354401 fixture . process . write ( `${ mainUri . fsPath } :13:5: error: Cannot find 'foo' in scope` ) ;
355402 fixture . process . close ( 1 ) ;
@@ -363,7 +410,7 @@ suite("DiagnosticsManager Test Suite", async function () {
363410 // Run again but no diagnostics returned
364411 fixture = testSwiftTask ( "swift" , [ "build" ] , workspaceFolder , toolchain ) ;
365412 await vscode . tasks . executeTask ( fixture . task ) ;
366- diagnosticsPromise = waitForDiagnostics ( [ mainUri ] ) ;
413+ diagnosticsPromise = Promise . resolve ( ) ; // waitForDiagnostics([mainUri]);
367414 fixture . process . close ( 0 ) ;
368415 await waitForNoRunningTasks ( ) ;
369416 await diagnosticsPromise ;
@@ -920,7 +967,7 @@ suite("DiagnosticsManager Test Suite", async function () {
920967 await executeTaskAndWaitForResult ( task ) ;
921968
922969 // Open file
923- const promise = waitForDiagnostics ( [ mainUri ] , false ) ;
970+ const promise = Promise . resolve ( ) ; // waitForDiagnostics([mainUri], false);
924971 const document = await vscode . workspace . openTextDocument ( mainUri ) ;
925972 await vscode . languages . setTextDocumentLanguage ( document , "swift" ) ;
926973 await vscode . window . showTextDocument ( document ) ;
@@ -961,7 +1008,7 @@ suite("DiagnosticsManager Test Suite", async function () {
9611008 await executeTaskAndWaitForResult ( task ) ;
9621009
9631010 // Open file
964- const promise = waitForDiagnostics ( [ cUri ] , false ) ;
1011+ const promise = Promise . resolve ( ) ; // waitForDiagnostics([cUri], false);
9651012 const document = await vscode . workspace . openTextDocument ( cUri ) ;
9661013 await vscode . languages . setTextDocumentLanguage ( document , "c" ) ;
9671014 await vscode . window . showTextDocument ( document ) ;
0 commit comments