@@ -11,21 +11,29 @@ import {
1111 TerminalShellExecution ,
1212 TerminalShellExecutionEndEvent ,
1313 TerminalShellIntegration ,
14+ Uri ,
1415 Terminal as VSCodeTerminal ,
1516 WorkspaceConfiguration ,
1617} from 'vscode' ;
1718import { ITerminalManager , IWorkspaceService } from '../../../client/common/application/types' ;
1819import { EXTENSION_ROOT_DIR } from '../../../client/common/constants' ;
1920import { IPlatformService } from '../../../client/common/platform/types' ;
2021import { TerminalService } from '../../../client/common/terminal/service' ;
21- import { ITerminalActivator , ITerminalHelper , TerminalShellType } from '../../../client/common/terminal/types' ;
22+ import {
23+ ITerminalActivator ,
24+ ITerminalHelper ,
25+ TerminalCreationOptions ,
26+ TerminalShellType ,
27+ } from '../../../client/common/terminal/types' ;
2228import { IDisposableRegistry } from '../../../client/common/types' ;
2329import { IServiceContainer } from '../../../client/ioc/types' ;
2430import { ITerminalAutoActivation } from '../../../client/terminals/types' ;
2531import { createPythonInterpreter } from '../../utils/interpreters' ;
2632import * as workspaceApis from '../../../client/common/vscodeApis/workspaceApis' ;
2733import * as platform from '../../../client/common/utils/platform' ;
2834import * as extapi from '../../../client/envExt/api.internal' ;
35+ import { IInterpreterService } from '../../../client/interpreter/contracts' ;
36+ import { PythonEnvironment } from '../../../client/pythonEnvironments/info' ;
2937
3038suite ( 'Terminal Service' , ( ) => {
3139 let service : TerminalService ;
@@ -46,6 +54,8 @@ suite('Terminal Service', () => {
4654 let editorConfig : TypeMoq . IMock < WorkspaceConfiguration > ;
4755 let isWindowsStub : sinon . SinonStub ;
4856 let useEnvExtensionStub : sinon . SinonStub ;
57+ let interpreterService : TypeMoq . IMock < IInterpreterService > ;
58+ let options : TypeMoq . IMock < TerminalCreationOptions > ;
4959
5060 setup ( ( ) => {
5161 useEnvExtensionStub = sinon . stub ( extapi , 'useEnvExtension' ) ;
@@ -92,6 +102,13 @@ suite('Terminal Service', () => {
92102 disposables = [ ] ;
93103
94104 mockServiceContainer = TypeMoq . Mock . ofType < IServiceContainer > ( ) ;
105+ interpreterService = TypeMoq . Mock . ofType < IInterpreterService > ( ) ;
106+ interpreterService
107+ . setup ( ( i ) => i . getActiveInterpreter ( TypeMoq . It . isAny ( ) ) )
108+ . returns ( ( ) => Promise . resolve ( ( { path : 'ps' } as unknown ) as PythonEnvironment ) ) ;
109+
110+ options = TypeMoq . Mock . ofType < TerminalCreationOptions > ( ) ;
111+ options . setup ( ( o ) => o . resource ) . returns ( ( ) => Uri . parse ( 'a' ) ) ;
95112
96113 mockServiceContainer . setup ( ( c ) => c . get ( ITerminalManager ) ) . returns ( ( ) => terminalManager . object ) ;
97114 mockServiceContainer . setup ( ( c ) => c . get ( ITerminalHelper ) ) . returns ( ( ) => terminalHelper . object ) ;
@@ -100,6 +117,7 @@ suite('Terminal Service', () => {
100117 mockServiceContainer . setup ( ( c ) => c . get ( IWorkspaceService ) ) . returns ( ( ) => workspaceService . object ) ;
101118 mockServiceContainer . setup ( ( c ) => c . get ( ITerminalActivator ) ) . returns ( ( ) => terminalActivator . object ) ;
102119 mockServiceContainer . setup ( ( c ) => c . get ( ITerminalAutoActivation ) ) . returns ( ( ) => terminalAutoActivator . object ) ;
120+ mockServiceContainer . setup ( ( c ) => c . get ( IInterpreterService ) ) . returns ( ( ) => interpreterService . object ) ;
103121 getConfigurationStub = sinon . stub ( workspaceApis , 'getConfiguration' ) ;
104122 isWindowsStub = sinon . stub ( platform , 'isWindows' ) ;
105123 pythonConfig = TypeMoq . Mock . ofType < WorkspaceConfiguration > ( ) ;
@@ -117,6 +135,8 @@ suite('Terminal Service', () => {
117135 }
118136 disposables . filter ( ( item ) => ! ! item ) . forEach ( ( item ) => item . dispose ( ) ) ;
119137 sinon . restore ( ) ;
138+ // reset setup for interpreterService
139+ interpreterService . reset ( ) ;
120140 } ) ;
121141
122142 test ( 'Ensure terminal is disposed' , async ( ) => {
@@ -239,7 +259,7 @@ suite('Terminal Service', () => {
239259 terminal . verify ( ( t ) => t . sendText ( TypeMoq . It . isValue ( textToSend ) ) , TypeMoq . Times . exactly ( 1 ) ) ;
240260 } ) ;
241261
242- test ( 'Ensure sendText is NOT called when Python shell integration and terminal shell integration are both enabled - Mac, Linux' , async ( ) => {
262+ test ( 'Ensure sendText is NOT called when Python shell integration and terminal shell integration are both enabled - Mac, Linux && Python < 3.13 ' , async ( ) => {
243263 isWindowsStub . returns ( false ) ;
244264 pythonConfig
245265 . setup ( ( p ) => p . get ( 'terminal.shellIntegration.enabled' ) )
@@ -261,6 +281,36 @@ suite('Terminal Service', () => {
261281 terminal . verify ( ( t ) => t . sendText ( TypeMoq . It . isValue ( textToSend ) ) , TypeMoq . Times . never ( ) ) ;
262282 } ) ;
263283
284+ test ( 'Ensure sendText is called when Python shell integration and terminal shell integration are both enabled - Mac, Linux && Python >= 3.13' , async ( ) => {
285+ interpreterService . reset ( ) ;
286+
287+ interpreterService
288+ . setup ( ( i ) => i . getActiveInterpreter ( TypeMoq . It . isAny ( ) ) )
289+ . returns ( ( ) =>
290+ Promise . resolve ( { path : 'yo' , version : { major : 3 , minor : 13 , patch : 0 } } as PythonEnvironment ) ,
291+ ) ;
292+
293+ isWindowsStub . returns ( false ) ;
294+ pythonConfig
295+ . setup ( ( p ) => p . get ( 'terminal.shellIntegration.enabled' ) )
296+ . returns ( ( ) => true )
297+ . verifiable ( TypeMoq . Times . once ( ) ) ;
298+
299+ terminalHelper
300+ . setup ( ( helper ) => helper . getEnvironmentActivationCommands ( TypeMoq . It . isAny ( ) , TypeMoq . It . isAny ( ) ) )
301+ . returns ( ( ) => Promise . resolve ( undefined ) ) ;
302+
303+ service = new TerminalService ( mockServiceContainer . object , options . object ) ;
304+ const textToSend = 'Some Text' ;
305+ terminalHelper . setup ( ( h ) => h . identifyTerminalShell ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => TerminalShellType . bash ) ;
306+ terminalManager . setup ( ( t ) => t . createTerminal ( TypeMoq . It . isAny ( ) ) ) . returns ( ( ) => terminal . object ) ;
307+
308+ await service . ensureTerminal ( ) ;
309+ await service . executeCommand ( textToSend , true ) ;
310+
311+ terminal . verify ( ( t ) => t . sendText ( TypeMoq . It . isValue ( textToSend ) ) , TypeMoq . Times . once ( ) ) ;
312+ } ) ;
313+
264314 test ( 'Ensure sendText IS called even when Python shell integration and terminal shell integration are both enabled - Window' , async ( ) => {
265315 isWindowsStub . returns ( true ) ;
266316 pythonConfig
0 commit comments