Skip to content

Commit 2ba23ce

Browse files
author
Dave Bartolomeo
committed
Fold TestManagerBase and related functions into TestManager
1 parent d8968db commit 2ba23ce

3 files changed

Lines changed: 93 additions & 114 deletions

File tree

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

Lines changed: 0 additions & 35 deletions
This file was deleted.

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

Lines changed: 0 additions & 74 deletions
This file was deleted.

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

Lines changed: 93 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import { readFile } from "fs-extra";
1+
import { copy, createFile, lstat, pathExists, readFile } from "fs-extra";
22
import type {
33
CancellationToken,
44
TestController,
55
TestItem,
66
TestRun,
77
TestRunRequest,
8+
TextDocumentShowOptions,
89
WorkspaceFolder,
910
WorkspaceFoldersChangeEvent,
1011
} from "vscode";
@@ -15,6 +16,7 @@ import {
1516
TestRunProfileKind,
1617
Uri,
1718
tests,
19+
window,
1820
workspace,
1921
} from "vscode";
2022
import { DisposableObject } from "../common/disposable-object";
@@ -23,11 +25,46 @@ import type { CodeQLCliServer } from "../codeql-cli/cli";
2325
import { getErrorMessage } from "../common/helpers-pure";
2426
import type { BaseLogger, LogOptions } from "../common/logging";
2527
import type { TestRunner } from "./test-runner";
26-
import { TestManagerBase } from "./test-manager-base";
2728
import type { App } from "../common/app";
2829
import { isWorkspaceFolderOnDisk } from "../common/vscode/workspace-folders";
2930
import type { FileTreeNode } from "../common/file-tree-nodes";
3031
import { FileTreeDirectory, FileTreeLeaf } from "../common/file-tree-nodes";
32+
import type { TestUICommands } from "../common/commands";
33+
import { basename, extname } from "path";
34+
35+
/**
36+
* Get the full path of the `.expected` file for the specified QL test.
37+
* @param testPath The full path to the test file.
38+
*/
39+
function getExpectedFile(testPath: string): string {
40+
return getTestOutputFile(testPath, ".expected");
41+
}
42+
43+
/**
44+
* Get the full path of the `.actual` file for the specified QL test.
45+
* @param testPath The full path to the test file.
46+
*/
47+
function getActualFile(testPath: string): string {
48+
return getTestOutputFile(testPath, ".actual");
49+
}
50+
51+
/**
52+
* Gets the the full path to a particular output file of the specified QL test.
53+
* @param testPath The full path to the QL test.
54+
* @param extension The file extension of the output file.
55+
*/
56+
function getTestOutputFile(testPath: string, extension: string): string {
57+
return changeExtension(testPath, extension);
58+
}
59+
60+
/**
61+
* Change the file extension of the specified path.
62+
* @param p The original file path.
63+
* @param ext The new extension, including the `.`.
64+
*/
65+
function changeExtension(p: string, ext: string): string {
66+
return p.slice(0, -extname(p).length) + ext;
67+
}
3168

3269
/**
3370
* Returns the complete text content of the specified file. If there is an error reading the file,
@@ -108,7 +145,7 @@ class WorkspaceFolderHandler extends DisposableObject {
108145
* Service that populates the VS Code "Test Explorer" panel for CodeQL, and handles running and
109146
* debugging of tests.
110147
*/
111-
export class TestManager extends TestManagerBase {
148+
export class TestManager extends DisposableObject {
112149
/**
113150
* Maps from each workspace folder being tracked to the `WorkspaceFolderHandler` responsible for
114151
* tracking it.
@@ -119,7 +156,7 @@ export class TestManager extends TestManagerBase {
119156
>();
120157

121158
public constructor(
122-
app: App,
159+
private readonly app: App,
123160
private readonly testRunner: TestRunner,
124161
private readonly cliServer: CodeQLCliServer,
125162
// Having this as a parameter with a default value makes passing in a mock easier.
@@ -128,7 +165,7 @@ export class TestManager extends TestManagerBase {
128165
"CodeQL Tests",
129166
),
130167
) {
131-
super(app);
168+
super();
132169

133170
this.testController.createRunProfile(
134171
"Run",
@@ -151,13 +188,64 @@ export class TestManager extends TestManagerBase {
151188
super.dispose();
152189
}
153190

191+
public getCommands(): TestUICommands {
192+
return {
193+
"codeQLTests.showOutputDifferences":
194+
this.showOutputDifferences.bind(this),
195+
"codeQLTests.acceptOutput": this.acceptOutput.bind(this),
196+
"codeQLTests.acceptOutputContextTestItem": this.acceptOutput.bind(this),
197+
};
198+
}
199+
154200
protected getTestPath(node: TestItem): string {
155201
if (node.uri === undefined || node.uri.scheme !== "file") {
156202
throw new Error("Selected test is not a CodeQL test.");
157203
}
158204
return node.uri.fsPath;
159205
}
160206

207+
private async acceptOutput(node: TestItem): Promise<void> {
208+
const testPath = this.getTestPath(node);
209+
const stat = await lstat(testPath);
210+
if (stat.isFile()) {
211+
const expectedPath = getExpectedFile(testPath);
212+
const actualPath = getActualFile(testPath);
213+
await copy(actualPath, expectedPath, { overwrite: true });
214+
}
215+
}
216+
217+
private async showOutputDifferences(node: TestItem): Promise<void> {
218+
const testId = this.getTestPath(node);
219+
const stat = await lstat(testId);
220+
if (stat.isFile()) {
221+
const expectedPath = getExpectedFile(testId);
222+
const expectedUri = Uri.file(expectedPath);
223+
const actualPath = getActualFile(testId);
224+
const options: TextDocumentShowOptions = {
225+
preserveFocus: true,
226+
preview: true,
227+
};
228+
229+
if (!(await pathExists(expectedPath))) {
230+
// Just create a new file.
231+
await createFile(expectedPath);
232+
}
233+
234+
if (await pathExists(actualPath)) {
235+
const actualUri = Uri.file(actualPath);
236+
await this.app.commands.execute(
237+
"vscode.diff",
238+
expectedUri,
239+
actualUri,
240+
`Expected vs. Actual for ${basename(testId)}`,
241+
options,
242+
);
243+
} else {
244+
await window.showTextDocument(expectedUri, options);
245+
}
246+
}
247+
}
248+
161249
/** Start tracking tests in the specified workspace folders. */
162250
private startTrackingWorkspaceFolders(
163251
workspaceFolders: readonly WorkspaceFolder[],

0 commit comments

Comments
 (0)