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.
6 * @fileoverview Unit test for the Braille IME.
10 * Mock Chrome event supporting one listener.
13 function MockEvent() {}
15 MockEvent.prototype = {
16 /** @type {Function?} */
20 * @param {Function} listener
22 addListener: function(listener) {
23 assertTrue(this.listener === null);
24 this.listener = listener;
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
33 dispatch: function() {
35 return this.listener.apply(null, arguments);
41 * Mock port that supports the {@code onMessage} and {@code onDisconnect}
42 * events as well as {@code postMessage}.
46 this.onMessage = new MockEvent();
47 this.onDisconnect = new MockEvent();
48 /** @type {Array<Object>} */
52 MockPort.prototype = {
54 * Stores {@code message} in this object.
55 * @param {Object} message Message to store.
57 postMessage: function(message) {
58 this.messages.push(message);
63 * Engine ID as specified in manifest.
66 ENGINE_ID = 'braille';
71 * Test fixture for the braille IME unit test.
73 * @extends {testing.Test}
75 function BrailleImeUnitTest() {
76 testing.Test.call(this);
79 BrailleImeUnitTest.prototype = {
80 __proto__: testing.Test.prototype,
89 chrome = chrome || {};
90 chrome.input = chrome.input || {};
91 chrome.input.ime = chrome.input.ime || {};
92 chrome.runtime = chrome.runtime || {};
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;
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();
112 chrome.input.ime.setMenuItems = function(parameters) {
113 this.menuItems = parameters.items;
115 chrome.runtime.connect = function() {
116 this.port = new MockPort();
119 this.menuItems = null;
121 this.ime = new BrailleIme();
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;
132 sendKeyEvent_: function(type, code, extra) {
133 var event = {type: type,
135 requestId: (++this.lastSentKeyRequestId_) + ''};
136 for (var key in extra) {
137 event[key] = extra[key];
139 this.onKeyEvent.dispatch(ENGINE_ID, event);
140 if (this.lastSentKeyRequestId_ === this.lastHandledKeyRequestId_) {
141 return this.lastHandledKeyResult_;
145 sendKeyDown: function(code, extra) {
146 return this.sendKeyEvent_('keydown', code, extra);
149 sendKeyUp: function(code, extra) {
150 return this.sendKeyEvent_('keyup', code, extra);
154 TEST_F('BrailleImeUnitTest', 'KeysWhenStandardKeyboardDisabled', function() {
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() {
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() {
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_ + '',
231 expectEquals(this.lastSentKeyRequestId_, this.lastHandledKeyRequestId_);
232 expectTrue(this.lastHandledKeyResult_);
235 TEST_F('BrailleImeUnitTest', 'UseStandardKeyboardSettingPreserved', function() {
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.
243 assertTrue(this.menuItems[0].checked);
246 TEST_F('BrailleImeUnitTest', 'ReplaceText', function() {
248 var hasSelection = false;
250 chrome.input.ime.commitText = function(params) {
251 assertEquals(CONTEXT_ID, params.contextID);
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);
259 assertEquals(0, params.length);
260 hasSelection = false;
262 text = text.slice(0, params.offset);
266 var sendReplaceText = function(deleteBefore, newText) {
267 this.port.onMessage.dispatch(
268 {type: 'replaceText', contextID: CONTEXT_ID,
269 deleteBefore: deleteBefore, newText: newText});
272 sendReplaceText(0, 'hello!');
273 assertEquals('Hi, hello!', text);
275 sendReplaceText('hello!'.length, 'good bye!');
276 assertFalse(hasSelection);
277 assertEquals('Hi, good bye!', text);
280 TEST_F('BrailleImeUnitTest', 'Uncommitted', function() {
283 chrome.input.ime.commitText = function(params) {
284 assertEquals(CONTEXT_ID, params.contextID);
287 var sendSetUncommitted = function(text) {
288 this.port.onMessage.dispatch(
289 {type: 'setUncommitted', contextID: CONTEXT_ID, text: text});
291 var sendCommitUncommitted = function(contextID) {
292 this.port.onMessage.dispatch(
293 {type: 'commitUncommitted', contextID: contextID});
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);