Path: blob/main/src/vs/editor/test/browser/view/viewController.test.ts
5222 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import assert from 'assert';6import { DisposableStore } from '../../../../base/common/lifecycle.js';7import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../base/test/common/utils.js';8import { TestInstantiationService } from '../../../../platform/instantiation/test/common/instantiationServiceMock.js';9import { TestThemeService } from '../../../../platform/theme/test/common/testThemeService.js';10import { NavigationCommandRevealType } from '../../../browser/coreCommands.js';11import { ViewController } from '../../../browser/view/viewController.js';12import { ViewUserInputEvents } from '../../../browser/view/viewUserInputEvents.js';13import { Position } from '../../../common/core/position.js';14import { ILanguageService } from '../../../common/languages/language.js';15import { ILanguageConfigurationService } from '../../../common/languages/languageConfigurationRegistry.js';16import { MonospaceLineBreaksComputerFactory } from '../../../common/viewModel/monospaceLineBreaksComputer.js';17import { ViewModel } from '../../../common/viewModel/viewModelImpl.js';18import { instantiateTextModel } from '../../../test/common/testTextModel.js';19import { TestLanguageConfigurationService } from '../../common/modes/testLanguageConfigurationService.js';20import { TestConfiguration } from '../config/testConfiguration.js';21import { createCodeEditorServices } from '../testCodeEditor.js';2223suite('ViewController - Bracket content selection', () => {24let disposables: DisposableStore;25let instantiationService: TestInstantiationService;26let languageConfigurationService: ILanguageConfigurationService;27let languageService: ILanguageService;28let viewModel: ViewModel | undefined;2930setup(() => {31disposables = new DisposableStore();32instantiationService = createCodeEditorServices(disposables);33languageConfigurationService = instantiationService.get(ILanguageConfigurationService);34languageService = instantiationService.get(ILanguageService);35viewModel = undefined;36});3738teardown(() => {39viewModel?.dispose();40viewModel = undefined;41disposables.dispose();42});4344ensureNoDisposablesAreLeakedInTestSuite();4546function createViewControllerWithText(text: string): ViewController {47const languageId = 'testMode';48disposables.add(languageService.registerLanguage({ id: languageId }));49disposables.add(languageConfigurationService.register(languageId, {50brackets: [51['{', '}'],52['[', ']'],53['(', ')'],54]55}));5657const configuration = disposables.add(new TestConfiguration({}));58const monospaceLineBreaksComputerFactory = MonospaceLineBreaksComputerFactory.create(configuration.options);5960viewModel = new ViewModel(611, // editorId62configuration,63disposables.add(instantiateTextModel(instantiationService, text, languageId)),64monospaceLineBreaksComputerFactory,65monospaceLineBreaksComputerFactory,66null!,67disposables.add(new TestLanguageConfigurationService()),68new TestThemeService(),69{ setVisibleLines() { } },70{ batchChanges: (cb: any) => cb() }71);7273return new ViewController(74configuration,75viewModel,76new ViewUserInputEvents(viewModel.coordinatesConverter),77{78paste: () => { },79type: () => { },80compositionType: () => { },81startComposition: () => { },82endComposition: () => { },83cut: () => { }84}85);86}8788function testBracketSelection(text: string, position: Position, expectedText: string | undefined) {89const controller = createViewControllerWithText(text);90controller.dispatchMouse({91position,92mouseColumn: position.column,93startedOnLineNumbers: false,94revealType: NavigationCommandRevealType.Minimal,95mouseDownCount: 2,96inSelectionMode: false,97altKey: false,98ctrlKey: false,99metaKey: false,100shiftKey: false,101leftButton: true,102middleButton: false,103onInjectedText: false104});105106const selections = viewModel!.getSelections();107const selectedText = viewModel!.model.getValueInRange(selections[0]);108if (expectedText === undefined) {109assert.notStrictEqual(selectedText, expectedText);110} else {111assert.strictEqual(selectedText, expectedText);112}113}114115test('Select content after opening curly brace', () => {116testBracketSelection('var x = { hello };', new Position(1, 10), ' hello ');117});118119test('Select content before closing curly brace', () => {120testBracketSelection('var x = { hello };', new Position(1, 17), ' hello ');121});122123test('Select content after opening parenthesis', () => {124testBracketSelection('function foo(arg1, arg2) {}', new Position(1, 14), 'arg1, arg2');125});126127test('Select content before closing parenthesis', () => {128testBracketSelection('function foo(arg1, arg2) {}', new Position(1, 24), 'arg1, arg2');129});130131test('Select content after opening square bracket', () => {132testBracketSelection('const arr = [ 1, 2, 3 ];', new Position(1, 14), ' 1, 2, 3 ');133});134135test('Select content before closing square bracket', () => {136testBracketSelection('const arr = [ 1, 2, 3 ];', new Position(1, 23), ' 1, 2, 3 ');137});138139test('Select innermost bracket content with nested brackets', () => {140testBracketSelection('var x = { a: { b: 123 }};', new Position(1, 15), ' b: 123 ');141});142143test('Empty brackets create empty selection', () => {144testBracketSelection('var x = {};', new Position(1, 10), '');145});146});147148149