Skip to content

Commit e48d1d7

Browse files
committed
Debug diagnostics tests
1 parent edbf32f commit e48d1d7

File tree

3 files changed

+138
-81
lines changed

3 files changed

+138
-81
lines changed

.vscode-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
const { defineConfig } = require("@vscode/test-cli");
1616
const path = require("path");
1717

18-
const isCIBuild = process.env["CI"] === "1";
18+
const isCIBuild = false; // process.env["CI"] === "1";
1919
const isFastTestRun = process.env["FAST_TEST_RUN"] === "1";
2020

2121
// "env" in launch.json doesn't seem to work with vscode-test

src/DiagnosticsManager.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,19 @@ export class DiagnosticsManager implements vscode.Disposable {
8787
.then(map => {
8888
// Clean up old "swiftc" diagnostics
8989
this.removeSwiftcDiagnostics();
90-
map.forEach((diagnostics, uri) =>
90+
map.forEach((diagnostics, uri) => {
91+
console.log(
92+
">>> PROVIDED DIAGNOSTIC!",
93+
uri,
94+
"::",
95+
JSON.stringify(diagnostics)
96+
);
9197
this.handleDiagnostics(
9298
vscode.Uri.file(uri),
9399
DiagnosticsManager.isSwiftc,
94100
diagnostics
95-
)
96-
);
101+
);
102+
});
97103
})
98104
.catch(e =>
99105
context.outputChannel.log(`${e}`, 'Failed to provide "swiftc" diagnostics')
@@ -138,6 +144,7 @@ export class DiagnosticsManager implements vscode.Disposable {
138144
}
139145
// Append the new diagnostics we just received
140146
allDiagnostics.push(...newDiagnostics);
147+
console.log(">>>> DiagnosticManager: handleDiagnostics set >>> ", uri.fsPath);
141148
this.allDiagnostics.set(uri.fsPath, allDiagnostics);
142149
// Update the collection
143150
this.updateDiagnosticsCollection(uri);
@@ -319,9 +326,12 @@ export class DiagnosticsManager implements vscode.Disposable {
319326
): ParsedDiagnostic | vscode.DiagnosticRelatedInformation | undefined {
320327
const diagnosticRegex = /^(.*?):(\d+)(?::(\d+))?:\s+(warning|error|note):\s+([^\\[]*)/g;
321328
const match = diagnosticRegex.exec(line);
329+
console.log(">>> CHECK LINE", line);
322330
if (!match) {
331+
console.log(">>> NO MATCH", line);
323332
return;
324333
}
334+
console.log(">>> MATCH", match);
325335
const uri = match[1];
326336
const message = this.capitalize(match[5]).trim();
327337
const range = this.range(match[2], match[3]);

test/integration-tests/DiagnosticsManager.test.ts

Lines changed: 124 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -25,27 +25,26 @@ import { Version } from "../../src/utilities/version";
2525
import { folderContextPromise, globalWorkspaceContextPromise } from "./extension.test";
2626
import { 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

5049
const 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

Comments
 (0)