Skip to content

Commit adb7538

Browse files
committed
Add TestClient and handle various test isolation issues
1 parent 64b7b8c commit adb7538

25 files changed

+430
-348
lines changed

language-server/src/build-server.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export type Feature = {
66
load: (connection: Connection, documents: TextDocuments<TextDocument>) => void;
77
onInitialize: (params: InitializeParams) => ServerCapabilities;
88
onInitialized: (connection: Connection, documents: TextDocuments<TextDocument>) => Promise<void>;
9+
onShutdown: (connection: Connection, documents: TextDocuments<TextDocument>) => void;
910
};
1011

1112
export const buildServer: (connection: Connection, features: Feature[]) => void;

language-server/src/build-server.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ export const buildServer = (connection, features) => {
3535
}
3636
});
3737

38+
connection.onShutdown(() => {
39+
for (const feature of features) {
40+
feature.onShutdown(connection, documents);
41+
}
42+
});
43+
3844
connection.listen();
3945
documents.listen(connection);
4046
};

language-server/src/features/completion.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,8 @@ export default {
3535
},
3636

3737
async onInitialized() {
38+
},
39+
40+
onShutdown() {
3841
}
3942
};

language-server/src/features/completion.test.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
1-
import { beforeAll, describe, expect, test } from "vitest";
2-
import { getTestClient, initializeServer } from "../test-utils.js";
1+
import { afterAll, beforeAll, describe, expect, test } from "vitest";
2+
import { TestClient } from "../test-client.js";
33
import completion from "./completion.js";
44

5-
import type { Connection, ServerCapabilities } from "vscode-languageserver";
5+
import type { DocumentSettings } from "./document-settings.js";
66

77

