Path: blob/main/src/vs/editor/test/browser/widget/codeEditorWidget.test.ts
3296 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 { Range } from '../../../common/core/range.js';9import { Selection } from '../../../common/core/selection.js';10import { ILanguageService } from '../../../common/languages/language.js';11import { ILanguageConfigurationService } from '../../../common/languages/languageConfigurationRegistry.js';12import { withTestCodeEditor } from '../testCodeEditor.js';1314suite('CodeEditorWidget', () => {1516ensureNoDisposablesAreLeakedInTestSuite();1718test('onDidChangeModelDecorations', () => {19withTestCodeEditor('', {}, (editor, viewModel) => {20const disposables = new DisposableStore();2122let invoked = false;23disposables.add(editor.onDidChangeModelDecorations((e) => {24invoked = true;25}));2627viewModel.model.deltaDecorations([], [{ range: new Range(1, 1, 1, 1), options: { description: 'test' } }]);2829assert.deepStrictEqual(invoked, true);3031disposables.dispose();32});33});3435test('onDidChangeModelLanguage', () => {36withTestCodeEditor('', {}, (editor, viewModel, instantiationService) => {37const languageService = instantiationService.get(ILanguageService);38const disposables = new DisposableStore();39disposables.add(languageService.registerLanguage({ id: 'testMode' }));4041let invoked = false;42disposables.add(editor.onDidChangeModelLanguage((e) => {43invoked = true;44}));4546viewModel.model.setLanguage('testMode');4748assert.deepStrictEqual(invoked, true);4950disposables.dispose();51});52});5354test('onDidChangeModelLanguageConfiguration', () => {55withTestCodeEditor('', {}, (editor, viewModel, instantiationService) => {56const languageConfigurationService = instantiationService.get(ILanguageConfigurationService);57const languageService = instantiationService.get(ILanguageService);58const disposables = new DisposableStore();59disposables.add(languageService.registerLanguage({ id: 'testMode' }));60viewModel.model.setLanguage('testMode');6162let invoked = false;63disposables.add(editor.onDidChangeModelLanguageConfiguration((e) => {64invoked = true;65}));6667disposables.add(languageConfigurationService.register('testMode', {68brackets: [['(', ')']]69}));7071assert.deepStrictEqual(invoked, true);7273disposables.dispose();74});75});7677test('onDidChangeModelContent', () => {78withTestCodeEditor('', {}, (editor, viewModel) => {79const disposables = new DisposableStore();8081let invoked = false;82disposables.add(editor.onDidChangeModelContent((e) => {83invoked = true;84}));8586viewModel.type('hello', 'test');8788assert.deepStrictEqual(invoked, true);8990disposables.dispose();91});92});9394test('onDidChangeModelOptions', () => {95withTestCodeEditor('', {}, (editor, viewModel) => {96const disposables = new DisposableStore();9798let invoked = false;99disposables.add(editor.onDidChangeModelOptions((e) => {100invoked = true;101}));102103viewModel.model.updateOptions({104tabSize: 3105});106107assert.deepStrictEqual(invoked, true);108109disposables.dispose();110});111});112113test('issue #145872 - Model change events are emitted before the selection updates', () => {114withTestCodeEditor('', {}, (editor, viewModel) => {115const disposables = new DisposableStore();116117let observedSelection: Selection | null = null;118disposables.add(editor.onDidChangeModelContent((e) => {119observedSelection = editor.getSelection();120}));121122viewModel.type('hello', 'test');123124assert.deepStrictEqual(observedSelection, new Selection(1, 6, 1, 6));125126disposables.dispose();127});128});129130test('monaco-editor issue #2774 - Wrong order of events onDidChangeModelContent and onDidChangeCursorSelection on redo', () => {131withTestCodeEditor('', {}, (editor, viewModel) => {132const disposables = new DisposableStore();133134const calls: string[] = [];135disposables.add(editor.onDidChangeModelContent((e) => {136calls.push(`contentchange(${e.changes.reduce<any[]>((aggr, c) => [...aggr, c.text, c.rangeOffset, c.rangeLength], []).join(', ')})`);137}));138disposables.add(editor.onDidChangeCursorSelection((e) => {139calls.push(`cursorchange(${e.selection.positionLineNumber}, ${e.selection.positionColumn})`);140}));141142viewModel.type('a', 'test');143viewModel.model.undo();144viewModel.model.redo();145146assert.deepStrictEqual(calls, [147'contentchange(a, 0, 0)',148'cursorchange(1, 2)',149'contentchange(, 0, 1)',150'cursorchange(1, 1)',151'contentchange(a, 0, 0)',152'cursorchange(1, 2)'153]);154155disposables.dispose();156});157});158159test('issue #146174: Events delivered out of order when adding decorations in content change listener (1 of 2)', () => {160withTestCodeEditor('', {}, (editor, viewModel) => {161const disposables = new DisposableStore();162163const calls: string[] = [];164disposables.add(editor.onDidChangeModelContent((e) => {165calls.push(`listener1 - contentchange(${e.changes.reduce<any[]>((aggr, c) => [...aggr, c.text, c.rangeOffset, c.rangeLength], []).join(', ')})`);166}));167disposables.add(editor.onDidChangeCursorSelection((e) => {168calls.push(`listener1 - cursorchange(${e.selection.positionLineNumber}, ${e.selection.positionColumn})`);169}));170disposables.add(editor.onDidChangeModelContent((e) => {171calls.push(`listener2 - contentchange(${e.changes.reduce<any[]>((aggr, c) => [...aggr, c.text, c.rangeOffset, c.rangeLength], []).join(', ')})`);172}));173disposables.add(editor.onDidChangeCursorSelection((e) => {174calls.push(`listener2 - cursorchange(${e.selection.positionLineNumber}, ${e.selection.positionColumn})`);175}));176177viewModel.type('a', 'test');178179assert.deepStrictEqual(calls, ([180'listener1 - contentchange(a, 0, 0)',181'listener2 - contentchange(a, 0, 0)',182'listener1 - cursorchange(1, 2)',183'listener2 - cursorchange(1, 2)',184]));185186disposables.dispose();187});188});189190test('issue #146174: Events delivered out of order when adding decorations in content change listener (2 of 2)', () => {191withTestCodeEditor('', {}, (editor, viewModel) => {192const disposables = new DisposableStore();193194const calls: string[] = [];195disposables.add(editor.onDidChangeModelContent((e) => {196calls.push(`listener1 - contentchange(${e.changes.reduce<any[]>((aggr, c) => [...aggr, c.text, c.rangeOffset, c.rangeLength], []).join(', ')})`);197editor.changeDecorations((changeAccessor) => {198changeAccessor.deltaDecorations([], [{ range: new Range(1, 1, 1, 1), options: { description: 'test' } }]);199});200}));201disposables.add(editor.onDidChangeCursorSelection((e) => {202calls.push(`listener1 - cursorchange(${e.selection.positionLineNumber}, ${e.selection.positionColumn})`);203}));204disposables.add(editor.onDidChangeModelContent((e) => {205calls.push(`listener2 - contentchange(${e.changes.reduce<any[]>((aggr, c) => [...aggr, c.text, c.rangeOffset, c.rangeLength], []).join(', ')})`);206}));207disposables.add(editor.onDidChangeCursorSelection((e) => {208calls.push(`listener2 - cursorchange(${e.selection.positionLineNumber}, ${e.selection.positionColumn})`);209}));210211viewModel.type('a', 'test');212213assert.deepStrictEqual(calls, ([214'listener1 - contentchange(a, 0, 0)',215'listener2 - contentchange(a, 0, 0)',216'listener1 - cursorchange(1, 2)',217'listener2 - cursorchange(1, 2)',218]));219220disposables.dispose();221});222});223224});225226227