blob: 60ea8adee3082d84522716fbb5d59614de5ab5d0 [file] [log] [blame]
Simon Hunt420691a2014-12-16 20:16:28 -08001/*
Simon Hunt8ead3a22015-01-06 11:00:15 -08002 * Copyright 2014,2015 Open Networking Laboratory
Simon Hunt420691a2014-12-16 20:16:28 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 ONOS GUI -- Key Handler Service - Unit Tests
Simon Hunt420691a2014-12-16 20:16:28 -080019 */
Yuta HIGUCHI4f39bcd2014-12-18 20:46:14 -080020describe('factory: fw/util/keys.js', function() {
Simon Huntdc6362a2014-12-18 19:55:23 -080021 var $log, ks, fs,
Simon Hunt7aeffa02014-12-18 14:58:26 -080022 d3Elem, elem, last;
Simon Huntdc6362a2014-12-18 19:55:23 -080023
Simon Hunt420691a2014-12-16 20:16:28 -080024
Simon Huntdc6362a2014-12-18 19:55:23 -080025 beforeEach(module('onosUtil'));
Simon Hunt420691a2014-12-16 20:16:28 -080026
Simon Huntdc6362a2014-12-18 19:55:23 -080027 beforeEach(inject(function (_$log_, KeyService, FnService) {
Simon Hunt7aeffa02014-12-18 14:58:26 -080028 $log = _$log_;
Simon Hunt420691a2014-12-16 20:16:28 -080029 ks = KeyService;
30 fs = FnService;
31 d3Elem = d3.select('body').append('p').attr('id', 'ptest');
Simon Hunt59df0b22014-12-17 10:32:25 -080032 elem = d3Elem.node();
Simon Hunt420691a2014-12-16 20:16:28 -080033 ks.installOn(d3Elem);
Simon Hunt59df0b22014-12-17 10:32:25 -080034 last = {
35 view: null,
36 key: null,
37 code: null,
38 ev: null
39 };
Simon Hunt420691a2014-12-16 20:16:28 -080040 }));
41
42 afterEach(function () {
43 d3.select('#ptest').remove();
44 });
45
Simon Huntdc6362a2014-12-18 19:55:23 -080046 // Code to emulate key presses....
Simon Hunt420691a2014-12-16 20:16:28 -080047 // NOTE: kinda messy, but it seems to get the job done.
48 function jsKeyDown(element, code) {
49 var ev = document.createEvent('KeyboardEvent');
50
51 // Chromium Hack
52 if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
53 Object.defineProperty(ev, 'keyCode', {
54 get: function () { return this.keyCodeVal; }
55 });
56 Object.defineProperty(ev, 'which', {
57 get: function () { return this.keyCodeVal; }
58 });
59 }
60
61 if (ev.initKeyboardEvent) {
62 ev.initKeyboardEvent('keydown', true, true, document.defaultView,
63 false, false, false, false, code, code);
64 } else {
65 ev.initKeyEvent('keydown', true, true, document.defaultView,
66 false, false, false, false, code, 0);
67 }
68
69 ev.keyCodeVal = code;
70
71 if (ev.keyCode !== code) {
72 console.warn("keyCode mismatch " + ev.keyCode +
73 "(" + ev.which + ") -> "+ code);
74 }
75 element.dispatchEvent(ev);
76 }
77
Simon Hunt59df0b22014-12-17 10:32:25 -080078 // === Key binding related tests
79 it('should start with default key bindings', function () {
80 var state = ks.keyBindings(),
81 gk = state.globalKeys,
82 mk = state.maskedKeys,
83 vk = state.viewKeys,
84 vf = state.viewFunction;
85
86 expect(gk.length).toEqual(4);
87 ['backSlash', 'slash', 'esc', 'T'].forEach(function (k) {
88 expect(fs.contains(gk, k)).toBeTruthy();
89 });
90
91 expect(mk.length).toEqual(3);
92 ['backSlash', 'slash', 'T'].forEach(function (k) {
93 expect(fs.contains(mk, k)).toBeTruthy();
94 });
95
96 expect(vk.length).toEqual(0);
97 expect(vf).toBeFalsy();
Simon Hunt420691a2014-12-16 20:16:28 -080098 });
Simon Hunt59df0b22014-12-17 10:32:25 -080099
100 function bindTestKeys(withDescs) {
101 var keys = ['A', '1', 'F5', 'equals'],
102 kb = {};
103
104 function cb(view, key, code, ev) {
105 last.view = view;
106 last.key = key;
107 last.code = code;
108 last.ev = ev;
109 }
110
111 function bind(k) {
112 return withDescs ? [cb, 'desc for key ' + k] : cb;
113 }
114
115 keys.forEach(function (k) {
116 kb[k] = bind(k);
117 });
118
119 ks.keyBindings(kb);
120 }
121
122 function verifyCall(key, code) {
123 // TODO: update expectation, when view tokens are implemented
124 expect(last.view).toEqual('NotYetAViewToken');
125 last.view = null;
126
127 expect(last.key).toEqual(key);
128 last.key = null;
129
130 expect(last.code).toEqual(code);
131 last.code = null;
132
133 expect(last.ev).toBeTruthy();
134 last.ev = null;
135 }
136
137 function verifyNoCall() {
138 expect(last.view).toBeNull();
139 expect(last.key).toBeNull();
140 expect(last.code).toBeNull();
141 expect(last.ev).toBeNull();
142 }
143
144 function verifyTestKeys() {
145 jsKeyDown(elem, 65); // 'A'
146 verifyCall('A', 65);
147 jsKeyDown(elem, 66); // 'B'
148 verifyNoCall();
149
150 jsKeyDown(elem, 49); // '1'
151 verifyCall('1', 49);
152 jsKeyDown(elem, 50); // '2'
153 verifyNoCall();
154
155 jsKeyDown(elem, 116); // 'F5'
156 verifyCall('F5', 116);
157 jsKeyDown(elem, 117); // 'F6'
158 verifyNoCall();
159
160 jsKeyDown(elem, 187); // 'equals'
161 verifyCall('equals', 187);
162 jsKeyDown(elem, 189); // 'dash'
163 verifyNoCall();
164
165 var vk = ks.keyBindings().viewKeys;
166
167 expect(vk.length).toEqual(4);
168 ['A', '1', 'F5', 'equals'].forEach(function (k) {
169 expect(fs.contains(vk, k)).toBeTruthy();
170 });
171
172 expect(ks.keyBindings().viewFunction).toBeFalsy();
173 }
174
175 it('should allow specific key bindings', function () {
176 bindTestKeys();
177 verifyTestKeys();
Simon Hunt420691a2014-12-16 20:16:28 -0800178 });
Simon Hunt59df0b22014-12-17 10:32:25 -0800179
180 it('should allow specific key bindings with descriptions', function () {
181 bindTestKeys(true);
182 verifyTestKeys();
Simon Hunt420691a2014-12-16 20:16:28 -0800183 });
184
Simon Huntaf322072014-12-18 13:23:40 -0800185 it('should warn about masked keys', function () {
186 var k = {'space': cb, 'T': cb},
187 count = 0;
Simon Hunt7aeffa02014-12-18 14:58:26 -0800188
Simon Huntdc6362a2014-12-18 19:55:23 -0800189 function cb(token, key, code, ev) {
190 count++;
191 //console.debug('count = ' + count, token, key, code);
192 }
Simon Huntaf322072014-12-18 13:23:40 -0800193
Simon Hunt7aeffa02014-12-18 14:58:26 -0800194 spyOn($log, 'warn');
195
Simon Huntaf322072014-12-18 13:23:40 -0800196 ks.keyBindings(k);
197
Simon Hunt7aeffa02014-12-18 14:58:26 -0800198 expect($log.warn).toHaveBeenCalledWith('setKeyBindings(): Key "T" is reserved');
Simon Huntaf322072014-12-18 13:23:40 -0800199
200 // the 'T' key should NOT invoke our callback
201 expect(count).toEqual(0);
202 jsKeyDown(elem, 84); // 'T'
203 expect(count).toEqual(0);
204
205 // but the 'space' key SHOULD invoke our callback
206 jsKeyDown(elem, 32); // 'space'
207 expect(count).toEqual(1);
208 });
209
210 // === Gesture notes related tests
211 it('should start with no notes', function () {
212 expect(ks.gestureNotes()).toEqual([]);
213 });
214
215 it('should allow us to add nodes', function () {
216 var notes = [
217 ['one', 'something about one'],
218 ['two', 'description of two']
219 ];
220 ks.gestureNotes(notes);
221
222 expect(ks.gestureNotes()).toEqual(notes);
223 });
224
225 it('should ignore non-arrays', function () {
226 ks.gestureNotes({foo:4});
227 expect(ks.gestureNotes()).toEqual([]);
228 });
229
230 // Consider adding test to ensure array contains 2-tuples of strings
Simon Hunt420691a2014-12-16 20:16:28 -0800231});