blob: ef5308480a064548dc31c67b1a73782cef75834b [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @fileoverview using private properties isn't a Closure violation in tests.
* @suppress {accessControls}
*/
SourcesTestRunner.createTestEditor = function(clientHeight, textEditorDelegate) {
const textEditor =
new SourceFrame.SourcesTextEditor(textEditorDelegate || new SourceFrame.SourcesTextEditorDelegate());
clientHeight = clientHeight || 100;
textEditor.element.style.height = clientHeight + 'px';
textEditor.element.style.flex = 'none';
textEditor.show(UI.inspectorView.element);
return textEditor;
};
function textWithSelection(text, selections) {
if (!selections.length) {
return text;
}
function lineWithCursor(line, column, cursorChar) {
return line.substring(0, column) + cursorChar + line.substring(column);
}
const lines = text.split('\n');
selections.sort(TextUtils.TextRange.comparator);
for (let i = selections.length - 1; i >= 0; --i) {
let selection = selections[i];
selection = selection.normalize();
const endCursorChar = (selection.isEmpty() ? '|' : '<');
lines[selection.endLine] = lineWithCursor(lines[selection.endLine], selection.endColumn, endCursorChar);
if (!selection.isEmpty()) {
lines[selection.startLine] = lineWithCursor(lines[selection.startLine], selection.startColumn, '>');
}
}
return lines.join('\n');
}
SourcesTestRunner.dumpTextWithSelection = function(textEditor, dumpWhiteSpaces) {
let text = textWithSelection(textEditor.text(), textEditor.selections());
if (dumpWhiteSpaces) {
text = text.replace(/ /g, '.');
}
TestRunner.addResult(text);
};
SourcesTestRunner.setLineSelections = function(editor, selections) {
const coords = [];
for (let i = 0; i < selections.length; ++i) {
const selection = selections[i];
if (typeof selection.column === 'number') {
selection.from = selection.column;
selection.to = selection.column;
}
coords.push(new TextUtils.TextRange(selection.line, selection.from, selection.line, selection.to));
}
editor.setSelections(coords);
};
SourcesTestRunner.typeIn = function(editor, typeText, callback) {
callback = callback || new Function();
const noop = new Function();
for (let charIndex = 0; charIndex < typeText.length; ++charIndex) {
const iterationCallback = (charIndex + 1 === typeText.length ? callback : noop);
switch (typeText[charIndex]) {
case '\n':
SourcesTestRunner.fakeKeyEvent(editor, 'Enter', null, iterationCallback);
break;
case 'L':
SourcesTestRunner.fakeKeyEvent(editor, 'ArrowLeft', null, iterationCallback);
break;
case 'R':
SourcesTestRunner.fakeKeyEvent(editor, 'ArrowRight', null, iterationCallback);
break;
case 'U':
SourcesTestRunner.fakeKeyEvent(editor, 'ArrowUp', null, iterationCallback);
break;
case 'D':
SourcesTestRunner.fakeKeyEvent(editor, 'ArrowDown', null, iterationCallback);
break;
default:
SourcesTestRunner.fakeKeyEvent(editor, typeText[charIndex], null, iterationCallback);
}
}
};
const eventCodes = {
Enter: 13,
Home: 36,
ArrowLeft: 37,
ArrowUp: 38,
ArrowRight: 39,
ArrowDown: 40
};
function createCodeMirrorFakeEvent(editor, eventType, code, charCode, modifiers) {
function eventPreventDefault() {
this._handled = true;
}
const event = {
_handled: false,
type: eventType,
keyCode: code,
charCode: charCode,
preventDefault: eventPreventDefault,
stopPropagation: function() {},
target: editor._codeMirror.display.input.textarea
};
if (modifiers) {
for (let i = 0; i < modifiers.length; ++i) {
event[modifiers[i]] = true;
}
}
return event;
}
function fakeCodeMirrorKeyEvent(editor, eventType, code, charCode, modifiers) {
const event = createCodeMirrorFakeEvent(editor, eventType, code, charCode, modifiers);
switch (eventType) {
case 'keydown':
editor._codeMirror.triggerOnKeyDown(event);
break;
case 'keypress':
editor._codeMirror.triggerOnKeyPress(event);
break;
case 'keyup':
editor._codeMirror.triggerOnKeyUp(event);
break;
default:
throw new Error('Unknown KeyEvent type');
}
return event._handled;
}
function fakeCodeMirrorInputEvent(editor, character) {
if (typeof character !== 'string') {
return;
}
const input = editor._codeMirror.display.input;
const value = input.textarea.value;
const newValue =
value.substring(0, input.textarea.selectionStart) + character + value.substring(input.textarea.selectionEnd);
const caretPosition = input.textarea.selectionStart + character.length;
input.textarea.value = newValue;
input.textarea.setSelectionRange(caretPosition, caretPosition);
input.poll();
}
SourcesTestRunner.fakeKeyEvent = function(editor, originalCode, modifiers, callback) {
modifiers = modifiers || [];
let code;
let charCode;
if (originalCode === '\'') {
code = 222;
charCode = 0;
} else if (originalCode === '"') {
code = 222;
modifiers.push('shiftKey');
charCode = 34;
} else if (originalCode === '(') {
code = '9'.charCodeAt(0);
modifiers.push('shiftKey');
charCode = originalCode.charCodeAt(0);
}
code = code || eventCodes[originalCode] || originalCode;
if (typeof code === 'string') {
code = code.charCodeAt(0);
}
if (fakeCodeMirrorKeyEvent(editor, 'keydown', code, charCode, modifiers)) {
callback();
return;
}
if (fakeCodeMirrorKeyEvent(editor, 'keypress', code, charCode, modifiers)) {
callback();
return;
}
const inputReadPromise = new Promise(x => editor._codeMirror.on('inputRead', x));
fakeCodeMirrorInputEvent(editor, originalCode);
fakeCodeMirrorKeyEvent(editor, 'keyup', code, charCode, modifiers);
inputReadPromise.then(callback);
};
SourcesTestRunner.dumpSelectionStats = function(textEditor) {
const listHashMap = {};
const sortedKeys = [];
const selections = textEditor.selections();
for (let i = 0; i < selections.length; ++i) {
const selection = selections[i];
const text = textEditor.text(selection);
if (!listHashMap[text]) {
listHashMap[text] = 1;
sortedKeys.push(text);
} else {
++listHashMap[text];
}
}
for (let i = 0; i < sortedKeys.length; ++i) {
let keyName = sortedKeys[i];
if (!keyName.length) {
keyName = '<Empty string>';
} else {
keyName = '\'' + keyName + '\'';
}
TestRunner.addResult(keyName + ': ' + listHashMap[sortedKeys[i]]);
}
};