UNPKG

app-com

Version:

Pub Sub Library for Communication in your App

722 lines (583 loc) 29.5 kB
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; import Com from './Com'; import { insert } from './Util'; import ERRORS from './ErrorMessages.js'; var events = void 0; var mock = { notObjects: [null, 3, 1.23, function () {}, false, [], true, 'blah'], notArraysOrObjects: [null, 3, 1.23, function () {}, false], notStrings: [null, 3, 1.23, function () {}, [], {}, false], notFunctions: ['notAFunction', null, 3, 1.23, [], {}, true, false], separator: '/', eventNames: { // ok to broadcast SPECIFIC_ONE: '/some/event', SPECIFIC_TWO: '/some/other/event', VARIOUS: { ONE: '/foo/bar', TWO: '/bazinga' }, // ok to subscribe (also the ones above) CATCHALL: '/', WILDCARD: '/some/', // not ok, will give errors NO_PATH: 'notInPathNotation', EMPTY_STRING: '' }, callback: function callback() {} }; describe('Com', function () { beforeEach(function () { events = new Com(); // spyOn(console, 'warn'); }); afterEach(function () { events = null; }); it('should be defined', function () { expect(typeof Com === 'undefined' ? 'undefined' : _typeof(Com)).toBe('function'); }); describe('setSeparator( separator )', function () { it('should have a method to set a separator for event names', function () { expect(_typeof(events.setSeparator)).toBe('function'); }); it('should throw when called more than one time', function () { expect(function () { events.setSeparator('1'); }).not.toThrow(); expect(function () { events.setSeparator('2'); }).toThrowError(ERRORS.SEPARATOR_NOT_DYNAMIC); }); it('should only accept strings and throw otherwise', function () { mock.notStrings.forEach(function (nope) { expect(function () { events.setSeparator(nope); }).toThrowError(ERRORS.SPEARATOR_NO_STRING); }); }); it('should throw when string has not a length of 1', function () { expect(function () { events.setSeparator('whoWouldDoThis'); }).toThrowError(ERRORS.SPEARATOR_LENGHT); expect(function () { events.setSeparator(''); }).toThrowError(ERRORS.SPEARATOR_LENGHT); expect(function () { events.setSeparator('/'); }).not.toThrow(); }); }); describe('registerEventNames( arrayOrObject )', function () { it('should have a method to register event names', function () { expect(_typeof(events.registerEventNames)).toBe('function'); }); it('should throw when used before .setSeparator', function () { expect(function () { events.registerEventNames(['/some', '/values']); }).toThrowError(ERRORS.SPEARATOR_NOT_SET); expect(function () { events.setSeparator(mock.separator); events.registerEventNames(['/some', '/values']); }).not.toThrow(); }); it('should accept an array', function () { expect(function () { events.setSeparator(mock.separator); events.registerEventNames(['/some', '/values']); }).not.toThrow(); }); it('should accept an object', function () { expect(function () { events.setSeparator(mock.separator); events.registerEventNames({ some: '/value' }); }).not.toThrow(); }); it('should throw when it gets not an object or an array', function () { events.setSeparator(mock.separator); mock.notArraysOrObjects.forEach(function (nope) { expect(function () { events.registerEventNames(nope); }).toThrowError(ERRORS.EVENTLIST_WRONG_FORMAT); }); }); it('should throw when duplicate event names were given', function () { events.setSeparator(mock.separator); expect(function () { events.registerEventNames({ aa: 'aa', bb: 'aa' }); }).toThrowError(ERRORS.EVENT_NAME_DUPLICATES); expect(function () { events.registerEventNames(['aaa', 'bbb', 'bbb']); }).toThrowError(ERRORS.EVENT_NAME_DUPLICATES); }); it('should throw when no event names are found', function () { events.setSeparator(mock.separator); expect(function () { events.registerEventNames({}); }).toThrowError(ERRORS.NO_EVENT_NAMES_FOUND); expect(function () { events.registerEventNames([]); }).toThrowError(ERRORS.NO_EVENT_NAMES_FOUND); }); it('should throw when called more than one time', function () { events.setSeparator(mock.separator); expect(function () { events.registerEventNames(mock.eventNames); }).not.toThrow(); expect(function () { events.registerEventNames(mock.eventNames); }).toThrowError(ERRORS.REGISTER_NOT_DYNAMIC); }); }); describe('broadcast( eventName, eventData )', function () { it('should have a method to send events', function () { expect(_typeof(events.broadcast)).toBe('function'); }); it('should throw when used before .registerEventNames()', function () { events.setSeparator(mock.separator); expect(function () { events.broadcast('/name'); }).toThrowError(ERRORS.REGISTER_EMPTY); expect(function () { events.registerEventNames(['/name']); events.broadcast('/name'); }).not.toThrow(); }); it('should accept the event name as string as first parameter ...', function () { events.setSeparator(mock.separator); expect(function () { events.registerEventNames(['/name']); events.broadcast('/name'); }).not.toThrow(); }); it('... and throw otherwise', function () { events.setSeparator(mock.separator); events.registerEventNames(['/name']); mock.notStrings.forEach(function (nope) { expect(function () { events.broadcast(nope); }).toThrowError(ERRORS.EVENT_NAME_NOT_STRING); }); }); it('should accept the event data as object as second optional parameter ...', function () { events.setSeparator(mock.separator); events.registerEventNames(['/name']); expect(function () { events.broadcast('/name', { event: 'data' }); }).not.toThrow(); expect(function () { events.broadcast('/name'); }).not.toThrow(); }); it('... and throw if its not an object', function () { events.setSeparator(mock.separator); events.registerEventNames(['/name']); mock.notObjects.forEach(function (nope) { expect(function () { events.broadcast('/name', nope); }).toThrowError(ERRORS.EVENT_DATA_NOT_OBJECT); }); }); it('should throw when event name is not in path notation', function () { events.setSeparator(mock.separator); events.registerEventNames(mock.eventNames); expect(function () { events.broadcast(mock.eventNames.SPECIFIC_ONE); }).not.toThrow(); expect(function () { events.broadcast(mock.eventNames.NO_PATH); }).toThrowError(insert(ERRORS.EVENT_NAME_NO_SEPARATOR, mock.separator)); expect(function () { events.broadcast(mock.eventNames.EMPTY_STRING); }).toThrowError(insert(ERRORS.EVENT_NAME_NO_SEPARATOR, mock.separator)); }); it('should throw when event name is a wildcard or a catchall', function () { events.setSeparator(mock.separator); events.registerEventNames(mock.eventNames); expect(function () { events.broadcast(mock.eventNames.WILDCARD); }).toThrowError(ERRORS.EVENT_NAME_IS_WILDCARD); expect(function () { events.broadcast(mock.eventNames.CATCHALL); }).toThrowError(ERRORS.EVENT_NAME_IS_WILDCARD); }); it('should throw when event name is not registered', function () { events.setSeparator(mock.separator); events.registerEventNames(mock.eventNames); expect(function () { events.broadcast('/NOT/REGISTERED'); }).toThrowError(ERRORS.EVENT_NAME_NOT_REGISTERED); }); it('should call registered subscriptions callbackFunctions - for specific subs', function () { events.setSeparator(mock.separator); spyOn(mock, 'callback'); events.registerEventNames(mock.eventNames); var specificOne = events.subscribe(mock.eventNames.SPECIFIC_ONE, mock.callback); specificOne.start(); events.broadcast(mock.eventNames.SPECIFIC_ONE); expect(mock.callback).toHaveBeenCalled(); }); it('should call registered subscriptions callbackFunctions - for wildcard subs', function () { events.setSeparator(mock.separator); spyOn(mock, 'callback'); events.registerEventNames(mock.eventNames); var wildcard = events.subscribe(mock.eventNames.WILDCARD, mock.callback); wildcard.start(); events.broadcast(mock.eventNames.SPECIFIC_ONE); events.broadcast(mock.eventNames.SPECIFIC_TWO); expect(mock.callback).toHaveBeenCalledTimes(2); }); it('should call registered subscriptions callbackFunctions - for catchalls', function () { events.setSeparator(mock.separator); spyOn(mock, 'callback'); events.registerEventNames(mock.eventNames); var catchall = events.subscribe(mock.eventNames.CATCHALL, mock.callback); catchall.start(); events.broadcast(mock.eventNames.SPECIFIC_ONE); events.broadcast(mock.eventNames.SPECIFIC_ONE); events.broadcast(mock.eventNames.SPECIFIC_TWO); expect(mock.callback).toHaveBeenCalledTimes(3); }); it('should call registered subscriptions callbackFunctions - for various combinations', function () { events.setSeparator(mock.separator); var callbacks = { specificOne: function specificOne() {}, specificTwo: function specificTwo() {}, wildcard: function wildcard() {}, catchall: function catchall() {} }; spyOn(callbacks, 'specificOne'); spyOn(callbacks, 'specificTwo'); spyOn(callbacks, 'wildcard'); spyOn(callbacks, 'catchall'); events.registerEventNames(mock.eventNames); var specificOne = events.subscribe(mock.eventNames.SPECIFIC_ONE, callbacks.specificOne); var specificTwo = events.subscribe(mock.eventNames.SPECIFIC_TWO, callbacks.specificTwo); var wildcard = events.subscribe(mock.eventNames.WILDCARD, callbacks.wildcard); var catchall = events.subscribe(mock.eventNames.CATCHALL, callbacks.catchall); specificOne.start(); specificTwo.start(); wildcard.start(); catchall.start(); events.broadcast(mock.eventNames.SPECIFIC_ONE); events.broadcast(mock.eventNames.SPECIFIC_ONE); events.broadcast(mock.eventNames.SPECIFIC_ONE); events.broadcast(mock.eventNames.SPECIFIC_ONE); // 4x events.broadcast(mock.eventNames.SPECIFIC_TWO); events.broadcast(mock.eventNames.SPECIFIC_TWO); // 2x events.broadcast(mock.eventNames.VARIOUS.ONE); events.broadcast(mock.eventNames.VARIOUS.TWO); expect(callbacks.specificOne).toHaveBeenCalledTimes(4); expect(callbacks.specificTwo).toHaveBeenCalledTimes(2); expect(callbacks.wildcard).toHaveBeenCalledTimes(6); expect(callbacks.catchall).toHaveBeenCalledTimes(8); }); it('should pass data to callback functions - for specific subs', function () { events.setSeparator(mock.separator); spyOn(mock, 'callback'); events.registerEventNames(mock.eventNames); var specificOne = events.subscribe(mock.eventNames.SPECIFIC_ONE, mock.callback); specificOne.start(); var eventData = { some: 'data' }; events.broadcast(mock.eventNames.SPECIFIC_ONE, eventData); expect(mock.callback).toHaveBeenCalledWith(eventData, { timestamp: jasmine.any(Number), eventName: mock.eventNames.SPECIFIC_ONE, eventData: eventData }); }); it('should pass data to callback functions - for wildcard subs', function () { events.setSeparator(mock.separator); spyOn(mock, 'callback'); events.registerEventNames(mock.eventNames); var wildcard = events.subscribe(mock.eventNames.WILDCARD, mock.callback); wildcard.start(); var eventData = { some: 'data' }; events.broadcast(mock.eventNames.SPECIFIC_ONE, eventData); expect(mock.callback).toHaveBeenCalledWith(eventData, { timestamp: jasmine.any(Number), eventName: mock.eventNames.SPECIFIC_ONE, eventData: eventData }); }); it('should pass data to callback functions - for catchall subs', function () { events.setSeparator(mock.separator); spyOn(mock, 'callback'); events.registerEventNames(mock.eventNames); var catchall = events.subscribe(mock.eventNames.CATCHALL, mock.callback); catchall.start(); var eventData = { some: 'data' }; events.broadcast(mock.eventNames.SPECIFIC_ONE, eventData); expect(mock.callback).toHaveBeenCalledWith(eventData, { timestamp: jasmine.any(Number), eventName: mock.eventNames.SPECIFIC_ONE, eventData: eventData }); }); }); describe('subscribe( eventName, callbackFunction )', function () { it('should have a method to listen for events', function () { events.setSeparator(mock.separator); expect(_typeof(events.subscribe)).toBe('function'); }); it('should throw when used before .registerEventNames()', function () { events.setSeparator(mock.separator); expect(function () { events.subscribe('/name', function () {}); }).toThrowError(ERRORS.REGISTER_EMPTY); expect(function () { events.registerEventNames(['/name']); events.subscribe('/name', function () {}); }).not.toThrow(); }); it('should accept the event name as string as first parameter ...', function () { events.setSeparator(mock.separator); expect(function () { events.registerEventNames(['/name']); events.subscribe('/name', function () {}); }).not.toThrow(); }); it('... and throw otherwise', function () { events.setSeparator(mock.separator); events.registerEventNames(['/name']); mock.notStrings.forEach(function (nope) { expect(function () { events.subscribe(nope, function () {}); }).toThrowError(ERRORS.EVENT_NAME_NOT_STRING); }); }); it('should accept a callback function as second parameter ...', function () { events.setSeparator(mock.separator); events.registerEventNames(['/name']); expect(function () { events.subscribe('/name', function () {}); }).not.toThrow(); }); it('... and throw if its not given or not a function', function () { events.setSeparator(mock.separator); events.registerEventNames(['/name']); mock.notFunctions.forEach(function (nope) { expect(function () { events.subscribe('/name', nope); }).toThrowError(ERRORS.EVENT_CALLBACK_NOT_FUNCTION); }); }); it('should throw when event name is not in path notation', function () { events.setSeparator(mock.separator); events.registerEventNames(mock.eventNames); expect(function () { events.subscribe(mock.eventNames.SPECIFIC_ONE, function () {}); }).not.toThrow(); expect(function () { events.subscribe(mock.eventNames.NO_PATH, function () {}); }).toThrowError(insert(ERRORS.EVENT_NAME_NO_SEPARATOR, mock.separator)); expect(function () { events.subscribe(mock.eventNames.EMPTY_STRING, function () {}); }).toThrowError(insert(ERRORS.EVENT_NAME_NO_SEPARATOR, mock.separator)); }); it('should throw when event name is not registered', function () { events.setSeparator(mock.separator); events.registerEventNames(mock.eventNames); expect(function () { events.subscribe('/NOT/REGISTERED', function () {}); }).toThrowError(ERRORS.EVENT_NAME_NOT_REGISTERED); }); it('should return a subscription object', function () { events.setSeparator(mock.separator); events.registerEventNames(mock.eventNames); var sub = events.subscribe(mock.eventNames.SPECIFIC_ONE, function () {}); expect(sub).toEqual(jasmine.any(Object)); }); it('subscription object - should have methods to manage the subscription', function () { events.setSeparator(mock.separator); events.registerEventNames(mock.eventNames); var sub = events.subscribe(mock.eventNames.SPECIFIC_ONE, function () {}); expect(_typeof(sub.kill)).toBe('function'); expect(_typeof(sub.start)).toBe('function'); expect(_typeof(sub.startWithLast)).toBe('function'); expect(_typeof(sub.startWithAll)).toBe('function'); expect(_typeof(sub.stop)).toBe('function'); }); it('subscription object - should stop listening after .stop() was called', function () { spyOn(mock, 'callback'); events.setSeparator(mock.separator); events.registerEventNames(mock.eventNames); var specificOne = events.subscribe(mock.eventNames.SPECIFIC_ONE, mock.callback); specificOne.start(); events.broadcast(mock.eventNames.SPECIFIC_ONE); events.broadcast(mock.eventNames.SPECIFIC_ONE); specificOne.stop(); events.broadcast(mock.eventNames.SPECIFIC_ONE); events.broadcast(mock.eventNames.SPECIFIC_ONE); events.broadcast(mock.eventNames.SPECIFIC_ONE); expect(mock.callback).toHaveBeenCalledTimes(2); }); it('... and resume when .start() was called again', function () { spyOn(mock, 'callback'); events.setSeparator(mock.separator); events.registerEventNames(mock.eventNames); var specificOne = events.subscribe(mock.eventNames.SPECIFIC_ONE, mock.callback); specificOne.start(); events.broadcast(mock.eventNames.SPECIFIC_ONE); events.broadcast(mock.eventNames.SPECIFIC_ONE); specificOne.stop(); events.broadcast(mock.eventNames.SPECIFIC_ONE); events.broadcast(mock.eventNames.SPECIFIC_ONE); events.broadcast(mock.eventNames.SPECIFIC_ONE); specificOne.start(); events.broadcast(mock.eventNames.SPECIFIC_ONE); expect(mock.callback).toHaveBeenCalledTimes(3); }); it('subscription object - should get all events when .startWithAll() is called', function () { spyOn(mock, 'callback'); events.setSeparator(mock.separator); events.registerEventNames(mock.eventNames); var specificOne = events.subscribe(mock.eventNames.SPECIFIC_ONE, mock.callback); events.broadcast(mock.eventNames.SPECIFIC_ONE); events.broadcast(mock.eventNames.SPECIFIC_ONE); specificOne.startWithAll(); expect(mock.callback).toHaveBeenCalledTimes(2); events.broadcast(mock.eventNames.SPECIFIC_ONE); events.broadcast(mock.eventNames.SPECIFIC_ONE); events.broadcast(mock.eventNames.SPECIFIC_ONE); specificOne.stop(); events.broadcast(mock.eventNames.SPECIFIC_ONE); expect(mock.callback).toHaveBeenCalledTimes(5); specificOne.startWithAll(); events.broadcast(mock.eventNames.SPECIFIC_ONE); events.broadcast(mock.eventNames.SPECIFIC_ONE); expect(mock.callback).toHaveBeenCalledTimes(13); }); it('subscription object - should get last event when .startWithLast() is called - for specific', function () { spyOn(mock, 'callback'); events.setSeparator(mock.separator); events.registerEventNames(mock.eventNames); var specificOne = events.subscribe(mock.eventNames.SPECIFIC_ONE, mock.callback); specificOne.startWithLast(); specificOne.stop(); expect(mock.callback).toHaveBeenCalledTimes(0); events.broadcast(mock.eventNames.SPECIFIC_ONE, { value: 1 }); events.broadcast(mock.eventNames.SPECIFIC_ONE, { value: 3 }); events.broadcast(mock.eventNames.SPECIFIC_ONE, { value: 4 }); events.broadcast(mock.eventNames.SPECIFIC_ONE, { value: 5 }); specificOne.startWithLast(); specificOne.stop(); expect(mock.callback).toHaveBeenCalledTimes(1); expect(mock.callback).toHaveBeenCalledWith({ value: 5 }, jasmine.any(Object)); events.broadcast(mock.eventNames.SPECIFIC_ONE, { value: 1 }); events.broadcast(mock.eventNames.SPECIFIC_ONE, { value: 2 }); events.broadcast(mock.eventNames.SPECIFIC_ONE, { value: 3 }); specificOne.startWithLast(); expect(mock.callback).toHaveBeenCalledTimes(2); expect(mock.callback).toHaveBeenCalledWith({ value: 3 }, jasmine.any(Object)); }); it('subscription object - should get last event when .startWithLast() is called - for wildcard', function () { spyOn(mock, 'callback'); events.setSeparator(mock.separator); events.registerEventNames(mock.eventNames); events.broadcast(mock.eventNames.SPECIFIC_ONE, { value: 1 }); events.broadcast(mock.eventNames.SPECIFIC_ONE, { value: 2 }); events.broadcast(mock.eventNames.SPECIFIC_ONE, { value: 3 }); events.broadcast(mock.eventNames.SPECIFIC_ONE, { value: 4 }); events.broadcast(mock.eventNames.SPECIFIC_ONE, { value: 5 }); var wildcard = events.subscribe(mock.eventNames.WILDCARD, mock.callback); wildcard.startWithLast(); expect(mock.callback).toHaveBeenCalledWith({ value: 5 }, jasmine.any(Object)); expect(mock.callback).toHaveBeenCalledTimes(1); wildcard.stop(); events.broadcast(mock.eventNames.SPECIFIC_ONE, { value: 1 }); events.broadcast(mock.eventNames.SPECIFIC_ONE, { value: 2 }); events.broadcast(mock.eventNames.SPECIFIC_ONE, { value: 3 }); wildcard.startWithLast(); expect(mock.callback).toHaveBeenCalledTimes(2); expect(mock.callback).toHaveBeenCalledWith({ value: 3 }, jasmine.any(Object)); }); it('subscription object - should get last event when .startWithLast() is called - for catchall', function () { spyOn(mock, 'callback'); events.setSeparator(mock.separator); events.registerEventNames(mock.eventNames); events.broadcast(mock.eventNames.SPECIFIC_ONE, { value: 1 }); events.broadcast(mock.eventNames.VARIOUS.ONE, { value: 2 }); events.broadcast(mock.eventNames.SPECIFIC_ONE, { value: 3 }); events.broadcast(mock.eventNames.SPECIFIC_TWO, { value: 4 }); events.broadcast(mock.eventNames.VARIOUS.TWO, { value: 5 }); var all = events.subscribe(mock.eventNames.CATCHALL, mock.callback); all.startWithLast(); expect(mock.callback).toHaveBeenCalledWith({ value: 5 }, jasmine.any(Object)); expect(mock.callback).toHaveBeenCalledTimes(1); all.stop(); events.broadcast(mock.eventNames.SPECIFIC_TWO, { value: 3 }); all.startWithLast(); expect(mock.callback).toHaveBeenCalledTimes(2); expect(mock.callback).toHaveBeenCalledWith({ value: 3 }, jasmine.any(Object)); }); it('subscription object - should disable subscription when .kill() was called', function () { spyOn(mock, 'callback'); events.setSeparator(mock.separator); events.registerEventNames(mock.eventNames); var all = events.subscribe(mock.eventNames.CATCHALL, mock.callback); all.start(); events.broadcast(mock.eventNames.SPECIFIC_ONE, { value: 1 }); events.broadcast(mock.eventNames.VARIOUS.ONE, { value: 2 }); all.kill(); expect(mock.callback).toHaveBeenCalledTimes(2); expect(function () { all.start(); }).toThrowError(ERRORS.SUB_WAS_KILLED_BEFORE); expect(function () { all.stop(); }).toThrowError(ERRORS.SUB_WAS_KILLED_BEFORE); expect(function () { all.startWithLast(); }).toThrowError(ERRORS.SUB_WAS_KILLED_BEFORE); expect(function () { all.startWithAll(); }).toThrowError(ERRORS.SUB_WAS_KILLED_BEFORE); expect(function () { all.kill(); }).toThrowError(ERRORS.SUB_WAS_KILLED_BEFORE); events.broadcast(mock.eventNames.VARIOUS.ONE, { value: 3 }); expect(mock.callback).toHaveBeenCalledTimes(2); }); it('subscription object - should throw when it gets started multiple times', function () { spyOn(mock, 'callback'); events.setSeparator(mock.separator); events.registerEventNames(mock.eventNames); var all = events.subscribe(mock.eventNames.CATCHALL, mock.callback); all.start(); events.broadcast(mock.eventNames.SPECIFIC_ONE, { value: 1 }); events.broadcast(mock.eventNames.VARIOUS.ONE, { value: 2 }); expect(mock.callback).toHaveBeenCalledTimes(2); expect(function () { all.start(); }).toThrowError(ERRORS.SUB_WAS_STARTED_BEFORE); expect(function () { all.startWithLast(); }).toThrowError(ERRORS.SUB_WAS_STARTED_BEFORE); expect(function () { all.startWithAll(); }).toThrowError(ERRORS.SUB_WAS_STARTED_BEFORE); events.broadcast(mock.eventNames.VARIOUS.ONE, { value: 3 }); expect(mock.callback).toHaveBeenCalledTimes(3); }); it('subscription object - should throw when it gets stopped multiple times', function () { spyOn(mock, 'callback'); events.setSeparator(mock.separator); events.registerEventNames(mock.eventNames); var all = events.subscribe(mock.eventNames.CATCHALL, mock.callback); all.start(); events.broadcast(mock.eventNames.SPECIFIC_ONE, { value: 1 }); events.broadcast(mock.eventNames.VARIOUS.ONE, { value: 2 }); expect(mock.callback).toHaveBeenCalledTimes(2); all.stop(); events.broadcast(mock.eventNames.SPECIFIC_ONE, { value: 3 }); expect(mock.callback).toHaveBeenCalledTimes(2); expect(function () { all.stop(); }).toThrowError(ERRORS.SUB_WAS_STOPPED_BEFORE); all.startWithLast(); events.broadcast(mock.eventNames.VARIOUS.ONE, { value: 4 }); expect(mock.callback).toHaveBeenCalledTimes(4); }); }); });