Skip to content

Commit 68a2a6c

Browse files
committed
Add test helper with disposal for test cleanup
Create reusable context helper with dispose method to properly clean up subscriptions between tests and prevent resource leaks.
1 parent 2760701 commit 68a2a6c

17 files changed

+189
-161
lines changed

vscode/src/test/suite/client.test.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import { WorkspaceChannel } from "../../workspaceChannel";
3333
import { MAJOR, MINOR } from "../rubyVersion";
3434

3535
import { FAKE_TELEMETRY, FakeLogger } from "./fakeTelemetry";
36-
import { createRubySymlinks } from "./helpers";
36+
import { createContext, createRubySymlinks } from "./helpers";
3737

3838
async function launchClient(workspaceUri: vscode.Uri) {
3939
const workspaceFolder: vscode.WorkspaceFolder = {
@@ -42,15 +42,7 @@ async function launchClient(workspaceUri: vscode.Uri) {
4242
index: 0,
4343
};
4444

45-
const context = {
46-
extensionMode: vscode.ExtensionMode.Test,
47-
subscriptions: [],
48-
workspaceState: {
49-
get: (_name: string) => undefined,
50-
update: (_name: string, _value: any) => Promise.resolve(),
51-
},
52-
extensionUri: vscode.Uri.file(path.join(workspaceUri.fsPath, "vscode")),
53-
} as unknown as vscode.ExtensionContext;
45+
const context = createContext();
5446
const fakeLogger = new FakeLogger();
5547
const outputChannel = new WorkspaceChannel("fake", fakeLogger as any);
5648

vscode/src/test/suite/debugger.test.ts

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ import { LOG_CHANNEL, asyncExec } from "../../common";
1414
import { RUBY_VERSION } from "../rubyVersion";
1515

1616
import { FAKE_TELEMETRY } from "./fakeTelemetry";
17-
import { createRubySymlinks } from "./helpers";
17+
import { createContext, createRubySymlinks, FakeContext } from "./helpers";
1818

1919
suite("Debugger", () => {
20+
let context: FakeContext;
21+
2022
const original = vscode.workspace
2123
.getConfiguration("debug")
2224
.get("saveBeforeStart");
@@ -25,16 +27,19 @@ suite("Debugger", () => {
2527
await vscode.workspace
2628
.getConfiguration("debug")
2729
.update("saveBeforeStart", "none", true);
30+
31+
context = createContext();
2832
});
2933

3034
afterEach(async () => {
3135
await vscode.workspace
3236
.getConfiguration("debug")
3337
.update("saveBeforeStart", original, true);
38+
39+
context.dispose();
3440
});
3541

3642
test("Provide debug configurations returns the default configs", () => {
37-
const context = { subscriptions: [] } as unknown as vscode.ExtensionContext;
3843
const debug = new Debugger(context, () => {
3944
return undefined;
4045
});
@@ -69,7 +74,6 @@ suite("Debugger", () => {
6974
});
7075

7176
test("Resolve configuration injects Ruby environment", async () => {
72-
const context = { subscriptions: [] } as unknown as vscode.ExtensionContext;
7377
const ruby = {
7478
env: { bogus: "hello!", overrideMe: "oldValue" },
7579
} as unknown as Ruby;
@@ -105,7 +109,6 @@ suite("Debugger", () => {
105109
});
106110

107111
test("Resolve configuration injects Ruby environment and allows users custom environment", async () => {
108-
const context = { subscriptions: [] } as unknown as vscode.ExtensionContext;
109112
const ruby = { env: { bogus: "hello!" } } as unknown as Ruby;
110113
const workspaceFolder = {
111114
name: "fake",
@@ -140,7 +143,6 @@ suite("Debugger", () => {
140143
fs.mkdirSync(path.join(tmpPath, ".ruby-lsp"));
141144
fs.writeFileSync(path.join(tmpPath, ".ruby-lsp", "Gemfile"), "hello!");
142145

143-
const context = { subscriptions: [] } as unknown as vscode.ExtensionContext;
144146
const ruby = { env: { bogus: "hello!" } } as unknown as Ruby;
145147
const workspaceFolder = {
146148
name: "fake",
@@ -204,15 +206,6 @@ suite("Debugger", () => {
204206
'source "https://rubygems.org"\ngem "debug"',
205207
);
206208

207-
const extensionPath = path.dirname(path.dirname(path.dirname(__dirname)));
208-
const context = {
209-
subscriptions: [],
210-
workspaceState: {
211-
get: () => undefined,
212-
update: () => undefined,
213-
},
214-
extensionUri: vscode.Uri.file(extensionPath),
215-
} as unknown as vscode.ExtensionContext;
216209
const outputChannel = new WorkspaceChannel("fake", LOG_CHANNEL);
217210
const workspaceFolder: vscode.WorkspaceFolder = {
218211
uri: vscode.Uri.file(tmpPath),

vscode/src/test/suite/helpers.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,19 @@ export const LSP_WORKSPACE_FOLDER: vscode.WorkspaceFolder = {
7070
name: path.basename(LSP_WORKSPACE_PATH),
7171
index: 0,
7272
};
73-
export const CONTEXT = {
74-
extensionMode: vscode.ExtensionMode.Test,
75-
subscriptions: [],
76-
workspaceState: new FakeWorkspaceState(),
77-
extensionUri: vscode.Uri.joinPath(LSP_WORKSPACE_URI, "vscode"),
78-
} as unknown as vscode.ExtensionContext;
73+
74+
export type FakeContext = vscode.ExtensionContext & { dispose: () => void };
75+
76+
export function createContext() {
77+
const subscriptions: vscode.Disposable[] = [];
78+
79+
return {
80+
extensionMode: vscode.ExtensionMode.Test,
81+
subscriptions,
82+
workspaceState: new FakeWorkspaceState(),
83+
extensionUri: vscode.Uri.joinPath(LSP_WORKSPACE_URI, "vscode"),
84+
dispose: () => {
85+
subscriptions.forEach((subscription) => subscription.dispose());
86+
},
87+
} as unknown as FakeContext;
88+
}

vscode/src/test/suite/launch.test.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ import os from "os";
66
import * as vscode from "vscode";
77
import { State } from "vscode-languageclient/node";
88
import sinon from "sinon";
9-
import { beforeEach } from "mocha";
9+
import { afterEach, beforeEach } from "mocha";
1010

1111
import { ManagerIdentifier, Ruby } from "../../ruby";
1212
import Client from "../../client";
1313
import { WorkspaceChannel } from "../../workspaceChannel";
1414
import * as common from "../../common";
1515

1616
import { FAKE_TELEMETRY, FakeLogger } from "./fakeTelemetry";
17-
import { createRubySymlinks } from "./helpers";
17+
import { createContext, createRubySymlinks, FakeContext } from "./helpers";
1818

1919
suite("Launch integrations", () => {
2020
const workspacePath = path.dirname(
@@ -27,15 +27,16 @@ suite("Launch integrations", () => {
2727
index: 0,
2828
};
2929

30-
const context = {
31-
extensionMode: vscode.ExtensionMode.Test,
32-
subscriptions: [],
33-
workspaceState: {
34-
get: (_name: string) => undefined,
35-
update: (_name: string, _value: any) => Promise.resolve(),
36-
},
37-
extensionUri: vscode.Uri.joinPath(workspaceUri, "vscode"),
38-
} as unknown as vscode.ExtensionContext;
30+
let context: FakeContext;
31+
32+
beforeEach(() => {
33+
context = createContext();
34+
});
35+
36+
afterEach(() => {
37+
context.dispose();
38+
});
39+
3940
const fakeLogger = new FakeLogger();
4041
const outputChannel = new WorkspaceChannel("fake", fakeLogger as any);
4142

vscode/src/test/suite/ruby.test.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
VALUE_SEPARATOR,
1818
} from "../../ruby/versionManager";
1919

20-
import { CONTEXT } from "./helpers";
20+
import { createContext, FakeContext } from "./helpers";
2121
import { FAKE_TELEMETRY } from "./fakeTelemetry";
2222

2323
suite("Ruby environment activation", () => {
@@ -31,13 +31,16 @@ suite("Ruby environment activation", () => {
3131
};
3232
const outputChannel = new WorkspaceChannel("fake", LOG_CHANNEL);
3333
let sandbox: sinon.SinonSandbox;
34+
let context: FakeContext;
3435

3536
beforeEach(() => {
3637
sandbox = sinon.createSandbox();
38+
context = createContext();
3739
});
3840

3941
afterEach(() => {
4042
sandbox.restore();
43+
context.dispose();
4144
});
4245

4346
test("Activate fetches Ruby information when outside of Ruby LSP", async () => {
@@ -58,7 +61,7 @@ suite("Ruby environment activation", () => {
5861
} as unknown as vscode.WorkspaceConfiguration);
5962

6063
const ruby = new Ruby(
61-
CONTEXT,
64+
context,
6265
workspaceFolder,
6366
outputChannel,
6467
FAKE_TELEMETRY,
@@ -91,7 +94,7 @@ suite("Ruby environment activation", () => {
9194
} as unknown as vscode.WorkspaceConfiguration);
9295

9396
const ruby = new Ruby(
94-
CONTEXT,
97+
context,
9598
workspaceFolder,
9699
outputChannel,
97100
FAKE_TELEMETRY,
@@ -136,7 +139,7 @@ suite("Ruby environment activation", () => {
136139
});
137140

138141
const ruby = new Ruby(
139-
CONTEXT,
142+
context,
140143
workspaceFolder,
141144
outputChannel,
142145
FAKE_TELEMETRY,
@@ -151,7 +154,7 @@ suite("Ruby environment activation", () => {
151154

152155
test("mergeComposedEnv merges environment variables", () => {
153156
const ruby = new Ruby(
154-
CONTEXT,
157+
context,
155158
workspaceFolder,
156159
outputChannel,
157160
FAKE_TELEMETRY,
@@ -168,7 +171,7 @@ suite("Ruby environment activation", () => {
168171

169172
test("Ignores untrusted workspace for telemetry", async () => {
170173
const telemetry = { ...FAKE_TELEMETRY, logError: sinon.stub() };
171-
const ruby = new Ruby(CONTEXT, workspaceFolder, outputChannel, telemetry);
174+
const ruby = new Ruby(context, workspaceFolder, outputChannel, telemetry);
172175

173176
sandbox
174177
.stub(Shadowenv.prototype, "activate")
@@ -198,12 +201,12 @@ suite("Ruby environment activation", () => {
198201
},
199202
} as unknown as vscode.WorkspaceConfiguration);
200203

201-
await CONTEXT.workspaceState.update(
204+
await context.workspaceState.update(
202205
`rubyLsp.workspaceRubyPath.${workspaceFolder.name}`,
203206
"/totally/non/existent/path/ruby",
204207
);
205208
const ruby = new Ruby(
206-
CONTEXT,
209+
context,
207210
workspaceFolder,
208211
outputChannel,
209212
FAKE_TELEMETRY,
@@ -212,7 +215,7 @@ suite("Ruby environment activation", () => {
212215
await ruby.activateRuby();
213216

214217
assert.strictEqual(
215-
CONTEXT.workspaceState.get(
218+
context.workspaceState.get(
216219
`rubyLsp.workspaceRubyPath.${workspaceFolder.name}`,
217220
),
218221
undefined,

vscode/src/test/suite/ruby/asdf.test.ts

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import os from "os";
44

55
import * as vscode from "vscode";
66
import sinon from "sinon";
7+
import { afterEach, beforeEach } from "mocha";
78

89
import { Asdf } from "../../../ruby/asdf";
910
import { WorkspaceChannel } from "../../../workspaceChannel";
@@ -13,22 +14,26 @@ import {
1314
FIELD_SEPARATOR,
1415
VALUE_SEPARATOR,
1516
} from "../../../ruby/versionManager";
17+
import { createContext, FakeContext } from "../helpers";
1618

1719
suite("Asdf", () => {
1820
if (os.platform() === "win32") {
1921
// eslint-disable-next-line no-console
2022
console.log("Skipping Asdf tests on Windows");
2123
return;
2224
}
23-
const context = {
24-
extensionMode: vscode.ExtensionMode.Test,
25-
subscriptions: [],
26-
workspaceState: {
27-
get: (_name: string) => undefined,
28-
update: (_name: string, _value: any) => Promise.resolve(),
29-
},
30-
extensionUri: vscode.Uri.parse("file:///fake"),
31-
} as unknown as vscode.ExtensionContext;
25+
let context: FakeContext;
26+
let activationPath: vscode.Uri;
27+
28+
beforeEach(() => {
29+
context = createContext();
30+
activationPath = vscode.Uri.joinPath(context.extensionUri, "activation.rb");
31+
});
32+
33+
afterEach(() => {
34+
context.dispose();
35+
});
36+
3237
// eslint-disable-next-line no-process-env
3338
const workspacePath = process.env.PWD!;
3439
const workspaceFolder = {
@@ -66,7 +71,7 @@ suite("Asdf", () => {
6671

6772
assert.ok(
6873
execStub.calledOnceWithExactly(
69-
`. ${os.homedir()}/.asdf/asdf.sh && asdf exec ruby -EUTF-8:UTF-8 '/fake/activation.rb'`,
74+
`. ${os.homedir()}/.asdf/asdf.sh && asdf exec ruby -EUTF-8:UTF-8 '${activationPath.fsPath}'`,
7075
{
7176
cwd: workspacePath,
7277
shell: "/bin/bash",
@@ -116,7 +121,7 @@ suite("Asdf", () => {
116121

117122
assert.ok(
118123
execStub.calledOnceWithExactly(
119-
`. ${os.homedir()}/.asdf/asdf.fish && asdf exec ruby -EUTF-8:UTF-8 '/fake/activation.rb'`,
124+
`. ${os.homedir()}/.asdf/asdf.fish && asdf exec ruby -EUTF-8:UTF-8 '${activationPath.fsPath}'`,
120125
{
121126
cwd: workspacePath,
122127
shell: "/opt/homebrew/bin/fish",
@@ -167,7 +172,7 @@ suite("Asdf", () => {
167172

168173
assert.ok(
169174
execStub.calledOnceWithExactly(
170-
`/opt/homebrew/bin/asdf exec ruby -EUTF-8:UTF-8 '/fake/activation.rb'`,
175+
`/opt/homebrew/bin/asdf exec ruby -EUTF-8:UTF-8 '${activationPath.fsPath}'`,
171176
{
172177
cwd: workspacePath,
173178
shell: vscode.env.shell,
@@ -214,7 +219,7 @@ suite("Asdf", () => {
214219

215220
assert.ok(
216221
execStub.calledOnceWithExactly(
217-
`asdf exec ruby -EUTF-8:UTF-8 '/fake/activation.rb'`,
222+
`asdf exec ruby -EUTF-8:UTF-8 '${activationPath.fsPath}'`,
218223
{
219224
cwd: workspacePath,
220225
shell: vscode.env.shell,

0 commit comments

Comments
 (0)