diff --git a/src/client/common/terminal/service.ts b/src/client/common/terminal/service.ts index 5eddf2d07fc5..0a1271d8153d 100644 --- a/src/client/common/terminal/service.ts +++ b/src/client/common/terminal/service.ts @@ -25,7 +25,7 @@ import { useEnvExtension } from '../../envExt/api.internal'; import { ensureTerminalLegacy } from '../../envExt/api.legacy'; import { sleep } from '../utils/async'; import { isWindows } from '../utils/platform'; -// import { getPythonMinorVersion } from '../../repl/replUtils'; +import { getPythonMinorVersion } from '../../repl/replUtils'; @injectable() export class TerminalService implements ITerminalService, Disposable { @@ -110,13 +110,13 @@ export class TerminalService implements ITerminalService, Disposable { const config = getConfiguration('python'); const pythonrcSetting = config.get('terminal.shellIntegration.enabled'); - // const minorVersion = this.options?.resource - // ? await getPythonMinorVersion( - // this.options.resource, - // this.serviceContainer.get(IInterpreterService), - // ) - // : undefined; - // || (minorVersion ?? 0) >= 13 + const minorVersion = this.options?.resource + ? await getPythonMinorVersion( + this.options.resource, + this.serviceContainer.get(IInterpreterService), + ) + : undefined; + || (minorVersion ?? 0) >= 13 if ((isPythonShell && !pythonrcSetting) || (isPythonShell && isWindows())) { // If user has explicitly disabled SI for Python, use sendText for inside Terminal REPL. diff --git a/src/test/common/terminals/service.unit.test.ts b/src/test/common/terminals/service.unit.test.ts index 8d0b441df64f..39512133f6b5 100644 --- a/src/test/common/terminals/service.unit.test.ts +++ b/src/test/common/terminals/service.unit.test.ts @@ -11,7 +11,7 @@ import { TerminalShellExecution, TerminalShellExecutionEndEvent, TerminalShellIntegration, - // Uri, + Uri, Terminal as VSCodeTerminal, WorkspaceConfiguration, } from 'vscode'; @@ -22,7 +22,7 @@ import { TerminalService } from '../../../client/common/terminal/service'; import { ITerminalActivator, ITerminalHelper, - // TerminalCreationOptions, + TerminalCreationOptions, TerminalShellType, } from '../../../client/common/terminal/types'; import { IDisposableRegistry } from '../../../client/common/types'; @@ -33,7 +33,7 @@ import * as workspaceApis from '../../../client/common/vscodeApis/workspaceApis' import * as platform from '../../../client/common/utils/platform'; import * as extapi from '../../../client/envExt/api.internal'; import { IInterpreterService } from '../../../client/interpreter/contracts'; -// import { PythonEnvironment } from '../../../client/pythonEnvironments/info'; +import { PythonEnvironment } from '../../../client/pythonEnvironments/info'; suite('Terminal Service', () => { let service: TerminalService; @@ -55,7 +55,7 @@ suite('Terminal Service', () => { let isWindowsStub: sinon.SinonStub; let useEnvExtensionStub: sinon.SinonStub; let interpreterService: TypeMoq.IMock; - // let options: TypeMoq.IMock; + let options: TypeMoq.IMock; setup(() => { useEnvExtensionStub = sinon.stub(extapi, 'useEnvExtension'); @@ -102,13 +102,13 @@ suite('Terminal Service', () => { disposables = []; mockServiceContainer = TypeMoq.Mock.ofType(); - // interpreterService = TypeMoq.Mock.ofType(); - // interpreterService - // .setup((i) => i.getActiveInterpreter(TypeMoq.It.isAny())) - // .returns(() => Promise.resolve(({ path: 'ps' } as unknown) as PythonEnvironment)); + interpreterService = TypeMoq.Mock.ofType(); + interpreterService + .setup((i) => i.getActiveInterpreter(TypeMoq.It.isAny())) + .returns(() => Promise.resolve(({ path: 'ps' } as unknown) as PythonEnvironment)); - // options = TypeMoq.Mock.ofType(); - // options.setup((o) => o.resource).returns(() => Uri.parse('a')); + options = TypeMoq.Mock.ofType(); + options.setup((o) => o.resource).returns(() => Uri.parse('a')); mockServiceContainer.setup((c) => c.get(ITerminalManager)).returns(() => terminalManager.object); mockServiceContainer.setup((c) => c.get(ITerminalHelper)).returns(() => terminalHelper.object); @@ -259,57 +259,57 @@ suite('Terminal Service', () => { terminal.verify((t) => t.sendText(TypeMoq.It.isValue(textToSend)), TypeMoq.Times.exactly(1)); }); - // test('Ensure sendText is NOT called when Python shell integration and terminal shell integration are both enabled - Mac, Linux && Python < 3.13', async () => { - // isWindowsStub.returns(false); - // pythonConfig - // .setup((p) => p.get('terminal.shellIntegration.enabled')) - // .returns(() => true) - // .verifiable(TypeMoq.Times.once()); - - // terminalHelper - // .setup((helper) => helper.getEnvironmentActivationCommands(TypeMoq.It.isAny(), TypeMoq.It.isAny())) - // .returns(() => Promise.resolve(undefined)); - // service = new TerminalService(mockServiceContainer.object); - // const textToSend = 'Some Text'; - // terminalHelper.setup((h) => h.identifyTerminalShell(TypeMoq.It.isAny())).returns(() => TerminalShellType.bash); - // terminalManager.setup((t) => t.createTerminal(TypeMoq.It.isAny())).returns(() => terminal.object); - - // service.ensureTerminal(); - // service.executeCommand(textToSend, true); - - // terminal.verify((t) => t.show(TypeMoq.It.isValue(true)), TypeMoq.Times.exactly(1)); - // terminal.verify((t) => t.sendText(TypeMoq.It.isValue(textToSend)), TypeMoq.Times.never()); - // }); - - // test('Ensure sendText is called when Python shell integration and terminal shell integration are both enabled - Mac, Linux && Python >= 3.13', async () => { - // interpreterService.reset(); - - // interpreterService - // .setup((i) => i.getActiveInterpreter(TypeMoq.It.isAny())) - // .returns(() => - // Promise.resolve({ path: 'yo', version: { major: 3, minor: 13, patch: 0 } } as PythonEnvironment), - // ); - - // isWindowsStub.returns(false); - // pythonConfig - // .setup((p) => p.get('terminal.shellIntegration.enabled')) - // .returns(() => true) - // .verifiable(TypeMoq.Times.once()); - - // terminalHelper - // .setup((helper) => helper.getEnvironmentActivationCommands(TypeMoq.It.isAny(), TypeMoq.It.isAny())) - // .returns(() => Promise.resolve(undefined)); - - // service = new TerminalService(mockServiceContainer.object, options.object); - // const textToSend = 'Some Text'; - // terminalHelper.setup((h) => h.identifyTerminalShell(TypeMoq.It.isAny())).returns(() => TerminalShellType.bash); - // terminalManager.setup((t) => t.createTerminal(TypeMoq.It.isAny())).returns(() => terminal.object); - - // await service.ensureTerminal(); - // await service.executeCommand(textToSend, true); - - // terminal.verify((t) => t.sendText(TypeMoq.It.isValue(textToSend)), TypeMoq.Times.once()); - // }); + test('Ensure sendText is NOT called when Python shell integration and terminal shell integration are both enabled - Mac, Linux && Python < 3.13', async () => { + isWindowsStub.returns(false); + pythonConfig + .setup((p) => p.get('terminal.shellIntegration.enabled')) + .returns(() => true) + .verifiable(TypeMoq.Times.once()); + + terminalHelper + .setup((helper) => helper.getEnvironmentActivationCommands(TypeMoq.It.isAny(), TypeMoq.It.isAny())) + .returns(() => Promise.resolve(undefined)); + service = new TerminalService(mockServiceContainer.object); + const textToSend = 'Some Text'; + terminalHelper.setup((h) => h.identifyTerminalShell(TypeMoq.It.isAny())).returns(() => TerminalShellType.bash); + terminalManager.setup((t) => t.createTerminal(TypeMoq.It.isAny())).returns(() => terminal.object); + + service.ensureTerminal(); + service.executeCommand(textToSend, true); + + terminal.verify((t) => t.show(TypeMoq.It.isValue(true)), TypeMoq.Times.exactly(1)); + terminal.verify((t) => t.sendText(TypeMoq.It.isValue(textToSend)), TypeMoq.Times.never()); + }); + + test('Ensure sendText is called when Python shell integration and terminal shell integration are both enabled - Mac, Linux && Python >= 3.13', async () => { + interpreterService.reset(); + + interpreterService + .setup((i) => i.getActiveInterpreter(TypeMoq.It.isAny())) + .returns(() => + Promise.resolve({ path: 'yo', version: { major: 3, minor: 13, patch: 0 } } as PythonEnvironment), + ); + + isWindowsStub.returns(false); + pythonConfig + .setup((p) => p.get('terminal.shellIntegration.enabled')) + .returns(() => true) + .verifiable(TypeMoq.Times.once()); + + terminalHelper + .setup((helper) => helper.getEnvironmentActivationCommands(TypeMoq.It.isAny(), TypeMoq.It.isAny())) + .returns(() => Promise.resolve(undefined)); + + service = new TerminalService(mockServiceContainer.object, options.object); + const textToSend = 'Some Text'; + terminalHelper.setup((h) => h.identifyTerminalShell(TypeMoq.It.isAny())).returns(() => TerminalShellType.bash); + terminalManager.setup((t) => t.createTerminal(TypeMoq.It.isAny())).returns(() => terminal.object); + + await service.ensureTerminal(); + await service.executeCommand(textToSend, true); + + terminal.verify((t) => t.sendText(TypeMoq.It.isValue(textToSend)), TypeMoq.Times.once()); + }); test('Ensure sendText IS called even when Python shell integration and terminal shell integration are both enabled - Window', async () => { isWindowsStub.returns(true);