diff --git a/resources/default.launch.json b/resources/default.launch.json new file mode 100644 index 000000000000..10f90e0b4286 --- /dev/null +++ b/resources/default.launch.json @@ -0,0 +1,58 @@ +[ + { + "name": "Python: Current File (Integrated Terminal)", + "type": "python", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal" + }, + { + "name": "Python: Attach", + "type": "python", + "request": "attach", + "port": 5678, + "host": "localhost" + }, + { + "name": "Python: Module", + "type": "python", + "request": "launch", + "module": "enter-your-module-name-here", + "console": "integratedTerminal" + }, + { + "name": "Python: Django", + "type": "python", + "request": "launch", + "program": "${workspaceFolder}/manage.py", + "console": "integratedTerminal", + "args": [ + "runserver", + "--noreload", + "--nothreading" + ], + "django": true + }, + { + "name": "Python: Flask", + "type": "python", + "request": "launch", + "module": "flask", + "env": { + "FLASK_APP": "app.py" + }, + "args": [ + "run", + "--no-debugger", + "--no-reload" + ], + "jinja": true + }, + { + "name": "Python: Current File (External Terminal)", + "type": "python", + "request": "launch", + "program": "${file}", + "console": "externalTerminal" + } +] diff --git a/src/client/common/utils/localize.ts b/src/client/common/utils/localize.ts index 9ba2b5e7bfd3..afbda48341f8 100644 --- a/src/client/common/utils/localize.ts +++ b/src/client/common/utils/localize.ts @@ -110,38 +110,38 @@ export namespace DebugConfigurationPrompts { export const selectConfigurationTitle = localize('debug.selectConfigurationTitle', 'Select a debug configuration'); export const selectConfigurationPlaceholder = localize('debug.selectConfigurationPlaceholder', 'Debug Configuration'); export const debugFileConfigurationLabel = localize('debug.debugFileConfigurationLabel', 'Python File'); - export const debugFileConfigurationDescription = localize('debug.debugFileConfigurationDescription', 'Debug Python file'); + export const debugFileConfigurationDescription = localize('debug.debugFileConfigurationDescription', 'Debug currently active Python file'); export const debugModuleConfigurationLabel = localize('debug.debugModuleConfigurationLabel', 'Module'); - export const debugModuleConfigurationDescription = localize('debug.debugModuleConfigurationDescription', 'Debug Python module/package'); + export const debugModuleConfigurationDescription = localize('debug.debugModuleConfigurationDescription', 'Debug a python module by invoking it with \'-m\''); export const remoteAttachConfigurationLabel = localize('debug.remoteAttachConfigurationLabel', 'Remote Attach'); - export const remoteAttachConfigurationDescription = localize('debug.remoteAttachConfigurationDescription', 'Debug a remote Python program'); + export const remoteAttachConfigurationDescription = localize('debug.remoteAttachConfigurationDescription', 'Attach to a remote ptsvd debug server'); export const debugDjangoConfigurationLabel = localize('debug.debugDjangoConfigurationLabel', 'Django'); - export const debugDjangoConfigurationDescription = localize('debug.debugDjangoConfigurationDescription', 'Web Application'); + export const debugDjangoConfigurationDescription = localize('debug.debugDjangoConfigurationDescription', 'Launch and debug a Django web application'); export const debugFlaskConfigurationLabel = localize('debug.debugFlaskConfigurationLabel', 'Flask'); - export const debugFlaskConfigurationDescription = localize('debug.debugFlaskConfigurationDescription', 'Web Application'); + export const debugFlaskConfigurationDescription = localize('debug.debugFlaskConfigurationDescription', 'Launch and debug a Flask web application'); export const debugPyramidConfigurationLabel = localize('debug.debugPyramidConfigurationLabel', 'Pyramid'); export const debugPyramidConfigurationDescription = localize('debug.debugPyramidConfigurationDescription', 'Web Application'); export const djangoEnterManagePyPathTitle = localize('debug.djangoEnterManagePyPathTitle', 'Debug Django'); // tslint:disable-next-line:no-invalid-template-strings - export const djangoEnterManagePyPathPrompt = localize('debug.djangoEnterManagePyPathPrompt', 'Enter path to manage.py (\'${workspaceFolderToken}\' points to the root of the current workspace folder)'); - export const djangoEnterManagePyPathInvalidFilePathError = localize('debug.djangoEnterManagePyPathInvalidFilePathError', 'Enter a valid Python file path'); + export const djangoEnterManagePyPathPrompt = localize('debug.djangoEnterManagePyPathPrompt', 'Enter path to manage.py (\'${workspaceFolder}\' points to the root of the current workspace folder)'); + export const djangoEnterManagePyPathInvalidFilePathError = localize('debug.djangoEnterManagePyPathInvalidFilePathError', 'Enter a valid python file path'); export const flaskEnterAppPathOrNamePathTitle = localize('debug.flaskEnterAppPathOrNamePathTitle', 'Debug Flask'); export const flaskEnterAppPathOrNamePathPrompt = localize('debug.flaskEnterAppPathOrNamePathPrompt', 'Enter path to application, e.g. \'app.py\' or \'app\''); export const flaskEnterAppPathOrNamePathInvalidNameError = localize('debug.flaskEnterAppPathOrNamePathInvalidNameError', 'Enter a valid name'); export const moduleEnterModuleTitle = localize('debug.moduleEnterModuleTitle', 'Debug Module'); export const moduleEnterModulePrompt = localize('debug.moduleEnterModulePrompt', 'Enter Python module/package name'); - export const moduleEnterModuleInvalidNameError = localize('debug.moduleEnterModuleInvalidNameError', 'Enter a valid name'); + export const moduleEnterModuleInvalidNameError = localize('debug.moduleEnterModuleInvalidNameError', 'Enter a valid module name'); export const pyramidEnterDevelopmentIniPathTitle = localize('debug.pyramidEnterDevelopmentIniPathTitle', 'Debug Pyramid'); // tslint:disable-next-line:no-invalid-template-strings export const pyramidEnterDevelopmentIniPathPrompt = localize('debug.pyramidEnterDevelopmentIniPathPrompt', '`Enter path to development.ini (\'${workspaceFolderToken}\' points to the root of the current workspace folder)`'); export const pyramidEnterDevelopmentIniPathInvalidFilePathError = localize('debug.pyramidEnterDevelopmentIniPathInvalidFilePathError', 'Enter a valid file path'); export const attachRemotePortTitle = localize('debug.attachRemotePortTitle', 'Remote Debugging'); - export const attachRemotePortPrompt = localize('debug.attachRemotePortPrompt', 'Enter port number'); + export const attachRemotePortPrompt = localize('debug.attachRemotePortPrompt', 'Enter the port number that the ptvsd server is listening on'); export const attachRemotePortValidationError = localize('debug.attachRemotePortValidationError', 'Enter a valid port number'); export const attachRemoteHostTitle = localize('debug.attachRemoteHostTitle', 'Remote Debugging'); - export const attachRemoteHostPrompt = localize('debug.attachRemoteHostPrompt', 'Enter a host name or IP address'); - export const attachRemoteHostValidationError = localize('debug.attachRemoteHostValidationError', 'Enter a valid host name or IP address'); + export const attachRemoteHostPrompt = localize('debug.attachRemoteHostPrompt', 'Enter host name'); + export const attachRemoteHostValidationError = localize('debug.attachRemoteHostValidationError', 'Enter a host name or IP address'); } // Skip using vscode-nls and instead just compute our strings based on key values. Key values diff --git a/src/client/debugger/extension/configuration/debugConfigurationProvider.ts b/src/client/debugger/extension/configuration/debugConfigurationProvider.ts deleted file mode 100644 index aa0230e2d605..000000000000 --- a/src/client/debugger/extension/configuration/debugConfigurationProvider.ts +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -'use strict'; - -import { inject, injectable, named } from 'inversify'; -import { CancellationToken, DebugConfiguration, DebugConfigurationProvider, WorkspaceFolder } from 'vscode'; -import { AttachRequestArguments, LaunchRequestArguments } from '../../types'; -import { IDebugConfigurationResolver } from './types'; - -@injectable() -export class PythonDebugConfigurationProvider implements DebugConfigurationProvider { - constructor(@inject(IDebugConfigurationResolver) @named('attach') private readonly attachResolver: IDebugConfigurationResolver, - @inject(IDebugConfigurationResolver) @named('launch') private readonly launchResolver: IDebugConfigurationResolver) { - } - public async resolveDebugConfiguration(folder: WorkspaceFolder | undefined, debugConfiguration: DebugConfiguration, token?: CancellationToken): Promise { - if (debugConfiguration.request === 'attach') { - return this.attachResolver.resolveDebugConfiguration(folder, debugConfiguration as AttachRequestArguments, token); - } else { - return this.launchResolver.resolveDebugConfiguration(folder, debugConfiguration as LaunchRequestArguments, token); - } } - -} diff --git a/src/client/debugger/extension/configuration/debugConfigurationService.ts b/src/client/debugger/extension/configuration/debugConfigurationService.ts index 3f37e0920882..d45bf0478982 100644 --- a/src/client/debugger/extension/configuration/debugConfigurationService.ts +++ b/src/client/debugger/extension/configuration/debugConfigurationService.ts @@ -4,9 +4,14 @@ 'use strict'; import { inject, injectable, named } from 'inversify'; +import * as path from 'path'; import { CancellationToken, DebugConfiguration, QuickPickItem, WorkspaceFolder } from 'vscode'; +import { IFileSystem } from '../../../common/platform/types'; import { DebugConfigurationPrompts } from '../../../common/utils/localize'; import { IMultiStepInput, IMultiStepInputFactory, InputStep, IQuickPickParameters } from '../../../common/utils/multiStepInput'; +import { EXTENSION_ROOT_DIR } from '../../../constants'; +import { sendTelemetryEvent } from '../../../telemetry'; +import { DEBUGGER_CONFIGURATION_PROMPTS } from '../../../telemetry/constants'; import { AttachRequestArguments, DebugConfigurationArguments, LaunchRequestArguments } from '../../types'; import { DebugConfigurationState, DebugConfigurationType, IDebugConfigurationService } from '../types'; import { IDebugConfigurationProviderFactory, IDebugConfigurationResolver } from './types'; @@ -16,14 +21,19 @@ export class PythonDebugConfigurationService implements IDebugConfigurationServi constructor(@inject(IDebugConfigurationResolver) @named('attach') private readonly attachResolver: IDebugConfigurationResolver, @inject(IDebugConfigurationResolver) @named('launch') private readonly launchResolver: IDebugConfigurationResolver, @inject(IDebugConfigurationProviderFactory) private readonly providerFactory: IDebugConfigurationProviderFactory, - @inject(IMultiStepInputFactory) private readonly multiStepFactory: IMultiStepInputFactory) { + @inject(IMultiStepInputFactory) private readonly multiStepFactory: IMultiStepInputFactory, + @inject(IFileSystem) private readonly fs: IFileSystem) { } - public async provideDebugConfigurations?(folder: WorkspaceFolder | undefined, token?: CancellationToken): Promise { + public async provideDebugConfigurations(folder: WorkspaceFolder | undefined, token?: CancellationToken): Promise { const config: Partial = {}; const state = { config, folder, token }; const multiStep = this.multiStepFactory.create(); await multiStep.run((input, s) => this.pickDebugConfiguration(input, s), state); - return state.config as DebugConfiguration[]; + if (Object.keys(state.config).length === 0) { + return this.getDefaultDebugConfig(); + } else { + return [state.config as DebugConfiguration]; + } } public async resolveDebugConfiguration(folder: WorkspaceFolder | undefined, debugConfiguration: DebugConfiguration, token?: CancellationToken): Promise { if (debugConfiguration.request === 'attach') { @@ -32,6 +42,12 @@ export class PythonDebugConfigurationService implements IDebugConfigurationServi return this.launchResolver.resolveDebugConfiguration(folder, debugConfiguration as LaunchRequestArguments, token); } } + protected async getDefaultDebugConfig(): Promise { + sendTelemetryEvent(DEBUGGER_CONFIGURATION_PROMPTS, undefined, { configurationType: DebugConfigurationType.default }); + const jsFilePath = path.join(EXTENSION_ROOT_DIR, 'resources', 'default.launch.json'); + const jsonStr = await this.fs.readFile(jsFilePath); + return JSON.parse(jsonStr) as DebugConfiguration[]; + } protected async pickDebugConfiguration(input: IMultiStepInput, state: DebugConfigurationState): Promise | void> { type DebugConfigurationQuickPickItem = QuickPickItem & { type: DebugConfigurationType }; const items: DebugConfigurationQuickPickItem[] = [ diff --git a/src/client/debugger/extension/configuration/providers/moduleLaunch.ts b/src/client/debugger/extension/configuration/providers/moduleLaunch.ts index 40804d57e376..baf11fa32f04 100644 --- a/src/client/debugger/extension/configuration/providers/moduleLaunch.ts +++ b/src/client/debugger/extension/configuration/providers/moduleLaunch.ts @@ -20,11 +20,11 @@ export class ModuleLaunchDebugConfigurationProvider implements IDebugConfigurati name: localize('python.snippet.launch.module.label', 'Python: Module')(), type: DebuggerTypeName, request: 'launch', - module: 'enter-your-module-name-here' + module: 'enter-your-module-name' }; const selectedModule = await input.showInputBox({ title: DebugConfigurationPrompts.moduleEnterModuleTitle(), - value: config.module || 'enter-your-module-name-here', + value: config.module || 'enter-your-module-name', prompt: DebugConfigurationPrompts.moduleEnterModulePrompt(), validate: value => Promise.resolve((value && value.trim().length > 0) ? undefined : DebugConfigurationPrompts.moduleEnterModuleInvalidNameError()) }); diff --git a/src/client/debugger/extension/types.ts b/src/client/debugger/extension/types.ts index 63d8691252ff..6b89701121f0 100644 --- a/src/client/debugger/extension/types.ts +++ b/src/client/debugger/extension/types.ts @@ -21,6 +21,7 @@ export interface IDebugConfigurationProvider { } export enum DebugConfigurationType { + default = 'default', launchFile = 'launchFile', remoteAttach = 'remoteAttach', launchDjango = 'launchDjango', diff --git a/src/test/debugger/attach.ptvsd.test.ts b/src/test/debugger/attach.ptvsd.test.ts index 576a90ac7329..c9a90e3f659b 100644 --- a/src/test/debugger/attach.ptvsd.test.ts +++ b/src/test/debugger/attach.ptvsd.test.ts @@ -6,12 +6,14 @@ import '../../client/common/extensions'; import { ChildProcess, spawn } from 'child_process'; import * as getFreePort from 'get-port'; import * as path from 'path'; +import { instance, mock } from 'ts-mockito'; import * as TypeMoq from 'typemoq'; import { DebugConfiguration, Uri } from 'vscode'; import { DebugClient } from 'vscode-debugadapter-testsupport'; import { IDocumentManager, IWorkspaceService } from '../../client/common/application/types'; import { EXTENSION_ROOT_DIR } from '../../client/common/constants'; import { IS_WINDOWS } from '../../client/common/platform/constants'; +import { FileSystem } from '../../client/common/platform/fileSystem'; import { IPlatformService } from '../../client/common/platform/types'; import { IConfigurationService } from '../../client/common/types'; import { IMultiStepInputFactory } from '../../client/common/utils/multiStepInput'; @@ -99,7 +101,8 @@ suite('Debugging - Attach Debugger', () => { const attachResolver = new AttachConfigurationResolver(workspaceService.object, documentManager.object, platformService.object, configurationService.object); const providerFactory = TypeMoq.Mock.ofType().object; const multiStepIput = TypeMoq.Mock.ofType().object; - const configProvider = new PythonDebugConfigurationService(attachResolver, launchResolver.object, providerFactory, multiStepIput); + const fs = mock(FileSystem); + const configProvider = new PythonDebugConfigurationService(attachResolver, launchResolver.object, providerFactory, multiStepIput, instance(fs)); await configProvider.resolveDebugConfiguration({ index: 0, name: 'root', uri: Uri.file(localRoot) }, options); const attachPromise = debugClient.attachRequest(options); diff --git a/src/test/debugger/extension/configuration/debugConfigurationProvider.unit.test.ts b/src/test/debugger/extension/configuration/debugConfigurationProvider.unit.test.ts deleted file mode 100644 index c0dd996fbf8e..000000000000 --- a/src/test/debugger/extension/configuration/debugConfigurationProvider.unit.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -'use strict'; - -// tslint:disable:no-any - -import { expect } from 'chai'; -import * as typemoq from 'typemoq'; -import { Uri } from 'vscode'; -import { PythonDebugConfigurationProvider } from '../../../../client/debugger/extension/configuration/debugConfigurationProvider'; -import { IDebugConfigurationResolver } from '../../../../client/debugger/extension/configuration/types'; -import { AttachRequestArguments, LaunchRequestArguments } from '../../../../client/debugger/types'; - -suite('Debugging - Configuration Provider', () => { - let attachResolver: typemoq.IMock>; - let launchResolver: typemoq.IMock>; - let provider: PythonDebugConfigurationProvider; - - setup(() => { - attachResolver = typemoq.Mock.ofType>(); - launchResolver = typemoq.Mock.ofType>(); - provider = new PythonDebugConfigurationProvider(attachResolver.object, launchResolver.object); - }); - test('Should use attach resolver when passing attach config', async () => { - const config = { - request: 'attach' - } as any as AttachRequestArguments; - const folder = { name: '1', index: 0, uri: Uri.parse('1234') }; - const expectedConfig = { yay: 1 }; - - attachResolver - .setup(a => a.resolveDebugConfiguration(typemoq.It.isValue(folder), typemoq.It.isValue(config), typemoq.It.isAny())) - .returns(() => Promise.resolve(expectedConfig as any)) - .verifiable(typemoq.Times.once()); - launchResolver - .setup(a => a.resolveDebugConfiguration(typemoq.It.isAny(), typemoq.It.isAny(), typemoq.It.isAny())) - .verifiable(typemoq.Times.never()); - - const resolvedConfig = await provider.resolveDebugConfiguration(folder, config as any); - - expect(resolvedConfig).to.deep.equal(expectedConfig); - attachResolver.verifyAll(); - launchResolver.verifyAll(); - }); - [ - { request: 'launch' }, { request: undefined } - ].forEach(config => { - test(`Should use launch resolver when passing launch config with request=${config.request}`, async () => { - const folder = { name: '1', index: 0, uri: Uri.parse('1234') }; - const expectedConfig = { yay: 1 }; - - launchResolver - .setup(a => a.resolveDebugConfiguration(typemoq.It.isValue(folder), typemoq.It.isValue(config as any as LaunchRequestArguments), typemoq.It.isAny())) - .returns(() => Promise.resolve(expectedConfig as any)) - .verifiable(typemoq.Times.once()); - attachResolver - .setup(a => a.resolveDebugConfiguration(typemoq.It.isAny(), typemoq.It.isAny(), typemoq.It.isAny())) - .verifiable(typemoq.Times.never()); - - const resolvedConfig = await provider.resolveDebugConfiguration(folder, config as any); - - expect(resolvedConfig).to.deep.equal(expectedConfig); - attachResolver.verifyAll(); - launchResolver.verifyAll(); - }); - }); -}); diff --git a/src/test/debugger/extension/configuration/debugConfigurationService.unit.test.ts b/src/test/debugger/extension/configuration/debugConfigurationService.unit.test.ts index 2dccfa8619e5..24dc5c67d169 100644 --- a/src/test/debugger/extension/configuration/debugConfigurationService.unit.test.ts +++ b/src/test/debugger/extension/configuration/debugConfigurationService.unit.test.ts @@ -6,10 +6,14 @@ // tslint:disable:no-any import { expect } from 'chai'; -import { instance, mock } from 'ts-mockito'; +import * as path from 'path'; +import { instance, mock, when } from 'ts-mockito'; import * as typemoq from 'typemoq'; import { Uri } from 'vscode'; +import { FileSystem } from '../../../../client/common/platform/fileSystem'; +import { IFileSystem } from '../../../../client/common/platform/types'; import { IMultiStepInput, IMultiStepInputFactory } from '../../../../client/common/utils/multiStepInput'; +import { EXTENSION_ROOT_DIR } from '../../../../client/constants'; import { PythonDebugConfigurationService } from '../../../../client/debugger/extension/configuration/debugConfigurationService'; import { DebugConfigurationProviderFactory } from '../../../../client/debugger/extension/configuration/providers/providerFactory'; import { IDebugConfigurationResolver } from '../../../../client/debugger/extension/configuration/types'; @@ -17,12 +21,13 @@ import { DebugConfigurationState } from '../../../../client/debugger/extension/t import { AttachRequestArguments, LaunchRequestArguments } from '../../../../client/debugger/types'; // tslint:disable-next-line:max-func-body-length -suite('Debugging - Configuration Provider', () => { +suite('Debugging - Configuration Service', () => { let attachResolver: typemoq.IMock>; let launchResolver: typemoq.IMock>; let configService: TestPythonDebugConfigurationService; let multiStepFactory: typemoq.IMock; let providerFactory: DebugConfigurationProviderFactory; + let fs: IFileSystem; class TestPythonDebugConfigurationService extends PythonDebugConfigurationService { // tslint:disable-next-line:no-unnecessary-override @@ -35,7 +40,9 @@ suite('Debugging - Configuration Provider', () => { launchResolver = typemoq.Mock.ofType>(); multiStepFactory = typemoq.Mock.ofType(); providerFactory = mock(DebugConfigurationProviderFactory); - configService = new TestPythonDebugConfigurationService(attachResolver.object, launchResolver.object, instance(providerFactory), multiStepFactory.object); + fs = mock(FileSystem); + configService = new TestPythonDebugConfigurationService(attachResolver.object, launchResolver.object, instance(providerFactory), multiStepFactory.object, + instance(fs)); }); test('Should use attach resolver when passing attach config', async () => { const config = { @@ -83,28 +90,65 @@ suite('Debugging - Configuration Provider', () => { test('Picker should be displayed', async () => { // tslint:disable-next-line:no-object-literal-type-assertion const state = { configs: [], folder: {}, token: undefined } as any as DebugConfigurationState; - const multStepInput = typemoq.Mock.ofType>(); - multStepInput + const multiStepInput = typemoq.Mock.ofType>(); + multiStepInput .setup(i => i.showQuickPick(typemoq.It.isAny())) .returns(() => Promise.resolve(undefined as any)) .verifiable(typemoq.Times.once()); - await configService.pickDebugConfiguration(multStepInput.object, state); + await configService.pickDebugConfiguration(multiStepInput.object, state); - multStepInput.verifyAll(); + multiStepInput.verifyAll(); }); test('Existing Configuration items must be removed before displaying picker', async () => { // tslint:disable-next-line:no-object-literal-type-assertion const state = { configs: [1, 2, 3], folder: {}, token: undefined } as any as DebugConfigurationState; - const multStepInput = typemoq.Mock.ofType>(); - multStepInput + const multiStepInput = typemoq.Mock.ofType>(); + multiStepInput .setup(i => i.showQuickPick(typemoq.It.isAny())) .returns(() => Promise.resolve(undefined as any)) .verifiable(typemoq.Times.once()); - await configService.pickDebugConfiguration(multStepInput.object, state); + await configService.pickDebugConfiguration(multiStepInput.object, state); - multStepInput.verifyAll(); + multiStepInput.verifyAll(); expect(Object.keys(state.config)).to.be.lengthOf(0); }); + test('Ensure generated config is returned', async () => { + const expectedConfig = { yes: 'Updated' }; + const multiStepInput = { + run: (_, state) => { + Object.assign(state.config, expectedConfig); + return Promise.resolve(); + } + }; + multiStepFactory + .setup(f => f.create()) + .returns(() => multiStepInput as any) + .verifiable(typemoq.Times.once()); + configService.pickDebugConfiguration = (_, state) => { + Object.assign(state.config, expectedConfig); + return Promise.resolve(); + }; + const config = await configService.provideDebugConfigurations!({} as any); + + multiStepFactory.verifyAll(); + expect(config).to.deep.equal([expectedConfig]); + }); + test('Ensure default config is returned', async () => { + const expectedConfig = { yes: 'Updated' }; + const multiStepInput = { + run: () => Promise.resolve() + }; + multiStepFactory + .setup(f => f.create()) + .returns(() => multiStepInput as any) + .verifiable(typemoq.Times.once()); + const jsFile = path.join(EXTENSION_ROOT_DIR, 'resources', 'default.launch.json'); + when(fs.readFile(jsFile)).thenResolve(JSON.stringify([expectedConfig])); + const config = await configService.provideDebugConfigurations!({} as any); + + multiStepFactory.verifyAll(); + expect(config).to.deep.equal([expectedConfig]); + }); }); diff --git a/src/test/debugger/extension/configuration/providers/moduleLaunch.unit.test.ts b/src/test/debugger/extension/configuration/providers/moduleLaunch.unit.test.ts index 7f8be8d55128..754516a388de 100644 --- a/src/test/debugger/extension/configuration/providers/moduleLaunch.unit.test.ts +++ b/src/test/debugger/extension/configuration/providers/moduleLaunch.unit.test.ts @@ -33,7 +33,7 @@ suite('Debugging - Configuration Provider Module', () => { name: localize('python.snippet.launch.module.label', 'Python: Module')(), type: DebuggerTypeName, request: 'launch', - module: 'enter-your-module-name-here' + module: 'enter-your-module-name' }; expect(state.config).to.be.deep.equal(config); diff --git a/src/test/debugger/extension/configuration/providers/providerFactory.unit.test.ts b/src/test/debugger/extension/configuration/providers/providerFactory.unit.test.ts index d1433326dc2f..bcbad4d04c45 100644 --- a/src/test/debugger/extension/configuration/providers/providerFactory.unit.test.ts +++ b/src/test/debugger/extension/configuration/providers/providerFactory.unit.test.ts @@ -29,7 +29,11 @@ suite('Debugging - Configuration Provider Factory', () => { ); }); getNamesAndValues(DebugConfigurationType).forEach(item => { - test(`Configuration Provider for ${item.name}`, () => { + test(`Configuration Provider for ${item.name}`, function () { + if (item.value === DebugConfigurationType.default) { + // tslint:disable-next-line:no-invalid-this + return this.skip(); + } const provider = factory.create(item.value); expect(provider).to.equal(mappedProviders.get(item.value)); }); diff --git a/src/test/initialize.ts b/src/test/initialize.ts index 1c3e6d0a320f..8090363452cb 100644 --- a/src/test/initialize.ts +++ b/src/test/initialize.ts @@ -63,7 +63,7 @@ export async function closeActiveWindows(): Promise { // Attempt to fix #1301. // Lets not waste too much time. setTimeout(() => { - reject(new Error('Command \'workbench.action.closeAllEditors\' timedout')); + reject(new Error('Command \'workbench.action.closeAllEditors\' timed out')); }, 15000); }); }