Path: blob/main/extensions/copilot/src/extension/prompt/node/test/positionOffsetTransformer.spec.ts
13405 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 { beforeEach, suite, test } from 'vitest';7import { PositionOffsetTransformer } from '../../../../platform/editing/common/positionOffsetTransformer';8import { Position, Range, TextEdit } from '../../../../vscodeTypes';910suite('PositionOffsetTransformer', () => {11const sampleText = `line1\nline2\nline3`;1213let transformer: PositionOffsetTransformer;1415beforeEach(() => {16transformer = new PositionOffsetTransformer(sampleText);17});1819test('should initialize correctly', () => {20assert.equal(transformer.getLineCount(), 3);21});2223test('should get correct offset for a position', () => {24const position = new Position(1, 2);25const offset = transformer.getOffset(position);26assert.equal(offset, 8); // 6 (line1\n) + 2 (line2)27});2829test('should get correct position for an offset', () => {30const offset = 8;31const position = transformer.getPosition(offset);32assert.equal(position.line, 1);33assert.equal(position.character, 2);34});3536test('should convert range to offset range and back', () => {37const range = new Range(new Position(0, 1), new Position(1, 2));38const offsetRange = transformer.toOffsetRange(range);39assert.equal(offsetRange.start, 1);40assert.equal(offsetRange.endExclusive, 8);4142const newRange = transformer.toRange(offsetRange);43assert.equal(newRange.start.line, 0);44assert.equal(newRange.start.character, 1);45assert.equal(newRange.end.line, 1);46assert.equal(newRange.end.character, 2);47});4849test('should apply offset edits correctly', () => {50const edits = [51new TextEdit(new Range(new Position(0, 0), new Position(0, 5)), 'Hello'),52new TextEdit(new Range(new Position(1, 0), new Position(1, 5)), 'World')53];54const offsetEdit = transformer.toOffsetEdit(edits);55transformer.applyOffsetEdits(offsetEdit);5657const newText = transformer.getText();58assert.equal(newText, 'Hello\nWorld\nline3');59});6061test('should validate position correctly', () => {62const invalidPosition = new Position(10, 10);63const validPosition = transformer.validatePosition(invalidPosition);64assert.equal(validPosition.line, 2);65assert.equal(validPosition.character, 5);66});6768test('should validate range correctly', () => {69const invalidRange = new Range(new Position(10, 10), new Position(20, 20));70const validRange = transformer.validateRange(invalidRange);71assert.equal(validRange.start.line, 2);72assert.equal(validRange.start.character, 5);73assert.equal(validRange.end.line, 2);74assert.equal(validRange.end.character, 5);75});7677test('should apply offset edits with insertion correctly', () => {78const edits = [79new TextEdit(new Range(new Position(0, 5), new Position(0, 5)), 'Hello '),80new TextEdit(new Range(new Position(1, 5), new Position(1, 5)), ' World')81];82const offsetEdit = transformer.toOffsetEdit(edits);83transformer.applyOffsetEdits(offsetEdit);8485const newText = transformer.getText();86assert.equal(newText, 'line1Hello \nline2 World\nline3');8788// Additional assertions89assert.equal(transformer.getPosition(11).line, 0);90assert.equal(transformer.getPosition(11).character, 11);91assert.equal(transformer.getPosition(12).line, 1);92assert.equal(transformer.getPosition(12).character, 0);93assert.equal(transformer.getOffset(new Position(1, 0)), 12);94assert.equal(transformer.getOffset(new Position(0, 11)), 11);95});9697test('should apply offset edits with deletion correctly', () => {98const edits = [99new TextEdit(new Range(new Position(0, 0), new Position(0, 5)), ''),100new TextEdit(new Range(new Position(1, 0), new Position(1, 5)), '')101];102const offsetEdit = transformer.toOffsetEdit(edits);103transformer.applyOffsetEdits(offsetEdit);104105const newText = transformer.getText();106assert.equal(newText, '\n\nline3');107108// Additional assertions109assert.equal(transformer.getPosition(0).line, 0);110assert.equal(transformer.getPosition(0).character, 0);111assert.equal(transformer.getPosition(1).line, 1);112assert.equal(transformer.getPosition(1).character, 0);113assert.equal(transformer.getOffset(new Position(0, 0)), 0);114assert.equal(transformer.getOffset(new Position(1, 0)), 1);115assert.equal(transformer.getOffset(new Position(2, 0)), 2);116});117118test('should apply offset edits with mixed edits correctly', () => {119const edits = [120new TextEdit(new Range(new Position(0, 0), new Position(0, 5)), 'Hello'),121new TextEdit(new Range(new Position(1, 0), new Position(1, 5)), 'World'),122new TextEdit(new Range(new Position(2, 0), new Position(2, 5)), 'Test')123];124const offsetEdit = transformer.toOffsetEdit(edits);125transformer.applyOffsetEdits(offsetEdit);126127const newText = transformer.getText();128assert.equal(newText, 'Hello\nWorld\nTest');129130// Additional assertions131assert.equal(transformer.getPosition(5).line, 0);132assert.equal(transformer.getPosition(5).character, 5);133assert.equal(transformer.getPosition(6).line, 1);134assert.equal(transformer.getPosition(6).character, 0);135assert.equal(transformer.getOffset(new Position(1, 0)), 6);136});137138test('should apply offset edits with multi-line insertion correctly', () => {139const edits = [140new TextEdit(new Range(new Position(0, 5), new Position(0, 5)), '\nInserted\nText\n')141];142const offsetEdit = transformer.toOffsetEdit(edits);143transformer.applyOffsetEdits(offsetEdit);144145const newText = transformer.getText();146assert.equal(newText, 'line1\nInserted\nText\n\nline2\nline3');147148// Additional assertions149assert.equal(transformer.getPosition(6).line, 1);150assert.equal(transformer.getPosition(6).character, 0);151assert.equal(transformer.getPosition(14).line, 1);152assert.equal(transformer.getPosition(14).character, 8);153assert.equal(transformer.getPosition(15).line, 2);154assert.equal(transformer.getPosition(15).character, 0);155assert.equal(transformer.getOffset(new Position(1, 0)), 6);156assert.equal(transformer.getOffset(new Position(1, 8)), 14);157assert.equal(transformer.getOffset(new Position(2, 0)), 15);158});159160test('should apply offset edits with multi-line insertion correctly with CRLF', () => {161const sampleTextWithCRLF = `line1\r\nline2\r\nline3`;162transformer = new PositionOffsetTransformer(sampleTextWithCRLF);163164const edits = [165new TextEdit(new Range(new Position(0, 5), new Position(0, 5)), '\r\nInserted\r\nText\r\n')166];167const offsetEdit = transformer.toOffsetEdit(edits);168transformer.applyOffsetEdits(offsetEdit);169170const newText = transformer.getText();171assert.equal(newText, 'line1\r\nInserted\r\nText\r\n\r\nline2\r\nline3');172173// Additional assertions174assert.equal(transformer.getPosition(7).line, 1);175assert.equal(transformer.getPosition(7).character, 0);176assert.equal(transformer.getPosition(15).line, 1);177assert.equal(transformer.getPosition(15).character, 8);178assert.equal(transformer.getPosition(17).line, 2);179assert.equal(transformer.getPosition(17).character, 0);180assert.equal(transformer.getOffset(new Position(1, 0)), 7);181assert.equal(transformer.getOffset(new Position(1, 8)), 15);182assert.equal(transformer.getOffset(new Position(2, 0)), 17);183});184});185186187