Skip to content

Commit 46e1265

Browse files
fix: return after terminal script dispatch
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 03176cd commit 46e1265

2 files changed

Lines changed: 143 additions & 2 deletions

File tree

src/features/envCommands.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,7 @@ export async function runInTerminalCommand(
831831
args: [item.fsPath],
832832
show: true,
833833
});
834+
return;
834835
}
835836
}
836837
throw new Error(`Invalid context for run-in-terminal: ${item}`);
@@ -855,6 +856,7 @@ export async function runInDedicatedTerminalCommand(
855856
args: [item.fsPath],
856857
show: true,
857858
});
859+
return;
858860
}
859861
}
860862
throw new Error(`Invalid context for run-in-terminal: ${item}`);

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

Lines changed: 141 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import * as assert from 'assert';
22
import * as sinon from 'sinon';
33
import * as typeMoq from 'typemoq';
4-
import { Uri } from 'vscode';
5-
import { PythonEnvironment, PythonProject } from '../../api';
4+
import { Terminal, Uri } from 'vscode';
5+
import { PythonEnvironment, PythonEnvironmentApi, PythonProject } from '../../api';
66
import * as commandApi from '../../common/command.api';
77
import { INLINE_SCRIPT_MANAGER_ID } from '../../common/constants';
88
import * as managerApi from '../../common/pickers/managers';
@@ -13,12 +13,17 @@ import {
1313
createAnyEnvironmentCommand,
1414
removePythonProject,
1515
revealEnvInManagerView,
16+
runInDedicatedTerminalCommand,
17+
runInTerminalCommand,
1618
} from '../../features/envCommands';
1719
import * as settingHelpers from '../../features/settings/settingHelpers';
20+
import * as terminalRunner from '../../features/terminal/runInTerminal';
21+
import { TerminalManager } from '../../features/terminal/terminalManager';
1822
import { EnvManagerView } from '../../features/views/envManagersView';
1923
import { ProjectEnvironment, ProjectItem } from '../../features/views/treeViewItems';
2024
import { EnvironmentManagers, InternalEnvironmentManager, PythonProjectManager } from '../../internal.api';
2125
import { setupNonThenable } from '../mocks/helper';
26+
import { createMockPythonEnvironment } from '../mocks/pythonEnvironment';
2227

