diff --git a/news/3 Code Health/1339.md b/news/3 Code Health/1339.md new file mode 100644 index 000000000000..e06d19240f67 --- /dev/null +++ b/news/3 Code Health/1339.md @@ -0,0 +1 @@ +Ensure custom environment variables are always used when spawning any process from within the extension. diff --git a/src/client/activation/analysis.ts b/src/client/activation/analysis.ts index d2e853dc7dda..239dbef44edb 100644 --- a/src/client/activation/analysis.ts +++ b/src/client/activation/analysis.ts @@ -9,7 +9,7 @@ import { IApplicationShell } from '../common/application/types'; import { isTestExecution, STANDARD_OUTPUT_CHANNEL } from '../common/constants'; import { createDeferred, Deferred } from '../common/helpers'; import { IFileSystem, IPlatformService } from '../common/platform/types'; -import { IProcessService } from '../common/process/types'; +import { IProcessServiceFactory } from '../common/process/types'; import { StopWatch } from '../common/stopWatch'; import { IConfigurationService, IOutputChannel, IPythonSettings } from '../common/types'; import { IEnvironmentVariablesProvider } from '../common/variables/types'; @@ -227,7 +227,7 @@ export class AnalysisExtensionActivator implements IExtensionActivator { } private async isDotNetInstalled(): Promise { - const ps = this.services.get(IProcessService); + const ps = await this.services.get(IProcessServiceFactory).create(); const result = await ps.exec('dotnet', ['--version']).catch(() => { return { stdout: '' }; }); return result.stdout.trim().startsWith('2.'); } diff --git a/src/client/common/configSettings.ts b/src/client/common/configSettings.ts index dd39cb4f5dbe..85a6ac61bc14 100644 --- a/src/client/common/configSettings.ts +++ b/src/client/common/configSettings.ts @@ -34,10 +34,10 @@ export class PythonSettings extends EventEmitter implements IPythonSettings { public devOptions: string[] = []; public linting!: ILintingSettings; public formatting!: IFormattingSettings; - public autoComplete?: IAutoCompleteSettings; + public autoComplete!: IAutoCompleteSettings; public unitTest!: IUnitTestSettings; public terminal!: ITerminalSettings; - public sortImports?: ISortImportSettings; + public sortImports!: ISortImportSettings; public workspaceSymbols!: IWorkspaceSymbolSettings; public disableInstallationChecks = false; public globalModuleInstallation = false; diff --git a/src/client/common/installer/productInstaller.ts b/src/client/common/installer/productInstaller.ts index a0929e86de66..d214653c6f43 100644 --- a/src/client/common/installer/productInstaller.ts +++ b/src/client/common/installer/productInstaller.ts @@ -9,7 +9,7 @@ import { ITestsHelper } from '../../unittests/common/types'; import { IApplicationShell } from '../application/types'; import { STANDARD_OUTPUT_CHANNEL } from '../constants'; import { IPlatformService } from '../platform/types'; -import { IProcessService, IPythonExecutionFactory } from '../process/types'; +import { IProcessServiceFactory, IPythonExecutionFactory } from '../process/types'; import { ITerminalServiceFactory } from '../terminal/types'; import { IConfigurationService, IInstaller, ILogger, InstallerResponse, IOutputChannel, ModuleNamePurpose, Product } from '../types'; import { ProductNames } from './productNames'; @@ -77,7 +77,7 @@ abstract class BaseInstaller { const pythonProcess = await this.serviceContainer.get(IPythonExecutionFactory).create(resource); return pythonProcess.isModuleInstalled(executableName); } else { - const process = this.serviceContainer.get(IProcessService); + const process = await this.serviceContainer.get(IProcessServiceFactory).create(resource); return process.exec(executableName, ['--version'], { mergeStdOutErr: true }) .then(() => true) .catch(() => false); diff --git a/src/client/common/process/proc.ts b/src/client/common/process/proc.ts index 426519f2ba68..ed511447db1f 100644 --- a/src/client/common/process/proc.ts +++ b/src/client/common/process/proc.ts @@ -4,22 +4,22 @@ // tslint:disable:no-any import { spawn } from 'child_process'; -import { inject, injectable } from 'inversify'; import { Observable } from 'rxjs/Observable'; import { Disposable } from 'vscode'; import { createDeferred } from '../helpers'; +import { EnvironmentVariables } from '../variables/types'; import { DEFAULT_ENCODING } from './constants'; import { ExecutionResult, IBufferDecoder, IProcessService, ObservableExecutionResult, Output, SpawnOptions, StdErrError } from './types'; -@injectable() export class ProcessService implements IProcessService { - constructor(@inject(IBufferDecoder) private decoder: IBufferDecoder) { } + constructor(private readonly decoder: IBufferDecoder, private readonly env?: EnvironmentVariables) { } public execObservable(file: string, args: string[], options: SpawnOptions = {}): ObservableExecutionResult { const encoding = options.encoding = typeof options.encoding === 'string' && options.encoding.length > 0 ? options.encoding : DEFAULT_ENCODING; delete options.encoding; const spawnOptions = { ...options }; if (!spawnOptions.env || Object.keys(spawnOptions).length === 0) { - spawnOptions.env = { ...process.env }; + const env = this.env ? this.env : process.env; + spawnOptions.env = { ...env }; } // Always ensure we have unbuffered output. @@ -79,7 +79,8 @@ export class ProcessService implements IProcessService { delete options.encoding; const spawnOptions = { ...options }; if (!spawnOptions.env || Object.keys(spawnOptions).length === 0) { - spawnOptions.env = { ...process.env }; + const env = this.env ? this.env : process.env; + spawnOptions.env = { ...env }; } // Always ensure we have unbuffered output. diff --git a/src/client/common/process/processFactory.ts b/src/client/common/process/processFactory.ts new file mode 100644 index 000000000000..91440cf9bddd --- /dev/null +++ b/src/client/common/process/processFactory.ts @@ -0,0 +1,24 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +'use strict'; + +import { inject, injectable } from 'inversify'; +import { Uri } from 'vscode'; +import { IServiceContainer } from '../../ioc/types'; +import { IEnvironmentVariablesProvider } from '../variables/types'; +import { ProcessService } from './proc'; +import { IBufferDecoder, IProcessService, IProcessServiceFactory } from './types'; + +@injectable() +export class ProcessServiceFactory implements IProcessServiceFactory { + private envVarsService: IEnvironmentVariablesProvider; + constructor(@inject(IServiceContainer) private serviceContainer: IServiceContainer) { + this.envVarsService = serviceContainer.get(IEnvironmentVariablesProvider); + } + public async create(resource?: Uri): Promise { + const customEnvVars = await this.envVarsService.getEnvironmentVariables(resource); + const decoder = this.serviceContainer.get(IBufferDecoder); + return new ProcessService(decoder, customEnvVars); + } +} diff --git a/src/client/common/process/pythonExecutionFactory.ts b/src/client/common/process/pythonExecutionFactory.ts index 4866e6e504f8..ceafb3aa827b 100644 --- a/src/client/common/process/pythonExecutionFactory.ts +++ b/src/client/common/process/pythonExecutionFactory.ts @@ -4,20 +4,17 @@ import { inject, injectable } from 'inversify'; import { Uri } from 'vscode'; import { IServiceContainer } from '../../ioc/types'; -import { IEnvironmentVariablesProvider } from '../variables/types'; import { PythonExecutionService } from './pythonProcess'; -import { IPythonExecutionFactory, IPythonExecutionService } from './types'; +import { IProcessServiceFactory, IPythonExecutionFactory, IPythonExecutionService } from './types'; @injectable() export class PythonExecutionFactory implements IPythonExecutionFactory { - private envVarsService: IEnvironmentVariablesProvider; + private processServiceFactory: IProcessServiceFactory; constructor(@inject(IServiceContainer) private serviceContainer: IServiceContainer) { - this.envVarsService = serviceContainer.get(IEnvironmentVariablesProvider); + this.processServiceFactory = serviceContainer.get(IProcessServiceFactory); } public async create(resource?: Uri): Promise { - return this.envVarsService.getEnvironmentVariables(resource) - .then(customEnvVars => { - return new PythonExecutionService(this.serviceContainer, customEnvVars, resource); - }); + const processService = await this.processServiceFactory.create(resource); + return new PythonExecutionService(this.serviceContainer, processService, resource); } } diff --git a/src/client/common/process/pythonProcess.ts b/src/client/common/process/pythonProcess.ts index 0d6622bed472..419b5d88dcba 100644 --- a/src/client/common/process/pythonProcess.ts +++ b/src/client/common/process/pythonProcess.ts @@ -9,17 +9,14 @@ import { ErrorUtils } from '../errors/errorUtils'; import { ModuleNotInstalledError } from '../errors/moduleNotInstalledError'; import { IFileSystem } from '../platform/types'; import { IConfigurationService } from '../types'; -import { EnvironmentVariables } from '../variables/types'; import { ExecutionResult, IProcessService, IPythonExecutionService, ObservableExecutionResult, SpawnOptions } from './types'; @injectable() export class PythonExecutionService implements IPythonExecutionService { - private readonly procService: IProcessService; private readonly configService: IConfigurationService; private readonly fileSystem: IFileSystem; - constructor(private serviceContainer: IServiceContainer, private envVars: EnvironmentVariables | undefined, private resource?: Uri) { - this.procService = serviceContainer.get(IProcessService); + constructor(private serviceContainer: IServiceContainer, private readonly procService: IProcessService, private resource?: Uri) { this.configService = serviceContainer.get(IConfigurationService); this.fileSystem = serviceContainer.get(IFileSystem); } @@ -34,40 +31,28 @@ export class PythonExecutionService implements IPythonExecutionService { if (await this.fileSystem.fileExistsAsync(this.pythonPath)) { return this.pythonPath; } - return this.procService.exec(this.pythonPath, ['-c', 'import sys;print(sys.executable)'], { env: this.envVars, throwOnStdErr: true }) + return this.procService.exec(this.pythonPath, ['-c', 'import sys;print(sys.executable)'], { throwOnStdErr: true }) .then(output => output.stdout.trim()); } public async isModuleInstalled(moduleName: string): Promise { - return this.procService.exec(this.pythonPath, ['-c', `import ${moduleName}`], { env: this.envVars, throwOnStdErr: true }) + return this.procService.exec(this.pythonPath, ['-c', `import ${moduleName}`], { throwOnStdErr: true }) .then(() => true).catch(() => false); } public execObservable(args: string[], options: SpawnOptions): ObservableExecutionResult { const opts: SpawnOptions = { ...options }; - if (this.envVars) { - opts.env = this.envVars; - } return this.procService.execObservable(this.pythonPath, args, opts); } public execModuleObservable(moduleName: string, args: string[], options: SpawnOptions): ObservableExecutionResult { const opts: SpawnOptions = { ...options }; - if (this.envVars) { - opts.env = this.envVars; - } return this.procService.execObservable(this.pythonPath, ['-m', moduleName, ...args], opts); } public async exec(args: string[], options: SpawnOptions): Promise> { const opts: SpawnOptions = { ...options }; - if (this.envVars) { - opts.env = this.envVars; - } return this.procService.exec(this.pythonPath, args, opts); } public async execModule(moduleName: string, args: string[], options: SpawnOptions): Promise> { const opts: SpawnOptions = { ...options }; - if (this.envVars) { - opts.env = this.envVars; - } const result = await this.procService.exec(this.pythonPath, ['-m', moduleName, ...args], opts); // If a module is not installed we'll have something in stderr. diff --git a/src/client/common/process/pythonToolService.ts b/src/client/common/process/pythonToolService.ts index 9419b005250b..3369c35ac6b6 100644 --- a/src/client/common/process/pythonToolService.ts +++ b/src/client/common/process/pythonToolService.ts @@ -5,12 +5,11 @@ import { inject, injectable } from 'inversify'; import { Uri } from 'vscode'; import { IServiceContainer } from '../../ioc/types'; import { ExecutionInfo } from '../types'; -import { IEnvironmentVariablesProvider } from '../variables/types'; -import { ExecutionResult, IProcessService, IPythonExecutionFactory, IPythonToolExecutionService, ObservableExecutionResult, SpawnOptions } from './types'; +import { ExecutionResult, IProcessServiceFactory, IPythonExecutionFactory, IPythonToolExecutionService, ObservableExecutionResult, SpawnOptions } from './types'; @injectable() export class PythonToolExecutionService implements IPythonToolExecutionService { - constructor( @inject(IServiceContainer) private serviceContainer: IServiceContainer) { } + constructor(@inject(IServiceContainer) private serviceContainer: IServiceContainer) { } public async execObservable(executionInfo: ExecutionInfo, options: SpawnOptions, resource: Uri): Promise> { if (options.env) { throw new Error('Environment variables are not supported'); @@ -19,9 +18,8 @@ export class PythonToolExecutionService implements IPythonToolExecutionService { const pythonExecutionService = await this.serviceContainer.get(IPythonExecutionFactory).create(resource); return pythonExecutionService.execModuleObservable(executionInfo.moduleName, executionInfo.args, options); } else { - const env = await this.serviceContainer.get(IEnvironmentVariablesProvider).getEnvironmentVariables(resource); - const processService = this.serviceContainer.get(IProcessService); - return processService.execObservable(executionInfo.execPath!, executionInfo.args, { ...options, env }); + const processService = await this.serviceContainer.get(IProcessServiceFactory).create(resource); + return processService.execObservable(executionInfo.execPath!, executionInfo.args, { ...options }); } } public async exec(executionInfo: ExecutionInfo, options: SpawnOptions, resource: Uri): Promise> { @@ -32,9 +30,8 @@ export class PythonToolExecutionService implements IPythonToolExecutionService { const pythonExecutionService = await this.serviceContainer.get(IPythonExecutionFactory).create(resource); return pythonExecutionService.execModule(executionInfo.moduleName!, executionInfo.args, options); } else { - const env = await this.serviceContainer.get(IEnvironmentVariablesProvider).getEnvironmentVariables(resource); - const processService = this.serviceContainer.get(IProcessService); - return processService.exec(executionInfo.execPath!, executionInfo.args, { ...options, env }); + const processService = await this.serviceContainer.get(IProcessServiceFactory).create(resource); + return processService.exec(executionInfo.execPath!, executionInfo.args, { ...options }); } } } diff --git a/src/client/common/process/serviceRegistry.ts b/src/client/common/process/serviceRegistry.ts index dd4242fec55e..27684a20cc32 100644 --- a/src/client/common/process/serviceRegistry.ts +++ b/src/client/common/process/serviceRegistry.ts @@ -3,14 +3,14 @@ import { IServiceManager } from '../../ioc/types'; import { BufferDecoder } from './decoder'; -import { ProcessService } from './proc'; +import { ProcessServiceFactory } from './processFactory'; import { PythonExecutionFactory } from './pythonExecutionFactory'; import { PythonToolExecutionService } from './pythonToolService'; -import { IBufferDecoder, IProcessService, IPythonExecutionFactory, IPythonToolExecutionService } from './types'; +import { IBufferDecoder, IProcessServiceFactory, IPythonExecutionFactory, IPythonToolExecutionService } from './types'; export function registerTypes(serviceManager: IServiceManager) { serviceManager.addSingleton(IBufferDecoder, BufferDecoder); - serviceManager.addSingleton(IProcessService, ProcessService); + serviceManager.addSingleton(IProcessServiceFactory, ProcessServiceFactory); serviceManager.addSingleton(IPythonExecutionFactory, PythonExecutionFactory); serviceManager.addSingleton(IPythonToolExecutionService, PythonToolExecutionService); } diff --git a/src/client/common/process/types.ts b/src/client/common/process/types.ts index c4a79d6435a6..22fb6965be55 100644 --- a/src/client/common/process/types.ts +++ b/src/client/common/process/types.ts @@ -34,13 +34,17 @@ export type ExecutionResult = { stderr?: T; }; -export const IProcessService = Symbol('IProcessService'); - export interface IProcessService { execObservable(file: string, args: string[], options?: SpawnOptions): ObservableExecutionResult; exec(file: string, args: string[], options?: SpawnOptions): Promise>; } +export const IProcessServiceFactory = Symbol('IProcessServiceFactory'); + +export interface IProcessServiceFactory { + create(resource?: Uri): Promise; +} + export const IPythonExecutionFactory = Symbol('IPythonExecutionFactory'); export interface IPythonExecutionFactory { diff --git a/src/client/common/types.ts b/src/client/common/types.ts index 697fd461a24c..027437f169cc 100644 --- a/src/client/common/types.ts +++ b/src/client/common/types.ts @@ -106,9 +106,9 @@ export interface IPythonSettings { readonly linting: ILintingSettings; readonly formatting: IFormattingSettings; readonly unitTest: IUnitTestSettings; - readonly autoComplete?: IAutoCompleteSettings; + readonly autoComplete: IAutoCompleteSettings; readonly terminal: ITerminalSettings; - readonly sortImports?: ISortImportSettings; + readonly sortImports: ISortImportSettings; readonly workspaceSymbols: IWorkspaceSymbolSettings; readonly envFile: string; readonly disableInstallationChecks: boolean; diff --git a/src/client/common/variables/environmentVariablesProvider.ts b/src/client/common/variables/environmentVariablesProvider.ts index f1e2ca6541bf..a10bb94c0a65 100644 --- a/src/client/common/variables/environmentVariablesProvider.ts +++ b/src/client/common/variables/environmentVariablesProvider.ts @@ -14,7 +14,7 @@ export class EnvironmentVariablesProvider implements IEnvironmentVariablesProvid private fileWatchers = new Map(); private disposables: Disposable[] = []; private changeEventEmitter: EventEmitter; - constructor( @inject(IEnvironmentVariablesService) private envVarsService: IEnvironmentVariablesService, + constructor(@inject(IEnvironmentVariablesService) private envVarsService: IEnvironmentVariablesService, @inject(IDisposableRegistry) disposableRegistry: Disposable[], @inject(IsWindows) private isWidows: boolean, @inject(ICurrentProcess) private process: ICurrentProcess) { disposableRegistry.push(this); diff --git a/src/client/interpreter/display/shebangCodeLensProvider.ts b/src/client/interpreter/display/shebangCodeLensProvider.ts index 8bb2595e752b..457e914200a8 100644 --- a/src/client/interpreter/display/shebangCodeLensProvider.ts +++ b/src/client/interpreter/display/shebangCodeLensProvider.ts @@ -1,8 +1,7 @@ import { inject, injectable } from 'inversify'; -import * as vscode from 'vscode'; -import { CancellationToken, CodeLens, TextDocument } from 'vscode'; +import { CancellationToken, CodeLens, Command, Event, Position, Range, TextDocument, Uri, workspace } from 'vscode'; import * as settings from '../../common/configSettings'; -import { IProcessService } from '../../common/process/types'; +import { IProcessServiceFactory } from '../../common/process/types'; import { IS_WINDOWS } from '../../common/utils'; import { IServiceContainer } from '../../ioc/types'; import { IShebangCodeLensProvider } from '../contracts'; @@ -10,10 +9,10 @@ import { IShebangCodeLensProvider } from '../contracts'; @injectable() export class ShebangCodeLensProvider implements IShebangCodeLensProvider { // tslint:disable-next-line:no-any - public onDidChangeCodeLenses: vscode.Event = vscode.workspace.onDidChangeConfiguration as any as vscode.Event; - private readonly processService: IProcessService; + public onDidChangeCodeLenses: Event = workspace.onDidChangeConfiguration as any as Event; + private readonly processServiceFactory: IProcessServiceFactory; constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) { - this.processService = serviceContainer.get(IProcessService); + this.processServiceFactory = serviceContainer.get(IProcessServiceFactory); } public async detectShebang(document: TextDocument): Promise { const firstLine = document.lineAt(0); @@ -26,14 +25,14 @@ export class ShebangCodeLensProvider implements IShebangCodeLensProvider { } const shebang = firstLine.text.substr(2).trim(); - const pythonPath = await this.getFullyQualifiedPathToInterpreter(shebang); + const pythonPath = await this.getFullyQualifiedPathToInterpreter(shebang, document.uri); return typeof pythonPath === 'string' && pythonPath.length > 0 ? pythonPath : undefined; } public async provideCodeLenses(document: TextDocument, token: CancellationToken): Promise { const codeLenses = await this.createShebangCodeLens(document); return Promise.resolve(codeLenses); } - private async getFullyQualifiedPathToInterpreter(pythonPath: string) { + private async getFullyQualifiedPathToInterpreter(pythonPath: string, resource: Uri) { let cmdFile = pythonPath; let args = ['-c', 'import sys;print(sys.executable)']; if (pythonPath.indexOf('bin/env ') >= 0 && !IS_WINDOWS) { @@ -42,24 +41,25 @@ export class ShebangCodeLensProvider implements IShebangCodeLensProvider { cmdFile = parts.shift()!; args = parts.concat(args); } - return this.processService.exec(cmdFile, args) + const processService = await this.processServiceFactory.create(resource); + return processService.exec(cmdFile, args) .then(output => output.stdout.trim()) .catch(() => ''); } private async createShebangCodeLens(document: TextDocument) { const shebang = await this.detectShebang(document); const pythonPath = settings.PythonSettings.getInstance(document.uri).pythonPath; - const resolvedPythonPath = await this.getFullyQualifiedPathToInterpreter(pythonPath); + const resolvedPythonPath = await this.getFullyQualifiedPathToInterpreter(pythonPath, document.uri); if (!shebang || shebang === resolvedPythonPath) { return []; } const firstLine = document.lineAt(0); - const startOfShebang = new vscode.Position(0, 0); - const endOfShebang = new vscode.Position(0, firstLine.text.length - 1); - const shebangRange = new vscode.Range(startOfShebang, endOfShebang); + const startOfShebang = new Position(0, 0); + const endOfShebang = new Position(0, firstLine.text.length - 1); + const shebangRange = new Range(startOfShebang, endOfShebang); - const cmd: vscode.Command = { + const cmd: Command = { command: 'python.setShebangInterpreter', title: 'Set as interpreter' }; diff --git a/src/client/interpreter/interpreterVersion.ts b/src/client/interpreter/interpreterVersion.ts index 5235d60f52ce..4b00ddadead2 100644 --- a/src/client/interpreter/interpreterVersion.ts +++ b/src/client/interpreter/interpreterVersion.ts @@ -1,21 +1,23 @@ import { inject, injectable } from 'inversify'; import '../common/extensions'; -import { IProcessService } from '../common/process/types'; +import { IProcessServiceFactory } from '../common/process/types'; import { IInterpreterVersionService } from './contracts'; export const PIP_VERSION_REGEX = '\\d+\\.\\d+(\\.\\d+)'; @injectable() export class InterpreterVersionService implements IInterpreterVersionService { - constructor(@inject(IProcessService) private processService: IProcessService) { } + constructor(@inject(IProcessServiceFactory) private readonly processServiceFactory: IProcessServiceFactory) { } public async getVersion(pythonPath: string, defaultValue: string): Promise { - return this.processService.exec(pythonPath, ['--version'], { mergeStdOutErr: true }) + const processService = await this.processServiceFactory.create(); + return processService.exec(pythonPath, ['--version'], { mergeStdOutErr: true }) .then(output => output.stdout.splitLines()[0]) .then(version => version.length === 0 ? defaultValue : version) .catch(() => defaultValue); } public async getPipVersion(pythonPath: string): Promise { - const output = await this.processService.exec(pythonPath, ['-m', 'pip', '--version'], { mergeStdOutErr: true }); + const processService = await this.processServiceFactory.create(); + const output = await processService.exec(pythonPath, ['-m', 'pip', '--version'], { mergeStdOutErr: true }); if (output.stdout.length > 0) { // Here's a sample output: // pip 9.0.1 from /Users/donjayamanne/anaconda3/lib/python3.6/site-packages (python 3.6). diff --git a/src/client/interpreter/locators/services/condaService.ts b/src/client/interpreter/locators/services/condaService.ts index f73cb277fd35..2e990c30fcbe 100644 --- a/src/client/interpreter/locators/services/condaService.ts +++ b/src/client/interpreter/locators/services/condaService.ts @@ -1,7 +1,7 @@ import { inject, injectable, named, optional } from 'inversify'; import * as path from 'path'; import { IFileSystem, IPlatformService } from '../../../common/platform/types'; -import { IProcessService } from '../../../common/process/types'; +import { IProcessServiceFactory } from '../../../common/process/types'; import { ILogger, IPersistentStateFactory } from '../../../common/types'; import { VersionUtils } from '../../../common/versionUtils'; import { IServiceContainer } from '../../../ioc/types'; @@ -17,9 +17,9 @@ export const KNOWN_CONDA_LOCATIONS = ['~/anaconda/bin/conda', '~/miniconda/bin/c @injectable() export class CondaService implements ICondaService { - private condaFile: Promise; + private condaFile!: Promise; private isAvailable: boolean | undefined; - private readonly processService: IProcessService; + private readonly processServiceFactory: IProcessServiceFactory; private readonly platform: IPlatformService; private readonly logger: ILogger; private readonly fileSystem: IFileSystem; @@ -30,7 +30,7 @@ export class CondaService implements ICondaService { } constructor(@inject(IServiceContainer) private serviceContainer: IServiceContainer, @inject(IInterpreterLocatorService) @named(WINDOWS_REGISTRY_SERVICE) @optional() private registryLookupForConda?: IInterpreterLocatorService) { - this.processService = this.serviceContainer.get(IProcessService); + this.processServiceFactory = this.serviceContainer.get(IProcessServiceFactory); this.platform = this.serviceContainer.get(IPlatformService); this.logger = this.serviceContainer.get(ILogger); this.fileSystem = this.serviceContainer.get(IFileSystem); @@ -54,20 +54,23 @@ export class CondaService implements ICondaService { .catch(() => this.isAvailable = false); } public async getCondaVersion(): Promise { + const processService = await this.processServiceFactory.create(); return this.getCondaFile() - .then(condaFile => this.processService.exec(condaFile, ['--version'], {})) + .then(condaFile => processService.exec(condaFile, ['--version'], {})) .then(result => result.stdout.trim()) .catch(() => undefined); } public async isCondaInCurrentPath() { - return this.processService.exec('conda', ['--version']) + const processService = await this.processServiceFactory.create(); + return processService.exec('conda', ['--version']) .then(output => output.stdout.length > 0) .catch(() => false); } public async getCondaInfo(): Promise { try { const condaFile = await this.getCondaFile(); - const condaInfo = await this.processService.exec(condaFile, ['info', '--json']).then(output => output.stdout); + const processService = await this.processServiceFactory.create(); + const condaInfo = await processService.exec(condaFile, ['info', '--json']).then(output => output.stdout); return JSON.parse(condaInfo) as CondaInfo; } catch (ex) { @@ -90,7 +93,7 @@ export class CondaService implements ICondaService { const condaMetaDirectory = isWindows ? path.join(dir, 'conda-meta') : path.join(dir, '..', 'conda-meta'); return fs.directoryExistsAsync(condaMetaDirectory); } - public async getCondaEnvironment(interpreterPath: string): Promise<{ name: string, path: string } | undefined> { + public async getCondaEnvironment(interpreterPath: string): Promise<{ name: string; path: string } | undefined> { const isCondaEnv = await this.isCondaEnvironment(interpreterPath); if (!isCondaEnv) { return; @@ -118,18 +121,19 @@ export class CondaService implements ICondaService { // If still not available, then the user created the env after starting vs code. // The only solution is to get the user to re-start vscode. } - public async getCondaEnvironments(ignoreCache: boolean): Promise<({ name: string, path: string }[]) | undefined> { + public async getCondaEnvironments(ignoreCache: boolean): Promise<({ name: string; path: string }[]) | undefined> { // Global cache. const persistentFactory = this.serviceContainer.get(IPersistentStateFactory); // tslint:disable-next-line:no-any - const globalPersistence = persistentFactory.createGlobalPersistentState<{ data: { name: string, path: string }[] | undefined }>('CONDA_ENVIRONMENTS', undefined as any); + const globalPersistence = persistentFactory.createGlobalPersistentState<{ data: { name: string; path: string }[] | undefined }>('CONDA_ENVIRONMENTS', undefined as any); if (!ignoreCache && globalPersistence.value) { return globalPersistence.value.data; } try { const condaFile = await this.getCondaFile(); - const envInfo = await this.processService.exec(condaFile, ['env', 'list']).then(output => output.stdout); + const processService = await this.processServiceFactory.create(); + const envInfo = await processService.exec(condaFile, ['env', 'list']).then(output => output.stdout); const environments = this.condaHelper.parseCondaEnvironmentNames(envInfo); await globalPersistence.updateValue({ data: environments }); return environments; diff --git a/src/client/interpreter/locators/services/currentPathService.ts b/src/client/interpreter/locators/services/currentPathService.ts index 48444e0dfba9..cf2f5dc8d321 100644 --- a/src/client/interpreter/locators/services/currentPathService.ts +++ b/src/client/interpreter/locators/services/currentPathService.ts @@ -3,7 +3,7 @@ import * as _ from 'lodash'; import * as path from 'path'; import { Uri } from 'vscode'; import { IFileSystem } from '../../../common/platform/types'; -import { IProcessService } from '../../../common/process/types'; +import { IProcessServiceFactory } from '../../../common/process/types'; import { IConfigurationService } from '../../../common/types'; import { IServiceContainer } from '../../../ioc/types'; import { IInterpreterVersionService, InterpreterType, PythonInterpreter } from '../../contracts'; @@ -15,7 +15,7 @@ export class CurrentPathService extends CacheableLocatorService { private readonly fs: IFileSystem; public constructor(@inject(IVirtualEnvironmentManager) private virtualEnvMgr: IVirtualEnvironmentManager, @inject(IInterpreterVersionService) private versionProvider: IInterpreterVersionService, - @inject(IProcessService) private processService: IProcessService, + @inject(IProcessServiceFactory) private readonly processServiceFactory: IProcessServiceFactory, @inject(IServiceContainer) serviceContainer: IServiceContainer) { super('CurrentPathService', serviceContainer); this.fs = serviceContainer.get(IFileSystem); @@ -54,12 +54,16 @@ export class CurrentPathService extends CacheableLocatorService { } private async getInterpreter(pythonPath: string, defaultValue: string) { try { - const output = await this.processService.exec(pythonPath, ['-c', 'import sys;print(sys.executable)'], {}); - const executablePath = output.stdout.trim(); - if (executablePath.length > 0 && await this.fs.fileExistsAsync(executablePath)) { - return executablePath; - } - return defaultValue; + const processService = await this.processServiceFactory.create(); + return processService.exec(pythonPath, ['-c', 'import sys;print(sys.executable)'], {}) + .then(output => output.stdout.trim()) + .then(async value => { + if (value.length > 0 && await this.fs.fileExistsAsync(value)) { + return value; + } + return defaultValue; + }) + .catch(() => defaultValue); // Ignore exceptions in getting the executable. } catch { return defaultValue; // Ignore exceptions in getting the executable. } diff --git a/src/client/interpreter/locators/services/pipEnvService.ts b/src/client/interpreter/locators/services/pipEnvService.ts index c2db5ff46020..10d4d451a44a 100644 --- a/src/client/interpreter/locators/services/pipEnvService.ts +++ b/src/client/interpreter/locators/services/pipEnvService.ts @@ -6,7 +6,7 @@ import * as path from 'path'; import { Uri } from 'vscode'; import { IApplicationShell, IWorkspaceService } from '../../../common/application/types'; import { IFileSystem } from '../../../common/platform/types'; -import { IProcessService } from '../../../common/process/types'; +import { IProcessServiceFactory } from '../../../common/process/types'; import { ICurrentProcess } from '../../../common/types'; import { IEnvironmentVariablesProvider } from '../../../common/variables/types'; import { getPythonExecutable } from '../../../debugger/Common/Utils'; @@ -20,7 +20,7 @@ const pipEnvFileNameVariable = 'PIPENV_PIPFILE'; @injectable() export class PipEnvService extends CacheableLocatorService { private readonly versionService: IInterpreterVersionService; - private readonly process: IProcessService; + private readonly processServiceFactory: IProcessServiceFactory; private readonly workspace: IWorkspaceService; private readonly fs: IFileSystem; private readonly envVarsProvider: IEnvironmentVariablesProvider; @@ -28,7 +28,7 @@ export class PipEnvService extends CacheableLocatorService { constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) { super('PipEnvService', serviceContainer); this.versionService = this.serviceContainer.get(IInterpreterVersionService); - this.process = this.serviceContainer.get(IProcessService); + this.processServiceFactory = this.serviceContainer.get(IProcessServiceFactory); this.workspace = this.serviceContainer.get(IWorkspaceService); this.fs = this.serviceContainer.get(IFileSystem); this.envVarsProvider = this.serviceContainer.get(IEnvironmentVariablesProvider); @@ -94,8 +94,8 @@ export class PipEnvService extends CacheableLocatorService { private async invokePipenv(arg: string, rootPath: string): Promise { try { - const env = await this.envVarsProvider.getEnvironmentVariables(Uri.file(rootPath)); - const result = await this.process.exec(execName, [arg], { cwd: rootPath, env }); + const processService = await this.processServiceFactory.create(Uri.file(rootPath)); + const result = await processService.exec(execName, [arg], { cwd: rootPath }); if (result) { const stdout = result.stdout ? result.stdout.trim() : ''; const stderr = result.stderr ? result.stderr.trim() : ''; diff --git a/src/client/interpreter/virtualEnvs/index.ts b/src/client/interpreter/virtualEnvs/index.ts index 4f535cb99151..bf05b6a3b917 100644 --- a/src/client/interpreter/virtualEnvs/index.ts +++ b/src/client/interpreter/virtualEnvs/index.ts @@ -2,22 +2,23 @@ // Licensed under the MIT License. import { inject, injectable } from 'inversify'; -import { IProcessService } from '../../common/process/types'; +import { IProcessServiceFactory } from '../../common/process/types'; import { IServiceContainer } from '../../ioc/types'; import { IVirtualEnvironmentManager } from './types'; @injectable() export class VirtualEnvironmentManager implements IVirtualEnvironmentManager { - private processService: IProcessService; + private processServiceFactory: IProcessServiceFactory; constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) { - this.processService = serviceContainer.get(IProcessService); + this.processServiceFactory = serviceContainer.get(IProcessServiceFactory); } public async getEnvironmentName(pythonPath: string): Promise { // https://stackoverflow.com/questions/1871549/determine-if-python-is-running-inside-virtualenv // hasattr(sys, 'real_prefix') works for virtualenv while // '(hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix))' works for venv const code = 'import sys\nif hasattr(sys, "real_prefix"):\n print("virtualenv")\nelif hasattr(sys, "base_prefix") and sys.base_prefix != sys.prefix:\n print("venv")'; - const output = await this.processService.exec(pythonPath, ['-c', code]); + const processService = await this.processServiceFactory.create(); + const output = await processService.exec(pythonPath, ['-c', code]); if (output.stdout.length > 0) { return output.stdout.trim(); } diff --git a/src/client/providers/importSortProvider.ts b/src/client/providers/importSortProvider.ts index e7e6d3347133..74effd123947 100644 --- a/src/client/providers/importSortProvider.ts +++ b/src/client/providers/importSortProvider.ts @@ -3,14 +3,19 @@ import * as path from 'path'; import { TextDocument, TextEdit } from 'vscode'; import { PythonSettings } from '../common/configSettings'; import { getTempFileWithDocumentContents, getTextEditsFromPatch } from '../common/editor'; -import { ExecutionResult, IProcessService, IPythonExecutionFactory } from '../common/process/types'; +import { ExecutionResult, IProcessServiceFactory, IPythonExecutionFactory } from '../common/process/types'; +import { IServiceContainer } from '../ioc/types'; import { captureTelemetry } from '../telemetry'; import { FORMAT_SORT_IMPORTS } from '../telemetry/constants'; // tslint:disable-next-line:completed-docs export class PythonImportSortProvider { - constructor(private pythonExecutionFactory: IPythonExecutionFactory, - private processService: IProcessService) { } + private readonly processServiceFactory: IProcessServiceFactory; + private readonly pythonExecutionFactory: IPythonExecutionFactory; + constructor(serviceContainer: IServiceContainer) { + this.pythonExecutionFactory = serviceContainer.get(IPythonExecutionFactory); + this.processServiceFactory = serviceContainer.get(IProcessServiceFactory); + } @captureTelemetry(FORMAT_SORT_IMPORTS) public async sortImports(extensionDir: string, document: TextDocument): Promise { if (document.lineCount === 1) { @@ -30,7 +35,8 @@ export class PythonImportSortProvider { if (typeof isort === 'string' && isort.length > 0) { // Lets just treat this as a standard tool. - promise = this.processService.exec(isort, args, { throwOnStdErr: true }); + const processService = await this.processServiceFactory.create(document.uri); + promise = processService.exec(isort, args, { throwOnStdErr: true }); } else { promise = this.pythonExecutionFactory.create(document.uri) .then(executionService => executionService.exec([importScript].concat(args), { throwOnStdErr: true })); diff --git a/src/client/refactor/proxy.ts b/src/client/refactor/proxy.ts index 523b4e726084..725f5eb65005 100644 --- a/src/client/refactor/proxy.ts +++ b/src/client/refactor/proxy.ts @@ -2,8 +2,7 @@ import { ChildProcess } from 'child_process'; import * as path from 'path'; -import * as vscode from 'vscode'; -import { Uri } from 'vscode'; +import { Disposable, Position, Range, TextDocument, TextEditorOptions, Uri, window } from 'vscode'; import '../common/extensions'; import { createDeferred, Deferred } from '../common/helpers'; import { IPythonExecutionFactory } from '../common/process/types'; @@ -11,15 +10,15 @@ import { IPythonSettings } from '../common/types'; import { getWindowsLineEndingCount, IS_WINDOWS } from '../common/utils'; import { IServiceContainer } from '../ioc/types'; -export class RefactorProxy extends vscode.Disposable { +export class RefactorProxy extends Disposable { private _process?: ChildProcess; private _extensionDir: string; private _previousOutData: string = ''; private _previousStdErrData: string = ''; private _startedSuccessfully: boolean = false; private _commandResolve?: (value?: any | PromiseLike) => void; - private _commandReject: (reason?: any) => void; - private initialized: Deferred; + private _commandReject!: (reason?: any) => void; + private initialized!: Deferred; constructor(extensionDir: string, private pythonSettings: IPythonSettings, private workspaceRoot: string, private serviceContainer: IServiceContainer) { super(() => { }); @@ -33,7 +32,7 @@ export class RefactorProxy extends vscode.Disposable { } this._process = undefined; } - private getOffsetAt(document: vscode.TextDocument, position: vscode.Position): number { + private getOffsetAt(document: TextDocument, position: Position): number { if (!IS_WINDOWS) { return document.offsetAt(position); } @@ -47,9 +46,9 @@ export class RefactorProxy extends vscode.Disposable { return offset - winEols; } - public rename(document: vscode.TextDocument, name: string, filePath: string, range: vscode.Range, options?: vscode.TextEditorOptions): Promise { + public rename(document: TextDocument, name: string, filePath: string, range: Range, options?: TextEditorOptions): Promise { if (!options) { - options = vscode.window.activeTextEditor!.options; + options = window.activeTextEditor!.options; } const command = { lookup: 'rename', @@ -62,9 +61,9 @@ export class RefactorProxy extends vscode.Disposable { return this.sendCommand(JSON.stringify(command)); } - public extractVariable(document: vscode.TextDocument, name: string, filePath: string, range: vscode.Range, options?: vscode.TextEditorOptions): Promise { + public extractVariable(document: TextDocument, name: string, filePath: string, range: Range, options?: TextEditorOptions): Promise { if (!options) { - options = vscode.window.activeTextEditor!.options; + options = window.activeTextEditor!.options; } const command = { lookup: 'extract_variable', @@ -77,9 +76,9 @@ export class RefactorProxy extends vscode.Disposable { }; return this.sendCommand(JSON.stringify(command)); } - public extractMethod(document: vscode.TextDocument, name: string, filePath: string, range: vscode.Range, options?: vscode.TextEditorOptions): Promise { + public extractMethod(document: TextDocument, name: string, filePath: string, range: Range, options?: TextEditorOptions): Promise { if (!options) { - options = vscode.window.activeTextEditor!.options; + options = window.activeTextEditor!.options; } // Ensure last line is an empty line if (!document.lineAt(document.lineCount - 1).isEmptyOrWhitespace && range.start.line === document.lineCount - 1) { @@ -131,7 +130,7 @@ export class RefactorProxy extends vscode.Disposable { // Possible there was an exception in parsing the data returned // So append the data then parse it let dataStr = this._previousStdErrData = this._previousStdErrData + data + ''; - let errorResponse: { message: string, traceback: string, type: string }[]; + let errorResponse: { message: string; traceback: string; type: string }[]; try { errorResponse = dataStr.split(/\r?\n/g).filter(line => line.length > 0).map(resp => JSON.parse(resp)); this._previousStdErrData = ''; diff --git a/src/client/sortImports.ts b/src/client/sortImports.ts index 53fadc8769a9..b32488ec1ed3 100644 --- a/src/client/sortImports.ts +++ b/src/client/sortImports.ts @@ -1,6 +1,5 @@ import * as os from 'os'; import * as vscode from 'vscode'; -import { IProcessService, IPythonExecutionFactory } from './common/process/types'; import { IServiceContainer } from './ioc/types'; import * as sortProvider from './providers/importSortProvider'; @@ -29,15 +28,14 @@ export function activate(context: vscode.ExtensionContext, outChannel: vscode.Ou }); } return emptyLineAdded.then(() => { - const processService = serviceContainer.get(IProcessService); - const pythonExecutionFactory = serviceContainer.get(IPythonExecutionFactory); - return new sortProvider.PythonImportSortProvider(pythonExecutionFactory, processService).sortImports(rootDir, activeEditor.document); + return new sortProvider.PythonImportSortProvider(serviceContainer).sortImports(rootDir, activeEditor.document); }).then(changes => { if (!changes || changes!.length === 0) { return; } - return new Promise((resolve, reject) => activeEditor.edit(builder => changes.forEach(change => builder.replace(change.range, change.newText))).then(resolve, reject)); + // tslint:disable-next-line:no-any + return new Promise((resolve, reject) => activeEditor.edit(builder => changes.forEach(change => builder.replace(change.range, change.newText))).then(resolve, reject)); }).catch(error => { const message = typeof error === 'string' ? error : (error.message ? error.message : error); outChannel.appendLine(error); diff --git a/src/client/terminals/codeExecution/helper.ts b/src/client/terminals/codeExecution/helper.ts index de31a8b94049..94380e8f247c 100644 --- a/src/client/terminals/codeExecution/helper.ts +++ b/src/client/terminals/codeExecution/helper.ts @@ -7,9 +7,8 @@ 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 { IProcessService } from '../../common/process/types'; +import { IProcessServiceFactory } from '../../common/process/types'; import { IConfigurationService } from '../../common/types'; -import { IEnvironmentVariablesProvider } from '../../common/variables/types'; import { IServiceContainer } from '../../ioc/types'; import { ICodeExecutionHelper } from '../types'; @@ -17,14 +16,12 @@ import { ICodeExecutionHelper } from '../types'; export class CodeExecutionHelper implements ICodeExecutionHelper { private readonly documentManager: IDocumentManager; private readonly applicationShell: IApplicationShell; - private readonly envVariablesProvider: IEnvironmentVariablesProvider; - private readonly processService: IProcessService; + private readonly processServiceFactory: IProcessServiceFactory; private readonly configurationService: IConfigurationService; constructor(@inject(IServiceContainer) serviceContainer: IServiceContainer) { this.documentManager = serviceContainer.get(IDocumentManager); this.applicationShell = serviceContainer.get(IApplicationShell); - this.envVariablesProvider = serviceContainer.get(IEnvironmentVariablesProvider); - this.processService = serviceContainer.get(IProcessService); + this.processServiceFactory = serviceContainer.get(IProcessServiceFactory); this.configurationService = serviceContainer.get(IConfigurationService); } public async normalizeLines(code: string, resource?: Uri): Promise { @@ -32,10 +29,10 @@ export class CodeExecutionHelper implements ICodeExecutionHelper { if (code.trim().length === 0) { return ''; } - const env = await this.envVariablesProvider.getEnvironmentVariables(resource); const pythonPath = this.configurationService.getSettings(resource).pythonPath; const args = [path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'normalizeForInterpreter.py'), code]; - const proc = await this.processService.exec(pythonPath, args, { env, throwOnStdErr: true }); + const processService = await this.processServiceFactory.create(resource); + const proc = await processService.exec(pythonPath, args, { throwOnStdErr: true }); return proc.stdout; } catch (ex) { console.error(ex, 'Python: Failed to normalize code for execution in terminal'); diff --git a/src/client/workspaceSymbols/generator.ts b/src/client/workspaceSymbols/generator.ts index 9d4a6458374b..86ea33be0eef 100644 --- a/src/client/workspaceSymbols/generator.ts +++ b/src/client/workspaceSymbols/generator.ts @@ -1,15 +1,15 @@ import * as fs from 'fs'; import * as path from 'path'; -import * as vscode from 'vscode'; +import { Disposable, OutputChannel, Uri, window } from 'vscode'; import { PythonSettings } from '../common/configSettings'; -import { IProcessService } from '../common/process/types'; +import { IProcessServiceFactory } from '../common/process/types'; import { IPythonSettings } from '../common/types'; import { captureTelemetry } from '../telemetry'; import { WORKSPACE_SYMBOLS_BUILD } from '../telemetry/constants'; -export class Generator implements vscode.Disposable { +export class Generator implements Disposable { private optionsFile: string; - private disposables: vscode.Disposable[]; + private disposables: Disposable[]; private pythonSettings: IPythonSettings; public get tagFilePath(): string { return this.pythonSettings.workspaceSymbols.tagFilePath; @@ -17,8 +17,8 @@ export class Generator implements vscode.Disposable { public get enabled(): boolean { return this.pythonSettings.workspaceSymbols.enabled; } - constructor(public readonly workspaceFolder: vscode.Uri, private output: vscode.OutputChannel, - private processService: IProcessService) { + constructor(public readonly workspaceFolder: Uri, private readonly output: OutputChannel, + private readonly processServiceFactory: IProcessServiceFactory) { this.disposables = []; this.optionsFile = path.join(__dirname, '..', '..', '..', 'resources', 'ctagOptions'); this.pythonSettings = PythonSettings.getInstance(workspaceFolder); @@ -60,8 +60,9 @@ export class Generator implements vscode.Disposable { args.push('-o', outputFile, '.'); this.output.appendLine(`${'-'.repeat(10)}Generating Tags${'-'.repeat(10)}`); this.output.appendLine(`${cmd} ${args.join(' ')}`); - const promise = new Promise((resolve, reject) => { - const result = this.processService.execObservable(cmd, args, { cwd: source.directory }); + const promise = new Promise(async (resolve, reject) => { + const processService = await this.processServiceFactory.create(); + const result = processService.execObservable(cmd, args, { cwd: source.directory }); let errorMsg = ''; result.out.subscribe(output => { if (output.source === 'stderr') { @@ -79,7 +80,7 @@ export class Generator implements vscode.Disposable { }); }); - vscode.window.setStatusBarMessage('Generating Tags', promise); + window.setStatusBarMessage('Generating Tags', promise); return promise; } diff --git a/src/client/workspaceSymbols/main.ts b/src/client/workspaceSymbols/main.ts index 9077e33a09d1..59919555ba11 100644 --- a/src/client/workspaceSymbols/main.ts +++ b/src/client/workspaceSymbols/main.ts @@ -1,8 +1,7 @@ -import * as vscode from 'vscode'; -import { OutputChannel, workspace } from 'vscode'; +import { CancellationToken, commands, Disposable, languages, OutputChannel, workspace } from 'vscode'; import { Commands, STANDARD_OUTPUT_CHANNEL } from '../common/constants'; import { isNotInstalledError } from '../common/helpers'; -import { IProcessService } from '../common/process/types'; +import { IProcessServiceFactory } from '../common/process/types'; import { IInstaller, InstallerResponse, IOutputChannel, Product } from '../common/types'; import { fsExistsAsync } from '../common/utils'; import { IServiceContainer } from '../ioc/types'; @@ -11,20 +10,18 @@ import { WorkspaceSymbolProvider } from './provider'; const MAX_NUMBER_OF_ATTEMPTS_TO_INSTALL_AND_BUILD = 2; -export class WorkspaceSymbols implements vscode.Disposable { - private disposables: vscode.Disposable[]; +export class WorkspaceSymbols implements Disposable { + private disposables: Disposable[]; private generators: Generator[] = []; private readonly outputChannel: OutputChannel; - // tslint:disable-next-line:no-any - private timeout: any; constructor(private serviceContainer: IServiceContainer) { this.outputChannel = this.serviceContainer.get(IOutputChannel, STANDARD_OUTPUT_CHANNEL); this.disposables = []; this.disposables.push(this.outputChannel); this.registerCommands(); this.initializeGenerators(); - vscode.languages.registerWorkspaceSymbolProvider(new WorkspaceSymbolProvider(this.generators, this.outputChannel)); - this.disposables.push(vscode.workspace.onDidChangeWorkspaceFolders(() => this.initializeGenerators())); + languages.registerWorkspaceSymbolProvider(new WorkspaceSymbolProvider(this.generators, this.outputChannel)); + this.disposables.push(workspace.onDidChangeWorkspaceFolders(() => this.initializeGenerators())); } public dispose() { this.disposables.forEach(d => d.dispose()); @@ -35,21 +32,21 @@ export class WorkspaceSymbols implements vscode.Disposable { generator.dispose(); } - if (Array.isArray(vscode.workspace.workspaceFolders)) { - vscode.workspace.workspaceFolders.forEach(wkSpc => { - const processService = this.serviceContainer.get(IProcessService); - this.generators.push(new Generator(wkSpc.uri, this.outputChannel, processService)); + if (Array.isArray(workspace.workspaceFolders)) { + workspace.workspaceFolders.forEach(wkSpc => { + const processServiceFactory = this.serviceContainer.get(IProcessServiceFactory); + this.generators.push(new Generator(wkSpc.uri, this.outputChannel, processServiceFactory)); }); } } private registerCommands() { - this.disposables.push(vscode.commands.registerCommand(Commands.Build_Workspace_Symbols, async (rebuild: boolean = true, token?: vscode.CancellationToken) => { + this.disposables.push(commands.registerCommand(Commands.Build_Workspace_Symbols, async (rebuild: boolean = true, token?: CancellationToken) => { const promises = this.buildWorkspaceSymbols(rebuild, token); return Promise.all(promises); })); } // tslint:disable-next-line:no-any - private buildWorkspaceSymbols(rebuild: boolean = true, token?: vscode.CancellationToken): Promise[] { + private buildWorkspaceSymbols(rebuild: boolean = true, token?: CancellationToken): Promise[] { if (token && token.isCancellationRequested) { return []; } diff --git a/src/test/common/installer.test.ts b/src/test/common/installer.test.ts index c491d93cd680..09b0385eaca2 100644 --- a/src/test/common/installer.test.ts +++ b/src/test/common/installer.test.ts @@ -12,10 +12,9 @@ import { Logger } from '../../client/common/logger'; import { PersistentStateFactory } from '../../client/common/persistentState'; import { PathUtils } from '../../client/common/platform/pathUtils'; import { CurrentProcess } from '../../client/common/process/currentProcess'; -import { IProcessService } from '../../client/common/process/types'; +import { IProcessServiceFactory } from '../../client/common/process/types'; import { IConfigurationService, ICurrentProcess, IInstaller, ILogger, IPathUtils, IPersistentStateFactory, IsWindows, ModuleNamePurpose, Product } from '../../client/common/types'; -import { rootWorkspaceUri } from '../common'; -import { updateSetting } from '../common'; +import { rootWorkspaceUri, updateSetting } from '../common'; import { MockModuleInstaller } from '../mocks/moduleInstaller'; import { MockProcessService } from '../mocks/proc'; import { UnitTestIocContainer } from '../unittests/serviceRegistry'; @@ -68,7 +67,7 @@ suite('Installer', () => { async function testCheckingIfProductIsInstalled(product: Product) { const installer = ioc.serviceContainer.get(IInstaller); - const processService = ioc.serviceContainer.get(IProcessService); + const processService = await ioc.serviceContainer.get(IProcessServiceFactory).create() as MockProcessService; const checkInstalledDef = createDeferred(); processService.onExec((file, args, options, callback) => { const moduleName = installer.translateProductToModuleName(product, ModuleNamePurpose.run); diff --git a/src/test/common/moduleInstaller.test.ts b/src/test/common/moduleInstaller.test.ts index 31ea81de250a..84835f18f7b2 100644 --- a/src/test/common/moduleInstaller.test.ts +++ b/src/test/common/moduleInstaller.test.ts @@ -16,7 +16,7 @@ import { PathUtils } from '../../client/common/platform/pathUtils'; import { PlatformService } from '../../client/common/platform/platformService'; import { Architecture, IFileSystem, IPlatformService } from '../../client/common/platform/types'; import { CurrentProcess } from '../../client/common/process/currentProcess'; -import { IProcessService, IPythonExecutionFactory } from '../../client/common/process/types'; +import { IProcessServiceFactory, IPythonExecutionFactory } from '../../client/common/process/types'; import { ITerminalService, ITerminalServiceFactory } from '../../client/common/terminal/types'; import { IConfigurationService, ICurrentProcess, IInstaller, ILogger, IPathUtils, IPersistentStateFactory, IPythonSettings, IsWindows } from '../../client/common/types'; import { ICondaService, IInterpreterLocatorService, IInterpreterService, INTERPRETER_LOCATOR_SERVICE, InterpreterType, PIPENV_SERVICE, PythonInterpreter } from '../../client/interpreter/contracts'; @@ -104,7 +104,7 @@ suite('Module Installer', () => { ioc.serviceManager.addSingletonInstance(IInterpreterLocatorService, mockInterpreterLocator.object, INTERPRETER_LOCATOR_SERVICE); ioc.serviceManager.addSingletonInstance(IInterpreterLocatorService, TypeMoq.Mock.ofType().object, PIPENV_SERVICE); - const processService = ioc.serviceContainer.get(IProcessService); + const processService = await ioc.serviceContainer.get(IProcessServiceFactory).create() as MockProcessService; processService.onExec((file, args, options, callback) => { if (args.length > 1 && args[0] === '-c' && args[1] === 'import pip') { callback({ stdout: '' }); @@ -137,7 +137,7 @@ suite('Module Installer', () => { ioc.serviceManager.addSingletonInstance(IInterpreterLocatorService, mockInterpreterLocator.object, INTERPRETER_LOCATOR_SERVICE); ioc.serviceManager.addSingletonInstance(IInterpreterLocatorService, TypeMoq.Mock.ofType().object, PIPENV_SERVICE); - const processService = ioc.serviceContainer.get(IProcessService); + const processService = await ioc.serviceContainer.get(IProcessServiceFactory).create() as MockProcessService; processService.onExec((file, args, options, callback) => { if (args.length > 1 && args[0] === '-c' && args[1] === 'import pip') { callback({ stdout: '' }); diff --git a/src/test/common/process/execFactory.test.ts b/src/test/common/process/execFactory.test.ts index 9a8aa3ce4322..2802a38cb749 100644 --- a/src/test/common/process/execFactory.test.ts +++ b/src/test/common/process/execFactory.test.ts @@ -1,32 +1,37 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +// tslint:disable:max-func-body-length no-any + import { expect } from 'chai'; import * as TypeMoq from 'typemoq'; import { Uri } from 'vscode'; import { IFileSystem } from '../../../client/common/platform/types'; -import { IProcessService } from '../../../client/common/process/types'; +import { IProcessService, IProcessServiceFactory } from '../../../client/common/process/types'; import { IConfigurationService, IPythonSettings } from '../../../client/common/types'; import { IEnvironmentVariablesProvider } from '../../../client/common/variables/types'; import { InterpreterVersionService } from '../../../client/interpreter/interpreterVersion'; import { IServiceContainer } from '../../../client/ioc/types'; -// tslint:disable-next-line:max-func-body-length suite('PythonExecutableService', () => { let serviceContainer: TypeMoq.IMock; let configService: TypeMoq.IMock; let procService: TypeMoq.IMock; + let procServiceFactory: TypeMoq.IMock; setup(() => { serviceContainer = TypeMoq.Mock.ofType(); const envVarsProvider = TypeMoq.Mock.ofType(); + procServiceFactory = TypeMoq.Mock.ofType(); procService = TypeMoq.Mock.ofType(); configService = TypeMoq.Mock.ofType(); const fileSystem = TypeMoq.Mock.ofType(); fileSystem.setup(f => f.fileExistsAsync(TypeMoq.It.isAny())).returns(() => Promise.resolve(false)); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IFileSystem))).returns(() => fileSystem.object); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IEnvironmentVariablesProvider))).returns(() => envVarsProvider.object); - serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IProcessService))).returns(() => procService.object); + serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IProcessServiceFactory))).returns(() => procServiceFactory.object); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IConfigurationService))).returns(() => configService.object); + procService.setup((x: any) => x.then).returns(() => undefined); + procServiceFactory.setup(p => p.create(TypeMoq.It.isAny())).returns(() => Promise.resolve(procService.object)); envVarsProvider.setup(v => v.getEnvironmentVariables(TypeMoq.It.isAny())).returns(() => Promise.resolve({})); }); @@ -38,7 +43,7 @@ suite('PythonExecutableService', () => { configService.setup(c => c.getSettings(TypeMoq.It.isValue(undefined))).returns(() => pythonSettings.object); procService.setup(p => p.exec(TypeMoq.It.isValue(pythonPath), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({ stdout: pythonVersion })); - const versionService = new InterpreterVersionService(procService.object); + const versionService = new InterpreterVersionService(procServiceFactory.object); const version = await versionService.getVersion(pythonPath, ''); expect(version).to.be.equal(pythonVersion); @@ -52,7 +57,7 @@ suite('PythonExecutableService', () => { configService.setup(c => c.getSettings(TypeMoq.It.isValue(resource))).returns(() => pythonSettings.object); procService.setup(p => p.exec(TypeMoq.It.isValue(pythonPath), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({ stdout: pythonVersion })); - const versionService = new InterpreterVersionService(procService.object); + const versionService = new InterpreterVersionService(procServiceFactory.object); const version = await versionService.getVersion(pythonPath, ''); expect(version).to.be.equal(pythonVersion); diff --git a/src/test/common/terminals/activation.conda.test.ts b/src/test/common/terminals/activation.conda.test.ts index d1d868dcc44f..b4498ce8edeb 100644 --- a/src/test/common/terminals/activation.conda.test.ts +++ b/src/test/common/terminals/activation.conda.test.ts @@ -1,6 +1,8 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +// tslint:disable:max-func-body-length no-any + import { expect } from 'chai'; import * as path from 'path'; import * as TypeMoq from 'typemoq'; @@ -8,7 +10,7 @@ import { Disposable } from 'vscode'; import { EnumEx } from '../../../client/common/enumUtils'; import '../../../client/common/extensions'; import { IFileSystem, IPlatformService } from '../../../client/common/platform/types'; -import { IProcessService } from '../../../client/common/process/types'; +import { IProcessService, IProcessServiceFactory } from '../../../client/common/process/types'; import { CondaActivationCommandProvider } from '../../../client/common/terminal/environmentActivationProviders/condaActivationProvider'; import { TerminalHelper } from '../../../client/common/terminal/helper'; import { ITerminalActivationCommandProvider, TerminalShellType } from '../../../client/common/terminal/types'; @@ -16,7 +18,6 @@ import { IConfigurationService, IDisposableRegistry, IPythonSettings, ITerminalS import { ICondaService } from '../../../client/interpreter/contracts'; import { IServiceContainer } from '../../../client/ioc/types'; -// tslint:disable-next-line:max-func-body-length suite('Terminal Environment Activation conda', () => { let terminalHelper: TerminalHelper; let disposables: Disposable[] = []; @@ -26,6 +27,7 @@ suite('Terminal Environment Activation conda', () => { let pythonSettings: TypeMoq.IMock; let serviceContainer: TypeMoq.IMock; let processService: TypeMoq.IMock; + let procServiceFactory: TypeMoq.IMock; let condaService: TypeMoq.IMock; setup(() => { @@ -37,10 +39,13 @@ suite('Terminal Environment Activation conda', () => { platformService = TypeMoq.Mock.ofType(); processService = TypeMoq.Mock.ofType(); condaService = TypeMoq.Mock.ofType(); + processService.setup((x: any) => x.then).returns(() => undefined); + procServiceFactory = TypeMoq.Mock.ofType(); + procServiceFactory.setup(p => p.create(TypeMoq.It.isAny())).returns(() => Promise.resolve(processService.object)); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IPlatformService), TypeMoq.It.isAny())).returns(() => platformService.object); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IFileSystem), TypeMoq.It.isAny())).returns(() => fileSystem.object); - serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IProcessService), TypeMoq.It.isAny())).returns(() => processService.object); + serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IProcessServiceFactory), TypeMoq.It.isAny())).returns(() => procServiceFactory.object); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(ICondaService), TypeMoq.It.isAny())).returns(() => condaService.object); const configService = TypeMoq.Mock.ofType(); diff --git a/src/test/format/extension.format.test.ts b/src/test/format/extension.format.test.ts index f50e678b3886..503de9c117c2 100644 --- a/src/test/format/extension.format.test.ts +++ b/src/test/format/extension.format.test.ts @@ -1,7 +1,8 @@ import * as fs from 'fs-extra'; import * as path from 'path'; import * as vscode from 'vscode'; -import { IProcessService, IPythonExecutionFactory } from '../../client/common/process/types'; +import { CancellationTokenSource, Position, Uri, window, workspace } from 'vscode'; +import { IProcessServiceFactory, IPythonExecutionFactory } from '../../client/common/process/types'; import { AutoPep8Formatter } from '../../client/formatters/autoPep8Formatter'; import { BlackFormatter } from '../../client/formatters/blackFormatter'; import { YapfFormatter } from '../../client/formatters/yapfFormatter'; @@ -10,7 +11,7 @@ import { MockProcessService } from '../mocks/proc'; import { compareFiles } from '../textUtils'; import { UnitTestIocContainer } from '../unittests/serviceRegistry'; -const ch = vscode.window.createOutputChannel('Tests'); +const ch = window.createOutputChannel('Tests'); const formatFilesPath = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'formatting'); const workspaceRootPath = path.join(__dirname, '..', '..', '..', 'src', 'test'); const originalUnformattedFile = path.join(formatFilesPath, 'fileToFormat.py'); @@ -85,8 +86,8 @@ suite('Formatting', () => { ioc.registerMockProcessTypes(); } - function injectFormatOutput(outputFileName: string) { - const procService = ioc.serviceContainer.get(IProcessService); + async function injectFormatOutput(outputFileName: string) { + const procService = await ioc.serviceContainer.get(IProcessServiceFactory).create() as MockProcessService; procService.onExecObservable((file, args, options, callback) => { if (args.indexOf('--diff') >= 0) { callback({ @@ -102,7 +103,7 @@ suite('Formatting', () => { const textEditor = await vscode.window.showTextDocument(textDocument); const options = { insertSpaces: textEditor.options.insertSpaces! as boolean, tabSize: textEditor.options.tabSize! as number }; - injectFormatOutput(outputFileName); + await injectFormatOutput(outputFileName); const edits = await formatter.formatDocument(textDocument, options, new vscode.CancellationTokenSource().token); await textEditor.edit(editBuilder => { @@ -137,11 +138,11 @@ suite('Formatting', () => { fs.copySync(path.join(sourceDir, originalName), fileToFormat, { overwrite: true }); fs.copySync(path.join(sourceDir, resultsName), formattedFile, { overwrite: true }); - const textDocument = await vscode.workspace.openTextDocument(fileToFormat); - const textEditor = await vscode.window.showTextDocument(textDocument); + const textDocument = await workspace.openTextDocument(fileToFormat); + const textEditor = await window.showTextDocument(textDocument); await textEditor.edit(builder => { // Make file dirty. Trailing blanks will be removed. - builder.insert(new vscode.Position(0, 0), '\n \n'); + builder.insert(new Position(0, 0), '\n \n'); }); const dir = path.dirname(fileToFormat); diff --git a/src/test/format/extension.sort.test.ts b/src/test/format/extension.sort.test.ts index af88891e6e91..884113bdb77b 100644 --- a/src/test/format/extension.sort.test.ts +++ b/src/test/format/extension.sort.test.ts @@ -3,7 +3,6 @@ import * as fs from 'fs'; import { EOL } from 'os'; import * as path from 'path'; import { commands, ConfigurationTarget, Position, Range, Uri, window, workspace } from 'vscode'; -import { IProcessService, IPythonExecutionFactory } from '../../client/common/process/types'; import { PythonImportSortProvider } from '../../client/providers/importSortProvider'; import { updateSetting } from '../common'; import { closeActiveWindows, initialize, initializeTest, IS_MULTI_ROOT_TEST } from '../initialize'; @@ -39,9 +38,7 @@ suite('Sorting', () => { fs.writeFileSync(fileToFormatWithConfig1, fs.readFileSync(originalFileToFormatWithConfig1)); await updateSetting('sortImports.args', [], Uri.file(sortingPath), configTarget); await closeActiveWindows(); - const pythonExecutionFactory = ioc.serviceContainer.get(IPythonExecutionFactory); - const processService = ioc.serviceContainer.get(IProcessService); - sorter = new PythonImportSortProvider(pythonExecutionFactory, processService); + sorter = new PythonImportSortProvider(ioc.serviceContainer); }); teardown(async () => { ioc.dispose(); diff --git a/src/test/interpreters/condaService.test.ts b/src/test/interpreters/condaService.test.ts index f6a16891e71a..21059a94e537 100644 --- a/src/test/interpreters/condaService.test.ts +++ b/src/test/interpreters/condaService.test.ts @@ -1,3 +1,4 @@ +// tslint:disable:no-require-imports no-var-requires no-any max-func-body-length import * as assert from 'assert'; import { expect } from 'chai'; import { EOL } from 'os'; @@ -5,19 +6,17 @@ import * as path from 'path'; import * as TypeMoq from 'typemoq'; import { FileSystem } from '../../client/common/platform/fileSystem'; import { IFileSystem, IPlatformService } from '../../client/common/platform/types'; -import { IProcessService } from '../../client/common/process/types'; +import { IProcessService, IProcessServiceFactory } from '../../client/common/process/types'; import { ILogger, IPersistentStateFactory } from '../../client/common/types'; import { IInterpreterLocatorService, InterpreterType, PythonInterpreter } from '../../client/interpreter/contracts'; import { CondaService, KNOWN_CONDA_LOCATIONS } from '../../client/interpreter/locators/services/condaService'; import { IServiceContainer } from '../../client/ioc/types'; import { MockState } from './mocks'; -// tslint:disable-next-line:no-require-imports no-var-requires const untildify: (value: string) => string = require('untildify'); const environmentsPath = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'environments'); -// tslint:disable-next-line:max-func-body-length suite('Interpreters Conda Service', () => { let processService: TypeMoq.IMock; let platformService: TypeMoq.IMock; @@ -25,14 +24,19 @@ suite('Interpreters Conda Service', () => { let fileSystem: TypeMoq.IMock; let registryInterpreterLocatorService: TypeMoq.IMock; let serviceContainer: TypeMoq.IMock; + let procServiceFactory: TypeMoq.IMock; setup(async () => { const logger = TypeMoq.Mock.ofType(); processService = TypeMoq.Mock.ofType(); platformService = TypeMoq.Mock.ofType(); registryInterpreterLocatorService = TypeMoq.Mock.ofType(); fileSystem = TypeMoq.Mock.ofType(); + procServiceFactory = TypeMoq.Mock.ofType(); + processService.setup((x: any) => x.then).returns(() => undefined); + procServiceFactory.setup(p => p.create(TypeMoq.It.isAny())).returns(() => Promise.resolve(processService.object)); + serviceContainer = TypeMoq.Mock.ofType(); - serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IProcessService), TypeMoq.It.isAny())).returns(() => processService.object); + serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IProcessServiceFactory), TypeMoq.It.isAny())).returns(() => procServiceFactory.object); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IPlatformService), TypeMoq.It.isAny())).returns(() => platformService.object); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(ILogger), TypeMoq.It.isAny())).returns(() => logger.object); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IFileSystem), TypeMoq.It.isAny())).returns(() => fileSystem.object); diff --git a/src/test/interpreters/currentPathService.test.ts b/src/test/interpreters/currentPathService.test.ts index 4d136735edf9..19e44c6eca76 100644 --- a/src/test/interpreters/currentPathService.test.ts +++ b/src/test/interpreters/currentPathService.test.ts @@ -3,17 +3,18 @@ 'use strict'; +// tslint:disable:max-func-body-length no-any + import { expect } from 'chai'; import * as TypeMoq from 'typemoq'; import { IFileSystem } from '../../client/common/platform/types'; -import { IProcessService } from '../../client/common/process/types'; +import { IProcessService, IProcessServiceFactory } from '../../client/common/process/types'; import { IConfigurationService, IPersistentState, IPersistentStateFactory, IPythonSettings } from '../../client/common/types'; import { IInterpreterVersionService, InterpreterType, PythonInterpreter } from '../../client/interpreter/contracts'; import { CurrentPathService } from '../../client/interpreter/locators/services/currentPathService'; import { IVirtualEnvironmentManager } from '../../client/interpreter/virtualEnvs/types'; import { IServiceContainer } from '../../client/ioc/types'; -// tslint:disable-next-line:max-func-body-length suite('Interpreters CurrentPath Service', () => { let processService: TypeMoq.IMock; let fileSystem: TypeMoq.IMock; @@ -32,21 +33,22 @@ suite('Interpreters CurrentPath Service', () => { configurationService.setup(c => c.getSettings(TypeMoq.It.isAny())).returns(() => pythonSettings.object); const persistentStateFactory = TypeMoq.Mock.ofType(); persistentState = TypeMoq.Mock.ofType>(); - // tslint:disable-next-line:no-any + processService.setup((x: any) => x.then).returns(() => undefined); persistentState.setup(p => p.value).returns(() => undefined as any); persistentState.setup(p => p.updateValue(TypeMoq.It.isAny())).returns(() => Promise.resolve()); fileSystem = TypeMoq.Mock.ofType(); persistentStateFactory.setup(p => p.createGlobalPersistentState(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => persistentState.object); + const procServiceFactory = TypeMoq.Mock.ofType(); + procServiceFactory.setup(p => p.create(TypeMoq.It.isAny())).returns(() => Promise.resolve(processService.object)); serviceContainer = TypeMoq.Mock.ofType(); - serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IProcessService), TypeMoq.It.isAny())).returns(() => processService.object); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IVirtualEnvironmentManager), TypeMoq.It.isAny())).returns(() => virtualEnvironmentManager.object); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IInterpreterVersionService), TypeMoq.It.isAny())).returns(() => interpreterVersionService.object); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IFileSystem), TypeMoq.It.isAny())).returns(() => fileSystem.object); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IPersistentStateFactory), TypeMoq.It.isAny())).returns(() => persistentStateFactory.object); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IConfigurationService), TypeMoq.It.isAny())).returns(() => configurationService.object); - currentPathService = new CurrentPathService(virtualEnvironmentManager.object, interpreterVersionService.object, processService.object, serviceContainer.object); + currentPathService = new CurrentPathService(virtualEnvironmentManager.object, interpreterVersionService.object, procServiceFactory.object, serviceContainer.object); }); test('Interpreters that do not exist on the file system are not excluded from the list', async () => { diff --git a/src/test/interpreters/interpreterVersion.test.ts b/src/test/interpreters/interpreterVersion.test.ts index 9e78d8ee5e66..6b9c9da81ad7 100644 --- a/src/test/interpreters/interpreterVersion.test.ts +++ b/src/test/interpreters/interpreterVersion.test.ts @@ -4,7 +4,7 @@ import { assert, expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; import '../../client/common/extensions'; -import { IProcessService } from '../../client/common/process/types'; +import { IProcessServiceFactory } from '../../client/common/process/types'; import { IInterpreterVersionService } from '../../client/interpreter/contracts'; import { PIP_VERSION_REGEX } from '../../client/interpreter/interpreterVersion'; import { PYTHON_PATH } from '../common'; @@ -31,7 +31,7 @@ suite('Interpreters display version', () => { } test('Must return the Python Version', async () => { - const pythonProcess = ioc.serviceContainer.get(IProcessService); + const pythonProcess = await ioc.serviceContainer.get(IProcessServiceFactory).create(); const output = await pythonProcess.exec(PYTHON_PATH, ['--version'], { cwd: __dirname, mergeStdOutErr: true }); const version = output.stdout.splitLines()[0]; const interpreterVersion = ioc.serviceContainer.get(IInterpreterVersionService); @@ -44,7 +44,7 @@ suite('Interpreters display version', () => { assert.equal(pyVersion, 'DEFAULT_TEST_VALUE', 'Incorrect version'); }); test('Must return the pip Version', async () => { - const pythonProcess = ioc.serviceContainer.get(IProcessService); + const pythonProcess = await ioc.serviceContainer.get(IProcessServiceFactory).create(); const result = await pythonProcess.exec(PYTHON_PATH, ['-m', 'pip', '--version'], { cwd: __dirname, mergeStdOutErr: true }); const output = result.stdout.splitLines()[0]; // Take the second part, see below example. diff --git a/src/test/interpreters/pipEnvService.test.ts b/src/test/interpreters/pipEnvService.test.ts index 65545cfc7b53..4571dd14b939 100644 --- a/src/test/interpreters/pipEnvService.test.ts +++ b/src/test/interpreters/pipEnvService.test.ts @@ -12,7 +12,7 @@ import { Uri, WorkspaceFolder } from 'vscode'; import { IApplicationShell, IWorkspaceService } from '../../client/common/application/types'; import { EnumEx } from '../../client/common/enumUtils'; import { IFileSystem } from '../../client/common/platform/types'; -import { IProcessService } from '../../client/common/process/types'; +import { IProcessService, IProcessServiceFactory } from '../../client/common/process/types'; import { ICurrentProcess, IPersistentState, IPersistentStateFactory } from '../../client/common/types'; import { IEnvironmentVariablesProvider } from '../../client/common/variables/types'; import { IInterpreterLocatorService, IInterpreterVersionService } from '../../client/interpreter/contracts'; @@ -38,6 +38,7 @@ suite('Interpreters - PipEnv', () => { let appShell: TypeMoq.IMock; let persistentStateFactory: TypeMoq.IMock; let envVarsProvider: TypeMoq.IMock; + let procServiceFactory: TypeMoq.IMock; setup(() => { serviceContainer = TypeMoq.Mock.ofType(); const workspaceService = TypeMoq.Mock.ofType(); @@ -48,6 +49,9 @@ suite('Interpreters - PipEnv', () => { currentProcess = TypeMoq.Mock.ofType(); persistentStateFactory = TypeMoq.Mock.ofType(); envVarsProvider = TypeMoq.Mock.ofType(); + procServiceFactory = TypeMoq.Mock.ofType(); + processService.setup((x: any) => x.then).returns(() => undefined); + procServiceFactory.setup(p => p.create(TypeMoq.It.isAny())).returns(() => Promise.resolve(processService.object)); // tslint:disable-next-line:no-any const persistentState = TypeMoq.Mock.ofType>(); @@ -61,9 +65,9 @@ suite('Interpreters - PipEnv', () => { workspaceService.setup(w => w.getWorkspaceFolder(TypeMoq.It.isAny())).returns(() => workspaceFolder.object); workspaceService.setup(w => w.rootPath).returns(() => rootWorkspace); + serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IProcessServiceFactory), TypeMoq.It.isAny())).returns(() => procServiceFactory.object); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IWorkspaceService))).returns(() => workspaceService.object); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IInterpreterVersionService))).returns(() => interpreterVersionService.object); - serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IProcessService))).returns(() => processService.object); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(ICurrentProcess))).returns(() => currentProcess.object); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IFileSystem))).returns(() => fileSystem.object); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IApplicationShell))).returns(() => appShell.object); @@ -101,7 +105,6 @@ suite('Interpreters - PipEnv', () => { }); test(`Should display warning message if there is a \'PipFile\' but \'pipenv --venv\' failes with stderr ${testSuffix}`, async () => { const env = {}; - envVarsProvider.setup(e => e.getEnvironmentVariables(TypeMoq.It.isAny())).returns(() => Promise.resolve({})).verifiable(TypeMoq.Times.once()); currentProcess.setup(c => c.env).returns(() => env); processService.setup(p => p.exec(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({ stderr: 'PipEnv Failed', stdout: '' })); fileSystem.setup(fs => fs.fileExistsAsync(TypeMoq.It.isValue(path.join(rootWorkspace, 'Pipfile')))).returns(() => Promise.resolve(true)); @@ -109,13 +112,11 @@ suite('Interpreters - PipEnv', () => { const environments = await pipEnvService.getInterpreters(resource); expect(environments).to.be.deep.equal([]); - envVarsProvider.verifyAll(); appShell.verifyAll(); }); test(`Should return interpreter information${testSuffix}`, async () => { const env = {}; const venvDir = 'one'; - envVarsProvider.setup(e => e.getEnvironmentVariables(TypeMoq.It.isAny())).returns(() => Promise.resolve({})).verifiable(TypeMoq.Times.once()); currentProcess.setup(c => c.env).returns(() => env); processService.setup(p => p.exec(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({ stdout: venvDir })); interpreterVersionService.setup(v => v.getVersion(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve('xyz')); @@ -125,7 +126,6 @@ suite('Interpreters - PipEnv', () => { expect(environments).to.be.lengthOf(1); fileSystem.verifyAll(); - envVarsProvider.verifyAll(); }); test(`Should return interpreter information using PipFile defined in Env variable${testSuffix}`, async () => { const envPipFile = 'XYZ'; @@ -133,7 +133,6 @@ suite('Interpreters - PipEnv', () => { PIPENV_PIPFILE: envPipFile }; const venvDir = 'one'; - envVarsProvider.setup(e => e.getEnvironmentVariables(TypeMoq.It.isAny())).returns(() => Promise.resolve({})).verifiable(TypeMoq.Times.once()); currentProcess.setup(c => c.env).returns(() => env); processService.setup(p => p.exec(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({ stdout: venvDir })); interpreterVersionService.setup(v => v.getVersion(TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve('xyz')); @@ -144,7 +143,6 @@ suite('Interpreters - PipEnv', () => { expect(environments).to.be.lengthOf(1); fileSystem.verifyAll(); - envVarsProvider.verifyAll(); }); }); }); diff --git a/src/test/interpreters/virtualEnvManager.test.ts b/src/test/interpreters/virtualEnvManager.test.ts index 3d00204b9269..4db50c4ac344 100644 --- a/src/test/interpreters/virtualEnvManager.test.ts +++ b/src/test/interpreters/virtualEnvManager.test.ts @@ -1,12 +1,14 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +// tslint:disable:no-any + import { expect } from 'chai'; import { Container } from 'inversify'; import * as TypeMoq from 'typemoq'; import { BufferDecoder } from '../../client/common/process/decoder'; import { ProcessService } from '../../client/common/process/proc'; -import { IBufferDecoder, IProcessService } from '../../client/common/process/types'; +import { IBufferDecoder, IProcessService, IProcessServiceFactory } from '../../client/common/process/types'; import { VirtualEnvironmentManager } from '../../client/interpreter/virtualEnvs'; import { ServiceContainer } from '../../client/ioc/container'; import { ServiceManager } from '../../client/ioc/serviceManager'; @@ -15,7 +17,6 @@ import { PYTHON_PATH } from '../common'; suite('Virtual environment manager', () => { let serviceManager: ServiceManager; let serviceContainer: ServiceContainer; - let process: TypeMoq.IMock; setup(async () => { const cont = new Container(); @@ -28,7 +29,9 @@ suite('Virtual environment manager', () => { test('Virtualenv Python environment suffix', async () => testSuffix('virtualenv')); test('Run actual virtual env detection code', async () => { - serviceManager.addSingleton(IProcessService, ProcessService); + const processServiceFactory = TypeMoq.Mock.ofType(); + processServiceFactory.setup(f => f.create(TypeMoq.It.isAny())).returns(() => Promise.resolve(new ProcessService(new BufferDecoder(), process.env as any))); + serviceManager.addSingletonInstance(IProcessServiceFactory, processServiceFactory.object); serviceManager.addSingleton(IBufferDecoder, BufferDecoder); const venvManager = new VirtualEnvironmentManager(serviceContainer); const name = await venvManager.getEnvironmentName(PYTHON_PATH); @@ -37,11 +40,14 @@ suite('Virtual environment manager', () => { }); async function testSuffix(expectedName: string) { - process = TypeMoq.Mock.ofType(); - serviceManager.addSingletonInstance(IProcessService, process.object); + const processService = TypeMoq.Mock.ofType(); + const processServiceFactory = TypeMoq.Mock.ofType(); + processService.setup((x: any) => x.then).returns(() => undefined); + processServiceFactory.setup(f => f.create(TypeMoq.It.isAny())).returns(() => Promise.resolve(processService.object)); + serviceManager.addSingletonInstance(IProcessServiceFactory, processServiceFactory.object); const venvManager = new VirtualEnvironmentManager(serviceContainer); - process + processService .setup(x => x.exec(PYTHON_PATH, TypeMoq.It.isAny())) .returns(() => Promise.resolve({ stdout: expectedName, diff --git a/src/test/mocks/proc.ts b/src/test/mocks/proc.ts index e910d0da4720..dcf1d5388859 100644 --- a/src/test/mocks/proc.ts +++ b/src/test/mocks/proc.ts @@ -1,5 +1,4 @@ import { EventEmitter } from 'events'; -import { inject, injectable } from 'inversify'; import 'rxjs/add/observable/of'; import { Observable } from 'rxjs/Observable'; import { ExecutionResult, IProcessService, ObservableExecutionResult, Output, SpawnOptions } from '../../client/common/process/types'; @@ -9,9 +8,8 @@ type ExecCallback = (result: ExecutionResult) => void; export const IOriginalProcessService = Symbol('IProcessService'); -@injectable() export class MockProcessService extends EventEmitter implements IProcessService { - constructor( @inject(IOriginalProcessService) private procService: IProcessService) { + constructor(private procService: IProcessService) { super(); } public onExecObservable(handler: (file: string, args: string[], options: SpawnOptions, callback: ExecObservableCallback) => void) { diff --git a/src/test/serviceRegistry.ts b/src/test/serviceRegistry.ts index f38344a474bd..5ce82911dea3 100644 --- a/src/test/serviceRegistry.ts +++ b/src/test/serviceRegistry.ts @@ -2,6 +2,7 @@ // Licensed under the MIT License. import { Container } from 'inversify'; +import * as TypeMoq from 'typemoq'; import { Disposable, Memento, OutputChannel } from 'vscode'; import { STANDARD_OUTPUT_CHANNEL } from '../client/common/constants'; import { Logger } from '../client/common/logger'; @@ -16,7 +17,7 @@ import { ProcessService } from '../client/common/process/proc'; import { PythonExecutionFactory } from '../client/common/process/pythonExecutionFactory'; import { PythonToolExecutionService } from '../client/common/process/pythonToolService'; import { registerTypes as processRegisterTypes } from '../client/common/process/serviceRegistry'; -import { IBufferDecoder, IProcessService, IPythonExecutionFactory, IPythonToolExecutionService } from '../client/common/process/types'; +import { IBufferDecoder, IProcessServiceFactory, IPythonExecutionFactory, IPythonToolExecutionService } from '../client/common/process/types'; import { registerTypes as commonRegisterTypes } from '../client/common/serviceRegistry'; import { GLOBAL_MEMENTO, ICurrentProcess, IDisposableRegistry, ILogger, IMemento, IOutputChannel, IPathUtils, Is64Bit, IsWindows, WORKSPACE_MEMENTO } from '../client/common/types'; import { registerTypes as variableRegisterTypes } from '../client/common/variables/serviceRegistry'; @@ -30,7 +31,7 @@ import { TEST_OUTPUT_CHANNEL } from '../client/unittests/common/constants'; import { registerTypes as unittestsRegisterTypes } from '../client/unittests/serviceRegistry'; import { MockOutputChannel } from './mockClasses'; import { MockMemento } from './mocks/mementos'; -import { IOriginalProcessService, MockProcessService } from './mocks/proc'; +import { MockProcessService } from './mocks/proc'; import { MockProcess } from './mocks/process'; export class IocContainer { @@ -93,8 +94,11 @@ export class IocContainer { } public registerMockProcessTypes() { this.serviceManager.addSingleton(IBufferDecoder, BufferDecoder); - this.serviceManager.addSingleton(IOriginalProcessService, ProcessService); - this.serviceManager.addSingleton(IProcessService, MockProcessService); + const processServiceFactory = TypeMoq.Mock.ofType(); + // tslint:disable-next-line:no-any + const processService = new MockProcessService(new ProcessService(new BufferDecoder(), process.env as any)); + processServiceFactory.setup(f => f.create(TypeMoq.It.isAny())).returns(() => Promise.resolve(processService)); + this.serviceManager.addSingletonInstance(IProcessServiceFactory, processServiceFactory.object); this.serviceManager.addSingleton(IPythonExecutionFactory, PythonExecutionFactory); this.serviceManager.addSingleton(IPythonToolExecutionService, PythonToolExecutionService); } diff --git a/src/test/terminals/codeExecution/helper.test.ts b/src/test/terminals/codeExecution/helper.test.ts index 56db9e5657cd..62c00bbd0115 100644 --- a/src/test/terminals/codeExecution/helper.test.ts +++ b/src/test/terminals/codeExecution/helper.test.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -// tslint:disable:no-multiline-string no-trailing-whitespace +// tslint:disable:no-multiline-string no-trailing-whitespace max-func-body-length no-any import { expect } from 'chai'; import * as fs from 'fs-extra'; @@ -14,7 +14,7 @@ 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 { IProcessService } from '../../../client/common/process/types'; +import { IProcessService, IProcessServiceFactory } from '../../../client/common/process/types'; import { IConfigurationService, IPythonSettings } from '../../../client/common/types'; import { IEnvironmentVariablesProvider } from '../../../client/common/variables/types'; import { IServiceContainer } from '../../../client/ioc/types'; @@ -24,7 +24,6 @@ import { PYTHON_PATH } from '../../common'; const TEST_FILES_PATH = path.join(EXTENSION_ROOT_DIR, 'src', 'test', 'pythonFiles', 'terminalExec'); -// tslint:disable-next-line:max-func-body-length suite('Terminal - Code Execution Helper', () => { let documentManager: TypeMoq.IMock; let applicationShell: TypeMoq.IMock; @@ -42,12 +41,15 @@ suite('Terminal - Code Execution Helper', () => { configService = TypeMoq.Mock.ofType(); const pythonSettings = TypeMoq.Mock.ofType(); pythonSettings.setup(p => p.pythonPath).returns(() => PYTHON_PATH); + processService.setup((x: any) => x.then).returns(() => undefined); configService.setup(c => c.getSettings(TypeMoq.It.isAny())).returns(() => pythonSettings.object); envVariablesProvider.setup(e => e.getEnvironmentVariables(TypeMoq.It.isAny())).returns(() => Promise.resolve({})); + const processServiceFactory = TypeMoq.Mock.ofType(); + processServiceFactory.setup(p => p.create(TypeMoq.It.isAny())).returns(() => Promise.resolve(processService.object)); + serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IProcessServiceFactory), TypeMoq.It.isAny())).returns(() => processServiceFactory.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); - serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IProcessService), TypeMoq.It.isAny())).returns(() => processService.object); serviceContainer.setup(c => c.get(TypeMoq.It.isValue(IConfigurationService), TypeMoq.It.isAny())).returns(() => configService.object); helper = new CodeExecutionHelper(serviceContainer.object); diff --git a/src/test/unittests/nosetest.disovery.test.ts b/src/test/unittests/nosetest.disovery.test.ts index d1acbecf149b..51001b1ab568 100644 --- a/src/test/unittests/nosetest.disovery.test.ts +++ b/src/test/unittests/nosetest.disovery.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import * as fs from 'fs'; import * as path from 'path'; import * as vscode from 'vscode'; -import { IProcessService } from '../../client/common/process/types'; +import { IProcessServiceFactory } from '../../client/common/process/types'; import { CommandSource } from '../../client/unittests/common/constants'; import { ITestManagerFactory } from '../../client/unittests/common/types'; import { rootWorkspaceUri, updateSetting } from '../common'; @@ -62,8 +62,8 @@ suite('Unit Tests - nose - discovery with mocked process output', () => { ioc.registerMockProcessTypes(); } - function injectTestDiscoveryOutput(outputFileName: string) { - const procService = ioc.serviceContainer.get(IProcessService); + async function injectTestDiscoveryOutput(outputFileName: string) { + const procService = await ioc.serviceContainer.get(IProcessServiceFactory).create() as MockProcessService; procService.onExecObservable((file, args, options, callback) => { if (args.indexOf('--collect-only') >= 0) { let out = fs.readFileSync(path.join(UNITTEST_TEST_FILES_PATH, outputFileName), 'utf8'); @@ -78,7 +78,7 @@ suite('Unit Tests - nose - discovery with mocked process output', () => { } test('Discover Tests (single test file)', async () => { - injectTestDiscoveryOutput('one.output'); + await injectTestDiscoveryOutput('one.output'); const factory = ioc.serviceContainer.get(ITestManagerFactory); const testManager = factory('nosetest', rootWorkspaceUri, UNITTEST_SINGLE_TEST_FILE_PATH); const tests = await testManager.discoverTests(CommandSource.ui, true, true); @@ -89,7 +89,7 @@ suite('Unit Tests - nose - discovery with mocked process output', () => { }); test('Check that nameToRun in testSuites has class name after : (single test file)', async () => { - injectTestDiscoveryOutput('two.output'); + await injectTestDiscoveryOutput('two.output'); const factory = ioc.serviceContainer.get(ITestManagerFactory); const testManager = factory('nosetest', rootWorkspaceUri, UNITTEST_SINGLE_TEST_FILE_PATH); const tests = await testManager.discoverTests(CommandSource.ui, true, true); @@ -99,7 +99,7 @@ suite('Unit Tests - nose - discovery with mocked process output', () => { assert.equal(tests.testSuites.every(t => t.testSuite.name === t.testSuite.nameToRun.split(':')[1]), true, 'Suite name does not match class name'); }); test('Discover Tests (-m=test)', async () => { - injectTestDiscoveryOutput('three.output'); + await injectTestDiscoveryOutput('three.output'); await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); const factory = ioc.serviceContainer.get(ITestManagerFactory); const testManager = factory('nosetest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); @@ -115,7 +115,7 @@ suite('Unit Tests - nose - discovery with mocked process output', () => { }); test('Discover Tests (-w=specific -m=tst)', async () => { - injectTestDiscoveryOutput('four.output'); + await injectTestDiscoveryOutput('four.output'); await updateSetting('unitTest.nosetestArgs', ['-w', 'specific', '-m', 'tst'], rootWorkspaceUri, configTarget); const factory = ioc.serviceContainer.get(ITestManagerFactory); const testManager = factory('nosetest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); @@ -128,7 +128,7 @@ suite('Unit Tests - nose - discovery with mocked process output', () => { }); test('Discover Tests (-m=test_)', async () => { - injectTestDiscoveryOutput('five.output'); + await injectTestDiscoveryOutput('five.output'); await updateSetting('unitTest.nosetestArgs', ['-m', 'test_'], rootWorkspaceUri, configTarget); const factory = ioc.serviceContainer.get(ITestManagerFactory); const testManager = factory('nosetest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); diff --git a/src/test/unittests/nosetest.run.test.ts b/src/test/unittests/nosetest.run.test.ts index 1fc34a684c34..37d26716a31e 100644 --- a/src/test/unittests/nosetest.run.test.ts +++ b/src/test/unittests/nosetest.run.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import * as fs from 'fs'; import * as path from 'path'; import * as vscode from 'vscode'; -import { IProcessService } from '../../client/common/process/types'; +import { IProcessServiceFactory } from '../../client/common/process/types'; import { CommandSource } from '../../client/unittests/common/constants'; import { ITestManagerFactory, TestsToRun } from '../../client/unittests/common/types'; import { rootWorkspaceUri, updateSetting } from '../common'; @@ -60,8 +60,8 @@ suite('Unit Tests - nose - run against actual python process', () => { ioc.registerMockProcessTypes(); } - function injectTestDiscoveryOutput(outputFileName: string) { - const procService = ioc.serviceContainer.get(IProcessService); + async function injectTestDiscoveryOutput(outputFileName: string) { + const procService = await ioc.serviceContainer.get(IProcessServiceFactory).create() as MockProcessService; procService.onExecObservable((file, args, options, callback) => { if (args.indexOf('--collect-only') >= 0) { callback({ @@ -72,8 +72,8 @@ suite('Unit Tests - nose - run against actual python process', () => { }); } - function injectTestRunOutput(outputFileName: string, failedOutput: boolean = false) { - const procService = ioc.serviceContainer.get(IProcessService); + async function injectTestRunOutput(outputFileName: string, failedOutput: boolean = false) { + const procService = await ioc.serviceContainer.get(IProcessServiceFactory).create() as MockProcessService; procService.onExecObservable((file, args, options, callback) => { if (failedOutput && args.indexOf('--failed') === -1) { return; @@ -90,8 +90,8 @@ suite('Unit Tests - nose - run against actual python process', () => { } test('Run Tests', async () => { - injectTestDiscoveryOutput('run.one.output'); - injectTestRunOutput('run.one.result'); + await injectTestDiscoveryOutput('run.one.output'); + await injectTestRunOutput('run.one.result'); await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); const factory = ioc.serviceContainer.get(ITestManagerFactory); const testManager = factory('nosetest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); @@ -103,9 +103,9 @@ suite('Unit Tests - nose - run against actual python process', () => { }); test('Run Failed Tests', async () => { - injectTestDiscoveryOutput('run.two.output'); - injectTestRunOutput('run.two.result'); - injectTestRunOutput('run.two.again.result', true); + await injectTestDiscoveryOutput('run.two.output'); + await injectTestRunOutput('run.two.result'); + await injectTestRunOutput('run.two.again.result', true); await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); const factory = ioc.serviceContainer.get(ITestManagerFactory); const testManager = factory('nosetest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); @@ -123,8 +123,8 @@ suite('Unit Tests - nose - run against actual python process', () => { }); test('Run Specific Test File', async () => { - injectTestDiscoveryOutput('run.three.output'); - injectTestRunOutput('run.three.result'); + await injectTestDiscoveryOutput('run.three.output'); + await injectTestRunOutput('run.three.result'); await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); const factory = ioc.serviceContainer.get(ITestManagerFactory); const testManager = factory('nosetest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); @@ -141,8 +141,8 @@ suite('Unit Tests - nose - run against actual python process', () => { }); test('Run Specific Test Suite', async () => { - injectTestDiscoveryOutput('run.four.output'); - injectTestRunOutput('run.four.result'); + await injectTestDiscoveryOutput('run.four.output'); + await injectTestRunOutput('run.four.result'); await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); const factory = ioc.serviceContainer.get(ITestManagerFactory); const testManager = factory('nosetest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); @@ -159,8 +159,8 @@ suite('Unit Tests - nose - run against actual python process', () => { }); test('Run Specific Test Function', async () => { - injectTestDiscoveryOutput('run.five.output'); - injectTestRunOutput('run.five.result'); + await injectTestDiscoveryOutput('run.five.output'); + await injectTestRunOutput('run.five.result'); await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); const factory = ioc.serviceContainer.get(ITestManagerFactory); const testManager = factory('nosetest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); diff --git a/src/test/unittests/pytest.discovery.test.ts b/src/test/unittests/pytest.discovery.test.ts index 9f073f8440bc..bdd6002ab81c 100644 --- a/src/test/unittests/pytest.discovery.test.ts +++ b/src/test/unittests/pytest.discovery.test.ts @@ -4,7 +4,7 @@ import * as assert from 'assert'; import * as path from 'path'; import * as vscode from 'vscode'; -import { IProcessService } from '../../client/common/process/types'; +import { IProcessServiceFactory } from '../../client/common/process/types'; import { CommandSource } from '../../client/unittests/common/constants'; import { ITestManagerFactory } from '../../client/unittests/common/types'; import { rootWorkspaceUri, updateSetting } from '../common'; @@ -44,8 +44,8 @@ suite('Unit Tests - pytest - discovery with mocked process output', () => { ioc.registerMockProcessTypes(); } - function injectTestDiscoveryOutput(output: string) { - const procService = ioc.serviceContainer.get(IProcessService); + async function injectTestDiscoveryOutput(output: string) { + const procService = await ioc.serviceContainer.get(IProcessServiceFactory).create() as MockProcessService; procService.onExecObservable((file, args, options, callback) => { if (args.indexOf('--collect-only') >= 0) { callback({ @@ -58,7 +58,7 @@ suite('Unit Tests - pytest - discovery with mocked process output', () => { test('Discover Tests (single test file)', async () => { // tslint:disable-next-line:no-multiline-string - injectTestDiscoveryOutput(` + await injectTestDiscoveryOutput(` ============================= test session starts ============================== platform darwin -- Python 3.6.2, pytest-3.3.0, py-1.5.2, pluggy-0.6.0 rootdir: /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/single, inifile: @@ -89,7 +89,7 @@ suite('Unit Tests - pytest - discovery with mocked process output', () => { test('Discover Tests (pattern = test_)', async () => { // tslint:disable-next-line:no-multiline-string - injectTestDiscoveryOutput(` + await injectTestDiscoveryOutput(` ============================= test session starts ============================== platform darwin -- Python 3.6.2, pytest-3.3.0, py-1.5.2, pluggy-0.6.0 rootdir: /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/standard, inifile: @@ -172,7 +172,7 @@ suite('Unit Tests - pytest - discovery with mocked process output', () => { test('Discover Tests (pattern = _test)', async () => { // tslint:disable-next-line:no-multiline-string - injectTestDiscoveryOutput(` + await injectTestDiscoveryOutput(` ============================= test session starts ============================== platform darwin -- Python 3.6.2, pytest-3.3.0, py-1.5.2, pluggy-0.6.0 rootdir: /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/standard, inifile: @@ -198,7 +198,7 @@ suite('Unit Tests - pytest - discovery with mocked process output', () => { test('Discover Tests (with config)', async () => { // tslint:disable-next-line:no-multiline-string - injectTestDiscoveryOutput(` + await injectTestDiscoveryOutput(` ============================= test session starts ============================== platform darwin -- Python 3.6.2, pytest-3.3.0, py-1.5.2, pluggy-0.6.0 rootdir: /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/unitestsWithConfigs, inifile: pytest.ini @@ -243,7 +243,7 @@ suite('Unit Tests - pytest - discovery with mocked process output', () => { test('Setting cwd should return tests', async () => { // tslint:disable-next-line:no-multiline-string - injectTestDiscoveryOutput(` + await injectTestDiscoveryOutput(` ============================= test session starts ============================== platform darwin -- Python 3.6.2, pytest-3.3.0, py-1.5.2, pluggy-0.6.0 rootdir: /Users/donjayamanne/.vscode/extensions/pythonVSCode/src/test/pythonFiles/testFiles/cwd/src, inifile: diff --git a/src/test/unittests/pytest.run.test.ts b/src/test/unittests/pytest.run.test.ts index b6695db63311..57cc69f7bf97 100644 --- a/src/test/unittests/pytest.run.test.ts +++ b/src/test/unittests/pytest.run.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import * as fs from 'fs'; import * as path from 'path'; import * as vscode from 'vscode'; -import { IProcessService } from '../../client/common/process/types'; +import { IProcessServiceFactory } from '../../client/common/process/types'; import { CommandSource } from '../../client/unittests/common/constants'; import { ITestManagerFactory, TestFile, TestsToRun } from '../../client/unittests/common/types'; import { rootWorkspaceUri, updateSetting } from '../common'; @@ -43,8 +43,8 @@ suite('Unit Tests - pytest - run with mocked process output', () => { ioc.registerMockProcessTypes(); } - function injectTestDiscoveryOutput(outputFileName: string) { - const procService = ioc.serviceContainer.get(IProcessService); + async function injectTestDiscoveryOutput(outputFileName: string) { + const procService = await ioc.serviceContainer.get(IProcessServiceFactory).create() as MockProcessService; procService.onExecObservable((file, args, options, callback) => { if (args.indexOf('--collect-only') >= 0) { callback({ @@ -55,8 +55,8 @@ suite('Unit Tests - pytest - run with mocked process output', () => { }); } - function injectTestRunOutput(outputFileName: string, failedOutput: boolean = false) { - const procService = ioc.serviceContainer.get(IProcessService); + async function injectTestRunOutput(outputFileName: string, failedOutput: boolean = false) { + const procService = await ioc.serviceContainer.get(IProcessServiceFactory).create() as MockProcessService; procService.onExecObservable((file, args, options, callback) => { if (failedOutput && args.indexOf('--last-failed') === -1) { return; @@ -73,8 +73,8 @@ suite('Unit Tests - pytest - run with mocked process output', () => { } test('Run Tests', async () => { - injectTestDiscoveryOutput('one.output'); - injectTestRunOutput('one.xml'); + await injectTestDiscoveryOutput('one.output'); + await injectTestRunOutput('one.xml'); await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); const factory = ioc.serviceContainer.get(ITestManagerFactory); const testManager = factory('pytest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); @@ -86,9 +86,9 @@ suite('Unit Tests - pytest - run with mocked process output', () => { }); test('Run Failed Tests', async () => { - injectTestDiscoveryOutput('two.output'); - injectTestRunOutput('two.xml'); - injectTestRunOutput('two.again.xml', true); + await injectTestDiscoveryOutput('two.output'); + await injectTestRunOutput('two.xml'); + await injectTestRunOutput('two.again.xml', true); await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); const factory = ioc.serviceContainer.get(ITestManagerFactory); const testManager = factory('pytest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); @@ -106,8 +106,8 @@ suite('Unit Tests - pytest - run with mocked process output', () => { }); test('Run Specific Test File', async () => { - injectTestDiscoveryOutput('three.output'); - injectTestRunOutput('three.xml'); + await injectTestDiscoveryOutput('three.output'); + await injectTestRunOutput('three.xml'); await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); const factory = ioc.serviceContainer.get(ITestManagerFactory); const testManager = factory('pytest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); @@ -130,8 +130,8 @@ suite('Unit Tests - pytest - run with mocked process output', () => { }); test('Run Specific Test Suite', async () => { - injectTestDiscoveryOutput('four.output'); - injectTestRunOutput('four.xml'); + await injectTestDiscoveryOutput('four.output'); + await injectTestRunOutput('four.xml'); await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); const factory = ioc.serviceContainer.get(ITestManagerFactory); const testManager = factory('pytest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); @@ -145,8 +145,8 @@ suite('Unit Tests - pytest - run with mocked process output', () => { }); test('Run Specific Test Function', async () => { - injectTestDiscoveryOutput('five.output'); - injectTestRunOutput('five.xml'); + await injectTestDiscoveryOutput('five.output'); + await injectTestRunOutput('five.xml'); await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); const factory = ioc.serviceContainer.get(ITestManagerFactory); const testManager = factory('pytest', rootWorkspaceUri, UNITTEST_TEST_FILES_PATH); diff --git a/src/test/unittests/serviceRegistry.ts b/src/test/unittests/serviceRegistry.ts index 725dba422e81..f3a6d21d2315 100644 --- a/src/test/unittests/serviceRegistry.ts +++ b/src/test/unittests/serviceRegistry.ts @@ -13,6 +13,7 @@ import { TestFlatteningVisitor } from '../../client/unittests/common/testVisitor import { TestFolderGenerationVisitor } from '../../client/unittests/common/testVisitors/folderGenerationVisitor'; import { TestResultResetVisitor } from '../../client/unittests/common/testVisitors/resultResetVisitor'; import { ITestResultsService, ITestsHelper, ITestsParser, ITestVisitor, IUnitTestSocketServer, TestProvider } from '../../client/unittests/common/types'; +// tslint:disable-next-line:no-duplicate-imports import { ITestCollectionStorageService, ITestDiscoveryService, ITestManager, ITestManagerFactory, ITestManagerService, ITestManagerServiceFactory } from '../../client/unittests/common/types'; import { TestManager as NoseTestManager } from '../../client/unittests/nosetest/main'; import { TestDiscoveryService as NoseTestDiscoveryService } from '../../client/unittests/nosetest/services/discoveryService'; diff --git a/src/test/unittests/unittest.discovery.test.ts b/src/test/unittests/unittest.discovery.test.ts index b1f95c6ed978..e573726c2b4e 100644 --- a/src/test/unittests/unittest.discovery.test.ts +++ b/src/test/unittests/unittest.discovery.test.ts @@ -6,7 +6,7 @@ import * as fs from 'fs-extra'; import { EOL } from 'os'; import * as path from 'path'; import { ConfigurationTarget } from 'vscode'; -import { IProcessService } from '../../client/common/process/types'; +import { IProcessServiceFactory } from '../../client/common/process/types'; import { CommandSource } from '../../client/unittests/common/constants'; import { ITestManagerFactory } from '../../client/unittests/common/types'; import { rootWorkspaceUri, updateSetting } from '../common'; @@ -59,8 +59,8 @@ suite('Unit Tests - unittest - discovery with mocked process output', () => { ioc.registerMockProcessTypes(); } - function injectTestDiscoveryOutput(output: string) { - const procService = ioc.serviceContainer.get(IProcessService); + async function injectTestDiscoveryOutput(output: string) { + const procService = await ioc.serviceContainer.get(IProcessServiceFactory).create() as MockProcessService; procService.onExecObservable((file, args, options, callback) => { if (args.length > 1 && args[0] === '-c' && args[1].includes('import unittest') && args[1].includes('loader = unittest.TestLoader()')) { callback({ @@ -75,7 +75,7 @@ suite('Unit Tests - unittest - discovery with mocked process output', () => { test('Discover Tests (single test file)', async () => { await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_*.py'], rootWorkspaceUri, configTarget); // tslint:disable-next-line:no-multiline-string - injectTestDiscoveryOutput(`start + await injectTestDiscoveryOutput(`start test_one.Test_test1.test_A test_one.Test_test1.test_B test_one.Test_test1.test_c @@ -92,7 +92,7 @@ suite('Unit Tests - unittest - discovery with mocked process output', () => { test('Discover Tests', async () => { await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_*.py'], rootWorkspaceUri, configTarget); // tslint:disable-next-line:no-multiline-string - injectTestDiscoveryOutput(`start + await injectTestDiscoveryOutput(`start test_unittest_one.Test_test1.test_A test_unittest_one.Test_test1.test_B test_unittest_one.Test_test1.test_c @@ -116,7 +116,7 @@ suite('Unit Tests - unittest - discovery with mocked process output', () => { test('Discover Tests (pattern = *_test_*.py)', async () => { await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=*_test*.py'], rootWorkspaceUri, configTarget); // tslint:disable-next-line:no-multiline-string - injectTestDiscoveryOutput(`start + await injectTestDiscoveryOutput(`start unittest_three_test.Test_test3.test_A unittest_three_test.Test_test3.test_B `); @@ -132,7 +132,7 @@ suite('Unit Tests - unittest - discovery with mocked process output', () => { test('Setting cwd should return tests', async () => { await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_*.py'], rootWorkspaceUri, configTarget); // tslint:disable-next-line:no-multiline-string - injectTestDiscoveryOutput(`start + await injectTestDiscoveryOutput(`start test_cwd.Test_Current_Working_Directory.test_cwd `); const factory = ioc.serviceContainer.get(ITestManagerFactory); diff --git a/src/test/unittests/unittest.run.test.ts b/src/test/unittests/unittest.run.test.ts index f74ff2522acb..757ecf836199 100644 --- a/src/test/unittests/unittest.run.test.ts +++ b/src/test/unittests/unittest.run.test.ts @@ -6,7 +6,7 @@ import * as fs from 'fs-extra'; import { EOL } from 'os'; import * as path from 'path'; import { ConfigurationTarget } from 'vscode'; -import { IProcessService } from '../../client/common/process/types'; +import { IProcessServiceFactory } from '../../client/common/process/types'; import { CommandSource } from '../../client/unittests/common/constants'; import { ITestManagerFactory, IUnitTestSocketServer, TestsToRun } from '../../client/unittests/common/types'; import { rootWorkspaceUri, updateSetting } from '../common'; @@ -43,7 +43,7 @@ suite('Unit Tests - unittest - run with mocked process output', () => { } await initializeTest(); initializeDI(); - ignoreTestLauncher(); + await ignoreTestLauncher(); }); teardown(async () => { ioc.dispose(); @@ -70,8 +70,8 @@ suite('Unit Tests - unittest - run with mocked process output', () => { ioc.registerTestVisitors(); } - function ignoreTestLauncher() { - const procService = ioc.serviceContainer.get(IProcessService); + async function ignoreTestLauncher() { + const procService = await ioc.serviceContainer.get(IProcessServiceFactory).create() as MockProcessService; // When running the python test launcher, just return. procService.onExecObservable((file, args, options, callback) => { if (args.length > 1 && args[0].endsWith('visualstudio_py_testlauncher.py')) { @@ -79,8 +79,8 @@ suite('Unit Tests - unittest - run with mocked process output', () => { } }); } - function injectTestDiscoveryOutput(output: string) { - const procService = ioc.serviceContainer.get(IProcessService); + async function injectTestDiscoveryOutput(output: string) { + const procService = await ioc.serviceContainer.get(IProcessServiceFactory).create() as MockProcessService; procService.onExecObservable((file, args, options, callback) => { if (args.length > 1 && args[0] === '-c' && args[1].includes('import unittest') && args[1].includes('loader = unittest.TestLoader()')) { callback({ @@ -101,7 +101,7 @@ suite('Unit Tests - unittest - run with mocked process output', () => { test('Run Tests', async () => { await updateSetting('unitTest.unittestArgs', ['-v', '-s', './tests', '-p', 'test_unittest*.py'], rootWorkspaceUri, configTarget); // tslint:disable-next-line:no-multiline-string - injectTestDiscoveryOutput(`start + await injectTestDiscoveryOutput(`start test_unittest_one.Test_test1.test_A test_unittest_one.Test_test1.test_B test_unittest_one.Test_test1.test_c @@ -138,7 +138,7 @@ suite('Unit Tests - unittest - run with mocked process output', () => { test('Run Failed Tests', async () => { await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_unittest*.py'], rootWorkspaceUri, configTarget); // tslint:disable-next-line:no-multiline-string - injectTestDiscoveryOutput(`start + await injectTestDiscoveryOutput(`start test_unittest_one.Test_test1.test_A test_unittest_one.Test_test1.test_B test_unittest_one.Test_test1.test_c @@ -191,7 +191,7 @@ suite('Unit Tests - unittest - run with mocked process output', () => { await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_unittest*.py'], rootWorkspaceUri, configTarget); // tslint:disable-next-line:no-multiline-string - injectTestDiscoveryOutput(`start + await injectTestDiscoveryOutput(`start test_unittest_one.Test_test_one_1.test_1_1_1 test_unittest_one.Test_test_one_1.test_1_1_2 test_unittest_one.Test_test_one_1.test_1_1_3 @@ -228,7 +228,7 @@ suite('Unit Tests - unittest - run with mocked process output', () => { test('Run Specific Test Suite', async () => { await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_unittest*.py'], rootWorkspaceUri, configTarget); // tslint:disable-next-line:no-multiline-string - injectTestDiscoveryOutput(`start + await injectTestDiscoveryOutput(`start test_unittest_one.Test_test_one_1.test_1_1_1 test_unittest_one.Test_test_one_1.test_1_1_2 test_unittest_one.Test_test_one_1.test_1_1_3 @@ -265,7 +265,7 @@ suite('Unit Tests - unittest - run with mocked process output', () => { test('Run Specific Test Function', async () => { await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_unittest*.py'], rootWorkspaceUri, configTarget); // tslint:disable-next-line:no-multiline-string - injectTestDiscoveryOutput(`start + await injectTestDiscoveryOutput(`start test_unittest_one.Test_test1.test_A test_unittest_one.Test_test1.test_B test_unittest_one.Test_test1.test_c diff --git a/src/test/workspaceSymbols/multiroot.test.ts b/src/test/workspaceSymbols/multiroot.test.ts index ccbf64b3adcb..e6e0f45febe3 100644 --- a/src/test/workspaceSymbols/multiroot.test.ts +++ b/src/test/workspaceSymbols/multiroot.test.ts @@ -1,7 +1,7 @@ import * as assert from 'assert'; import * as path from 'path'; import { CancellationTokenSource, ConfigurationTarget, Uri } from 'vscode'; -import { IProcessService } from '../../client/common/process/types'; +import { IProcessServiceFactory } from '../../client/common/process/types'; import { Generator } from '../../client/workspaceSymbols/generator'; import { WorkspaceSymbolProvider } from '../../client/workspaceSymbols/provider'; import { closeActiveWindows, initialize, initializeTest, IS_MULTI_ROOT_TEST } from '../initialize'; @@ -13,7 +13,7 @@ const multirootPath = path.join(__dirname, '..', '..', '..', 'src', 'testMultiRo suite('Multiroot Workspace Symbols', () => { let ioc: UnitTestIocContainer; - let processService: IProcessService; + let processServiceFactory: IProcessServiceFactory; suiteSetup(function () { if (!IS_MULTI_ROOT_TEST) { // tslint:disable-next-line:no-invalid-this @@ -37,7 +37,7 @@ suite('Multiroot Workspace Symbols', () => { ioc.registerCommonTypes(); ioc.registerVariableTypes(); ioc.registerProcessTypes(); - processService = ioc.serviceContainer.get(IProcessService); + processServiceFactory = ioc.serviceContainer.get(IProcessServiceFactory); } test('symbols should be returned when enabeld and vice versa', async () => { @@ -46,7 +46,7 @@ suite('Multiroot Workspace Symbols', () => { await updateSetting('workspaceSymbols.enabled', false, childWorkspaceUri, ConfigurationTarget.WorkspaceFolder); - let generator = new Generator(childWorkspaceUri, outputChannel, processService); + let generator = new Generator(childWorkspaceUri, outputChannel, processServiceFactory); let provider = new WorkspaceSymbolProvider([generator], outputChannel); let symbols = await provider.provideWorkspaceSymbols('', new CancellationTokenSource().token); assert.equal(symbols.length, 0, 'Symbols returned even when workspace symbols are turned off'); @@ -54,7 +54,7 @@ suite('Multiroot Workspace Symbols', () => { await updateSetting('workspaceSymbols.enabled', true, childWorkspaceUri, ConfigurationTarget.WorkspaceFolder); - generator = new Generator(childWorkspaceUri, outputChannel, processService); + generator = new Generator(childWorkspaceUri, outputChannel, processServiceFactory); provider = new WorkspaceSymbolProvider([generator], outputChannel); symbols = await provider.provideWorkspaceSymbols('', new CancellationTokenSource().token); assert.notEqual(symbols.length, 0, 'Symbols should be returned when workspace symbols are turned on'); @@ -68,8 +68,8 @@ suite('Multiroot Workspace Symbols', () => { await updateSetting('workspaceSymbols.enabled', true, workspace2Uri, ConfigurationTarget.WorkspaceFolder); const generators = [ - new Generator(childWorkspaceUri, outputChannel, processService), - new Generator(workspace2Uri, outputChannel, processService)]; + new Generator(childWorkspaceUri, outputChannel, processServiceFactory), + new Generator(workspace2Uri, outputChannel, processServiceFactory)]; const provider = new WorkspaceSymbolProvider(generators, outputChannel); const symbols = await provider.provideWorkspaceSymbols('meth1Of', new CancellationTokenSource().token); diff --git a/src/test/workspaceSymbols/standard.test.ts b/src/test/workspaceSymbols/standard.test.ts index 5d264e7fd35a..46fdd9ba6102 100644 --- a/src/test/workspaceSymbols/standard.test.ts +++ b/src/test/workspaceSymbols/standard.test.ts @@ -2,7 +2,7 @@ import * as assert from 'assert'; import * as path from 'path'; import { CancellationTokenSource, ConfigurationTarget, Uri } from 'vscode'; import { PythonSettings } from '../../client/common/configSettings'; -import { IProcessService } from '../../client/common/process/types'; +import { IProcessServiceFactory } from '../../client/common/process/types'; import { Generator } from '../../client/workspaceSymbols/generator'; import { WorkspaceSymbolProvider } from '../../client/workspaceSymbols/provider'; import { closeActiveWindows, initialize, initializeTest, IS_MULTI_ROOT_TEST } from '../initialize'; @@ -15,7 +15,7 @@ const configUpdateTarget = IS_MULTI_ROOT_TEST ? ConfigurationTarget.WorkspaceFol suite('Workspace Symbols', () => { let ioc: UnitTestIocContainer; - let processService: IProcessService; + let processServiceFactory: IProcessServiceFactory; suiteSetup(initialize); suiteTeardown(closeActiveWindows); setup(async () => { @@ -32,7 +32,7 @@ suite('Workspace Symbols', () => { ioc.registerCommonTypes(); ioc.registerVariableTypes(); ioc.registerProcessTypes(); - processService = ioc.serviceContainer.get(IProcessService); + processServiceFactory = ioc.serviceContainer.get(IProcessServiceFactory); } test('symbols should be returned when enabeld and vice versa', async () => { @@ -42,9 +42,9 @@ suite('Workspace Symbols', () => { // The workspace will be in the output test folder // So lets modify the settings so it sees the source test folder let settings = PythonSettings.getInstance(workspaceUri); - settings.workspaceSymbols.tagFilePath = path.join(workspaceUri.fsPath, '.vscode', 'tags'); + settings.workspaceSymbols!.tagFilePath = path.join(workspaceUri.fsPath, '.vscode', 'tags'); - let generator = new Generator(workspaceUri, outputChannel, processService); + let generator = new Generator(workspaceUri, outputChannel, processServiceFactory); let provider = new WorkspaceSymbolProvider([generator], outputChannel); let symbols = await provider.provideWorkspaceSymbols('', new CancellationTokenSource().token); assert.equal(symbols.length, 0, 'Symbols returned even when workspace symbols are turned off'); @@ -55,9 +55,9 @@ suite('Workspace Symbols', () => { // The workspace will be in the output test folder // So lets modify the settings so it sees the source test folder settings = PythonSettings.getInstance(workspaceUri); - settings.workspaceSymbols.tagFilePath = path.join(workspaceUri.fsPath, '.vscode', 'tags'); + settings.workspaceSymbols!.tagFilePath = path.join(workspaceUri.fsPath, '.vscode', 'tags'); - generator = new Generator(workspaceUri, outputChannel, processService); + generator = new Generator(workspaceUri, outputChannel, processServiceFactory); provider = new WorkspaceSymbolProvider([generator], outputChannel); symbols = await provider.provideWorkspaceSymbols('', new CancellationTokenSource().token); assert.notEqual(symbols.length, 0, 'Symbols should be returned when workspace symbols are turned on'); @@ -70,9 +70,9 @@ suite('Workspace Symbols', () => { // The workspace will be in the output test folder // So lets modify the settings so it sees the source test folder const settings = PythonSettings.getInstance(workspaceUri); - settings.workspaceSymbols.tagFilePath = path.join(workspaceUri.fsPath, '.vscode', 'tags'); + settings.workspaceSymbols!.tagFilePath = path.join(workspaceUri.fsPath, '.vscode', 'tags'); - const generators = [new Generator(workspaceUri, outputChannel, processService)]; + const generators = [new Generator(workspaceUri, outputChannel, processServiceFactory)]; const provider = new WorkspaceSymbolProvider(generators, outputChannel); const symbols = await provider.provideWorkspaceSymbols('meth1Of', new CancellationTokenSource().token);