208 lines
6.5 KiB
JavaScript
208 lines
6.5 KiB
JavaScript
import '../_setup.js';
|
|
|
|
describe('lib/evnet', function () {
|
|
let listenerRegistry;
|
|
let spyAEL;
|
|
let spyREL;
|
|
//
|
|
let registerListeners;
|
|
let unregisterListeners;
|
|
let findElementInEventPath;
|
|
|
|
before(function () {
|
|
spyAEL = sinon.spy(EventTarget.prototype, 'addEventListener');
|
|
spyREL = sinon.spy(EventTarget.prototype, 'removeEventListener');
|
|
|
|
const origWeakMap = global.WeakMap;
|
|
global.WeakMap = function (...args) {
|
|
return listenerRegistry = new origWeakMap(...args);
|
|
};
|
|
return import('../../../js/lib/event.js')
|
|
.then((module) => {
|
|
global.WeakMap = origWeakMap;
|
|
|
|
registerListeners = module.registerListeners;
|
|
unregisterListeners = module.unregisterListeners;
|
|
findElementInEventPath = module.findElementInEventPath;
|
|
});
|
|
});
|
|
|
|
after(function () {
|
|
spyAEL.restore();
|
|
spyREL.restore();
|
|
});
|
|
|
|
afterEach(function () {
|
|
spyAEL.resetHistory();
|
|
spyREL.resetHistory();
|
|
});
|
|
|
|
describe('registerListeners()', function () {
|
|
let target;
|
|
|
|
before(function () {
|
|
target = document.createElement('input');
|
|
testContainer.appendChild(target);
|
|
});
|
|
|
|
after(function () {
|
|
testContainer.removeChild(target);
|
|
});
|
|
|
|
it('registers event listeres with key object calling addEventListener()', function () {
|
|
const keyObj = {};
|
|
const onClick = sinon.spy();
|
|
const onKeydown = sinon.spy();
|
|
const onMounseEnter = () => {};
|
|
const listeners = [
|
|
[document, 'click', onClick],
|
|
[target, 'keydown', onKeydown, {capture: false}],
|
|
[target, 'mouseenter', onMounseEnter, true],
|
|
];
|
|
|
|
registerListeners(keyObj, listeners);
|
|
expect(listenerRegistry.get(keyObj), 'to equal', listeners);
|
|
expect(spyAEL.args, 'to equal', listeners.map(listener => listener.slice(1)));
|
|
|
|
testContainer.click();
|
|
expect(onClick.called, 'to be true');
|
|
simulant.fire(target, 'keydown', {key: 'enter'});
|
|
expect(onKeydown.called, 'to be true');
|
|
|
|
listeners.forEach((listener) => {
|
|
EventTarget.prototype.removeEventListener.call(...listener);
|
|
});
|
|
listenerRegistry.delete(keyObj);
|
|
});
|
|
|
|
it('appends listeners if registration for key object already exists', function () {
|
|
const keyObj = {};
|
|
const onClick = () => {};
|
|
const onKeydown = () => {};
|
|
const onMounseEnter = () => {};
|
|
const listeners = [
|
|
[document, 'click', onClick],
|
|
];
|
|
const listenersToAdd = [
|
|
[target, 'keydown', onKeydown, {capture: false}],
|
|
[target, 'mouseenter', onMounseEnter, true],
|
|
];
|
|
listenerRegistry.set(keyObj, listeners);
|
|
|
|
registerListeners(keyObj, listenersToAdd);
|
|
expect(listeners.length, 'to be', 3);
|
|
expect(listenerRegistry.get(keyObj), 'to equal', listeners);
|
|
expect(spyAEL.args, 'to equal', listenersToAdd.map(listener => listener.slice(1)));
|
|
|
|
listenersToAdd.forEach((listener) => {
|
|
EventTarget.prototype.removeEventListener.call(...listener);
|
|
});
|
|
listenerRegistry.delete(keyObj);
|
|
});
|
|
});
|
|
|
|
describe('unregisterListeners()', function () {
|
|
let target;
|
|
|
|
before(function () {
|
|
target = document.createElement('input');
|
|
testContainer.appendChild(target);
|
|
});
|
|
|
|
after(function () {
|
|
testContainer.removeChild(target);
|
|
});
|
|
|
|
it('unregisters all event listeres for key object calling removeEventListener()', function () {
|
|
const keyObj = {};
|
|
const onClick = sinon.spy();
|
|
const onKeydown = sinon.spy();
|
|
const onMounseEnter = () => {};
|
|
const listeners = [
|
|
[document, 'click', onClick],
|
|
[target, 'keydown', onKeydown, {capture: false}],
|
|
[target, 'mouseenter', onMounseEnter, true],
|
|
];
|
|
listeners.forEach((listener) => {
|
|
EventTarget.prototype.addEventListener.call(...listener);
|
|
});
|
|
listenerRegistry.set(keyObj, listeners);
|
|
|
|
unregisterListeners(keyObj);
|
|
expect(listenerRegistry.get(keyObj), 'to be undefined');
|
|
expect(spyREL.args, 'to equal', listeners.map(listener => listener.slice(1)));
|
|
|
|
testContainer.click();
|
|
expect(onClick.called, 'to be false');
|
|
simulant.fire(target, 'keydown', {key: 'enter'});
|
|
expect(onKeydown.called, 'to be false');
|
|
});
|
|
});
|
|
|
|
describe('findElementInEventPath()', function () {
|
|
let field;
|
|
let control;
|
|
let input;
|
|
|
|
before(function () {
|
|
input = document.createElement('input');
|
|
control = document.createElement('div');
|
|
control.className = 'control';
|
|
control.appendChild(input);
|
|
field = document.createElement('div');
|
|
field.className = 'field';
|
|
field.appendChild(control);
|
|
testContainer.appendChild(field);
|
|
});
|
|
|
|
after(function () {
|
|
testContainer.removeChild(field);
|
|
});
|
|
|
|
it('returns the first element in event\'s path that matches given selector', function () {
|
|
const test = (ev) => {
|
|
expect(findElementInEventPath(ev, '.control'), 'to be', control);
|
|
expect(findElementInEventPath(ev, '.field'), 'to be', field);
|
|
expect(findElementInEventPath(ev, 'div'), 'to be', control);
|
|
};
|
|
|
|
document.addEventListener('click', test);
|
|
simulant.fire(input, 'click');
|
|
document.removeEventListener('click', test);
|
|
});
|
|
|
|
it('returns undefined if no matched element is in event\'s path', function () {
|
|
const test = (ev) => {
|
|
expect(findElementInEventPath(ev, '.foo'), 'to be undefined',);
|
|
};
|
|
|
|
document.addEventListener('click', test);
|
|
simulant.fire(input, 'click');
|
|
document.removeEventListener('click', test);
|
|
});
|
|
|
|
it('stops searching when it reaches event\'s currentTarget', function () {
|
|
const test = (ev) => {
|
|
expect(findElementInEventPath(ev, '.control'), 'to be', control);
|
|
expect(findElementInEventPath(ev, '.field'), 'to be undefined',);
|
|
};
|
|
|
|
control.addEventListener('click', test);
|
|
simulant.fire(input, 'click');
|
|
control.removeEventListener('click', test);
|
|
});
|
|
|
|
it('function can be used to evaluate the condition instead of css selector', function () {
|
|
const test = (ev) => {
|
|
expect(findElementInEventPath(ev, target => [field, control].includes(target)), 'to be', control);
|
|
expect(findElementInEventPath(ev, target => target === field), 'to be', field);
|
|
expect(findElementInEventPath(ev, target => target.tagName === 'DIV'), 'to be', control);
|
|
};
|
|
|
|
document.addEventListener('click', test);
|
|
simulant.fire(input, 'click');
|
|
document.removeEventListener('click', test);
|
|
});
|
|
});
|
|
});
|