Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
475 lines
15 KiB
JavaScript
Executable file
475 lines
15 KiB
JavaScript
Executable file
/*global EventDispatcher,
|
|
Set
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
require('/shared/js/event_dispatcher.js');
|
|
|
|
suite('EventDispatcher >', function() {
|
|
var originalObject = {
|
|
property: 3,
|
|
method: () => {}
|
|
};
|
|
|
|
var originalRestrictedObject = {
|
|
property: 3,
|
|
method: () => {}
|
|
};
|
|
|
|
var allowedEvents = ['allowed-event-1', 'allowed-event-2'];
|
|
|
|
var eventTarget = null,
|
|
restrictedEventTarget = null;
|
|
|
|
suiteSetup(function() {
|
|
eventTarget = EventDispatcher.mixin(originalObject);
|
|
restrictedEventTarget = EventDispatcher.mixin(
|
|
originalRestrictedObject,
|
|
allowedEvents
|
|
);
|
|
});
|
|
|
|
teardown(function() {
|
|
eventTarget.offAll();
|
|
});
|
|
|
|
suite('mixin >', function() {
|
|
test('throws if object to mix into is not valid object', function() {
|
|
assert.throws(() => EventDispatcher.mixin());
|
|
assert.throws(() => EventDispatcher.mixin(null));
|
|
assert.throws(() => EventDispatcher.mixin(() => {}));
|
|
assert.throws(() => EventDispatcher.mixin(3));
|
|
});
|
|
|
|
test('throws if object to mix into already has dispatcher methods',
|
|
function() {
|
|
var CustomClass = function() {};
|
|
EventDispatcher.mixin(CustomClass.prototype);
|
|
|
|
assert.throws(() => EventDispatcher.mixin({ on: () => {} }));
|
|
assert.throws(() => EventDispatcher.mixin({ on: null }));
|
|
assert.throws(() => EventDispatcher.mixin({ off: () => {} }));
|
|
assert.throws(() => EventDispatcher.mixin({ off: 'day off' }));
|
|
assert.throws(() => EventDispatcher.mixin({ offAll: () => {} }));
|
|
assert.throws(() => EventDispatcher.mixin({ emit: () => {} }));
|
|
assert.throws(() => EventDispatcher.mixin(new CustomClass()));
|
|
assert.throws(() => EventDispatcher.mixin(EventDispatcher.mixin({})));
|
|
});
|
|
|
|
test('throws if invalid array is passed for allowedEvents', function() {
|
|
assert.throws(() => EventDispatcher.mixin({}, null));
|
|
assert.throws(() => EventDispatcher.mixin({}, 'event'));
|
|
assert.throws(() => EventDispatcher.mixin({}, new Set()));
|
|
});
|
|
|
|
test('correctly adds methods to target object', function() {
|
|
assert.equal(typeof eventTarget.on, 'function');
|
|
assert.equal(typeof eventTarget.off, 'function');
|
|
assert.equal(typeof eventTarget.offAll, 'function');
|
|
assert.equal(typeof eventTarget.emit, 'function');
|
|
|
|
assert.strictEqual(eventTarget, originalObject);
|
|
assert.strictEqual(eventTarget.method, originalObject.method);
|
|
assert.strictEqual(eventTarget.property, originalObject.property);
|
|
});
|
|
});
|
|
|
|
suite('on >', function() {
|
|
test('throws if event name is not valid string', function() {
|
|
assert.throws(() => eventTarget.on());
|
|
assert.throws(() => eventTarget.on('', () => {}));
|
|
assert.throws(() => eventTarget.on(null, () => {}));
|
|
});
|
|
|
|
test('throws if handler is not function', function() {
|
|
assert.throws(() => eventTarget.on('event'));
|
|
assert.throws(() => eventTarget.on('event', null));
|
|
assert.throws(() => eventTarget.on('event', {}));
|
|
});
|
|
|
|
test('successfully registers handler', function() {
|
|
var expectedHandler = sinon.stub(),
|
|
unexpectedHandler = sinon.stub();
|
|
|
|
eventTarget.on('not-expected-event', unexpectedHandler);
|
|
eventTarget.on('event', expectedHandler);
|
|
|
|
eventTarget.emit('event');
|
|
sinon.assert.calledOnce(expectedHandler);
|
|
|
|
eventTarget.emit('event');
|
|
sinon.assert.calledTwice(expectedHandler);
|
|
sinon.assert.notCalled(unexpectedHandler);
|
|
});
|
|
|
|
test('successfully registers multiple handlers', function() {
|
|
var expectedHandler1 = sinon.stub(),
|
|
expectedHandler2 = sinon.stub(),
|
|
unexpectedHandler = sinon.stub();
|
|
|
|
eventTarget.on('not-expected-event', unexpectedHandler);
|
|
eventTarget.on('event', expectedHandler1);
|
|
eventTarget.on('event', expectedHandler2);
|
|
|
|
eventTarget.emit('event');
|
|
|
|
sinon.assert.notCalled(unexpectedHandler);
|
|
sinon.assert.calledOnce(expectedHandler1);
|
|
sinon.assert.calledOnce(expectedHandler2);
|
|
sinon.assert.callOrder(expectedHandler1, expectedHandler2);
|
|
});
|
|
|
|
suite('with allowed events >', function() {
|
|
test('throws if event name is not allowed', function() {
|
|
assert.throws(() => restrictedEventTarget.on('event'));
|
|
});
|
|
|
|
test('successfully registers handler for allowed event', function() {
|
|
var expectedHandler = sinon.stub(),
|
|
unexpectedHandler = sinon.stub();
|
|
|
|
restrictedEventTarget.on('allowed-event-2', unexpectedHandler);
|
|
restrictedEventTarget.on('allowed-event-1', expectedHandler);
|
|
|
|
restrictedEventTarget.emit('allowed-event-1');
|
|
sinon.assert.calledOnce(expectedHandler);
|
|
|
|
restrictedEventTarget.emit('allowed-event-1');
|
|
sinon.assert.calledTwice(expectedHandler);
|
|
sinon.assert.notCalled(unexpectedHandler);
|
|
});
|
|
});
|
|
});
|
|
|
|
suite('once >', function() {
|
|
test('throws if event name is not valid string', function() {
|
|
assert.throws(() => eventTarget.once());
|
|
assert.throws(() => eventTarget.once('', () => {}));
|
|
assert.throws(() => eventTarget.once(null, () => {}));
|
|
});
|
|
|
|
test('throws if handler is not function', function() {
|
|
assert.throws(() => eventTarget.once('event'));
|
|
assert.throws(() => eventTarget.once('event', null));
|
|
assert.throws(() => eventTarget.once('event', {}));
|
|
});
|
|
|
|
test('successfully registers handler', function() {
|
|
var expectedHandler = sinon.stub(),
|
|
unexpectedHandler = sinon.stub();
|
|
|
|
eventTarget.once('not-expected-event', unexpectedHandler);
|
|
eventTarget.once('event', expectedHandler);
|
|
|
|
eventTarget.emit('event');
|
|
sinon.assert.calledOnce(expectedHandler);
|
|
|
|
// Should not call handler more than once.
|
|
eventTarget.emit('event');
|
|
sinon.assert.calledOnce(expectedHandler);
|
|
sinon.assert.notCalled(unexpectedHandler);
|
|
});
|
|
|
|
test('successfully registers multiple handlers', function() {
|
|
var expectedHandler1 = sinon.stub(),
|
|
expectedHandler2 = sinon.stub(),
|
|
unexpectedHandler = sinon.stub();
|
|
|
|
eventTarget.once('not-expected-event', unexpectedHandler);
|
|
eventTarget.once('event', expectedHandler1);
|
|
eventTarget.once('event', expectedHandler2);
|
|
|
|
eventTarget.emit('event');
|
|
|
|
sinon.assert.notCalled(unexpectedHandler);
|
|
sinon.assert.calledOnce(expectedHandler1);
|
|
sinon.assert.calledOnce(expectedHandler2);
|
|
sinon.assert.callOrder(expectedHandler1, expectedHandler2);
|
|
});
|
|
|
|
test('correctly passes parameters', function() {
|
|
var handler = sinon.stub();
|
|
|
|
eventTarget.once('event', handler);
|
|
eventTarget.emit('event');
|
|
|
|
sinon.assert.calledOnce(handler);
|
|
sinon.assert.calledWithExactly(handler, undefined);
|
|
|
|
eventTarget.once('event', handler);
|
|
eventTarget.emit('event', { a: 'b' });
|
|
|
|
sinon.assert.calledTwice(handler);
|
|
sinon.assert.calledWithExactly(handler, { a: 'b' });
|
|
});
|
|
|
|
suite('with allowed events >', function() {
|
|
test('throws if event name is not allowed', function() {
|
|
assert.throws(() => restrictedEventTarget.once('event'));
|
|
});
|
|
|
|
test('successfully registers handler for allowed event', function() {
|
|
var expectedHandler = sinon.stub(),
|
|
unexpectedHandler = sinon.stub();
|
|
|
|
restrictedEventTarget.once('allowed-event-2', unexpectedHandler);
|
|
restrictedEventTarget.once('allowed-event-1', expectedHandler);
|
|
|
|
restrictedEventTarget.emit('allowed-event-1');
|
|
sinon.assert.calledOnce(expectedHandler);
|
|
|
|
// Should not call handler more than once.
|
|
restrictedEventTarget.emit('allowed-event-1');
|
|
sinon.assert.calledOnce(expectedHandler);
|
|
sinon.assert.notCalled(unexpectedHandler);
|
|
});
|
|
});
|
|
});
|
|
|
|
suite('off >', function() {
|
|
test('throws if event name is not valid string', function() {
|
|
assert.throws(() => eventTarget.off());
|
|
assert.throws(() => eventTarget.off('', () => {}));
|
|
assert.throws(() => eventTarget.off(null, () => {}));
|
|
});
|
|
|
|
test('throws if handler is not function', function() {
|
|
assert.throws(() => eventTarget.off('event'));
|
|
assert.throws(() => eventTarget.off('event', null));
|
|
assert.throws(() => eventTarget.off('event', {}));
|
|
});
|
|
|
|
test('successfully unregisters handler', function() {
|
|
var handler = sinon.stub();
|
|
|
|
eventTarget.on('event', handler);
|
|
eventTarget.emit('event');
|
|
|
|
sinon.assert.calledOnce(handler);
|
|
|
|
eventTarget.off('event', handler);
|
|
eventTarget.emit('event');
|
|
|
|
sinon.assert.calledOnce(handler);
|
|
});
|
|
|
|
test('unregisters correct handler', function() {
|
|
var handler1 = sinon.stub(),
|
|
handler2 = sinon.stub(),
|
|
handler3 = sinon.stub();
|
|
|
|
eventTarget.on('event', handler1);
|
|
eventTarget.on('event', handler2);
|
|
eventTarget.emit('event');
|
|
|
|
sinon.assert.calledOnce(handler1);
|
|
sinon.assert.calledOnce(handler2);
|
|
|
|
eventTarget.off('event', handler3);
|
|
eventTarget.emit('event');
|
|
|
|
sinon.assert.calledTwice(handler1);
|
|
sinon.assert.calledTwice(handler2);
|
|
|
|
eventTarget.off('event', handler1);
|
|
eventTarget.emit('event');
|
|
|
|
sinon.assert.calledTwice(handler1);
|
|
sinon.assert.calledThrice(handler2);
|
|
|
|
eventTarget.off('event', handler2);
|
|
eventTarget.emit('event');
|
|
|
|
sinon.assert.calledTwice(handler1);
|
|
sinon.assert.calledThrice(handler2);
|
|
});
|
|
|
|
suite('with allowed events >', function() {
|
|
test('throws if event name is not allowed', function() {
|
|
assert.throws(() => restrictedEventTarget.off('event'));
|
|
});
|
|
|
|
test('successfully unregisters handler for allowed event', function() {
|
|
var handler = sinon.stub();
|
|
|
|
restrictedEventTarget.on('allowed-event-1', handler);
|
|
restrictedEventTarget.emit('allowed-event-1');
|
|
|
|
sinon.assert.calledOnce(handler);
|
|
|
|
restrictedEventTarget.off('allowed-event-1', handler);
|
|
restrictedEventTarget.emit('allowed-event-1');
|
|
|
|
sinon.assert.calledOnce(handler);
|
|
});
|
|
});
|
|
});
|
|
|
|
suite('offAll >', function() {
|
|
test('throws if event name is not valid string', function() {
|
|
assert.throws(() => eventTarget.offAll(''));
|
|
assert.throws(() => eventTarget.offAll(null));
|
|
});
|
|
|
|
test('unregisters all handlers for a specific event', function() {
|
|
var handler1 = sinon.stub(),
|
|
handler2 = sinon.stub();
|
|
|
|
eventTarget.on('event', handler1);
|
|
eventTarget.on('event', handler2);
|
|
eventTarget.emit('event');
|
|
|
|
sinon.assert.calledOnce(handler1);
|
|
sinon.assert.calledOnce(handler2);
|
|
|
|
eventTarget.offAll('other-event');
|
|
eventTarget.emit('event');
|
|
|
|
sinon.assert.calledTwice(handler1);
|
|
sinon.assert.calledTwice(handler2);
|
|
|
|
eventTarget.offAll('event');
|
|
eventTarget.emit('event');
|
|
|
|
sinon.assert.calledTwice(handler1);
|
|
sinon.assert.calledTwice(handler2);
|
|
});
|
|
|
|
test('unregisters all handlers for all events', function() {
|
|
var handler1 = sinon.stub();
|
|
var handler2 = sinon.stub();
|
|
var handler3 = sinon.stub();
|
|
|
|
eventTarget.on('event-1', handler1);
|
|
eventTarget.on('event-1', handler2);
|
|
eventTarget.on('event-2', handler3);
|
|
|
|
eventTarget.offAll();
|
|
eventTarget.emit('event-1');
|
|
eventTarget.emit('event-2');
|
|
|
|
sinon.assert.notCalled(handler1);
|
|
sinon.assert.notCalled(handler2);
|
|
sinon.assert.notCalled(handler3);
|
|
});
|
|
|
|
suite('with allowed events >', function() {
|
|
test('throws if event name is not allowed', function() {
|
|
assert.throws(() => restrictedEventTarget.offAll('event'));
|
|
});
|
|
|
|
test('successfully unregisters all handlers for allowed event',
|
|
function() {
|
|
var handler1 = sinon.stub(),
|
|
handler2 = sinon.stub();
|
|
|
|
restrictedEventTarget.on('allowed-event-1', handler1);
|
|
restrictedEventTarget.on('allowed-event-1', handler2);
|
|
restrictedEventTarget.emit('allowed-event-1');
|
|
|
|
sinon.assert.calledOnce(handler1);
|
|
sinon.assert.calledOnce(handler2);
|
|
|
|
restrictedEventTarget.offAll('allowed-event-2');
|
|
restrictedEventTarget.emit('allowed-event-1');
|
|
|
|
sinon.assert.calledTwice(handler1);
|
|
sinon.assert.calledTwice(handler2);
|
|
|
|
restrictedEventTarget.offAll('allowed-event-1');
|
|
restrictedEventTarget.emit('allowed-event-1');
|
|
|
|
sinon.assert.calledTwice(handler1);
|
|
sinon.assert.calledTwice(handler2);
|
|
});
|
|
});
|
|
});
|
|
|
|
suite('emit >', function() {
|
|
test('throws if event name is not valid string', function() {
|
|
assert.throws(() => eventTarget.emit());
|
|
assert.throws(() => eventTarget.emit('', {}));
|
|
assert.throws(() => eventTarget.emit(null, {}));
|
|
});
|
|
|
|
test('execute all handlers in the right order', function() {
|
|
var expectedHandler1 = sinon.stub(),
|
|
expectedHandler2 = sinon.stub(),
|
|
unexpectedHandler = sinon.stub();
|
|
|
|
eventTarget.on('event', expectedHandler1);
|
|
eventTarget.on('event', expectedHandler2);
|
|
eventTarget.on('other-event', unexpectedHandler);
|
|
|
|
eventTarget.emit('event');
|
|
|
|
sinon.assert.notCalled(unexpectedHandler);
|
|
sinon.assert.calledOnce(expectedHandler1);
|
|
sinon.assert.calledOnce(expectedHandler2);
|
|
sinon.assert.callOrder(expectedHandler1, expectedHandler2);
|
|
});
|
|
|
|
test('passes correct parameters to the handlers', function() {
|
|
var handler1 = sinon.stub(),
|
|
handler2 = sinon.stub(),
|
|
handler3 = sinon.stub();
|
|
|
|
var parameters1 = {
|
|
id: 1
|
|
};
|
|
|
|
var parameters2 = 'hello!';
|
|
|
|
eventTarget.on('event', handler1);
|
|
eventTarget.on('event-1', handler2);
|
|
eventTarget.on('other-event', handler3);
|
|
|
|
eventTarget.emit('event', parameters1);
|
|
eventTarget.emit('event-1', parameters2);
|
|
eventTarget.emit('other-event');
|
|
|
|
sinon.assert.calledWith(handler1, parameters1);
|
|
sinon.assert.calledWith(handler2, parameters2);
|
|
sinon.assert.calledWith(handler3, undefined);
|
|
});
|
|
|
|
test('execute all handlers even if exception occurs', function() {
|
|
var handler1 = sinon.stub().throws('Type Error'),
|
|
handler2 = sinon.stub();
|
|
|
|
eventTarget.on('event', handler1);
|
|
eventTarget.on('event', handler2);
|
|
|
|
eventTarget.emit('event');
|
|
|
|
sinon.assert.calledOnce(handler1);
|
|
sinon.assert.calledOnce(handler2);
|
|
sinon.assert.callOrder(handler1, handler2);
|
|
});
|
|
|
|
suite('with allowed events >', function() {
|
|
test('throws if event name is not allowed', function() {
|
|
assert.throws(() => restrictedEventTarget.emit('event'));
|
|
});
|
|
|
|
test('execute all handlers for allowed event in the right order',
|
|
function() {
|
|
var expectedHandler1 = sinon.stub(),
|
|
expectedHandler2 = sinon.stub(),
|
|
unexpectedHandler = sinon.stub();
|
|
|
|
restrictedEventTarget.on('allowed-event-1', expectedHandler1);
|
|
restrictedEventTarget.on('allowed-event-1', expectedHandler2);
|
|
restrictedEventTarget.on('allowed-event-2', unexpectedHandler);
|
|
|
|
restrictedEventTarget.emit('allowed-event-1');
|
|
|
|
sinon.assert.notCalled(unexpectedHandler);
|
|
sinon.assert.calledOnce(expectedHandler1);
|
|
sinon.assert.calledOnce(expectedHandler2);
|
|
sinon.assert.callOrder(expectedHandler1, expectedHandler2);
|
|
});
|
|
});
|
|
});
|
|
});
|