Upstream version 10.38.222.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / resources / chromeos / chromevox / common / editable_text_test.unitjs
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 });