Skip to content

Commit f73ea67

Browse files
authored
Merge pull request #3413 from github/koesie10/fix-tests-with-warnings
Show test results for tests with warnings
2 parents 23bbff2 + eaa432b commit f73ea67

File tree

5 files changed

+113
-23
lines changed

5 files changed

+113
-23
lines changed

extensions/ql-vscode/src/codeql-cli/cli.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,17 @@ type ResolvedQueries = string[];
156156
type ResolvedTests = string[];
157157

158158
/**
159-
* A compilation message for a test message (either an error or a warning)
159+
* The severity of a compilation message for a test message.
160160
*/
161-
interface CompilationMessage {
161+
export enum CompilationMessageSeverity {
162+
Error = "ERROR",
163+
Warning = "WARNING",
164+
}
165+
166+
/**
167+
* A compilation message for a test message (either an error or a warning).
168+
*/
169+
export interface CompilationMessage {
162170
/**
163171
* The text of the message
164172
*/
@@ -170,7 +178,7 @@ interface CompilationMessage {
170178
/**
171179
* The severity of the message
172180
*/
173-
severity: number;
181+
severity: CompilationMessageSeverity;
174182
}
175183

176184
/**

extensions/ql-vscode/src/query-testing/test-manager.ts

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ import {
2121
} from "vscode";
2222
import { DisposableObject } from "../common/disposable-object";
2323
import { QLTestDiscovery } from "./qltest-discovery";
24-
import type { CodeQLCliServer } from "../codeql-cli/cli";
24+
import type { CodeQLCliServer, CompilationMessage } from "../codeql-cli/cli";
25+
import { CompilationMessageSeverity } from "../codeql-cli/cli";
2526
import { getErrorMessage } from "../common/helpers-pure";
2627
import type { BaseLogger, LogOptions } from "../common/logging";
2728
import type { TestRunner } from "./test-runner";
@@ -66,6 +67,23 @@ function changeExtension(p: string, ext: string): string {
6667
return p.slice(0, -extname(p).length) + ext;
6768
}
6869

70+
function compilationMessageToTestMessage(
71+
compilationMessage: CompilationMessage,
72+
): TestMessage {
73+
const location = new Location(
74+
Uri.file(compilationMessage.position.fileName),
75+
new Range(
76+
compilationMessage.position.line - 1,
77+
compilationMessage.position.column - 1,
78+
compilationMessage.position.endLine - 1,
79+
compilationMessage.position.endColumn - 1,
80+
),
81+
);
82+
const testMessage = new TestMessage(compilationMessage.message);
83+
testMessage.location = location;
84+
return testMessage;
85+
}
86+
6987
/**
7088
* Returns the complete text content of the specified file. If there is an error reading the file,
7189
* an error message is added to `testMessages` and this function returns undefined.
@@ -398,23 +416,15 @@ export class TestManager extends DisposableObject {
398416
);
399417
}
400418
}
401-
if (event.messages?.length > 0) {
419+
const errorMessages = event.messages.filter(
420+
(m) => m.severity === CompilationMessageSeverity.Error,
421+
);
422+
if (errorMessages.length > 0) {
402423
// The test didn't make it far enough to produce results. Transform any error messages
403424
// into `TestMessage`s and report the test as "errored".
404-
const testMessages = event.messages.map((m) => {
405-
const location = new Location(
406-
Uri.file(m.position.fileName),
407-
new Range(
408-
m.position.line - 1,
409-
m.position.column - 1,
410-
m.position.endLine - 1,
411-
m.position.endColumn - 1,
412-
),
413-
);
414-
const testMessage = new TestMessage(m.message);
415-
testMessage.location = location;
416-
return testMessage;
417-
});
425+
const testMessages = event.messages.map(
426+
compilationMessageToTestMessage,
427+
);
418428
testRun.errored(testItem, testMessages, duration);
419429
} else {
420430
// Results didn't match expectations. Report the test as "failed".
@@ -423,6 +433,12 @@ export class TestManager extends DisposableObject {
423433
// here. Any failed test needs at least one message.
424434
testMessages.push(new TestMessage("Test failed"));
425435
}
436+
437+
// Add any warnings produced by the test to the test messages.
438+
testMessages.push(
439+
...event.messages.map(compilationMessageToTestMessage),
440+
);
441+
426442
testRun.failed(testItem, testMessages, duration);
427443
}
428444
}

extensions/ql-vscode/test/vscode-tests/no-workspace/query-testing/test-adapter.test.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { TestItem, TestItemCollection, TestRun } from "vscode";
22
import {
33
CancellationTokenSource,
4+
Location,
45
Range,
56
TestRunRequest,
67
Uri,
@@ -75,6 +76,11 @@ describe("test-adapter", () => {
7576
id: `test ${mockTestsInfo.hPath}`,
7677
uri: Uri.file(mockTestsInfo.hPath),
7778
} as TestItem,
79+
{
80+
children: { size: 0 } as TestItemCollection,
81+
id: `test ${mockTestsInfo.kPath}`,
82+
uri: Uri.file(mockTestsInfo.kPath),
83+
} as TestItem,
7884
];
7985
const childElements: IdTestItemPair[] = childItems.map((childItem) => [
8086
childItem.id,
@@ -87,15 +93,15 @@ describe("test-adapter", () => {
8793
id: `dir ${mockTestsInfo.testsPath}`,
8894
uri: Uri.file(mockTestsInfo.testsPath),
8995
children: {
90-
size: 3,
96+
size: 4,
9197
[Symbol.iterator]: childIteratorFunc,
9298
} as TestItemCollection,
9399
} as TestItem;
94100

95101
const request = new TestRunRequest([rootItem]);
96102
await testManager.run(request, new CancellationTokenSource().token);
97103

98-
expect(enqueuedSpy).toHaveBeenCalledTimes(3);
104+
expect(enqueuedSpy).toHaveBeenCalledTimes(4);
99105
expect(passedSpy).toHaveBeenCalledTimes(1);
100106
expect(passedSpy).toHaveBeenCalledWith(childItems[0], 3000);
101107
expect(erroredSpy).toHaveBeenCalledTimes(1);
@@ -112,6 +118,7 @@ describe("test-adapter", () => {
112118
],
113119
4000,
114120
);
121+
expect(failedSpy).toHaveBeenCalledTimes(2);
115122
expect(failedSpy).toHaveBeenCalledWith(
116123
childItems[2],
117124
[
@@ -121,7 +128,22 @@ describe("test-adapter", () => {
121128
],
122129
11000,
123130
);
124-
expect(failedSpy).toHaveBeenCalledTimes(1);
131+
expect(failedSpy).toHaveBeenCalledWith(
132+
childItems[3],
133+
[
134+
{
135+
message: "Test failed",
136+
},
137+
{
138+
message: "abc",
139+
location: new Location(
140+
Uri.file(mockTestsInfo.kPath),
141+
new Range(0, 0, 1, 1),
142+
),
143+
},
144+
],
145+
15000,
146+
);
125147
expect(endSpy).toHaveBeenCalledTimes(1);
126148
});
127149
});

extensions/ql-vscode/test/vscode-tests/no-workspace/query-testing/test-runner-helpers.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const mockTestsInfo = {
1111
dPath: Uri.parse("file:/ab/c/d.ql").fsPath,
1212
gPath: Uri.parse("file:/ab/c/e/f/g.ql").fsPath,
1313
hPath: Uri.parse("file:/ab/c/e/f/h.ql").fsPath,
14+
kPath: Uri.parse("file:/ab/c/e/f/k.ql").fsPath,
1415
};
1516

1617
/**
@@ -89,6 +90,28 @@ function mockRunTests(): jest.Mock<any, any> {
8990
evaluationMs: 6000,
9091
messages: [],
9192
});
93+
yield Promise.resolve({
94+
test: mockTestsInfo.kPath,
95+
pass: false,
96+
diff: ["jkh", "tuv"],
97+
failureStage: "RESULT",
98+
compilationMs: 7000,
99+
evaluationMs: 8000,
100+
// a warning in an otherwise successful test
101+
messages: [
102+
{
103+
position: {
104+
fileName: mockTestsInfo.kPath,
105+
line: 1,
106+
column: 1,
107+
endLine: 2,
108+
endColumn: 2,
109+
},
110+
message: "abc",
111+
severity: "WARNING",
112+
},
113+
],
114+
});
92115
})(),
93116
);
94117

extensions/ql-vscode/test/vscode-tests/no-workspace/query-testing/test-runner.test.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ describe("test-runner", () => {
9494
eventHandlerSpy,
9595
);
9696

97-
expect(eventHandlerSpy).toHaveBeenCalledTimes(3);
97+
expect(eventHandlerSpy).toHaveBeenCalledTimes(4);
9898

9999
expect(eventHandlerSpy).toHaveBeenNthCalledWith(1, {
100100
test: mockTestsInfo.dPath,
@@ -133,6 +133,27 @@ describe("test-runner", () => {
133133
failureStage: "RESULT",
134134
messages: [],
135135
});
136+
expect(eventHandlerSpy).toHaveBeenNthCalledWith(4, {
137+
test: mockTestsInfo.kPath,
138+
pass: false,
139+
compilationMs: 7000,
140+
evaluationMs: 8000,
141+
diff: ["jkh", "tuv"],
142+
failureStage: "RESULT",
143+
messages: [
144+
{
145+
position: {
146+
fileName: mockTestsInfo.kPath,
147+
line: 1,
148+
column: 1,
149+
endLine: 2,
150+
endColumn: 2,
151+
},
152+
message: "abc",
153+
severity: "WARNING",
154+
},
155+
],
156+
});
136157
});
137158

138159
it("should reregister testproj databases around test run", async () => {

0 commit comments

Comments
 (0)