diff --git a/src/connectionController.ts b/src/connectionController.ts index 4b4515b8a..ddedadc4d 100644 --- a/src/connectionController.ts +++ b/src/connectionController.ts @@ -788,6 +788,10 @@ export default class ConnectionController { this.eventEmitter.removeListener(eventType, listener); } + deactivate() { + this.eventEmitter.removeAllListeners(); + } + closeConnectionStringInput() { this._connectionStringInputCancellationToken?.cancel(); } diff --git a/src/editors/activeConnectionCodeLensProvider.ts b/src/editors/activeConnectionCodeLensProvider.ts index 62f227687..046b335eb 100644 --- a/src/editors/activeConnectionCodeLensProvider.ts +++ b/src/editors/activeConnectionCodeLensProvider.ts @@ -1,9 +1,10 @@ import * as vscode from 'vscode'; -import type { TextEditor } from 'vscode'; + import EXTENSION_COMMANDS from '../commands'; import type ConnectionController from '../connectionController'; import { isPlayground } from '../utils/playground'; import { getDBFromConnectionString } from '../utils/connection-string-db'; +import { DataServiceEventTypes } from '../connectionController'; export default class ActiveConnectionCodeLensProvider implements vscode.CodeLensProvider @@ -11,35 +12,29 @@ export default class ActiveConnectionCodeLensProvider _connectionController: ConnectionController; _onDidChangeCodeLenses: vscode.EventEmitter = new vscode.EventEmitter(); - activeTextEditor?: TextEditor; + _activeConnectionChangedHandler: () => void; readonly onDidChangeCodeLenses: vscode.Event = this._onDidChangeCodeLenses.event; constructor(connectionController: ConnectionController) { this._connectionController = connectionController; - this.activeTextEditor = vscode.window.activeTextEditor; vscode.workspace.onDidChangeConfiguration(() => { this._onDidChangeCodeLenses.fire(); }); - } - - setActiveTextEditor(activeTextEditor?: TextEditor) { - this.activeTextEditor = activeTextEditor; - this._onDidChangeCodeLenses.fire(); - } - - refresh(): void { - this._onDidChangeCodeLenses.fire(); - } - isPlayground(): boolean { - return isPlayground(this.activeTextEditor?.document.uri); + this._activeConnectionChangedHandler = () => { + this._onDidChangeCodeLenses.fire(); + }; + this._connectionController.addEventListener( + DataServiceEventTypes.ACTIVE_CONNECTION_CHANGED, + this._activeConnectionChangedHandler + ); } - provideCodeLenses(): vscode.CodeLens[] { - if (!this.isPlayground()) { + provideCodeLenses(document: vscode.TextDocument): vscode.CodeLens[] { + if (!isPlayground(document.uri)) { return []; } @@ -69,4 +64,11 @@ export default class ActiveConnectionCodeLensProvider return [codeLens]; } + + deactivate() { + this._connectionController.removeEventListener( + DataServiceEventTypes.ACTIVE_CONNECTION_CHANGED, + this._activeConnectionChangedHandler + ); + } } diff --git a/src/editors/playgroundController.ts b/src/editors/playgroundController.ts index 64b2594a3..4378e80b8 100644 --- a/src/editors/playgroundController.ts +++ b/src/editors/playgroundController.ts @@ -6,7 +6,6 @@ import vm from 'vm'; import os from 'os'; import transpiler from 'bson-transpilers'; -import type ActiveConnectionCodeLensProvider from './activeConnectionCodeLensProvider'; import type PlaygroundSelectedCodeActionProvider from './playgroundSelectedCodeActionProvider'; import type ConnectionController from '../connectionController'; import { DataServiceEventTypes } from '../connectionController'; @@ -127,11 +126,11 @@ export default class PlaygroundController { _isPartialRun = false; - private _activeConnectionCodeLensProvider: ActiveConnectionCodeLensProvider; private _playgroundResultViewColumn?: vscode.ViewColumn; private _playgroundResultTextDocument?: vscode.TextDocument; private _statusView: StatusView; private _playgroundResultViewProvider: PlaygroundResultProvider; + private _activeConnectionChangedHandler: () => void; private _codeToEvaluate = ''; @@ -141,7 +140,6 @@ export default class PlaygroundController { telemetryService, statusView, playgroundResultViewProvider, - activeConnectionCodeLensProvider, exportToLanguageCodeLensProvider, playgroundSelectedCodeActionProvider, }: { @@ -150,7 +148,6 @@ export default class PlaygroundController { telemetryService: TelemetryService; statusView: StatusView; playgroundResultViewProvider: PlaygroundResultProvider; - activeConnectionCodeLensProvider: ActiveConnectionCodeLensProvider; exportToLanguageCodeLensProvider: ExportToLanguageCodeLensProvider; playgroundSelectedCodeActionProvider: PlaygroundSelectedCodeActionProvider; }) { @@ -160,16 +157,16 @@ export default class PlaygroundController { this._telemetryService = telemetryService; this._statusView = statusView; this._playgroundResultViewProvider = playgroundResultViewProvider; - this._activeConnectionCodeLensProvider = activeConnectionCodeLensProvider; this._exportToLanguageCodeLensProvider = exportToLanguageCodeLensProvider; this._playgroundSelectedCodeActionProvider = playgroundSelectedCodeActionProvider; + this._activeConnectionChangedHandler = () => { + void this._activeConnectionChanged(); + }; this._connectionController.addEventListener( DataServiceEventTypes.ACTIVE_CONNECTION_CHANGED, - () => { - void this._activeConnectionChanged(); - } + this._activeConnectionChangedHandler ); const onDidChangeActiveTextEditor = ( @@ -189,9 +186,6 @@ export default class PlaygroundController { if (isPlaygroundEditor) { this._activeTextEditor = editor; - this._activeConnectionCodeLensProvider.setActiveTextEditor( - this._activeTextEditor - ); this._playgroundSelectedCodeActionProvider.setActiveTextEditor( this._activeTextEditor ); @@ -270,8 +264,6 @@ export default class PlaygroundController { const connectionId = this._connectionController.getActiveConnectionId(); let mongoClientOption; - this._activeConnectionCodeLensProvider.refresh(); - if (dataService && connectionId) { mongoClientOption = this._connectionController.getMongoClientConnectionOptions(); @@ -893,9 +885,7 @@ export default class PlaygroundController { deactivate(): void { this._connectionController.removeEventListener( DataServiceEventTypes.ACTIVE_CONNECTION_CHANGED, - () => { - // No action is required after removing the listener. - } + this._activeConnectionChangedHandler ); } } diff --git a/src/mdbExtensionController.ts b/src/mdbExtensionController.ts index 2a6391f25..f49ee48d4 100644 --- a/src/mdbExtensionController.ts +++ b/src/mdbExtensionController.ts @@ -113,7 +113,6 @@ export default class MDBExtensionController implements vscode.Disposable { telemetryService: this._telemetryService, statusView: this._statusView, playgroundResultViewProvider: this._playgroundResultViewProvider, - activeConnectionCodeLensProvider: this._activeConnectionCodeLensProvider, exportToLanguageCodeLensProvider: this._exportToLanguageCodeLensProvider, playgroundSelectedCodeActionProvider: this._playgroundSelectedCodeActionProvider, @@ -878,5 +877,7 @@ export default class MDBExtensionController implements vscode.Disposable { this._telemetryService.deactivate(); this._editorsController.deactivate(); this._webviewController.deactivate(); + this._activeConnectionCodeLensProvider.deactivate(); + this._connectionController.deactivate(); } } diff --git a/src/test/suite/editors/activeConnectionCodeLensProvider.test.ts b/src/test/suite/editors/activeConnectionCodeLensProvider.test.ts index 827c928f7..0af23e134 100644 --- a/src/test/suite/editors/activeConnectionCodeLensProvider.test.ts +++ b/src/test/suite/editors/activeConnectionCodeLensProvider.test.ts @@ -1,8 +1,9 @@ import * as vscode from 'vscode'; import { beforeEach, afterEach } from 'mocha'; -import chai from 'chai'; +import { expect } from 'chai'; import sinon from 'sinon'; import type { DataService } from 'mongodb-data-service'; +import path from 'path'; import ActiveConnectionCodeLensProvider from '../../../editors/activeConnectionCodeLensProvider'; import ConnectionController from '../../../connectionController'; @@ -12,8 +13,6 @@ import { ExtensionContextStub } from '../stubs'; import TelemetryService from '../../../telemetry/telemetryService'; import { TEST_DATABASE_URI } from '../dbTestHelper'; -const expect = chai.expect; - suite('Active Connection CodeLens Provider Test Suite', () => { const extensionContextStub = new ExtensionContextStub(); const testStorageController = new StorageController(extensionContextStub); @@ -42,19 +41,23 @@ suite('Active Connection CodeLens Provider Test Suite', () => { }); suite('the MongoDB playground in JS', () => { + const mockFileName = path.join('nonexistent', 'playground-test.mongodb.js'); + const mockDocumentUri = vscode.Uri.from({ + path: mockFileName, + scheme: 'untitled', + }); + const mockTextDoc: vscode.TextDocument = { + uri: mockDocumentUri, + } as Pick as vscode.TextDocument; + suite('user is not connected', () => { beforeEach(() => { - testCodeLensProvider.setActiveTextEditor( - vscode.window.activeTextEditor - ); const fakeShowQuickPick = sandbox.fake(); sandbox.replace(vscode.window, 'showQuickPick', fakeShowQuickPick); - const fakeIsPlayground = sandbox.fake.returns(true); - sandbox.replace(testCodeLensProvider, 'isPlayground', fakeIsPlayground); }); test('show disconnected message in code lenses', () => { - const codeLens = testCodeLensProvider.provideCodeLenses(); + const codeLens = testCodeLensProvider.provideCodeLenses(mockTextDoc); expect(codeLens).to.be.an('array'); expect(codeLens.length).to.be.equal(1); @@ -89,16 +92,11 @@ suite('Active Connection CodeLens Provider Test Suite', () => { } as unknown as DataService; testConnectionController.setActiveDataService(activeDataServiceStub); - testCodeLensProvider.setActiveTextEditor( - vscode.window.activeTextEditor - ); sandbox.replace( testConnectionController, 'getActiveConnectionName', sandbox.fake.returns('fakeName') ); - const fakeIsPlayground = sandbox.fake.returns(true); - sandbox.replace(testCodeLensProvider, 'isPlayground', fakeIsPlayground); }); test('show active connection in code lenses', () => { @@ -109,7 +107,7 @@ suite('Active Connection CodeLens Provider Test Suite', () => { url: TEST_DATABASE_URI, }) ); - const codeLens = testCodeLensProvider.provideCodeLenses(); + const codeLens = testCodeLensProvider.provideCodeLenses(mockTextDoc); expect(codeLens).to.be.an('array'); expect(codeLens.length).to.be.equal(1); @@ -131,7 +129,7 @@ suite('Active Connection CodeLens Provider Test Suite', () => { url: `${TEST_DATABASE_URI}/fakeDBName`, }) ); - const codeLens = testCodeLensProvider.provideCodeLenses(); + const codeLens = testCodeLensProvider.provideCodeLenses(mockTextDoc); expect(codeLens).to.be.an('array'); expect(codeLens.length).to.be.equal(1); expect(codeLens[0].command?.title).to.be.equal( @@ -147,16 +145,23 @@ suite('Active Connection CodeLens Provider Test Suite', () => { }); suite('the regular JS file', () => { + const mockFileName = path.join('nonexistent', 'playground-test.js'); + const mockDocumentUri = vscode.Uri.from({ + path: mockFileName, + scheme: 'untitled', + }); + const mockTextDoc: vscode.TextDocument = { + uri: mockDocumentUri, + } as Pick as vscode.TextDocument; + suite('user is not connected', () => { beforeEach(() => { const fakeShowQuickPick = sandbox.fake(); sandbox.replace(vscode.window, 'showQuickPick', fakeShowQuickPick); - const fakeIsPlayground = sandbox.fake.returns(false); - sandbox.replace(testCodeLensProvider, 'isPlayground', fakeIsPlayground); }); test('show not show the active connection code lenses', () => { - const codeLens = testCodeLensProvider.provideCodeLenses(); + const codeLens = testCodeLensProvider.provideCodeLenses(mockTextDoc); expect(codeLens).to.be.an('array'); expect(codeLens.length).to.be.equal(0); @@ -191,12 +196,10 @@ suite('Active Connection CodeLens Provider Test Suite', () => { 'getActiveConnectionName', sandbox.fake.returns('fakeName') ); - const fakeIsPlayground = sandbox.fake.returns(false); - sandbox.replace(testCodeLensProvider, 'isPlayground', fakeIsPlayground); }); - test('show not show the active connection code lensess', () => { - const codeLens = testCodeLensProvider.provideCodeLenses(); + test('show not show the active connection code lenses', () => { + const codeLens = testCodeLensProvider.provideCodeLenses(mockTextDoc); expect(codeLens).to.be.an('array'); expect(codeLens.length).to.be.equal(0); diff --git a/src/test/suite/editors/playgroundController.test.ts b/src/test/suite/editors/playgroundController.test.ts index 14df23617..2a0e44e12 100644 --- a/src/test/suite/editors/playgroundController.test.ts +++ b/src/test/suite/editors/playgroundController.test.ts @@ -8,7 +8,6 @@ import { v4 as uuidv4 } from 'uuid'; import path from 'path'; import chaiAsPromised from 'chai-as-promised'; -import ActiveDBCodeLensProvider from '../../../editors/activeConnectionCodeLensProvider'; import PlaygroundSelectedCodeActionProvider from '../../../editors/playgroundSelectedCodeActionProvider'; import ConnectionController from '../../../connectionController'; import EditDocumentCodeLensProvider from '../../../editors/editDocumentCodeLensProvider'; @@ -50,7 +49,6 @@ suite('Playground Controller Test Suite', function () { let testConnectionController: ConnectionController; let testEditDocumentCodeLensProvider: EditDocumentCodeLensProvider; let testPlaygroundResultProvider: PlaygroundResultProvider; - let testActiveDBCodeLensProvider: ActiveDBCodeLensProvider; let testExportToLanguageCodeLensProvider: ExportToLanguageCodeLensProvider; let testCodeActionProvider: PlaygroundSelectedCodeActionProvider; let languageServerControllerStub: LanguageServerController; @@ -78,9 +76,6 @@ suite('Playground Controller Test Suite', function () { testConnectionController, testEditDocumentCodeLensProvider ); - testActiveDBCodeLensProvider = new ActiveDBCodeLensProvider( - testConnectionController - ); testExportToLanguageCodeLensProvider = new ExportToLanguageCodeLensProvider(); testCodeActionProvider = new PlaygroundSelectedCodeActionProvider(); @@ -95,7 +90,6 @@ suite('Playground Controller Test Suite', function () { telemetryService: testTelemetryService, statusView: testStatusView, playgroundResultViewProvider: testPlaygroundResultProvider, - activeConnectionCodeLensProvider: testActiveDBCodeLensProvider, exportToLanguageCodeLensProvider: testExportToLanguageCodeLensProvider, playgroundSelectedCodeActionProvider: testCodeActionProvider, }); @@ -350,7 +344,6 @@ suite('Playground Controller Test Suite', function () { telemetryService: testTelemetryService, statusView: testStatusView, playgroundResultViewProvider: testPlaygroundResultProvider, - activeConnectionCodeLensProvider: testActiveDBCodeLensProvider, exportToLanguageCodeLensProvider: testExportToLanguageCodeLensProvider, playgroundSelectedCodeActionProvider: testCodeActionProvider, @@ -368,7 +361,6 @@ suite('Playground Controller Test Suite', function () { telemetryService: testTelemetryService, statusView: testStatusView, playgroundResultViewProvider: testPlaygroundResultProvider, - activeConnectionCodeLensProvider: testActiveDBCodeLensProvider, exportToLanguageCodeLensProvider: testExportToLanguageCodeLensProvider, playgroundSelectedCodeActionProvider: testCodeActionProvider, diff --git a/src/test/suite/editors/playgroundSelectedCodeActionProvider.test.ts b/src/test/suite/editors/playgroundSelectedCodeActionProvider.test.ts index 1dea18fbd..735ce1a0b 100644 --- a/src/test/suite/editors/playgroundSelectedCodeActionProvider.test.ts +++ b/src/test/suite/editors/playgroundSelectedCodeActionProvider.test.ts @@ -3,7 +3,6 @@ import { beforeEach, afterEach } from 'mocha'; import chai from 'chai'; import sinon from 'sinon'; -import ActiveConnectionCodeLensProvider from '../../../editors/activeConnectionCodeLensProvider'; import ExportToLanguageCodeLensProvider from '../../../editors/exportToLanguageCodeLensProvider'; import PlaygroundSelectedCodeActionProvider from '../../../editors/playgroundSelectedCodeActionProvider'; import { LanguageServerController } from '../../../language'; @@ -50,10 +49,6 @@ suite('Playground Selected CodeAction Provider Test Suite', function () { TEST_DATABASE_URI ); - const activeConnectionCodeLensProvider = - new ActiveConnectionCodeLensProvider( - mdbTestExtension.testExtensionController._connectionController - ); const testExportToLanguageCodeLensProvider = new ExportToLanguageCodeLensProvider(); @@ -69,7 +64,6 @@ suite('Playground Selected CodeAction Provider Test Suite', function () { playgroundResultViewProvider: mdbTestExtension.testExtensionController ._playgroundResultViewProvider, - activeConnectionCodeLensProvider, exportToLanguageCodeLensProvider: testExportToLanguageCodeLensProvider, playgroundSelectedCodeActionProvider: testCodeActionProvider, diff --git a/src/test/suite/language/languageServerController.test.ts b/src/test/suite/language/languageServerController.test.ts index b34944301..87d09b17b 100644 --- a/src/test/suite/language/languageServerController.test.ts +++ b/src/test/suite/language/languageServerController.test.ts @@ -8,7 +8,6 @@ import type { SinonStub } from 'sinon'; import type { DataService } from 'mongodb-data-service'; import chaiAsPromised from 'chai-as-promised'; -import ActiveDBCodeLensProvider from '../../../editors/activeConnectionCodeLensProvider'; import PlaygroundSelectedCodeActionProvider from '../../../editors/playgroundSelectedCodeActionProvider'; import ConnectionController from '../../../connectionController'; import EditDocumentCodeLensProvider from '../../../editors/editDocumentCodeLensProvider'; @@ -51,9 +50,6 @@ suite('Language Server Controller Test Suite', () => { testConnectionController, testEditDocumentCodeLensProvider ); - const testActiveDBCodeLensProvider = new ActiveDBCodeLensProvider( - testConnectionController - ); const testExportToLanguageCodeLensProvider = new ExportToLanguageCodeLensProvider(); const testCodeActionProvider = new PlaygroundSelectedCodeActionProvider(); @@ -73,7 +69,6 @@ suite('Language Server Controller Test Suite', () => { telemetryService: testTelemetryService, statusView: testStatusView, playgroundResultViewProvider: testPlaygroundResultProvider, - activeConnectionCodeLensProvider: testActiveDBCodeLensProvider, exportToLanguageCodeLensProvider: testExportToLanguageCodeLensProvider, playgroundSelectedCodeActionProvider: testCodeActionProvider, }); diff --git a/src/test/suite/views/webview-app/overview-page.test.tsx b/src/test/suite/views/webview-app/overview-page.test.tsx index 27b9b2c05..459e2d75b 100644 --- a/src/test/suite/views/webview-app/overview-page.test.tsx +++ b/src/test/suite/views/webview-app/overview-page.test.tsx @@ -39,7 +39,9 @@ describe('OverviewPage test suite', function () { describe('Connection Form', function () { // Rendering the connection form takes ~4 seconds, so we need to increase the timeout. // Not sure on the cause of this slowdown, it could be animation based. - this.timeout(10000); + // Without this it's flaky on mac CI. + // TODO(COMPASS-7762): Once we update the connection form this may be able to go away. + this.timeout(25000); it('is able to open and close the new connection form', async function () { render();