Skip to content

Commit 48b8120

Browse files
acaoimolorhe
andcommitted
Completion tests (#50)
* start on basic tests for completion * avoid debug logging in tests * use Samuel's approach for mocking snippets Co-authored-by: Samuel Imolorhe <[email protected]>
1 parent 58c30da commit 48b8120

File tree

3 files changed

+107
-45
lines changed

3 files changed

+107
-45
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { describe, it, expect, vitest, Mock } from "vitest";
2+
3+
import { json, jsonLanguage } from "@codemirror/lang-json";
4+
import { EditorState } from "@codemirror/state";
5+
import {
6+
Completion,
7+
CompletionContext,
8+
CompletionResult,
9+
CompletionSource,
10+
} from "@codemirror/autocomplete";
11+
import { jsonCompletion } from "../../json-completion";
12+
import { JSONSchema7 } from "json-schema";
13+
import { testSchema2 } from "../__fixtures__/schemas";
14+
import { EditorView } from "@codemirror/view";
15+
16+
vitest.mock("@codemirror/autocomplete", async () => {
17+
const mod = await vitest.importActual<
18+
typeof import("@codemirror/autocomplete")
19+
>("@codemirror/autocomplete");
20+
return {
21+
...mod,
22+
snippetCompletion(template: string, completion: Completion) {
23+
const c = {
24+
...completion,
25+
// pass the snippet template to the completion result
26+
// to make it easier to test
27+
TESTONLY_template: template,
28+
};
29+
return mod.snippetCompletion(template, c);
30+
},
31+
};
32+
});
33+
34+
type MockedCompletionResult = CompletionResult["options"][0] & {
35+
template?: string;
36+
};
37+
38+
export async function expectCompletion(
39+
doc: string,
40+
results: MockedCompletionResult[],
41+
schema?: JSONSchema7,
42+
conf: { explicit?: boolean } = {}
43+
) {
44+
let cur = doc.indexOf("|"),
45+
currentSchema = schema || testSchema2;
46+
doc = doc.slice(0, cur) + doc.slice(cur + 1);
47+
let state = EditorState.create({
48+
doc,
49+
selection: { anchor: cur },
50+
extensions: [
51+
json(),
52+
jsonLanguage.data.of({
53+
autocomplete: jsonCompletion(currentSchema),
54+
}),
55+
],
56+
});
57+
const view = new EditorView({ state });
58+
59+
let result = await state.languageDataAt<CompletionSource>(
60+
"autocomplete",
61+
cur
62+
)[0](new CompletionContext(state, cur, !!conf.explicit));
63+
if (!result) {
64+
return expect(result).toEqual(results);
65+
}
66+
const filteredResults = result.options.map((item) => ({
67+
detail: item.detail,
68+
info: item.info,
69+
label: item.label,
70+
type: item.type,
71+
// @ts-expect-error
72+
template: item?.TESTONLY_template as string | undefined,
73+
}));
74+
expect(filteredResults).toEqual(results);
75+
}

src/__tests__/json-completion.spec.ts

Lines changed: 31 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,35 @@
1-
import { it, describe, expect } from "vitest";
2-
import { JSONCompletion } from "../json-completion";
3-
import { CompletionResult, autocompletion } from "@codemirror/autocomplete";
4-
import { testSchema } from "./__fixtures__/schemas";
5-
import { EditorView } from "@codemirror/view";
6-
import { json, jsonLanguage } from "@codemirror/lang-json";
7-
import { EditorState } from "@codemirror/state";
1+
import { describe, it } from "vitest";
82

9-
describe("json-completion", () => {
3+
import { expectCompletion } from "./__helpers__/completion";
4+
5+
describe("jsonCompletion", () => {
6+
it("should return completion data for simple types", async () => {
7+
await expectCompletion('{ "f| }', [
8+
{
9+
label: "foo",
10+
type: "property",
11+
detail: "string",
12+
info: "",
13+
template: '"foo": "#{}"',
14+
},
15+
]);
16+
});
1017
it("should return completion data for simple types", async () => {
11-
expect(true).toEqual(true);
18+
await expectCompletion('{ "one| }', [
19+
{
20+
label: "oneOfEg",
21+
type: "property",
22+
detail: "",
23+
info: "an example oneOf",
24+
template: '"oneOfEg": ',
25+
},
26+
{
27+
label: "oneOfEg2",
28+
type: "property",
29+
detail: "",
30+
info: "",
31+
template: '"oneOfEg2": ',
32+
},
33+
]);
1234
});
1335
});
14-
15-
// const getCompletionResult = (
16-
// jsonString: string,
17-
// pos: number
18-
// ): Promise<CompletionResult | undefined> => {
19-
// return new Promise((resolve, reject) => {
20-
// console.log("hello1");
21-
// const completionInstance = new JSONCompletion(testSchema);
22-
// const state = EditorState.create({
23-
// doc: jsonString,
24-
// selection: { anchor: pos, head: pos },
25-
// extensions: [
26-
// json(),
27-
// jsonLanguage.data.of({
28-
// autocomplete: () => {
29-
// const result =
30-
// completionInstance.doComplete.bind(completionInstance);
31-
// console.log(result)
32-
// resolve(result);
33-
// return result;
34-
// },
35-
// }),
36-
// ],
37-
// });
38-
// });
39-
// };
40-
41-
// describe("json-completion", () => {
42-
// console.log("hello");
43-
// it("should return completion data for simple types", async () => {
44-
// const completionResult = await getCompletionResult('{ "f }', 5);
45-
// console.log(completionResult);
46-
// expect(completionResult).toEqual(true);
47-
// });
48-
// });

src/utils/debug.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export const debug = {
22
log: (...args: any[]) => {
3-
if (process.env.NODE_ENV === "production") {
3+
if (process.env.NODE_ENV !== "development") {
44
return;
55
}
66
console.log(...args);

0 commit comments

Comments
 (0)