MailOnline/VPAIDHTML5Client

View on GitHub
test/unit/subscriber.spec.js

Summary

Maintainability
A
2 hrs
Test Coverage
'use strict';
var noop = require('../testHelper').noop;
var Subscriber = require('../../js/subscriber');

describe('subscriber.js api', function () {
    it('must be a constructor function', function () {
        assert.isFunction(Subscriber);
    });

    describe('instance like object', function() {
        var subscriber;

        beforeEach(function () {
            subscriber = new Subscriber();
        });

        it('must return instance', function () {
            assert.instanceOf(subscriber, Subscriber);
        });

        describe('get', function () {
            it('must implement', function () {
                assert.isFunction(subscriber.get);
                assert.lengthOf(subscriber.get, 1);
            });

            it('must return an empty array if doesnt\'t exist any', function() {
                assert.isArray(subscriber.get('noEvent'));
                assert.lengthOf(subscriber.get('noEvent'), 0);
            });

        });

        describe('subscribe', function() {

            it('must implement', function() {
                assert.isFunction(subscriber.subscribe);
                assert.lengthOf(subscriber.subscribe, 3);
            });

            it('must register', function() {
                var f1 = function(){};
                var f2 = function(){};
                var f3 = function(){};
                subscriber.subscribe(f1, 'test', this);
                subscriber.subscribe(f2, 'test', this);
                subscriber.subscribe(f3, 'test1', this);

                assert.lengthOf(subscriber._subscribers.test, 2);
                assert.lengthOf(subscriber._subscribers.test1, 1);
                assert.sameDeepMembers(subscriber.get('test'), [{handler: f1, context: this, eventName: 'test'}, {handler: f2, context: this, eventName: 'test'}]);
                assert.sameDeepMembers(subscriber.get('test1'), [{handler: f3, context: this, eventName: 'test1'}]);
            });

        });

        describe('unsubscribe', function () {
            it('must implement', function() {
                assert.isFunction(subscriber.unsubscribe);
                assert.lengthOf(subscriber.unsubscribe, 2);
            });

            it('must not throw', function() {
                assert.doesNotThrow(function () {
                    subscriber.unsubscribe(noop, 'test');
                });
            });

            it('must unRegister', function() {
                var f1 = function f1() {};
                var f2 = function f2() {};

                subscriber.subscribe(f1, 'test', this);
                subscriber.subscribe(f2, 'test', this);
                subscriber.subscribe(f1, 'test1', this);
                subscriber.subscribe(f2, 'test1', this);

                assert.lengthOf(subscriber.get('test'), 2);
                assert.lengthOf(subscriber.get('test1'), 2);

                subscriber.unsubscribe(f2, 'test1', this);

                assert.sameDeepMembers(subscriber.get('test'), [{handler: f1, context: this, eventName: 'test'}, {handler: f2, context: this, eventName: 'test'}]);
                assert.sameDeepMembers(subscriber.get('test1'), [{handler: f1, context: this, eventName: 'test1'}]);
            });

        });

        describe('unsubscribeAll', function () {

            it('must implement', function () {
                assert.isFunction(subscriber.unsubscribeAll);
            });

            it('must remove all', function (){
                subscriber.subscribe(function(){}, 'test', this);
                subscriber.subscribe(noop, 'test', this);
                subscriber.subscribe(function(){}, 'test1', this);
                subscriber.subscribe(noop, 'test1', this);

                assert.lengthOf(subscriber.get('test'), 2);
                assert.lengthOf(subscriber.get('test1'), 2);

                subscriber.unsubscribeAll();

                assert.lengthOf(subscriber.get('test'), 0);
                assert.lengthOf(subscriber.get('test1'), 0);
            });
        });

        describe('trigger', function () {
            var clock;

            beforeEach(function () {
                clock = sinon.useFakeTimers();
            });

            afterEach(function () {
                clock.restore();
            });

            it('must implement', function () {
                assert.isFunction(subscriber.trigger);
            });

            it('must trigger the event listeners', function (){
                var cb1 = [sinon.spy(), sinon.spy()];
                var cb2 = [sinon.spy()];

                cb1.forEach(function (cb) {
                    subscriber.subscribe(cb, 'event1');
                });

                cb2.forEach(function (cb) {
                    subscriber.subscribe(cb, 'event2');
                });

                var data1 = {};
                var data2 = {};
                subscriber.trigger('event1', data1);
                subscriber.trigger('event2', data2);

                clock.tick(100);

                cb1.forEach(function (cb) {
                    assert(cb.calledWith(data1));
                });

                cb2.forEach(function (cb) {
                    assert(cb.calledWith(data2));
                });
            });

            it('must trigger the * event listeners', function () {
                var cb1 = sinon.spy();
                var cb2 = sinon.spy();
                subscriber.subscribe(cb1, 'event1');
                subscriber.subscribe(cb2, '*');

                var data1 = {};
                var data2 = {};

                subscriber.trigger('event1', data1);
                clock.tick(1);

                assert(cb1.calledWith(data1));
                assert(cb2.calledWith(data1));

                cb2.reset();

                subscriber.trigger('event2', data2);
                clock.tick(1);
                assert(cb2.calledWith(data2));
            });
        });

        describe('triggerSync', function () {

            it('must implement', function () {
                assert.isFunction(subscriber.trigger);
            });

            it('must trigger the event listeners immediately', function (){
                var cb1 = [sinon.spy(), sinon.spy()];
                var cb2 = [sinon.spy()];

                cb1.forEach(function (cb) {
                    subscriber.subscribe(cb, 'event1');
                });

                cb2.forEach(function (cb) {
                    subscriber.subscribe(cb, 'event2');
                });

                var data1 = {};
                var data2 = {};
                subscriber.triggerSync('event1', data1);
                subscriber.triggerSync('event2', data2);

                cb1.forEach(function (cb) {
                    assert(cb.calledWith(data1));
                });

                cb2.forEach(function (cb) {
                    assert(cb.calledWith(data2));
                });
            });

            it('must trigger the * event listeners', function () {
                var cb1 = sinon.spy();
                var cb2 = sinon.spy();
                subscriber.subscribe(cb1, 'event1');
                subscriber.subscribe(cb2, '*');

                var data1 = {};
                var data2 = {};

                subscriber.triggerSync('event1', data1);

                assert(cb1.calledWith(data1));
                assert(cb2.calledWith(data1));

                cb2.reset();

                subscriber.triggerSync('event2', data2);
                assert(cb2.calledWith(data2));
            });
        });

    });
});