blob: c72d7d599cd7b4878873e8f50a015fce275c3d01 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Include test fixture.
GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
/**
* A TTS class implementing speak and stop methods intended only for testing.
* @constructor
* @implements cvox.TtsInterface
*/
function TestTts() {
this.strings = [];
}
/**
* The strings that were spoken since the last call to get().
* @type {Array<string>}
*/
TestTts.prototype.strings;
/**
* Returns the list of strings spoken since the last time this method was
* called, and then clears the list.
* @return {Array<string>} The list of strings.
*/
TestTts.prototype.get = function() {
var result = this.strings;
this.strings = [];
return result;
};
/** @override */
TestTts.prototype.speak = function(text, queueMode, properties) {
this.strings.push(text);
};
/** @override */
TestTts.prototype.isSpeaking = function() {
return false;
};
/** @override */
TestTts.prototype.stop = function() {
// Do nothing.
};
/** @override */
TestTts.prototype.increaseOrDecreaseProperty =
function(propertyName, increase) {
// Do nothing.
};
/**
* Stores the last braille content.
* @constructor
* @implements cvox.BrailleInterface
*/
function TestBraille() {
this.content = null;
}
/** @override */
TestBraille.prototype.write = function(params) {
this.content = params;
};
/**
* Asserts the current braille content.
*
* @param {string} text Braille text.
* @param {number=} opt_start Selection start.
* @param {number=} opt_end Selection end.
*/
TestBraille.assertContent = function(text, opt_start, opt_end) {
var c = cvox.ChromeVox.braille.content;
assertTrue(c != null);
opt_start = opt_start !== undefined ? opt_start : -1;
opt_end = opt_end !== undefined ? opt_end : opt_start;
assertEquals(text, c.text.toString());
assertEquals(opt_start, c.startIndex);
assertEquals(opt_end, c.endIndex);
};
/**
* Test fixture.
* @constructor
* @extends {ChromeVoxUnitTestBase}
*/
function ChromeVoxEditableTextUnitTest() {}
ChromeVoxEditableTextUnitTest.prototype = {
__proto__: ChromeVoxUnitTestBase.prototype,
/** @override */
closureModuleDeps: [
'cvox.ChromeVoxEditableElement',
'cvox.ChromeVoxEditableHTMLInput',
'cvox.ChromeVoxEditableTextBase',
'cvox.ChromeVoxEventWatcher',
'cvox.TextChangeEvent',
'cvox.TtsInterface',
'cvox.TypingEcho',
],
/** @override */
setUp: function() {
// TODO: These tests are all assuming we used the IBeam cursor.
// We need to add coverage for block cursor.
cvox.ChromeVoxEditableTextBase.useIBeamCursor = true;
cvox.ChromeVox.typingEcho = cvox.TypingEcho.CHARACTER_AND_WORD;
cvox.ChromeVoxEditableTextBase.eventTypingEcho = false;
cvox.ChromeVoxEditableTextBase.shouldSpeakInsertions = true;
cvox.ChromeVox.braille = new TestBraille();
/** Simple mock. */
Msgs = {};
/**
* Simply return the message id.
* @param {string} msg Message id.
* @return {string} Message id.
*/
Msgs.getMsg = function(msg) {
return msg;
};
},
/**
* Sets up for a cursor movement test.
* @param {string} tagName Desired tag name, "input" or "textarea".
* @return {Object} object containing the editable element, and functions
* to prepare, run the test, and tear down.
* @private
*/
setUpForCursorTest_: function(tagName) {
var element, editable;
switch (tagName) {
case 'input':
element = document.createElement('input');
editable = new cvox.ChromeVoxEditableHTMLInput(element, new TestTts());
break;
case 'textarea':
element = document.createElement('textarea');
editable = new cvox.ChromeVoxEditableTextArea(element, new TestTts());
break;
default:
throw 'invalid tagName in setUpForCursorTest_';
}
document.body.appendChild(element);
element.focus();
var expect = function(str) {
assertEquals(element.selectionStart, element.selectionEnd);
assertEquals(str, element.value.substring(0, element.selectionStart) +
'|' + element.value.substring(element.selectionEnd));
};
return {
editable: editable,
expect: expect,
prepare: function(str) {
var position = str.indexOf('|');
var value = str.substring(0, position) + str.substring(position + 1);
element.value = value;
element.selectionStart = element.selectionEnd = position;
editable.update(true /* triggeredByUser */);
expect(str);
},
tearDown: function() {
document.body.removeChild(element);
}
};
}
};
TEST_F('ChromeVoxEditableTextUnitTest', 'CursorNavigation', function() {
var tts = new TestTts();
var obj = new cvox.ChromeVoxEditableTextBase('Hello', 0, 0, false, tts);
obj.changed(new cvox.TextChangeEvent('Hello', 1, 1));
obj.changed(new cvox.TextChangeEvent('Hello', 2, 2));
obj.changed(new cvox.TextChangeEvent('Hello', 3, 3));
obj.changed(new cvox.TextChangeEvent('Hello', 4, 4));
obj.changed(new cvox.TextChangeEvent('Hello', 5, 5));
obj.changed(new cvox.TextChangeEvent('Hello', 4, 4));
obj.changed(new cvox.TextChangeEvent('Hello', 3, 3));
assertEqualStringArrays(['H', 'e', 'l', 'l', 'o',
'o', 'l'], tts.get());
obj.changed(new cvox.TextChangeEvent('Hello', 0, 0));
obj.changed(new cvox.TextChangeEvent('Hello', 5, 5));
assertEqualStringArrays(['Hel', 'Hello'], tts.get());
});
/** Test typing words. */
TEST_F('ChromeVoxEditableTextUnitTest', 'TypingWords', function() {
var tts = new TestTts();
var obj = new cvox.ChromeVoxEditableTextBase('', 0, 0, false, tts);
obj.changed(new cvox.TextChangeEvent('H', 1, 1));
obj.changed(new cvox.TextChangeEvent('He', 2, 2));
obj.changed(new cvox.TextChangeEvent('Hel', 3, 3));
obj.changed(new cvox.TextChangeEvent('Hell', 4, 4));
obj.changed(new cvox.TextChangeEvent('Hello', 5, 5));
obj.changed(new cvox.TextChangeEvent('Hello,', 6, 6));
obj.changed(new cvox.TextChangeEvent('Hello, ', 7, 7));
obj.changed(new cvox.TextChangeEvent('Hello, W', 8, 8));
obj.changed(new cvox.TextChangeEvent('Hello, Wo', 9, 9));
obj.changed(new cvox.TextChangeEvent('Hello, Wor', 10, 10));
obj.changed(new cvox.TextChangeEvent('Hello, Worl', 11, 11));
obj.changed(new cvox.TextChangeEvent('Hello, World', 12, 12));
obj.changed(new cvox.TextChangeEvent('Hello, World.', 13, 13));
assertEqualStringArrays(['H', 'e', 'l', 'l', 'o', 'Hello,',
' ',
'W', 'o', 'r', 'l', 'd', 'World.'],
tts.get());
// Backspace
obj.changed(new cvox.TextChangeEvent('Hello, World', 12, 12));
obj.changed(new cvox.TextChangeEvent('Hello, Worl', 11, 11));
obj.changed(new cvox.TextChangeEvent('Hello, Wor', 10, 10));
assertEqualStringArrays(['.', 'd', 'l'], tts.get());
// Forward-delete
cvox.ChromeVoxEditableTextBase.useIBeamCursor = true;
obj.changed(new cvox.TextChangeEvent('Hello, Wor', 9, 9));
obj.changed(new cvox.TextChangeEvent('Hello, Wor', 8, 8));
obj.changed(new cvox.TextChangeEvent('Hello, Wor', 7, 7));
obj.changed(new cvox.TextChangeEvent('Hello, or', 7, 7));
obj.changed(new cvox.TextChangeEvent('Hello, r', 7, 7));
obj.changed(new cvox.TextChangeEvent('Hello, ', 7, 7));
assertEqualStringArrays(['r', 'o', 'W', 'W', 'o', 'r'], tts.get());
obj.changed(new cvox.TextChangeEvent('Hello, Wor', 10, 10));
cvox.ChromeVoxEditableTextBase.useIBeamCursor = false;
obj.changed(new cvox.TextChangeEvent('Hello, Wor', 9, 9));
obj.changed(new cvox.TextChangeEvent('Hello, Wor', 8, 8));
obj.changed(new cvox.TextChangeEvent('Hello, Wor', 7, 7));
obj.changed(new cvox.TextChangeEvent('Hello, or', 7, 7));
obj.changed(new cvox.TextChangeEvent('Hello, r', 7, 7));
obj.changed(new cvox.TextChangeEvent('Hello, ', 7, 7));
assertEqualStringArrays(['Wor', 'r', 'o', 'W', 'o', 'r'], tts.get());
// Clear all
obj.changed(new cvox.TextChangeEvent('', 0, 0));
assertEqualStringArrays(['Hello, , deleted'], tts.get());
// Paste / insert a whole word
obj.changed(new cvox.TextChangeEvent('Hello', 5, 5));
assertEqualStringArrays(['Hello'], tts.get());
obj.changed(new cvox.TextChangeEvent('Hello, World', 12, 12));
assertEqualStringArrays([', World'], tts.get());
});
/** Test selection. */
TEST_F('ChromeVoxEditableTextUnitTest', 'Selection', function() {
var tts = new TestTts();
var obj =
new cvox.ChromeVoxEditableTextBase('Hello, world.', 0, 0, false, tts);
obj.changed(new cvox.TextChangeEvent('Hello, world.', 0, 1));
obj.changed(new cvox.TextChangeEvent('Hello, world.', 0, 2));
obj.changed(new cvox.TextChangeEvent('Hello, world.', 0, 3));
obj.changed(new cvox.TextChangeEvent('Hello, world.', 0, 4));
obj.changed(new cvox.TextChangeEvent('Hello, world.', 0, 5));
obj.changed(new cvox.TextChangeEvent('Hello, world.', 0, 6));
assertEqualStringArrays(['H', 'selected',
'e', 'added_to_selection',
'l', 'added_to_selection',
'l', 'added_to_selection',
'o', 'added_to_selection',
',', 'added_to_selection'],
tts.get());
obj.changed(new cvox.TextChangeEvent('Hello, world.', 0, 12));
assertEqualStringArrays([' world', 'added_to_selection'],
tts.get());
obj.changed(new cvox.TextChangeEvent('Hello, world.', 1, 12));
assertEqualStringArrays(['H', 'removed_from_selection'],
tts.get());
obj.changed(new cvox.TextChangeEvent('Hello, world.', 2, 5));
assertEqualStringArrays(['llo', 'selected'],
tts.get());
obj.changed(new cvox.TextChangeEvent('Hello, world.', 2, 2));
assertEqualStringArrays(['Unselected'],
tts.get());
});
/** Test multi-line text. */
TEST_F('ChromeVoxEditableTextUnitTest', 'MultiLineText', function() {
var str = 'This string\nspans\nfive lines.\n \n';
var tts = new TestTts();
var obj = new cvox.ChromeVoxEditableElement(null, str, 0, 0, false, tts);
obj.multiline = true;
obj.getLineIndex = function(index) {
if (index >= 33) {
return 4;
} else if (index >= 30) {
return 3;
} else if (index >= 18) {
return 2;
} else if (index >= 12) {
return 1;
} else {
return 0;
}
};
obj.getLineStart = function(index) {
return [0, 12, 18, 30, 33][index];
};
obj.getLineEnd = function(index) {
return [11, 17, 29, 32, 33][index];
};
assertEquals('This string', obj.getLine(0));
obj.changed(new cvox.TextChangeEvent(str, 12, 12));
assertEqualStringArrays(['spans'], tts.get());
TestBraille.assertContent('spans', 0);
obj.changed(new cvox.TextChangeEvent(str, 18, 18));
assertEqualStringArrays(['five lines.'], tts.get());
TestBraille.assertContent('five lines.', 0);
obj.changed(new cvox.TextChangeEvent(str, 30, 30));
assertEqualStringArrays(['text_box_whitespace'], tts.get());
TestBraille.assertContent(' ', 0);
obj.changed(new cvox.TextChangeEvent(str, 33, 33));
assertEqualStringArrays(['text_box_blank'], tts.get());
TestBraille.assertContent('', 0);
obj.changed(new cvox.TextChangeEvent(str, 0, 1));
assertEqualStringArrays(['T', 'selected'], tts.get());
TestBraille.assertContent('This string', 0, 1);
obj.changed(new cvox.TextChangeEvent(str, 0, 12));
assertEqualStringArrays(['his string\n', 'added_to_selection'],
tts.get());
// Newline stripped, thus 11, not 12.
TestBraille.assertContent('This string', 0, 11);
obj.changed(new cvox.TextChangeEvent(str, 0, str.length));
assertEqualStringArrays([str.substr(12), 'added_to_selection'],
tts.get());
TestBraille.assertContent('This string', 0, 11);
obj.changed(new cvox.TextChangeEvent(str, 12, 19));
assertEqualStringArrays(['spans\nf', 'selected'], tts.get());
TestBraille.assertContent('spans', 0, 5);
});
/**
* Test autocomplete; suppose a user is typing "google.com/firefox" into an
* address bar, and it's being autocompleted. Sometimes it's autocompleted
* as they type, sometimes there's a short delay.
*/
TEST_F('ChromeVoxEditableTextUnitTest', 'Autocomplete', function() {
var tts = new TestTts();
var obj = new cvox.ChromeVoxEditableTextBase('', 0, 0, false, tts);
// User types 'g'
obj.changed(new cvox.TextChangeEvent('g', 1, 1));
assertEqualStringArrays(['g'], tts.get());
// The rest of 'google.com' is autocompleted and automatically selected.
obj.changed(new cvox.TextChangeEvent('google.com', 1, 10));
assertEqualStringArrays(['oogle.com, oogle.com'], tts.get());
// The user doesn't realize it and types a few more characters of 'google.com'
// and this changes the selection (unselecting) as the user types them.
obj.changed(new cvox.TextChangeEvent('google.com', 2, 10));
assertEqualStringArrays(['o', 'ogle.com'], tts.get());
obj.changed(new cvox.TextChangeEvent('google.com', 3, 10));
assertEqualStringArrays(['o', 'gle.com'], tts.get());
obj.changed(new cvox.TextChangeEvent('google.com', 4, 10));
assertEqualStringArrays(['g', 'le.com'], tts.get());
// The user presses right-arrow, which fully unselects the remaining text.
obj.changed(new cvox.TextChangeEvent('google.com', 10, 10));
assertEqualStringArrays(['Unselected'], tts.get());
// The user types '/'
obj.changed(new cvox.TextChangeEvent('google.com/', 11, 11));
assertEqualStringArrays(['com/'], tts.get());
// The user types 'f', and 'finance' is autocompleted
obj.changed(new cvox.TextChangeEvent('google.com/finance', 12, 18));
assertEqualStringArrays(['finance, inance'], tts.get());
// The user types 'i'
obj.changed(new cvox.TextChangeEvent('google.com/finance', 13, 18));
assertEqualStringArrays(['i', 'nance'], tts.get());
// The user types 'r', now 'firefox' is autocompleted
obj.changed(new cvox.TextChangeEvent('google.com/firefox', 14, 18));
assertEqualStringArrays(['refox, efox'], tts.get());
// The user presses right-arrow to accept the completion.
obj.changed(new cvox.TextChangeEvent('google.com/firefox', 18, 18));
assertEqualStringArrays(['Unselected'], tts.get());
});
/**
* Test a few common scenarios where text is replaced.
*/
TEST_F('ChromeVoxEditableTextUnitTest', 'ReplacingText', function() {
// Initial value is Alabama.
var tts = new TestTts();
var obj = new cvox.ChromeVoxEditableTextBase('Alabama', 0, 0, false, tts);
// Entire text replaced with Alaska.
obj.changed(new cvox.TextChangeEvent('Alaska', 0, 0));
assertEqualStringArrays(['Alaska'], tts.get());
// Entire text selected.
obj.changed(new cvox.TextChangeEvent('Alaska', 0, 6));
assertEqualStringArrays(['Alaska', 'selected'], tts.get());
// Entire text replaced with Arizona.
obj.changed(new cvox.TextChangeEvent('Arizona', 7, 7));
assertEqualStringArrays(['Arizona'], tts.get());
// Entire text selected.
obj.changed(new cvox.TextChangeEvent('Arizona', 0, 7));
assertEqualStringArrays(['Arizona', 'selected'], tts.get());
// Click between 'r' and 'i'.
obj.changed(new cvox.TextChangeEvent('Arizona', 2, 2));
assertEqualStringArrays(['Unselected'], tts.get());
// Next character removed from selection.
obj.changed(new cvox.TextChangeEvent('Arizona', 2, 7));
assertEqualStringArrays(['izona', 'selected'], tts.get());
// Selection replaced with "kansas" to make Arkansas. This time it
// says "kansas" because the deleted text was selected.
obj.changed(new cvox.TextChangeEvent('Arkansas', 8, 8));
assertEqualStringArrays(['kansas'], tts.get());
});
/**
* Test feedback when text changes in a long sentence.
*/
TEST_F('ChromeVoxEditableTextUnitTest', 'ReplacingLongText', function() {
var tts = new TestTts();
var obj = new cvox.ChromeVoxEditableTextBase(
'I love deadlines. I like the whooshing sound they make as they fly by.',
0, 0, false, tts);
// Change the whole sentence without moving the cursor. It should speak
// only the part that changed, but it should speak whole words.
obj.changed(new cvox.TextChangeEvent(
'I love deadlines. I love the whooshing sounds they make as they fly by.',
0, 0));
assertEqualStringArrays(['love the whooshing sounds'], tts.get());
});
/** Tests character echo. */
TEST_F('ChromeVoxEditableTextUnitTest', 'CharacterEcho', function() {
cvox.ChromeVox.typingEcho = cvox.TypingEcho.CHARACTER;
var tts = new TestTts();
var obj = new cvox.ChromeVoxEditableTextBase('', 0, 0, false, tts);
obj.changed(new cvox.TextChangeEvent('H', 1, 1));
obj.changed(new cvox.TextChangeEvent('He', 2, 2));
obj.changed(new cvox.TextChangeEvent('Hel', 3, 3));
obj.changed(new cvox.TextChangeEvent('Hell', 4, 4));
obj.changed(new cvox.TextChangeEvent('Hello', 5, 5));
obj.changed(new cvox.TextChangeEvent('Hello,', 6, 6));
obj.changed(new cvox.TextChangeEvent('Hello, ', 7, 7));
obj.changed(new cvox.TextChangeEvent('Hello, W', 8, 8));
obj.changed(new cvox.TextChangeEvent('Hello, Wo', 9, 9));
obj.changed(new cvox.TextChangeEvent('Hello, Wor', 10, 10));
obj.changed(new cvox.TextChangeEvent('Hello, Worl', 11, 11));
obj.changed(new cvox.TextChangeEvent('Hello, World', 12, 12));
obj.changed(new cvox.TextChangeEvent('Hello, World.', 13, 13));
assertEqualStringArrays(
['H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '.'],
tts.get());
});
/** Tests word echo. */
TEST_F('ChromeVoxEditableTextUnitTest', 'WordEcho', function() {
cvox.ChromeVox.typingEcho = cvox.TypingEcho.WORD;
var tts = new TestTts();
var obj = new cvox.ChromeVoxEditableTextBase('', 0, 0, false, tts);
obj.changed(new cvox.TextChangeEvent('H', 1, 1));
obj.changed(new cvox.TextChangeEvent('He', 2, 2));
obj.changed(new cvox.TextChangeEvent('Hel', 3, 3));
obj.changed(new cvox.TextChangeEvent('Hell', 4, 4));
obj.changed(new cvox.TextChangeEvent('Hello', 5, 5));
obj.changed(new cvox.TextChangeEvent('Hello,', 6, 6));
obj.changed(new cvox.TextChangeEvent('Hello, ', 7, 7));
obj.changed(new cvox.TextChangeEvent('Hello, W', 8, 8));
obj.changed(new cvox.TextChangeEvent('Hello, Wo', 9, 9));
obj.changed(new cvox.TextChangeEvent('Hello, Wor', 10, 10));
obj.changed(new cvox.TextChangeEvent('Hello, Worl', 11, 11));
obj.changed(new cvox.TextChangeEvent('Hello, World', 12, 12));
obj.changed(new cvox.TextChangeEvent('Hello, World.', 13, 13));
assertEqualStringArrays(
['Hello,', 'World.'],
tts.get());
});
/** Tests no echo. */
TEST_F('ChromeVoxEditableTextUnitTest', 'NoEcho', function() {
cvox.ChromeVox.typingEcho = cvox.TypingEcho.NONE;
var tts = new TestTts();
var obj = new cvox.ChromeVoxEditableTextBase('', 0, 0, false, tts);
obj.changed(new cvox.TextChangeEvent('H', 1, 1));
obj.changed(new cvox.TextChangeEvent('He', 2, 2));
obj.changed(new cvox.TextChangeEvent('Hel', 3, 3));
obj.changed(new cvox.TextChangeEvent('Hell', 4, 4));
obj.changed(new cvox.TextChangeEvent('Hello', 5, 5));
obj.changed(new cvox.TextChangeEvent('Hello,', 6, 6));
obj.changed(new cvox.TextChangeEvent('Hello, ', 7, 7));
obj.changed(new cvox.TextChangeEvent('Hello, W', 8, 8));
obj.changed(new cvox.TextChangeEvent('Hello, Wo', 9, 9));
obj.changed(new cvox.TextChangeEvent('Hello, Wor', 10, 10));
obj.changed(new cvox.TextChangeEvent('Hello, Worl', 11, 11));
obj.changed(new cvox.TextChangeEvent('Hello, World', 12, 12));
obj.changed(new cvox.TextChangeEvent('Hello, World.', 13, 13));
assertEqualStringArrays(
[],
tts.get());
});
/** Tests cursor movement in an input field by character. */
TEST_F('ChromeVoxEditableTextUnitTest', 'CursorMovementByCharacter',
function() {
var test = this.setUpForCursorTest_('input');
var editable = test.editable, prepare = test.prepare, expect = test.expect;
try {
// Moving near the beginning of the text.
prepare('|"Hello," says Sally.');
editable.moveCursorToPreviousCharacter();
expect('|"Hello," says Sally.');
editable.moveCursorToNextCharacter();
expect('"|Hello," says Sally.');
editable.moveCursorToNextCharacter();
expect('"H|ello," says Sally.');
// Moving near the end of the text.
prepare('"Hello," says Sally|.');
editable.moveCursorToPreviousCharacter();
expect('"Hello," says Sall|y.');
editable.moveCursorToNextCharacter();
expect('"Hello," says Sally|.');
editable.moveCursorToNextCharacter();
expect('"Hello," says Sally.|');
editable.moveCursorToNextCharacter();
expect('"Hello," says Sally.|');
} finally {
test.tearDown();
}
});
/** Tests cursor movement in an input field by word. */
TEST_F('ChromeVoxEditableTextUnitTest', 'CursorMovementByWord', function() {
var test = this.setUpForCursorTest_('input');
var editable = test.editable, prepare = test.prepare, expect = test.expect;
try {
// Moving forward.
prepare('"He|llo," says Sally.');
editable.moveCursorToNextWord();
expect('"Hello|," says Sally.');
editable.moveCursorToNextWord();
expect('"Hello," says| Sally.');
editable.moveCursorToNextWord();
expect('"Hello," says Sally|.');
editable.moveCursorToNextWord();
expect('"Hello," says Sally.|');
editable.moveCursorToNextWord();
expect('"Hello," says Sally.|');
// Moving backward.
prepare('"Hello," says S|ally.');
editable.moveCursorToPreviousWord();
expect('"Hello," says |Sally.');
editable.moveCursorToPreviousWord();
expect('"Hello," |says Sally.');
editable.moveCursorToPreviousWord();
expect('"|Hello," says Sally.');
editable.moveCursorToPreviousWord();
expect('|"Hello," says Sally.');
editable.moveCursorToPreviousWord();
expect('|"Hello," says Sally.');
} finally {
test.tearDown();
}
});
/** Tests that character and word movement still work in <textarea>. */
TEST_F('ChromeVoxEditableTextUnitTest', 'CursorMovementTextArea', function() {
var test = this.setUpForCursorTest_('textarea');
var editable = test.editable, prepare = test.prepare, expect = test.expect;
try {
prepare('|Hello, Larry.\nHello, Sergey.');
editable.moveCursorToNextCharacter();
expect('H|ello, Larry.\nHello, Sergey.');
editable.moveCursorToNextWord();
expect('Hello|, Larry.\nHello, Sergey.');
editable.moveCursorToNextWord();
expect('Hello, Larry|.\nHello, Sergey.');
editable.moveCursorToNextWord();
expect('Hello, Larry.\nHello|, Sergey.');
editable.moveCursorToNextCharacter();
expect('Hello, Larry.\nHello,| Sergey.');
editable.moveCursorToPreviousWord();
expect('Hello, Larry.\n|Hello, Sergey.');
editable.moveCursorToPreviousCharacter();
expect('Hello, Larry.|\nHello, Sergey.');
} finally {
test.tearDown();
}
});
/** Tests that line navigation works. */
TEST_F('ChromeVoxEditableTextUnitTest', 'CursorMovementByLine', function() {
var test = this.setUpForCursorTest_('textarea');
var editable = test.editable, prepare = test.prepare, expect = test.expect;
try {
prepare('123\n1234\n1234|5\n\nHi');
editable.moveCursorToPreviousLine();
expect('123\n1234|\n12345\n\nHi');
editable.moveCursorToPreviousLine();
expect('123|\n1234\n12345\n\nHi');
editable.moveCursorToNextLine();
expect('123\n123|4\n12345\n\nHi');
editable.moveCursorToNextLine();
expect('123\n1234\n123|45\n\nHi');
editable.moveCursorToNextLine();
expect('123\n1234\n12345\n|\nHi');
editable.moveCursorToNextLine();
expect('123\n1234\n12345\n\n|Hi');
editable.moveCursorToNextLine();
expect('123\n1234\n12345\n\nHi|');
prepare('foo|bar');
editable.moveCursorToPreviousLine();
expect('|foobar');
editable.moveCursorToPreviousLine();
expect('|foobar');
editable.moveCursorToNextLine();
expect('foobar|');
editable.moveCursorToNextLine();
expect('foobar|');
} finally {
test.tearDown();
}
});
/** Tests that paragraph navigation works. */
TEST_F('ChromeVoxEditableTextUnitTest', 'CursorMovementByParagraph', function() {
var test = this.setUpForCursorTest_('textarea');
var editable = test.editable, prepare = test.prepare, expect = test.expect;
try {
prepare('Para|graph 1\nParagraph 2\nParagraph 3');
editable.moveCursorToNextParagraph();
expect('Paragraph 1\n|Paragraph 2\nParagraph 3');
editable.moveCursorToNextParagraph();
expect('Paragraph 1\nParagraph 2\n|Paragraph 3');
editable.moveCursorToNextParagraph();
expect('Paragraph 1\nParagraph 2\nParagraph 3|');
editable.moveCursorToPreviousParagraph();
expect('Paragraph 1\nParagraph 2\n|Paragraph 3');
editable.moveCursorToPreviousParagraph();
expect('Paragraph 1\n|Paragraph 2\nParagraph 3');
editable.moveCursorToPreviousParagraph();
expect('|Paragraph 1\nParagraph 2\nParagraph 3');
} finally {
test.tearDown();
}
});
/** Tests normalization of TextChangeEvent's */
TEST_F('ChromeVoxEditableTextUnitTest', 'TextChangeEvent', function() {
var event1 = new cvox.TextChangeEvent('foo', 0, 1, true);
var event2 = new cvox.TextChangeEvent('foo', 1, 0, true);
var event3 = new cvox.TextChangeEvent('foo', 1, 1, true);
assertEquals(0, event1.start);
assertEquals(1, event1.end);
assertEquals(0, event2.start);
assertEquals(1, event2.end);
assertEquals(1, event3.start);
assertEquals(1, event3.end);
});
TEST_F('ChromeVoxEditableTextUnitTest', 'ContentEditableBraille', function() {
this.loadDoc(function() {/*!
<div id='1' contenteditable='true'>
Some &nbsp; text.<br><br>
After blank line.
</div>
*/});
var element = $('1');
element.focus();
var editable = new cvox.ChromeVoxEditableContentEditable(
element, new TestTts());
var firstLine = 'Some text.\n';
for (var i = 0; i < firstLine.length; ++i) {
editable.update(true);
TestBraille.assertContent(firstLine, i, i);
window.getSelection().modify('move', 'forward', 'character');
}
// We should have crossed the line break to the second line which is blank.
editable.update(true);
TestBraille.assertContent('', 0, 0);
});
TEST_F('ChromeVoxEditableTextUnitTest', 'TypingNonBreakingSpaces', function() {
var tts = new TestTts();
var obj = new cvox.ChromeVoxEditableTextBase('Hello', 0, 0, false, tts);
obj.changed(new cvox.TextChangeEvent('h', 1, 1));
obj.changed(new cvox.TextChangeEvent('hi', 2, 2));
obj.changed(new cvox.TextChangeEvent('hi\u00a0', 3, 3));
obj.changed(new cvox.TextChangeEvent('hi t', 4, 4));
assertEqualStringArrays(['h', 'i', 'hi ', 't'], tts.get());
});