11import * as assert from 'assert' ;
22import * as sinon from 'sinon' ;
33import * 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' ;
66import * as commandApi from '../../common/command.api' ;
77import { INLINE_SCRIPT_MANAGER_ID } from '../../common/constants' ;
88import * 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' ;
1719import * as settingHelpers from '../../features/settings/settingHelpers' ;
20+ import * as terminalRunner from '../../features/terminal/runInTerminal' ;
21+ import { TerminalManager } from '../../features/terminal/terminalManager' ;
1822import { EnvManagerView } from '../../features/views/envManagersView' ;
1923import { ProjectEnvironment , ProjectItem } from '../../features/views/treeViewItems' ;
2024import { EnvironmentManagers , InternalEnvironmentManager , PythonProjectManager } from '../../internal.api' ;
2125import { setupNonThenable } from '../mocks/helper' ;
26+ import { createMockPythonEnvironment } from '../mocks/pythonEnvironment' ;
2227
2328suite ( '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+ / I n v a l i d c o n t e x t f o r r u n - i n - t e r m i n a l / ,
487+ ) ;
488+ sinon . assert . notCalled ( getPythonProject ) ;
489+ sinon . assert . notCalled ( getEnvironment ) ;
490+
491+ getPythonProject . returns ( undefined ) ;
492+ await assert . rejects ( runInTerminalCommand ( scriptUri , api , terminalManager ) , / I n v a l i d c o n t e x t f o r r u n - i n - t e r m i n a l / ) ;
493+
494+ getPythonProject . returns ( project ) ;
495+ getEnvironment . resolves ( undefined ) ;
496+ await assert . rejects ( runInTerminalCommand ( scriptUri , api , terminalManager ) , / I n v a l i d c o n t e x t f o r r u n - i n - t e r m i n a l / ) ;
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+ / I n v a l i d c o n t e x t f o r r u n - i n - t e r m i n a l / ,
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+ / I n v a l i d c o n t e x t f o r r u n - i n - t e r m i n a l / ,
514+ ) ;
515+
516+ getPythonProject . returns ( project ) ;
517+ getEnvironment . resolves ( undefined ) ;
518+ await assert . rejects (
519+ runInDedicatedTerminalCommand ( scriptUri , api , terminalManager ) ,
520+ / I n v a l i d c o n t e x t f o r r u n - i n - t e r m i n a l / ,
521+ ) ;
522+
523+ sinon . assert . notCalled ( getDedicatedTerminal ) ;
524+ sinon . assert . notCalled ( runInTerminalStub ) ;
525+ } ) ;
526+ } ) ;
0 commit comments