blob: 16b115c3ac3ebc045e8009902c14c0a2c48bb81d [file] [log] [blame]
/*
* Copyright 2014-present 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
*/
xdescribe('factory: fw/util/keys.js', function() {
var $log, ks, fs, qhs,
d3Elem, elem, last;
beforeEach(module('onosUtil', 'onosSvg', 'onosLayer', 'onosNav', 'onosRemote'));
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
});