From 6832fec76ce1520fd118f5646c25e22441ce36b0 Mon Sep 17 00:00:00 2001 From: Paula Camargo Date: Mon, 24 Oct 2022 12:52:53 -0700 Subject: [PATCH 01/10] RemoveDI from factory --- src/client/debugger/extension/adapter/factory.ts | 9 +++------ src/test/debugger/extension/adapter/factory.unit.test.ts | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/client/debugger/extension/adapter/factory.ts b/src/client/debugger/extension/adapter/factory.ts index 5a228ca289ff..d27b47343bcd 100644 --- a/src/client/debugger/extension/adapter/factory.ts +++ b/src/client/debugger/extension/adapter/factory.ts @@ -10,9 +10,9 @@ import { DebugAdapterExecutable, DebugAdapterServer, DebugSession, + window, WorkspaceFolder, } from 'vscode'; -import { IApplicationShell } from '../../../common/application/types'; import { EXTENSION_ROOT_DIR } from '../../../constants'; import { IInterpreterService } from '../../../interpreter/contracts'; import { traceLog, traceVerbose } from '../../../logging'; @@ -27,10 +27,7 @@ const localize: nls.LocalizeFunc = nls.loadMessageBundle(); @injectable() export class DebugAdapterDescriptorFactory implements IDebugAdapterDescriptorFactory { - constructor( - @inject(IInterpreterService) private readonly interpreterService: IInterpreterService, - @inject(IApplicationShell) private readonly appShell: IApplicationShell, - ) {} + constructor(@inject(IInterpreterService) private readonly interpreterService: IInterpreterService) {} public async createDebugAdapterDescriptor( session: DebugSession, @@ -161,7 +158,7 @@ export class DebugAdapterDescriptorFactory implements IDebugAdapterDescriptorFac * @memberof DebugAdapterDescriptorFactory */ private async notifySelectInterpreter() { - await this.appShell.showErrorMessage( + await window.showErrorMessage( localize('interpreterError', 'Please install Python or select a Python Interpreter to use the debugger.'), ); } diff --git a/src/test/debugger/extension/adapter/factory.unit.test.ts b/src/test/debugger/extension/adapter/factory.unit.test.ts index f23e8aa12704..d6b9b9a8fd15 100644 --- a/src/test/debugger/extension/adapter/factory.unit.test.ts +++ b/src/test/debugger/extension/adapter/factory.unit.test.ts @@ -75,7 +75,7 @@ suite('Debugging - Adapter Factory', () => { when(interpreterService.getInterpreterDetails(pythonPath)).thenResolve(interpreter); when(interpreterService.getInterpreters(anything())).thenReturn([interpreter]); - factory = new DebugAdapterDescriptorFactory(instance(interpreterService), instance(appShell)); + factory = new DebugAdapterDescriptorFactory(instance(interpreterService)); }); teardown(() => { From af6bfa8a6c072f1a4027c8b87b00ec69ef0294ae Mon Sep 17 00:00:00 2001 From: Paula Camargo Date: Mon, 24 Oct 2022 14:54:38 -0700 Subject: [PATCH 02/10] remove di in debugger prompt --- .../debugger/extension/adapter/browser.ts | 10 +++ .../adapter/outdatedDebuggerPrompt.ts | 31 +++------ .../extension/configuration/utils/common.ts | 4 ++ .../outdatedDebuggerPrompt.unit.test.ts | 66 +++++++++++-------- 4 files changed, 63 insertions(+), 48 deletions(-) create mode 100644 src/client/debugger/extension/adapter/browser.ts diff --git a/src/client/debugger/extension/adapter/browser.ts b/src/client/debugger/extension/adapter/browser.ts new file mode 100644 index 000000000000..ccf51bd07ec8 --- /dev/null +++ b/src/client/debugger/extension/adapter/browser.ts @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +'use strict'; + +import { env, Uri } from 'vscode'; + +export function launch(url: string): void { + env.openExternal(Uri.parse(url)); +} diff --git a/src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts b/src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts index c86f3a9ef206..636c8d155b1d 100644 --- a/src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts +++ b/src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts @@ -3,33 +3,26 @@ 'use strict'; -import { inject, injectable } from 'inversify'; import { DebugAdapterTracker, DebugAdapterTrackerFactory, DebugSession, ProviderResult } from 'vscode'; import { DebugProtocol } from 'vscode-debugprotocol'; -import { IApplicationShell } from '../../../common/application/types'; -import { IBrowserService } from '../../../common/types'; import { Common, OutdatedDebugger } from '../../../common/utils/localize'; +import { showInformationMessage } from '../configuration/utils/common'; +import { launch } from './browser'; import { IPromptShowState } from './types'; // This situation occurs when user connects to old containers or server where // the debugger they had installed was ptvsd. We should show a prompt to ask them to update. class OutdatedDebuggerPrompt implements DebugAdapterTracker { - constructor( - private promptCheck: IPromptShowState, - private appShell: IApplicationShell, - private browserService: IBrowserService, - ) {} + constructor(private promptCheck: IPromptShowState) {} public onDidSendMessage(message: DebugProtocol.ProtocolMessage) { if (this.promptCheck.shouldShowPrompt() && this.isPtvsd(message)) { const prompts = [Common.moreInfo]; - this.appShell - .showInformationMessage(OutdatedDebugger.outdatedDebuggerMessage, ...prompts) - .then((selection) => { - if (selection === prompts[0]) { - this.browserService.launch('https://aka.ms/migrateToDebugpy'); - } - }); + showInformationMessage(OutdatedDebugger.outdatedDebuggerMessage, ...prompts).then((selection) => { + if (selection === prompts[0]) { + launch('https://aka.ms/migrateToDebugpy'); + } + }); } } @@ -68,16 +61,12 @@ class OutdatedDebuggerPromptState implements IPromptShowState { } } -@injectable() export class OutdatedDebuggerPromptFactory implements DebugAdapterTrackerFactory { private readonly promptCheck: OutdatedDebuggerPromptState; - constructor( - @inject(IApplicationShell) private readonly appShell: IApplicationShell, - @inject(IBrowserService) private browserService: IBrowserService, - ) { + constructor() { this.promptCheck = new OutdatedDebuggerPromptState(); } public createDebugAdapterTracker(_session: DebugSession): ProviderResult { - return new OutdatedDebuggerPrompt(this.promptCheck, this.appShell, this.browserService); + return new OutdatedDebuggerPrompt(this.promptCheck); } } diff --git a/src/client/debugger/extension/configuration/utils/common.ts b/src/client/debugger/extension/configuration/utils/common.ts index 36572419908f..1f2d21846247 100644 --- a/src/client/debugger/extension/configuration/utils/common.ts +++ b/src/client/debugger/extension/configuration/utils/common.ts @@ -46,3 +46,7 @@ export function getActiveTextEditor(): TextEditor | undefined { const { activeTextEditor } = window; return activeTextEditor; } + +export function showInformationMessage(message: string, ...items: string[]): Thenable { + return window.showInformationMessage(message, ...items); +} diff --git a/src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts b/src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts index e17b80ab34f7..82c832fce680 100644 --- a/src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts +++ b/src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts @@ -4,23 +4,23 @@ 'use strict'; import * as assert from 'assert'; -import { anyString, anything, instance, mock, verify, when } from 'ts-mockito'; +import * as sinon from 'sinon'; +import { anyString, mock, when } from 'ts-mockito'; import { DebugSession, WorkspaceFolder } from 'vscode'; import { DebugProtocol } from 'vscode-debugprotocol'; -import { ApplicationShell } from '../../../../client/common/application/applicationShell'; -import { IApplicationShell } from '../../../../client/common/application/types'; import { ConfigurationService } from '../../../../client/common/configuration/service'; -import { BrowserService } from '../../../../client/common/net/browser'; -import { IBrowserService, IPythonSettings } from '../../../../client/common/types'; import { createDeferred, sleep } from '../../../../client/common/utils/async'; import { Common } from '../../../../client/common/utils/localize'; import { OutdatedDebuggerPromptFactory } from '../../../../client/debugger/extension/adapter/outdatedDebuggerPrompt'; import { clearTelemetryReporter } from '../../../../client/telemetry'; +import * as browser from '../../../../client/debugger/extension/adapter/browser'; +import * as common from '../../../../client/debugger/extension/configuration/utils/common'; +import { IPythonSettings } from '../../../../client/common/types'; suite('Debugging - Outdated Debugger Prompt tests.', () => { let promptFactory: OutdatedDebuggerPromptFactory; - let appShell: IApplicationShell; - let browserService: IBrowserService; + let showInformationMessageStub: sinon.SinonStub; + let browserLaunchStub: sinon.SinonStub; const ptvsdOutputEvent: DebugProtocol.OutputEvent = { seq: 1, @@ -42,12 +42,14 @@ suite('Debugging - Outdated Debugger Prompt tests.', () => { experiments: { enabled: true }, } as any) as IPythonSettings); - appShell = mock(ApplicationShell); - browserService = mock(BrowserService); - promptFactory = new OutdatedDebuggerPromptFactory(instance(appShell), instance(browserService)); + showInformationMessageStub = sinon.stub(common, 'showInformationMessage'); + browserLaunchStub = sinon.stub(browser, 'launch'); + + promptFactory = new OutdatedDebuggerPromptFactory(); }); teardown(() => { + sinon.restore(); clearTelemetryReporter(); }); @@ -67,33 +69,38 @@ suite('Debugging - Outdated Debugger Prompt tests.', () => { }; } - test('Show prompt when attaching to ptvsd, more info is NOT clicked', async () => { - when(appShell.showInformationMessage(anything(), anything())).thenReturn(Promise.resolve(undefined)); - + test.only('Show prompt when attaching to ptvsd, more info is NOT clicked', async () => { + // when(appShell.showInformationMessage(anything(), anything())).thenReturn(Promise.resolve(undefined)); + showInformationMessageStub.returns(Promise.resolve(undefined)); const session = createSession(); const prompter = await promptFactory.createDebugAdapterTracker(session); if (prompter) { prompter.onDidSendMessage!(ptvsdOutputEvent); } - verify(browserService.launch(anyString())).never(); + browserLaunchStub.neverCalledWith(anyString()); + // First call should show info once - verify(appShell.showInformationMessage(anything(), anything())).once(); + + sinon.assert.calledOnce(showInformationMessageStub); assert(prompter); prompter!.onDidSendMessage!(ptvsdOutputEvent); // Can't use deferred promise here await sleep(1); - verify(browserService.launch(anyString())).never(); + browserLaunchStub.neverCalledWith(anyString()); // Second time it should not be called, so overall count is one. - verify(appShell.showInformationMessage(anything(), anything())).once(); + sinon.assert.calledOnce(showInformationMessageStub); }); test('Show prompt when attaching to ptvsd, more info is clicked', async () => { - when(appShell.showInformationMessage(anything(), anything())).thenReturn(Promise.resolve(Common.moreInfo)); + // when(appShell.showInformationMessage(anything(), anything())).thenReturn(Promise.resolve(Common.moreInfo)); + showInformationMessageStub.returns(Promise.resolve(Common.moreInfo)); + const deferred = createDeferred(); - when(browserService.launch(anything())).thenCall(() => deferred.resolve()); + // when(browserService.launch(anything())).thenCall(() => deferred.resolve()); + browserLaunchStub.callsFake(() => deferred.resolve()); const session = createSession(); const prompter = await promptFactory.createDebugAdapterTracker(session); @@ -102,22 +109,26 @@ suite('Debugging - Outdated Debugger Prompt tests.', () => { prompter!.onDidSendMessage!(ptvsdOutputEvent); await deferred.promise; - verify(browserService.launch(anything())).once(); + // verify(browserService.launch(anything())).once(); + sinon.assert.calledOnce(browserLaunchStub); + // First call should show info once - verify(appShell.showInformationMessage(anything(), anything())).once(); + // verify(appShell.showInformationMessage(anything(), anything())).once(); + sinon.assert.calledOnce(showInformationMessageStub); prompter!.onDidSendMessage!(ptvsdOutputEvent); // The second call does not go through the same path. So we just give enough time for the // operation to complete. await sleep(1); - verify(browserService.launch(anyString())).once(); + // verify(browserService.launch(anyString())).once(); // Second time it should not be called, so overall count is one. - verify(appShell.showInformationMessage(anything(), anything())).once(); + // verify(appShell.showInformationMessage(anything(), anything())).once(); }); test("Don't show prompt attaching to debugpy", async () => { - when(appShell.showInformationMessage(anything(), anything())).thenReturn(Promise.resolve(undefined)); + // when(appShell.showInformationMessage(anything(), anything())).thenReturn(Promise.resolve(undefined)); + showInformationMessageStub.returns(Promise.resolve(undefined)); const session = createSession(); const prompter = await promptFactory.createDebugAdapterTracker(session); @@ -127,7 +138,7 @@ suite('Debugging - Outdated Debugger Prompt tests.', () => { // Can't use deferred promise here await sleep(1); - verify(appShell.showInformationMessage(anything(), anything())).never(); + // verify(appShell.showInformationMessage(anything(), anything())).never(); }); const someRequest: DebugProtocol.RunInTerminalRequest = { @@ -155,7 +166,8 @@ suite('Debugging - Outdated Debugger Prompt tests.', () => { [someRequest, someEvent, someOutputEvent].forEach((message) => { test(`Don't show prompt when non-telemetry events are seen: ${JSON.stringify(message)}`, async () => { - when(appShell.showInformationMessage(anything(), anything())).thenReturn(Promise.resolve(undefined)); + // when(appShell.showInformationMessage(anything(), anything())).thenReturn(Promise.resolve(undefined)); + showInformationMessageStub.returns(Promise.resolve(undefined)); const session = createSession(); const prompter = await promptFactory.createDebugAdapterTracker(session); @@ -165,7 +177,7 @@ suite('Debugging - Outdated Debugger Prompt tests.', () => { // Can't use deferred promise here await sleep(1); - verify(appShell.showInformationMessage(anything(), anything())).never(); + // verify(appShell.showInformationMessage(anything(), anything())).never(); }); }); }); From 6c7f8d5bb900a5670a33e31a1eced283e1be87a6 Mon Sep 17 00:00:00 2001 From: Paula Camargo Date: Mon, 24 Oct 2022 17:30:55 -0700 Subject: [PATCH 03/10] Fix outdatedDebuggerPrompt tests --- .../outdatedDebuggerPrompt.unit.test.ts | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts b/src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts index 82c832fce680..630579e858e5 100644 --- a/src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts +++ b/src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts @@ -5,7 +5,7 @@ import * as assert from 'assert'; import * as sinon from 'sinon'; -import { anyString, mock, when } from 'ts-mockito'; +import { anyString, anything, mock, when } from 'ts-mockito'; import { DebugSession, WorkspaceFolder } from 'vscode'; import { DebugProtocol } from 'vscode-debugprotocol'; import { ConfigurationService } from '../../../../client/common/configuration/service'; @@ -69,7 +69,7 @@ suite('Debugging - Outdated Debugger Prompt tests.', () => { }; } - test.only('Show prompt when attaching to ptvsd, more info is NOT clicked', async () => { + test('Show prompt when attaching to ptvsd, more info is NOT clicked', async () => { // when(appShell.showInformationMessage(anything(), anything())).thenReturn(Promise.resolve(undefined)); showInformationMessageStub.returns(Promise.resolve(undefined)); const session = createSession(); @@ -95,12 +95,13 @@ suite('Debugging - Outdated Debugger Prompt tests.', () => { }); test('Show prompt when attaching to ptvsd, more info is clicked', async () => { - // when(appShell.showInformationMessage(anything(), anything())).thenReturn(Promise.resolve(Common.moreInfo)); showInformationMessageStub.returns(Promise.resolve(Common.moreInfo)); const deferred = createDeferred(); - // when(browserService.launch(anything())).thenCall(() => deferred.resolve()); browserLaunchStub.callsFake(() => deferred.resolve()); + browserLaunchStub.onCall(1).callsFake(() => { + return new Promise(() => deferred.resolve()); + }); const session = createSession(); const prompter = await promptFactory.createDebugAdapterTracker(session); @@ -109,11 +110,9 @@ suite('Debugging - Outdated Debugger Prompt tests.', () => { prompter!.onDidSendMessage!(ptvsdOutputEvent); await deferred.promise; - // verify(browserService.launch(anything())).once(); sinon.assert.calledOnce(browserLaunchStub); // First call should show info once - // verify(appShell.showInformationMessage(anything(), anything())).once(); sinon.assert.calledOnce(showInformationMessageStub); prompter!.onDidSendMessage!(ptvsdOutputEvent); @@ -121,13 +120,14 @@ suite('Debugging - Outdated Debugger Prompt tests.', () => { // operation to complete. await sleep(1); - // verify(browserService.launch(anyString())).once(); + sinon.assert.calledOnce(browserLaunchStub); + // Second time it should not be called, so overall count is one. // verify(appShell.showInformationMessage(anything(), anything())).once(); + sinon.assert.calledOnce(showInformationMessageStub); }); test("Don't show prompt attaching to debugpy", async () => { - // when(appShell.showInformationMessage(anything(), anything())).thenReturn(Promise.resolve(undefined)); showInformationMessageStub.returns(Promise.resolve(undefined)); const session = createSession(); @@ -138,7 +138,7 @@ suite('Debugging - Outdated Debugger Prompt tests.', () => { // Can't use deferred promise here await sleep(1); - // verify(appShell.showInformationMessage(anything(), anything())).never(); + showInformationMessageStub.neverCalledWith(anything(), anything()); }); const someRequest: DebugProtocol.RunInTerminalRequest = { @@ -166,7 +166,6 @@ suite('Debugging - Outdated Debugger Prompt tests.', () => { [someRequest, someEvent, someOutputEvent].forEach((message) => { test(`Don't show prompt when non-telemetry events are seen: ${JSON.stringify(message)}`, async () => { - // when(appShell.showInformationMessage(anything(), anything())).thenReturn(Promise.resolve(undefined)); showInformationMessageStub.returns(Promise.resolve(undefined)); const session = createSession(); @@ -177,7 +176,7 @@ suite('Debugging - Outdated Debugger Prompt tests.', () => { // Can't use deferred promise here await sleep(1); - // verify(appShell.showInformationMessage(anything(), anything())).never(); + showInformationMessageStub.neverCalledWith(anything(), anything()); }); }); }); From 7cce59c4ffdc204dd59798aef6248edb5aea7fd4 Mon Sep 17 00:00:00 2001 From: Paula Camargo Date: Mon, 24 Oct 2022 17:45:12 -0700 Subject: [PATCH 04/10] Fix factory test --- src/client/debugger/extension/adapter/factory.ts | 3 ++- .../debugger/extension/configuration/utils/common.ts | 4 ++++ .../debugger/extension/adapter/factory.unit.test.ts | 12 ++++++------ .../adapter/outdatedDebuggerPrompt.unit.test.ts | 2 -- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/client/debugger/extension/adapter/factory.ts b/src/client/debugger/extension/adapter/factory.ts index d27b47343bcd..13974ac2b9bf 100644 --- a/src/client/debugger/extension/adapter/factory.ts +++ b/src/client/debugger/extension/adapter/factory.ts @@ -22,6 +22,7 @@ import { EventName } from '../../../telemetry/constants'; import { AttachRequestArguments, LaunchRequestArguments } from '../../types'; import { IDebugAdapterDescriptorFactory } from '../types'; import * as nls from 'vscode-nls'; +import { showErrorMessage } from '../configuration/utils/common'; const localize: nls.LocalizeFunc = nls.loadMessageBundle(); @@ -158,7 +159,7 @@ export class DebugAdapterDescriptorFactory implements IDebugAdapterDescriptorFac * @memberof DebugAdapterDescriptorFactory */ private async notifySelectInterpreter() { - await window.showErrorMessage( + await showErrorMessage( localize('interpreterError', 'Please install Python or select a Python Interpreter to use the debugger.'), ); } diff --git a/src/client/debugger/extension/configuration/utils/common.ts b/src/client/debugger/extension/configuration/utils/common.ts index 1f2d21846247..16b23d6cb51a 100644 --- a/src/client/debugger/extension/configuration/utils/common.ts +++ b/src/client/debugger/extension/configuration/utils/common.ts @@ -50,3 +50,7 @@ export function getActiveTextEditor(): TextEditor | undefined { export function showInformationMessage(message: string, ...items: string[]): Thenable { return window.showInformationMessage(message, ...items); } + +export function showErrorMessage(message: string, ...items: string[]): Thenable { + return window.showErrorMessage(message, ...items); +} diff --git a/src/test/debugger/extension/adapter/factory.unit.test.ts b/src/test/debugger/extension/adapter/factory.unit.test.ts index d6b9b9a8fd15..cebb1e49e1bf 100644 --- a/src/test/debugger/extension/adapter/factory.unit.test.ts +++ b/src/test/debugger/extension/adapter/factory.unit.test.ts @@ -7,13 +7,11 @@ import * as assert from 'assert'; import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; import * as path from 'path'; - +import * as sinon from 'sinon'; import rewiremock from 'rewiremock'; import { SemVer } from 'semver'; import { anyString, anything, instance, mock, verify, when } from 'ts-mockito'; import { DebugAdapterExecutable, DebugAdapterServer, DebugConfiguration, DebugSession, WorkspaceFolder } from 'vscode'; -import { ApplicationShell } from '../../../../client/common/application/applicationShell'; -import { IApplicationShell } from '../../../../client/common/application/types'; import { ConfigurationService } from '../../../../client/common/configuration/service'; import { IPythonSettings } from '../../../../client/common/types'; import { Architecture } from '../../../../client/common/utils/platform'; @@ -25,13 +23,14 @@ import { InterpreterService } from '../../../../client/interpreter/interpreterSe import { EnvironmentType } from '../../../../client/pythonEnvironments/info'; import { clearTelemetryReporter } from '../../../../client/telemetry'; import { EventName } from '../../../../client/telemetry/constants'; +import * as common from '../../../../client/debugger/extension/configuration/utils/common'; use(chaiAsPromised); suite('Debugging - Adapter Factory', () => { let factory: IDebugAdapterDescriptorFactory; let interpreterService: IInterpreterService; - let appShell: IApplicationShell; + let showErrorMessageStub: sinon.SinonStub; const nodeExecutable = undefined; const debugAdapterPath = path.join(EXTENSION_ROOT_DIR, 'pythonFiles', 'lib', 'python', 'debugpy', 'adapter'); @@ -63,6 +62,7 @@ suite('Debugging - Adapter Factory', () => { process.env.VSC_PYTHON_CI_TEST = undefined; rewiremock.enable(); rewiremock('@vscode/extension-telemetry').with({ default: Reporter }); + showErrorMessageStub = sinon.stub(common, 'showErrorMessage'); const configurationService = mock(ConfigurationService); when(configurationService.getSettings(undefined)).thenReturn(({ @@ -70,7 +70,6 @@ suite('Debugging - Adapter Factory', () => { } as any) as IPythonSettings); interpreterService = mock(InterpreterService); - appShell = mock(ApplicationShell); when(interpreterService.getInterpreterDetails(pythonPath)).thenResolve(interpreter); when(interpreterService.getInterpreters(anything())).thenReturn([interpreter]); @@ -86,6 +85,7 @@ suite('Debugging - Adapter Factory', () => { Reporter.measures = []; rewiremock.disable(); clearTelemetryReporter(); + sinon.restore(); }); function createSession(config: Partial, workspaceFolder?: WorkspaceFolder): DebugSession { @@ -136,7 +136,7 @@ suite('Debugging - Adapter Factory', () => { const promise = factory.createDebugAdapterDescriptor(session, nodeExecutable); await expect(promise).to.eventually.be.rejectedWith('Debug Adapter Executable not provided'); - verify(appShell.showErrorMessage(anyString())).once(); + sinon.assert.calledOnce(showErrorMessageStub); }); test('Return Debug Adapter server if request is "attach", and port is specified directly', async () => { diff --git a/src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts b/src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts index 630579e858e5..36bfccc206a0 100644 --- a/src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts +++ b/src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts @@ -70,7 +70,6 @@ suite('Debugging - Outdated Debugger Prompt tests.', () => { } test('Show prompt when attaching to ptvsd, more info is NOT clicked', async () => { - // when(appShell.showInformationMessage(anything(), anything())).thenReturn(Promise.resolve(undefined)); showInformationMessageStub.returns(Promise.resolve(undefined)); const session = createSession(); const prompter = await promptFactory.createDebugAdapterTracker(session); @@ -123,7 +122,6 @@ suite('Debugging - Outdated Debugger Prompt tests.', () => { sinon.assert.calledOnce(browserLaunchStub); // Second time it should not be called, so overall count is one. - // verify(appShell.showInformationMessage(anything(), anything())).once(); sinon.assert.calledOnce(showInformationMessageStub); }); From 50fee394483e055cad76b62f446075a68533c7c3 Mon Sep 17 00:00:00 2001 From: Paula Camargo Date: Mon, 24 Oct 2022 17:48:10 -0700 Subject: [PATCH 05/10] fix linting --- .vscode/launch.json | 2 +- src/test/debugger/extension/adapter/factory.unit.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 7b654703dbd8..303524f15580 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -155,7 +155,7 @@ "stopOnEntry": false, "sourceMaps": true, "args": [ - "./out/test/**/*.unit.test.js", + "./out/test/**/factory.unit.test.js", "--require=out/test/unittests.js", "--ui=tdd", "--recursive", diff --git a/src/test/debugger/extension/adapter/factory.unit.test.ts b/src/test/debugger/extension/adapter/factory.unit.test.ts index cebb1e49e1bf..ad3ba1762bf5 100644 --- a/src/test/debugger/extension/adapter/factory.unit.test.ts +++ b/src/test/debugger/extension/adapter/factory.unit.test.ts @@ -10,7 +10,7 @@ import * as path from 'path'; import * as sinon from 'sinon'; import rewiremock from 'rewiremock'; import { SemVer } from 'semver'; -import { anyString, anything, instance, mock, verify, when } from 'ts-mockito'; +import { anything, instance, mock, verify, when } from 'ts-mockito'; import { DebugAdapterExecutable, DebugAdapterServer, DebugConfiguration, DebugSession, WorkspaceFolder } from 'vscode'; import { ConfigurationService } from '../../../../client/common/configuration/service'; import { IPythonSettings } from '../../../../client/common/types'; From 00ea523881805f7f88699c0be6a7f866996afb03 Mon Sep 17 00:00:00 2001 From: Paula Camargo Date: Mon, 24 Oct 2022 17:50:19 -0700 Subject: [PATCH 06/10] Fix code lint --- .vscode/launch.json | 2 +- src/client/debugger/extension/adapter/factory.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 303524f15580..7b654703dbd8 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -155,7 +155,7 @@ "stopOnEntry": false, "sourceMaps": true, "args": [ - "./out/test/**/factory.unit.test.js", + "./out/test/**/*.unit.test.js", "--require=out/test/unittests.js", "--ui=tdd", "--recursive", diff --git a/src/client/debugger/extension/adapter/factory.ts b/src/client/debugger/extension/adapter/factory.ts index 13974ac2b9bf..06b8a80d004e 100644 --- a/src/client/debugger/extension/adapter/factory.ts +++ b/src/client/debugger/extension/adapter/factory.ts @@ -10,7 +10,6 @@ import { DebugAdapterExecutable, DebugAdapterServer, DebugSession, - window, WorkspaceFolder, } from 'vscode'; import { EXTENSION_ROOT_DIR } from '../../../constants'; From a9e6d1120622c1a4f5b8ccb71409b97f5503521e Mon Sep 17 00:00:00 2001 From: Paula Camargo Date: Wed, 2 Nov 2022 01:59:39 -0700 Subject: [PATCH 07/10] Fix tests --- .../debugger/extension/adapter/outdatedDebuggerPrompt.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts b/src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts index 636c8d155b1d..9f08649464b3 100644 --- a/src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts +++ b/src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts @@ -2,7 +2,7 @@ // Licensed under the MIT License. 'use strict'; - +import { injectable } from 'inversify'; import { DebugAdapterTracker, DebugAdapterTrackerFactory, DebugSession, ProviderResult } from 'vscode'; import { DebugProtocol } from 'vscode-debugprotocol'; import { Common, OutdatedDebugger } from '../../../common/utils/localize'; @@ -61,6 +61,7 @@ class OutdatedDebuggerPromptState implements IPromptShowState { } } +@injectable() export class OutdatedDebuggerPromptFactory implements DebugAdapterTrackerFactory { private readonly promptCheck: OutdatedDebuggerPromptState; constructor() { From aed1bf4f75105333dc4973dd1b88527a069b3610 Mon Sep 17 00:00:00 2001 From: Paula Camargo Date: Fri, 4 Nov 2022 13:17:32 -0700 Subject: [PATCH 08/10] Use functions in windowApis --- src/client/debugger/extension/adapter/factory.ts | 2 +- .../debugger/extension/adapter/outdatedDebuggerPrompt.ts | 2 +- .../debugger/extension/configuration/utils/common.ts | 8 -------- src/test/debugger/extension/adapter/factory.unit.test.ts | 4 ++-- .../extension/adapter/outdatedDebuggerPrompt.unit.test.ts | 4 ++-- 5 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/client/debugger/extension/adapter/factory.ts b/src/client/debugger/extension/adapter/factory.ts index 06b8a80d004e..1a84b73f2003 100644 --- a/src/client/debugger/extension/adapter/factory.ts +++ b/src/client/debugger/extension/adapter/factory.ts @@ -21,7 +21,7 @@ import { EventName } from '../../../telemetry/constants'; import { AttachRequestArguments, LaunchRequestArguments } from '../../types'; import { IDebugAdapterDescriptorFactory } from '../types'; import * as nls from 'vscode-nls'; -import { showErrorMessage } from '../configuration/utils/common'; +import { showErrorMessage } from '../../../common/vscodeApis/windowApis'; const localize: nls.LocalizeFunc = nls.loadMessageBundle(); diff --git a/src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts b/src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts index 9f08649464b3..ed85093ea264 100644 --- a/src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts +++ b/src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts @@ -6,7 +6,7 @@ import { injectable } from 'inversify'; import { DebugAdapterTracker, DebugAdapterTrackerFactory, DebugSession, ProviderResult } from 'vscode'; import { DebugProtocol } from 'vscode-debugprotocol'; import { Common, OutdatedDebugger } from '../../../common/utils/localize'; -import { showInformationMessage } from '../configuration/utils/common'; +import { showInformationMessage } from '../../../common/vscodeApis/windowApis'; import { launch } from './browser'; import { IPromptShowState } from './types'; diff --git a/src/client/debugger/extension/configuration/utils/common.ts b/src/client/debugger/extension/configuration/utils/common.ts index 16b23d6cb51a..36572419908f 100644 --- a/src/client/debugger/extension/configuration/utils/common.ts +++ b/src/client/debugger/extension/configuration/utils/common.ts @@ -46,11 +46,3 @@ export function getActiveTextEditor(): TextEditor | undefined { const { activeTextEditor } = window; return activeTextEditor; } - -export function showInformationMessage(message: string, ...items: string[]): Thenable { - return window.showInformationMessage(message, ...items); -} - -export function showErrorMessage(message: string, ...items: string[]): Thenable { - return window.showErrorMessage(message, ...items); -} diff --git a/src/test/debugger/extension/adapter/factory.unit.test.ts b/src/test/debugger/extension/adapter/factory.unit.test.ts index ad3ba1762bf5..9686588b96d3 100644 --- a/src/test/debugger/extension/adapter/factory.unit.test.ts +++ b/src/test/debugger/extension/adapter/factory.unit.test.ts @@ -23,7 +23,7 @@ import { InterpreterService } from '../../../../client/interpreter/interpreterSe import { EnvironmentType } from '../../../../client/pythonEnvironments/info'; import { clearTelemetryReporter } from '../../../../client/telemetry'; import { EventName } from '../../../../client/telemetry/constants'; -import * as common from '../../../../client/debugger/extension/configuration/utils/common'; +import * as windowApis from '../../../../client/common/vscodeApis/windowApis'; use(chaiAsPromised); @@ -62,7 +62,7 @@ suite('Debugging - Adapter Factory', () => { process.env.VSC_PYTHON_CI_TEST = undefined; rewiremock.enable(); rewiremock('@vscode/extension-telemetry').with({ default: Reporter }); - showErrorMessageStub = sinon.stub(common, 'showErrorMessage'); + showErrorMessageStub = sinon.stub(windowApis, 'showErrorMessage'); const configurationService = mock(ConfigurationService); when(configurationService.getSettings(undefined)).thenReturn(({ diff --git a/src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts b/src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts index 36bfccc206a0..a0d2c004a5db 100644 --- a/src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts +++ b/src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts @@ -14,7 +14,7 @@ import { Common } from '../../../../client/common/utils/localize'; import { OutdatedDebuggerPromptFactory } from '../../../../client/debugger/extension/adapter/outdatedDebuggerPrompt'; import { clearTelemetryReporter } from '../../../../client/telemetry'; import * as browser from '../../../../client/debugger/extension/adapter/browser'; -import * as common from '../../../../client/debugger/extension/configuration/utils/common'; +import * as windowApis from '../../../../client/common/vscodeApis/windowApis'; import { IPythonSettings } from '../../../../client/common/types'; suite('Debugging - Outdated Debugger Prompt tests.', () => { @@ -42,7 +42,7 @@ suite('Debugging - Outdated Debugger Prompt tests.', () => { experiments: { enabled: true }, } as any) as IPythonSettings); - showInformationMessageStub = sinon.stub(common, 'showInformationMessage'); + showInformationMessageStub = sinon.stub(windowApis, 'showInformationMessage'); browserLaunchStub = sinon.stub(browser, 'launch'); promptFactory = new OutdatedDebuggerPromptFactory(); From ca7d0f696ded5332ac737caaa138ddc3656a1799 Mon Sep 17 00:00:00 2001 From: Paula Camargo Date: Fri, 4 Nov 2022 13:44:44 -0700 Subject: [PATCH 09/10] Move browser to vscodeApis --- .../adapter/browser.ts => common/vscodeApis/browserApis.ts} | 0 .../debugger/extension/adapter/outdatedDebuggerPrompt.ts | 2 +- .../extension/adapter/outdatedDebuggerPrompt.unit.test.ts | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) rename src/client/{debugger/extension/adapter/browser.ts => common/vscodeApis/browserApis.ts} (100%) diff --git a/src/client/debugger/extension/adapter/browser.ts b/src/client/common/vscodeApis/browserApis.ts similarity index 100% rename from src/client/debugger/extension/adapter/browser.ts rename to src/client/common/vscodeApis/browserApis.ts diff --git a/src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts b/src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts index ed85093ea264..8485bd0ff7e1 100644 --- a/src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts +++ b/src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts @@ -6,8 +6,8 @@ import { injectable } from 'inversify'; import { DebugAdapterTracker, DebugAdapterTrackerFactory, DebugSession, ProviderResult } from 'vscode'; import { DebugProtocol } from 'vscode-debugprotocol'; import { Common, OutdatedDebugger } from '../../../common/utils/localize'; +import { launch } from '../../../common/vscodeApis/browserAPIS'; import { showInformationMessage } from '../../../common/vscodeApis/windowApis'; -import { launch } from './browser'; import { IPromptShowState } from './types'; // This situation occurs when user connects to old containers or server where diff --git a/src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts b/src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts index a0d2c004a5db..0ab094119a5c 100644 --- a/src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts +++ b/src/test/debugger/extension/adapter/outdatedDebuggerPrompt.unit.test.ts @@ -13,7 +13,7 @@ import { createDeferred, sleep } from '../../../../client/common/utils/async'; import { Common } from '../../../../client/common/utils/localize'; import { OutdatedDebuggerPromptFactory } from '../../../../client/debugger/extension/adapter/outdatedDebuggerPrompt'; import { clearTelemetryReporter } from '../../../../client/telemetry'; -import * as browser from '../../../../client/debugger/extension/adapter/browser'; +import * as browserApis from '../../../../client/common/vscodeApis/browserApis'; import * as windowApis from '../../../../client/common/vscodeApis/windowApis'; import { IPythonSettings } from '../../../../client/common/types'; @@ -43,7 +43,7 @@ suite('Debugging - Outdated Debugger Prompt tests.', () => { } as any) as IPythonSettings); showInformationMessageStub = sinon.stub(windowApis, 'showInformationMessage'); - browserLaunchStub = sinon.stub(browser, 'launch'); + browserLaunchStub = sinon.stub(browserApis, 'launch'); promptFactory = new OutdatedDebuggerPromptFactory(); }); From 5e4d5708b7d769f1fdbf25cab2f5210c9d70c67e Mon Sep 17 00:00:00 2001 From: Paula Camargo Date: Fri, 4 Nov 2022 14:01:58 -0700 Subject: [PATCH 10/10] Fix import --- src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts b/src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts index 8485bd0ff7e1..04117e9838d1 100644 --- a/src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts +++ b/src/client/debugger/extension/adapter/outdatedDebuggerPrompt.ts @@ -6,7 +6,7 @@ import { injectable } from 'inversify'; import { DebugAdapterTracker, DebugAdapterTrackerFactory, DebugSession, ProviderResult } from 'vscode'; import { DebugProtocol } from 'vscode-debugprotocol'; import { Common, OutdatedDebugger } from '../../../common/utils/localize'; -import { launch } from '../../../common/vscodeApis/browserAPIS'; +import { launch } from '../../../common/vscodeApis/browserApis'; import { showInformationMessage } from '../../../common/vscodeApis/windowApis'; import { IPromptShowState } from './types';