Skip to content

Commit e03f10b

Browse files
committed
updates
1 parent 0bb04cb commit e03f10b

File tree

1 file changed

+63
-85
lines changed

1 file changed

+63
-85
lines changed

src/test/integration/pythonProjects.integration.test.ts

Lines changed: 63 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,45 @@ import { PythonEnvironment, PythonEnvironmentApi } from '../../api';
2323
import { ENVS_EXTENSION_ID } from '../constants';
2424
import { TestEventHandler, waitForCondition } from '../testUtils';
2525

26+
const ENV_CHANGE_TIMEOUT_MS = 15_000;
27+
28+
function getDifferentEnvironment(
29+
environments: PythonEnvironment[],
30+
currentEnv: PythonEnvironment | undefined,
31+
): PythonEnvironment | undefined {
32+
return environments.find((env) => env.envId.id !== currentEnv?.envId.id);
33+
}
34+
35+
async function setEnvironmentAndWaitForChange(
36+
api: PythonEnvironmentApi,
37+
projectUri: vscode.Uri,
38+
env: PythonEnvironment,
39+
timeoutMs = ENV_CHANGE_TIMEOUT_MS,
40+
): Promise<void> {
41+
await new Promise<void>((resolve, reject) => {
42+
let subscription: vscode.Disposable | undefined;
43+
const timeout = setTimeout(() => {
44+
subscription?.dispose();
45+
reject(new Error(`onDidChangeEnvironment did not fire within ${timeoutMs}ms. Expected envId: ${env.envId.id}`));
46+
}, timeoutMs);
47+
48+
subscription = api.onDidChangeEnvironment((e) => {
49+
if (e.uri?.toString() === projectUri.toString() && e.new?.envId.id === env.envId.id) {
50+
clearTimeout(timeout);
51+
subscription?.dispose();
52+
resolve();
53+
}
54+
});
55+
56+
// Set environment after subscribing so we don't miss the event.
57+
api.setEnvironment(projectUri, env).catch((err) => {
58+
clearTimeout(timeout);
59+
subscription?.dispose();
60+
reject(err);
61+
});
62+
});
63+
}
64+
2665
suite('Integration: Python Projects', function () {
2766
this.timeout(60_000);
2867

@@ -170,43 +209,19 @@ suite('Integration: Python Projects', function () {
170209
const project = projects[0];
171210

172211
// Pick an environment different from the current one so setEnvironment
173-
// actually triggers a change event. If we pick the already-active env,
174-
// the event never fires and the test times out.
212+
// actually triggers a change event. If all candidates map to the same env,
213+
// skip instead of hanging on an event that will never fire.
175214
const currentEnv = await api.getEnvironment(project.uri);
176-
let env = environments[0];
177-
if (currentEnv && currentEnv.envId.id === env.envId.id) {
178-
env = environments[1];
215+
const env = getDifferentEnvironment(environments, currentEnv);
216+
if (!env) {
217+
this.skip();
218+
return;
179219
}
180220

181-
// Wait for the change event, then verify getEnvironment.
182221
// Using an event-driven approach instead of polling avoids a race condition where
183222
// setEnvironment's async settings write hasn't landed by the time getEnvironment
184223
// reads back the manager from settings.
185-
await new Promise<void>((resolve, reject) => {
186-
const timeout = setTimeout(() => {
187-
subscription.dispose();
188-
reject(
189-
new Error(
190-
`onDidChangeEnvironment did not fire for project within 15s. Expected envId: ${env.envId.id}`,
191-
),
192-
);
193-
}, 15_000);
194-
195-
const subscription = api.onDidChangeEnvironment((e) => {
196-
if (e.uri?.toString() === project.uri.toString() && e.new?.envId.id === env.envId.id) {
197-
clearTimeout(timeout);
198-
subscription.dispose();
199-
resolve();
200-
}
201-
});
202-
203-
// Set environment after subscribing so we don't miss the event
204-
api.setEnvironment(project.uri, env).catch((err) => {
205-
clearTimeout(timeout);
206-
subscription.dispose();
207-
reject(err);
208-
});
209-
});
224+
await setEnvironmentAndWaitForChange(api, project.uri, env);
210225

211226
// Verify getEnvironment returns the correct value now that setEnvironment has fully completed
212227
const retrievedEnv = await api.getEnvironment(project.uri);
@@ -231,13 +246,12 @@ suite('Integration: Python Projects', function () {
231246

232247
const project = projects[0];
233248

234-
// Get current environment to pick a different one
249+
// Pick an environment different from the current one so a change event is guaranteed.
235250
const currentEnv = await api.getEnvironment(project.uri);
236-
237-
// Pick an environment different from current
238-
let targetEnv = environments[0];
239-
if (currentEnv && currentEnv.envId.id === targetEnv.envId.id) {
240-
targetEnv = environments[1];
251+
const targetEnv = getDifferentEnvironment(environments, currentEnv);
252+
if (!targetEnv) {
253+
this.skip();
254+
return;
241255
}
242256

243257
// Register handler BEFORE making the change
@@ -283,32 +297,14 @@ suite('Integration: Python Projects', function () {
283297

284298
// Pick an environment different from the current one to guarantee a change event
285299
const currentEnv = await api.getEnvironment(project.uri);
286-
let env = environments[0];
287-
if (currentEnv && currentEnv.envId.id === env.envId.id) {
288-
env = environments[1];
300+
const env = getDifferentEnvironment(environments, currentEnv);
301+
if (!env) {
302+
this.skip();
303+
return;
289304
}
290305

291-
// Set environment first, using event-driven wait
292-
await new Promise<void>((resolve, reject) => {
293-
const timeout = setTimeout(() => {
294-
subscription.dispose();
295-
reject(new Error(`onDidChangeEnvironment did not fire within 15s. Expected envId: ${env.envId.id}`));
296-
}, 15_000);
297-
298-
const subscription = api.onDidChangeEnvironment((e) => {
299-
if (e.uri?.toString() === project.uri.toString() && e.new?.envId.id === env.envId.id) {
300-
clearTimeout(timeout);
301-
subscription.dispose();
302-
resolve();
303-
}
304-
});
305-
306-
api.setEnvironment(project.uri, env).catch((err) => {
307-
clearTimeout(timeout);
308-
subscription.dispose();
309-
reject(err);
310-
});
311-
});
306+
// Set environment first, using event-driven wait.
307+
await setEnvironmentAndWaitForChange(api, project.uri, env);
312308

313309
// Verify it was set
314310
const beforeClear = await api.getEnvironment(project.uri);
@@ -356,32 +352,14 @@ suite('Integration: Python Projects', function () {
356352

357353
// Pick an environment different from the current one to guarantee a change event
358354
const currentEnv = await api.getEnvironment(project.uri);
359-
let env = environments[0];
360-
if (currentEnv && currentEnv.envId.id === env.envId.id) {
361-
env = environments[1];
355+
const env = getDifferentEnvironment(environments, currentEnv);
356+
if (!env) {
357+
this.skip();
358+
return;
362359
}
363360

364-
// Set environment for project, using event-driven wait
365-
await new Promise<void>((resolve, reject) => {
366-
const timeout = setTimeout(() => {
367-
subscription.dispose();
368-
reject(new Error(`onDidChangeEnvironment did not fire within 15s. Expected envId: ${env.envId.id}`));
369-
}, 15_000);
370-
371-
const subscription = api.onDidChangeEnvironment((e) => {
372-
if (e.uri?.toString() === project.uri.toString() && e.new?.envId.id === env.envId.id) {
373-
clearTimeout(timeout);
374-
subscription.dispose();
375-
resolve();
376-
}
377-
});
378-
379-
api.setEnvironment(project.uri, env).catch((err) => {
380-
clearTimeout(timeout);
381-
subscription.dispose();
382-
reject(err);
383-
});
384-
});
361+
// Set environment for project, using event-driven wait.
362+
await setEnvironmentAndWaitForChange(api, project.uri, env);
385363

386364
// Create a hypothetical file path inside the project
387365
const fileUri = vscode.Uri.joinPath(project.uri, 'some_script.py');

0 commit comments

Comments
 (0)