Skip to content

Commit a876c2d

Browse files
committed
Add tests for extension pack and model file selection
1 parent cdb6e8a commit a876c2d

File tree

2 files changed

+210
-3
lines changed

2 files changed

+210
-3
lines changed

extensions/ql-vscode/src/data-extensions-editor/extension-packs.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { ProgressCallback } from "../progress";
77
const maxStep = 3;
88

99
export async function pickExtensionPackModelFile(
10-
cliServer: CodeQLCliServer,
10+
cliServer: Pick<CodeQLCliServer, "resolveQlpacks" | "resolveExtensions">,
1111
progress: ProgressCallback,
1212
): Promise<string | undefined> {
1313
const extensionPackPath = await pickExtensionPack(cliServer, progress);
@@ -24,7 +24,7 @@ export async function pickExtensionPackModelFile(
2424
}
2525

2626
async function pickExtensionPack(
27-
cliServer: CodeQLCliServer,
27+
cliServer: Pick<CodeQLCliServer, "resolveQlpacks">,
2828
progress: ProgressCallback,
2929
): Promise<string | undefined> {
3030
progress({
@@ -73,7 +73,7 @@ async function pickExtensionPack(
7373
}
7474

7575
async function pickModelFile(
76-
cliServer: CodeQLCliServer,
76+
cliServer: Pick<CodeQLCliServer, "resolveExtensions">,
7777
progress: ProgressCallback,
7878
extensionPackPath: string,
7979
): Promise<string | undefined> {
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
import { QuickPickItem, window } from "vscode";
2+
3+
import { pickExtensionPackModelFile } from "../../../../src/data-extensions-editor/extension-packs";
4+
import { QlpacksInfo, ResolveExtensionsResult } from "../../../../src/cli";
5+
import * as helpers from "../../../../src/helpers";
6+
7+
describe("pickExtensionPackModelFile", () => {
8+
const qlPacks = {
9+
"my-extension-pack": ["/a/b/c/my-extension-pack"],
10+
"another-extension-pack": ["/a/b/c/another-extension-pack"],
11+
};
12+
const extensions = {
13+
models: [],
14+
data: {
15+
"/a/b/c/my-extension-pack": [
16+
{
17+
file: "/a/b/c/my-extension-pack/models/model.yml",
18+
index: 0,
19+
predicate: "sinkModel",
20+
},
21+
],
22+
},
23+
};
24+
25+
const progress = jest.fn();
26+
let showQuickPickSpy: jest.SpiedFunction<typeof window.showQuickPick>;
27+
28+
beforeEach(() => {
29+
showQuickPickSpy = jest
30+
.spyOn(window, "showQuickPick")
31+
.mockRejectedValue(new Error("Unexpected call to showQuickPick"));
32+
});
33+
34+
it("allows choosing an existing extension pack and model file", async () => {
35+
const cliServer = mockCliServer(qlPacks, extensions);
36+
37+
showQuickPickSpy.mockResolvedValueOnce({
38+
label: "my-extension-pack",
39+
extensionPack: "my-extension-pack",
40+
} as QuickPickItem);
41+
showQuickPickSpy.mockResolvedValueOnce({
42+
label: "models/model.yml",
43+
file: "/a/b/c/my-extension-pack/models/model.yml",
44+
} as QuickPickItem);
45+
46+
expect(await pickExtensionPackModelFile(cliServer, progress)).toEqual(
47+
"/a/b/c/my-extension-pack/models/model.yml",
48+
);
49+
expect(showQuickPickSpy).toHaveBeenCalledTimes(2);
50+
expect(showQuickPickSpy).toHaveBeenCalledWith(
51+
[
52+
{
53+
label: "my-extension-pack",
54+
extensionPack: "my-extension-pack",
55+
},
56+
{
57+
label: "another-extension-pack",
58+
extensionPack: "another-extension-pack",
59+
},
60+
],
61+
{
62+
title: expect.any(String),
63+
},
64+
);
65+
expect(showQuickPickSpy).toHaveBeenCalledWith(
66+
[
67+
{
68+
label: "models/model.yml",
69+
file: "/a/b/c/my-extension-pack/models/model.yml",
70+
},
71+
],
72+
{
73+
title: expect.any(String),
74+
},
75+
);
76+
expect(cliServer.resolveQlpacks).toHaveBeenCalledTimes(1);
77+
expect(cliServer.resolveQlpacks).toHaveBeenCalledWith([], true);
78+
expect(cliServer.resolveExtensions).toHaveBeenCalledTimes(1);
79+
expect(cliServer.resolveExtensions).toHaveBeenCalledWith(
80+
"/a/b/c/my-extension-pack",
81+
[],
82+
);
83+
});
84+
85+
it("allows cancelling the extension pack prompt", async () => {
86+
const cliServer = mockCliServer(qlPacks, extensions);
87+
88+
showQuickPickSpy.mockResolvedValueOnce(undefined);
89+
90+
expect(await pickExtensionPackModelFile(cliServer, progress)).toEqual(
91+
undefined,
92+
);
93+
expect(cliServer.resolveQlpacks).toHaveBeenCalled();
94+
expect(cliServer.resolveExtensions).not.toHaveBeenCalled();
95+
});
96+
97+
it("does not show any options when there are no extension packs", async () => {
98+
const cliServer = mockCliServer({}, { models: [], data: {} });
99+
100+
showQuickPickSpy.mockResolvedValueOnce(undefined);
101+
102+
expect(await pickExtensionPackModelFile(cliServer, progress)).toEqual(
103+
undefined,
104+
);
105+
expect(showQuickPickSpy).toHaveBeenCalledTimes(1);
106+
expect(showQuickPickSpy).toHaveBeenCalledWith([], {
107+
title: expect.any(String),
108+
});
109+
expect(cliServer.resolveQlpacks).toHaveBeenCalled();
110+
expect(cliServer.resolveExtensions).not.toHaveBeenCalled();
111+
});
112+
113+
it("shows an error when an extension pack resolves to more than 1 location", async () => {
114+
const showAndLogErrorMessageSpy = jest.spyOn(
115+
helpers,
116+
"showAndLogErrorMessage",
117+
);
118+
119+
const cliServer = mockCliServer(
120+
{
121+
"my-extension-pack": [
122+
"/a/b/c/my-extension-pack",
123+
"/a/b/c/my-extension-pack2",
124+
],
125+
},
126+
{ models: [], data: {} },
127+
);
128+
129+
showQuickPickSpy.mockResolvedValueOnce({
130+
label: "my-extension-pack",
131+
extensionPack: "my-extension-pack",
132+
} as QuickPickItem);
133+
134+
expect(await pickExtensionPackModelFile(cliServer, progress)).toEqual(
135+
undefined,
136+
);
137+
expect(showAndLogErrorMessageSpy).toHaveBeenCalledTimes(1);
138+
expect(showAndLogErrorMessageSpy).toHaveBeenCalledWith(
139+
expect.stringMatching(/could not be resolved to a single location/),
140+
expect.anything(),
141+
);
142+
expect(showQuickPickSpy).toHaveBeenCalledTimes(1);
143+
expect(cliServer.resolveQlpacks).toHaveBeenCalled();
144+
expect(cliServer.resolveExtensions).not.toHaveBeenCalled();
145+
});
146+
147+
it("allows cancelling the model file prompt", async () => {
148+
const cliServer = mockCliServer(qlPacks, extensions);
149+
150+
showQuickPickSpy.mockResolvedValueOnce({
151+
label: "my-extension-pack",
152+
extensionPack: "my-extension-pack",
153+
} as QuickPickItem);
154+
showQuickPickSpy.mockResolvedValueOnce(undefined);
155+
156+
expect(await pickExtensionPackModelFile(cliServer, progress)).toEqual(
157+
undefined,
158+
);
159+
expect(cliServer.resolveQlpacks).toHaveBeenCalled();
160+
expect(cliServer.resolveExtensions).toHaveBeenCalled();
161+
});
162+
163+
it("does not show any options when there are no model files", async () => {
164+
const cliServer = mockCliServer(qlPacks, { models: [], data: {} });
165+
166+
showQuickPickSpy.mockResolvedValueOnce({
167+
label: "my-extension-pack",
168+
extensionPack: "my-extension-pack",
169+
} as QuickPickItem);
170+
showQuickPickSpy.mockResolvedValueOnce(undefined);
171+
172+
expect(await pickExtensionPackModelFile(cliServer, progress)).toEqual(
173+
undefined,
174+
);
175+
expect(showQuickPickSpy).toHaveBeenCalledTimes(2);
176+
expect(showQuickPickSpy).toHaveBeenCalledWith(
177+
[
178+
{
179+
label: "my-extension-pack",
180+
extensionPack: "my-extension-pack",
181+
},
182+
{
183+
label: "another-extension-pack",
184+
extensionPack: "another-extension-pack",
185+
},
186+
],
187+
{
188+
title: expect.any(String),
189+
},
190+
);
191+
expect(showQuickPickSpy).toHaveBeenCalledWith([], {
192+
title: expect.any(String),
193+
});
194+
expect(cliServer.resolveQlpacks).toHaveBeenCalled();
195+
expect(cliServer.resolveExtensions).toHaveBeenCalled();
196+
});
197+
});
198+
199+
function mockCliServer(
200+
qlpacks: QlpacksInfo,
201+
extensions: ResolveExtensionsResult,
202+
) {
203+
return {
204+
resolveQlpacks: jest.fn().mockResolvedValue(qlpacks),
205+
resolveExtensions: jest.fn().mockResolvedValue(extensions),
206+
};
207+
}

0 commit comments

Comments
 (0)