Path: blob/main/src/vs/editor/test/common/model/model.line.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 { Range } from '../../../common/core/range.js';8import { MetadataConsts } from '../../../common/encodedTokenAttributes.js';9import { EncodedTokenizationResult, IBackgroundTokenizationStore, IBackgroundTokenizer, IState, ITokenizationSupport, TokenizationRegistry, TokenizationResult } from '../../../common/languages.js';10import { ITextModel } from '../../../common/model.js';11import { computeIndentLevel } from '../../../common/model/utils.js';12import { ContiguousMultilineTokensBuilder } from '../../../common/tokens/contiguousMultilineTokensBuilder.js';13import { LineTokens } from '../../../common/tokens/lineTokens.js';14import { TestLineToken, TestLineTokenFactory } from '../core/testLineToken.js';15import { createTextModel } from '../testTextModel.js';1617interface ILineEdit {18startColumn: number;19endColumn: number;20text: string;21}2223function assertLineTokens(__actual: LineTokens, _expected: TestToken[]): void {24const tmp = TestToken.toTokens(_expected);25LineTokens.convertToEndOffset(tmp, __actual.getLineContent().length);26const expected = TestLineTokenFactory.inflateArr(tmp);27const _actual = __actual.inflate();28interface ITestToken {29endIndex: number;30type: string;31}32const actual: ITestToken[] = [];33for (let i = 0, len = _actual.getCount(); i < len; i++) {34actual[i] = {35endIndex: _actual.getEndOffset(i),36type: _actual.getClassName(i)37};38}39const decode = (token: TestLineToken) => {40return {41endIndex: token.endIndex,42type: token.getType()43};44};45assert.deepStrictEqual(actual, expected.map(decode));46}4748suite('ModelLine - getIndentLevel', () => {4950ensureNoDisposablesAreLeakedInTestSuite();5152function assertIndentLevel(text: string, expected: number, tabSize: number = 4): void {53const actual = computeIndentLevel(text, tabSize);54assert.strictEqual(actual, expected, text);55}5657test('getIndentLevel', () => {58assertIndentLevel('', -1);59assertIndentLevel(' ', -1);60assertIndentLevel(' \t', -1);61assertIndentLevel('Hello', 0);62assertIndentLevel(' Hello', 1);63assertIndentLevel(' Hello', 3);64assertIndentLevel('\tHello', 4);65assertIndentLevel(' \tHello', 4);66assertIndentLevel(' \tHello', 4);67assertIndentLevel(' \tHello', 4);68assertIndentLevel(' \tHello', 8);69assertIndentLevel(' \tHello', 8);70assertIndentLevel('\t Hello', 5);71assertIndentLevel('\t \tHello', 8);72});73});7475class TestToken {76public readonly startOffset: number;77public readonly color: number;7879constructor(startOffset: number, color: number) {80this.startOffset = startOffset;81this.color = color;82}8384public static toTokens(tokens: TestToken[]): Uint32Array;85public static toTokens(tokens: TestToken[] | null): Uint32Array | null {86if (tokens === null) {87return null;88}89const tokensLen = tokens.length;90const result = new Uint32Array((tokensLen << 1));91for (let i = 0; i < tokensLen; i++) {92const token = tokens[i];93result[(i << 1)] = token.startOffset;94result[(i << 1) + 1] = (95token.color << MetadataConsts.FOREGROUND_OFFSET96) >>> 0;97}98return result;99}100}101102class ManualTokenizationSupport implements ITokenizationSupport {103private readonly tokens = new Map<number, Uint32Array>();104private readonly stores = new Set<IBackgroundTokenizationStore>();105106public setLineTokens(lineNumber: number, tokens: Uint32Array): void {107const b = new ContiguousMultilineTokensBuilder();108b.add(lineNumber, tokens);109for (const s of this.stores) {110s.setTokens(b.finalize());111}112}113114getInitialState(): IState {115return new LineState(1);116}117118tokenize(line: string, hasEOL: boolean, state: IState): TokenizationResult {119throw new Error();120}121122tokenizeEncoded(line: string, hasEOL: boolean, state: IState): EncodedTokenizationResult {123const s = state as LineState;124return new EncodedTokenizationResult(this.tokens.get(s.lineNumber)!, new LineState(s.lineNumber + 1));125}126127/**128* Can be/return undefined if default background tokenization should be used.129*/130createBackgroundTokenizer?(textModel: ITextModel, store: IBackgroundTokenizationStore): IBackgroundTokenizer | undefined {131this.stores.add(store);132return {133dispose: () => {134this.stores.delete(store);135},136requestTokens(startLineNumber, endLineNumberExclusive) {137},138};139}140}141142class LineState implements IState {143constructor(public readonly lineNumber: number) { }144clone(): IState {145return this;146}147equals(other: IState): boolean {148return (other as LineState).lineNumber === this.lineNumber;149}150}151152suite('ModelLinesTokens', () => {153154ensureNoDisposablesAreLeakedInTestSuite();155156interface IBufferLineState {157text: string;158tokens: TestToken[];159}160161interface IEdit {162range: Range;163text: string;164}165166function testApplyEdits(initial: IBufferLineState[], edits: IEdit[], expected: IBufferLineState[]): void {167const initialText = initial.map(el => el.text).join('\n');168169const s = new ManualTokenizationSupport();170const d = TokenizationRegistry.register('test', s);171172const model = createTextModel(initialText, 'test');173model.onBeforeAttached();174for (let lineIndex = 0; lineIndex < initial.length; lineIndex++) {175const lineTokens = initial[lineIndex].tokens;176const lineTextLength = model.getLineMaxColumn(lineIndex + 1) - 1;177const tokens = TestToken.toTokens(lineTokens);178LineTokens.convertToEndOffset(tokens, lineTextLength);179s.setLineTokens(lineIndex + 1, tokens);180}181182model.applyEdits(edits.map((ed) => ({183identifier: null,184range: ed.range,185text: ed.text,186forceMoveMarkers: false187})));188189for (let lineIndex = 0; lineIndex < expected.length; lineIndex++) {190const actualLine = model.getLineContent(lineIndex + 1);191const actualTokens = model.tokenization.getLineTokens(lineIndex + 1);192assert.strictEqual(actualLine, expected[lineIndex].text);193assertLineTokens(actualTokens, expected[lineIndex].tokens);194}195196model.dispose();197d.dispose();198}199200test('single delete 1', () => {201testApplyEdits(202[{203text: 'hello world',204tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(6, 3)]205}],206[{ range: new Range(1, 1, 1, 2), text: '' }],207[{208text: 'ello world',209tokens: [new TestToken(0, 1), new TestToken(4, 2), new TestToken(5, 3)]210}]211);212});213214test('single delete 2', () => {215testApplyEdits(216[{217text: 'helloworld',218tokens: [new TestToken(0, 1), new TestToken(5, 2)]219}],220[{ range: new Range(1, 3, 1, 8), text: '' }],221[{222text: 'herld',223tokens: [new TestToken(0, 1), new TestToken(2, 2)]224}]225);226});227228test('single delete 3', () => {229testApplyEdits(230[{231text: 'hello world',232tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(6, 3)]233}],234[{ range: new Range(1, 1, 1, 6), text: '' }],235[{236text: ' world',237tokens: [new TestToken(0, 2), new TestToken(1, 3)]238}]239);240});241242test('single delete 4', () => {243testApplyEdits(244[{245text: 'hello world',246tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(6, 3)]247}],248[{ range: new Range(1, 2, 1, 7), text: '' }],249[{250text: 'hworld',251tokens: [new TestToken(0, 1), new TestToken(1, 3)]252}]253);254});255256test('single delete 5', () => {257testApplyEdits(258[{259text: 'hello world',260tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(6, 3)]261}],262[{ range: new Range(1, 1, 1, 12), text: '' }],263[{264text: '',265tokens: [new TestToken(0, 1)]266}]267);268});269270test('multi delete 6', () => {271testApplyEdits(272[{273text: 'hello world',274tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(6, 3)]275}, {276text: 'hello world',277tokens: [new TestToken(0, 4), new TestToken(5, 5), new TestToken(6, 6)]278}, {279text: 'hello world',280tokens: [new TestToken(0, 7), new TestToken(5, 8), new TestToken(6, 9)]281}],282[{ range: new Range(1, 6, 3, 6), text: '' }],283[{284text: 'hello world',285tokens: [new TestToken(0, 1), new TestToken(5, 8), new TestToken(6, 9)]286}]287);288});289290test('multi delete 7', () => {291testApplyEdits(292[{293text: 'hello world',294tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(6, 3)]295}, {296text: 'hello world',297tokens: [new TestToken(0, 4), new TestToken(5, 5), new TestToken(6, 6)]298}, {299text: 'hello world',300tokens: [new TestToken(0, 7), new TestToken(5, 8), new TestToken(6, 9)]301}],302[{ range: new Range(1, 12, 3, 12), text: '' }],303[{304text: 'hello world',305tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(6, 3)]306}]307);308});309310test('multi delete 8', () => {311testApplyEdits(312[{313text: 'hello world',314tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(6, 3)]315}, {316text: 'hello world',317tokens: [new TestToken(0, 4), new TestToken(5, 5), new TestToken(6, 6)]318}, {319text: 'hello world',320tokens: [new TestToken(0, 7), new TestToken(5, 8), new TestToken(6, 9)]321}],322[{ range: new Range(1, 1, 3, 1), text: '' }],323[{324text: 'hello world',325tokens: [new TestToken(0, 7), new TestToken(5, 8), new TestToken(6, 9)]326}]327);328});329330test('multi delete 9', () => {331testApplyEdits(332[{333text: 'hello world',334tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(6, 3)]335}, {336text: 'hello world',337tokens: [new TestToken(0, 4), new TestToken(5, 5), new TestToken(6, 6)]338}, {339text: 'hello world',340tokens: [new TestToken(0, 7), new TestToken(5, 8), new TestToken(6, 9)]341}],342[{ range: new Range(1, 12, 3, 1), text: '' }],343[{344text: 'hello worldhello world',345tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(6, 3), new TestToken(11, 7), new TestToken(16, 8), new TestToken(17, 9)]346}]347);348});349350test('single insert 1', () => {351testApplyEdits(352[{353text: 'hello world',354tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(6, 3)]355}],356[{ range: new Range(1, 1, 1, 1), text: 'xx' }],357[{358text: 'xxhello world',359tokens: [new TestToken(0, 1), new TestToken(7, 2), new TestToken(8, 3)]360}]361);362});363364test('single insert 2', () => {365testApplyEdits(366[{367text: 'hello world',368tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(6, 3)]369}],370[{ range: new Range(1, 2, 1, 2), text: 'xx' }],371[{372text: 'hxxello world',373tokens: [new TestToken(0, 1), new TestToken(7, 2), new TestToken(8, 3)]374}]375);376});377378test('single insert 3', () => {379testApplyEdits(380[{381text: 'hello world',382tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(6, 3)]383}],384[{ range: new Range(1, 6, 1, 6), text: 'xx' }],385[{386text: 'helloxx world',387tokens: [new TestToken(0, 1), new TestToken(7, 2), new TestToken(8, 3)]388}]389);390});391392test('single insert 4', () => {393testApplyEdits(394[{395text: 'hello world',396tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(6, 3)]397}],398[{ range: new Range(1, 7, 1, 7), text: 'xx' }],399[{400text: 'hello xxworld',401tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(8, 3)]402}]403);404});405406test('single insert 5', () => {407testApplyEdits(408[{409text: 'hello world',410tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(6, 3)]411}],412[{ range: new Range(1, 12, 1, 12), text: 'xx' }],413[{414text: 'hello worldxx',415tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(6, 3)]416}]417);418});419420test('multi insert 6', () => {421testApplyEdits(422[{423text: 'hello world',424tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(6, 3)]425}],426[{ range: new Range(1, 1, 1, 1), text: '\n' }],427[{428text: '',429tokens: [new TestToken(0, 1)]430}, {431text: 'hello world',432tokens: [new TestToken(0, 1)]433}]434);435});436437test('multi insert 7', () => {438testApplyEdits(439[{440text: 'hello world',441tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(6, 3)]442}],443[{ range: new Range(1, 12, 1, 12), text: '\n' }],444[{445text: 'hello world',446tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(6, 3)]447}, {448text: '',449tokens: [new TestToken(0, 1)]450}]451);452});453454test('multi insert 8', () => {455testApplyEdits(456[{457text: 'hello world',458tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(6, 3)]459}],460[{ range: new Range(1, 7, 1, 7), text: '\n' }],461[{462text: 'hello ',463tokens: [new TestToken(0, 1), new TestToken(5, 2)]464}, {465text: 'world',466tokens: [new TestToken(0, 1)]467}]468);469});470471test('multi insert 9', () => {472testApplyEdits(473[{474text: 'hello world',475tokens: [new TestToken(0, 1), new TestToken(5, 2), new TestToken(6, 3)]476}, {477text: 'hello world',478tokens: [new TestToken(0, 4), new TestToken(5, 5), new TestToken(6, 6)]479}],480[{ range: new Range(1, 7, 1, 7), text: 'xx\nyy' }],481[{482text: 'hello xx',483tokens: [new TestToken(0, 1), new TestToken(5, 2)]484}, {485text: 'yyworld',486tokens: [new TestToken(0, 1)]487}, {488text: 'hello world',489tokens: [new TestToken(0, 4), new TestToken(5, 5), new TestToken(6, 6)]490}]491);492});493494function testLineEditTokens(initialText: string, initialTokens: TestToken[], edits: ILineEdit[], expectedText: string, expectedTokens: TestToken[]): void {495testApplyEdits(496[{497text: initialText,498tokens: initialTokens499}],500edits.map((ed) => ({501range: new Range(1, ed.startColumn, 1, ed.endColumn),502text: ed.text503})),504[{505text: expectedText,506tokens: expectedTokens507}]508);509}510511test('insertion on empty line', () => {512const s = new ManualTokenizationSupport();513const d = TokenizationRegistry.register('test', s);514515const model = createTextModel('some text', 'test');516const tokens = TestToken.toTokens([new TestToken(0, 1)]);517LineTokens.convertToEndOffset(tokens, model.getLineMaxColumn(1) - 1);518s.setLineTokens(1, tokens);519520model.applyEdits([{521range: new Range(1, 1, 1, 10),522text: ''523}]);524525s.setLineTokens(1, new Uint32Array(0));526527model.applyEdits([{528range: new Range(1, 1, 1, 1),529text: 'a'530}]);531532const actualTokens = model.tokenization.getLineTokens(1);533assertLineTokens(actualTokens, [new TestToken(0, 1)]);534535model.dispose();536d.dispose();537});538539test('updates tokens on insertion 1', () => {540testLineEditTokens(541'abcd efgh',542[543new TestToken(0, 1),544new TestToken(4, 2),545new TestToken(5, 3)546],547[{548startColumn: 1,549endColumn: 1,550text: 'a',551}],552'aabcd efgh',553[554new TestToken(0, 1),555new TestToken(5, 2),556new TestToken(6, 3)557]558);559});560561test('updates tokens on insertion 2', () => {562testLineEditTokens(563'aabcd efgh',564[565new TestToken(0, 1),566new TestToken(5, 2),567new TestToken(6, 3)568],569[{570startColumn: 2,571endColumn: 2,572text: 'x',573}],574'axabcd efgh',575[576new TestToken(0, 1),577new TestToken(6, 2),578new TestToken(7, 3)579]580);581});582583test('updates tokens on insertion 3', () => {584testLineEditTokens(585'axabcd efgh',586[587new TestToken(0, 1),588new TestToken(6, 2),589new TestToken(7, 3)590],591[{592startColumn: 3,593endColumn: 3,594text: 'stu',595}],596'axstuabcd efgh',597[598new TestToken(0, 1),599new TestToken(9, 2),600new TestToken(10, 3)601]602);603});604605test('updates tokens on insertion 4', () => {606testLineEditTokens(607'axstuabcd efgh',608[609new TestToken(0, 1),610new TestToken(9, 2),611new TestToken(10, 3)612],613[{614startColumn: 10,615endColumn: 10,616text: '\t',617}],618'axstuabcd\t efgh',619[620new TestToken(0, 1),621new TestToken(10, 2),622new TestToken(11, 3)623]624);625});626627test('updates tokens on insertion 5', () => {628testLineEditTokens(629'axstuabcd\t efgh',630[631new TestToken(0, 1),632new TestToken(10, 2),633new TestToken(11, 3)634],635[{636startColumn: 12,637endColumn: 12,638text: 'dd',639}],640'axstuabcd\t ddefgh',641[642new TestToken(0, 1),643new TestToken(10, 2),644new TestToken(13, 3)645]646);647});648649test('updates tokens on insertion 6', () => {650testLineEditTokens(651'axstuabcd\t ddefgh',652[653new TestToken(0, 1),654new TestToken(10, 2),655new TestToken(13, 3)656],657[{658startColumn: 18,659endColumn: 18,660text: 'xyz',661}],662'axstuabcd\t ddefghxyz',663[664new TestToken(0, 1),665new TestToken(10, 2),666new TestToken(13, 3)667]668);669});670671test('updates tokens on insertion 7', () => {672testLineEditTokens(673'axstuabcd\t ddefghxyz',674[675new TestToken(0, 1),676new TestToken(10, 2),677new TestToken(13, 3)678],679[{680startColumn: 1,681endColumn: 1,682text: 'x',683}],684'xaxstuabcd\t ddefghxyz',685[686new TestToken(0, 1),687new TestToken(11, 2),688new TestToken(14, 3)689]690);691});692693test('updates tokens on insertion 8', () => {694testLineEditTokens(695'xaxstuabcd\t ddefghxyz',696[697new TestToken(0, 1),698new TestToken(11, 2),699new TestToken(14, 3)700],701[{702startColumn: 22,703endColumn: 22,704text: 'x',705}],706'xaxstuabcd\t ddefghxyzx',707[708new TestToken(0, 1),709new TestToken(11, 2),710new TestToken(14, 3)711]712);713});714715test('updates tokens on insertion 9', () => {716testLineEditTokens(717'xaxstuabcd\t ddefghxyzx',718[719new TestToken(0, 1),720new TestToken(11, 2),721new TestToken(14, 3)722],723[{724startColumn: 2,725endColumn: 2,726text: '',727}],728'xaxstuabcd\t ddefghxyzx',729[730new TestToken(0, 1),731new TestToken(11, 2),732new TestToken(14, 3)733]734);735});736737test('updates tokens on insertion 10', () => {738testLineEditTokens(739'',740[],741[{742startColumn: 1,743endColumn: 1,744text: 'a',745}],746'a',747[748new TestToken(0, 1)749]750);751});752753test('delete second token 2', () => {754testLineEditTokens(755'abcdefghij',756[757new TestToken(0, 1),758new TestToken(3, 2),759new TestToken(6, 3)760],761[{762startColumn: 4,763endColumn: 7,764text: '',765}],766'abcghij',767[768new TestToken(0, 1),769new TestToken(3, 3)770]771);772});773774test('insert right before second token', () => {775testLineEditTokens(776'abcdefghij',777[778new TestToken(0, 1),779new TestToken(3, 2),780new TestToken(6, 3)781],782[{783startColumn: 4,784endColumn: 4,785text: 'hello',786}],787'abchellodefghij',788[789new TestToken(0, 1),790new TestToken(8, 2),791new TestToken(11, 3)792]793);794});795796test('delete first char', () => {797testLineEditTokens(798'abcd efgh',799[800new TestToken(0, 1),801new TestToken(4, 2),802new TestToken(5, 3)803],804[{805startColumn: 1,806endColumn: 2,807text: '',808}],809'bcd efgh',810[811new TestToken(0, 1),812new TestToken(3, 2),813new TestToken(4, 3)814]815);816});817818test('delete 2nd and 3rd chars', () => {819testLineEditTokens(820'abcd efgh',821[822new TestToken(0, 1),823new TestToken(4, 2),824new TestToken(5, 3)825],826[{827startColumn: 2,828endColumn: 4,829text: '',830}],831'ad efgh',832[833new TestToken(0, 1),834new TestToken(2, 2),835new TestToken(3, 3)836]837);838});839840test('delete first token', () => {841testLineEditTokens(842'abcd efgh',843[844new TestToken(0, 1),845new TestToken(4, 2),846new TestToken(5, 3)847],848[{849startColumn: 1,850endColumn: 5,851text: '',852}],853' efgh',854[855new TestToken(0, 2),856new TestToken(1, 3)857]858);859});860861test('delete second token', () => {862testLineEditTokens(863'abcd efgh',864[865new TestToken(0, 1),866new TestToken(4, 2),867new TestToken(5, 3)868],869[{870startColumn: 5,871endColumn: 6,872text: '',873}],874'abcdefgh',875[876new TestToken(0, 1),877new TestToken(4, 3)878]879);880});881882test('delete second token + a bit of the third one', () => {883testLineEditTokens(884'abcd efgh',885[886new TestToken(0, 1),887new TestToken(4, 2),888new TestToken(5, 3)889],890[{891startColumn: 5,892endColumn: 7,893text: '',894}],895'abcdfgh',896[897new TestToken(0, 1),898new TestToken(4, 3)899]900);901});902903test('delete second and third token', () => {904testLineEditTokens(905'abcd efgh',906[907new TestToken(0, 1),908new TestToken(4, 2),909new TestToken(5, 3)910],911[{912startColumn: 5,913endColumn: 10,914text: '',915}],916'abcd',917[918new TestToken(0, 1)919]920);921});922923test('delete everything', () => {924testLineEditTokens(925'abcd efgh',926[927new TestToken(0, 1),928new TestToken(4, 2),929new TestToken(5, 3)930],931[{932startColumn: 1,933endColumn: 10,934text: '',935}],936'',937[938new TestToken(0, 1)939]940);941});942943test('noop', () => {944testLineEditTokens(945'abcd efgh',946[947new TestToken(0, 1),948new TestToken(4, 2),949new TestToken(5, 3)950],951[{952startColumn: 1,953endColumn: 1,954text: '',955}],956'abcd efgh',957[958new TestToken(0, 1),959new TestToken(4, 2),960new TestToken(5, 3)961]962);963});964965test('equivalent to deleting first two chars', () => {966testLineEditTokens(967'abcd efgh',968[969new TestToken(0, 1),970new TestToken(4, 2),971new TestToken(5, 3)972],973[{974startColumn: 1,975endColumn: 3,976text: '',977}],978'cd efgh',979[980new TestToken(0, 1),981new TestToken(2, 2),982new TestToken(3, 3)983]984);985});986987test('equivalent to deleting from 5 to the end', () => {988testLineEditTokens(989'abcd efgh',990[991new TestToken(0, 1),992new TestToken(4, 2),993new TestToken(5, 3)994],995[{996startColumn: 5,997endColumn: 10,998text: '',999}],1000'abcd',1001[1002new TestToken(0, 1)1003]1004);1005});10061007test('updates tokens on replace 1', () => {1008testLineEditTokens(1009'Hello world, ciao',1010[1011new TestToken(0, 1),1012new TestToken(5, 0),1013new TestToken(6, 2),1014new TestToken(11, 0),1015new TestToken(13, 0)1016],1017[{1018startColumn: 1,1019endColumn: 6,1020text: 'Hi',1021}],1022'Hi world, ciao',1023[1024new TestToken(0, 0),1025new TestToken(3, 2),1026new TestToken(8, 0),1027new TestToken(10, 0),1028]1029);1030});10311032test('updates tokens on replace 2', () => {1033testLineEditTokens(1034'Hello world, ciao',1035[1036new TestToken(0, 1),1037new TestToken(5, 0),1038new TestToken(6, 2),1039new TestToken(11, 0),1040new TestToken(13, 0),1041],1042[{1043startColumn: 1,1044endColumn: 6,1045text: 'Hi',1046}, {1047startColumn: 8,1048endColumn: 12,1049text: 'my friends',1050}],1051'Hi wmy friends, ciao',1052[1053new TestToken(0, 0),1054new TestToken(3, 2),1055new TestToken(14, 0),1056new TestToken(16, 0),1057]1058);1059});10601061function testLineSplitTokens(initialText: string, initialTokens: TestToken[], splitColumn: number, expectedText1: string, expectedText2: string, expectedTokens: TestToken[]): void {1062testApplyEdits(1063[{1064text: initialText,1065tokens: initialTokens1066}],1067[{1068range: new Range(1, splitColumn, 1, splitColumn),1069text: '\n'1070}],1071[{1072text: expectedText1,1073tokens: expectedTokens1074}, {1075text: expectedText2,1076tokens: [new TestToken(0, 1)]1077}]1078);1079}10801081test('split at the beginning', () => {1082testLineSplitTokens(1083'abcd efgh',1084[1085new TestToken(0, 1),1086new TestToken(4, 2),1087new TestToken(5, 3)1088],10891,1090'',1091'abcd efgh',1092[1093new TestToken(0, 1),1094]1095);1096});10971098test('split at the end', () => {1099testLineSplitTokens(1100'abcd efgh',1101[1102new TestToken(0, 1),1103new TestToken(4, 2),1104new TestToken(5, 3)1105],110610,1107'abcd efgh',1108'',1109[1110new TestToken(0, 1),1111new TestToken(4, 2),1112new TestToken(5, 3)1113]1114);1115});11161117test('split inthe middle 1', () => {1118testLineSplitTokens(1119'abcd efgh',1120[1121new TestToken(0, 1),1122new TestToken(4, 2),1123new TestToken(5, 3)1124],11255,1126'abcd',1127' efgh',1128[1129new TestToken(0, 1)1130]1131);1132});11331134test('split inthe middle 2', () => {1135testLineSplitTokens(1136'abcd efgh',1137[1138new TestToken(0, 1),1139new TestToken(4, 2),1140new TestToken(5, 3)1141],11426,1143'abcd ',1144'efgh',1145[1146new TestToken(0, 1),1147new TestToken(4, 2)1148]1149);1150});11511152function testLineAppendTokens(aText: string, aTokens: TestToken[], bText: string, bTokens: TestToken[], expectedText: string, expectedTokens: TestToken[]): void {1153testApplyEdits(1154[{1155text: aText,1156tokens: aTokens1157}, {1158text: bText,1159tokens: bTokens1160}],1161[{1162range: new Range(1, aText.length + 1, 2, 1),1163text: ''1164}],1165[{1166text: expectedText,1167tokens: expectedTokens1168}]1169);1170}11711172test('append empty 1', () => {1173testLineAppendTokens(1174'abcd efgh',1175[1176new TestToken(0, 1),1177new TestToken(4, 2),1178new TestToken(5, 3)1179],1180'',1181[],1182'abcd efgh',1183[1184new TestToken(0, 1),1185new TestToken(4, 2),1186new TestToken(5, 3)1187]1188);1189});11901191test('append empty 2', () => {1192testLineAppendTokens(1193'',1194[],1195'abcd efgh',1196[1197new TestToken(0, 1),1198new TestToken(4, 2),1199new TestToken(5, 3)1200],1201'abcd efgh',1202[1203new TestToken(0, 1),1204new TestToken(4, 2),1205new TestToken(5, 3)1206]1207);1208});12091210test('append 1', () => {1211testLineAppendTokens(1212'abcd efgh',1213[1214new TestToken(0, 1),1215new TestToken(4, 2),1216new TestToken(5, 3)1217],1218'abcd efgh',1219[1220new TestToken(0, 4),1221new TestToken(4, 5),1222new TestToken(5, 6)1223],1224'abcd efghabcd efgh',1225[1226new TestToken(0, 1),1227new TestToken(4, 2),1228new TestToken(5, 3),1229new TestToken(9, 4),1230new TestToken(13, 5),1231new TestToken(14, 6)1232]1233);1234});12351236test('append 2', () => {1237testLineAppendTokens(1238'abcd ',1239[1240new TestToken(0, 1),1241new TestToken(4, 2)1242],1243'efgh',1244[1245new TestToken(0, 3)1246],1247'abcd efgh',1248[1249new TestToken(0, 1),1250new TestToken(4, 2),1251new TestToken(5, 3)1252]1253);1254});12551256test('append 3', () => {1257testLineAppendTokens(1258'abcd',1259[1260new TestToken(0, 1),1261],1262' efgh',1263[1264new TestToken(0, 2),1265new TestToken(1, 3)1266],1267'abcd efgh',1268[1269new TestToken(0, 1),1270new TestToken(4, 2),1271new TestToken(5, 3)1272]1273);1274});1275});127612771278