From 00f3466b93e9f8ef28a0ca4928965f1033029ca0 Mon Sep 17 00:00:00 2001 From: Rich Chiodo Date: Wed, 8 Jan 2020 09:40:34 -0800 Subject: [PATCH 1/5] Conda run doesn't work for normalizing lines or starting a repl --- src/client/terminals/codeExecution/helper.ts | 17 ++++++++++++----- .../codeExecution/terminalCodeExecution.ts | 5 ----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/client/terminals/codeExecution/helper.ts b/src/client/terminals/codeExecution/helper.ts index ee707df767a3..2deb4630d9c8 100644 --- a/src/client/terminals/codeExecution/helper.ts +++ b/src/client/terminals/codeExecution/helper.ts @@ -8,7 +8,9 @@ import { IApplicationShell, IDocumentManager } from '../../common/application/ty import { EXTENSION_ROOT_DIR, PYTHON_LANGUAGE } from '../../common/constants'; import '../../common/extensions'; import { traceError } from '../../common/logger'; -import { IPythonExecutionFactory } from '../../common/process/types'; +import { IFileSystem } from '../../common/platform/types'; +import { IProcessServiceFactory, IPythonExecutionFactory } from '../../common/process/types'; +import { IInterpreterService } from '../../interpreter/contracts'; import { IServiceContainer } from '../../ioc/types'; import { ICodeExecutionHelper } from '../types'; @@ -16,11 +18,15 @@ import { ICodeExecutionHelper } from '../types'; export class CodeExecutionHelper implements ICodeExecutionHelper { private readonly documentManager: IDocumentManager; private readonly applicationShell: IApplicationShell; - private readonly pythonServiceFactory: IPythonExecutionFactory; + private readonly processServiceFactory: IProcessServiceFactory; + private readonly fileSystem: IFileSystem; + private readonly interpreterService: IInterpreterService; constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) { this.documentManager = serviceContainer.get(IDocumentManager); this.applicationShell = serviceContainer.get(IApplicationShell); - this.pythonServiceFactory = serviceContainer.get(IPythonExecutionFactory); + this.processServiceFactory = serviceContainer.get(IProcessServiceFactory); + this.fileSystem = serviceContainer.get(IFileSystem); + this.interpreterService = serviceContainer.get(IInterpreterService); } public async normalizeLines(code: string, resource?: Uri): Promise { try { @@ -30,9 +36,10 @@ export class CodeExecutionHelper implements ICodeExecutionHelper { // On windows cr is not handled well by python when passing in/out via stdin/stdout. // So just remove cr from the input. code = code.replace(new RegExp('\\r', 'g'), ''); + const interpreter = await this.interpreterService.getActiveInterpreter(resource); + const processService = await this.processServiceFactory.create(resource); const args = [path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'normalizeForInterpreter.py'), code]; - const processService = await this.pythonServiceFactory.create({ resource }); - const proc = await processService.exec(args, { throwOnStdErr: true }); + const proc = await processService.exec(interpreter?.path || 'python', args, { throwOnStdErr: true }); return proc.stdout; } catch (ex) { diff --git a/src/client/terminals/codeExecution/terminalCodeExecution.ts b/src/client/terminals/codeExecution/terminalCodeExecution.ts index 77cf4a0f9d75..106fbfc36a18 100644 --- a/src/client/terminals/codeExecution/terminalCodeExecution.ts +++ b/src/client/terminals/codeExecution/terminalCodeExecution.ts @@ -64,11 +64,6 @@ export class TerminalCodeExecutionProvider implements ICodeExecutionService { const command = pythonSettings.pythonPath; const launchArgs = pythonSettings.terminal.launchArgs; - const condaExecutionService = await this.pythonExecFactory.createCondaExecutionService(command, undefined, resource); - if (condaExecutionService) { - return condaExecutionService.getExecutionInfo([...launchArgs, ...args]); - } - const isWindows = this.platformService.isWindows; return { From 2a52f44316b4d4344d9e8027e5aed3d60317d941 Mon Sep 17 00:00:00 2001 From: Rich Chiodo Date: Wed, 8 Jan 2020 09:42:23 -0800 Subject: [PATCH 2/5] Add news entries --- news/2 Fixes/9437.md | 1 + news/2 Fixes/9439.md | 1 + 2 files changed, 2 insertions(+) create mode 100644 news/2 Fixes/9437.md create mode 100644 news/2 Fixes/9439.md diff --git a/news/2 Fixes/9437.md b/news/2 Fixes/9437.md new file mode 100644 index 000000000000..0440859fa7d0 --- /dev/null +++ b/news/2 Fixes/9437.md @@ -0,0 +1 @@ +Shift+Enter can no longer send multiple lines to the interactive window. \ No newline at end of file diff --git a/news/2 Fixes/9439.md b/news/2 Fixes/9439.md new file mode 100644 index 000000000000..47c6305f5cb8 --- /dev/null +++ b/news/2 Fixes/9439.md @@ -0,0 +1 @@ +Shift+Enter can no longer run code in the terminal. \ No newline at end of file From af942a4ec31c68ba07dd05406ade945ef8e7e584 Mon Sep 17 00:00:00 2001 From: Rich Chiodo Date: Wed, 8 Jan 2020 09:45:34 -0800 Subject: [PATCH 3/5] Fix the rest of the linter errors --- .../codeExecution/djangoShellCodeExecution.ts | 5 ++--- src/client/terminals/codeExecution/helper.ts | 8 +++----- src/client/terminals/codeExecution/repl.ts | 4 +--- .../terminals/codeExecution/terminalCodeExecution.ts | 5 ++--- .../codeExecution/djangoShellCodeExect.unit.test.ts | 1 - .../codeExecution/terminalCodeExec.unit.test.ts | 12 ++---------- 6 files changed, 10 insertions(+), 25 deletions(-) diff --git a/src/client/terminals/codeExecution/djangoShellCodeExecution.ts b/src/client/terminals/codeExecution/djangoShellCodeExecution.ts index e1b7d23d7bab..2ead5fe58e82 100644 --- a/src/client/terminals/codeExecution/djangoShellCodeExecution.ts +++ b/src/client/terminals/codeExecution/djangoShellCodeExecution.ts @@ -9,7 +9,7 @@ import { Disposable, Uri } from 'vscode'; import { ICommandManager, IDocumentManager, IWorkspaceService } from '../../common/application/types'; import '../../common/extensions'; import { IFileSystem, IPlatformService } from '../../common/platform/types'; -import { IPythonExecutionFactory, PythonExecutionInfo } from '../../common/process/types'; +import { PythonExecutionInfo } from '../../common/process/types'; import { ITerminalServiceFactory } from '../../common/terminal/types'; import { IConfigurationService, IDisposableRegistry } from '../../common/types'; import { DjangoContextInitializer } from './djangoContext'; @@ -25,10 +25,9 @@ export class DjangoShellCodeExecutionProvider extends TerminalCodeExecutionProvi @inject(IPlatformService) platformService: IPlatformService, @inject(ICommandManager) commandManager: ICommandManager, @inject(IFileSystem) fileSystem: IFileSystem, - @inject(IPythonExecutionFactory) pythonExecFactory: IPythonExecutionFactory, @inject(IDisposableRegistry) disposableRegistry: Disposable[] ) { - super(terminalServiceFactory, configurationService, workspace, disposableRegistry, platformService, pythonExecFactory); + super(terminalServiceFactory, configurationService, workspace, disposableRegistry, platformService); this.terminalTitle = 'Django Shell'; disposableRegistry.push(new DjangoContextInitializer(documentManager, workspace, fileSystem, commandManager)); } diff --git a/src/client/terminals/codeExecution/helper.ts b/src/client/terminals/codeExecution/helper.ts index 2deb4630d9c8..c2172d490391 100644 --- a/src/client/terminals/codeExecution/helper.ts +++ b/src/client/terminals/codeExecution/helper.ts @@ -1,15 +1,15 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +import '../../common/extensions'; import { inject, injectable } from 'inversify'; import * as path from 'path'; import { Range, TextEditor, Uri } from 'vscode'; + import { IApplicationShell, IDocumentManager } from '../../common/application/types'; import { EXTENSION_ROOT_DIR, PYTHON_LANGUAGE } from '../../common/constants'; -import '../../common/extensions'; import { traceError } from '../../common/logger'; -import { IFileSystem } from '../../common/platform/types'; -import { IProcessServiceFactory, IPythonExecutionFactory } from '../../common/process/types'; +import { IProcessServiceFactory } from '../../common/process/types'; import { IInterpreterService } from '../../interpreter/contracts'; import { IServiceContainer } from '../../ioc/types'; import { ICodeExecutionHelper } from '../types'; @@ -19,13 +19,11 @@ export class CodeExecutionHelper implements ICodeExecutionHelper { private readonly documentManager: IDocumentManager; private readonly applicationShell: IApplicationShell; private readonly processServiceFactory: IProcessServiceFactory; - private readonly fileSystem: IFileSystem; private readonly interpreterService: IInterpreterService; constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) { this.documentManager = serviceContainer.get(IDocumentManager); this.applicationShell = serviceContainer.get(IApplicationShell); this.processServiceFactory = serviceContainer.get(IProcessServiceFactory); - this.fileSystem = serviceContainer.get(IFileSystem); this.interpreterService = serviceContainer.get(IInterpreterService); } public async normalizeLines(code: string, resource?: Uri): Promise { diff --git a/src/client/terminals/codeExecution/repl.ts b/src/client/terminals/codeExecution/repl.ts index 816b3ea3df6b..f3c620e83b75 100644 --- a/src/client/terminals/codeExecution/repl.ts +++ b/src/client/terminals/codeExecution/repl.ts @@ -7,7 +7,6 @@ import { inject, injectable } from 'inversify'; import { Disposable } from 'vscode'; import { IWorkspaceService } from '../../common/application/types'; import { IPlatformService } from '../../common/platform/types'; -import { IPythonExecutionFactory } from '../../common/process/types'; import { ITerminalServiceFactory } from '../../common/terminal/types'; import { IConfigurationService, IDisposableRegistry } from '../../common/types'; import { TerminalCodeExecutionProvider } from './terminalCodeExecution'; @@ -18,11 +17,10 @@ export class ReplProvider extends TerminalCodeExecutionProvider { @inject(ITerminalServiceFactory) terminalServiceFactory: ITerminalServiceFactory, @inject(IConfigurationService) configurationService: IConfigurationService, @inject(IWorkspaceService) workspace: IWorkspaceService, - @inject(IPythonExecutionFactory) pythonExecFactory: IPythonExecutionFactory, @inject(IDisposableRegistry) disposableRegistry: Disposable[], @inject(IPlatformService) platformService: IPlatformService ) { - super(terminalServiceFactory, configurationService, workspace, disposableRegistry, platformService, pythonExecFactory); + super(terminalServiceFactory, configurationService, workspace, disposableRegistry, platformService); this.terminalTitle = 'REPL'; } } diff --git a/src/client/terminals/codeExecution/terminalCodeExecution.ts b/src/client/terminals/codeExecution/terminalCodeExecution.ts index 106fbfc36a18..a8e72ba0f58d 100644 --- a/src/client/terminals/codeExecution/terminalCodeExecution.ts +++ b/src/client/terminals/codeExecution/terminalCodeExecution.ts @@ -9,7 +9,7 @@ import { Disposable, Uri } from 'vscode'; import { IWorkspaceService } from '../../common/application/types'; import '../../common/extensions'; import { IPlatformService } from '../../common/platform/types'; -import { IPythonExecutionFactory, PythonExecutionInfo } from '../../common/process/types'; +import { PythonExecutionInfo } from '../../common/process/types'; import { ITerminalService, ITerminalServiceFactory } from '../../common/terminal/types'; import { IConfigurationService, IDisposableRegistry } from '../../common/types'; import { ICodeExecutionService } from '../../terminals/types'; @@ -24,8 +24,7 @@ export class TerminalCodeExecutionProvider implements ICodeExecutionService { @inject(IConfigurationService) protected readonly configurationService: IConfigurationService, @inject(IWorkspaceService) protected readonly workspace: IWorkspaceService, @inject(IDisposableRegistry) protected readonly disposables: Disposable[], - @inject(IPlatformService) protected readonly platformService: IPlatformService, - @inject(IPythonExecutionFactory) private readonly pythonExecFactory: IPythonExecutionFactory + @inject(IPlatformService) protected readonly platformService: IPlatformService ) {} public async executeFile(file: Uri) { diff --git a/src/test/terminals/codeExecution/djangoShellCodeExect.unit.test.ts b/src/test/terminals/codeExecution/djangoShellCodeExect.unit.test.ts index cb45844345c7..ab0912b66569 100644 --- a/src/test/terminals/codeExecution/djangoShellCodeExect.unit.test.ts +++ b/src/test/terminals/codeExecution/djangoShellCodeExect.unit.test.ts @@ -54,7 +54,6 @@ suite('Terminal - Django Shell Code Execution', () => { platform.object, commandManager.object, fileSystem.object, - pythonExecutionFactory.object, disposables ); diff --git a/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts b/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts index c0ccf96c0b5e..ce8750254a1f 100644 --- a/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts +++ b/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts @@ -67,18 +67,11 @@ suite('Terminal - Code Execution', () => { switch (testSuiteName) { case 'Terminal Execution': { - executor = new TerminalCodeExecutionProvider( - terminalFactory.object, - configService.object, - workspace.object, - disposables, - platform.object, - pythonExecutionFactory.object - ); + executor = new TerminalCodeExecutionProvider(terminalFactory.object, configService.object, workspace.object, disposables, platform.object); break; } case 'Repl Execution': { - executor = new ReplProvider(terminalFactory.object, configService.object, workspace.object, pythonExecutionFactory.object, disposables, platform.object); + executor = new ReplProvider(terminalFactory.object, configService.object, workspace.object, disposables, platform.object); expectedTerminalTitle = 'REPL'; break; } @@ -97,7 +90,6 @@ suite('Terminal - Code Execution', () => { platform.object, commandManager.object, fileSystem.object, - pythonExecutionFactory.object, disposables ); expectedTerminalTitle = 'Django Shell'; From 1ceea24fce89bd8eea4a9e76898f8041d20b90a5 Mon Sep 17 00:00:00 2001 From: Rich Chiodo Date: Wed, 8 Jan 2020 10:34:53 -0800 Subject: [PATCH 4/5] Fix unit tests --- .../djangoShellCodeExect.unit.test.ts | 8 +++----- .../terminalCodeExec.unit.test.ts | 18 +++++------------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/test/terminals/codeExecution/djangoShellCodeExect.unit.test.ts b/src/test/terminals/codeExecution/djangoShellCodeExect.unit.test.ts index ab0912b66569..0c00e9ec8c5d 100644 --- a/src/test/terminals/codeExecution/djangoShellCodeExect.unit.test.ts +++ b/src/test/terminals/codeExecution/djangoShellCodeExect.unit.test.ts @@ -185,9 +185,7 @@ suite('Terminal - Django Shell Code Execution', () => { const serviceContainer = TypeMoq.Mock.ofType(); const processService = TypeMoq.Mock.ofType(); const condaExecutionService = new CondaExecutionService(serviceContainer.object, processService.object, pythonPath, condaFile, condaEnv); - const hasEnvName = condaEnv.name !== ''; - const condaArgs = ['run', ...(hasEnvName ? ['-n', condaEnv.name] : ['-p', condaEnv.path]), 'python']; - const expectedTerminalArgs = [...condaArgs, ...terminalArgs, 'manage.py', 'shell']; + const expectedTerminalArgs = [...terminalArgs, 'manage.py', 'shell']; pythonExecutionFactory .setup(p => p.createCondaExecutionService(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())) .returns(() => Promise.resolve(condaExecutionService)); @@ -195,8 +193,8 @@ suite('Terminal - Django Shell Code Execution', () => { const replCommandArgs = await (executor as DjangoShellCodeExecutionProvider).getExecutableInfo(resource); expect(replCommandArgs).not.to.be.an('undefined', 'Conda command args are undefined'); - expect(replCommandArgs.command).to.be.equal(condaFile, 'Incorrect conda path'); - expect(replCommandArgs.args).to.be.deep.equal(expectedTerminalArgs, 'Incorrect conda arguments'); + expect(replCommandArgs.command).to.be.equal(pythonPath, 'Repl should use python not conda'); + expect(replCommandArgs.args).to.be.deep.equal(expectedTerminalArgs, 'Incorrect terminal arguments'); } test('Ensure conda args including env name are passed when using a conda environment with a name', async () => { diff --git a/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts b/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts index ce8750254a1f..d890056d83f5 100644 --- a/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts +++ b/src/test/terminals/codeExecution/terminalCodeExec.unit.test.ts @@ -231,7 +231,6 @@ suite('Terminal - Code Execution', () => { const expectedPythonPath = isWindows ? pythonPath.replace(/\\/g, '/') : pythonPath; const expectedArgs = terminalArgs.concat(file.fsPath.fileToCommandArgument()); terminalService.verify(async t => t.sendCommand(TypeMoq.It.isValue(expectedPythonPath), TypeMoq.It.isValue(expectedArgs)), TypeMoq.Times.once()); - pythonExecutionFactory.verify(async p => p.createCondaExecutionService(pythonPath, undefined, file), TypeMoq.Times.once()); } test('Ensure python file execution script is sent to terminal on windows', async () => { @@ -270,12 +269,9 @@ suite('Terminal - Code Execution', () => { await executor.executeFile(file); - const hasEnvName = condaEnv.name !== ''; - const condaArgs = ['run', ...(hasEnvName ? ['-n', condaEnv.name] : ['-p', condaEnv.path]), 'python']; - const expectedArgs = [...condaArgs, ...terminalArgs, file.fsPath.fileToCommandArgument()]; + const expectedArgs = [...terminalArgs, file.fsPath.fileToCommandArgument()]; - pythonExecutionFactory.verify(async p => p.createCondaExecutionService(pythonPath, undefined, file), TypeMoq.Times.once()); - terminalService.verify(async t => t.sendCommand(TypeMoq.It.isValue(condaFile), TypeMoq.It.isValue(expectedArgs)), TypeMoq.Times.once()); + terminalService.verify(async t => t.sendCommand(TypeMoq.It.isValue(pythonPath), TypeMoq.It.isValue(expectedArgs)), TypeMoq.Times.once()); } test('Ensure conda args with conda env name are sent to terminal if there is a conda environment with a name', async () => { @@ -301,7 +297,6 @@ suite('Terminal - Code Execution', () => { expect(replCommandArgs).not.to.be.an('undefined', 'Command args is undefined'); expect(replCommandArgs.command).to.be.equal(expectedPythonPath, 'Incorrect python path'); expect(replCommandArgs.args).to.be.deep.equal(expectedTerminalArgs, 'Incorrect arguments'); - pythonExecutionFactory.verify(async p => p.createCondaExecutionService(pythonPath, undefined, undefined), TypeMoq.Times.once()); } test('Ensure fully qualified python path is escaped when building repl args on Windows', async () => { @@ -351,17 +346,14 @@ suite('Terminal - Code Execution', () => { .setup(p => p.createCondaExecutionService(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())) .returns(() => Promise.resolve(condaExecutionService)); - const hasEnvName = condaEnv.name !== ''; - const condaArgs = ['run', ...(hasEnvName ? ['-n', condaEnv.name] : ['-p', condaEnv.path]), 'python']; const djangoArgs = isDjangoRepl ? ['manage.py', 'shell'] : []; - const expectedTerminalArgs = [...condaArgs, ...terminalArgs, ...djangoArgs]; + const expectedTerminalArgs = [...terminalArgs, ...djangoArgs]; const replCommandArgs = await (executor as TerminalCodeExecutionProvider).getExecutableInfo(); expect(replCommandArgs).not.to.be.an('undefined', 'Conda command args are undefined'); - expect(replCommandArgs.command).to.be.equal('conda', 'Incorrect conda path'); - expect(replCommandArgs.args).to.be.deep.equal(expectedTerminalArgs, 'Incorrect conda arguments'); - pythonExecutionFactory.verify(async p => p.createCondaExecutionService(pythonPath, undefined, undefined), TypeMoq.Times.once()); + expect(replCommandArgs.command).to.be.equal(pythonPath, 'Repl needs to use python, not conda'); + expect(replCommandArgs.args).to.be.deep.equal(expectedTerminalArgs, 'Incorrect terminal arguments'); } test('Ensure conda args with env name are returned when building repl args with a conda env with a name', async () => { From fe0718bcef55a1dcaa65c8b0ee38b698cab155b8 Mon Sep 17 00:00:00 2001 From: Rich Chiodo Date: Wed, 8 Jan 2020 10:49:21 -0800 Subject: [PATCH 5/5] Fix helper tests --- .../terminals/codeExecution/helper.test.ts | 46 +++++++++++++------ 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/src/test/terminals/codeExecution/helper.test.ts b/src/test/terminals/codeExecution/helper.test.ts index 8df26f02b2ca..767133aaa9d8 100644 --- a/src/test/terminals/codeExecution/helper.test.ts +++ b/src/test/terminals/codeExecution/helper.test.ts @@ -7,6 +7,7 @@ import { expect } from 'chai'; import * as fs from 'fs-extra'; import { EOL } from 'os'; import * as path from 'path'; +import { SemVer } from 'semver'; import * as TypeMoq from 'typemoq'; import { Range, Selection, TextDocument, TextEditor, TextLine, Uri } from 'vscode'; import { IApplicationShell, IDocumentManager } from '../../../client/common/application/types'; @@ -14,9 +15,10 @@ import { EXTENSION_ROOT_DIR, PYTHON_LANGUAGE } from '../../../client/common/cons import '../../../client/common/extensions'; import { BufferDecoder } from '../../../client/common/process/decoder'; import { ProcessService } from '../../../client/common/process/proc'; -import { IPythonExecutionFactory, IPythonExecutionService } from '../../../client/common/process/types'; -import { OSType } from '../../../client/common/utils/platform'; +import { IProcessService, IProcessServiceFactory } from '../../../client/common/process/types'; +import { Architecture, OSType } from '../../../client/common/utils/platform'; import { IEnvironmentVariablesProvider } from '../../../client/common/variables/types'; +import { IInterpreterService, InterpreterType, PythonInterpreter } from '../../../client/interpreter/contracts'; import { IServiceContainer } from '../../../client/ioc/types'; import { CodeExecutionHelper } from '../../../client/terminals/codeExecution/helper'; import { ICodeExecutionHelper } from '../../../client/terminals/types'; @@ -31,19 +33,33 @@ suite('Terminal - Code Execution Helper', () => { let helper: ICodeExecutionHelper; let document: TypeMoq.IMock; let editor: TypeMoq.IMock; - let pythonService: TypeMoq.IMock; + let processService: TypeMoq.IMock; + let interpreterService: TypeMoq.IMock; + const workingPython: PythonInterpreter = { + path: PYTHON_PATH, + version: new SemVer('3.6.6-final'), + sysVersion: '1.0.0.0', + sysPrefix: 'Python', + displayName: 'Python', + type: InterpreterType.Unknown, + architecture: Architecture.x64 + }; + setup(() => { const serviceContainer = TypeMoq.Mock.ofType(); documentManager = TypeMoq.Mock.ofType(); applicationShell = TypeMoq.Mock.ofType(); const envVariablesProvider = TypeMoq.Mock.ofType(); - pythonService = TypeMoq.Mock.ofType(); + processService = TypeMoq.Mock.ofType(); + interpreterService = TypeMoq.Mock.ofType(); // tslint:disable-next-line:no-any - pythonService.setup((x: any) => x.then).returns(() => undefined); + processService.setup((x: any) => x.then).returns(() => undefined); + interpreterService.setup(i => i.getActiveInterpreter(TypeMoq.It.isAny())).returns(() => Promise.resolve(workingPython)); + const processServiceFactory = TypeMoq.Mock.ofType(); + processServiceFactory.setup(p => p.create(TypeMoq.It.isAny())).returns(() => Promise.resolve(processService.object)); envVariablesProvider.setup(e => e.getEnvironmentVariables(TypeMoq.It.isAny())).returns(() => Promise.resolve({})); - const pythonExecFactory = TypeMoq.Mock.ofType(); - pythonExecFactory.setup(p => p.create(TypeMoq.It.isAny())).returns(() => Promise.resolve(pythonService.object)); - serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IPythonExecutionFactory), TypeMoq.It.isAny())).returns(() => pythonExecFactory.object); + serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IProcessServiceFactory), TypeMoq.It.isAny())).returns(() => processServiceFactory.object); + serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IInterpreterService), TypeMoq.It.isAny())).returns(() => interpreterService.object); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IDocumentManager), TypeMoq.It.isAny())).returns(() => documentManager.object); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IApplicationShell), TypeMoq.It.isAny())).returns(() => applicationShell.object); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IEnvironmentVariablesProvider), TypeMoq.It.isAny())).returns(() => envVariablesProvider.object); @@ -56,10 +72,10 @@ suite('Terminal - Code Execution Helper', () => { async function ensureBlankLinesAreRemoved(source: string, expectedSource: string) { const actualProcessService = new ProcessService(new BufferDecoder()); - pythonService - .setup(p => p.exec(TypeMoq.It.isAny(), TypeMoq.It.isAny())) - .returns((args, options) => { - return actualProcessService.exec.apply(actualProcessService, [PYTHON_PATH, args, options]); + processService + .setup(p => p.exec(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())) + .returns((file, args, options) => { + return actualProcessService.exec.apply(actualProcessService, [file, args, options]); }); const normalizedZCode = await helper.normalizeLines(source); // In case file has been saved with different line endings. @@ -81,9 +97,9 @@ suite('Terminal - Code Execution Helper', () => { test('Ensure there are no multiple-CR elements in the normalized code.', async () => { const code = ['import sys', '', '', '', 'print(sys.executable)', '', 'print("1234")', '', '', 'print(1)', 'print(2)']; const actualProcessService = new ProcessService(new BufferDecoder()); - pythonService - .setup(p => p.exec(TypeMoq.It.isAny(), TypeMoq.It.isAny())) - .returns((args, options) => { + processService + .setup(p => p.exec(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())) + .returns((_file, args, options) => { return actualProcessService.exec.apply(actualProcessService, [PYTHON_PATH, args, options]); }); const normalizedCode = await helper.normalizeLines(code.join(EOL));