Skip to content

Commit 5fcb6b0

Browse files
Fix terminal creation for selected environment
Co-authored-by: eleanorjboyd <26030610+eleanorjboyd@users.noreply.github.com>
1 parent c4a48f8 commit 5fcb6b0

2 files changed

Lines changed: 91 additions & 10 deletions

File tree

‎src/features/envCommands.ts‎

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,13 @@ export async function createTerminalCommand(
814814
tm: TerminalManager,
815815
): Promise<Terminal | undefined> {
816816
const pythonProjects = api.getPythonProjects();
817+
if (context instanceof PythonEnvTreeItem) {
818+
const pw = await pickProject(pythonProjects);
819+
const cwd = pw ? await findParentIfFile(pw.uri.fsPath) : undefined;
820+
const terminal = await tm.create(context.environment, { cwd });
821+
terminal.show();
822+
return terminal;
823+
}
817824
// If no context is provided, or there are multiple projects, prompt the user to select a project for the terminal's cwd
818825
if (context === undefined || pythonProjects.length > 0) {
819826
const pw = await pickProject(pythonProjects);
@@ -848,15 +855,6 @@ export async function createTerminalCommand(
848855
terminal.show();
849856
return terminal;
850857
}
851-
} else if (context instanceof PythonEnvTreeItem) {
852-
const view = context as PythonEnvTreeItem;
853-
const pw = await pickProject(pythonProjects);
854-
if (pw) {
855-
const cwd = await findParentIfFile(pw.uri.fsPath);
856-
const terminal = await tm.create(view.environment, { cwd });
857-
terminal.show();
858-
return terminal;
859-
}
860858
}
861859
}
862860

‎src/test/features/envCommands.unit.test.ts‎

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
clearEnvironmentCachesCommand,
1515
clearScriptEnvironmentCacheCommand,
1616
createAnyEnvironmentCommand,
17+
createTerminalCommand,
1718
removeEnvironmentCommand,
1819
removePythonProject,
1920
revealEnvInManagerView,
@@ -26,7 +27,12 @@ import * as shellProviders from '../../features/terminal/shells/providers';
2627
import { ShellStartupScriptProvider } from '../../features/terminal/shells/startupProvider';
2728
import { TerminalManager } from '../../features/terminal/terminalManager';
2829
import { EnvManagerView } from '../../features/views/envManagersView';
29-
import { ProjectEnvironment, ProjectItem } from '../../features/views/treeViewItems';
30+
import {
31+
EnvManagerTreeItem,
32+
ProjectEnvironment,
33+
ProjectItem,
34+
PythonEnvTreeItem,
35+
} from '../../features/views/treeViewItems';
3036
import type { EnvironmentManagers } from '../../features/envManagers';
3137
import type { PythonProjectManager } from '../../features/projectManager';
3238
import { InternalEnvironmentManager } from '../../managers/common/registeredManagers';
@@ -94,6 +100,83 @@ suite('Environment removal command ownership', () => {
94100
});
95101
});
96102

103+
suite('Create Terminal Command Tests', () => {
104+
teardown(() => {
105+
sinon.restore();
106+
});
107+
108+
function createEnvironmentItem(environment: PythonEnvironment): PythonEnvTreeItem {
109+
const manager = {
110+
id: environment.envId.managerId,
111+
name: 'venv',
112+
displayName: 'Venv',
113+
} as InternalEnvironmentManager;
114+
return new PythonEnvTreeItem(environment, new EnvManagerTreeItem(manager));
115+
}
116+
117+
function createTerminalManager() {
118+
const terminal = { show: sinon.stub() } as unknown as Terminal;
119+
const create = sinon.stub().resolves(terminal);
120+
return { terminal, create, manager: { create } as unknown as TerminalManager };
121+
}
122+
123+
test('creates a terminal for the clicked environment without a project', async () => {
124+
const environment = createMockPythonEnvironment({
125+
managerId: 'ms-python.python:venv',
126+
envPath: path.join(process.cwd(), '.venv', 'python'),
127+
});
128+
const getEnvironment = sinon.stub().resolves(undefined);
129+
const api = {
130+
getPythonProjects: sinon.stub().returns([]),
131+
getEnvironment,
132+
} as unknown as PythonEnvironmentApi;
133+
const terminalManager = createTerminalManager();
134+
135+
const result = await createTerminalCommand(createEnvironmentItem(environment), api, terminalManager.manager);
136+
137+
assert.strictEqual(result, terminalManager.terminal);
138+
sinon.assert.calledOnceWithExactly(terminalManager.create, environment, { cwd: undefined });
139+
sinon.assert.calledOnce(terminalManager.terminal.show as sinon.SinonStub);
140+
sinon.assert.notCalled(getEnvironment);
141+
});
142+
143+
for (const projectEnvironment of [
144+
undefined,
145+
createMockPythonEnvironment({
146+
name: 'project-environment',
147+
managerId: 'ms-python.python:venv',
148+
envPath: path.join(process.cwd(), 'project-environment', 'python'),
149+
}),
150+
]) {
151+
const projectEnvironmentDescription = projectEnvironment ? 'a different environment' : 'no environment';
152+
153+
test(`creates a terminal for the clicked environment when the project has ${projectEnvironmentDescription}`, async () => {
154+
const environment = createMockPythonEnvironment({
155+
name: 'clicked-environment',
156+
managerId: 'ms-python.python:venv',
157+
envPath: path.join(process.cwd(), 'clicked-environment', 'python'),
158+
});
159+
const project: PythonProject = {
160+
name: 'project',
161+
uri: Uri.file(process.cwd()),
162+
};
163+
const getEnvironment = sinon.stub().resolves(projectEnvironment);
164+
const api = {
165+
getPythonProjects: sinon.stub().returns([project]),
166+
getEnvironment,
167+
} as unknown as PythonEnvironmentApi;
168+
const terminalManager = createTerminalManager();
169+
170+
const result = await createTerminalCommand(createEnvironmentItem(environment), api, terminalManager.manager);
171+
172+
assert.strictEqual(result, terminalManager.terminal);
173+
sinon.assert.calledOnceWithExactly(terminalManager.create, environment, { cwd: project.uri.fsPath });
174+
sinon.assert.calledOnce(terminalManager.terminal.show as sinon.SinonStub);
175+
sinon.assert.notCalled(getEnvironment);
176+
});
177+
}
178+
});
179+
97180
suite('Create Any Environment Command Tests', () => {
98181
let em: typeMoq.IMock<EnvironmentManagers>;
99182
let pm: typeMoq.IMock<PythonProjectManager>;

0 commit comments

Comments
 (0)