123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700 |
- var sinon = require('sinon');
- var assert = require('assert');
- var Keyboard = require('../lib/keyboard');
- var KeyCombo = require('../lib/key-combo');
- var Locale = require('../lib/locale');
- var doc = require('./fixtures/document');
- var win = require('./fixtures/window');
- describe('Keyboard', function() {
- var keyboard;
- beforeEach(function() {
- keyboard = new Keyboard(win, doc);
- });
- describe('#setLocale', function() {
- it('creates and sets a locale', function() {
- keyboard.setLocale('testName', function(locale, platform, userAgent) {
- assert.equal(platform, 'test-platform');
- assert.equal(userAgent, 'test-user-agent');
- locale.test = 1;
- });
- assert.equal(keyboard._locale.test, 1);
- assert.equal(keyboard._locales.testName.test, 1);
- });
- it('sets a locale', function() {
- keyboard._locales.testName = { test: 2 };
- keyboard.setLocale('testName');
- assert.equal(keyboard._locale.test, 2);
- });
- it('accepts locale instance and sets it', function() {
- keyboard.setLocale({
- localeName: 'testName',
- test: 3
- });
- assert.equal(keyboard._locale.test, 3);
- });
- });
- describe('#getLocale', function() {
- it('returns the current locale', function() {
- keyboard._locales.testName = { test: 4, localeName: 'testName' };
- keyboard._locale = keyboard._locales.testName;
- var locale = keyboard.getLocale();
- assert.equal(locale.test, 4);
- });
- it('returns the a locale by name', function() {
- keyboard._locales.testName = { test: 5 };
- keyboard._locale = keyboard._locales.testName;
- var locale = keyboard.getLocale('testName');
- assert.equal(locale.test, 5);
- });
- });
- describe('#bind', function() {
- it('binds a combo to press handler and release handlers', function() {
- var pressHandler = function() {};
- var releaseHandler = function() {};
- keyboard.bind('a', pressHandler, releaseHandler);
- assert.equal(keyboard._listeners[0].keyCombo.sourceStr, 'a');
- assert.equal(keyboard._listeners[0].pressHandler, pressHandler);
- assert.equal(keyboard._listeners[0].releaseHandler, releaseHandler);
- });
- it('binds a combo to a press handler', function() {
- var pressHandler = function() {};
- keyboard.bind('a', pressHandler);
- assert.equal(keyboard._listeners[0].keyCombo.sourceStr, 'a');
- assert.equal(keyboard._listeners[0].pressHandler, pressHandler);
- assert.equal(keyboard._listeners[0].releaseHandler, null);
- });
- it('binds a combo to a release handler', function() {
- var releaseHandler = function() {};
- keyboard.bind('a', null, releaseHandler);
- assert.equal(keyboard._listeners[0].keyCombo.sourceStr, 'a');
- assert.equal(keyboard._listeners[0].pressHandler, null);
- assert.equal(keyboard._listeners[0].releaseHandler, releaseHandler);
- });
- it('binds several combos to press and release handlers', function() {
- var pressHandler = function() {};
- var releaseHandler = function() {};
- keyboard.bind(['a', 'b'], pressHandler, releaseHandler);
- assert.equal(keyboard._listeners[0].keyCombo.sourceStr, 'a');
- assert.equal(keyboard._listeners[1].keyCombo.sourceStr, 'b');
- assert.equal(keyboard._listeners[0].pressHandler, pressHandler);
- assert.equal(keyboard._listeners[1].pressHandler, pressHandler);
- assert.equal(keyboard._listeners[0].releaseHandler, releaseHandler);
- assert.equal(keyboard._listeners[1].releaseHandler, releaseHandler);
- });
- it('binds press and release handlers to any keypress', function() {
- var pressHandler = function() {};
- var releaseHandler = function() {};
- keyboard.bind(pressHandler, releaseHandler);
- assert.equal(keyboard._listeners[0].keyCombo, null);
- assert.equal(keyboard._listeners[0].pressHandler, pressHandler);
- assert.equal(keyboard._listeners[0].releaseHandler, releaseHandler);
- });
- it('accepts preventRepeat as a final argument', function() {
- var pressHandler = function() {};
- var releaseHandler = function() {};
- keyboard.bind('a', pressHandler, releaseHandler, true);
- keyboard.bind(pressHandler, releaseHandler, true);
- assert.equal(keyboard._listeners[0].keyCombo.sourceStr, 'a');
- assert.equal(keyboard._listeners[0].pressHandler, pressHandler);
- assert.equal(keyboard._listeners[0].releaseHandler, releaseHandler);
- assert.equal(keyboard._listeners[0].preventRepeat, true);
- assert.equal(keyboard._listeners[1].keyCombo, null);
- assert.equal(keyboard._listeners[1].pressHandler, pressHandler);
- assert.equal(keyboard._listeners[1].releaseHandler, releaseHandler);
- assert.equal(keyboard._listeners[1].preventRepeat, true);
- });
- });
- describe('#addListener', function() {
- it('is an alias for bind', function() {
- assert.equal(keyboard.addListener, keyboard.bind);
- });
- });
- describe('#on', function() {
- it('is an alias for bind', function() {
- assert.equal(keyboard.on, keyboard.bind);
- });
- });
- describe('#unbind', function() {
- var pressHandler = function() {};
- var releaseHandler = function() {};
- beforeEach(function() {
- keyboard._listeners.push({
- keyCombo: new KeyCombo('a'),
- pressHandler: pressHandler,
- releaseHandler: releaseHandler,
- preventRepeat: false
- });
- keyboard._listeners.push({
- keyCombo: new KeyCombo('a'),
- pressHandler: null,
- releaseHandler: releaseHandler,
- preventRepeat: false
- });
- keyboard._listeners.push({
- keyCombo: new KeyCombo('a'),
- pressHandler: pressHandler,
- releaseHandler: null,
- preventRepeat: false
- });
- });
- afterEach(function() {
- keyboard._listeners.length = 0;
- });
- it('unbinds a combo from press handler and release handlers', function() {
- keyboard.unbind('a', pressHandler, releaseHandler);
- assert.equal(keyboard._listeners.length, 2);
- assert.equal(keyboard._listeners[0].pressHandler, null);
- assert.equal(keyboard._listeners[0].releaseHandler, releaseHandler);
- assert.equal(keyboard._listeners[1].pressHandler, pressHandler);
- assert.equal(keyboard._listeners[1].releaseHandler, null);
- });
- it('unbinds a combo from a press handler', function() {
- keyboard.unbind('a', pressHandler);
- assert.equal(keyboard._listeners.length, 2);
- assert.equal(keyboard._listeners[0].pressHandler, pressHandler);
- assert.equal(keyboard._listeners[0].releaseHandler, releaseHandler);
- assert.equal(keyboard._listeners[1].pressHandler, null);
- assert.equal(keyboard._listeners[1].releaseHandler, releaseHandler);
- });
- it('unbinds a combo from a release handler', function() {
- keyboard.unbind('a', null, releaseHandler);
- assert.equal(keyboard._listeners.length, 2);
- assert.equal(keyboard._listeners[0].pressHandler, pressHandler);
- assert.equal(keyboard._listeners[0].releaseHandler, releaseHandler);
- assert.equal(keyboard._listeners[1].pressHandler, pressHandler);
- assert.equal(keyboard._listeners[1].releaseHandler, null);
- });
- it('unbinds a several combos from press and release handlers', function() {
- keyboard._listeners.push({
- keyCombo: new KeyCombo('b'),
- pressHandler: pressHandler,
- releaseHandler: releaseHandler,
- preventRepeat: false
- });
- keyboard.unbind(['a', 'b'], pressHandler, releaseHandler);
- assert.equal(keyboard._listeners.length, 2);
- assert.equal(keyboard._listeners[0].pressHandler, null);
- assert.equal(keyboard._listeners[0].releaseHandler, releaseHandler);
- assert.equal(keyboard._listeners[1].pressHandler, pressHandler);
- assert.equal(keyboard._listeners[1].releaseHandler, null);
- });
- it('unbinds press and release handlers bound to any key press', function() {
- keyboard._listeners.push({
- keyCombo: null,
- pressHandler: pressHandler,
- releaseHandler: releaseHandler,
- preventRepeat: false
- });
- keyboard.unbind(pressHandler, releaseHandler);
- assert.equal(keyboard._listeners.length, 3);
- assert.equal(keyboard._listeners[0].pressHandler, pressHandler);
- assert.equal(keyboard._listeners[0].releaseHandler, releaseHandler);
- assert.equal(keyboard._listeners[1].pressHandler, null);
- assert.equal(keyboard._listeners[1].releaseHandler, releaseHandler);
- assert.equal(keyboard._listeners[2].pressHandler, pressHandler);
- assert.equal(keyboard._listeners[2].releaseHandler, null);
- });
- });
- describe('#removeListener', function() {
- it('is an alias for unbind', function() {
- assert.equal(keyboard.removeListener, keyboard.unbind);
- });
- });
- describe('#off', function() {
- it('is an alias for unbind', function() {
- assert.equal(keyboard.off, keyboard.unbind);
- });
- });
- describe('#setContext', function() {
- it('releases all keys before setting the context', function() {
- keyboard._locale = {};
- sinon.stub(keyboard, 'releaseAllKeys');
- keyboard.setContext('myContext');
- assert.ok(keyboard.releaseAllKeys.calledOnce);
- keyboard.releaseAllKeys.restore();
- });
- it('creates a new context with the given name if it doesn\'t exist.', function() {
- keyboard.setContext('myContext');
- assert.ok(keyboard._contexts.myContext);
- assert.equal(keyboard._currentContext, 'myContext');
- });
- it('applies an existing context if one with the given name already exists', function() {
- keyboard._contexts.myContext = [1];
- keyboard.setContext('myContext');
- assert.equal(keyboard._currentContext, 'myContext');
- assert.equal(keyboard._contexts[keyboard._currentContext][0], 1);
- });
- });
- describe('#getContext', function() {
- it('returns the current context', function() {
- keyboard._currentContext = 'myContext';
- assert.equal(keyboard.getContext(), 'myContext');
- });
- });
- describe('#watch', function() {
- it('calls stop', function() {
- sinon.stub(keyboard, 'stop');
- keyboard.watch(win, doc);
- assert.ok(keyboard.stop.calledOnce);
- keyboard.stop.restore();
- });
- it('attaches to a given window and document', function() {
- var win = { addEventListener: sinon.stub() };
- var doc = { addEventListener: sinon.stub() };
- keyboard.watch(win, doc);
- assert.equal(keyboard._isModernBrowser, true);
- assert.equal(keyboard._targetWindow, win);
- assert.equal(keyboard._targetElement, doc);
- assert.ok(win.addEventListener.firstCall.args[0], 'focus');
- assert.ok(win.addEventListener.secondCall.args[0], 'blur');
- assert.ok(doc.addEventListener.firstCall.args[0], 'keydown');
- assert.ok(doc.addEventListener.secondCall.args[0], 'keyup');
- });
- it('attaches to a given window and document (Legacy IE)', function() {
- var win = { attachEvent: sinon.stub() };
- var doc = { attachEvent: sinon.stub() };
- keyboard.watch(win, doc);
- assert.equal(keyboard._isModernBrowser, false);
- assert.equal(keyboard._targetWindow, win);
- assert.equal(keyboard._targetElement, doc);
- assert.ok(win.attachEvent.firstCall.args[0], 'onfocus');
- assert.ok(win.attachEvent.secondCall.args[0], 'onblur');
- assert.ok(doc.attachEvent.firstCall.args[0], 'onkeydown');
- assert.ok(doc.attachEvent.secondCall.args[0], 'onkeyup');
- });
-
- it('attaches to the global namespace if a window and document is not given', function() {
- global.addEventListener = sinon.stub();
- global.document = { addEventListener: sinon.stub() };
- keyboard.watch();
- assert.equal(keyboard._isModernBrowser, true);
- assert.equal(keyboard._targetWindow, global);
- assert.equal(keyboard._targetElement, global.document);
- assert.ok(global.addEventListener.firstCall.args[0], 'focus');
- assert.ok(global.addEventListener.secondCall.args[0], 'blur');
- assert.ok(global.document.addEventListener.firstCall.args[0], 'keydown');
- assert.ok(global.document.addEventListener.secondCall.args[0], 'keyup');
-
- delete global.addEventListener;
- delete global.document;
- });
-
- it('throws is error if the target window does not have the nessisary methods', function() {
- var win = {};
- var doc = {};
-
- assert.throws(function() {
- keyboard.watch(win, doc);
- }, /^(?=.*targetWindow)(?=.*addEventListener)(?=.*attachEvent).*$/);
- });
-
- it('throws is error a target window was not given and if the global does contain the nessisary functions', function() {
- assert.throws(function() {
- keyboard.watch();
- }, /^(?=.*global)(?=.*addEventListener)(?=.*attachEvent).*$/);
- });
- });
- describe('#stop', function() {
- it('dettaches from the currently attached window and document', function() {
- var doc = keyboard._targetElement = { removeEventListener: sinon.stub() };
- var win = keyboard._targetWindow = { removeEventListener: sinon.stub() };
- keyboard.stop();
- assert.equal(keyboard._targetWindow, null);
- assert.equal(keyboard._targetElement, null);
- assert.ok(win.removeEventListener.firstCall.args[0], 'focus');
- assert.ok(win.removeEventListener.secondCall.args[0], 'blur');
- assert.ok(doc.removeEventListener.firstCall.args[0], 'keydown');
- assert.ok(doc.removeEventListener.secondCall.args[0], 'keyup');
- });
- it('dettaches from the currently attached window and document (Legacy IE)', function() {
- var doc = { detachEvent: sinon.stub() };
- var win = { detachEvent: sinon.stub() };
- keyboard._isModernBrowser = false;
- keyboard._targetElement = doc;
- keyboard._targetWindow = win;
- keyboard.stop();
- assert.equal(keyboard._targetWindow, null);
- assert.equal(keyboard._targetElement, null);
- assert.ok(win.detachEvent.firstCall.args[0], 'onfocus');
- assert.ok(win.detachEvent.secondCall.args[0], 'onblur');
- assert.ok(doc.detachEvent.firstCall.args[0], 'onkeydown');
- assert.ok(doc.detachEvent.secondCall.args[0], 'onkeyup');
- });
- });
- describe('#pressKey', function() {
- var locale;
- beforeEach(function() {
- locale = new Locale('test');
- locale.bindKeyCode(0, 'a');
- locale.bindKeyCode(1, 'b');
- keyboard._locale = locale;
- });
- it('calls pressKey on the locale', function() {
- sinon.stub(locale, 'pressKey');
- keyboard.pressKey('a');
- assert.equal(locale.pressKey.lastCall.args[0], 'a');
- locale.pressKey.restore();
- });
- it('executes bindings with a combo matching the pressed keys within the locale', function() {
- var pressHandler = sinon.stub();
- keyboard._listeners.push({
- keyCombo: new KeyCombo('a'),
- pressHandler: pressHandler,
- releaseHandler: null,
- preventRepeat: false
- });
- keyboard.pressKey('a');
- assert.ok(pressHandler.calledOnce);
- });
- it('executes bindings without a combo', function() {
- var pressHandler = sinon.stub();
- keyboard._listeners.push({
- keyCombo: null,
- pressHandler: pressHandler,
- releaseHandler: null,
- preventRepeat: false
- });
- keyboard.pressKey('a');
- keyboard.pressKey('b');
- assert.ok(pressHandler.calledTwice);
- });
- it('prevents combo overlap by marking off keys once they have been used by a combo', function() {
- var aPressHandler = sinon.stub();
- var aBPressHandler = sinon.stub();
- keyboard._listeners.push({
- keyCombo: new KeyCombo('a'),
- pressHandler: aPressHandler,
- releaseHandler: null,
- preventRepeat: false
- });
- keyboard._listeners.push({
- keyCombo: new KeyCombo('a + b'),
- pressHandler: aBPressHandler,
- releaseHandler: null,
- preventRepeat: false
- });
- keyboard.pressKey('a'); // combo a fires
- keyboard.pressKey('b'); // combo a + b fires, but not combo a because the
- // a key has been consumed by combo a + b
- assert.ok(aPressHandler.calledOnce);
- assert.ok(aBPressHandler.calledOnce);
- });
- it('allows any number of identical bindings to fire without inhibiting each other', function() {
- var a1PressHandler = sinon.stub();
- var a2PressHandler = sinon.stub();
- keyboard._listeners.push({
- keyCombo: new KeyCombo('a'),
- pressHandler: a1PressHandler,
- releaseHandler: null,
- preventRepeat: false
- });
- keyboard._listeners.push({
- keyCombo: new KeyCombo('a'),
- pressHandler: a2PressHandler,
- releaseHandler: null,
- preventRepeat: false
- });
- keyboard.pressKey('a'); // combo a1 and a2 fires
- assert.ok(a1PressHandler.calledOnce);
- assert.ok(a2PressHandler.calledOnce);
- });
- it('does nothing when paused', function() {
- sinon.stub(locale, 'pressKey');
- keyboard._paused = true;
- keyboard.pressKey('a');
- assert.equal(locale.pressKey.called, false);
- assert.equal(locale.pressedKeys.length, 0);
- locale.pressKey.restore();
- });
- });
- describe('#releaseKey', function() {
- var locale;
- beforeEach(function() {
- locale = new Locale('test');
- locale.bindKeyCode(0, 'a');
- keyboard._locale = locale;
- });
- it('calls releaseKey on the locale', function() {
- sinon.stub(locale, 'releaseKey');
- keyboard.releaseKey('a');
- assert.equal(locale.releaseKey.lastCall.args[0], 'a');
- locale.releaseKey.restore();
- });
- it('will not execute a binding\'s releaseHandler unless it was triggered first by a press', function() {
- var releaseHandler = sinon.stub();
- keyboard.pressKey('a');
- keyboard._listeners.push({
- keyCombo: new KeyCombo('a'),
- pressHandler: null,
- releaseHandler: releaseHandler,
- preventRepeat: false
- });
- keyboard.releaseKey('a');
- assert.equal(releaseHandler.calledOnce, false);
- });
- it('executes the releaseHandler of active bindings that no longer match the pressed keys', function() {
- var releaseHandler = sinon.stub();
- keyboard._listeners.push({
- keyCombo: new KeyCombo('a'),
- pressHandler: null,
- releaseHandler: releaseHandler,
- preventRepeat: false
- });
- keyboard.pressKey('a');
- keyboard.releaseKey('a');
- assert.ok(releaseHandler.calledOnce);
- });
- it('executes the releaseHandler without a combo', function() {
- var releaseHandler = sinon.stub();
- keyboard._listeners.push({
- keyCombo: null,
- pressHandler: null,
- releaseHandler: releaseHandler,
- preventRepeat: false
- });
- keyboard.pressKey('a');
- keyboard.pressKey('b');
- keyboard.releaseKey('a');
- keyboard.releaseKey('b');
- assert.ok(releaseHandler.calledTwice);
- });
- });
- describe('#releaseAllKeys', function() {
- var locale;
- beforeEach(function() {
- locale = new Locale('test');
- locale.bindKeyCode(0, 'a');
- keyboard._locale = locale;
- });
- it('clears pressedKeys on the locale', function() {
- keyboard.releaseAllKeys();
- assert.equal(locale.pressedKeys.length, 0);
- });
- it('will not execute a binding\'s releaseHandler unless it was triggered first by a press', function() {
- var releaseHandler = sinon.stub();
- keyboard.pressKey('a');
- keyboard._listeners.push({
- keyCombo: new KeyCombo('a'),
- pressHandler: null,
- releaseHandler: releaseHandler,
- preventRepeat: false
- });
- keyboard.releaseAllKeys();
- assert.equal(releaseHandler.calledOnce, false);
- });
- it('executes the releaseHandler of active bindings that no longer match the pressed keys', function() {
- var releaseHandler = sinon.stub();
- keyboard._listeners.push({
- keyCombo: new KeyCombo('a'),
- pressHandler: null,
- releaseHandler: releaseHandler,
- preventRepeat: false
- });
- keyboard.pressKey('a');
- keyboard.releaseAllKeys();
- assert.ok(releaseHandler.calledOnce);
- });
- });
- describe('#pause', function() {
- it('pauses the instance', function() {
- keyboard.pause();
- assert.ok(keyboard._paused);
- });
- });
- describe('#resume', function() {
- it('resumes the instance', function() {
- keyboard.resume();
- assert.equal(keyboard._paused, false);
- });
- });
- describe('#reset', function() {
- it('calls releaseAllKeys', function() {
- sinon.stub(keyboard, 'releaseAllKeys');
- keyboard.reset();
- assert.ok(keyboard.releaseAllKeys.calledOnce);
- keyboard.releaseAllKeys.reset();
- });
- it('clears all listeners', function() {
- sinon.stub(keyboard, 'releaseAllKeys');
- keyboard._listeners = [1];
- keyboard.reset();
- assert.equal(keyboard._listeners.length, 0);
- keyboard.releaseAllKeys.reset();
- });
- });
- });
|