diff --git a/src/editors/codeActionProvider.ts b/src/editors/codeActionProvider.ts new file mode 100644 index 000000000..b209ddbce --- /dev/null +++ b/src/editors/codeActionProvider.ts @@ -0,0 +1,29 @@ +import * as vscode from 'vscode'; +import EXTENSION_COMMANDS from '../commands'; +import PlaygroundController from './playgroundController'; + +export default class CodeActionProvider implements vscode.CodeActionProvider { + _playgroundController: PlaygroundController; + + static readonly providedCodeActionKinds = [vscode.CodeActionKind.QuickFix]; + + constructor(playgroundController: PlaygroundController) { + this._playgroundController = playgroundController; + } + + provideCodeActions(): vscode.CodeAction[] | undefined { + if (!this._playgroundController._selectedText) { + return; + } + + const commandAction = new vscode.CodeAction('Run selected playground blocks', vscode.CodeActionKind.Empty); + + commandAction.command = { + command: EXTENSION_COMMANDS.MDB_RUN_SELECTED_PLAYGROUND_BLOCKS, + title: 'Run selected playground blocks', + tooltip: 'Run selected playground blocks' + }; + + return [commandAction]; + } +} diff --git a/src/editors/editorsController.ts b/src/editors/editorsController.ts index 5ed2ea3e6..408e0c0fe 100644 --- a/src/editors/editorsController.ts +++ b/src/editors/editorsController.ts @@ -2,6 +2,7 @@ import * as vscode from 'vscode'; import { EJSON } from 'bson'; import ActiveConnectionCodeLensProvider from './activeConnectionCodeLensProvider'; +import CodeActionProvider from './codeActionProvider'; import ConnectionController from '../connectionController'; import CollectionDocumentsCodeLensProvider from './collectionDocumentsCodeLensProvider'; import CollectionDocumentsOperationsStore from './collectionDocumentsOperationsStore'; @@ -22,7 +23,6 @@ import MongoDBDocumentService, { DOCUMENT_SOURCE_URI_IDENTIFIER, VIEW_DOCUMENT_SCHEME } from './mongoDBDocumentService'; -import PartialExecutionCodeLensProvider from './partialExecutionCodeLensProvider'; import PlaygroundController from './playgroundController'; import PlaygroundResultProvider, { PLAYGROUND_RESULT_SCHEME @@ -37,6 +37,7 @@ const log = createLogger('editors controller'); * new editors and the data they need. It also manages active editors. */ export default class EditorsController { + _codeActionProvider: CodeActionProvider; _connectionController: ConnectionController; _playgroundController: PlaygroundController; _collectionDocumentsOperationsStore = new CollectionDocumentsOperationsStore(); @@ -49,7 +50,6 @@ export default class EditorsController { _telemetryService: TelemetryService; _playgroundResultViewProvider: PlaygroundResultProvider; _activeConnectionCodeLensProvider: ActiveConnectionCodeLensProvider; - _partialExecutionCodeLensProvider: PartialExecutionCodeLensProvider; _editDocumentCodeLensProvider: EditDocumentCodeLensProvider; _collectionDocumentsCodeLensProvider: CollectionDocumentsCodeLensProvider; @@ -61,7 +61,7 @@ export default class EditorsController { telemetryService: TelemetryService, playgroundResultViewProvider: PlaygroundResultProvider, activeConnectionCodeLensProvider: ActiveConnectionCodeLensProvider, - partialExecutionCodeLensProvider: PartialExecutionCodeLensProvider, + codeActionProvider: CodeActionProvider, editDocumentCodeLensProvider: EditDocumentCodeLensProvider ) { log.info('activating...'); @@ -90,10 +90,10 @@ export default class EditorsController { ); this._playgroundResultViewProvider = playgroundResultViewProvider; this._activeConnectionCodeLensProvider = activeConnectionCodeLensProvider; - this._partialExecutionCodeLensProvider = partialExecutionCodeLensProvider; this._collectionDocumentsCodeLensProvider = new CollectionDocumentsCodeLensProvider( this._collectionDocumentsOperationsStore ); + this._codeActionProvider = codeActionProvider; vscode.workspace.onDidCloseTextDocument((e) => { const uriParams = new URLSearchParams(e.uri.query); @@ -372,12 +372,6 @@ export default class EditorsController { this._activeConnectionCodeLensProvider ) ); - this._context.subscriptions.push( - vscode.languages.registerCodeLensProvider( - { language: 'mongodb' }, - this._partialExecutionCodeLensProvider - ) - ); this._context.subscriptions.push( vscode.languages.registerCodeLensProvider( { @@ -396,6 +390,11 @@ export default class EditorsController { this._editDocumentCodeLensProvider ) ); + this._context.subscriptions.push( + vscode.languages.registerCodeActionsProvider('mongodb', this._codeActionProvider, { + providedCodeActionKinds: CodeActionProvider.providedCodeActionKinds + }) + ); } deactivate(): void { diff --git a/src/editors/partialExecutionCodeLensProvider.ts b/src/editors/partialExecutionCodeLensProvider.ts deleted file mode 100644 index d7f8529c8..000000000 --- a/src/editors/partialExecutionCodeLensProvider.ts +++ /dev/null @@ -1,92 +0,0 @@ -import * as vscode from 'vscode'; -import EXTENSION_COMMANDS from '../commands'; - -// Returns a boolean if the selection is one that is valid to show a -// code lens for (isn't a partial line etc.). -export function isSelectionValidForCodeLens( - selections: vscode.Selection[], - textDocument: vscode.TextDocument -): boolean { - if (selections.length > 1) { - // Show codelens when it's multi cursor. - return true; - } - - if (!selections[0].isSingleLine) { - // Show codelens when it's a multi-line selection. - return true; - } - - const lineContent = (textDocument.lineAt(selections[0].end.line).text || '').trim(); - const selectionContent = (textDocument.getText(selections[0]) || '').trim(); - - // Show codelens when it contains the whole line. - return lineContent === selectionContent; -} - -export function getCodeLensLineOffsetForSelection( - selections: vscode.Selection[], - editor: vscode.TextEditor -): number { - const lastSelection = selections[selections.length - 1]; - const lastSelectedLineNumber = lastSelection.end.line; - const lastSelectedLineContent = editor.document.lineAt(lastSelectedLineNumber).text || ''; - - // Show a code lens after the selected line, unless the - // contents of the selection in the last line is empty. - const lastSelectedLineContentRange = new vscode.Range( - new vscode.Position( - lastSelection.end.line, - 0 - ), - new vscode.Position( - lastSelection.end.line, - lastSelectedLineContent.length - ) - ); - const interectedSelection = lastSelection.intersection(lastSelectedLineContentRange); - if (!interectedSelection || interectedSelection.isEmpty) { - return 0; - } - - return lastSelectedLineContent.trim().length > 0 ? 1 : 0; -} - -export default class PartialExecutionCodeLensProvider -implements vscode.CodeLensProvider { - _selection?: vscode.Range; - _onDidChangeCodeLenses: vscode.EventEmitter< - void - > = new vscode.EventEmitter(); - - readonly onDidChangeCodeLenses: vscode.Event = this - ._onDidChangeCodeLenses.event; - - constructor() { - vscode.workspace.onDidChangeConfiguration(() => { - this._onDidChangeCodeLenses.fire(); - }); - } - - refresh(selection?: vscode.Range): void { - this._selection = selection; - this._onDidChangeCodeLenses.fire(); - } - - provideCodeLenses(): vscode.CodeLens[] { - if (!this._selection) { - return []; - } - - const message = '► Run Selected Lines From Playground'; - const codeLens = new vscode.CodeLens(this._selection); - - codeLens.command = { - title: message, - command: EXTENSION_COMMANDS.MDB_RUN_SELECTED_PLAYGROUND_BLOCKS, - arguments: [message] - }; - - return [codeLens]; - } -} diff --git a/src/editors/playgroundController.ts b/src/editors/playgroundController.ts index 2c6664b17..355d9a0a5 100644 --- a/src/editors/playgroundController.ts +++ b/src/editors/playgroundController.ts @@ -9,10 +9,6 @@ import { createLogger } from '../logging'; import { ExplorerController, ConnectionTreeItem, DatabaseTreeItem } from '../explorer'; import { LanguageServerController } from '../language'; import { OutputChannel, ProgressLocation, TextEditor } from 'vscode'; -import PartialExecutionCodeLensProvider, { - isSelectionValidForCodeLens, - getCodeLensLineOffsetForSelection -} from './partialExecutionCodeLensProvider'; import playgroundCreateIndexTemplate from '../templates/playgroundCreateIndexTemplate'; import playgroundCreateCollectionTemplate from '../templates/playgroundCreateCollectionTemplate'; import playgroundCreateCollectionWithTSTemplate from '../templates/playgroundCreateCollectionWithTSTemplate'; @@ -59,7 +55,6 @@ export default class PlaygroundController { _languageServerController: LanguageServerController; _telemetryService: TelemetryService; _activeConnectionCodeLensProvider: ActiveConnectionCodeLensProvider; - _partialExecutionCodeLensProvider: PartialExecutionCodeLensProvider; _outputChannel: OutputChannel; _connectionString?: string; _selectedText?: string; @@ -79,7 +74,6 @@ export default class PlaygroundController { statusView: StatusView, playgroundResultViewProvider: PlaygroundResultProvider, activeConnectionCodeLensProvider: ActiveConnectionCodeLensProvider, - partialExecutionCodeLensProvider: PartialExecutionCodeLensProvider, explorerController: ExplorerController ) { this._context = context; @@ -93,7 +87,6 @@ export default class PlaygroundController { 'Playground output' ); this._activeConnectionCodeLensProvider = activeConnectionCodeLensProvider; - this._partialExecutionCodeLensProvider = partialExecutionCodeLensProvider; this._explorerController = explorerController; this._connectionController.addEventListener( @@ -130,60 +123,15 @@ export default class PlaygroundController { .sort((a, b) => (a.start.line > b.start.line ? 1 : -1)); this._selectedText = sortedSelections - .map((selection) => this._getSelectedText(selection)) + .map((item) => this._getSelectedText(item)) .join('\n'); - - void this._showCodeLensForSelection( - sortedSelections, - changeEvent.textEditor - ); } } ); } - _showCodeLensForSelection( - selections: vscode.Selection[], - editor: vscode.TextEditor - ): void { - if (!this._selectedText || this._selectedText.trim().length === 0) { - this._partialExecutionCodeLensProvider.refresh(); - return; - } - - if (!isSelectionValidForCodeLens(selections, editor.document)) { - this._partialExecutionCodeLensProvider.refresh(); - return; - } - - const lastSelection = selections[selections.length - 1]; - const lastSelectedLineNumber = lastSelection.end.line; - const lastSelectedLineContent = editor.document.lineAt(lastSelectedLineNumber).text || ''; - // Add an empty line to the end of the file when the selection includes - // the last line and it is not empty. - // We do this so that we can show the code lens after the line's contents. - if ( - lastSelection.end.line === editor.document.lineCount - 1 && - lastSelectedLineContent.trim().length > 0 - ) { - void editor.edit(edit => { - edit.insert( - new vscode.Position(lastSelection.end.line + 1, 0), - '\n' - ); - }); - } - - const codeLensLineOffset = getCodeLensLineOffsetForSelection(selections, editor); - this._partialExecutionCodeLensProvider.refresh( - new vscode.Range( - lastSelectedLineNumber + codeLensLineOffset, 0, - lastSelectedLineNumber + codeLensLineOffset, 0 - ) - ); - } - async _connectToServiceProvider(): Promise { + // Disconnect if already connected. await this._languageServerController.disconnectFromServiceProvider(); const dataService = this._connectionController.getActiveDataService(); @@ -505,34 +453,17 @@ export default class PlaygroundController { } runSelectedPlaygroundBlocks(): Promise { - if ( - !this._activeTextEditor || - this._activeTextEditor.document.languageId !== 'mongodb' - ) { - void vscode.window.showErrorMessage( - "Please open a '.mongodb' playground file before running it." - ); - - return Promise.resolve(false); - } - - const selections = this._activeTextEditor.selections; - - if ( - !selections || - !Array.isArray(selections) || - (selections.length === 1 && this._getSelectedText(selections[0]) === '') - ) { + if (!this._selectedText) { void vscode.window.showInformationMessage( 'Please select one or more lines in the playground.' ); return Promise.resolve(true); - } else if (this._selectedText) { - this._isPartialRun = true; - this._codeToEvaluate = this._selectedText; } + this._isPartialRun = true; + this._codeToEvaluate = this._selectedText; + return this._evaluatePlayground(); } diff --git a/src/mdbExtensionController.ts b/src/mdbExtensionController.ts index fd5a173ad..e7858c098 100644 --- a/src/mdbExtensionController.ts +++ b/src/mdbExtensionController.ts @@ -22,6 +22,7 @@ import { HelpExplorer, CollectionTreeItem } from './explorer'; +import CodeActionProvider from './editors/codeActionProvider'; import EXTENSION_COMMANDS from './commands'; import FieldTreeItem from './explorer/fieldTreeItem'; import IndexListTreeItem from './explorer/indexListTreeItem'; @@ -31,7 +32,6 @@ import SchemaTreeItem from './explorer/schemaTreeItem'; import { StatusView } from './views'; import { StorageController, StorageVariables } from './storage'; import TelemetryService from './telemetry/telemetryService'; -import PartialExecutionCodeLensProvider from './editors/partialExecutionCodeLensProvider'; import PlaygroundsTreeItem from './explorer/playgroundsTreeItem'; import PlaygroundResultProvider from './editors/playgroundResultProvider'; import WebviewController from './views/webviewController'; @@ -41,6 +41,7 @@ const log = createLogger('commands'); // This class is the top-level controller for our extension. // Commands which the extensions handles are defined in the function `activate`. export default class MDBExtensionController implements vscode.Disposable { + _codeActionProvider: CodeActionProvider; _connectionController: ConnectionController; _context: vscode.ExtensionContext; _editorsController: EditorsController; @@ -55,7 +56,6 @@ export default class MDBExtensionController implements vscode.Disposable { _webviewController: WebviewController; _playgroundResultViewProvider: PlaygroundResultProvider; _activeConnectionCodeLensProvider: ActiveConnectionCodeLensProvider; - _partialExecutionCodeLensProvider: PartialExecutionCodeLensProvider; _editDocumentCodeLensProvider: EditDocumentCodeLensProvider; constructor( @@ -91,7 +91,6 @@ export default class MDBExtensionController implements vscode.Disposable { this._activeConnectionCodeLensProvider = new ActiveConnectionCodeLensProvider( this._connectionController ); - this._partialExecutionCodeLensProvider = new PartialExecutionCodeLensProvider(); this._playgroundController = new PlaygroundController( context, this._connectionController, @@ -100,9 +99,9 @@ export default class MDBExtensionController implements vscode.Disposable { this._statusView, this._playgroundResultViewProvider, this._activeConnectionCodeLensProvider, - this._partialExecutionCodeLensProvider, this._explorerController ); + this._codeActionProvider = new CodeActionProvider(this._playgroundController); this._editorsController = new EditorsController( context, this._connectionController, @@ -111,7 +110,7 @@ export default class MDBExtensionController implements vscode.Disposable { this._telemetryService, this._playgroundResultViewProvider, this._activeConnectionCodeLensProvider, - this._partialExecutionCodeLensProvider, + this._codeActionProvider, this._editDocumentCodeLensProvider ); this._webviewController = new WebviewController( diff --git a/src/test/suite/editors/codeActionProvider.test.ts b/src/test/suite/editors/codeActionProvider.test.ts new file mode 100644 index 000000000..cd2798b33 --- /dev/null +++ b/src/test/suite/editors/codeActionProvider.test.ts @@ -0,0 +1,79 @@ +import assert from 'assert'; +import { beforeEach } from 'mocha'; + +import ActiveDBCodeLensProvider from '../../../editors/activeConnectionCodeLensProvider'; +import CodeActionProvider from '../../../editors/codeActionProvider'; +import ConnectionController from '../../../connectionController'; +import EditDocumentCodeLensProvider from '../../../editors/editDocumentCodeLensProvider'; +import { ExplorerController } from '../../../explorer'; +import { LanguageServerController } from '../../../language'; +import { PlaygroundController } from '../../../editors'; +import PlaygroundResultProvider from '../../../editors/playgroundResultProvider'; +import { StatusView } from '../../../views'; +import { StorageController } from '../../../storage'; +import TelemetryService from '../../../telemetry/telemetryService'; +import { TestExtensionContext, MockLanguageServerController } from '../stubs'; + +suite('Code Action Provider Test Suite', () => { + const mockExtensionContext = new TestExtensionContext(); + + mockExtensionContext.extensionPath = '../../'; + + const mockStorageController = new StorageController(mockExtensionContext); + const testTelemetryService = new TelemetryService( + mockStorageController, + mockExtensionContext + ); + const testStatusView = new StatusView(mockExtensionContext); + const testConnectionController = new ConnectionController( + testStatusView, + mockStorageController, + testTelemetryService + ); + const mockLanguageServerController = new MockLanguageServerController( + mockExtensionContext, + mockStorageController + ); + const testEditDocumentCodeLensProvider = new EditDocumentCodeLensProvider( + testConnectionController + ); + const testPlaygroundResultProvider = new PlaygroundResultProvider( + testConnectionController, + testEditDocumentCodeLensProvider + ); + const testActiveDBCodeLensProvider = new ActiveDBCodeLensProvider( + testConnectionController + ); + const testExplorerController = new ExplorerController( + testConnectionController + ); + let testPlaygroundController: PlaygroundController; + + beforeEach(() => { + testPlaygroundController = new PlaygroundController( + mockExtensionContext, + testConnectionController, + mockLanguageServerController as LanguageServerController, + testTelemetryService, + testStatusView, + testPlaygroundResultProvider, + testActiveDBCodeLensProvider, + testExplorerController + ); + }); + + test('expected provideCodeActions to return undefined when text is not selected', () => { + const testCodeActionProvider = new CodeActionProvider(testPlaygroundController); + const codeActions = testCodeActionProvider.provideCodeActions(); + + assert(!codeActions); + }); + + test('expected provideCodeActions to return a run selected playground blocks action', () => { + const testCodeActionProvider = new CodeActionProvider(testPlaygroundController); + const codeActions = testCodeActionProvider.provideCodeActions(); + + assert(!!codeActions); + assert(codeActions.length === 1); + }); +}); diff --git a/src/test/suite/editors/partialExecutionCodeLensProvider.test.ts b/src/test/suite/editors/partialExecutionCodeLensProvider.test.ts deleted file mode 100644 index 239b75609..000000000 --- a/src/test/suite/editors/partialExecutionCodeLensProvider.test.ts +++ /dev/null @@ -1,38 +0,0 @@ -import assert from 'assert'; -import * as vscode from 'vscode'; -import PartialExecutionCodeLensProvider from '../../../editors/partialExecutionCodeLensProvider'; - -suite('Partial Execution Code Lens Provider Test Suite', () => { - test('expected provideCodeLenses to return empty array when text is not selected', () => { - const testCodeLensProvider = new PartialExecutionCodeLensProvider(); - - testCodeLensProvider.refresh(); - - const codeLens = testCodeLensProvider.provideCodeLenses(); - - assert(!!codeLens); - assert(codeLens.length === 0); - }); - - test('expected provideCodeLenses to return a code lens when text is selected', () => { - const testCodeLensProvider = new PartialExecutionCodeLensProvider(); - - testCodeLensProvider.refresh(new vscode.Range(4, 5, 5, 30)); - - const codeLens = testCodeLensProvider.provideCodeLenses(); - - assert(!!codeLens); - assert(codeLens.length === 1); - const range = codeLens[0].range; - const expectedStartLine = 4; - assert( - range.start.line === expectedStartLine, - `Expected a codeLens position to be at line ${expectedStartLine}, found ${range.start.line}` - ); - const expectedEnd = 5; - assert( - range.end.line === expectedEnd, - `Expected a codeLens position to be at line ${expectedEnd}, found ${range.end.line}` - ); - }); -}); diff --git a/src/test/suite/editors/playgroundController.test.ts b/src/test/suite/editors/playgroundController.test.ts index 53150b63e..f42cf4dbc 100644 --- a/src/test/suite/editors/playgroundController.test.ts +++ b/src/test/suite/editors/playgroundController.test.ts @@ -1,22 +1,22 @@ import * as vscode from 'vscode'; -import { PlaygroundController } from '../../../editors'; -import { LanguageServerController } from '../../../language'; -import ConnectionController from '../../../connectionController'; -import { StatusView } from '../../../views'; -import { StorageController } from '../../../storage'; -import { TestExtensionContext, MockLanguageServerController } from '../stubs'; import { before, beforeEach, afterEach } from 'mocha'; -import TelemetryService from '../../../telemetry/telemetryService'; -import PlaygroundResultProvider from '../../../editors/playgroundResultProvider'; +import chai from 'chai'; +import sinon from 'sinon'; + import ActiveDBCodeLensProvider from '../../../editors/activeConnectionCodeLensProvider'; -import PartialExecutionCodeLensProvider from '../../../editors/partialExecutionCodeLensProvider'; +import ConnectionController from '../../../connectionController'; +import { ConnectionModel } from '../../../types/connectionModelType'; import EditDocumentCodeLensProvider from '../../../editors/editDocumentCodeLensProvider'; import { ExplorerController } from '../../../explorer'; - -import sinon from 'sinon'; -import chai from 'chai'; +import { LanguageServerController } from '../../../language'; +import { PlaygroundController } from '../../../editors'; +import PlaygroundResultProvider from '../../../editors/playgroundResultProvider'; +import { StatusView } from '../../../views'; +import { StorageController } from '../../../storage'; +import TelemetryService from '../../../telemetry/telemetryService'; import { TEST_DATABASE_URI } from '../dbTestHelper'; -import { ConnectionModel } from '../../../types/connectionModelType'; +import { TestExtensionContext, MockLanguageServerController } from '../stubs'; + const expect = chai.expect; chai.use(require('chai-as-promised')); @@ -26,30 +26,6 @@ const CONNECTION = { driverOptions: {} }; -const mockPlayground = 'use(\'dbName\');\n a\n\n\n\ndb.find();'; - -const activeTestEditorWithSelectionMock = { - document: { - languageId: 'mongodb', - uri: { - path: 'test' - } as vscode.Uri, - getText: (range: vscode.Range) => mockPlayground.split('\n')[range.start.line].substr(range.start.character, range.end.character), - lineAt: (lineNumber: number) => ({ - text: mockPlayground.split('\n')[lineNumber] - }), - lineCount: mockPlayground.split('\n').length - }, - selections: [ - new vscode.Selection( - new vscode.Position(0, 5), - new vscode.Position(0, 11) - ) - ], - edit: () => null -} as unknown as vscode.TextEditor; - - suite('Playground Controller Test Suite', function () { this.timeout(5000); @@ -82,7 +58,6 @@ suite('Playground Controller Test Suite', function () { const testActiveDBCodeLensProvider = new ActiveDBCodeLensProvider( testConnectionController ); - const testPartialExecutionCodeLensProvider = new PartialExecutionCodeLensProvider(); const testExplorerController = new ExplorerController( testConnectionController ); @@ -94,7 +69,6 @@ suite('Playground Controller Test Suite', function () { testStatusView, testPlaygroundResultProvider, testActiveDBCodeLensProvider, - testPartialExecutionCodeLensProvider, testExplorerController ); const sandbox = sinon.createSandbox(); @@ -467,122 +441,6 @@ suite('Playground Controller Test Suite', function () { }); }); - test('do not show code lens if a part of a line with content is selected', () => { - testPlaygroundController._selectedText = 'db'; - testPlaygroundController._activeTextEditor = activeTestEditorWithSelectionMock; - - testPlaygroundController._showCodeLensForSelection( - [new vscode.Selection( - new vscode.Position(0, 5), - new vscode.Position(0, 11) - )], - activeTestEditorWithSelectionMock - ); - - const codeLens = testPlaygroundController._partialExecutionCodeLensProvider?.provideCodeLenses(); - - expect(codeLens.length).to.be.equal(0); - }); - - test('do not show code lens when it has no content (multi-line)', () => { - testPlaygroundController._selectedText = ' \n\n '; - testPlaygroundController._activeTextEditor = activeTestEditorWithSelectionMock; - - testPlaygroundController._showCodeLensForSelection( - [new vscode.Selection( - new vscode.Position(2, 0), - new vscode.Position(4, 0) - )], - activeTestEditorWithSelectionMock - ); - - const codeLens = testPlaygroundController._partialExecutionCodeLensProvider?.provideCodeLenses(); - - expect(codeLens.length).to.be.equal(0); - }); - - test('show code lens if whole line is selected', () => { - testPlaygroundController._selectedText = 'use(\'dbName\');'; - testPlaygroundController._showCodeLensForSelection( - [new vscode.Selection( - new vscode.Position(0, 0), - new vscode.Position(0, 15) - )], - activeTestEditorWithSelectionMock - ); - - const codeLens = testPlaygroundController._partialExecutionCodeLensProvider.provideCodeLenses(); - - expect(codeLens.length).to.be.equal(1); - expect(codeLens[0].range.end.line).to.be.equal(1); - }); - - test('has the correct line number for code lens when the selection includes the last line', () => { - testPlaygroundController._selectedText = 'use(\'dbName\');\n\na'; - const fakeEdit = sinon.fake.returns(() => ({ insert: sinon.fake() })); - sandbox.replace( - activeTestEditorWithSelectionMock, - 'edit', - fakeEdit - ); - testPlaygroundController._showCodeLensForSelection( - [new vscode.Selection( - new vscode.Position(0, 0), - new vscode.Position(5, 5) - )], - activeTestEditorWithSelectionMock - ); - - const codeLens = testPlaygroundController._partialExecutionCodeLensProvider.provideCodeLenses(); - - expect(codeLens.length).to.be.equal(1); - expect(codeLens[0].range.start.line).to.be.equal(6); - expect(codeLens[0].range.end.line).to.be.equal(6); - expect(fakeEdit).to.be.called; - }); - - test('it calls to edit the document to add an empty line if the selection includes the last line with content', (done) => { - testPlaygroundController._selectedText = 'use(\'dbName\');\n\na'; - sandbox.replace( - activeTestEditorWithSelectionMock, - 'edit', - (cb) => { - cb({ - insert: (position: vscode.Position, toInsert: string) => { - expect(position.line).to.equal(6); - expect(toInsert).to.equal('\n'); - done(); - } - } as unknown as vscode.TextEditorEdit); - return new Promise((resolve) => resolve(true)); - } - ); - testPlaygroundController._showCodeLensForSelection( - [new vscode.Selection( - new vscode.Position(0, 0), - new vscode.Position(5, 5) - )], - activeTestEditorWithSelectionMock - ); - }); - - test('shows the codelens on the line above the last selected line when the last selected line is empty', () => { - testPlaygroundController._selectedText = 'use(\'dbName\');\n\n'; - testPlaygroundController._showCodeLensForSelection( - [new vscode.Selection( - new vscode.Position(0, 0), - new vscode.Position(1, 3) - )], - activeTestEditorWithSelectionMock - ); - - const codeLens = testPlaygroundController._partialExecutionCodeLensProvider.provideCodeLenses(); - - expect(codeLens.length).to.be.equal(1); - expect(codeLens[0].range.start.line).to.be.equal(2); - expect(codeLens[0].range.end.line).to.be.equal(2); - }); - test('playground controller loads the active editor on start', () => { sandbox.replaceGetter( vscode.window, @@ -601,7 +459,6 @@ suite('Playground Controller Test Suite', function () { testStatusView, testPlaygroundResultProvider, testActiveDBCodeLensProvider, - testPartialExecutionCodeLensProvider, testExplorerController ); diff --git a/src/test/suite/language/languageServerController.test.ts b/src/test/suite/language/languageServerController.test.ts index 99c7e5533..bf2333a13 100644 --- a/src/test/suite/language/languageServerController.test.ts +++ b/src/test/suite/language/languageServerController.test.ts @@ -1,29 +1,28 @@ import { before, after } from 'mocha'; -import TelemetryService from '../../../telemetry/telemetryService'; -import { ExplorerController } from '../../../explorer'; - -import path from 'path'; +import chai from 'chai'; import fs from 'fs'; +import path from 'path'; import sinon from 'sinon'; -import chai from 'chai'; -const expect = chai.expect; -chai.use(require('chai-as-promised')); - -import { PlaygroundController } from '../../../editors'; -import { LanguageServerController } from '../../../language'; +import ActiveDBCodeLensProvider from '../../../editors/activeConnectionCodeLensProvider'; import ConnectionController from '../../../connectionController'; -import { StatusView } from '../../../views'; -import { StorageController } from '../../../storage'; -import { TestExtensionContext } from '../stubs'; +import { DataServiceType } from '../../../types/dataServiceType'; +import EditDocumentCodeLensProvider from '../../../editors/editDocumentCodeLensProvider'; +import { ExplorerController } from '../../../explorer'; +import { LanguageServerController } from '../../../language'; import { mdbTestExtension } from '../stubbableMdbExtension'; +import { PlaygroundController } from '../../../editors'; import PlaygroundResultProvider from '../../../editors/playgroundResultProvider'; -import ActiveDBCodeLensProvider from '../../../editors/activeConnectionCodeLensProvider'; -import PartialExecutionCodeLensProvider from '../../../editors/partialExecutionCodeLensProvider'; -import EditDocumentCodeLensProvider from '../../../editors/editDocumentCodeLensProvider'; -import { TEST_DATABASE_URI } from '../dbTestHelper'; import READ_PREFERENCES from '../../../views/webview-app/connection-model/constants/read-preferences'; -import { DataServiceType } from '../../../types/dataServiceType'; +import { StatusView } from '../../../views'; +import { StorageController } from '../../../storage'; +import { TEST_DATABASE_URI } from '../dbTestHelper'; +import TelemetryService from '../../../telemetry/telemetryService'; +import { TestExtensionContext } from '../stubs'; + +const expect = chai.expect; + +chai.use(require('chai-as-promised')); suite('Language Server Controller Test Suite', () => { const mockExtensionContext = new TestExtensionContext(); @@ -54,7 +53,6 @@ suite('Language Server Controller Test Suite', () => { const testActiveDBCodeLensProvider = new ActiveDBCodeLensProvider( testConnectionController ); - const testPartialExecutionCodeLensProvider = new PartialExecutionCodeLensProvider(); const testExplorerController = new ExplorerController( testConnectionController ); @@ -66,7 +64,6 @@ suite('Language Server Controller Test Suite', () => { testStatusView, testPlaygroundResultProvider, testActiveDBCodeLensProvider, - testPartialExecutionCodeLensProvider, testExplorerController );