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 |