Files
simple-bookreader/client/islets/core/y-event-emitter/y-event-emitter.test.js
Oleg Mokhov f3546ef3a5 Release
2015-06-20 14:48:34 +05:00

404 lines
13 KiB
JavaScript

modules.define(
'test',
['y-event-emitter'],
function (provide, YEventEmitter) {
describe('YEventEmitter', function () {
var emitter;
beforeEach(function () {
emitter = new YEventEmitter();
});
function testWrongCallbacks(action) {
var wrongCallbacks = [
undefined,
null,
0,
'',
[],
{},
/\w/
];
wrongCallbacks.forEach(function (wrongCallback) {
var fn = function () {
action(wrongCallback);
};
fn.should.throw(TypeError, 'callback must be a function');
});
}
describe('on()', function () {
it('should add event listeners', function () {
var spy1 = sinon.spy();
var spy1_1 = sinon.spy();
var spy2 = sinon.spy();
emitter
.on('event1', spy1)
.on('event1', spy1_1)
.on('event2', spy2)
.emit('event1');
spy1.calledOnce.should.be.true;
spy1.firstCall.calledWithExactly().should.be.true;
spy1_1.calledOnce.should.be.true;
spy2.called.should.be.false;
emitter.emit('event2', 2, 3, 'foo');
spy2.calledOnce.should.be.true;
spy2.firstCall.calledWithExactly(2, 3, 'foo').should.be.true;
var obj = {a: 'b'};
emitter.emit('event1', obj);
spy1.calledTwice.should.be.true;
spy1.secondCall.calledWithExactly(obj).should.be.true;
spy1_1.calledTwice.should.be.true;
spy1_1.secondCall.calledWithExactly(obj).should.be.true;
});
it('should add event listener with context', function () {
var spy1 = sinon.spy();
var context1 = {foo: 1};
var spy2 = sinon.spy();
var context2 = {bar: 2};
emitter.on('event', spy1, context1);
emitter.on('event', spy2, context2);
emitter.emit('event');
spy1.firstCall.calledOn(context1).should.be.true;
spy2.firstCall.calledOn(context2).should.be.true;
});
it('should can add the same listener many times', function () {
var spy1 = sinon.spy();
var spy2 = sinon.spy();
var ctx = {};
emitter
.on('event', spy1)
.on('event', spy1)
.on('event', spy2, ctx)
.on('event', spy2, ctx)
.emit('event');
spy1.callCount.should.eq(2);
spy2.callCount.should.eq(2);
spy2.alwaysCalledOn(ctx).should.be.true;
});
it('should throw error if callback is not a function', function () {
testWrongCallbacks(function (callback) {
emitter.on('event', callback);
});
});
});
describe('once()', function () {
it('should add a single-shot listener', function () {
var spy = sinon.spy();
emitter
.once('event', spy)
.emit('event')
.emit('event')
.emit('event');
spy.calledOnce.should.be.true;
});
it('should add a single-shot listener with context', function () {
var ctx1 = {};
var spy1 = sinon.spy();
var ctx2 = {};
var spy2 = sinon.spy();
emitter
.once('event', spy1, ctx1)
.once('event', spy2, ctx2)
.emit('event')
.emit('event')
.emit('event');
spy1.calledOnce.should.be.true;
spy1.firstCall.calledOn(ctx1).should.be.true;
spy2.calledOnce.should.be.true;
spy2.firstCall.calledOn(ctx2).should.be.true;
});
it('should throw error if callback is not a function', function () {
testWrongCallbacks(function (callback) {
emitter.once('event', callback);
});
});
});
describe('emit()', function () {
it('should work before add any event', function () {
emitter.emit('event', 1, 2).should.eq(emitter);
});
describe('while emiting event', function () {
it('should not call listener that was added in another listener', function () {
var spy = sinon.spy();
emitter.on('event', function () {
emitter.on('event', spy);
});
emitter.emit('event');
spy.called.should.be.false;
emitter.emit('event');
spy.called.should.be.true;
});
it('should call listener that was removed in another listener', function () {
var spy = sinon.spy();
emitter.on('event', spy);
emitter.on('event', function () {
emitter.off('event', spy);
});
emitter.emit('event');
spy.calledOnce.should.be.true;
spy.reset();
emitter.emit('event');
spy.called.should.be.false;
});
});
});
describe('off()', function () {
it('should remove listener according to event', function () {
var spy1 = sinon.spy();
var spy2 = sinon.spy();
emitter
.on('event', spy1)
.on('event', spy2)
.on('event2', spy1)
.off('event', spy1)
.off('event2', spy2)
.emit('event');
spy1.called.should.be.false;
spy2.called.should.be.true;
emitter.emit('event2');
spy1.called.should.be.true;
});
it('should remove listener according to event and context', function () {
var spy = sinon.spy();
var ctx1 = {};
var ctx2 = {};
emitter
.on('event', spy, ctx1)
.on('event', spy, ctx2)
.on('event', spy)
.off('event', spy, ctx1)
.emit('event');
spy.callCount.should.eq(2);
});
it('should remove once listener according to event', function () {
var spy = sinon.spy();
emitter
.once('event', spy)
.off('event', spy)
.emit('event')
.emit('event')
.emit('event');
spy.called.should.be.false;
});
it('should remove once listener according to event and context', function () {
var ctx1 = {};
var ctx2 = {};
var spy = sinon.spy();
emitter
.once('event', spy, ctx1)
.once('event', spy, ctx2)
.off('event', spy, ctx1)
.off('event', spy)
.emit('event')
.emit('event');
spy.calledOnce.should.be.true;
spy.firstCall.calledOn(ctx2).should.be.true;
});
it('should work before add any event', function () {
emitter.off('event', function () {}).should.eq(emitter);
});
it('should remove first listener from the list of same listeners', function () {
var spy = sinon.spy();
emitter
.on('event', spy)
.on('event', spy)
.on('event', spy);
emitter.off('event', spy);
emitter.emit('event');
spy.callCount.should.eq(2);
spy.reset();
emitter.off('event', spy);
emitter.emit('event');
spy.callCount.should.eq(1);
spy.reset();
emitter.off('event', spy);
emitter.emit('event');
spy.called.should.be.false;
});
it('should throw error if callback is not a function', function () {
testWrongCallbacks(function (callback) {
emitter.off('event', callback);
});
});
});
describe('offAll()', function () {
it('should remove all listeners of all events', function () {
var spy1 = sinon.spy();
var spy2 = sinon.spy();
emitter.on('event1', spy1);
emitter.on('event2', spy2);
emitter.emit('event1');
emitter.emit('event2');
emitter
.offAll()
.emit('event1')
.emit('event2');
spy1.calledOnce.should.be.true;
spy2.calledOnce.should.be.true;
});
it('should work before add any event', function () {
emitter.offAll().should.eq(emitter);
});
});
describe('offAll(event)', function () {
it('should remove all listeners for the specified event', function () {
var spy1 = sinon.spy();
var spy2 = sinon.spy();
var spy3 = sinon.spy();
emitter
.on('event1', spy1)
.on('event1', spy2)
.on('event2', spy1)
.on('event2', spy3)
.offAll('event2')
.emit('event1')
.emit('event2');
spy1.calledOnce.should.be.true;
spy2.calledOnce.should.be.true;
spy3.called.should.be.false;
});
it('should work before add any event', function () {
emitter.offAll('event').should.eq(emitter);
});
});
describe('_onAddEvent()', function () {
it('should be called when new event was added', function () {
var _onAddEvent = sinon.spy(emitter, '_onAddEvent');
var fn1 = function () {};
var fn2 = function () {};
var fn3 = function () {};
emitter.on('event1', fn1);
_onAddEvent.callCount.should.eq(1);
_onAddEvent.getCall(0).calledWithExactly('event1').should.be.true;
emitter.on('event1', fn2);
_onAddEvent.callCount.should.eq(1);
emitter.on('event2', fn1);
_onAddEvent.callCount.should.eq(2);
_onAddEvent.getCall(1).calledWithExactly('event2').should.be.true;
emitter.on('event1', fn3);
emitter.on('event2', fn2);
_onAddEvent.callCount.should.eq(2);
});
});
describe('_onRemoveEvent()', function () {
var _onRemoveEvent;
beforeEach(function () {
_onRemoveEvent = sinon.spy(emitter, '_onRemoveEvent');
});
it('should be called when event was removed', function () {
var fn1 = function () {};
var fn2 = function () {};
var fn3 = function () {};
var fn4 = function () {};
emitter.on('event1', fn1);
emitter.on('event1', fn2);
emitter.on('event2', fn3);
emitter.on('event2', fn4);
emitter.off('event1', fn2);
_onRemoveEvent.called.should.be.false;
emitter.off('event1', fn1);
_onRemoveEvent.callCount.should.eq(1);
_onRemoveEvent.getCall(0).calledWithExactly('event1').should.be.true;
emitter.offAll('event1');
_onRemoveEvent.callCount.should.eq(1, 'should not be called for already removed event');
emitter.offAll('event2');
_onRemoveEvent.callCount.should.eq(2);
_onRemoveEvent.getCall(1).calledWithExactly('event2').should.be.true;
});
describe('when remove all events using offAll()', function () {
it('should be called for each removed event', function () {
emitter
.on('event1', function () {})
.on('event2', function () {})
.on('event2', function () {})
.on('event3', function () {})
.offAll();
_onRemoveEvent.callCount.should.eq(3);
_onRemoveEvent.getCall(0).calledWithExactly('event1').should.be.true;
_onRemoveEvent.getCall(1).calledWithExactly('event2').should.be.true;
_onRemoveEvent.getCall(2).calledWithExactly('event3').should.be.true;
});
});
});
});
provide();
});