Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / resources / chromeos / braille_ime / braille_ime_unittest.gtestjs
bloba0335ab243283d27799c12e10e3b4023d5d795ef
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.
5 /**
6  * @fileoverview Unit test for the Braille IME.
7  */
9 /**
10  * Mock Chrome event supporting one listener.
11  * @constructor
12  */
13 function MockEvent() {}
15 MockEvent.prototype = {
16   /** @type {Function?} */
17   listener: null,
19   /**
20    * @param {Function} listener
21    */
22   addListener: function(listener) {
23     assertTrue(this.listener === null);
24     this.listener = listener;
25   },
27   /**
28    * Dispatches an event to the listener if any.
29    * @param {...*} var_args Arguments to pass to the event listener.
30    * @return {*} Return value from listener or {@code undefined} if no
31    *     listener.
32    */
33   dispatch: function() {
34     if (this.listener) {
35       return this.listener.apply(null, arguments);
36     }
37   }
40 /**
41  * Mock port that supports the {@code onMessage} and {@code onDisconnect}
42  * events as well as {@code postMessage}.
43  * @constructor.
44  */
45 function MockPort() {
46   this.onMessage = new MockEvent();
47   this.onDisconnect = new MockEvent();
48   /** @type {Array<Object>} */
49   this.messages = [];
52 MockPort.prototype = {
53   /**
54    * Stores {@code message} in this object.
55    * @param {Object} message Message to store.
56    */
57   postMessage: function(message) {
58     this.messages.push(message);
59   }
62 /**
63  * Engine ID as specified in manifest.
64  * @const {string}
65  */
66 ENGINE_ID = 'braille';
68 var localStorage;
70 /**
71  * Test fixture for the braille IME unit test.
72  * @constructor
73  * @extends {testing.Test}
74  */
75 function BrailleImeUnitTest() {
76   testing.Test.call(this);
79 BrailleImeUnitTest.prototype = {
80   __proto__: testing.Test.prototype,
82   /** @Override */
83   extraLibraries: [
84     'braille_ime.js'
85   ],
87   /** @Override */
88   setUp: function() {
89     chrome = chrome || {};
90     chrome.input = chrome.input || {};
91     chrome.input.ime = chrome.input.ime || {};
92     chrome.runtime = chrome.runtime || {};
93     localStorage = {};
94     this.lastSentKeyRequestId_ = 0;
95     this.lastHandledKeyRequestId_ = undefined;
96     this.lastHandledKeyResult_ = undefined;
97     chrome.input.ime.keyEventHandled = function(requestId, result) {
98       this.lastHandledKeyRequestId_ = Number(requestId);
99       this.lastHandledKeyResult_ = result;
100     }.bind(this);
101     this.createIme();
102   },
104   createIme: function() {
105     var IME_EVENTS = [ 'onActivate', 'onDeactivated', 'onFocus', 'onBlur',
106                        'onInputContextUpdate', 'onKeyEvent', 'onReset',
107                        'onMenuItemActivated' ];
108     for (var i = 0, name; name = IME_EVENTS[i]; ++i) {
109       this[name] = chrome.input.ime[name] = new MockEvent();
111     }
112     chrome.input.ime.setMenuItems = function(parameters) {
113       this.menuItems = parameters.items;
114     }.bind(this);
115     chrome.runtime.connect = function() {
116       this.port = new MockPort();
117       return this.port;
118     }.bind(this);
119     this.menuItems = null;
120     this.port = null;
121     this.ime = new BrailleIme();
122     this.ime.init();
123   },
125   activateIme: function() {
126     this.onActivate.dispatch(ENGINE_ID);
127     assertThat(this.port.messages,
128                eqJSON([{type: 'activeState', active: true}]));
129     this.port.messages.length = 0;
130   },
132   sendKeyEvent_: function(type, code, extra) {
133     var event = {type: type,
134                  code: code,
135                  requestId: (++this.lastSentKeyRequestId_) + ''};
136     for (var key in extra) {
137       event[key] = extra[key];
138     }
139     this.onKeyEvent.dispatch(ENGINE_ID, event);
140     if (this.lastSentKeyRequestId_ === this.lastHandledKeyRequestId_) {
141       return this.lastHandledKeyResult_;
142     }
143   },
145   sendKeyDown: function(code, extra) {
146     return this.sendKeyEvent_('keydown', code, extra);
147   },
149   sendKeyUp: function(code, extra) {
150     return this.sendKeyEvent_('keyup', code, extra);
151   },
154 TEST_F('BrailleImeUnitTest', 'KeysWhenStandardKeyboardDisabled', function() {
155   this.activateIme();
156   expectFalse(this.sendKeyDown('KeyF'));
157   expectFalse(this.sendKeyDown('KeyD'));
158   expectFalse(this.sendKeyUp('KeyD'));
159   expectFalse(this.sendKeyUp('KeyF'));
160   expectEquals(0, this.port.messages.length);
163 TEST_F('BrailleImeUnitTest', 'KeysWhenStandardKeysEnabled', function() {
164   this.activateIme();
165   assertFalse(this.menuItems[0].checked);
166   this.onMenuItemActivated.dispatch(ENGINE_ID, this.menuItems[0].id);
167   assertTrue(this.menuItems[0].checked);
168   // Type the letters 'b' and 'c' and verify the right dots get sent.
169   expectTrue(this.sendKeyDown('KeyF'));
170   expectTrue(this.sendKeyDown('KeyD'));
171   expectTrue(this.sendKeyUp('KeyD'));
172   expectTrue(this.sendKeyUp('KeyF'));
173   expectTrue(this.sendKeyDown('KeyJ'));
174   expectTrue(this.sendKeyDown('KeyF'));
175   expectTrue(this.sendKeyUp('KeyJ'));
176   expectTrue(this.sendKeyUp('KeyF'));
178   // Make sure that other keys are not handled, either by themselves or while
179   // one of the 'braille keys' is pressed.
180   expectFalse(this.sendKeyDown('KeyX'));
181   expectFalse(this.sendKeyUp('KeyX'));
183   expectTrue(this.sendKeyDown('KeyS'));  // Dot 3
184   expectFalse(this.sendKeyDown('KeyG'));  // To the right of dot 1.
185   expectTrue(this.sendKeyUp('KeyS'));
186   expectFalse(this.sendKeyUp('KeyG'));
188   // Keys like Ctrl L should not be handled, despite L being a dot key.
189   var ctrlFlag = {ctrlKey: true};
190   expectFalse(this.sendKeyDown('ControlLeft', ctrlFlag));
191   expectFalse(this.sendKeyDown('KeyL', ctrlFlag));
192   expectFalse(this.sendKeyUp('KeyL', ctrlFlag));
193   expectFalse(this.sendKeyUp('ControlLeft', ctrlFlag))
195   // Space key by itself should send a blank cell.
196   expectTrue(this.sendKeyDown('Space'));
197   expectTrue(this.sendKeyUp('Space'));
199   // Space and braille dots results in no event.
200   expectTrue(this.sendKeyDown('Space'));
201   expectTrue(this.sendKeyDown('KeyF'));
202   expectTrue(this.sendKeyUp('Space'));
203   expectTrue(this.sendKeyUp('KeyF'));
204   // Send the braille key first, still no event should be produced.
205   expectTrue(this.sendKeyDown('KeyF'));
206   expectTrue(this.sendKeyDown('Space'));
207   expectTrue(this.sendKeyUp('Space'));
208   expectTrue(this.sendKeyUp('KeyF'));
210   assertThat(this.port.messages,
211              eqJSON([{type: 'brailleDots', dots: 0x03},
212                      {type: 'brailleDots', dots: 0x09},
213                      {type: 'brailleDots', dots: 0}]));
216 TEST_F('BrailleImeUnitTest', 'TestBackspaceKey', function() {
217   this.activateIme();
218   // Enable standard keyboard feature.
219   assertFalse(this.menuItems[0].checked);
220   this.onMenuItemActivated.dispatch(ENGINE_ID, this.menuItems[0].id);
221   assertTrue(this.menuItems[0].checked);
223   expectEquals(undefined, this.sendKeyDown('Backspace'));
224   assertThat(this.port.messages,
225              eqJSON([{type: 'backspace',
226                       requestId: this.lastSentKeyRequestId_ + ''}]));
227   this.port.onMessage.dispatch(
228       {type: 'keyEventHandled',
229        requestId: this.lastSentKeyRequestId_ + '',
230        result: true});
231   expectEquals(this.lastSentKeyRequestId_, this.lastHandledKeyRequestId_);
232   expectTrue(this.lastHandledKeyResult_);
235 TEST_F('BrailleImeUnitTest', 'UseStandardKeyboardSettingPreserved', function() {
236   this.activateIme();
237   assertFalse(this.menuItems[0].checked);
238   this.onMenuItemActivated.dispatch(ENGINE_ID, this.menuItems[0].id);
239   assertTrue(this.menuItems[0].checked);
240   // Create a new instance and make sure the setting is still turned on.
241   this.createIme();
242   this.activateIme();
243   assertTrue(this.menuItems[0].checked);
246 TEST_F('BrailleImeUnitTest', 'ReplaceText', function() {
247   var CONTEXT_ID = 1;
248   var hasSelection = false;
249   var text = 'Hi, ';
250   chrome.input.ime.commitText = function(params) {
251     assertEquals(CONTEXT_ID, params.contextID);
252     text += params.text;
253   };
254   chrome.input.ime.deleteSurroundingText = function(params, callback) {
255     assertEquals(ENGINE_ID, params.engineID);
256     assertEquals(CONTEXT_ID, params.contextID);
257     assertEquals(0, params.offset + params.length);
258     if (hasSelection) {
259       assertEquals(0, params.length);
260       hasSelection = false;
261     } else {
262       text = text.slice(0, params.offset);
263     }
264     callback();
265   };
266   var sendReplaceText = function(deleteBefore, newText) {
267     this.port.onMessage.dispatch(
268         {type: 'replaceText', contextID: CONTEXT_ID,
269        deleteBefore: deleteBefore, newText: newText});
270   }.bind(this);
271   this.activateIme();
272   sendReplaceText(0, 'hello!');
273   assertEquals('Hi, hello!', text);
274   hasSelection = true;
275   sendReplaceText('hello!'.length, 'good bye!');
276   assertFalse(hasSelection);
277   assertEquals('Hi, good bye!', text);
280 TEST_F('BrailleImeUnitTest', 'Uncommitted', function() {
281   var CONTEXT_ID = 1;
282   var text = '';
283   chrome.input.ime.commitText = function(params) {
284     assertEquals(CONTEXT_ID, params.contextID);
285     text += params.text;
286   };
287   var sendSetUncommitted = function(text) {
288     this.port.onMessage.dispatch(
289         {type: 'setUncommitted', contextID: CONTEXT_ID, text: text});
290   }.bind(this);
291   var sendCommitUncommitted = function(contextID) {
292     this.port.onMessage.dispatch(
293         {type: 'commitUncommitted', contextID: contextID});
294   }.bind(this);
296   this.activateIme();
297   sendSetUncommitted('Hi');
298   assertEquals('', text);
299   sendSetUncommitted('Hello');
300   sendCommitUncommitted(CONTEXT_ID);
301   assertEquals('Hello', text);
302   sendSetUncommitted(' there!');
303   sendCommitUncommitted(CONTEXT_ID + 1);
304   assertEquals('Hello', text);
306   sendSetUncommitted(' you!');
307   assertFalse(this.sendKeyDown('KeyY'));
308   assertEquals('Hello you!', text);
309   assertFalse(this.sendKeyUp('KeyY'));
310   assertEquals('Hello you!', text);