Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: chrome/browser/resources/chromeos/chromevox/braille/braille_input_handler_test.unitjs

Issue 1039703002: Make contracted braille input work in more contexts. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@docs2
Patch Set: Rebase Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Include test fixture. 5 // Include test fixture.
6 GEN_INCLUDE(['../testing/chromevox_unittest_base.js']); 6 GEN_INCLUDE(['../testing/chromevox_unittest_base.js']);
7 7
8 GEN_INCLUDE(['../testing/fake_objects.js']); 8 GEN_INCLUDE(['../testing/fake_objects.js']);
9 9
10 // Fake out the Chrome API namespace we depend on. 10 // Fake out the Chrome API namespace we depend on.
(...skipping 20 matching lines...) Expand all
31 /** @private {string} */ 31 /** @private {string} */
32 this.text_ = ''; 32 this.text_ = '';
33 /** @private {number} */ 33 /** @private {number} */
34 this.selectionStart_ = 0; 34 this.selectionStart_ = 0;
35 /** @private {number} */ 35 /** @private {number} */
36 this.selectionEnd_ = 0; 36 this.selectionEnd_ = 0;
37 /** @private {number} */ 37 /** @private {number} */
38 this.contextID_ = 0; 38 this.contextID_ = 0;
39 /** @private {boolean} */ 39 /** @private {boolean} */
40 this.allowDeletes_ = false; 40 this.allowDeletes_ = false;
41 /** @private {string} */
42 this.uncommittedText_ = '';
43 /** @private {?Array<number>} */
44 this.extraCells_ = [];
41 port.postMessage = goog.bind(this.handleMessage_, this); 45 port.postMessage = goog.bind(this.handleMessage_, this);
42 } 46 }
43 47
44 48
45 /** 49 /**
46 * Sets the content and selection (or cursor) of the edit field. 50 * Sets the content and selection (or cursor) of the edit field.
47 * This fakes what happens when the field is edited by other means than 51 * This fakes what happens when the field is edited by other means than
48 * via the braille keyboard. 52 * via the braille keyboard.
49 * @param {string} text Text to replace the current content of the field. 53 * @param {string} text Text to replace the current content of the field.
50 * @param {number} selectionStart Start of the selection or cursor position. 54 * @param {number} selectionStart Start of the selection or cursor position.
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 text, selectionStart, opt_selectionEnd) { 131 text, selectionStart, opt_selectionEnd) {
128 var selectionEnd = goog.isDef(opt_selectionEnd) ? opt_selectionEnd : 132 var selectionEnd = goog.isDef(opt_selectionEnd) ? opt_selectionEnd :
129 selectionStart; 133 selectionStart;
130 assertEquals(text, this.text_); 134 assertEquals(text, this.text_);
131 assertEquals(selectionStart, this.selectionStart_); 135 assertEquals(selectionStart, this.selectionStart_);
132 assertEquals(selectionEnd, this.selectionEnd_); 136 assertEquals(selectionEnd, this.selectionEnd_);
133 }; 137 };
134 138
135 139
136 /** 140 /**
141 * Asserts that the uncommitted text last sent to the IME is the given text.
142 * @param {string} text
143 */
144 FakeEditor.prototype.assertUncommittedTextIs = function(text) {
145 assertEquals(text, this.uncommittedText_);
146 };
147
148
149 /**
150 * Asserts that the input handler has added 'extra cells' for uncommitted
151 * text into the braille content.
152 * @param {string} cells Cells as a space-separated list of numbers.
153 */
154 FakeEditor.prototype.assertExtraCellsAre = function(cells) {
155 assertEqualsJSON(cellsToArray(cells), this.extraCells_);
156 };
157
158
159 /**
137 * Sends a message from the IME to the input handler. 160 * Sends a message from the IME to the input handler.
138 * @param {Object} msg The message to send. 161 * @param {Object} msg The message to send.
139 * @private 162 * @private
140 */ 163 */
141 FakeEditor.prototype.message_ = function(msg) { 164 FakeEditor.prototype.message_ = function(msg) {
142 var listener = this.port_.onMessage.getListener(); 165 var listener = this.port_.onMessage.getListener();
143 assertNotEquals(null, listener); 166 assertNotEquals(null, listener);
144 listener(msg); 167 listener(msg);
145 }; 168 };
146 169
147 170
148 /** 171 /**
149 * Calls the {@code onDisplayContentChanged} method of the input handler 172 * Calls the {@code onDisplayContentChanged} method of the input handler
150 * with the current editor content and selection. 173 * with the current editor content and selection.
151 * @private 174 * @private
152 */ 175 */
153 FakeEditor.prototype.callOnDisplayContentChanged_ = function() { 176 FakeEditor.prototype.callOnDisplayContentChanged_ = function() {
154 this.inputHandler_.onDisplayContentChanged( 177 var content = cvox.BrailleUtil.createValue(
155 cvox.BrailleUtil.createValue( 178 this.text_, this.selectionStart_, this.selectionEnd_)
156 this.text_, this.selectionStart_, this.selectionEnd_)); 179 var grabExtraCells = function() {
180 var span = content.getSpanInstanceOf(cvox.ExtraCellsSpan);
181 assertNotEquals(null, span);
182 // Convert the ArrayBuffer to a normal array for easier comparision.
183 this.extraCells_ = Array.prototype.map.call(new Uint8Array(span.cells),
184 function(a) {return a;});
185 }.bind(this);
186 this.inputHandler_.onDisplayContentChanged(content, grabExtraCells);
187 grabExtraCells();
157 }; 188 };
158 189
159 190
160 /** 191 /**
161 * Informs the input handler that a new text field is focused. The content 192 * Informs the input handler that a new text field is focused. The content
162 * of the field is not cleared and should be updated separately. 193 * of the field is not cleared and should be updated separately.
163 * @param {string} fieldType The type of the field (see the documentation 194 * @param {string} fieldType The type of the field (see the documentation
164 * for the {@code chrome.input.ime} API). 195 * for the {@code chrome.input.ime} API).
165 */ 196 */
166 FakeEditor.prototype.focus = function(fieldType) { 197 FakeEditor.prototype.focus = function(fieldType) {
(...skipping 12 matching lines...) Expand all
179 this.contextID_ = 0; 210 this.contextID_ = 0;
180 }; 211 };
181 212
182 213
183 /** 214 /**
184 * Handles a message from the input handler to the IME. 215 * Handles a message from the input handler to the IME.
185 * @param {Object} msg The message. 216 * @param {Object} msg The message.
186 * @private 217 * @private
187 */ 218 */
188 FakeEditor.prototype.handleMessage_ = function(msg) { 219 FakeEditor.prototype.handleMessage_ = function(msg) {
189 assertEquals('replaceText', msg.type);
190 assertEquals(this.contextID_, msg.contextID); 220 assertEquals(this.contextID_, msg.contextID);
191 var deleteBefore = msg.deleteBefore; 221 switch(msg.type) {
192 var newText = msg.newText; 222 case 'replaceText':
193 assertTrue(goog.isNumber(deleteBefore)); 223 var deleteBefore = msg.deleteBefore;
194 assertTrue(goog.isString(newText)); 224 var newText = msg.newText;
195 assertTrue(deleteBefore <= this.selectionStart_); 225 assertTrue(goog.isNumber(deleteBefore));
196 if (deleteBefore > 0) { 226 assertTrue(goog.isString(newText));
197 assertTrue(this.allowDeletes_); 227 assertTrue(deleteBefore <= this.selectionStart_);
198 this.text_ = 228 if (deleteBefore > 0) {
199 this.text_.substring(0, this.selectionStart_ - deleteBefore) + 229 assertTrue(this.allowDeletes_);
200 this.text_.substring(this.selectionEnd_); 230 this.text_ =
201 this.selectionStart_ -= deleteBefore; 231 this.text_.substring(0, this.selectionStart_ - deleteBefore) +
202 this.selectionEnd_ = this.selectionStart_; 232 this.text_.substring(this.selectionEnd_);
203 this.callOnDisplayContentChanged_(); 233 this.selectionStart_ -= deleteBefore;
234 this.selectionEnd_ = this.selectionStart_;
235 this.callOnDisplayContentChanged_();
236 }
237 this.insert(newText);
238 break;
239 case 'setUncommitted':
240 assertTrue(goog.isString(msg.text));
241 this.uncommittedText_ = msg.text;
242 break;
243 case 'commitUncommitted':
244 this.insert(this.uncommittedText_);
245 this.uncommittedText_ = '';
246 break;
247 default:
248 throw new Error('Unexpected message to IME: ' + JSON.stringify(msg));
204 } 249 }
205 this.insert(newText);
206 }; 250 };
207 251
208 /* 252 /*
209 * Fakes a {@code Port} used for message passing in the Chrome extension APIs. 253 * Fakes a {@code Port} used for message passing in the Chrome extension APIs.
210 * @constructor 254 * @constructor
211 */ 255 */
212 function FakePort() { 256 function FakePort() {
213 /** @type {FakeChromeEvent} */ 257 /** @type {FakeChromeEvent} */
214 this.onDisconnect = new FakeChromeEvent(); 258 this.onDisconnect = new FakeChromeEvent();
215 /** @type {FakeChromeEvent} */ 259 /** @type {FakeChromeEvent} */
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 /** 399 /**
356 * Converts a list of cells, represented as a string, to an array. 400 * Converts a list of cells, represented as a string, to an array.
357 * @param {string} cells A string with space separated groups of digits. 401 * @param {string} cells A string with space separated groups of digits.
358 * Each group corresponds to one braille cell and each digit in a group 402 * Each group corresponds to one braille cell and each digit in a group
359 * corresponds to a particular dot in the cell (1 to 8). As a special 403 * corresponds to a particular dot in the cell (1 to 8). As a special
360 * case, the digit 0 by itself represents a blank cell. 404 * case, the digit 0 by itself represents a blank cell.
361 * @return {Array.<number>} An array with each cell encoded as a bit 405 * @return {Array.<number>} An array with each cell encoded as a bit
362 * pattern (dot 1 uses bit 0, etc). 406 * pattern (dot 1 uses bit 0, etc).
363 */ 407 */
364 function cellsToArray(cells) { 408 function cellsToArray(cells) {
409 if (!cells)
410 return [];
365 return cells.split(/\s+/).map(function(cellString) { 411 return cells.split(/\s+/).map(function(cellString) {
366 var cell = 0; 412 var cell = 0;
367 assertTrue(cellString.length > 0); 413 assertTrue(cellString.length > 0);
368 if (cellString != '0') { 414 if (cellString != '0') {
369 for (var i = 0; i < cellString.length; ++i) { 415 for (var i = 0; i < cellString.length; ++i) {
370 var dot = cellString.charCodeAt(i) - '0'.charCodeAt(0); 416 var dot = cellString.charCodeAt(i) - '0'.charCodeAt(0);
371 assertTrue(dot >= 1); 417 assertTrue(dot >= 1);
372 assertTrue(dot <= 8); 418 assertTrue(dot <= 8);
373 cell |= 1 << (dot - 1); 419 cell |= 1 << (dot - 1);
374 } 420 }
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 571
526 editor.blur(); 572 editor.blur();
527 editor.setActive(false); 573 editor.setActive(false);
528 }); 574 });
529 575
530 576
531 TEST_F('CvoxBrailleInputHandlerUnitTest', 'InputContracted', function() { 577 TEST_F('CvoxBrailleInputHandlerUnitTest', 'InputContracted', function() {
532 var editor = this.createEditor(); 578 var editor = this.createEditor();
533 this.translatorManager.setTranslators(this.contractedTranslator, 579 this.translatorManager.setTranslators(this.contractedTranslator,
534 this.uncontractedTranslator); 580 this.uncontractedTranslator);
581 editor.setContent('', 0);
535 editor.setActive(true); 582 editor.setActive(true);
536 editor.focus('text'); 583 editor.focus('text');
537 this.assertExpandingSelection(); 584 this.assertExpandingSelection();
538 585
539 // First, type a 'b'. 586 // First, type a 'b'.
540 assertTrue(this.sendCells('12')); 587 assertTrue(this.sendCells('12'));
588 editor.assertContentIs('', 0);
541 // Remember that the contracted translator produces uppercase. 589 // Remember that the contracted translator produces uppercase.
542 editor.assertContentIs('BUT', 'BUT'.length); 590 editor.assertUncommittedTextIs('BUT');
591 editor.assertExtraCellsAre('12');
543 this.assertExpandingNone(); 592 this.assertExpandingNone();
544 593
545 // From here on, the input handler needs to replace already entered text.
546 editor.setAllowDeletes(true);
547 // Typing 'rl' changes to a different contraction. 594 // Typing 'rl' changes to a different contraction.
548 assertTrue(this.sendCells('1235 123')); 595 assertTrue(this.sendCells('1235 123'));
549 editor.assertContentIs('BRAILLE', 'BRAILLE'.length); 596 editor.assertUncommittedTextIs('BRAILLE');
597 editor.assertContentIs('', 0);
598 editor.assertExtraCellsAre('12 1235 123');
599 this.assertExpandingNone();
600
550 // Now, finish the word. 601 // Now, finish the word.
551 assertTrue(this.sendCells('0')); 602 assertTrue(this.sendCells('0'));
552 editor.assertContentIs('BRAILLE ', 'BRAILLE '.length); 603 editor.assertContentIs('BRAILLE ', 'BRAILLE '.length);
553 this.assertExpandingNone(); 604 editor.assertUncommittedTextIs('');
605 editor.assertExtraCellsAre('');
606 this.assertExpandingSelection();
554 607
555 // Move the cursor to the beginning. 608 // Move the cursor to the beginning.
556 editor.select(0); 609 editor.select(0);
557 this.assertExpandingSelection(); 610 this.assertExpandingSelection();
558 611
559 // Typing now uses the uncontracted table. 612 // Typing now uses the uncontracted table.
560 assertTrue(this.sendCells('12')); // 'b' 613 assertTrue(this.sendCells('12')); // 'b'
561 editor.assertContentIs('bBRAILLE ', 1); 614 editor.assertContentIs('bBRAILLE ', 1);
562 this.assertExpandingSelection(); 615 this.assertExpandingSelection();
563 editor.select('bBRAILLE'.length); 616 editor.select('bBRAILLE'.length);
564 this.assertExpandingSelection(); 617 this.assertExpandingSelection();
565 assertTrue(this.sendCells('12')); // 'b' 618 assertTrue(this.sendCells('12')); // 'b'
566 editor.assertContentIs('bBRAILLEb ', 'bBRAILLEb'.length); 619 editor.assertContentIs('bBRAILLEb ', 'bBRAILLEb'.length);
567 // Move to the end, where contracted typing should work. 620 // Move to the end, where contracted typing should work.
568 editor.select('bBRAILLEb '.length); 621 editor.select('bBRAILLEb '.length);
569 assertTrue(this.sendCells('1456 0')); // Symbol for 'this', then space. 622 assertTrue(this.sendCells('1456 0')); // Symbol for 'this', then space.
570 this.assertExpandingNone(); 623 this.assertExpandingSelection();
571 editor.assertContentIs('bBRAILLEb THIS ', 'bBRAILLEb this '.length); 624 editor.assertContentIs('bBRAILLEb THIS ', 'bBRAILLEb THIS '.length);
572 625
573 // Move between the two words. 626 // Move to between the two words.
574 editor.select('bBRAILLEb'.length); 627 editor.select('bBRAILLEb'.length);
575 this.assertExpandingSelection(); 628 this.assertExpandingSelection();
576 assertTrue(this.sendCells('0')); 629 assertTrue(this.sendCells('0 12')); // Space plus 'b' for 'but'
577 assertTrue(this.sendCells('12')); // 'b' for 'but' 630 editor.assertUncommittedTextIs('BUT');
578 editor.assertContentIs('bBRAILLEb BUT THIS ', 'bBRAILLEb BUT'.length); 631 editor.assertExtraCellsAre('12');
632 editor.assertContentIs('bBRAILLEb THIS ', 'bBRAILLEb '.length);
579 this.assertExpandingNone(); 633 this.assertExpandingNone();
580 }); 634 });
581 635
582 636
583 TEST_F('CvoxBrailleInputHandlerUnitTest', 'TypingUrlWithContracted', 637 TEST_F('CvoxBrailleInputHandlerUnitTest', 'TypingUrlWithContracted',
584 function() { 638 function() {
585 var editor = this.createEditor(); 639 var editor = this.createEditor();
586 this.translatorManager.setTranslators(this.contractedTranslator, 640 this.translatorManager.setTranslators(this.contractedTranslator,
587 this.uncontractedTranslator); 641 this.uncontractedTranslator);
588 editor.setActive(true); 642 editor.setActive(true);
(...skipping 18 matching lines...) Expand all
607 TEST_F('CvoxBrailleInputHandlerUnitTest', 'Backspace', function() { 661 TEST_F('CvoxBrailleInputHandlerUnitTest', 'Backspace', function() {
608 var editor = this.createEditor(); 662 var editor = this.createEditor();
609 this.translatorManager.setTranslators(this.contractedTranslator, 663 this.translatorManager.setTranslators(this.contractedTranslator,
610 this.uncontractedTranslator); 664 this.uncontractedTranslator);
611 editor.setActive(true); 665 editor.setActive(true);
612 editor.focus('text'); 666 editor.focus('text');
613 667
614 // Add some text that we can delete later. 668 // Add some text that we can delete later.
615 editor.setContent('Text ', 'Text '.length); 669 editor.setContent('Text ', 'Text '.length);
616 670
617 // The IME needs to delete text, even when typing.
618 editor.setAllowDeletes(true);
619 // Type 'brl' to make sure replacement works when deleting text. 671 // Type 'brl' to make sure replacement works when deleting text.
620 assertTrue(this.sendCells('12 1235 123')); 672 assertTrue(this.sendCells('12 1235 123'));
621 editor.assertContentIs('Text BRAILLE', 'Text BRAILLE'.length); 673 editor.assertUncommittedTextIs('BRAILLE');
622 674
623 // Delete what we just typed, one cell at a time. 675 // Delete what we just typed, one cell at a time.
624 this.sendKeyEvent('Backspace'); 676 this.sendKeyEvent('Backspace');
625 editor.assertContentIs('Text BR', 'Text BR'.length); 677 editor.assertUncommittedTextIs('BR');
626 this.sendKeyEvent('Backspace'); 678 this.sendKeyEvent('Backspace');
627 editor.assertContentIs('Text BUT', 'Text BUT'.length); 679 editor.assertUncommittedTextIs('BUT');
628 this.sendKeyEvent('Backspace'); 680 this.sendKeyEvent('Backspace');
629 editor.assertContentIs('Text ', 'Text '.length); 681 editor.assertUncommittedTextIs('');
630 682
631 // Now, backspace should be handled as usual, synthetizing key events. 683 // Now, backspace should be handled as usual, synthetizing key events.
632 assertEquals(0, this.keyEvents.length); 684 assertEquals(0, this.keyEvents.length);
633 this.sendKeyEvent('Backspace'); 685 this.sendKeyEvent('Backspace');
634 assertEqualsJSON([{keyCode: 8, keyName: 'Backspace', charValue: 8}], 686 assertEqualsJSON([{keyCode: 8, keyName: 'Backspace', charValue: 8}],
635 this.keyEvents); 687 this.keyEvents);
636 }); 688 });
637 689
638 690
639 TEST_F('CvoxBrailleInputHandlerUnitTest', 'KeysImeNotActive', function() { 691 TEST_F('CvoxBrailleInputHandlerUnitTest', 'KeysImeNotActive', function() {
640 var editor = this.createEditor(); 692 var editor = this.createEditor();
641 this.sendKeyEvent('Enter'); 693 this.sendKeyEvent('Enter');
642 this.sendKeyEvent('ArrowUp'); 694 this.sendKeyEvent('ArrowUp');
643 assertEqualsJSON([{keyCode: 13, keyName: 'Enter', charValue: 0x0A}, 695 assertEqualsJSON([{keyCode: 13, keyName: 'Enter', charValue: 0x0A},
644 {keyCode: 38, keyName: 'ArrowUp', charValue: 0x41}], 696 {keyCode: 38, keyName: 'ArrowUp', charValue: 0x41}],
645 this.keyEvents); 697 this.keyEvents);
646 }); 698 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698