blob: a297bf90f1d153d64a0ddd6d7d6428a1f5cfc987 [file] [log] [blame]
Simon Hunt420691a2014-12-16 20:16:28 -08001/*
2 * Copyright 2014 Open Networking Laboratory
3 *
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
19
20 @author Simon Hunt
21 */
Yuta HIGUCHI4f39bcd2014-12-18 20:46:14 -080022describe('factory: fw/util/keys.js', function() {
Simon Huntdc6362a2014-12-18 19:55:23 -080023 var $log, ks, fs,
Simon Hunt7aeffa02014-12-18 14:58:26 -080024 d3Elem, elem, last;
Simon Huntdc6362a2014-12-18 19:55:23 -080025
Simon Hunt420691a2014-12-16 20:16:28 -080026
Simon Huntdc6362a2014-12-18 19:55:23 -080027 beforeEach(module('onosUtil'));
Simon Hunt420691a2014-12-16 20:16:28 -080028
Simon Huntdc6362a2014-12-18 19:55:23 -080029 beforeEach(inject(function (_$log_, KeyService, FnService) {
Simon Hunt7aeffa02014-12-18 14:58:26 -080030 $log = _$log_;
Simon Hunt420691a2014-12-16 20:16:28 -080031 ks = KeyService;
32 fs = FnService;
33 d3Elem = d3.select('body').append('p').attr('id', 'ptest');
Simon Hunt59df0b22014-12-17 10:32:25 -080034 elem = d3Elem.node();
Simon Hunt420691a2014-12-16 20:16:28 -080035 ks.installOn(d3Elem);
Simon Hunt59df0b22014-12-17 10:32:25 -080036 last = {
37 view: null,
38 key: null,
39 code: null,
40 ev: null
41 };
Simon Hunt420691a2014-12-16 20:16:28 -080042 }));
43
44 afterEach(function () {
45 d3.select('#ptest').remove();
46 });
47
Simon Huntdc6362a2014-12-18 19:55:23 -080048 // Code to emulate key presses....
Simon Hunt420691a2014-12-16 20:16:28 -080049 // NOTE: kinda messy, but it seems to get the job done.
50 function jsKeyDown(element, code) {
51 var ev = document.createEvent('KeyboardEvent');
52
53 // Chromium Hack
54 if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
55 Object.defineProperty(ev, 'keyCode', {
56 get: function () { return this.keyCodeVal; }
57 });
58 Object.defineProperty(ev, 'which', {
59 get: function () { return this.keyCodeVal; }
60 });
61 }
62
63 if (ev.initKeyboardEvent) {
64 ev.initKeyboardEvent('keydown', true, true, document.defaultView,
65 false, false, false, false, code, code);
66 } else {
67 ev.initKeyEvent('keydown', true, true, document.defaultView,
68 false, false, false, false, code, 0);
69 }
70
71 ev.keyCodeVal = code;
72
73 if (ev.keyCode !== code) {
74 console.warn("keyCode mismatch " + ev.keyCode +
75 "(" + ev.which + ") -> "+ code);
76 }
77 element.dispatchEvent(ev);
78 }
79
Simon Hunt59df0b22014-12-17 10:32:25 -080080 // === Key binding related tests
81 it('should start with default key bindings', function () {
82 var state = ks.keyBindings(),
83 gk = state.globalKeys,
84 mk = state.maskedKeys,
85 vk = state.viewKeys,
86 vf = state.viewFunction;
87
88 expect(gk.length).toEqual(4);
89 ['backSlash', 'slash', 'esc', 'T'].forEach(function (k) {
90 expect(fs.contains(gk, k)).toBeTruthy();
91 });
92
93 expect(mk.length).toEqual(3);
94 ['backSlash', 'slash', 'T'].forEach(function (k) {
95 expect(fs.contains(mk, k)).toBeTruthy();
96 });
97
98 expect(vk.length).toEqual(0);
99 expect(vf).toBeFalsy();
Simon Hunt420691a2014-12-16 20:16:28 -0800100 });
Simon Hunt59df0b22014-12-17 10:32:25 -0800101
102 function bindTestKeys(withDescs) {
103 var keys = ['A', '1', 'F5', 'equals'],
104 kb = {};
105
106 function cb(view, key, code, ev) {
107 last.view = view;
108 last.key = key;
109 last.code = code;
110 last.ev = ev;
111 }
112
113 function bind(k) {
114 return withDescs ? [cb, 'desc for key ' + k] : cb;
115 }
116
117 keys.forEach(function (k) {
118 kb[k] = bind(k);
119 });
120
121 ks.keyBindings(kb);
122 }
123
124 function verifyCall(key, code) {
125 // TODO: update expectation, when view tokens are implemented
126 expect(last.view).toEqual('NotYetAViewToken');
127 last.view = null;
128
129 expect(last.key).toEqual(key);
130 last.key = null;
131
132 expect(last.code).toEqual(code);
133 last.code = null;
134
135 expect(last.ev).toBeTruthy();
136 last.ev = null;
137 }
138
139 function verifyNoCall() {
140 expect(last.view).toBeNull();
141 expect(last.key).toBeNull();
142 expect(last.code).toBeNull();
143 expect(last.ev).toBeNull();
144 }
145
146 function verifyTestKeys() {
147 jsKeyDown(elem, 65); // 'A'
148 verifyCall('A', 65);
149 jsKeyDown(elem, 66); // 'B'
150 verifyNoCall();
151
152 jsKeyDown(elem, 49); // '1'
153 verifyCall('1', 49);
154 jsKeyDown(elem, 50); // '2'
155 verifyNoCall();
156
157 jsKeyDown(elem, 116); // 'F5'
158 verifyCall('F5', 116);
159 jsKeyDown(elem, 117); // 'F6'
160 verifyNoCall();
161
162 jsKeyDown(elem, 187); // 'equals'
163 verifyCall('equals', 187);
164 jsKeyDown(elem, 189); // 'dash'
165 verifyNoCall();
166
167 var vk = ks.keyBindings().viewKeys;
168
169 expect(vk.length).toEqual(4);
170 ['A', '1', 'F5', 'equals'].forEach(function (k) {
171 expect(fs.contains(vk, k)).toBeTruthy();
172 });
173
174 expect(ks.keyBindings().viewFunction).toBeFalsy();
175 }
176
177 it('should allow specific key bindings', function () {
178 bindTestKeys();
179 verifyTestKeys();
Simon Hunt420691a2014-12-16 20:16:28 -0800180 });
Simon Hunt59df0b22014-12-17 10:32:25 -0800181
182 it('should allow specific key bindings with descriptions', function () {
183 bindTestKeys(true);
184 verifyTestKeys();
Simon Hunt420691a2014-12-16 20:16:28 -0800185 });
186
Simon Huntaf322072014-12-18 13:23:40 -0800187 it('should warn about masked keys', function () {
188 var k = {'space': cb, 'T': cb},
189 count = 0;
Simon Hunt7aeffa02014-12-18 14:58:26 -0800190
Simon Huntdc6362a2014-12-18 19:55:23 -0800191 function cb(token, key, code, ev) {
192 count++;
193 //console.debug('count = ' + count, token, key, code);
194 }
Simon Huntaf322072014-12-18 13:23:40 -0800195
Simon Hunt7aeffa02014-12-18 14:58:26 -0800196 spyOn($log, 'warn');
197
Simon Huntaf322072014-12-18 13:23:40 -0800198 ks.keyBindings(k);
199
Simon Hunt7aeffa02014-12-18 14:58:26 -0800200 expect($log.warn).toHaveBeenCalledWith('setKeyBindings(): Key "T" is reserved');
Simon Huntaf322072014-12-18 13:23:40 -0800201
202 // the 'T' key should NOT invoke our callback
203 expect(count).toEqual(0);
204 jsKeyDown(elem, 84); // 'T'
205 expect(count).toEqual(0);
206
207 // but the 'space' key SHOULD invoke our callback
208 jsKeyDown(elem, 32); // 'space'
209 expect(count).toEqual(1);
210 });
211
212 // === Gesture notes related tests
213 it('should start with no notes', function () {
214 expect(ks.gestureNotes()).toEqual([]);
215 });
216
217 it('should allow us to add nodes', function () {
218 var notes = [
219 ['one', 'something about one'],
220 ['two', 'description of two']
221 ];
222 ks.gestureNotes(notes);
223
224 expect(ks.gestureNotes()).toEqual(notes);
225 });
226
227 it('should ignore non-arrays', function () {
228 ks.gestureNotes({foo:4});
229 expect(ks.gestureNotes()).toEqual([]);
230 });
231
232 // Consider adding test to ensure array contains 2-tuples of strings
Simon Hunt420691a2014-12-16 20:16:28 -0800233});