2328
suite('Create Any Environment Command Tests', () => {
2429
let em: typeMoq.IMock<EnvironmentManagers>;
@@ -385,3 +390,137 @@ suite('Reveal Env In Manager View Command Tests', () => {
385390
managerView.verify((m) => m.reveal(environment), typeMoq.Times.once());
386391
});
387392
});
393+
394+
suite('Run In Terminal Command Tests', () => {
395+
const scriptUri = Uri.file('/some/test/workspace/folder/script.py');
396+
const project: PythonProject = {
397+
uri: Uri.file('/some/test/workspace/folder'),
398+
name: 'test-folder',
399+
};
400+
401+
let environment: PythonEnvironment;
402+
let resolvedEnvironment: PythonEnvironment;
403+
let terminal: Terminal;
404+
let api: PythonEnvironmentApi;
405+
let terminalManager: TerminalManager;
406+
let getPythonProject: sinon.SinonStub;
407+
let getEnvironment: sinon.SinonStub;
408+
let resolveEnvironment: sinon.SinonStub;
409+
let getProjectTerminal: sinon.SinonStub;
410+
let getDedicatedTerminal: sinon.SinonStub;
411+
let runInTerminalStub: sinon.SinonStub;
412+
413+
setup(() => {
414+
environment = createMockPythonEnvironment({
415+
envPath: '/some/test/env/python',
416+
id: 'discovered-environment',
417+
});
418+
resolvedEnvironment = createMockPythonEnvironment({
419+
envPath: '/some/test/resolved-env/python',
420+
id: 'resolved-environment',
421+
});
422+
terminal = {} as Terminal;
423+
424+
getPythonProject = sinon.stub().returns(project);
425+
getEnvironment = sinon.stub().resolves(environment);
426+
resolveEnvironment = sinon.stub().resolves(resolvedEnvironment);
427+
api = {
428+
getPythonProject,
429+
getEnvironment,
430+
resolveEnvironment,
431+
} as unknown as PythonEnvironmentApi;
432+
433+
getProjectTerminal = sinon.stub().resolves(terminal);
434+
getDedicatedTerminal = sinon.stub().resolves(terminal);
435+
terminalManager = {
436+
getProjectTerminal,
437+
getDedicatedTerminal,
438+
} as unknown as TerminalManager;
439+
440+
runInTerminalStub = sinon.stub(terminalRunner, 'runInTerminal').resolves();
441+
});
442+
443+
teardown(() => {
444+
sinon.restore();
445+
});
446+
447+
test('successful normal terminal dispatch resolves and uses the resolved environment', async () => {
448+
const result = await runInTerminalCommand(scriptUri, api, terminalManager);
449+
450+
assert.strictEqual(result, undefined);
451+
sinon.assert.calledOnceWithExactly(resolveEnvironment, environment.environmentPath);
452+
sinon.assert.calledOnceWithExactly(getProjectTerminal, project, resolvedEnvironment);
453+
sinon.assert.calledOnce(runInTerminalStub);
454+
const [receivedEnvironment, receivedTerminal, receivedOptions] = runInTerminalStub.firstCall.args;
455+
assert.strictEqual(receivedEnvironment, resolvedEnvironment);
456+
assert.strictEqual(receivedTerminal, terminal);
457+
assert.deepStrictEqual(receivedOptions, {
458+
cwd: project.uri,
459+
args: [scriptUri.fsPath],
460+
show: true,
461+
});
462+
});
463+
464+
test('successful dedicated terminal dispatch resolves and falls back to the discovered environment', async () => {
465+
resolveEnvironment.resolves(undefined);
466+
467+
const result = await runInDedicatedTerminalCommand(scriptUri, api, terminalManager);
468+
469+
assert.strictEqual(result, undefined);
470+
sinon.assert.calledOnceWithExactly(resolveEnvironment, environment.environmentPath);
471+
sinon.assert.calledOnceWithExactly(getDedicatedTerminal, scriptUri, project, environment);
472+
sinon.assert.calledOnce(runInTerminalStub);
473+
const [receivedEnvironment, receivedTerminal, receivedOptions] = runInTerminalStub.firstCall.args;
474+
assert.strictEqual(receivedEnvironment, environment);
475+
assert.strictEqual(receivedTerminal, terminal);
476+
assert.deepStrictEqual(receivedOptions, {
477+
cwd: project.uri,
478+
args: [scriptUri.fsPath],
479+
show: true,
480+
});
481+
});
482+
483+
test('normal terminal dispatch rejects non-URI and missing project/environment contexts', async () => {
484+
await assert.rejects(
485+
runInTerminalCommand('not-a-uri', api, terminalManager),
486+
/Invalid context for run-in-terminal/,
487+
);
488+
sinon.assert.notCalled(getPythonProject);
489+
sinon.assert.notCalled(getEnvironment);
490+
491+
getPythonProject.returns(undefined);
492+
await assert.rejects(runInTerminalCommand(scriptUri, api, terminalManager), /Invalid context for run-in-terminal/);
493+
494+
getPythonProject.returns(project);
495+
getEnvironment.resolves(undefined);
496+
await assert.rejects(runInTerminalCommand(scriptUri, api, terminalManager), /Invalid context for run-in-terminal/);
497+
498+
sinon.assert.notCalled(getProjectTerminal);
499+
sinon.assert.notCalled(runInTerminalStub);
500+
});
501+
502+
test('dedicated terminal dispatch rejects non-URI and missing project/environment contexts', async () => {
503+
await assert.rejects(
504+
runInDedicatedTerminalCommand('not-a-uri', api, terminalManager),
505+
/Invalid context for run-in-terminal/,
506+
);
507+
sinon.assert.notCalled(getPythonProject);
508+
sinon.assert.notCalled(getEnvironment);
509+
510+
getPythonProject.returns(undefined);
511+
await assert.rejects(
512+
runInDedicatedTerminalCommand(scriptUri, api, terminalManager),
513+
/Invalid context for run-in-terminal/,
514+
);
515+
516+
getPythonProject.returns(project);
517+
getEnvironment.resolves(undefined);
518+
await assert.rejects(
519+
runInDedicatedTerminalCommand(scriptUri, api, terminalManager),
520+
/Invalid context for run-in-terminal/,
521+
);
522+
523+
sinon.assert.notCalled(getDedicatedTerminal);
524+
sinon.assert.notCalled(runInTerminalStub);
525+
});
526+
});

0 commit comments

Comments
 (0)