UNPKG

servicelocatorjs

Version:
454 lines (453 loc) 18 kB
console.log('\033[2J'); // // < Includes > // var ServiceLocator = require('../source/servicelocator.js'); var chai = require('chai'); var assert = chai.assert; // // < Config > // chai.config.includeStack = true; chai.config.showDiff = true; // // < Utilities > // function keys(hash) { return Object.keys(hash).sort(); } function objLength(hash) { return keys(hash).length; } function merge(array1, array2) { return array1.concat(array2).sort(); } function fresh() { locator = new ServiceLocator.Constructor(); } function pullName(service) { return service.name ? service.name : service.constructor.name; } // // < Initialization > // var locator = new ServiceLocator.Constructor; // Create mixin for services var mixin = { /** * Set in service object new property <_state> for further use * @param {*} value */ setState: function (value) { this._state = value; }, /** * Get <_state> property from service object * @return {*} */ getState: function () { return '_state' in this ? this._state : undefined; }, /** * Get service object name * @return {String} */ getName: function () { return 'name' in this ? this.name : 'Service has no name!'; } }; // Create constructors for services /** @constructor */ function ServiceOne() { this.name = 'ServiceOne'; // this is not required } /** @constructor */ function ServiceTwo() { this.name = 'ServiceTwo'; this.serviceFunction = function () { return 'Service number two function'; }; } /** * @param {*=} data * @constructor */ function ServiceThree(data) { // Service without <name> property this.data = data; } /** @constructor */ function ServiceFour() { this.name = 'ServiceFour'; } var serviceFour = new ServiceFour(); var services = [ ServiceOne, ServiceTwo, ServiceThree, ServiceFour ]; // // < Tests > // describe('Initialization', function () { beforeEach(function () { fresh(); }); it('Include', function () { assert.isObject(ServiceLocator, 'ServiceLocator must be instantiated'); assert.isFunction(ServiceLocator.Constructor, 'Constructor must be function'); }); it('Instantiate', function () { assert.isObject(new ServiceLocator.Constructor, 'Constructor must create new object'); }); }); describe('Mixins', function () { beforeEach(function () { fresh(); }); it('setMixin()', function () { assert.isObject(locator.setMixin(), 'No service locator returned'); assert.lengthOf(keys(locator.getMixin()), 0, 'Mixins should be empty'); assert.isObject(locator.setMixin('DUMMY VALUE')); assert.lengthOf(keys(locator.getMixin()), 0, 'Mixins should be empty'); locator.setMixin(mixin); assert.lengthOf(keys(locator.getMixin()), Object.keys(mixin).length, 'Mixins not installed correctly'); }); it('getMixin()', function () { assert.isObject(locator.getMixin(), 'Empty object expected'); assert.lengthOf(keys(locator.setMixin(mixin).getMixin()), keys(mixin).length, 'Mixins not installed correctly'); assert.property(locator.getMixin(), 'setState', 'Expected parameter not found'); assert.property(locator.getMixin(), 'getState', 'Expected parameter not found'); assert.property(locator.getMixin(), 'getName', 'Expected parameter not found'); }); it('mixin()', function () { assert.lengthOf(keys(locator.mixin()), 0, 'Mixins should be empty'); assert.isObject(locator.mixin('DUMMY VALUE')); assert.lengthOf(keys(locator.mixin()), 0, 'Mixins should be empty'); locator.mixin(mixin); assert.lengthOf(keys(locator.mixin()), objLength(mixin), 'Mixins not installed correctly'); assert.property(locator.mixin(), 'setState', 'Expected parameter not found'); assert.property(locator.mixin(), 'getState', 'Expected parameter not found'); assert.property(locator.mixin(), 'getName', 'Expected parameter not found'); }); }); describe('Services', function () { beforeEach(function () { fresh(); }); describe('Registration', function () { beforeEach(function () { fresh(); }); it('register() - no arguments', function () { assert.isFalse(locator.register(), 'No parameters at all. Result must be falsy'); }); it('register() - wrong arguments', function () { assert.isFalse(locator.register(1, new Function), 'Service name must be string only. Result must be falsy'); assert.isFalse(locator.register('serviceName', ''), 'Service object must be function or object. Result must be falsy'); }); it('register(name, ConstructorFunction) - pass name and constructor function', function () { assert.isTrue(locator.register(ServiceOne.name, ServiceOne), 'Service registration failed'); assert.isFalse(locator.register(ServiceOne.name), 'Successful registration of already registered module'); assert.include(locator.getAllInstantiate(), ServiceOne.name, 'Service not included'); assert.isTrue(locator.isRegistered(ServiceOne.name), 'Service not registered correctly'); assert.isTrue(locator.isInstantiated(ServiceOne.name), 'Service not instantiated'); }); it('register(name, object) - pass name and object', function () { assert.isTrue(locator.register(ServiceFour.name + '_1', serviceFour), 'Prepared object not registered'); assert.isTrue(locator.isInstantiated(serviceFour.name + '_1'), 'Pass prepared object. Must be instantiated'); assert.isTrue(locator.register(ServiceFour.name + '_2', serviceFour, false), 'Prepared object not registered'); assert.isTrue(locator.isInstantiated(serviceFour.name + '_2'), 'Pass prepared object. Must be instantiated'); }); it('register(serviceName, ConstructorFunction, boolFalse, argumentValue)', function () { assert.isTrue(locator.register(ServiceThree.name, ServiceThree, false, 'argValue1'), 'Service registration failed'); assert.isFalse(locator.isInstantiated(ServiceThree.name), 'Service is instantiated'); assert.isTrue(locator.instantiate(ServiceThree.name), 'Waiting for object from instance'); assert.property(locator.get(ServiceThree.name), 'data', 'Service should have data property'); assert.isString(locator.get(ServiceThree.name).data, 'Service parameter should be string'); assert.equal(locator.get(ServiceThree.name).data, 'argValue1', 'Service value is different'); }); it('register(serviceName, ConstructorFunction, boolTrue, argumentValue)', function () { assert.isTrue(locator.register(ServiceThree.name, ServiceThree, true, 'argValue1'), 'Service registration failed'); assert.isTrue(locator.isInstantiated(ServiceThree.name), 'Service is instantiated'); assert.property(locator.get(ServiceThree.name), 'data', 'Service should have data property'); assert.isString(locator.get(ServiceThree.name).data, 'Service parameter should be string'); assert.equal(locator.get(ServiceThree.name).data, 'argValue1', 'Service value is different'); }); }); describe('Get service instance', function () { beforeEach(function () { fresh(); }); it('get() - without arguments in registration', function () { assert.isTrue(locator.register(ServiceOne.name, ServiceOne), 'Service registration failed'); assert.isObject(locator.get(ServiceOne.name), 'Service not instantiated'); assert.deepEqual(locator.get(ServiceOne.name), {__mixins: ['id'], id: 'ServiceOne', name: 'ServiceOne'}, 'Expected different service structure'); }); it('get() - with instantiation in registration', function () { assert.isTrue(locator.register(ServiceOne.name, ServiceOne, true), 'Service registration failed'); assert.isObject(locator.get(ServiceOne.name), 'Service not instantiated'); assert.deepEqual(locator.get(ServiceOne.name), {__mixins: ['id'], id: 'ServiceOne', name: 'ServiceOne'}, 'Expected different service structure'); }); it('get() - with lazy instantiation in registration', function () { assert.isTrue(locator.register(ServiceOne.name, ServiceOne, false), 'Service registration failed'); assert.isObject(locator.get(ServiceOne.name), 'Service not instantiated'); assert.deepEqual(locator.get(ServiceOne.name), {__mixins: ['id'], id: 'ServiceOne', name: 'ServiceOne'}, 'Expected different service structure'); }); }); describe('Instance manipulation', function () { beforeEach(function () { fresh(); }); it('instantiate()', function () { assert.isTrue(locator.register(ServiceOne.name, ServiceOne), 'Service registration failed'); assert.isFalse(locator.instantiate(), 'No argument passed'); assert.isFalse(locator.instantiate(ServiceTwo.name), 'Successful instantiation of unregistered service'); assert.isTrue(locator.instantiate(ServiceOne.name), 'Expect instance'); }); it('instantiateAll() - no filter', function () { assert.isTrue(locator.register(ServiceOne.name, ServiceOne, false), 'Service registration failed: ' + ServiceOne.name); assert.isTrue(locator.register(ServiceTwo.name, ServiceTwo, false), 'Service registration failed: ' + ServiceTwo.name); assert.isTrue(locator.register(ServiceThree.name, ServiceThree, false), 'Service registration failed: ' + ServiceThree.name); assert.isTrue(locator.register(ServiceFour.name, ServiceFour, false), 'Service registration failed: ' + ServiceFour.name); assert.lengthOf(locator.getAllInstantiate(), 0, 'No services should be instantiated'); assert.lengthOf(locator.instantiateAll(), 4, 'Not instantiated correctly'); }); it('instantiateAll() - with filter', function () { assert.isTrue(locator.register(ServiceOne.name, ServiceOne, false), 'Service registration failed: ' + ServiceOne.name); assert.isTrue(locator.register(ServiceTwo.name, ServiceTwo, false), 'Service registration failed: ' + ServiceTwo.name); assert.isTrue(locator.register(ServiceThree.name, ServiceThree, false), 'Service registration failed: ' + ServiceThree.name); assert.isTrue(locator.register(ServiceFour.name, ServiceFour, false), 'Service registration failed: ' + ServiceFour.name); assert.lengthOf(locator.getAllInstantiate(), 0, 'No services should be instantiated'); assert.lengthOf(locator.instantiateAll(function () { return false; }), 0, 'Not instantiated correctly'); assert.lengthOf(locator.instantiateAll(function (serviceName) { return !!((serviceName === ServiceOne.name) || (serviceName === ServiceTwo.name)); }), 2, 'Not instantiated correctly'); }); it('removeInstance()', function () { locator.printLog(true); assert.isTrue(locator.register(ServiceOne.name, ServiceOne, true), 'Service instantiation failed: ' + ServiceOne.name); assert.isTrue(locator.register(ServiceTwo.name, ServiceTwo, true), 'Service instantiation failed: ' + ServiceTwo.name); assert.isTrue(locator.register(ServiceThree.name, ServiceThree, true), 'Service instantiation failed: ' + ServiceThree.name); assert.isTrue(locator.register(ServiceFour.name, ServiceFour, true), 'Service instantiation failed: ' + ServiceFour.name); assert.lengthOf(locator.getAllInstantiate(), 4); assert.isTrue(locator.removeInstance(ServiceOne.name)); assert.lengthOf(locator.getAllInstantiate(), 3); assert.isTrue(locator.removeInstance(ServiceTwo.name)); assert.lengthOf(locator.getAllInstantiate(), 2); assert.isTrue(locator.removeInstance(ServiceThree.name)); assert.lengthOf(locator.getAllInstantiate(), 1); assert.isTrue(locator.removeInstance(ServiceFour.name)); assert.lengthOf(locator.getAllInstantiate(), 0); }); }); describe('De-registration', function () { beforeEach(function () { fresh(); }); it('unRegister() - without arguments', function () { assert.isTrue(locator.register(ServiceOne.name, ServiceOne, true), 'Service registered incorrectly'); assert.isTrue(locator.register(ServiceTwo.name, ServiceTwo, false), 'Service registered incorrectly'); assert.lengthOf(locator.getAllInstantiate(), 1, 'Expect services registered'); assert.deepEqual(locator.unRegister(ServiceOne.name), {name: 'ServiceOne', __mixins: ['id'], id: 'ServiceOne'}, 'Service has unexpected' ); assert.isFalse(locator.isRegistered(ServiceOne.name)); assert.isNull(locator.unRegister(ServiceTwo.name)); assert.isFalse(locator.isRegistered(ServiceTwo.name)); }); it('unRegister() - don\'t remove mixins', function () { assert.isObject(locator.mixin(mixin), 'Mixins not applied'); assert.deepEqual(locator.getMixin(), mixin, 'Mixins not applied correctly'); assert.isTrue(locator.register(ServiceOne.name, ServiceOne, true), 'Service registered incorrectly'); assert.isTrue(locator.register(ServiceTwo.name, ServiceTwo, false), 'Service registered incorrectly'); assert.lengthOf(locator.getAllInstantiate(), 1, 'Expect services registered'); assert.includeMembers( keys(locator.get(ServiceOne.name)), merge(keys(mixin), ['__mixins', 'id', 'name']), 'Different set of members' ); assert.deepEqual( keys(locator.unRegister(ServiceOne.name)), merge(keys(mixin), ['__mixins', 'id', 'name']), 'Different set of members' ); assert.isFalse(locator.isRegistered(ServiceOne.name)); assert.isNull(locator.unRegister(ServiceTwo.name)); assert.isFalse(locator.isRegistered(ServiceTwo.name)); }); it('unRegister() - remove mixins', function () { assert.isObject(locator.mixin(mixin), 'Mixins not applied'); assert.deepEqual(locator.getMixin(), mixin, 'Mixins not applied correctly'); assert.isTrue(locator.register(ServiceOne.name, ServiceOne, true), 'Service registered incorrectly'); assert.isTrue(locator.register(ServiceTwo.name, ServiceTwo, false), 'Service registered incorrectly'); assert.lengthOf(locator.getAllInstantiate(), 1, 'Expect services registered'); assert.deepEqual( keys(locator.get(ServiceOne.name)), merge(keys(mixin), ['__mixins', 'id', 'name']), 'Different set of members' ); assert.deepEqual(keys(locator.unRegister(ServiceOne.name, true)), ['name'], 'Different set of members after un-registration' ); assert.isFalse(locator.isRegistered(ServiceOne.name)); assert.isNull(locator.unRegister(ServiceTwo.name)); assert.isFalse(locator.isRegistered(ServiceTwo.name)); }); it('unRegisterAll() - without arguments', function () { assert.isObject(locator.mixin(mixin)); services.forEach(function (service) { assert.isTrue(locator.register(pullName(service), service)); }); var unregistered = locator.unRegisterAll(); assert.isObject(unregistered); var mix = merge(keys(mixin), ['__mixins', 'id']); services.forEach(function (service) { var name = pullName(service); assert.property(unregistered, name); assert.includeMembers(keys(unregistered[name]), mix); }); }); it('unRegisterAll() - don\'t remove mixins', function () { assert.isObject(locator.mixin(mixin)); services.forEach(function (service) { assert.isTrue(locator.register(pullName(service), service)); }); var unregistered = locator.unRegisterAll(false); assert.isObject(unregistered); var mix = merge(keys(mixin), ['__mixins', 'id']); services.forEach(function (service) { var name = pullName(service); assert.property(unregistered, name); assert.includeMembers(keys(unregistered[name]), mix); }); }); it('unRegisterAll() - remove mixins', function () { assert.isObject(locator.mixin(mixin)); services.forEach(function (service) { assert.isTrue(locator.register(pullName(service), service)); }); var unregistered = locator.unRegisterAll(true); assert.isObject(unregistered); services.forEach(function (service) { var name = pullName(service); assert.property(unregistered, name); keys(mixin).forEach(function (propName) { assert.notProperty(unregistered[name], propName); }); }); }); }); describe('State check', function () { beforeEach(function () { fresh(); }); it('isRegistered()', function () { assert.isFalse(locator.isRegistered(), 'Non existent service'); assert.isFalse(locator.isRegistered(ServiceOne.name), 'Non existent service'); assert.isTrue(locator.register(ServiceOne.name, ServiceOne)); assert.isTrue(locator.isRegistered(ServiceOne.name), 'Service not registered correctly'); }); it('isInstantiated()', function () { assert.isTrue(locator.register(ServiceOne.name, ServiceOne), ServiceOne.name); assert.isTrue(locator.isInstantiated(ServiceOne.name), ServiceOne.name); assert.isTrue(locator.register(ServiceTwo.name, ServiceTwo, false), ServiceTwo.name); assert.isFalse(locator.isInstantiated(ServiceTwo.name), ServiceTwo.name); assert.isTrue(locator.register(ServiceThree.name, ServiceThree, true), ServiceThree.name); assert.isTrue(locator.isInstantiated(ServiceThree.name), ServiceThree.name); }); }); });