| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 // Include test fixture. | |
| 6 GEN_INCLUDE(['../testing/chromevox_unittest_base.js']); | |
| 7 | |
| 8 /** | |
| 9 * A TTS class implementing speak and stop methods intended only for testing. | |
| 10 * @constructor | |
| 11 * @implements cvox.TtsInterface | |
| 12 */ | |
| 13 function TestTts() { | |
| 14 this.strings = []; | |
| 15 } | |
| 16 | |
| 17 /** | |
| 18 * The strings that were spoken since the last call to get(). | |
| 19 * @type {Array.<string>} | |
| 20 */ | |
| 21 TestTts.prototype.strings; | |
| 22 | |
| 23 /** | |
| 24 * Returns the list of strings spoken since the last time this method was | |
| 25 * called, and then clears the list. | |
| 26 * @return {Array.<string>} The list of strings. | |
| 27 */ | |
| 28 TestTts.prototype.get = function() { | |
| 29 var result = this.strings; | |
| 30 this.strings = []; | |
| 31 return result; | |
| 32 }; | |
| 33 | |
| 34 /** @override */ | |
| 35 TestTts.prototype.speak = function(text, queueMode, properties) { | |
| 36 this.strings.push(text); | |
| 37 }; | |
| 38 | |
| 39 /** @override */ | |
| 40 TestTts.prototype.isSpeaking = function() { | |
| 41 return false; | |
| 42 }; | |
| 43 | |
| 44 /** @override */ | |
| 45 TestTts.prototype.stop = function() { | |
| 46 // Do nothing. | |
| 47 }; | |
| 48 | |
| 49 /** @override */ | |
| 50 TestTts.prototype.increaseOrDecreaseProperty = | |
| 51 function(propertyName, increase) { | |
| 52 // Do nothing. | |
| 53 }; | |
| 54 | |
| 55 /** | |
| 56 * Stores the last braille content. | |
| 57 * @constructor | |
| 58 * @implements cvox.BrailleInterface | |
| 59 */ | |
| 60 function TestBraille() { | |
| 61 this.content = null; | |
| 62 } | |
| 63 | |
| 64 /** @override */ | |
| 65 TestBraille.prototype.write = function(params) { | |
| 66 this.content = params; | |
| 67 }; | |
| 68 | |
| 69 /** | |
| 70 * Asserts the current braille content. | |
| 71 * | |
| 72 * @param {string} text Braille text. | |
| 73 * @param {number=} opt_start Selection start. | |
| 74 * @param {number=} opt_end Selection end. | |
| 75 */ | |
| 76 TestBraille.assertContent = function(text, opt_start, opt_end) { | |
| 77 var c = cvox.ChromeVox.braille.content; | |
| 78 assertTrue(c != null); | |
| 79 opt_start = opt_start !== undefined ? opt_start : -1; | |
| 80 opt_end = opt_end !== undefined ? opt_end : opt_start; | |
| 81 assertEquals(text, c.text.toString()); | |
| 82 assertEquals(opt_start, c.startIndex); | |
| 83 assertEquals(opt_end, c.endIndex); | |
| 84 }; | |
| 85 | |
| 86 /** | |
| 87 * Test fixture. | |
| 88 * @constructor | |
| 89 * @extends {ChromeVoxUnitTestBase} | |
| 90 */ | |
| 91 function CvoxEditableTextUnitTest() {} | |
| 92 | |
| 93 CvoxEditableTextUnitTest.prototype = { | |
| 94 __proto__: ChromeVoxUnitTestBase.prototype, | |
| 95 | |
| 96 /** @override */ | |
| 97 closureModuleDeps: [ | |
| 98 'cvox.ChromeVoxEditableHTMLInput', | |
| 99 'cvox.ChromeVoxEditableTextBase', | |
| 100 'cvox.ChromeVoxEventWatcher', | |
| 101 'cvox.TextChangeEvent', | |
| 102 'cvox.TtsInterface', | |
| 103 'cvox.TypingEcho', | |
| 104 ], | |
| 105 | |
| 106 /** @override */ | |
| 107 setUp: function() { | |
| 108 // TODO: These tests are all assuming we used the IBeam cursor. | |
| 109 // We need to add coverage for block cursor. | |
| 110 cvox.ChromeVoxEditableTextBase.useIBeamCursor = true; | |
| 111 cvox.ChromeVox.typingEcho = cvox.TypingEcho.CHARACTER_AND_WORD; | |
| 112 cvox.ChromeVoxEditableTextBase.eventTypingEcho = false; | |
| 113 cvox.ChromeVox.braille = new TestBraille(); | |
| 114 | |
| 115 /** Simple mock. */ | |
| 116 cvox.ChromeVox.msgs = {}; | |
| 117 | |
| 118 /** | |
| 119 * Simply return the message id. | |
| 120 * @param {string} msg Message id. | |
| 121 * @return {string} Message id. | |
| 122 */ | |
| 123 cvox.ChromeVox.msgs.getMsg = function(msg) { | |
| 124 return msg; | |
| 125 }; | |
| 126 }, | |
| 127 | |
| 128 /** | |
| 129 * Sets up for a cursor movement test. | |
| 130 * @param {string} tagName Desired tag name, "input" or "textarea". | |
| 131 * @return {Object} object containing the editable element, and functions | |
| 132 * to prepare, run the test, and tear down. | |
| 133 * @private | |
| 134 */ | |
| 135 setUpForCursorTest_: function(tagName) { | |
| 136 var element, editable; | |
| 137 switch (tagName) { | |
| 138 case 'input': | |
| 139 element = document.createElement('input'); | |
| 140 editable = new cvox.ChromeVoxEditableHTMLInput(element, new TestTts()); | |
| 141 break; | |
| 142 case 'textarea': | |
| 143 element = document.createElement('textarea'); | |
| 144 editable = new cvox.ChromeVoxEditableTextArea(element, new TestTts()); | |
| 145 break; | |
| 146 default: | |
| 147 throw 'invalid tagName in setUpForCursorTest_'; | |
| 148 } | |
| 149 document.body.appendChild(element); | |
| 150 element.focus(); | |
| 151 | |
| 152 var expect = function(str) { | |
| 153 assertEquals(element.selectionStart, element.selectionEnd); | |
| 154 assertEquals(str, element.value.substring(0, element.selectionStart) + | |
| 155 '|' + element.value.substring(element.selectionEnd)); | |
| 156 }; | |
| 157 return { | |
| 158 editable: editable, | |
| 159 expect: expect, | |
| 160 prepare: function(str) { | |
| 161 var position = str.indexOf('|'); | |
| 162 var value = str.substring(0, position) + str.substring(position + 1); | |
| 163 element.value = value; | |
| 164 element.selectionStart = element.selectionEnd = position; | |
| 165 editable.update(true /* triggeredByUser */); | |
| 166 expect(str); | |
| 167 }, | |
| 168 tearDown: function() { | |
| 169 document.body.removeChild(element); | |
| 170 } | |
| 171 }; | |
| 172 } | |
| 173 }; | |
| 174 | |
| 175 TEST_F('CvoxEditableTextUnitTest', 'CursorNavigation', function() { | |
| 176 var tts = new TestTts(); | |
| 177 var obj = new cvox.ChromeVoxEditableTextBase('Hello', 0, 0, false, tts); | |
| 178 | |
| 179 obj.changed(new cvox.TextChangeEvent('Hello', 1, 1)); | |
| 180 obj.changed(new cvox.TextChangeEvent('Hello', 2, 2)); | |
| 181 obj.changed(new cvox.TextChangeEvent('Hello', 3, 3)); | |
| 182 obj.changed(new cvox.TextChangeEvent('Hello', 4, 4)); | |
| 183 obj.changed(new cvox.TextChangeEvent('Hello', 5, 5)); | |
| 184 obj.changed(new cvox.TextChangeEvent('Hello', 4, 4)); | |
| 185 obj.changed(new cvox.TextChangeEvent('Hello', 3, 3)); | |
| 186 assertEqualStringArrays(['H', 'e', 'l', 'l', 'o', | |
| 187 'o', 'l'], tts.get()); | |
| 188 obj.changed(new cvox.TextChangeEvent('Hello', 0, 0)); | |
| 189 obj.changed(new cvox.TextChangeEvent('Hello', 5, 5)); | |
| 190 assertEqualStringArrays(['Hel', 'Hello'], tts.get()); | |
| 191 }); | |
| 192 | |
| 193 /** Test typing words. */ | |
| 194 TEST_F('CvoxEditableTextUnitTest', 'TypingWords', function() { | |
| 195 var tts = new TestTts(); | |
| 196 var obj = new cvox.ChromeVoxEditableTextBase('', 0, 0, false, tts); | |
| 197 obj.changed(new cvox.TextChangeEvent('H', 1, 1)); | |
| 198 obj.changed(new cvox.TextChangeEvent('He', 2, 2)); | |
| 199 obj.changed(new cvox.TextChangeEvent('Hel', 3, 3)); | |
| 200 obj.changed(new cvox.TextChangeEvent('Hell', 4, 4)); | |
| 201 obj.changed(new cvox.TextChangeEvent('Hello', 5, 5)); | |
| 202 obj.changed(new cvox.TextChangeEvent('Hello,', 6, 6)); | |
| 203 obj.changed(new cvox.TextChangeEvent('Hello, ', 7, 7)); | |
| 204 obj.changed(new cvox.TextChangeEvent('Hello, W', 8, 8)); | |
| 205 obj.changed(new cvox.TextChangeEvent('Hello, Wo', 9, 9)); | |
| 206 obj.changed(new cvox.TextChangeEvent('Hello, Wor', 10, 10)); | |
| 207 obj.changed(new cvox.TextChangeEvent('Hello, Worl', 11, 11)); | |
| 208 obj.changed(new cvox.TextChangeEvent('Hello, World', 12, 12)); | |
| 209 obj.changed(new cvox.TextChangeEvent('Hello, World.', 13, 13)); | |
| 210 assertEqualStringArrays(['H', 'e', 'l', 'l', 'o', 'Hello,', | |
| 211 ' ', | |
| 212 'W', 'o', 'r', 'l', 'd', 'World.'], | |
| 213 tts.get()); | |
| 214 | |
| 215 // Backspace | |
| 216 obj.changed(new cvox.TextChangeEvent('Hello, World', 12, 12)); | |
| 217 obj.changed(new cvox.TextChangeEvent('Hello, Worl', 11, 11)); | |
| 218 obj.changed(new cvox.TextChangeEvent('Hello, Wor', 10, 10)); | |
| 219 assertEqualStringArrays(['.', 'd', 'l'], tts.get()); | |
| 220 | |
| 221 // Forward-delete | |
| 222 obj.changed(new cvox.TextChangeEvent('Hello, Wor', 9, 9)); | |
| 223 obj.changed(new cvox.TextChangeEvent('Hello, Wor', 8, 8)); | |
| 224 obj.changed(new cvox.TextChangeEvent('Hello, Wor', 7, 7)); | |
| 225 obj.changed(new cvox.TextChangeEvent('Hello, or', 7, 7)); | |
| 226 obj.changed(new cvox.TextChangeEvent('Hello, r', 7, 7)); | |
| 227 obj.changed(new cvox.TextChangeEvent('Hello, ', 7, 7)); | |
| 228 assertEqualStringArrays(['r', 'o', 'W', 'W', 'o', 'r'], tts.get()); | |
| 229 | |
| 230 // Clear all | |
| 231 obj.changed(new cvox.TextChangeEvent('', 0, 0)); | |
| 232 assertEqualStringArrays(['Hello, , deleted'], tts.get()); | |
| 233 | |
| 234 // Paste / insert a whole word | |
| 235 obj.changed(new cvox.TextChangeEvent('Hello', 5, 5)); | |
| 236 assertEqualStringArrays(['Hello'], tts.get()); | |
| 237 obj.changed(new cvox.TextChangeEvent('Hello, World', 12, 12)); | |
| 238 assertEqualStringArrays([', World'], tts.get()); | |
| 239 }); | |
| 240 | |
| 241 /** Test selection. */ | |
| 242 TEST_F('CvoxEditableTextUnitTest', 'Selection', function() { | |
| 243 var tts = new TestTts(); | |
| 244 var obj = | |
| 245 new cvox.ChromeVoxEditableTextBase('Hello, world.', 0, 0, false, tts); | |
| 246 obj.changed(new cvox.TextChangeEvent('Hello, world.', 0, 1)); | |
| 247 obj.changed(new cvox.TextChangeEvent('Hello, world.', 0, 2)); | |
| 248 obj.changed(new cvox.TextChangeEvent('Hello, world.', 0, 3)); | |
| 249 obj.changed(new cvox.TextChangeEvent('Hello, world.', 0, 4)); | |
| 250 obj.changed(new cvox.TextChangeEvent('Hello, world.', 0, 5)); | |
| 251 obj.changed(new cvox.TextChangeEvent('Hello, world.', 0, 6)); | |
| 252 assertEqualStringArrays(['H', 'selected', | |
| 253 'e', 'added_to_selection', | |
| 254 'l', 'added_to_selection', | |
| 255 'l', 'added_to_selection', | |
| 256 'o', 'added_to_selection', | |
| 257 ',', 'added_to_selection'], | |
| 258 tts.get()); | |
| 259 obj.changed(new cvox.TextChangeEvent('Hello, world.', 0, 12)); | |
| 260 assertEqualStringArrays([' world', 'added_to_selection'], | |
| 261 tts.get()); | |
| 262 obj.changed(new cvox.TextChangeEvent('Hello, world.', 1, 12)); | |
| 263 assertEqualStringArrays(['H', 'removed_from_selection'], | |
| 264 tts.get()); | |
| 265 obj.changed(new cvox.TextChangeEvent('Hello, world.', 2, 5)); | |
| 266 assertEqualStringArrays(['llo', 'selected'], | |
| 267 tts.get()); | |
| 268 obj.changed(new cvox.TextChangeEvent('Hello, world.', 2, 2)); | |
| 269 assertEqualStringArrays(['Unselected'], | |
| 270 tts.get()); | |
| 271 }); | |
| 272 | |
| 273 | |
| 274 /** Test multi-line text. */ | |
| 275 TEST_F('CvoxEditableTextUnitTest', 'MultiLineText', function() { | |
| 276 var str = 'This string\nspans\nfive lines.\n \n'; | |
| 277 var tts = new TestTts(); | |
| 278 var obj = new cvox.ChromeVoxEditableTextBase(str, 0, 0, false, tts); | |
| 279 obj.multiline = true; | |
| 280 obj.getLineIndex = function(index) { | |
| 281 if (index >= 33) { | |
| 282 return 4; | |
| 283 } else if (index >= 30) { | |
| 284 return 3; | |
| 285 } else if (index >= 18) { | |
| 286 return 2; | |
| 287 } else if (index >= 12) { | |
| 288 return 1; | |
| 289 } else { | |
| 290 return 0; | |
| 291 } | |
| 292 }; | |
| 293 obj.getLineStart = function(index) { | |
| 294 return [0, 12, 18, 30, 33][index]; | |
| 295 }; | |
| 296 obj.getLineEnd = function(index) { | |
| 297 return [11, 17, 29, 32, 33][index]; | |
| 298 }; | |
| 299 assertEquals('This string', obj.getLine(0)); | |
| 300 obj.changed(new cvox.TextChangeEvent(str, 12, 12)); | |
| 301 assertEqualStringArrays(['spans'], tts.get()); | |
| 302 TestBraille.assertContent('spans', 0); | |
| 303 obj.changed(new cvox.TextChangeEvent(str, 18, 18)); | |
| 304 assertEqualStringArrays(['five lines.'], tts.get()); | |
| 305 TestBraille.assertContent('five lines.', 0); | |
| 306 obj.changed(new cvox.TextChangeEvent(str, 30, 30)); | |
| 307 assertEqualStringArrays(['text_box_whitespace'], tts.get()); | |
| 308 TestBraille.assertContent(' ', 0); | |
| 309 obj.changed(new cvox.TextChangeEvent(str, 33, 33)); | |
| 310 assertEqualStringArrays(['text_box_blank'], tts.get()); | |
| 311 TestBraille.assertContent('', 0); | |
| 312 obj.changed(new cvox.TextChangeEvent(str, 0, 1)); | |
| 313 assertEqualStringArrays(['T', 'selected'], tts.get()); | |
| 314 TestBraille.assertContent('This string', 0, 1); | |
| 315 obj.changed(new cvox.TextChangeEvent(str, 0, 12)); | |
| 316 assertEqualStringArrays(['his string\n', 'added_to_selection'], | |
| 317 tts.get()); | |
| 318 // Newline stripped, thus 11, not 12. | |
| 319 TestBraille.assertContent('This string', 0, 11); | |
| 320 obj.changed(new cvox.TextChangeEvent(str, 0, str.length)); | |
| 321 assertEqualStringArrays([str.substr(12), 'added_to_selection'], | |
| 322 tts.get()); | |
| 323 TestBraille.assertContent('This string', 0, 11); | |
| 324 obj.changed(new cvox.TextChangeEvent(str, 12, 19)); | |
| 325 assertEqualStringArrays(['spans\nf', 'selected'], tts.get()); | |
| 326 TestBraille.assertContent('spans', 0, 5); | |
| 327 }); | |
| 328 | |
| 329 | |
| 330 /** | |
| 331 * Test autocomplete; suppose a user is typing "google.com/firefox" into an | |
| 332 * address bar, and it's being autocompleted. Sometimes it's autocompleted | |
| 333 * as they type, sometimes there's a short delay. | |
| 334 */ | |
| 335 TEST_F('CvoxEditableTextUnitTest', 'Autocomplete', function() { | |
| 336 var tts = new TestTts(); | |
| 337 var obj = new cvox.ChromeVoxEditableTextBase('', 0, 0, false, tts); | |
| 338 | |
| 339 // User types 'g' | |
| 340 obj.changed(new cvox.TextChangeEvent('g', 1, 1)); | |
| 341 assertEqualStringArrays(['g'], tts.get()); | |
| 342 | |
| 343 // The rest of 'google.com' is autocompleted and automatically selected. | |
| 344 obj.changed(new cvox.TextChangeEvent('google.com', 1, 10)); | |
| 345 assertEqualStringArrays(['oogle.com, oogle.com'], tts.get()); | |
| 346 | |
| 347 // The user doesn't realize it and types a few more characters of 'google.com' | |
| 348 // and this changes the selection (unselecting) as the user types them. | |
| 349 obj.changed(new cvox.TextChangeEvent('google.com', 2, 10)); | |
| 350 assertEqualStringArrays(['o', 'ogle.com'], tts.get()); | |
| 351 obj.changed(new cvox.TextChangeEvent('google.com', 3, 10)); | |
| 352 assertEqualStringArrays(['o', 'gle.com'], tts.get()); | |
| 353 obj.changed(new cvox.TextChangeEvent('google.com', 4, 10)); | |
| 354 assertEqualStringArrays(['g', 'le.com'], tts.get()); | |
| 355 | |
| 356 // The user presses right-arrow, which fully unselects the remaining text. | |
| 357 obj.changed(new cvox.TextChangeEvent('google.com', 10, 10)); | |
| 358 assertEqualStringArrays(['Unselected'], tts.get()); | |
| 359 | |
| 360 // The user types '/' | |
| 361 obj.changed(new cvox.TextChangeEvent('google.com/', 11, 11)); | |
| 362 assertEqualStringArrays(['com/'], tts.get()); | |
| 363 | |
| 364 // The user types 'f', and 'finance' is autocompleted | |
| 365 obj.changed(new cvox.TextChangeEvent('google.com/finance', 12, 18)); | |
| 366 assertEqualStringArrays(['finance, inance'], tts.get()); | |
| 367 | |
| 368 // The user types 'i' | |
| 369 obj.changed(new cvox.TextChangeEvent('google.com/finance', 13, 18)); | |
| 370 assertEqualStringArrays(['i', 'nance'], tts.get()); | |
| 371 | |
| 372 // The user types 'r', now 'firefox' is autocompleted | |
| 373 obj.changed(new cvox.TextChangeEvent('google.com/firefox', 14, 18)); | |
| 374 assertEqualStringArrays(['refox, efox'], tts.get()); | |
| 375 | |
| 376 // The user presses right-arrow to accept the completion. | |
| 377 obj.changed(new cvox.TextChangeEvent('google.com/firefox', 18, 18)); | |
| 378 assertEqualStringArrays(['Unselected'], tts.get()); | |
| 379 }); | |
| 380 | |
| 381 | |
| 382 /** | |
| 383 * Test a few common scenarios where text is replaced. | |
| 384 */ | |
| 385 TEST_F('CvoxEditableTextUnitTest', 'ReplacingText', function() { | |
| 386 // Initial value is Alabama. | |
| 387 var tts = new TestTts(); | |
| 388 var obj = new cvox.ChromeVoxEditableTextBase('Alabama', 0, 0, false, tts); | |
| 389 | |
| 390 // Entire text replaced with Alaska. | |
| 391 obj.changed(new cvox.TextChangeEvent('Alaska', 0, 0)); | |
| 392 assertEqualStringArrays(['Alaska'], tts.get()); | |
| 393 | |
| 394 // Entire text selected. | |
| 395 obj.changed(new cvox.TextChangeEvent('Alaska', 0, 6)); | |
| 396 assertEqualStringArrays(['Alaska', 'selected'], tts.get()); | |
| 397 | |
| 398 // Entire text replaced with Arizona. | |
| 399 obj.changed(new cvox.TextChangeEvent('Arizona', 7, 7)); | |
| 400 assertEqualStringArrays(['Arizona'], tts.get()); | |
| 401 | |
| 402 // Entire text selected. | |
| 403 obj.changed(new cvox.TextChangeEvent('Arizona', 0, 7)); | |
| 404 assertEqualStringArrays(['Arizona', 'selected'], tts.get()); | |
| 405 | |
| 406 // Click between 'r' and 'i'. | |
| 407 obj.changed(new cvox.TextChangeEvent('Arizona', 2, 2)); | |
| 408 assertEqualStringArrays(['Unselected'], tts.get()); | |
| 409 | |
| 410 // Next character removed from selection. | |
| 411 obj.changed(new cvox.TextChangeEvent('Arizona', 2, 7)); | |
| 412 assertEqualStringArrays(['izona', 'selected'], tts.get()); | |
| 413 | |
| 414 // Selection replaced with "kansas" to make Arkansas. This time it | |
| 415 // says "kansas" because the deleted text was selected. | |
| 416 obj.changed(new cvox.TextChangeEvent('Arkansas', 8, 8)); | |
| 417 assertEqualStringArrays(['kansas'], tts.get()); | |
| 418 }); | |
| 419 | |
| 420 | |
| 421 /** | |
| 422 * Test feedback when text changes in a long sentence. | |
| 423 */ | |
| 424 TEST_F('CvoxEditableTextUnitTest', 'ReplacingLongText', function() { | |
| 425 var tts = new TestTts(); | |
| 426 var obj = new cvox.ChromeVoxEditableTextBase( | |
| 427 'I love deadlines. I like the whooshing sound they make as they fly by.', | |
| 428 0, 0, false, tts); | |
| 429 | |
| 430 // Change the whole sentence without moving the cursor. It should speak | |
| 431 // only the part that changed, but it should speak whole words. | |
| 432 obj.changed(new cvox.TextChangeEvent( | |
| 433 'I love deadlines. I love the whooshing sounds they make as they fly by.', | |
| 434 0, 0)); | |
| 435 assertEqualStringArrays(['love the whooshing sounds'], tts.get()); | |
| 436 }); | |
| 437 | |
| 438 /** Tests character echo. */ | |
| 439 TEST_F('CvoxEditableTextUnitTest', 'CharacterEcho', function() { | |
| 440 cvox.ChromeVox.typingEcho = cvox.TypingEcho.CHARACTER; | |
| 441 var tts = new TestTts(); | |
| 442 var obj = new cvox.ChromeVoxEditableTextBase('', 0, 0, false, tts); | |
| 443 obj.changed(new cvox.TextChangeEvent('H', 1, 1)); | |
| 444 obj.changed(new cvox.TextChangeEvent('He', 2, 2)); | |
| 445 obj.changed(new cvox.TextChangeEvent('Hel', 3, 3)); | |
| 446 obj.changed(new cvox.TextChangeEvent('Hell', 4, 4)); | |
| 447 obj.changed(new cvox.TextChangeEvent('Hello', 5, 5)); | |
| 448 obj.changed(new cvox.TextChangeEvent('Hello,', 6, 6)); | |
| 449 obj.changed(new cvox.TextChangeEvent('Hello, ', 7, 7)); | |
| 450 obj.changed(new cvox.TextChangeEvent('Hello, W', 8, 8)); | |
| 451 obj.changed(new cvox.TextChangeEvent('Hello, Wo', 9, 9)); | |
| 452 obj.changed(new cvox.TextChangeEvent('Hello, Wor', 10, 10)); | |
| 453 obj.changed(new cvox.TextChangeEvent('Hello, Worl', 11, 11)); | |
| 454 obj.changed(new cvox.TextChangeEvent('Hello, World', 12, 12)); | |
| 455 obj.changed(new cvox.TextChangeEvent('Hello, World.', 13, 13)); | |
| 456 assertEqualStringArrays( | |
| 457 ['H', 'e', 'l', 'l', 'o', ',', ' ', 'W', 'o', 'r', 'l', 'd', '.'], | |
| 458 tts.get()); | |
| 459 }); | |
| 460 | |
| 461 | |
| 462 /** Tests word echo. */ | |
| 463 TEST_F('CvoxEditableTextUnitTest', 'WordEcho', function() { | |
| 464 cvox.ChromeVox.typingEcho = cvox.TypingEcho.WORD; | |
| 465 var tts = new TestTts(); | |
| 466 var obj = new cvox.ChromeVoxEditableTextBase('', 0, 0, false, tts); | |
| 467 obj.changed(new cvox.TextChangeEvent('H', 1, 1)); | |
| 468 obj.changed(new cvox.TextChangeEvent('He', 2, 2)); | |
| 469 obj.changed(new cvox.TextChangeEvent('Hel', 3, 3)); | |
| 470 obj.changed(new cvox.TextChangeEvent('Hell', 4, 4)); | |
| 471 obj.changed(new cvox.TextChangeEvent('Hello', 5, 5)); | |
| 472 obj.changed(new cvox.TextChangeEvent('Hello,', 6, 6)); | |
| 473 obj.changed(new cvox.TextChangeEvent('Hello, ', 7, 7)); | |
| 474 obj.changed(new cvox.TextChangeEvent('Hello, W', 8, 8)); | |
| 475 obj.changed(new cvox.TextChangeEvent('Hello, Wo', 9, 9)); | |
| 476 obj.changed(new cvox.TextChangeEvent('Hello, Wor', 10, 10)); | |
| 477 obj.changed(new cvox.TextChangeEvent('Hello, Worl', 11, 11)); | |
| 478 obj.changed(new cvox.TextChangeEvent('Hello, World', 12, 12)); | |
| 479 obj.changed(new cvox.TextChangeEvent('Hello, World.', 13, 13)); | |
| 480 assertEqualStringArrays( | |
| 481 ['Hello,', 'World.'], | |
| 482 tts.get()); | |
| 483 }); | |
| 484 | |
| 485 | |
| 486 /** Tests no echo. */ | |
| 487 TEST_F('CvoxEditableTextUnitTest', 'NoEcho', function() { | |
| 488 cvox.ChromeVox.typingEcho = cvox.TypingEcho.NONE; | |
| 489 var tts = new TestTts(); | |
| 490 var obj = new cvox.ChromeVoxEditableTextBase('', 0, 0, false, tts); | |
| 491 obj.changed(new cvox.TextChangeEvent('H', 1, 1)); | |
| 492 obj.changed(new cvox.TextChangeEvent('He', 2, 2)); | |
| 493 obj.changed(new cvox.TextChangeEvent('Hel', 3, 3)); | |
| 494 obj.changed(new cvox.TextChangeEvent('Hell', 4, 4)); | |
| 495 obj.changed(new cvox.TextChangeEvent('Hello', 5, 5)); | |
| 496 obj.changed(new cvox.TextChangeEvent('Hello,', 6, 6)); | |
| 497 obj.changed(new cvox.TextChangeEvent('Hello, ', 7, 7)); | |
| 498 obj.changed(new cvox.TextChangeEvent('Hello, W', 8, 8)); | |
| 499 obj.changed(new cvox.TextChangeEvent('Hello, Wo', 9, 9)); | |
| 500 obj.changed(new cvox.TextChangeEvent('Hello, Wor', 10, 10)); | |
| 501 obj.changed(new cvox.TextChangeEvent('Hello, Worl', 11, 11)); | |
| 502 obj.changed(new cvox.TextChangeEvent('Hello, World', 12, 12)); | |
| 503 obj.changed(new cvox.TextChangeEvent('Hello, World.', 13, 13)); | |
| 504 assertEqualStringArrays( | |
| 505 [], | |
| 506 tts.get()); | |
| 507 }); | |
| 508 | |
| 509 /** Tests cursor movement in an input field by character. */ | |
| 510 TEST_F('CvoxEditableTextUnitTest', 'CursorMovementByCharacter', function() { | |
| 511 var test = this.setUpForCursorTest_('input'); | |
| 512 var editable = test.editable, prepare = test.prepare, expect = test.expect; | |
| 513 try { | |
| 514 // Moving near the beginning of the text. | |
| 515 prepare('|"Hello," says Sally.'); | |
| 516 editable.moveCursorToPreviousCharacter(); | |
| 517 expect('|"Hello," says Sally.'); | |
| 518 editable.moveCursorToNextCharacter(); | |
| 519 expect('"|Hello," says Sally.'); | |
| 520 editable.moveCursorToNextCharacter(); | |
| 521 expect('"H|ello," says Sally.'); | |
| 522 | |
| 523 // Moving near the end of the text. | |
| 524 prepare('"Hello," says Sally|.'); | |
| 525 editable.moveCursorToPreviousCharacter(); | |
| 526 expect('"Hello," says Sall|y.'); | |
| 527 editable.moveCursorToNextCharacter(); | |
| 528 expect('"Hello," says Sally|.'); | |
| 529 editable.moveCursorToNextCharacter(); | |
| 530 expect('"Hello," says Sally.|'); | |
| 531 editable.moveCursorToNextCharacter(); | |
| 532 expect('"Hello," says Sally.|'); | |
| 533 } finally { | |
| 534 test.tearDown(); | |
| 535 } | |
| 536 }); | |
| 537 | |
| 538 /** Tests cursor movement in an input field by word. */ | |
| 539 TEST_F('CvoxEditableTextUnitTest', 'CursorMovementByWord', function() { | |
| 540 var test = this.setUpForCursorTest_('input'); | |
| 541 var editable = test.editable, prepare = test.prepare, expect = test.expect; | |
| 542 try { | |
| 543 // Moving forward. | |
| 544 prepare('"He|llo," says Sally.'); | |
| 545 editable.moveCursorToNextWord(); | |
| 546 expect('"Hello|," says Sally.'); | |
| 547 editable.moveCursorToNextWord(); | |
| 548 expect('"Hello," says| Sally.'); | |
| 549 editable.moveCursorToNextWord(); | |
| 550 expect('"Hello," says Sally|.'); | |
| 551 editable.moveCursorToNextWord(); | |
| 552 expect('"Hello," says Sally.|'); | |
| 553 editable.moveCursorToNextWord(); | |
| 554 expect('"Hello," says Sally.|'); | |
| 555 | |
| 556 // Moving backward. | |
| 557 prepare('"Hello," says S|ally.'); | |
| 558 editable.moveCursorToPreviousWord(); | |
| 559 expect('"Hello," says |Sally.'); | |
| 560 editable.moveCursorToPreviousWord(); | |
| 561 expect('"Hello," |says Sally.'); | |
| 562 editable.moveCursorToPreviousWord(); | |
| 563 expect('"|Hello," says Sally.'); | |
| 564 editable.moveCursorToPreviousWord(); | |
| 565 expect('|"Hello," says Sally.'); | |
| 566 editable.moveCursorToPreviousWord(); | |
| 567 expect('|"Hello," says Sally.'); | |
| 568 } finally { | |
| 569 test.tearDown(); | |
| 570 } | |
| 571 }); | |
| 572 | |
| 573 /** Tests that character and word movement still work in <textarea>. */ | |
| 574 TEST_F('CvoxEditableTextUnitTest', 'CursorMovementTextArea', function() { | |
| 575 var test = this.setUpForCursorTest_('textarea'); | |
| 576 var editable = test.editable, prepare = test.prepare, expect = test.expect; | |
| 577 try { | |
| 578 prepare('|Hello, Larry.\nHello, Sergey.'); | |
| 579 editable.moveCursorToNextCharacter(); | |
| 580 expect('H|ello, Larry.\nHello, Sergey.'); | |
| 581 editable.moveCursorToNextWord(); | |
| 582 expect('Hello|, Larry.\nHello, Sergey.'); | |
| 583 editable.moveCursorToNextWord(); | |
| 584 expect('Hello, Larry|.\nHello, Sergey.'); | |
| 585 editable.moveCursorToNextWord(); | |
| 586 expect('Hello, Larry.\nHello|, Sergey.'); | |
| 587 editable.moveCursorToNextCharacter(); | |
| 588 expect('Hello, Larry.\nHello,| Sergey.'); | |
| 589 editable.moveCursorToPreviousWord(); | |
| 590 expect('Hello, Larry.\n|Hello, Sergey.'); | |
| 591 editable.moveCursorToPreviousCharacter(); | |
| 592 expect('Hello, Larry.|\nHello, Sergey.'); | |
| 593 } finally { | |
| 594 test.tearDown(); | |
| 595 } | |
| 596 }); | |
| 597 | |
| 598 /** Tests that line navigation works. */ | |
| 599 TEST_F('CvoxEditableTextUnitTest', 'CursorMovementByLine', function() { | |
| 600 var test = this.setUpForCursorTest_('textarea'); | |
| 601 var editable = test.editable, prepare = test.prepare, expect = test.expect; | |
| 602 try { | |
| 603 prepare('123\n1234\n1234|5\n\nHi'); | |
| 604 editable.moveCursorToPreviousLine(); | |
| 605 expect('123\n1234|\n12345\n\nHi'); | |
| 606 editable.moveCursorToPreviousLine(); | |
| 607 expect('123|\n1234\n12345\n\nHi'); | |
| 608 editable.moveCursorToNextLine(); | |
| 609 expect('123\n123|4\n12345\n\nHi'); | |
| 610 editable.moveCursorToNextLine(); | |
| 611 expect('123\n1234\n123|45\n\nHi'); | |
| 612 editable.moveCursorToNextLine(); | |
| 613 expect('123\n1234\n12345\n|\nHi'); | |
| 614 editable.moveCursorToNextLine(); | |
| 615 expect('123\n1234\n12345\n\n|Hi'); | |
| 616 editable.moveCursorToNextLine(); | |
| 617 expect('123\n1234\n12345\n\nHi|'); | |
| 618 | |
| 619 prepare('foo|bar'); | |
| 620 editable.moveCursorToPreviousLine(); | |
| 621 expect('|foobar'); | |
| 622 editable.moveCursorToPreviousLine(); | |
| 623 expect('|foobar'); | |
| 624 editable.moveCursorToNextLine(); | |
| 625 expect('foobar|'); | |
| 626 editable.moveCursorToNextLine(); | |
| 627 expect('foobar|'); | |
| 628 } finally { | |
| 629 test.tearDown(); | |
| 630 } | |
| 631 }); | |
| 632 | |
| 633 /** Tests that paragraph navigation works. */ | |
| 634 TEST_F('CvoxEditableTextUnitTest', 'CursorMovementByParagraph', function() { | |
| 635 var test = this.setUpForCursorTest_('textarea'); | |
| 636 var editable = test.editable, prepare = test.prepare, expect = test.expect; | |
| 637 try { | |
| 638 prepare('Para|graph 1\nParagraph 2\nParagraph 3'); | |
| 639 editable.moveCursorToNextParagraph(); | |
| 640 expect('Paragraph 1\n|Paragraph 2\nParagraph 3'); | |
| 641 editable.moveCursorToNextParagraph(); | |
| 642 expect('Paragraph 1\nParagraph 2\n|Paragraph 3'); | |
| 643 editable.moveCursorToNextParagraph(); | |
| 644 expect('Paragraph 1\nParagraph 2\nParagraph 3|'); | |
| 645 editable.moveCursorToPreviousParagraph(); | |
| 646 expect('Paragraph 1\nParagraph 2\n|Paragraph 3'); | |
| 647 editable.moveCursorToPreviousParagraph(); | |
| 648 expect('Paragraph 1\n|Paragraph 2\nParagraph 3'); | |
| 649 editable.moveCursorToPreviousParagraph(); | |
| 650 expect('|Paragraph 1\nParagraph 2\nParagraph 3'); | |
| 651 } finally { | |
| 652 test.tearDown(); | |
| 653 } | |
| 654 }); | |
| 655 | |
| 656 /** Tests normalization of TextChangeEvent's */ | |
| 657 TEST_F('CvoxEditableTextUnitTest', 'TextChangeEvent', function() { | |
| 658 var event1 = new cvox.TextChangeEvent('foo', 0, 1, true); | |
| 659 var event2 = new cvox.TextChangeEvent('foo', 1, 0, true); | |
| 660 var event3 = new cvox.TextChangeEvent('foo', 1, 1, true); | |
| 661 | |
| 662 assertEquals(0, event1.start); | |
| 663 assertEquals(1, event1.end); | |
| 664 | |
| 665 assertEquals(0, event2.start); | |
| 666 assertEquals(1, event2.end); | |
| 667 | |
| 668 assertEquals(1, event3.start); | |
| 669 assertEquals(1, event3.end); | |
| 670 }); | |
| OLD | NEW |