Path: blob/main/src/vs/editor/test/browser/viewModel/viewModelImpl.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 { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../base/test/common/utils.js';7import { Position } from '../../../common/core/position.js';8import { Range } from '../../../common/core/range.js';9import { EndOfLineSequence, PositionAffinity } from '../../../common/model.js';10import { ViewEventHandler } from '../../../common/viewEventHandler.js';11import { ViewEvent } from '../../../common/viewEvents.js';12import { testViewModel } from './testViewModel.js';1314suite('ViewModel', () => {1516ensureNoDisposablesAreLeakedInTestSuite();1718test('issue #21073: SplitLinesCollection: attempt to access a \'newer\' model', () => {19const text = [''];20const opts = {21lineNumbersMinChars: 122};23testViewModel(text, opts, (viewModel, model) => {24assert.strictEqual(viewModel.getLineCount(), 1);2526viewModel.setViewport(1, 1, 1);2728model.applyEdits([{29range: new Range(1, 1, 1, 1),30text: [31'line01',32'line02',33'line03',34'line04',35'line05',36'line06',37'line07',38'line08',39'line09',40'line10',41].join('\n')42}]);4344assert.strictEqual(viewModel.getLineCount(), 10);45});46});4748test('issue #44805: SplitLinesCollection: attempt to access a \'newer\' model', () => {49const text = [''];50testViewModel(text, {}, (viewModel, model) => {51assert.strictEqual(viewModel.getLineCount(), 1);5253model.pushEditOperations([], [{54range: new Range(1, 1, 1, 1),55text: '\ninsert1'56}], () => ([]));5758model.pushEditOperations([], [{59range: new Range(1, 1, 1, 1),60text: '\ninsert2'61}], () => ([]));6263model.pushEditOperations([], [{64range: new Range(1, 1, 1, 1),65text: '\ninsert3'66}], () => ([]));6768const viewLineCount: number[] = [];6970viewLineCount.push(viewModel.getLineCount());71const eventHandler = new class extends ViewEventHandler {72override handleEvents(events: ViewEvent[]): void {73// Access the view model74viewLineCount.push(viewModel.getLineCount());75}76};77viewModel.addViewEventHandler(eventHandler);78model.undo();79viewLineCount.push(viewModel.getLineCount());8081assert.deepStrictEqual(viewLineCount, [4, 1, 1, 1, 1]);8283viewModel.removeViewEventHandler(eventHandler);84eventHandler.dispose();85});86});8788test('issue #44805: No visible lines via API call', () => {89const text = [90'line1',91'line2',92'line3'93];94testViewModel(text, {}, (viewModel, model) => {95assert.strictEqual(viewModel.getLineCount(), 3);96viewModel.setHiddenAreas([new Range(1, 1, 3, 1)]);97assert.ok(viewModel.getVisibleRanges() !== null);98});99});100101test('issue #44805: No visible lines via undoing', () => {102const text = [103''104];105testViewModel(text, {}, (viewModel, model) => {106assert.strictEqual(viewModel.getLineCount(), 1);107108model.pushEditOperations([], [{109range: new Range(1, 1, 1, 1),110text: 'line1\nline2\nline3'111}], () => ([]));112113viewModel.setHiddenAreas([new Range(1, 1, 1, 1)]);114assert.strictEqual(viewModel.getLineCount(), 2);115116model.undo();117assert.ok(viewModel.getVisibleRanges() !== null);118});119});120121function assertGetPlainTextToCopy(text: string[], ranges: Range[], emptySelectionClipboard: boolean, expected: string | string[]): void {122testViewModel(text, {}, (viewModel, model) => {123const actual = viewModel.getPlainTextToCopy(ranges, emptySelectionClipboard, false);124assert.deepStrictEqual(actual, expected);125});126}127128const USUAL_TEXT = [129'',130'line2',131'line3',132'line4',133''134];135136test('getPlainTextToCopy 0/1', () => {137assertGetPlainTextToCopy(138USUAL_TEXT,139[140new Range(2, 2, 2, 2)141],142false,143''144);145});146147test('getPlainTextToCopy 0/1 - emptySelectionClipboard', () => {148assertGetPlainTextToCopy(149USUAL_TEXT,150[151new Range(2, 2, 2, 2)152],153true,154'line2\n'155);156});157158test('getPlainTextToCopy 1/1', () => {159assertGetPlainTextToCopy(160USUAL_TEXT,161[162new Range(2, 2, 2, 6)163],164false,165'ine2'166);167});168169test('getPlainTextToCopy 1/1 - emptySelectionClipboard', () => {170assertGetPlainTextToCopy(171USUAL_TEXT,172[173new Range(2, 2, 2, 6)174],175true,176'ine2'177);178});179180test('getPlainTextToCopy 0/2', () => {181assertGetPlainTextToCopy(182USUAL_TEXT,183[184new Range(2, 2, 2, 2),185new Range(3, 2, 3, 2),186],187false,188''189);190});191192test('getPlainTextToCopy 0/2 - emptySelectionClipboard', () => {193assertGetPlainTextToCopy(194USUAL_TEXT,195[196new Range(2, 2, 2, 2),197new Range(3, 2, 3, 2),198],199true,200'line2\nline3\n'201);202});203204test('getPlainTextToCopy 1/2', () => {205assertGetPlainTextToCopy(206USUAL_TEXT,207[208new Range(2, 2, 2, 6),209new Range(3, 2, 3, 2),210],211false,212'ine2'213);214});215216test('getPlainTextToCopy 1/2 - emptySelectionClipboard', () => {217assertGetPlainTextToCopy(218USUAL_TEXT,219[220new Range(2, 2, 2, 6),221new Range(3, 2, 3, 2),222],223true,224['ine2', 'line3']225);226});227228test('getPlainTextToCopy 2/2', () => {229assertGetPlainTextToCopy(230USUAL_TEXT,231[232new Range(2, 2, 2, 6),233new Range(3, 2, 3, 6),234],235false,236['ine2', 'ine3']237);238});239240test('getPlainTextToCopy 2/2 reversed', () => {241assertGetPlainTextToCopy(242USUAL_TEXT,243[244new Range(3, 2, 3, 6),245new Range(2, 2, 2, 6),246],247false,248['ine2', 'ine3']249);250});251252test('getPlainTextToCopy 0/3 - emptySelectionClipboard', () => {253assertGetPlainTextToCopy(254USUAL_TEXT,255[256new Range(2, 2, 2, 2),257new Range(2, 3, 2, 3),258new Range(3, 2, 3, 2),259],260true,261'line2\nline3\n'262);263});264265test('issue #22688 - always use CRLF for clipboard on Windows', () => {266testViewModel(USUAL_TEXT, {}, (viewModel, model) => {267model.setEOL(EndOfLineSequence.LF);268const actual = viewModel.getPlainTextToCopy([new Range(2, 1, 5, 1)], true, true);269assert.deepStrictEqual(actual, 'line2\r\nline3\r\nline4\r\n');270});271});272273test('issue #40926: Incorrect spacing when inserting new line after multiple folded blocks of code', () => {274testViewModel(275[276'foo = {',277' foobar: function() {',278' this.foobar();',279' },',280' foobar: function() {',281' this.foobar();',282' },',283' foobar: function() {',284' this.foobar();',285' },',286'}',287], {}, (viewModel, model) => {288viewModel.setHiddenAreas([289new Range(3, 1, 3, 1),290new Range(6, 1, 6, 1),291new Range(9, 1, 9, 1),292]);293294model.applyEdits([295{ range: new Range(4, 7, 4, 7), text: '\n ' },296{ range: new Range(7, 7, 7, 7), text: '\n ' },297{ range: new Range(10, 7, 10, 7), text: '\n ' }298]);299300assert.strictEqual(viewModel.getLineCount(), 11);301}302);303});304305test('normalizePosition with multiple touching injected text', () => {306testViewModel(307[308'just some text'309],310{},311(viewModel, model) => {312model.deltaDecorations([], [313{314range: new Range(1, 8, 1, 8),315options: {316description: 'test',317before: {318content: 'bar'319},320showIfCollapsed: true321}322},323{324range: new Range(1, 8, 1, 8),325options: {326description: 'test',327before: {328content: 'bz'329},330showIfCollapsed: true331}332},333]);334335// just sobarbzme text336337assert.deepStrictEqual(viewModel.normalizePosition(new Position(1, 8), PositionAffinity.None), new Position(1, 8));338assert.deepStrictEqual(viewModel.normalizePosition(new Position(1, 9), PositionAffinity.None), new Position(1, 8));339assert.deepStrictEqual(viewModel.normalizePosition(new Position(1, 11), PositionAffinity.None), new Position(1, 11));340assert.deepStrictEqual(viewModel.normalizePosition(new Position(1, 12), PositionAffinity.None), new Position(1, 11));341assert.deepStrictEqual(viewModel.normalizePosition(new Position(1, 13), PositionAffinity.None), new Position(1, 13));342343assert.deepStrictEqual(viewModel.normalizePosition(new Position(1, 8), PositionAffinity.Left), new Position(1, 8));344assert.deepStrictEqual(viewModel.normalizePosition(new Position(1, 9), PositionAffinity.Left), new Position(1, 8));345assert.deepStrictEqual(viewModel.normalizePosition(new Position(1, 11), PositionAffinity.Left), new Position(1, 8));346assert.deepStrictEqual(viewModel.normalizePosition(new Position(1, 12), PositionAffinity.Left), new Position(1, 8));347assert.deepStrictEqual(viewModel.normalizePosition(new Position(1, 13), PositionAffinity.Left), new Position(1, 8));348349assert.deepStrictEqual(viewModel.normalizePosition(new Position(1, 8), PositionAffinity.Right), new Position(1, 13));350assert.deepStrictEqual(viewModel.normalizePosition(new Position(1, 9), PositionAffinity.Right), new Position(1, 13));351assert.deepStrictEqual(viewModel.normalizePosition(new Position(1, 11), PositionAffinity.Right), new Position(1, 13));352assert.deepStrictEqual(viewModel.normalizePosition(new Position(1, 12), PositionAffinity.Right), new Position(1, 13));353assert.deepStrictEqual(viewModel.normalizePosition(new Position(1, 13), PositionAffinity.Right), new Position(1, 13));354}355);356});357358test('issue #193262: Incorrect implementation of modifyPosition', () => {359testViewModel(360[361'just some text'362],363{364wordWrap: 'wordWrapColumn',365wordWrapColumn: 5366},367(viewModel, model) => {368assert.deepStrictEqual(369new Position(3, 1),370viewModel.modifyPosition(new Position(3, 2), -1)371);372}373);374});375});376377378