['@test The registered factory returned from resolve is the same factory each time'](assert) { let registry = new Registry(); let PostController = factory(); registry.register('controller:post', PostController); assert.deepEqual( registry.resolve('controller:post'), registry.resolve('controller:post'), 'The return of resolve is always the same' ); }
['@test A non-singleton instance is never cached'](assert) { let registry = new Registry(); let container = registry.container(); let PostView = factory(); registry.register('view:post', PostView, { singleton: false }); let postView1 = container.lookup('view:post'); let postView2 = container.lookup('view:post'); assert.ok(postView1 !== postView2, 'Non-singletons are not cached'); }
QUnit.test('Lazy injection validations are cached', function() { expect(1); let registry = new Registry(); let container = registry.container(); let Apple = factory(); let Orange = factory(); Apple.reopenClass({ _lazyInjections() { ok(true, 'should call lazy injection method'); return ['orange:main']; } }); registry.register('apple:main', Apple); registry.register('orange:main', Orange); container.lookup('apple:main'); container.lookup('apple:main'); });
QUnit.test('A factory with both type and individual injections', function() { let registry = new Registry(); let container = registry.container(); let PostController = factory(); let Store = factory(); let Router = factory(); registry.register('controller:post', PostController); registry.register('store:main', Store); registry.register('router:main', Router); registry.injection('controller:post', 'store', 'store:main'); registry.typeInjection('controller', 'router', 'router:main'); let postController = container.lookup('controller:post'); let store = container.lookup('store:main'); let router = container.lookup('router:main'); equal(postController.store, store); equal(postController.router, router); });
['@test Lazy injection validations are cached'](assert) { assert.expect(1); let registry = new Registry(); let container = registry.container(); let Apple = factory(); let Orange = factory(); Apple.reopenClass({ _lazyInjections: () => { assert.ok(true, 'should call lazy injection method'); return [{ specifier: 'orange:main' }]; }, }); registry.register('apple:main', Apple); registry.register('orange:main', Orange); container.lookup('apple:main'); container.lookup('apple:main'); }
QUnit.test('A non-singleton instance is never cached', function() { let registry = new Registry(); let container = registry.container(); let PostView = factory(); registry.register('view:post', PostView, { singleton: false }); let postView1 = container.lookup('view:post'); let postView2 = container.lookup('view:post'); ok(postView1 !== postView2, 'Non-singletons are not cached'); });
QUnit.test('A registered factory returns the same instance each time', function() { let registry = new Registry(); let container = registry.container(); let PostController = factory(); registry.register('controller:post', PostController); let postController = container.lookup('controller:post'); ok(postController instanceof PostController, 'The lookup is an instance of the factory'); equal(postController, container.lookup('controller:post')); });
['@test The registry respects the resolver hook for `has`'](assert) { let PostController = factory(); let resolver = { resolve(fullName) { if (fullName === 'controller:post') { return PostController; } } }; let registry = new Registry({ resolver }); assert.ok(registry.has('controller:post'), 'the `has` method uses the resolver hook'); }
['@test registry.container creates a container'](assert) { let registry = new Registry(); let PostController = factory(); registry.register('controller:post', PostController); let container = registry.container(); let postController = container.lookup('controller:post'); assert.ok( postController instanceof PostController, 'The lookup is an instance of the registered factory' ); }
['@test The registry can take a hook to resolve factories lazily'](assert) { let PostController = factory(); let resolver = { resolve(fullName) { if (fullName === 'controller:post') { return PostController; } } }; let registry = new Registry({ resolver }); assert.strictEqual(registry.resolve('controller:post'), PostController, 'The correct factory was provided'); }
['@test The registry normalizes names when resolving'](assert) { let registry = new Registry(); let PostController = factory(); registry.normalizeFullName = function() { return 'controller:post'; }; registry.register('controller:post', PostController); let type = registry.resolve('controller:normalized'); assert.strictEqual(type, PostController, 'Normalizes the name when resolving'); }
['@test `resolve` can be handled by a fallback registry'](assert) { let fallback = new Registry(); let registry = new Registry({ fallback: fallback }); let PostController = factory(); fallback.register('controller:post', PostController); let PostControllerFactory = registry.resolve('controller:post'); assert.ok(PostControllerFactory, 'factory is returned'); assert.ok(PostControllerFactory.create() instanceof PostController, 'The return of factory.create is an instance of PostController'); }
['@test The registry normalizes names when checking if the factory is registered'](assert) { let registry = new Registry(); let PostController = factory(); registry.normalizeFullName = function(fullName) { return fullName === 'controller:normalized' ? 'controller:post' : fullName; }; registry.register('controller:post', PostController); let isPresent = registry.has('controller:normalized'); assert.equal(isPresent, true, 'Normalizes the name when checking if the factory or instance is present'); }
QUnit.test('The registry respects the resolver hook for `has`', function() { let PostController = factory(); let resolver = { resolve(fullName) { if (fullName === 'controller:post') { return PostController; } } }; let registry = new Registry({ resolver }); ok(registry.has('controller:post'), 'the `has` method uses the resolver hook'); });
['@test registry.has should not accidentally cause injections on that factory to be run. (Mitigate merely on observing)']( assert ) { assert.expect(1); let registry = new Registry(); let FirstApple = factory('first'); let SecondApple = factory('second'); SecondApple.extend = function() { assert.ok( false, 'should not extend or touch the injected model, merely to inspect existence of another' ); }; registry.register('controller:apple', FirstApple); registry.register('controller:second-apple', SecondApple); registry.injection('controller:apple', 'badApple', 'controller:second-apple'); assert.ok(registry.has('controller:apple')); }
['@test The container normalizes names before resolving'](assert) { let registry = new Registry(); let container = registry.container(); let PostController = factory(); registry.normalizeFullName = function() { return 'controller:post'; }; registry.register('controller:post', PostController); let postController = container.lookup('controller:normalized'); assert.ok(postController instanceof PostController, 'Normalizes the name before resolving'); }
['@test #factoryFor instance have a common parent'](assert) { let registry = new Registry(); let container = registry.container(); let Component = factory(); registry.register('component:foo-bar', Component); let factoryManager1 = container.factoryFor('component:foo-bar'); let factoryManager2 = container.factoryFor('component:foo-bar'); let instance1 = factoryManager1.create({ foo: 'foo' }); let instance2 = factoryManager2.create({ bar: 'bar' }); assert.deepEqual(instance1.constructor, instance2.constructor); }
['@test `has` can be handled by a fallback registry'](assert) { let fallback = new Registry(); let registry = new Registry({ fallback: fallback }); let PostController = factory(); fallback.register('controller:post', PostController); assert.equal( registry.has('controller:post'), true, 'Fallback registry is checked for registration' ); }
['@test Destroying the container destroys any cached singletons'](assert) { let registry = new Registry(); let container = registry.container(); let PostController = factory(); let PostView = factory(); let template = function() {}; registry.register('controller:post', PostController); registry.register('view:post', PostView, { singleton: false }); registry.register('template:post', template, { instantiate: false }); registry.injection('controller:post', 'postView', 'view:post'); let postController = container.lookup('controller:post'); let postView = postController.postView; assert.ok(postView instanceof PostView, 'The non-singleton was injected'); container.destroy(); assert.ok(postController.isDestroyed, 'Singletons are destroyed'); assert.ok(!postView.isDestroyed, 'Non-singletons are not destroyed'); }
['@test A registered factory is returned from resolve'](assert) { let registry = new Registry(); let PostController = factory(); registry.register('controller:post', PostController); let PostControllerFactory = registry.resolve('controller:post'); assert.ok(PostControllerFactory, 'factory is returned'); assert.ok( PostControllerFactory.create() instanceof PostController, 'The return of factory.create is an instance of PostController' ); }
['@test The registry normalizes names when injecting'](assert) { let registry = new Registry(); let PostController = factory(); let user = { name: 'Stef' }; registry.normalize = function() { return 'controller:post'; }; registry.register('controller:post', PostController); registry.register('user:post', user, { instantiate: false }); registry.injection('controller:post', 'user', 'controller:normalized'); assert.deepEqual(registry.resolve('controller:post'), user, 'Normalizes the name when injecting'); }
['@test #factoryFor returns a cached factory manager for the same type'](assert) { let registry = new Registry(); let container = registry.container(); let Component = factory(); registry.register('component:foo-bar', Component); registry.register('component:baz-bar', Component); let factoryManager1 = container.factoryFor('component:foo-bar'); let factoryManager2 = container.factoryFor('component:foo-bar'); let factoryManager3 = container.factoryFor('component:baz-bar'); assert.equal(factoryManager1, factoryManager2, 'cache hit'); assert.notEqual(factoryManager1, factoryManager3, 'cache miss'); }
['@test The container normalizes names when looking factory up'](assert) { let registry = new Registry(); let container = registry.container(); let PostController = factory(); registry.normalizeFullName = function() { return 'controller:post'; }; registry.register('controller:post', PostController); let fact = container.factoryFor('controller:normalized'); let factInstance = fact.create(); assert.ok(factInstance instanceof PostController, 'Normalizes the name'); }
[`@test assert when calling factoryFor after destroy on a container`](assert) { let registry = new Registry(); let container = registry.container(); let Component = factory(); registry.register('component:foo-bar', Component); let instance = container.factoryFor('component:foo-bar'); assert.ok(instance, 'precond lookup successful'); this.runTask(() => { container.destroy(); }); expectAssertion(() => { container.factoryFor('component:foo-bar'); }); }
['@test A registered factory returns the same instance each time'](assert) { let registry = new Registry(); let container = registry.container(); let PostController = factory(); registry.register('controller:post', PostController); let postController = container.lookup('controller:post'); assert.ok( postController instanceof PostController, 'The lookup is an instance of the factory' ); assert.equal(postController, container.lookup('controller:post')); }
['@test A registered factory returns true for `has` if an item is registered'](assert) { let registry = new Registry(); let PostController = factory(); registry.register('controller:post', PostController); assert.equal( registry.has('controller:post'), true, 'The `has` method returned true for registered factories' ); assert.equal( registry.has('controller:posts'), false, 'The `has` method returned false for unregistered factories' ); }
QUnit.test('The container can use a registry hook to resolve factories lazily', function() { let registry = new Registry(); let container = registry.container(); let PostController = factory(); registry.resolver = { resolve(fullName) { if (fullName === 'controller:post') { return PostController; } } }; let postController = container.lookup('controller:post'); ok(postController instanceof PostController, 'The correct factory was provided'); });
['@test factory for non extendables (MODEL) resolves are cached'](assert) { let registry = new Registry(); let container = registry.container(); let PostController = factory(); let resolveWasCalled = []; registry.resolve = function(fullName) { resolveWasCalled.push(fullName); return PostController; }; assert.deepEqual(resolveWasCalled, []); container.factoryFor('model:post'); assert.deepEqual(resolveWasCalled, ['model:post']); container.factoryFor('model:post'); assert.deepEqual(resolveWasCalled, ['model:post']); }
QUnit.test('Factory resolves are cached', function() { let registry = new Registry(); let container = registry.container(); let PostController = factory(); let resolveWasCalled = []; registry.resolve = function(fullName) { resolveWasCalled.push(fullName); return PostController; }; deepEqual(resolveWasCalled, []); container.factoryFor('controller:post'); deepEqual(resolveWasCalled, ['controller:post']); container.factoryFor('controller:post'); deepEqual(resolveWasCalled, ['controller:post']); });
['@test The container can use a registry hook to resolve factories lazily'](assert) { let registry = new Registry(); let container = registry.container(); let PostController = factory(); registry.resolver = { resolve(fullName) { if (fullName === 'controller:post') { return PostController; } }, }; let postController = container.lookup('controller:post'); assert.ok(postController instanceof PostController, 'The correct factory was provided'); }