88
describe("Feature - Completion", () => {
9-
let client: Connection;
10-
let capabilities: ServerCapabilities;
9+
let client: TestClient<DocumentSettings>;
1110

1211
beforeAll(async () => {
13-
client = getTestClient([completion]);
14-
capabilities = await initializeServer(client);
12+
client = new TestClient([completion]);
13+
await client.start();
14+
});
15+
16+
afterAll(async () => {
17+
await client.stop();
1518
});
1619

1720
test("completion provider capabilities", async () => {
18-
expect(capabilities.completionProvider).to.eql({
21+
expect(client.serverCapabilities?.completionProvider).to.eql({
1922
resolveProvider: false,
2023
triggerCharacters: ["\"", ":", " "]
2124
});

language-server/src/features/deprecated.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,8 @@ export default {
3131
},
3232

3333
async onInitialized() {
34+
},
35+
36+
onShutdown() {
3437
}
3538
};

language-server/src/features/document-settings.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { DidChangeConfigurationNotification } from "vscode-languageserver";
2-
import { publish } from "../pubsub.js";
2+
import { publishAsync } from "../pubsub.js";
33
import { clearSchemaDocuments } from "./schema-registry.js";
44

55
/**
@@ -14,13 +14,13 @@ let hasDidChangeConfigurationCapability = false;
1414
/** @type Feature */
1515
export default {
1616
load(connection, documents) {
17-
connection.onDidChangeConfiguration(() => {
17+
connection.onDidChangeConfiguration(async () => {
1818
if (hasConfigurationCapability) {
1919
documentSettings.clear();
2020
clearSchemaDocuments();
2121
}
2222

23-
publish("workspaceChanged", { changes: [] });
23+
await publishAsync("workspaceChanged", { changes: [] });
2424
});
2525

2626
documents.onDidClose(({ document }) => {
@@ -37,11 +37,13 @@ export default {
3737

3838
async onInitialized(connection) {
3939
if (hasDidChangeConfigurationCapability) {
40-
connection.client.register(DidChangeConfigurationNotification.type, {
40+
await connection.client.register(DidChangeConfigurationNotification.type, {
4141
section: "jsonSchemaLanguageServer"
4242
});
4343
}
44-
}
44+
},
45+
46+
onShutdown() {}
4547
};
4648

4749
const documentSettings = new Map();
Lines changed: 35 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,119 +1,103 @@
1-
import { afterAll, beforeAll, describe, expect, test } from "vitest";
2-
import {
3-
ConfigurationRequest,
4-
DidChangeTextDocumentNotification,
5-
PublishDiagnosticsNotification
6-
} from "vscode-languageserver";
7-
import { getTestClient, closeDocument, initializeServer, openDocument } from "../test-utils.js";
1+
import { afterEach, beforeEach, describe, expect, test } from "vitest";
2+
import { PublishDiagnosticsNotification } from "vscode-languageserver";
3+
import { TestClient } from "../test-client.js";
84
import documentSettings from "./document-settings.js";
5+
import semanticTokens from "./semantic-tokens.js";
96
import schemaRegistry from "./schema-registry.js";
107
import workspace from "./workspace.js";
118
import validationErrorsFeature from "./validation-errors.js";
129

13-
import type { Connection, Diagnostic } from "vscode-languageserver";
10+
import type { Diagnostic } from "vscode-languageserver";
11+
import type { DocumentSettings } from "./document-settings.js";
1412

1513

1614
describe("Feature - Document Settings", () => {
17-
let client: Connection;
18-
let documentUri: string;
15+
let client: TestClient<DocumentSettings>;
1916

20-
beforeAll(async () => {
21-
client = getTestClient([
17+
beforeEach(async () => {
18+
client = new TestClient([
2219
workspace,
2320
documentSettings,
21+
semanticTokens,
2422
schemaRegistry,
2523
validationErrorsFeature
2624
]);
27-
const init = {};
28-
const settings = { "defaultDialect": "https://json-schema.org/draft/2020-12/schema" };
29-
await initializeServer(client, init, settings);
25+
await client.start();
3026
});
3127

32-
afterAll(async () => {
33-
await closeDocument(client, documentUri);
28+
afterEach(async () => {
29+
await client.stop();
3430
});
3531

3632
test("test default dialect", async () => {
37-
documentUri = await openDocument(client, "./subject.schema.json", `{}`);
33+
await client.changeConfiguration({ defaultDialect: "https://json-schema.org/draft/2020-12/schema" });
3834

3935
const diagnosticsPromise = new Promise<Diagnostic[]>((resolve) => {
4036
client.onNotification(PublishDiagnosticsNotification.type, (params) => {
4137
resolve(params.diagnostics);
4238
});
4339
});
4440

45-
await client.sendNotification(DidChangeTextDocumentNotification.type, {
46-
textDocument: { uri: documentUri, version: 1 },
47-
contentChanges: []
48-
});
41+
await client.openDocument("./subject.schema.json", `{}`);
4942

5043
const diagnostics = await diagnosticsPromise;
5144
expect(diagnostics).to.eql([]);
5245
});
5346

5447
test("test no dialect", async () => {
55-
documentUri = await openDocument(client, "./subject.schema.json", `{}`);
56-
57-
client.onRequest(ConfigurationRequest.type, () => {
58-
return [{}];
59-
});
60-
6148
const diagnosticsPromise = new Promise<Diagnostic[]>((resolve) => {
6249
client.onNotification(PublishDiagnosticsNotification.type, (params) => {
6350
resolve(params.diagnostics);
6451
});
6552
});
6653

67-
await client.sendNotification(DidChangeTextDocumentNotification.type, {
68-
textDocument: { uri: documentUri, version: 1 },
69-
contentChanges: []
70-
});
54+
await client.openDocument("./subject.schema.json", `{}`);
7155

7256
const diagnostics = await diagnosticsPromise;
7357
expect(diagnostics[0].message).to.eql("No dialect");
7458
});
7559

7660
test("test unknown dialect", async () => {
77-
documentUri = await openDocument(client, "./subject.schema.json", `{ "$schema": "" }`);
78-
79-
client.onRequest(ConfigurationRequest.type, () => {
80-
return [{}];
81-
});
82-
8361
const diagnosticsPromise = new Promise<Diagnostic[]>((resolve) => {
8462
client.onNotification(PublishDiagnosticsNotification.type, (params) => {
8563
resolve(params.diagnostics);
8664
});
8765
});
8866

89-
await client.sendNotification(DidChangeTextDocumentNotification.type, {
90-
textDocument: { uri: documentUri, version: 1 },
91-
contentChanges: []
92-
});
67+
await client.openDocument("./subject.schema.json", `{ "$schema": "" }`);
9368

9469
const diagnostics = await diagnosticsPromise;
9570
expect(diagnostics[0].message).to.eql("Unknown dialect");
9671
});
9772

9873
test("test unknown dialect when default dialect is unknown", async () => {
99-
documentUri = await openDocument(client, "./subject.schema.json", `{}`);
100-
101-
client.onRequest(ConfigurationRequest.type, () => {
102-
return [{ "defaultDialect": "" }];
103-
});
74+
await client.changeConfiguration({ defaultDialect: "https://example.com/unknown-dialect" });
10475

10576
const diagnosticsPromise = new Promise<Diagnostic[]>((resolve) => {
10677
client.onNotification(PublishDiagnosticsNotification.type, (params) => {
10778
resolve(params.diagnostics);
10879
});
10980
});
11081

111-
await client.sendNotification(DidChangeTextDocumentNotification.type, {
112-
textDocument: { uri: documentUri, version: 1 },
113-
contentChanges: []
114-
});
82+
await client.openDocument("./subject.schema.json", `{}`);
11583

11684
const diagnostics = await diagnosticsPromise;
11785
expect(diagnostics[0].message).to.eql("Unknown dialect");
11886
});
87+
88+
test("watches only specified files", async () => {
89+
await client.changeConfiguration({ "schemaFilePatterns": ["**/subjectB.schema.json"] });
90+
91+
const diagnosticsPromise = new Promise<string>((resolve) => {
92+
client.onNotification(PublishDiagnosticsNotification.type, (params) => {
93+
resolve(params.uri);
94+
});
95+
});
96+
97+
await client.openDocument("./subject.schema.json", "{}");
98+
const documentUriB = await client.openDocument("./subjectB.schema.json", "{}");
99+
100+
const diagnostics = await diagnosticsPromise;
101+
expect(diagnostics).to.equal(documentUriB);
102+
});
119103
});

language-server/src/features/file-patterns-watch-all-files.test.ts

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

0 commit comments

Comments
 (0)