aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/web/gui/src/main/webapp/tests/app/fw/util/keys-spec.js
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/web/gui/src/main/webapp/tests/app/fw/util/keys-spec.js')
-rw-r--r--framework/src/onos/web/gui/src/main/webapp/tests/app/fw/util/keys-spec.js278
1 files changed, 278 insertions, 0 deletions
diff --git a/framework/src/onos/web/gui/src/main/webapp/tests/app/fw/util/keys-spec.js b/framework/src/onos/web/gui/src/main/webapp/tests/app/fw/util/keys-spec.js
new file mode 100644
index 00000000..227d7904
--- /dev/null
+++ b/framework/src/onos/web/gui/src/main/webapp/tests/app/fw/util/keys-spec.js
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2014,2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ ONOS GUI -- Key Handler Service - Unit Tests
+ */
+describe('factory: fw/util/keys.js', function() {
+ var $log, ks, fs, qhs,
+ d3Elem, elem, last;
+
+
+ beforeEach(module('onosUtil', 'onosSvg', 'onosLayer', 'onosNav'));
+
+ beforeEach(inject(function (_$log_, KeyService, FnService, QuickHelpService) {
+ $log = _$log_;
+ ks = KeyService;
+ fs = FnService;
+ qhs = QuickHelpService;
+ d3Elem = d3.select('body').append('p').attr('id', 'ptest');
+ elem = d3Elem.node();
+ ks.installOn(d3Elem);
+ ks.bindQhs(qhs);
+ last = {
+ view: null,
+ key: null,
+ code: null,
+ ev: null
+ };
+ }));
+
+ afterEach(function () {
+ d3.select('#ptest').remove();
+ });
+
+ it('should define the key service', function () {
+ expect(ks).toBeDefined();
+ });
+
+ it('should define api functions', function () {
+ expect(fs.areFunctions(ks, [
+ 'bindQhs', 'installOn', 'keyBindings', 'gestureNotes', 'enableKeys'
+ ])).toBeTruthy();
+ });
+
+ // This no longer works because 'initKeyboardEvent' has been depreciated.
+ // Now there is a constructor for 'KeyboardEvent' where you can modify
+ // the new event with a dictionary(?) 'KeyboardEventInit'.
+ // However, the below code has been so recently depreciated, there are no
+ // examples online of how to use the new interface, and some browsers
+ // don't support it still. These tests will have to be put off for a
+ // while more. (Investigated 4/28/15)
+ // Also tried was Angular's triggerHandler() function, but it doesn't seem
+ // that it can take arguments about the event.
+ // Using jQuery in tests might be a good idea, for triggering test events.
+ function jsKeyDown(element, code) {
+ var ev = document.createEvent('KeyboardEvent');
+
+ // Chromium Hack
+ if (navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
+ Object.defineProperty(ev, 'keyCode', {
+ get: function () { return this.keyCodeVal; }
+ });
+ Object.defineProperty(ev, 'which', {
+ get: function () { return this.keyCodeVal; }
+ });
+ }
+
+ if (ev.initKeyboardEvent) {
+ ev.initKeyboardEvent('keydown', true, true, document.defaultView,
+ false, false, false, false, code, code);
+ } else {
+ ev.initKeyEvent('keydown', true, true, document.defaultView,
+ false, false, false, false, code, 0);
+ }
+
+ ev.keyCodeVal = code;
+
+ if (ev.keyCode !== code) {
+ console.warn("keyCode mismatch " + ev.keyCode +
+ "(" + ev.which + ") -> "+ code);
+ }
+ element.dispatchEvent(ev);
+ }
+
+ // === Key binding related tests
+ it('should start with default key bindings', function () {
+ var state = ks.keyBindings(),
+ gk = state.globalKeys,
+ mk = state.maskedKeys,
+ vk = state.viewKeys,
+ vf = state.viewFunction;
+
+ expect(gk.length).toEqual(4);
+ ['backSlash', 'slash', 'esc', 'T'].forEach(function (k) {
+ expect(fs.contains(gk, k)).toBeTruthy();
+ });
+
+ expect(mk.length).toEqual(3);
+ ['backSlash', 'slash', 'T'].forEach(function (k) {
+ expect(fs.contains(mk, k)).toBeTruthy();
+ });
+
+ expect(vk.length).toEqual(0);
+ expect(vf).toBeFalsy();
+ });
+
+ function bindTestKeys(withDescs) {
+ var keys = ['A', '1', 'F5', 'equals'],
+ kb = {};
+
+ function cb(view, key, code, ev) {
+ last.view = view;
+ last.key = key;
+ last.code = code;
+ last.ev = ev;
+ }
+
+ function bind(k) {
+ return withDescs ? [cb, 'desc for key ' + k] : cb;
+ }
+
+ keys.forEach(function (k) {
+ kb[k] = bind(k);
+ });
+
+ ks.keyBindings(kb);
+ }
+
+ function verifyCall(key, code) {
+ // TODO: update expectation, when view tokens are implemented
+ expect(last.view).toEqual('NotYetAViewToken');
+ last.view = null;
+
+ expect(last.key).toEqual(key);
+ last.key = null;
+
+ expect(last.code).toEqual(code);
+ last.code = null;
+
+ expect(last.ev).toBeTruthy();
+ last.ev = null;
+ }
+
+ function verifyNoCall() {
+ expect(last.view).toBeNull();
+ expect(last.key).toBeNull();
+ expect(last.code).toBeNull();
+ expect(last.ev).toBeNull();
+ }
+
+ function verifyTestKeys() {
+ jsKeyDown(elem, 65); // 'A'
+ verifyCall('A', 65);
+ jsKeyDown(elem, 66); // 'B'
+ verifyNoCall();
+
+ jsKeyDown(elem, 49); // '1'
+ verifyCall('1', 49);
+ jsKeyDown(elem, 50); // '2'
+ verifyNoCall();
+
+ jsKeyDown(elem, 116); // 'F5'
+ verifyCall('F5', 116);
+ jsKeyDown(elem, 117); // 'F6'
+ verifyNoCall();
+
+ jsKeyDown(elem, 187); // 'equals'
+ verifyCall('equals', 187);
+ jsKeyDown(elem, 189); // 'dash'
+ verifyNoCall();
+
+ var vk = ks.keyBindings().viewKeys;
+
+ expect(vk.length).toEqual(4);
+ ['A', '1', 'F5', 'equals'].forEach(function (k) {
+ expect(fs.contains(vk, k)).toBeTruthy();
+ });
+
+ expect(ks.keyBindings().viewFunction).toBeFalsy();
+ }
+
+ // TODO: jsKeyDown(...) no longer emulates key presses ?! :(
+ // The following four unit tests ignored until we can figure this out.
+ // INVESTIGATED: see jsKeyDown for details...
+
+ xit('should allow specific key bindings', function () {
+ bindTestKeys();
+ verifyTestKeys();
+ });
+
+ xit('should allow specific key bindings with descriptions', function () {
+ bindTestKeys(true);
+ verifyTestKeys();
+ });
+
+ xit('should warn about masked keys', function () {
+ var k = {'space': cb, 'T': cb},
+ count = 0;
+
+ function cb(token, key, code, ev) {
+ count++;
+ //console.debug('count = ' + count, token, key, code);
+ }
+
+ spyOn($log, 'warn');
+
+ ks.keyBindings(k);
+
+ expect($log.warn).toHaveBeenCalledWith('setKeyBindings(): Key "T" is reserved');
+
+ // the 'T' key should NOT invoke our callback
+ expect(count).toEqual(0);
+ jsKeyDown(elem, 84); // 'T'
+ expect(count).toEqual(0);
+
+ // but the 'space' key SHOULD invoke our callback
+ jsKeyDown(elem, 32); // 'space'
+ expect(count).toEqual(1);
+ });
+
+ xit('should block keys when disabled', function () {
+ var cbCount = 0;
+
+ function cb() { cbCount++; }
+
+ function pressA() { jsKeyDown(elem, 65); } // 65 == 'A' keycode
+
+ ks.keyBindings({ A: cb });
+
+ expect(cbCount).toBe(0);
+
+ pressA();
+ expect(cbCount).toBe(1);
+
+ ks.enableKeys(false);
+ pressA();
+ expect(cbCount).toBe(1);
+
+ ks.enableKeys(true);
+ pressA();
+ expect(cbCount).toBe(2);
+ });
+
+ // === Gesture notes related tests
+ it('should start with no notes', function () {
+ expect(ks.gestureNotes()).toEqual([]);
+ });
+
+ it('should allow us to add nodes', function () {
+ var notes = [
+ ['one', 'something about one'],
+ ['two', 'description of two']
+ ];
+ ks.gestureNotes(notes);
+
+ expect(ks.gestureNotes()).toEqual(notes);
+ });
+
+ it('should ignore non-arrays', function () {
+ ks.gestureNotes({foo:4});
+ expect(ks.gestureNotes()).toEqual([]);
+ });
+
+ // Consider adding test to ensure array contains 2-tuples of strings
+});