Skip to content

Commit df4f582

Browse files
committed
Add sinon sandbox to prevent test leakage
Replace direct `sinon.stub()` with sandbox pattern for proper cleanup between tests
1 parent 68a2a6c commit df4f582

File tree

12 files changed

+88
-78
lines changed

12 files changed

+88
-78
lines changed

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

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
ShowMessageParams,
2626
MessageType,
2727
} from "vscode-languageclient/node";
28-
import { after, afterEach, before, setup } from "mocha";
28+
import { after, afterEach, before, beforeEach, setup } from "mocha";
2929

3030
import { Ruby, ManagerIdentifier } from "../../ruby";
3131
import Client from "../../client";
@@ -141,6 +141,7 @@ suite("Client", () => {
141141
"fake.rb",
142142
);
143143
let client: Client;
144+
let sandbox: sinon.SinonSandbox;
144145

145146
before(async function () {
146147
// 60000 should be plenty but we're seeing timeouts on Windows in CI
@@ -150,6 +151,10 @@ suite("Client", () => {
150151
client = await launchClient(workspaceUri);
151152
});
152153

154+
beforeEach(() => {
155+
sandbox = sinon.createSandbox();
156+
});
157+
153158
after(async function () {
154159
// eslint-disable-next-line no-invalid-this
155160
this.timeout(20000);
@@ -177,6 +182,7 @@ suite("Client", () => {
177182
});
178183

179184
afterEach(async () => {
185+
sandbox.restore();
180186
await client.sendNotification("textDocument/didClose", {
181187
textDocument: {
182188
uri: documentUri.toString(),
@@ -807,15 +813,14 @@ suite("Client", () => {
807813
},
808814
});
809815

810-
const stub = sinon.stub(vscode.commands, "executeCommand").resolves(null);
816+
const stub = sandbox.stub(vscode.commands, "executeCommand").resolves(null);
811817

812818
await client.sendRequest("textDocument/definition", {
813819
textDocument: {
814820
uri,
815821
},
816822
position: { line: 1, character: 5 },
817823
});
818-
stub.restore();
819824

820825
await client.sendNotification("textDocument/didClose", {
821826
textDocument: { uri },
@@ -862,7 +867,7 @@ suite("Client", () => {
862867
},
863868
});
864869

865-
const stub = sinon.stub(vscode.commands, "executeCommand").resolves(null);
870+
const stub = sandbox.stub(vscode.commands, "executeCommand").resolves(null);
866871

867872
await client.sendRequest("textDocument/signatureHelp", {
868873
textDocument: {
@@ -871,7 +876,6 @@ suite("Client", () => {
871876
position: { line: 1, character: 23 },
872877
context: {},
873878
});
874-
stub.restore();
875879

876880
await client.sendNotification("textDocument/didClose", {
877881
textDocument: { uri },
@@ -919,7 +923,7 @@ suite("Client", () => {
919923
},
920924
});
921925

922-
const stub = sinon.stub(vscode.commands, "executeCommand").resolves(null);
926+
const stub = sandbox.stub(vscode.commands, "executeCommand").resolves(null);
923927

924928
await client.sendRequest("textDocument/documentHighlight", {
925929
textDocument: {
@@ -928,7 +932,6 @@ suite("Client", () => {
928932
position: { line: 1, character: 4 },
929933
context: {},
930934
});
931-
stub.restore();
932935

933936
await client.sendNotification("textDocument/didClose", {
934937
textDocument: { uri },

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,15 @@ suite("Launch integrations", () => {
2828
};
2929

3030
let context: FakeContext;
31+
let sandbox: sinon.SinonSandbox;
3132

3233
beforeEach(() => {
34+
sandbox = sinon.createSandbox();
3335
context = createContext();
3436
});
3537

3638
afterEach(() => {
39+
sandbox.restore();
3740
context.dispose();
3841
});
3942

@@ -98,9 +101,8 @@ suite("Launch integrations", () => {
98101
});
99102

100103
test("with launcher mode enabled", async () => {
101-
const featureStub = sinon.stub(common, "featureEnabled").returns(true);
104+
sandbox.stub(common, "featureEnabled").returns(true);
102105
const client = await createClient();
103-
featureStub.restore();
104106

105107
await startClient(client);
106108

vscode/src/test/suite/rails.test.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import path from "path";
44

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

89
import { Rails } from "../../rails";
910
import { Workspace } from "../../workspace";
@@ -21,8 +22,18 @@ suite("Rails", () => {
2122
index: 0,
2223
};
2324

25+
let sandbox: sinon.SinonSandbox;
26+
27+
beforeEach(() => {
28+
sandbox = sinon.createSandbox();
29+
});
30+
31+
afterEach(() => {
32+
sandbox.restore();
33+
});
34+
2435
test("generate", async () => {
25-
const executeStub = sinon.stub();
36+
const executeStub = sandbox.stub();
2637
const workspace = {
2738
workspaceFolder,
2839
execute: executeStub.resolves({
@@ -31,8 +42,8 @@ suite("Rails", () => {
3142
}),
3243
} as unknown as Workspace;
3344

34-
const showDocumentStub = sinon.stub(vscode.window, "showTextDocument");
35-
const executeCommandStub = sinon.stub(vscode.commands, "executeCommand");
45+
const showDocumentStub = sandbox.stub(vscode.window, "showTextDocument");
46+
sandbox.stub(vscode.commands, "executeCommand");
3647

3748
const selectedWorkspace = undefined;
3849
const rails = new Rails(() => Promise.resolve(workspace));
@@ -64,12 +75,10 @@ suite("Rails", () => {
6475
{ preview: false },
6576
),
6677
);
67-
showDocumentStub.restore();
68-
executeCommandStub.restore();
6978
});
7079

7180
test("destroy", async () => {
72-
const executeStub = sinon.stub();
81+
const executeStub = sandbox.stub();
7382
const workspace = {
7483
workspaceFolder,
7584
execute: executeStub.resolves({
@@ -78,7 +87,7 @@ suite("Rails", () => {
7887
}),
7988
} as unknown as Workspace;
8089

81-
const executeCommandStub = sinon.stub(vscode.commands, "executeCommand");
90+
const executeCommandStub = sandbox.stub(vscode.commands, "executeCommand");
8291

8392
const selectedWorkspace = undefined;
8493
const rails = new Rails(() => Promise.resolve(workspace));
@@ -110,6 +119,5 @@ suite("Rails", () => {
110119
vscode.Uri.joinPath(workspaceUri, "app/models/user.rb"),
111120
),
112121
);
113-
executeCommandStub.restore();
114122
});
115123
});

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ suite("Ruby environment activation", () => {
170170
});
171171

172172
test("Ignores untrusted workspace for telemetry", async () => {
173-
const telemetry = { ...FAKE_TELEMETRY, logError: sinon.stub() };
173+
const telemetry = { ...FAKE_TELEMETRY, logError: sandbox.stub() };
174174
const ruby = new Ruby(context, workspaceFolder, outputChannel, telemetry);
175175

176176
sandbox

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

Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,16 @@ suite("Asdf", () => {
2424
}
2525
let context: FakeContext;
2626
let activationPath: vscode.Uri;
27+
let sandbox: sinon.SinonSandbox;
2728

2829
beforeEach(() => {
30+
sandbox = sinon.createSandbox();
2931
context = createContext();
3032
activationPath = vscode.Uri.joinPath(context.extensionUri, "activation.rb");
3133
});
3234

3335
afterEach(() => {
36+
sandbox.restore();
3437
context.dispose();
3538
});
3639

@@ -57,15 +60,15 @@ suite("Asdf", () => {
5760
`ANY${VALUE_SEPARATOR}true`,
5861
].join(FIELD_SEPARATOR);
5962

60-
const execStub = sinon.stub(common, "asyncExec").resolves({
63+
const execStub = sandbox.stub(common, "asyncExec").resolves({
6164
stdout: "",
6265
stderr: `${ACTIVATION_SEPARATOR}${envStub}${ACTIVATION_SEPARATOR}`,
6366
});
6467

65-
const findInstallationStub = sinon
68+
sandbox
6669
.stub(asdf, "findAsdfInstallation")
6770
.resolves(`${os.homedir()}/.asdf/asdf.sh`);
68-
const shellStub = sinon.stub(vscode.env, "shell").get(() => "/bin/bash");
71+
sandbox.stub(vscode.env, "shell").get(() => "/bin/bash");
6972

7073
const { env, version, yjit } = await asdf.activate();
7174

@@ -85,10 +88,6 @@ suite("Asdf", () => {
8588
assert.strictEqual(version, "3.0.0");
8689
assert.strictEqual(yjit, true);
8790
assert.strictEqual(env.ANY, "true");
88-
89-
execStub.restore();
90-
findInstallationStub.restore();
91-
shellStub.restore();
9291
});
9392

9493
test("Searches for asdf.fish when using the fish shell", async () => {
@@ -105,17 +104,15 @@ suite("Asdf", () => {
105104
"true",
106105
`ANY${VALUE_SEPARATOR}true`,
107106
].join(FIELD_SEPARATOR);
108-
const execStub = sinon.stub(common, "asyncExec").resolves({
107+
const execStub = sandbox.stub(common, "asyncExec").resolves({
109108
stdout: "",
110109
stderr: `${ACTIVATION_SEPARATOR}${envStub}${ACTIVATION_SEPARATOR}`,
111110
});
112111

113-
const findInstallationStub = sinon
112+
sandbox
114113
.stub(asdf, "findAsdfInstallation")
115114
.resolves(`${os.homedir()}/.asdf/asdf.fish`);
116-
const shellStub = sinon
117-
.stub(vscode.env, "shell")
118-
.get(() => "/opt/homebrew/bin/fish");
115+
sandbox.stub(vscode.env, "shell").get(() => "/opt/homebrew/bin/fish");
119116

120117
const { env, version, yjit } = await asdf.activate();
121118

@@ -135,10 +132,6 @@ suite("Asdf", () => {
135132
assert.strictEqual(version, "3.0.0");
136133
assert.strictEqual(yjit, true);
137134
assert.strictEqual(env.ANY, "true");
138-
139-
execStub.restore();
140-
findInstallationStub.restore();
141-
shellStub.restore();
142135
});
143136

144137
test("Finds ASDF executable for Homebrew if script is not available", async () => {
@@ -155,16 +148,14 @@ suite("Asdf", () => {
155148
"true",
156149
`ANY${VALUE_SEPARATOR}true`,
157150
].join(FIELD_SEPARATOR);
158-
const execStub = sinon.stub(common, "asyncExec").resolves({
151+
const execStub = sandbox.stub(common, "asyncExec").resolves({
159152
stdout: "",
160153
stderr: `${ACTIVATION_SEPARATOR}${envStub}${ACTIVATION_SEPARATOR}`,
161154
});
162155

163-
const findInstallationStub = sinon
164-
.stub(asdf, "findAsdfInstallation")
165-
.resolves(undefined);
156+
sandbox.stub(asdf, "findAsdfInstallation").resolves(undefined);
166157

167-
const fsStub = sinon.stub(vscode.workspace, "fs").value({
158+
sandbox.stub(vscode.workspace, "fs").value({
168159
stat: () => Promise.resolve(undefined),
169160
});
170161

@@ -186,10 +177,6 @@ suite("Asdf", () => {
186177
assert.strictEqual(version, "3.0.0");
187178
assert.strictEqual(yjit, true);
188179
assert.strictEqual(env.ANY, "true");
189-
190-
fsStub.restore();
191-
execStub.restore();
192-
findInstallationStub.restore();
193180
});
194181

195182
test("Uses ASDF executable in PATH if script and Homebrew executable are not available", async () => {
@@ -206,14 +193,12 @@ suite("Asdf", () => {
206193
"true",
207194
`ANY${VALUE_SEPARATOR}true`,
208195
].join(FIELD_SEPARATOR);
209-
const execStub = sinon.stub(common, "asyncExec").resolves({
196+
const execStub = sandbox.stub(common, "asyncExec").resolves({
210197
stdout: "",
211198
stderr: `${ACTIVATION_SEPARATOR}${envStub}${ACTIVATION_SEPARATOR}`,
212199
});
213200

214-
const findInstallationStub = sinon
215-
.stub(asdf, "findAsdfInstallation")
216-
.resolves(undefined);
201+
sandbox.stub(asdf, "findAsdfInstallation").resolves(undefined);
217202

218203
const { env, version, yjit } = await asdf.activate();
219204

@@ -233,8 +218,5 @@ suite("Asdf", () => {
233218
assert.strictEqual(version, "3.0.0");
234219
assert.strictEqual(yjit, true);
235220
assert.strictEqual(env.ANY, "true");
236-
237-
execStub.restore();
238-
findInstallationStub.restore();
239221
});
240222
});

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@ import { createContext, FakeContext } from "../helpers";
1919

2020
suite("Custom", () => {
2121
let context: FakeContext;
22+
let sandbox: sinon.SinonSandbox;
2223

2324
beforeEach(() => {
25+
sandbox = sinon.createSandbox();
2426
context = createContext();
2527
});
2628

2729
afterEach(() => {
30+
sandbox.restore();
2831
context.dispose();
2932
});
3033

@@ -53,12 +56,12 @@ suite("Custom", () => {
5356
`ANY${VALUE_SEPARATOR}true`,
5457
].join(FIELD_SEPARATOR);
5558

56-
const execStub = sinon.stub(common, "asyncExec").resolves({
59+
const execStub = sandbox.stub(common, "asyncExec").resolves({
5760
stdout: "",
5861
stderr: `${ACTIVATION_SEPARATOR}${envStub}${ACTIVATION_SEPARATOR}`,
5962
});
6063

61-
const commandStub = sinon
64+
sandbox
6265
.stub(custom, "customCommand")
6366
.returns("my_version_manager activate_env");
6467
const { env, version, yjit } = await custom.activate();
@@ -87,8 +90,6 @@ suite("Custom", () => {
8790
assert.strictEqual(yjit, true);
8891
assert.deepStrictEqual(env.ANY, "true");
8992

90-
execStub.restore();
91-
commandStub.restore();
9293
fs.rmSync(workspacePath, { recursive: true, force: true });
9394
});
9495
});

0 commit comments

Comments
 (0)