Files
azuredatastudio/src/vs/editor/test/common/model/editableTextModelTestUtils.ts
2018-06-05 11:24:51 -07:00

124 lines
4.7 KiB
TypeScript

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { TextModel } from 'vs/editor/common/model/textModel';
import { MirrorTextModel } from 'vs/editor/common/model/mirrorTextModel';
import { Position } from 'vs/editor/common/core/position';
import { IModelContentChangedEvent } from 'vs/editor/common/model/textModelEvents';
import { EndOfLinePreference, IIdentifiedSingleEditOperation, EndOfLineSequence } from 'vs/editor/common/model';
export function testApplyEditsWithSyncedModels(original: string[], edits: IIdentifiedSingleEditOperation[], expected: string[], inputEditsAreInvalid: boolean = false): void {
var originalStr = original.join('\n');
var expectedStr = expected.join('\n');
assertSyncedModels(originalStr, (model, assertMirrorModels) => {
// Apply edits & collect inverse edits
var inverseEdits = model.applyEdits(edits);
// Assert edits produced expected result
assert.deepEqual(model.getValue(EndOfLinePreference.LF), expectedStr);
assertMirrorModels();
// Apply the inverse edits
var inverseInverseEdits = model.applyEdits(inverseEdits);
// Assert the inverse edits brought back model to original state
assert.deepEqual(model.getValue(EndOfLinePreference.LF), originalStr);
if (!inputEditsAreInvalid) {
const simplifyEdit = (edit: IIdentifiedSingleEditOperation) => {
return {
identifier: edit.identifier,
range: edit.range,
text: edit.text,
forceMoveMarkers: edit.forceMoveMarkers,
isAutoWhitespaceEdit: edit.isAutoWhitespaceEdit
};
};
// Assert the inverse of the inverse edits are the original edits
assert.deepEqual(inverseInverseEdits.map(simplifyEdit), edits.map(simplifyEdit));
}
assertMirrorModels();
});
}
const enum AssertDocumentLineMappingDirection {
OffsetToPosition,
PositionToOffset
}
function assertOneDirectionLineMapping(model: TextModel, direction: AssertDocumentLineMappingDirection, msg: string): void {
let allText = model.getValue();
let line = 1, column = 1, previousIsCarriageReturn = false;
for (let offset = 0; offset <= allText.length; offset++) {
// The position coordinate system cannot express the position between \r and \n
let position = new Position(line, column + (previousIsCarriageReturn ? -1 : 0));
if (direction === AssertDocumentLineMappingDirection.OffsetToPosition) {
let actualPosition = model.getPositionAt(offset);
assert.equal(actualPosition.toString(), position.toString(), msg + ' - getPositionAt mismatch for offset ' + offset);
} else {
// The position coordinate system cannot express the position between \r and \n
let expectedOffset = offset + (previousIsCarriageReturn ? -1 : 0);
let actualOffset = model.getOffsetAt(position);
assert.equal(actualOffset, expectedOffset, msg + ' - getOffsetAt mismatch for position ' + position.toString());
}
if (allText.charAt(offset) === '\n') {
line++;
column = 1;
} else {
column++;
}
previousIsCarriageReturn = (allText.charAt(offset) === '\r');
}
}
function assertLineMapping(model: TextModel, msg: string): void {
assertOneDirectionLineMapping(model, AssertDocumentLineMappingDirection.PositionToOffset, msg);
assertOneDirectionLineMapping(model, AssertDocumentLineMappingDirection.OffsetToPosition, msg);
}
export function assertSyncedModels(text: string, callback: (model: TextModel, assertMirrorModels: () => void) => void, setup: (model: TextModel) => void = null): void {
var model = new TextModel(text, TextModel.DEFAULT_CREATION_OPTIONS, null);
model.setEOL(EndOfLineSequence.LF);
assertLineMapping(model, 'model');
if (setup) {
setup(model);
assertLineMapping(model, 'model');
}
var mirrorModel2 = new MirrorTextModel(null, model.getLinesContent(), model.getEOL(), model.getVersionId());
var mirrorModel2PrevVersionId = model.getVersionId();
model.onDidChangeContent((e: IModelContentChangedEvent) => {
let versionId = e.versionId;
if (versionId < mirrorModel2PrevVersionId) {
console.warn('Model version id did not advance between edits (2)');
}
mirrorModel2PrevVersionId = versionId;
mirrorModel2.onEvents(e);
});
var assertMirrorModels = () => {
assertLineMapping(model, 'model');
assert.equal(mirrorModel2.getText(), model.getValue(), 'mirror model 2 text OK');
assert.equal(mirrorModel2.version, model.getVersionId(), 'mirror model 2 version OK');
};
callback(model, assertMirrorModels);
model.dispose();
mirrorModel2.dispose();
}