mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-12 11:08:31 -05:00
SQL Operations Studio Public Preview 1 (0.23) release source code
This commit is contained in:
57
src/vs/editor/test/browser/controller/imeTester.html
Normal file
57
src/vs/editor/test/browser/controller/imeTester.html
Normal file
@@ -0,0 +1,57 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||
<style>
|
||||
.container {
|
||||
border-top: 1px solid #ccc;
|
||||
padding-top: 5px;
|
||||
clear: both;
|
||||
margin-top: 30px;
|
||||
}
|
||||
.container .title {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.container button {
|
||||
float: left;
|
||||
}
|
||||
.container textarea {
|
||||
float: left;
|
||||
width: 200px;
|
||||
height: 100px;
|
||||
margin-left: 50px;
|
||||
}
|
||||
.container .output {
|
||||
float: left;
|
||||
background: lightblue;
|
||||
margin: 0;
|
||||
margin-left: 50px;
|
||||
}
|
||||
|
||||
.container .check {
|
||||
float: left;
|
||||
background: grey;
|
||||
margin: 0;
|
||||
margin-left: 50px;
|
||||
}
|
||||
.container .check.good {
|
||||
background: lightgreen;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h3>Detailed setup steps at https://github.com/Microsoft/vscode/wiki/IME-Test</h3>
|
||||
<script src="../../../../loader.js"></script>
|
||||
<script>
|
||||
require.config({
|
||||
baseUrl: '../../../../../../out'
|
||||
});
|
||||
|
||||
require(['vs/editor/test/browser/controller/imeTester'], function(imeTester) {
|
||||
// console.log('loaded', imeTester);
|
||||
// imeTester.createTest();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
183
src/vs/editor/test/browser/controller/imeTester.ts
Normal file
183
src/vs/editor/test/browser/controller/imeTester.ts
Normal file
@@ -0,0 +1,183 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 { TextAreaInput, ITextAreaInputHost } from 'vs/editor/browser/controller/textAreaInput';
|
||||
import { ISimpleModel, TextAreaState, PagedScreenReaderStrategy } from 'vs/editor/browser/controller/textAreaState';
|
||||
import { Range, IRange } from 'vs/editor/common/core/range';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { createFastDomNode } from 'vs/base/browser/fastDomNode';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
|
||||
// To run this test, open imeTester.html
|
||||
|
||||
class SingleLineTestModel implements ISimpleModel {
|
||||
|
||||
private _line: string;
|
||||
private _eol: string;
|
||||
|
||||
constructor(line: string) {
|
||||
this._line = line;
|
||||
this._eol = '\n';
|
||||
}
|
||||
|
||||
_setText(text: string) {
|
||||
this._line = text;
|
||||
}
|
||||
|
||||
getLineMaxColumn(lineNumber: number): number {
|
||||
return this._line.length + 1;
|
||||
}
|
||||
|
||||
getValueInRange(range: IRange, eol: editorCommon.EndOfLinePreference): string {
|
||||
return this._line.substring(range.startColumn - 1, range.endColumn - 1);
|
||||
}
|
||||
|
||||
getModelLineContent(lineNumber: number): string {
|
||||
return this._line;
|
||||
}
|
||||
|
||||
getLineCount(): number {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
class TestView {
|
||||
|
||||
private _model: SingleLineTestModel;
|
||||
|
||||
constructor(model: SingleLineTestModel) {
|
||||
this._model = model;
|
||||
}
|
||||
|
||||
public paint(output: HTMLElement) {
|
||||
let r = '';
|
||||
for (let i = 1; i <= this._model.getLineCount(); i++) {
|
||||
let content = this._model.getModelLineContent(i);
|
||||
r += content + '<br/>';
|
||||
}
|
||||
output.innerHTML = r;
|
||||
}
|
||||
}
|
||||
|
||||
function doCreateTest(description: string, inputStr: string, expectedStr: string): HTMLElement {
|
||||
let cursorOffset: number = 0;
|
||||
let cursorLength: number = 0;
|
||||
|
||||
let container = document.createElement('div');
|
||||
container.className = 'container';
|
||||
|
||||
let title = document.createElement('div');
|
||||
title.className = 'title';
|
||||
|
||||
title.innerHTML = description + '. Type <strong>' + inputStr + '</strong>';
|
||||
container.appendChild(title);
|
||||
|
||||
let startBtn = document.createElement('button');
|
||||
startBtn.innerHTML = 'Start';
|
||||
container.appendChild(startBtn);
|
||||
|
||||
|
||||
let input = document.createElement('textarea');
|
||||
input.setAttribute('rows', '10');
|
||||
input.setAttribute('cols', '40');
|
||||
container.appendChild(input);
|
||||
|
||||
let model = new SingleLineTestModel('some text');
|
||||
|
||||
const textAreaInputHost: ITextAreaInputHost = {
|
||||
getPlainTextToCopy: (): string => '',
|
||||
getHTMLToCopy: (): string => '',
|
||||
getScreenReaderContent: (currentState: TextAreaState): TextAreaState => {
|
||||
|
||||
if (browser.isIPad) {
|
||||
// Do not place anything in the textarea for the iPad
|
||||
return TextAreaState.EMPTY;
|
||||
}
|
||||
|
||||
const selection = new Range(1, 1 + cursorOffset, 1, 1 + cursorOffset + cursorLength);
|
||||
|
||||
return PagedScreenReaderStrategy.fromEditorSelection(currentState, model, selection);
|
||||
},
|
||||
deduceModelPosition: (viewAnchorPosition: Position, deltaOffset: number, lineFeedCnt: number): Position => {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
let handler = new TextAreaInput(textAreaInputHost, createFastDomNode(input));
|
||||
|
||||
let output = document.createElement('pre');
|
||||
output.className = 'output';
|
||||
container.appendChild(output);
|
||||
|
||||
let check = document.createElement('pre');
|
||||
check.className = 'check';
|
||||
container.appendChild(check);
|
||||
|
||||
let br = document.createElement('br');
|
||||
br.style.clear = 'both';
|
||||
container.appendChild(br);
|
||||
|
||||
let view = new TestView(model);
|
||||
|
||||
let updatePosition = (off: number, len: number) => {
|
||||
cursorOffset = off;
|
||||
cursorLength = len;
|
||||
handler.writeScreenReaderContent('selection changed');
|
||||
handler.focusTextArea();
|
||||
};
|
||||
|
||||
let updateModelAndPosition = (text: string, off: number, len: number) => {
|
||||
model._setText(text);
|
||||
updatePosition(off, len);
|
||||
view.paint(output);
|
||||
|
||||
let expected = 'some ' + expectedStr + ' text';
|
||||
if (text === expected) {
|
||||
check.innerHTML = '[GOOD]';
|
||||
check.className = 'check good';
|
||||
} else {
|
||||
check.innerHTML = '[BAD]';
|
||||
check.className = 'check bad';
|
||||
}
|
||||
check.innerHTML += expected;
|
||||
};
|
||||
|
||||
handler.onType((e) => {
|
||||
console.log('type text: ' + e.text + ', replaceCharCnt: ' + e.replaceCharCnt);
|
||||
let text = model.getModelLineContent(1);
|
||||
let preText = text.substring(0, cursorOffset - e.replaceCharCnt);
|
||||
let postText = text.substring(cursorOffset + cursorLength);
|
||||
let midText = e.text;
|
||||
|
||||
updateModelAndPosition(preText + midText + postText, (preText + midText).length, 0);
|
||||
});
|
||||
|
||||
view.paint(output);
|
||||
|
||||
startBtn.onclick = function () {
|
||||
updateModelAndPosition('some text', 5, 0);
|
||||
input.focus();
|
||||
};
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
const TESTS = [
|
||||
{ description: 'Japanese IME 1', in: 'sennsei [Enter]', out: 'せんせい' },
|
||||
{ description: 'Japanese IME 2', in: 'konnichiha [Enter]', out: 'こんいちは' },
|
||||
{ description: 'Japanese IME 3', in: 'mikann [Enter]', out: 'みかん' },
|
||||
{ description: 'Korean IME 1', in: 'gksrmf [Space]', out: '한글 ' },
|
||||
{ description: 'Chinese IME 1', in: '.,', out: '。,' },
|
||||
{ description: 'Chinese IME 2', in: 'ni [Space] hao [Space]', out: '你好' },
|
||||
{ description: 'Chinese IME 3', in: 'hazni [Space]', out: '哈祝你' },
|
||||
{ description: 'Mac dead key 1', in: '`.', out: '`.' },
|
||||
{ description: 'Mac hold key 1', in: 'e long press and 1', out: 'é' }
|
||||
];
|
||||
|
||||
TESTS.forEach((t) => {
|
||||
document.body.appendChild(doCreateTest(t.description, t.in, t.out));
|
||||
});
|
||||
115
src/vs/editor/test/browser/controller/inputRecorder.html
Normal file
115
src/vs/editor/test/browser/controller/inputRecorder.html
Normal file
@@ -0,0 +1,115 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>Input Recorder</h2>
|
||||
<p>Records input events and logs them in the console</p>
|
||||
|
||||
<button id="start">Start</button>
|
||||
<button id="stop">Stop</button><br/><br/>
|
||||
<textarea rows="20" cols="50" id="input"></textarea>
|
||||
|
||||
<script>
|
||||
var interestingEvents = [
|
||||
'keydown',
|
||||
'keyup',
|
||||
'keypress',
|
||||
'compositionstart',
|
||||
'compositionupdate',
|
||||
'compositionend',
|
||||
'input',
|
||||
'cut',
|
||||
'copy',
|
||||
'paste',
|
||||
];
|
||||
|
||||
var RECORDED_EVENTS = [];
|
||||
|
||||
var input = document.getElementById('input');
|
||||
|
||||
var blackListedProps = [
|
||||
'currentTarget',
|
||||
'path',
|
||||
'srcElement',
|
||||
'target',
|
||||
'view'
|
||||
];
|
||||
blackListedProps = blackListedProps.concat([
|
||||
'AT_TARGET',
|
||||
'BLUR',
|
||||
'BUBBLING_PHASE',
|
||||
'CAPTURING_PHASE',
|
||||
'CHANGE',
|
||||
'CLICK',
|
||||
'DBLCLICK',
|
||||
'DOM_KEY_LOCATION_LEFT',
|
||||
'DOM_KEY_LOCATION_NUMPAD',
|
||||
'DOM_KEY_LOCATION_RIGHT',
|
||||
'DOM_KEY_LOCATION_STANDARD',
|
||||
'DRAGDROP',
|
||||
'FOCUS',
|
||||
'KEYDOWN',
|
||||
'KEYPRESS',
|
||||
'KEYUP',
|
||||
'MOUSEDOWN',
|
||||
'MOUSEDRAG',
|
||||
'MOUSEMOVE',
|
||||
'MOUSEOUT',
|
||||
'MOUSEOVER',
|
||||
'MOUSEUP',
|
||||
'NONE',
|
||||
'SELECT'
|
||||
])
|
||||
|
||||
function toSerializable(e) {
|
||||
var r = {};
|
||||
for (var k in e) {
|
||||
if (blackListedProps.indexOf(k) >= 0) {
|
||||
continue;
|
||||
}
|
||||
if (typeof e[k] === 'function') {
|
||||
continue;
|
||||
}
|
||||
r[k] = e[k];
|
||||
}
|
||||
console.log(r);
|
||||
return r;
|
||||
}
|
||||
|
||||
function recordEvent(eventType, e) {
|
||||
RECORDED_EVENTS.push({
|
||||
type: eventType,
|
||||
textarea: {
|
||||
value: input.value,
|
||||
selectionStart: input.selectionStart,
|
||||
selectionEnd: input.selectionEnd
|
||||
},
|
||||
event: toSerializable(e)
|
||||
});
|
||||
}
|
||||
|
||||
interestingEvents.forEach(function(eventType) {
|
||||
input.addEventListener(eventType, function(e) {
|
||||
recordEvent(eventType, e);
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById('start').onclick = function() {
|
||||
input.value = 'some text';
|
||||
input.setSelectionRange(5, 5);
|
||||
input.focus();
|
||||
RECORDED_EVENTS = [];
|
||||
};
|
||||
|
||||
document.getElementById('stop').onclick = function() {
|
||||
console.log(JSON.stringify(RECORDED_EVENTS));
|
||||
};
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
643
src/vs/editor/test/browser/controller/textAreaState.test.ts
Normal file
643
src/vs/editor/test/browser/controller/textAreaState.test.ts
Normal file
@@ -0,0 +1,643 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 { ISimpleModel, TextAreaState, ITextAreaWrapper, PagedScreenReaderStrategy } from 'vs/editor/browser/controller/textAreaState';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { EndOfLinePreference } from 'vs/editor/common/editorCommon';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Model } from 'vs/editor/common/model/model';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
|
||||
export class MockTextAreaWrapper extends Disposable implements ITextAreaWrapper {
|
||||
|
||||
public _value: string;
|
||||
public _selectionStart: number;
|
||||
public _selectionEnd: number;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._value = '';
|
||||
this._selectionStart = 0;
|
||||
this._selectionEnd = 0;
|
||||
}
|
||||
|
||||
public getValue(): string {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
public setValue(reason: string, value: string): void {
|
||||
this._value = value;
|
||||
this._selectionStart = this._value.length;
|
||||
this._selectionEnd = this._value.length;
|
||||
}
|
||||
|
||||
public getSelectionStart(): number {
|
||||
return this._selectionStart;
|
||||
}
|
||||
|
||||
public getSelectionEnd(): number {
|
||||
return this._selectionEnd;
|
||||
}
|
||||
|
||||
public setSelectionRange(reason: string, selectionStart: number, selectionEnd: number): void {
|
||||
if (selectionStart < 0) {
|
||||
selectionStart = 0;
|
||||
}
|
||||
if (selectionStart > this._value.length) {
|
||||
selectionStart = this._value.length;
|
||||
}
|
||||
if (selectionEnd < 0) {
|
||||
selectionEnd = 0;
|
||||
}
|
||||
if (selectionEnd > this._value.length) {
|
||||
selectionEnd = this._value.length;
|
||||
}
|
||||
this._selectionStart = selectionStart;
|
||||
this._selectionEnd = selectionEnd;
|
||||
}
|
||||
}
|
||||
|
||||
suite('TextAreaState', () => {
|
||||
|
||||
function assertTextAreaState(actual: TextAreaState, value: string, selectionStart: number, selectionEnd: number): void {
|
||||
let desired = new TextAreaState(value, selectionStart, selectionEnd, null, null);
|
||||
assert.ok(desired.equals(actual), desired.toString() + ' == ' + actual.toString());
|
||||
}
|
||||
|
||||
test('fromTextArea', () => {
|
||||
let textArea = new MockTextAreaWrapper();
|
||||
textArea._value = 'Hello world!';
|
||||
textArea._selectionStart = 1;
|
||||
textArea._selectionEnd = 12;
|
||||
let actual = TextAreaState.EMPTY.readFromTextArea(textArea);
|
||||
|
||||
assertTextAreaState(actual, 'Hello world!', 1, 12);
|
||||
assert.equal(actual.value, 'Hello world!');
|
||||
assert.equal(actual.selectionStart, 1);
|
||||
|
||||
actual = actual.collapseSelection();
|
||||
assertTextAreaState(actual, 'Hello world!', 12, 12);
|
||||
|
||||
textArea.dispose();
|
||||
});
|
||||
|
||||
test('applyToTextArea', () => {
|
||||
let textArea = new MockTextAreaWrapper();
|
||||
textArea._value = 'Hello world!';
|
||||
textArea._selectionStart = 1;
|
||||
textArea._selectionEnd = 12;
|
||||
|
||||
let state = new TextAreaState('Hi world!', 2, 2, null, null);
|
||||
state.writeToTextArea('test', textArea, false);
|
||||
|
||||
assert.equal(textArea._value, 'Hi world!');
|
||||
assert.equal(textArea._selectionStart, 9);
|
||||
assert.equal(textArea._selectionEnd, 9);
|
||||
|
||||
state = new TextAreaState('Hi world!', 3, 3, null, null);
|
||||
state.writeToTextArea('test', textArea, false);
|
||||
|
||||
assert.equal(textArea._value, 'Hi world!');
|
||||
assert.equal(textArea._selectionStart, 9);
|
||||
assert.equal(textArea._selectionEnd, 9);
|
||||
|
||||
state = new TextAreaState('Hi world!', 0, 2, null, null);
|
||||
state.writeToTextArea('test', textArea, true);
|
||||
|
||||
assert.equal(textArea._value, 'Hi world!');
|
||||
assert.equal(textArea._selectionStart, 0);
|
||||
assert.equal(textArea._selectionEnd, 2);
|
||||
|
||||
textArea.dispose();
|
||||
});
|
||||
|
||||
function testDeduceInput(prevState: TextAreaState, value: string, selectionStart: number, selectionEnd: number, expected: string, expectedCharReplaceCnt: number): void {
|
||||
prevState = prevState || TextAreaState.EMPTY;
|
||||
|
||||
let textArea = new MockTextAreaWrapper();
|
||||
textArea._value = value;
|
||||
textArea._selectionStart = selectionStart;
|
||||
textArea._selectionEnd = selectionEnd;
|
||||
|
||||
let newState = prevState.readFromTextArea(textArea);
|
||||
let actual = TextAreaState.deduceInput(prevState, newState, true);
|
||||
|
||||
assert.equal(actual.text, expected);
|
||||
assert.equal(actual.replaceCharCnt, expectedCharReplaceCnt);
|
||||
|
||||
textArea.dispose();
|
||||
}
|
||||
|
||||
test('deduceInput - Japanese typing sennsei and accepting', () => {
|
||||
// manual test:
|
||||
// - choose keyboard layout: Japanese -> Hiragama
|
||||
// - type sennsei
|
||||
// - accept with Enter
|
||||
// - expected: せんせい
|
||||
|
||||
// s
|
||||
// PREVIOUS STATE: [ <>, selectionStart: 0, selectionEnd: 0, selectionToken: 0]
|
||||
// CURRENT STATE: [ <s>, selectionStart: 0, selectionEnd: 1, selectionToken: 0]
|
||||
testDeduceInput(
|
||||
TextAreaState.EMPTY,
|
||||
's',
|
||||
0, 1,
|
||||
's', 0
|
||||
);
|
||||
|
||||
// e
|
||||
// PREVIOUS STATE: [ <s>, selectionStart: 0, selectionEnd: 1, selectionToken: 0]
|
||||
// CURRENT STATE: [ <せ>, selectionStart: 0, selectionEnd: 1, selectionToken: 0]
|
||||
testDeduceInput(
|
||||
new TextAreaState('s', 0, 1, null, null),
|
||||
'せ',
|
||||
0, 1,
|
||||
'せ', 1
|
||||
);
|
||||
|
||||
// n
|
||||
// PREVIOUS STATE: [ <せ>, selectionStart: 0, selectionEnd: 1, selectionToken: 0]
|
||||
// CURRENT STATE: [ <せn>, selectionStart: 0, selectionEnd: 2, selectionToken: 0]
|
||||
testDeduceInput(
|
||||
new TextAreaState('せ', 0, 1, null, null),
|
||||
'せn',
|
||||
0, 2,
|
||||
'せn', 1
|
||||
);
|
||||
|
||||
// n
|
||||
// PREVIOUS STATE: [ <せn>, selectionStart: 0, selectionEnd: 2, selectionToken: 0]
|
||||
// CURRENT STATE: [ <せん>, selectionStart: 0, selectionEnd: 2, selectionToken: 0]
|
||||
testDeduceInput(
|
||||
new TextAreaState('せn', 0, 2, null, null),
|
||||
'せん',
|
||||
0, 2,
|
||||
'せん', 2
|
||||
);
|
||||
|
||||
// s
|
||||
// PREVIOUS STATE: [ <せん>, selectionStart: 0, selectionEnd: 2, selectionToken: 0]
|
||||
// CURRENT STATE: [ <せんs>, selectionStart: 0, selectionEnd: 3, selectionToken: 0]
|
||||
testDeduceInput(
|
||||
new TextAreaState('せん', 0, 2, null, null),
|
||||
'せんs',
|
||||
0, 3,
|
||||
'せんs', 2
|
||||
);
|
||||
|
||||
// e
|
||||
// PREVIOUS STATE: [ <せんs>, selectionStart: 0, selectionEnd: 3, selectionToken: 0]
|
||||
// CURRENT STATE: [ <せんせ>, selectionStart: 0, selectionEnd: 3, selectionToken: 0]
|
||||
testDeduceInput(
|
||||
new TextAreaState('せんs', 0, 3, null, null),
|
||||
'せんせ',
|
||||
0, 3,
|
||||
'せんせ', 3
|
||||
);
|
||||
|
||||
// no-op? [was recorded]
|
||||
// PREVIOUS STATE: [ <せんせ>, selectionStart: 0, selectionEnd: 3, selectionToken: 0]
|
||||
// CURRENT STATE: [ <せんせ>, selectionStart: 0, selectionEnd: 3, selectionToken: 0]
|
||||
testDeduceInput(
|
||||
new TextAreaState('せんせ', 0, 3, null, null),
|
||||
'せんせ',
|
||||
0, 3,
|
||||
'せんせ', 3
|
||||
);
|
||||
|
||||
// i
|
||||
// PREVIOUS STATE: [ <せんせ>, selectionStart: 0, selectionEnd: 3, selectionToken: 0]
|
||||
// CURRENT STATE: [ <せんせい>, selectionStart: 0, selectionEnd: 4, selectionToken: 0]
|
||||
testDeduceInput(
|
||||
new TextAreaState('せんせ', 0, 3, null, null),
|
||||
'せんせい',
|
||||
0, 4,
|
||||
'せんせい', 3
|
||||
);
|
||||
|
||||
// ENTER (accept)
|
||||
// PREVIOUS STATE: [ <せんせい>, selectionStart: 0, selectionEnd: 4, selectionToken: 0]
|
||||
// CURRENT STATE: [ <せんせい>, selectionStart: 4, selectionEnd: 4, selectionToken: 0]
|
||||
testDeduceInput(
|
||||
new TextAreaState('せんせい', 0, 4, null, null),
|
||||
'せんせい',
|
||||
4, 4,
|
||||
'', 0
|
||||
);
|
||||
});
|
||||
|
||||
test('deduceInput - Japanese typing sennsei and choosing different suggestion', () => {
|
||||
// manual test:
|
||||
// - choose keyboard layout: Japanese -> Hiragama
|
||||
// - type sennsei
|
||||
// - arrow down (choose next suggestion)
|
||||
// - accept with Enter
|
||||
// - expected: せんせい
|
||||
|
||||
// sennsei
|
||||
// PREVIOUS STATE: [ <せんせい>, selectionStart: 0, selectionEnd: 4, selectionToken: 0]
|
||||
// CURRENT STATE: [ <せんせい>, selectionStart: 0, selectionEnd: 4, selectionToken: 0]
|
||||
testDeduceInput(
|
||||
new TextAreaState('せんせい', 0, 4, null, null),
|
||||
'せんせい',
|
||||
0, 4,
|
||||
'せんせい', 4
|
||||
);
|
||||
|
||||
// arrow down
|
||||
// CURRENT STATE: [ <先生>, selectionStart: 0, selectionEnd: 2, selectionToken: 0]
|
||||
// PREVIOUS STATE: [ <せんせい>, selectionStart: 0, selectionEnd: 4, selectionToken: 0]
|
||||
testDeduceInput(
|
||||
new TextAreaState('せんせい', 0, 4, null, null),
|
||||
'先生',
|
||||
0, 2,
|
||||
'先生', 4
|
||||
);
|
||||
|
||||
// ENTER (accept)
|
||||
// PREVIOUS STATE: [ <先生>, selectionStart: 0, selectionEnd: 2, selectionToken: 0]
|
||||
// CURRENT STATE: [ <先生>, selectionStart: 2, selectionEnd: 2, selectionToken: 0]
|
||||
testDeduceInput(
|
||||
new TextAreaState('先生', 0, 2, null, null),
|
||||
'先生',
|
||||
2, 2,
|
||||
'', 0
|
||||
);
|
||||
});
|
||||
|
||||
test('extractNewText - no previous state with selection', () => {
|
||||
testDeduceInput(
|
||||
null,
|
||||
'a',
|
||||
0, 1,
|
||||
'a', 0
|
||||
);
|
||||
});
|
||||
|
||||
test('issue #2586: Replacing selected end-of-line with newline locks up the document', () => {
|
||||
testDeduceInput(
|
||||
new TextAreaState(']\n', 1, 2, null, null),
|
||||
']\n',
|
||||
2, 2,
|
||||
'\n', 0
|
||||
);
|
||||
});
|
||||
|
||||
test('extractNewText - no previous state without selection', () => {
|
||||
testDeduceInput(
|
||||
null,
|
||||
'a',
|
||||
1, 1,
|
||||
'a', 0
|
||||
);
|
||||
});
|
||||
|
||||
test('extractNewText - typing does not cause a selection', () => {
|
||||
testDeduceInput(
|
||||
TextAreaState.EMPTY,
|
||||
'a',
|
||||
0, 1,
|
||||
'a', 0
|
||||
);
|
||||
});
|
||||
|
||||
test('extractNewText - had the textarea empty', () => {
|
||||
testDeduceInput(
|
||||
TextAreaState.EMPTY,
|
||||
'a',
|
||||
1, 1,
|
||||
'a', 0
|
||||
);
|
||||
});
|
||||
|
||||
test('extractNewText - had the entire line selected', () => {
|
||||
testDeduceInput(
|
||||
new TextAreaState('Hello world!', 0, 12, null, null),
|
||||
'H',
|
||||
1, 1,
|
||||
'H', 0
|
||||
);
|
||||
});
|
||||
|
||||
test('extractNewText - had previous text 1', () => {
|
||||
testDeduceInput(
|
||||
new TextAreaState('Hello world!', 12, 12, null, null),
|
||||
'Hello world!a',
|
||||
13, 13,
|
||||
'a', 0
|
||||
);
|
||||
});
|
||||
|
||||
test('extractNewText - had previous text 2', () => {
|
||||
testDeduceInput(
|
||||
new TextAreaState('Hello world!', 0, 0, null, null),
|
||||
'aHello world!',
|
||||
1, 1,
|
||||
'a', 0
|
||||
);
|
||||
});
|
||||
|
||||
test('extractNewText - had previous text 3', () => {
|
||||
testDeduceInput(
|
||||
new TextAreaState('Hello world!', 6, 11, null, null),
|
||||
'Hello other!',
|
||||
11, 11,
|
||||
'other', 0
|
||||
);
|
||||
});
|
||||
|
||||
test('extractNewText - IME', () => {
|
||||
testDeduceInput(
|
||||
TextAreaState.EMPTY,
|
||||
'これは',
|
||||
3, 3,
|
||||
'これは', 0
|
||||
);
|
||||
});
|
||||
|
||||
test('extractNewText - isInOverwriteMode', () => {
|
||||
testDeduceInput(
|
||||
new TextAreaState('Hello world!', 0, 0, null, null),
|
||||
'Aello world!',
|
||||
1, 1,
|
||||
'A', 0
|
||||
);
|
||||
});
|
||||
|
||||
test('extractMacReplacedText - does nothing if there is selection', () => {
|
||||
testDeduceInput(
|
||||
new TextAreaState('Hello world!', 5, 5, null, null),
|
||||
'Hellö world!',
|
||||
4, 5,
|
||||
'ö', 0
|
||||
);
|
||||
});
|
||||
|
||||
test('extractMacReplacedText - does nothing if there is more than one extra char', () => {
|
||||
testDeduceInput(
|
||||
new TextAreaState('Hello world!', 5, 5, null, null),
|
||||
'Hellöö world!',
|
||||
5, 5,
|
||||
'öö', 1
|
||||
);
|
||||
});
|
||||
|
||||
test('extractMacReplacedText - does nothing if there is more than one changed char', () => {
|
||||
testDeduceInput(
|
||||
new TextAreaState('Hello world!', 5, 5, null, null),
|
||||
'Helöö world!',
|
||||
5, 5,
|
||||
'öö', 2
|
||||
);
|
||||
});
|
||||
|
||||
test('extractMacReplacedText', () => {
|
||||
testDeduceInput(
|
||||
new TextAreaState('Hello world!', 5, 5, null, null),
|
||||
'Hellö world!',
|
||||
5, 5,
|
||||
'ö', 1
|
||||
);
|
||||
});
|
||||
|
||||
test('issue #25101 - First key press ignored', () => {
|
||||
testDeduceInput(
|
||||
new TextAreaState('a', 0, 1, null, null),
|
||||
'a',
|
||||
1, 1,
|
||||
'a', 0
|
||||
);
|
||||
});
|
||||
|
||||
test('issue #16520 - Cmd-d of single character followed by typing same character as has no effect', () => {
|
||||
testDeduceInput(
|
||||
new TextAreaState('x x', 0, 1, null, null),
|
||||
'x x',
|
||||
1, 1,
|
||||
'x', 0
|
||||
);
|
||||
});
|
||||
|
||||
test('issue #4271 (example 1) - When inserting an emoji on OSX, it is placed two spaces left of the cursor', () => {
|
||||
// The OSX emoji inserter inserts emojis at random positions in the text, unrelated to where the cursor is.
|
||||
testDeduceInput(
|
||||
new TextAreaState(
|
||||
[
|
||||
'some1 text',
|
||||
'some2 text',
|
||||
'some3 text',
|
||||
'some4 text', // cursor is here in the middle of the two spaces
|
||||
'some5 text',
|
||||
'some6 text',
|
||||
'some7 text'
|
||||
].join('\n'),
|
||||
42, 42,
|
||||
null, null
|
||||
),
|
||||
[
|
||||
'so📅me1 text',
|
||||
'some2 text',
|
||||
'some3 text',
|
||||
'some4 text',
|
||||
'some5 text',
|
||||
'some6 text',
|
||||
'some7 text'
|
||||
].join('\n'),
|
||||
4, 4,
|
||||
'📅', 0
|
||||
);
|
||||
});
|
||||
|
||||
test('issue #4271 (example 2) - When inserting an emoji on OSX, it is placed two spaces left of the cursor', () => {
|
||||
// The OSX emoji inserter inserts emojis at random positions in the text, unrelated to where the cursor is.
|
||||
testDeduceInput(
|
||||
new TextAreaState(
|
||||
'some1 text',
|
||||
6, 6,
|
||||
null, null
|
||||
),
|
||||
'some💊1 text',
|
||||
6, 6,
|
||||
'💊', 0
|
||||
);
|
||||
});
|
||||
|
||||
test('issue #4271 (example 3) - When inserting an emoji on OSX, it is placed two spaces left of the cursor', () => {
|
||||
// The OSX emoji inserter inserts emojis at random positions in the text, unrelated to where the cursor is.
|
||||
testDeduceInput(
|
||||
new TextAreaState(
|
||||
'qwertyu\nasdfghj\nzxcvbnm',
|
||||
12, 12,
|
||||
null, null
|
||||
),
|
||||
'qwertyu\nasdfghj\nzxcvbnm🎈',
|
||||
25, 25,
|
||||
'🎈', 0
|
||||
);
|
||||
});
|
||||
|
||||
// an example of an emoji missed by the regex but which has the FE0F variant 16 hint
|
||||
test('issue #4271 (example 4) - When inserting an emoji on OSX, it is placed two spaces left of the cursor', () => {
|
||||
// The OSX emoji inserter inserts emojis at random positions in the text, unrelated to where the cursor is.
|
||||
testDeduceInput(
|
||||
new TextAreaState(
|
||||
'some1 text',
|
||||
6, 6,
|
||||
null, null
|
||||
),
|
||||
'some⌨️1 text',
|
||||
6, 6,
|
||||
'⌨️', 0
|
||||
);
|
||||
});
|
||||
|
||||
suite('PagedScreenReaderStrategy', () => {
|
||||
|
||||
function testPagedScreenReaderStrategy(lines: string[], selection: Selection, expected: TextAreaState): void {
|
||||
const model = Model.createFromString(lines.join('\n'));
|
||||
const actual = PagedScreenReaderStrategy.fromEditorSelection(TextAreaState.EMPTY, model, selection);
|
||||
assert.ok(actual.equals(expected));
|
||||
model.dispose();
|
||||
}
|
||||
|
||||
test('simple', () => {
|
||||
testPagedScreenReaderStrategy(
|
||||
[
|
||||
'Hello world!'
|
||||
],
|
||||
new Selection(1, 13, 1, 13),
|
||||
new TextAreaState('Hello world!', 12, 12, new Position(1, 13), new Position(1, 13))
|
||||
);
|
||||
|
||||
testPagedScreenReaderStrategy(
|
||||
[
|
||||
'Hello world!'
|
||||
],
|
||||
new Selection(1, 1, 1, 1),
|
||||
new TextAreaState('Hello world!', 0, 0, new Position(1, 1), new Position(1, 1))
|
||||
);
|
||||
|
||||
testPagedScreenReaderStrategy(
|
||||
[
|
||||
'Hello world!'
|
||||
],
|
||||
new Selection(1, 1, 1, 6),
|
||||
new TextAreaState('Hello world!', 0, 5, new Position(1, 1), new Position(1, 6))
|
||||
);
|
||||
});
|
||||
|
||||
test('multiline', () => {
|
||||
testPagedScreenReaderStrategy(
|
||||
[
|
||||
'Hello world!',
|
||||
'How are you?'
|
||||
],
|
||||
new Selection(1, 1, 1, 1),
|
||||
new TextAreaState('Hello world!\nHow are you?', 0, 0, new Position(1, 1), new Position(1, 1))
|
||||
);
|
||||
|
||||
testPagedScreenReaderStrategy(
|
||||
[
|
||||
'Hello world!',
|
||||
'How are you?'
|
||||
],
|
||||
new Selection(2, 1, 2, 1),
|
||||
new TextAreaState('Hello world!\nHow are you?', 13, 13, new Position(2, 1), new Position(2, 1))
|
||||
);
|
||||
});
|
||||
|
||||
test('page', () => {
|
||||
testPagedScreenReaderStrategy(
|
||||
[
|
||||
'L1\nL2\nL3\nL4\nL5\nL6\nL7\nL8\nL9\nL10\nL11\nL12\nL13\nL14\nL15\nL16\nL17\nL18\nL19\nL20\nL21'
|
||||
],
|
||||
new Selection(1, 1, 1, 1),
|
||||
new TextAreaState('L1\nL2\nL3\nL4\nL5\nL6\nL7\nL8\nL9\nL10\n', 0, 0, new Position(1, 1), new Position(1, 1))
|
||||
);
|
||||
|
||||
testPagedScreenReaderStrategy(
|
||||
[
|
||||
'L1\nL2\nL3\nL4\nL5\nL6\nL7\nL8\nL9\nL10\nL11\nL12\nL13\nL14\nL15\nL16\nL17\nL18\nL19\nL20\nL21'
|
||||
],
|
||||
new Selection(11, 1, 11, 1),
|
||||
new TextAreaState('L11\nL12\nL13\nL14\nL15\nL16\nL17\nL18\nL19\nL20\n', 0, 0, new Position(11, 1), new Position(11, 1))
|
||||
);
|
||||
|
||||
testPagedScreenReaderStrategy(
|
||||
[
|
||||
'L1\nL2\nL3\nL4\nL5\nL6\nL7\nL8\nL9\nL10\nL11\nL12\nL13\nL14\nL15\nL16\nL17\nL18\nL19\nL20\nL21'
|
||||
],
|
||||
new Selection(12, 1, 12, 1),
|
||||
new TextAreaState('L11\nL12\nL13\nL14\nL15\nL16\nL17\nL18\nL19\nL20\n', 4, 4, new Position(12, 1), new Position(12, 1))
|
||||
);
|
||||
|
||||
testPagedScreenReaderStrategy(
|
||||
[
|
||||
'L1\nL2\nL3\nL4\nL5\nL6\nL7\nL8\nL9\nL10\nL11\nL12\nL13\nL14\nL15\nL16\nL17\nL18\nL19\nL20\nL21'
|
||||
],
|
||||
new Selection(21, 1, 21, 1),
|
||||
new TextAreaState('L21', 0, 0, new Position(21, 1), new Position(21, 1))
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
class SimpleModel implements ISimpleModel {
|
||||
|
||||
private _lines: string[];
|
||||
private _eol: string;
|
||||
|
||||
constructor(lines: string[], eol: string) {
|
||||
this._lines = lines;
|
||||
this._eol = eol;
|
||||
}
|
||||
|
||||
public getLineMaxColumn(lineNumber: number): number {
|
||||
return this._lines[lineNumber - 1].length + 1;
|
||||
}
|
||||
|
||||
private _getEndOfLine(eol: EndOfLinePreference): string {
|
||||
switch (eol) {
|
||||
case EndOfLinePreference.LF:
|
||||
return '\n';
|
||||
case EndOfLinePreference.CRLF:
|
||||
return '\r\n';
|
||||
case EndOfLinePreference.TextDefined:
|
||||
return this._eol;
|
||||
}
|
||||
throw new Error('Unknown EOL preference');
|
||||
}
|
||||
|
||||
public getValueInRange(range: Range, eol: EndOfLinePreference): string {
|
||||
if (Range.isEmpty(range)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (range.startLineNumber === range.endLineNumber) {
|
||||
return this._lines[range.startLineNumber - 1].substring(range.startColumn - 1, range.endColumn - 1);
|
||||
}
|
||||
|
||||
var lineEnding = this._getEndOfLine(eol),
|
||||
startLineIndex = range.startLineNumber - 1,
|
||||
endLineIndex = range.endLineNumber - 1,
|
||||
resultLines: string[] = [];
|
||||
|
||||
resultLines.push(this._lines[startLineIndex].substring(range.startColumn - 1));
|
||||
for (var i = startLineIndex + 1; i < endLineIndex; i++) {
|
||||
resultLines.push(this._lines[i]);
|
||||
}
|
||||
resultLines.push(this._lines[endLineIndex].substring(0, range.endColumn - 1));
|
||||
|
||||
return resultLines.join(lineEnding);
|
||||
}
|
||||
|
||||
public getLineCount(): number {
|
||||
return this._lines.length;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 URI from 'vs/base/common/uri';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { CodeEditorServiceImpl } from 'vs/editor/browser/services/codeEditorServiceImpl';
|
||||
import { IDecorationRenderOptions } from 'vs/editor/common/editorCommon';
|
||||
import { TestTheme, TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
|
||||
|
||||
const themeServiceMock = new TestThemeService();
|
||||
|
||||
suite('Decoration Render Options', () => {
|
||||
test('register and resolve decoration type', () => {
|
||||
assert.equal(1, 1);
|
||||
});
|
||||
});
|
||||
25
src/vs/editor/test/browser/view/minimapFontCreator.html
Normal file
25
src/vs/editor/test/browser/view/minimapFontCreator.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body style="background:black">
|
||||
<canvas id="my-canvas"></canvas>
|
||||
|
||||
<script src="../../../../loader.js"></script>
|
||||
<script>
|
||||
require.config({
|
||||
baseUrl: '../../../../../../out'
|
||||
});
|
||||
|
||||
require(['vs/editor/test/browser/view/minimapFontCreator'], function() {
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
145
src/vs/editor/test/browser/view/minimapFontCreator.ts
Normal file
145
src/vs/editor/test/browser/view/minimapFontCreator.ts
Normal file
@@ -0,0 +1,145 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 { Constants, MinimapCharRenderer } from 'vs/editor/common/view/minimapCharRenderer';
|
||||
import { MinimapCharRendererFactory } from 'vs/editor/test/common/view/minimapCharRendererFactory';
|
||||
import { getOrCreateMinimapCharRenderer } from 'vs/editor/common/view/runtimeMinimapCharRenderer';
|
||||
import { RGBA8 } from 'vs/editor/common/core/rgba';
|
||||
|
||||
let canvas = <HTMLCanvasElement>document.getElementById('my-canvas');
|
||||
let ctx = canvas.getContext('2d');
|
||||
|
||||
canvas.style.height = 100 + 'px';
|
||||
canvas.height = 100;
|
||||
|
||||
canvas.width = Constants.CHAR_COUNT * Constants.SAMPLED_CHAR_WIDTH;
|
||||
canvas.style.width = (Constants.CHAR_COUNT * Constants.SAMPLED_CHAR_WIDTH) + 'px';
|
||||
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.font = 'bold 16px monospace';
|
||||
for (let chCode = Constants.START_CH_CODE; chCode <= Constants.END_CH_CODE; chCode++) {
|
||||
ctx.fillText(String.fromCharCode(chCode), (chCode - Constants.START_CH_CODE) * Constants.SAMPLED_CHAR_WIDTH, Constants.SAMPLED_CHAR_HEIGHT);
|
||||
}
|
||||
|
||||
let sampleData = ctx.getImageData(0, 4, Constants.SAMPLED_CHAR_WIDTH * Constants.CHAR_COUNT, Constants.SAMPLED_CHAR_HEIGHT);
|
||||
let minimapCharRenderer = MinimapCharRendererFactory.create(sampleData.data);
|
||||
|
||||
renderImageData(sampleData, 10, 100);
|
||||
renderMinimapCharRenderer(minimapCharRenderer, 400);
|
||||
renderMinimapCharRenderer(getOrCreateMinimapCharRenderer(), 600);
|
||||
|
||||
function createFakeImageData(width: number, height: number): ImageData {
|
||||
return {
|
||||
width: width,
|
||||
height: height,
|
||||
data: new Uint8ClampedArray(width * height * Constants.RGBA_CHANNELS_CNT)
|
||||
};
|
||||
}
|
||||
|
||||
function renderMinimapCharRenderer(minimapCharRenderer: MinimapCharRenderer, y: number): void {
|
||||
|
||||
let background = new RGBA8(0, 0, 0, 255);
|
||||
let color = new RGBA8(255, 255, 255, 255);
|
||||
|
||||
{
|
||||
let x2 = createFakeImageData(Constants.x2_CHAR_WIDTH * Constants.CHAR_COUNT, Constants.x2_CHAR_HEIGHT);
|
||||
// set the background color
|
||||
for (let i = 0, len = x2.data.length / 4; i < len; i++) {
|
||||
x2.data[4 * i + 0] = background.r;
|
||||
x2.data[4 * i + 1] = background.g;
|
||||
x2.data[4 * i + 2] = background.b;
|
||||
x2.data[4 * i + 3] = 255;
|
||||
}
|
||||
let dx = 0;
|
||||
for (let chCode = Constants.START_CH_CODE; chCode <= Constants.END_CH_CODE; chCode++) {
|
||||
minimapCharRenderer.x2RenderChar(x2, dx, 0, chCode, color, background, false);
|
||||
dx += Constants.x2_CHAR_WIDTH;
|
||||
}
|
||||
renderImageData(x2, 10, y);
|
||||
}
|
||||
{
|
||||
let x1 = createFakeImageData(Constants.x1_CHAR_WIDTH * Constants.CHAR_COUNT, Constants.x1_CHAR_HEIGHT);
|
||||
// set the background color
|
||||
for (let i = 0, len = x1.data.length / 4; i < len; i++) {
|
||||
x1.data[4 * i + 0] = background.r;
|
||||
x1.data[4 * i + 1] = background.g;
|
||||
x1.data[4 * i + 2] = background.b;
|
||||
x1.data[4 * i + 3] = 255;
|
||||
}
|
||||
let dx = 0;
|
||||
for (let chCode = Constants.START_CH_CODE; chCode <= Constants.END_CH_CODE; chCode++) {
|
||||
minimapCharRenderer.x1RenderChar(x1, dx, 0, chCode, color, background, false);
|
||||
dx += Constants.x1_CHAR_WIDTH;
|
||||
}
|
||||
renderImageData(x1, 10, y + 100);
|
||||
}
|
||||
}
|
||||
|
||||
(function () {
|
||||
let r = 'let x2Data = [', offset = 0;
|
||||
for (let charIndex = 0; charIndex < Constants.CHAR_COUNT; charIndex++) {
|
||||
let charCode = charIndex + Constants.START_CH_CODE;
|
||||
r += '\n\n// ' + String.fromCharCode(charCode);
|
||||
|
||||
for (let i = 0; i < Constants.x2_CHAR_HEIGHT * Constants.x2_CHAR_WIDTH; i++) {
|
||||
if (i % 2 === 0) {
|
||||
r += '\n';
|
||||
}
|
||||
r += minimapCharRenderer.x2charData[offset] + ',';
|
||||
offset++;
|
||||
}
|
||||
|
||||
}
|
||||
r += '\n\n]';
|
||||
console.log(r);
|
||||
})();
|
||||
|
||||
(function () {
|
||||
let r = 'let x1Data = [', offset = 0;
|
||||
for (let charIndex = 0; charIndex < Constants.CHAR_COUNT; charIndex++) {
|
||||
let charCode = charIndex + Constants.START_CH_CODE;
|
||||
r += '\n\n// ' + String.fromCharCode(charCode);
|
||||
|
||||
for (let i = 0; i < Constants.x1_CHAR_HEIGHT * Constants.x1_CHAR_WIDTH; i++) {
|
||||
r += '\n';
|
||||
r += minimapCharRenderer.x1charData[offset] + ',';
|
||||
offset++;
|
||||
}
|
||||
|
||||
}
|
||||
r += '\n\n]';
|
||||
console.log(r);
|
||||
})();
|
||||
|
||||
|
||||
|
||||
function renderImageData(imageData: ImageData, left: number, top: number): void {
|
||||
let output = '';
|
||||
var offset = 0;
|
||||
var PX_SIZE = 15;
|
||||
for (var i = 0; i < imageData.height; i++) {
|
||||
for (var j = 0; j < imageData.width; j++) {
|
||||
var R = imageData.data[offset];
|
||||
var G = imageData.data[offset + 1];
|
||||
var B = imageData.data[offset + 2];
|
||||
var A = imageData.data[offset + 3];
|
||||
offset += 4;
|
||||
|
||||
output += `<div style="position:absolute;top:${PX_SIZE * i}px;left:${PX_SIZE * j}px;width:${PX_SIZE}px;height:${PX_SIZE}px;background:rgba(${R},${G},${B},${A / 256})"></div>`;
|
||||
}
|
||||
}
|
||||
|
||||
var domNode = document.createElement('div');
|
||||
domNode.style.position = 'absolute';
|
||||
domNode.style.top = top + 'px';
|
||||
domNode.style.left = left + 'px';
|
||||
domNode.style.width = (imageData.width * PX_SIZE) + 'px';
|
||||
domNode.style.height = (imageData.height * PX_SIZE) + 'px';
|
||||
domNode.style.border = '1px solid #ccc';
|
||||
domNode.style.background = '#000000';
|
||||
domNode.innerHTML = output;
|
||||
document.body.appendChild(domNode);
|
||||
}
|
||||
753
src/vs/editor/test/browser/view/viewLayer.test.ts
Normal file
753
src/vs/editor/test/browser/view/viewLayer.test.ts
Normal file
@@ -0,0 +1,753 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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 { RenderedLinesCollection, ILine } from 'vs/editor/browser/view/viewLayer';
|
||||
|
||||
class TestLine implements ILine {
|
||||
|
||||
_pinged = false;
|
||||
constructor(public id: string) {
|
||||
}
|
||||
|
||||
onContentChanged(): void {
|
||||
this._pinged = true;
|
||||
}
|
||||
onTokensChanged(): void {
|
||||
this._pinged = true;
|
||||
}
|
||||
}
|
||||
|
||||
interface ILinesCollectionState {
|
||||
startLineNumber: number;
|
||||
lines: string[];
|
||||
pinged: boolean[];
|
||||
}
|
||||
|
||||
function assertState(col: RenderedLinesCollection<TestLine>, state: ILinesCollectionState): void {
|
||||
let actualState: ILinesCollectionState = {
|
||||
startLineNumber: col.getStartLineNumber(),
|
||||
lines: [],
|
||||
pinged: []
|
||||
};
|
||||
for (let lineNumber = col.getStartLineNumber(); lineNumber <= col.getEndLineNumber(); lineNumber++) {
|
||||
actualState.lines.push(col.getLine(lineNumber).id);
|
||||
actualState.pinged.push(col.getLine(lineNumber)._pinged);
|
||||
}
|
||||
assert.deepEqual(actualState, state);
|
||||
}
|
||||
|
||||
suite('RenderedLinesCollection onLinesDeleted', () => {
|
||||
|
||||
function testOnModelLinesDeleted(deleteFromLineNumber: number, deleteToLineNumber: number, expectedDeleted: string[], expectedState: ILinesCollectionState): void {
|
||||
let col = new RenderedLinesCollection<TestLine>(() => new TestLine('new'));
|
||||
col._set(6, [
|
||||
new TestLine('old6'),
|
||||
new TestLine('old7'),
|
||||
new TestLine('old8'),
|
||||
new TestLine('old9')
|
||||
]);
|
||||
let actualDeleted1 = col.onLinesDeleted(deleteFromLineNumber, deleteToLineNumber);
|
||||
let actualDeleted: string[] = [];
|
||||
if (actualDeleted1) {
|
||||
actualDeleted = actualDeleted1.map(line => line.id);
|
||||
}
|
||||
assert.deepEqual(actualDeleted, expectedDeleted);
|
||||
assertState(col, expectedState);
|
||||
}
|
||||
|
||||
test('A1', () => {
|
||||
testOnModelLinesDeleted(3, 3, [], {
|
||||
startLineNumber: 5,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('A2', () => {
|
||||
testOnModelLinesDeleted(3, 4, [], {
|
||||
startLineNumber: 4,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('A3', () => {
|
||||
testOnModelLinesDeleted(3, 5, [], {
|
||||
startLineNumber: 3,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('A4', () => {
|
||||
testOnModelLinesDeleted(3, 6, ['old6'], {
|
||||
startLineNumber: 3,
|
||||
lines: ['old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('A5', () => {
|
||||
testOnModelLinesDeleted(3, 7, ['old6', 'old7'], {
|
||||
startLineNumber: 3,
|
||||
lines: ['old8', 'old9'],
|
||||
pinged: [false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('A6', () => {
|
||||
testOnModelLinesDeleted(3, 8, ['old6', 'old7', 'old8'], {
|
||||
startLineNumber: 3,
|
||||
lines: ['old9'],
|
||||
pinged: [false]
|
||||
});
|
||||
});
|
||||
|
||||
test('A7', () => {
|
||||
testOnModelLinesDeleted(3, 9, ['old6', 'old7', 'old8', 'old9'], {
|
||||
startLineNumber: 3,
|
||||
lines: [],
|
||||
pinged: []
|
||||
});
|
||||
});
|
||||
|
||||
test('A8', () => {
|
||||
testOnModelLinesDeleted(3, 10, ['old6', 'old7', 'old8', 'old9'], {
|
||||
startLineNumber: 3,
|
||||
lines: [],
|
||||
pinged: []
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('B1', () => {
|
||||
testOnModelLinesDeleted(5, 5, [], {
|
||||
startLineNumber: 5,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('B2', () => {
|
||||
testOnModelLinesDeleted(5, 6, ['old6'], {
|
||||
startLineNumber: 5,
|
||||
lines: ['old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('B3', () => {
|
||||
testOnModelLinesDeleted(5, 7, ['old6', 'old7'], {
|
||||
startLineNumber: 5,
|
||||
lines: ['old8', 'old9'],
|
||||
pinged: [false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('B4', () => {
|
||||
testOnModelLinesDeleted(5, 8, ['old6', 'old7', 'old8'], {
|
||||
startLineNumber: 5,
|
||||
lines: ['old9'],
|
||||
pinged: [false]
|
||||
});
|
||||
});
|
||||
|
||||
test('B5', () => {
|
||||
testOnModelLinesDeleted(5, 9, ['old6', 'old7', 'old8', 'old9'], {
|
||||
startLineNumber: 5,
|
||||
lines: [],
|
||||
pinged: []
|
||||
});
|
||||
});
|
||||
|
||||
test('B6', () => {
|
||||
testOnModelLinesDeleted(5, 10, ['old6', 'old7', 'old8', 'old9'], {
|
||||
startLineNumber: 5,
|
||||
lines: [],
|
||||
pinged: []
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('C1', () => {
|
||||
testOnModelLinesDeleted(6, 6, ['old6'], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('C2', () => {
|
||||
testOnModelLinesDeleted(6, 7, ['old6', 'old7'], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old8', 'old9'],
|
||||
pinged: [false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('C3', () => {
|
||||
testOnModelLinesDeleted(6, 8, ['old6', 'old7', 'old8'], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old9'],
|
||||
pinged: [false]
|
||||
});
|
||||
});
|
||||
|
||||
test('C4', () => {
|
||||
testOnModelLinesDeleted(6, 9, ['old6', 'old7', 'old8', 'old9'], {
|
||||
startLineNumber: 6,
|
||||
lines: [],
|
||||
pinged: []
|
||||
});
|
||||
});
|
||||
|
||||
test('C5', () => {
|
||||
testOnModelLinesDeleted(6, 10, ['old6', 'old7', 'old8', 'old9'], {
|
||||
startLineNumber: 6,
|
||||
lines: [],
|
||||
pinged: []
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('D1', () => {
|
||||
testOnModelLinesDeleted(7, 7, ['old7'], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old8', 'old9'],
|
||||
pinged: [false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('D2', () => {
|
||||
testOnModelLinesDeleted(7, 8, ['old7', 'old8'], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old9'],
|
||||
pinged: [false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('D3', () => {
|
||||
testOnModelLinesDeleted(7, 9, ['old7', 'old8', 'old9'], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6'],
|
||||
pinged: [false]
|
||||
});
|
||||
});
|
||||
|
||||
test('D4', () => {
|
||||
testOnModelLinesDeleted(7, 10, ['old7', 'old8', 'old9'], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6'],
|
||||
pinged: [false]
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('E1', () => {
|
||||
testOnModelLinesDeleted(8, 8, ['old8'], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old9'],
|
||||
pinged: [false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('E2', () => {
|
||||
testOnModelLinesDeleted(8, 9, ['old8', 'old9'], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7'],
|
||||
pinged: [false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('E3', () => {
|
||||
testOnModelLinesDeleted(8, 10, ['old8', 'old9'], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7'],
|
||||
pinged: [false, false]
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('F1', () => {
|
||||
testOnModelLinesDeleted(9, 9, ['old9'], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8'],
|
||||
pinged: [false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('F2', () => {
|
||||
testOnModelLinesDeleted(9, 10, ['old9'], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8'],
|
||||
pinged: [false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('G1', () => {
|
||||
testOnModelLinesDeleted(10, 10, [], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('G2', () => {
|
||||
testOnModelLinesDeleted(10, 11, [], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('H1', () => {
|
||||
testOnModelLinesDeleted(11, 13, [], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('RenderedLinesCollection onLineChanged', () => {
|
||||
|
||||
function testOnModelLineChanged(changedLineNumber: number, expectedPinged: boolean, expectedState: ILinesCollectionState): void {
|
||||
let col = new RenderedLinesCollection<TestLine>(() => new TestLine('new'));
|
||||
col._set(6, [
|
||||
new TestLine('old6'),
|
||||
new TestLine('old7'),
|
||||
new TestLine('old8'),
|
||||
new TestLine('old9')
|
||||
]);
|
||||
let actualPinged = col.onLinesChanged(changedLineNumber, changedLineNumber);
|
||||
assert.deepEqual(actualPinged, expectedPinged);
|
||||
assertState(col, expectedState);
|
||||
}
|
||||
|
||||
test('3', () => {
|
||||
testOnModelLineChanged(3, false, {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
test('4', () => {
|
||||
testOnModelLineChanged(4, false, {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
test('5', () => {
|
||||
testOnModelLineChanged(5, false, {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
test('6', () => {
|
||||
testOnModelLineChanged(6, true, {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [true, false, false, false]
|
||||
});
|
||||
});
|
||||
test('7', () => {
|
||||
testOnModelLineChanged(7, true, {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, true, false, false]
|
||||
});
|
||||
});
|
||||
test('8', () => {
|
||||
testOnModelLineChanged(8, true, {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, true, false]
|
||||
});
|
||||
});
|
||||
test('9', () => {
|
||||
testOnModelLineChanged(9, true, {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, true]
|
||||
});
|
||||
});
|
||||
test('10', () => {
|
||||
testOnModelLineChanged(10, false, {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
test('11', () => {
|
||||
testOnModelLineChanged(11, false, {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
suite('RenderedLinesCollection onLinesInserted', () => {
|
||||
|
||||
function testOnModelLinesInserted(insertFromLineNumber: number, insertToLineNumber: number, expectedDeleted: string[], expectedState: ILinesCollectionState): void {
|
||||
let col = new RenderedLinesCollection<TestLine>(() => new TestLine('new'));
|
||||
col._set(6, [
|
||||
new TestLine('old6'),
|
||||
new TestLine('old7'),
|
||||
new TestLine('old8'),
|
||||
new TestLine('old9')
|
||||
]);
|
||||
let actualDeleted1 = col.onLinesInserted(insertFromLineNumber, insertToLineNumber);
|
||||
let actualDeleted: string[] = [];
|
||||
if (actualDeleted1) {
|
||||
actualDeleted = actualDeleted1.map(line => line.id);
|
||||
}
|
||||
assert.deepEqual(actualDeleted, expectedDeleted);
|
||||
assertState(col, expectedState);
|
||||
}
|
||||
|
||||
test('A1', () => {
|
||||
testOnModelLinesInserted(3, 3, [], {
|
||||
startLineNumber: 7,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('A2', () => {
|
||||
testOnModelLinesInserted(3, 4, [], {
|
||||
startLineNumber: 8,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('A3', () => {
|
||||
testOnModelLinesInserted(3, 5, [], {
|
||||
startLineNumber: 9,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('A4', () => {
|
||||
testOnModelLinesInserted(3, 6, [], {
|
||||
startLineNumber: 10,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('A5', () => {
|
||||
testOnModelLinesInserted(3, 7, [], {
|
||||
startLineNumber: 11,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('A6', () => {
|
||||
testOnModelLinesInserted(3, 8, [], {
|
||||
startLineNumber: 12,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('A7', () => {
|
||||
testOnModelLinesInserted(3, 9, [], {
|
||||
startLineNumber: 13,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('A8', () => {
|
||||
testOnModelLinesInserted(3, 10, [], {
|
||||
startLineNumber: 14,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('B1', () => {
|
||||
testOnModelLinesInserted(5, 5, [], {
|
||||
startLineNumber: 7,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('B2', () => {
|
||||
testOnModelLinesInserted(5, 6, [], {
|
||||
startLineNumber: 8,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('B3', () => {
|
||||
testOnModelLinesInserted(5, 7, [], {
|
||||
startLineNumber: 9,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('B4', () => {
|
||||
testOnModelLinesInserted(5, 8, [], {
|
||||
startLineNumber: 10,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('B5', () => {
|
||||
testOnModelLinesInserted(5, 9, [], {
|
||||
startLineNumber: 11,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('B6', () => {
|
||||
testOnModelLinesInserted(5, 10, [], {
|
||||
startLineNumber: 12,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('C1', () => {
|
||||
testOnModelLinesInserted(6, 6, [], {
|
||||
startLineNumber: 7,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('C2', () => {
|
||||
testOnModelLinesInserted(6, 7, [], {
|
||||
startLineNumber: 8,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('C3', () => {
|
||||
testOnModelLinesInserted(6, 8, [], {
|
||||
startLineNumber: 9,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('C4', () => {
|
||||
testOnModelLinesInserted(6, 9, [], {
|
||||
startLineNumber: 10,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('C5', () => {
|
||||
testOnModelLinesInserted(6, 10, [], {
|
||||
startLineNumber: 11,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('D1', () => {
|
||||
testOnModelLinesInserted(7, 7, ['old9'], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'new', 'old7', 'old8'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('D2', () => {
|
||||
testOnModelLinesInserted(7, 8, ['old8', 'old9'], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'new', 'new', 'old7'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('D3', () => {
|
||||
testOnModelLinesInserted(7, 9, ['old7', 'old8', 'old9'], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6'],
|
||||
pinged: [false]
|
||||
});
|
||||
});
|
||||
|
||||
test('D4', () => {
|
||||
testOnModelLinesInserted(7, 10, ['old7', 'old8', 'old9'], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6'],
|
||||
pinged: [false]
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('E1', () => {
|
||||
testOnModelLinesInserted(8, 8, ['old9'], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'new', 'old8'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('E2', () => {
|
||||
testOnModelLinesInserted(8, 9, ['old8', 'old9'], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7'],
|
||||
pinged: [false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('E3', () => {
|
||||
testOnModelLinesInserted(8, 10, ['old8', 'old9'], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7'],
|
||||
pinged: [false, false]
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('F1', () => {
|
||||
testOnModelLinesInserted(9, 9, ['old9'], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8'],
|
||||
pinged: [false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('F2', () => {
|
||||
testOnModelLinesInserted(9, 10, ['old9'], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8'],
|
||||
pinged: [false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('G1', () => {
|
||||
testOnModelLinesInserted(10, 10, [], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
test('G2', () => {
|
||||
testOnModelLinesInserted(10, 11, [], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test('H1', () => {
|
||||
testOnModelLinesInserted(11, 13, [], {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
suite('RenderedLinesCollection onTokensChanged', () => {
|
||||
|
||||
function testOnModelTokensChanged(changedFromLineNumber: number, changedToLineNumber: number, expectedPinged: boolean, expectedState: ILinesCollectionState): void {
|
||||
let col = new RenderedLinesCollection<TestLine>(() => new TestLine('new'));
|
||||
col._set(6, [
|
||||
new TestLine('old6'),
|
||||
new TestLine('old7'),
|
||||
new TestLine('old8'),
|
||||
new TestLine('old9')
|
||||
]);
|
||||
let actualPinged = col.onTokensChanged([{ fromLineNumber: changedFromLineNumber, toLineNumber: changedToLineNumber }]);
|
||||
assert.deepEqual(actualPinged, expectedPinged);
|
||||
assertState(col, expectedState);
|
||||
}
|
||||
|
||||
test('A', () => {
|
||||
testOnModelTokensChanged(3, 3, false, {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
test('B', () => {
|
||||
testOnModelTokensChanged(3, 5, false, {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
test('C', () => {
|
||||
testOnModelTokensChanged(3, 6, true, {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [true, false, false, false]
|
||||
});
|
||||
});
|
||||
test('D', () => {
|
||||
testOnModelTokensChanged(6, 6, true, {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [true, false, false, false]
|
||||
});
|
||||
});
|
||||
test('E', () => {
|
||||
testOnModelTokensChanged(5, 10, true, {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [true, true, true, true]
|
||||
});
|
||||
});
|
||||
test('F', () => {
|
||||
testOnModelTokensChanged(8, 9, true, {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, true, true]
|
||||
});
|
||||
});
|
||||
test('G', () => {
|
||||
testOnModelTokensChanged(8, 11, true, {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, true, true]
|
||||
});
|
||||
});
|
||||
test('H', () => {
|
||||
testOnModelTokensChanged(10, 10, false, {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
test('I', () => {
|
||||
testOnModelTokensChanged(10, 11, false, {
|
||||
startLineNumber: 6,
|
||||
lines: ['old6', 'old7', 'old8', 'old9'],
|
||||
pinged: [false, false, false, false]
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user