UNPKG

ember-app-scheduler

Version:

Ember addon to schedule work at different phases of app life cycle.

1,465 lines (1,089 loc) 2.69 MB
(function() { /*! * @overview Ember - JavaScript Application Framework * @copyright Copyright 2011-2017 Tilde Inc. and contributors * Portions Copyright 2006-2011 Strobe Inc. * Portions Copyright 2008-2011 Apple Inc. All rights reserved. * @license Licensed under MIT license * See https://raw.github.com/emberjs/ember.js/master/LICENSE * @version 2.15.0 */ var enifed, requireModule, Ember; var mainContext = this; // Used in ember-environment/lib/global.js (function() { var isNode = typeof window === 'undefined' && typeof process !== 'undefined' && {}.toString.call(process) === '[object process]'; if (!isNode) { Ember = this.Ember = this.Ember || {}; } if (typeof Ember === 'undefined') { Ember = {}; } if (typeof Ember.__loader === 'undefined') { var registry = {}; var seen = {}; enifed = function(name, deps, callback) { var value = { }; if (!callback) { value.deps = []; value.callback = deps; } else { value.deps = deps; value.callback = callback; } registry[name] = value; }; requireModule = function(name) { return internalRequire(name, null); }; // setup `require` module requireModule['default'] = requireModule; requireModule.has = function registryHas(moduleName) { return !!registry[moduleName] || !!registry[moduleName + '/index']; }; function missingModule(name, referrerName) { if (referrerName) { throw new Error('Could not find module ' + name + ' required by: ' + referrerName); } else { throw new Error('Could not find module ' + name); } } function internalRequire(_name, referrerName) { var name = _name; var mod = registry[name]; if (!mod) { name = name + '/index'; mod = registry[name]; } var exports = seen[name]; if (exports !== undefined) { return exports; } exports = seen[name] = {}; if (!mod) { missingModule(_name, referrerName); } var deps = mod.deps; var callback = mod.callback; var reified = new Array(deps.length); for (var i = 0; i < deps.length; i++) { if (deps[i] === 'exports') { reified[i] = exports; } else if (deps[i] === 'require') { reified[i] = requireModule; } else { reified[i] = internalRequire(deps[i], name); } } callback.apply(this, reified); return exports; } requireModule._eak_seen = registry; Ember.__loader = { define: enifed, require: requireModule, registry: registry }; } else { enifed = Ember.__loader.define; requireModule = Ember.__loader.require; } })(); enifed('container/tests/container_test', ['ember-utils', 'ember-environment', 'ember-metal', 'container', 'internal-test-helpers'], function (_emberUtils, _emberEnvironment, _emberMetal, _container, _internalTestHelpers) { 'use strict'; QUnit.module('Container'); QUnit.test('A registered factory returns the same instance each time', function () { var registry = new _container.Registry(); var container = registry.container(); var PostController = (0, _internalTestHelpers.factory)(); registry.register('controller:post', PostController); var postController = container.lookup('controller:post'); ok(postController instanceof PostController, 'The lookup is an instance of the factory'); equal(postController, container.lookup('controller:post')); }); QUnit.test('uses create time injections if factory has no extend', function () { var registry = new _container.Registry(); var container = registry.container(); var AppleController = (0, _internalTestHelpers.factory)(); var PostController = (0, _internalTestHelpers.factory)(); PostController.extend = undefined; // remove extend registry.register('controller:apple', AppleController); registry.register('controller:post', PostController); registry.injection('controller:post', 'apple', 'controller:apple'); var postController = container.lookup('controller:post'); ok(postController.apple instanceof AppleController, 'instance receives an apple of instance AppleController'); }); QUnit.test('A registered factory returns a fresh instance if singleton: false is passed as an option', function () { var registry = new _container.Registry(); var container = registry.container(); var PostController = (0, _internalTestHelpers.factory)(); registry.register('controller:post', PostController); var postController1 = container.lookup('controller:post'); var postController2 = container.lookup('controller:post', { singleton: false }); var postController3 = container.lookup('controller:post', { singleton: false }); var postController4 = container.lookup('controller:post'); equal(postController1.toString(), postController4.toString(), 'Singleton factories looked up normally return the same value'); notEqual(postController1.toString(), postController2.toString(), 'Singleton factories are not equal to factories looked up with singleton: false'); notEqual(postController2.toString(), postController3.toString(), 'Two factories looked up with singleton: false are not equal'); notEqual(postController3.toString(), postController4.toString(), 'A singleton factory looked up after a factory called with singleton: false is not equal'); ok(postController1 instanceof PostController, 'All instances are instances of the registered factory'); ok(postController2 instanceof PostController, 'All instances are instances of the registered factory'); ok(postController3 instanceof PostController, 'All instances are instances of the registered factory'); ok(postController4 instanceof PostController, 'All instances are instances of the registered factory'); }); QUnit.test('A factory type with a registered injection\'s instances receive that injection', function () { var registry = new _container.Registry(); var container = registry.container(); var PostController = (0, _internalTestHelpers.factory)(); var Store = (0, _internalTestHelpers.factory)(); registry.register('controller:post', PostController); registry.register('store:main', Store); registry.typeInjection('controller', 'store', 'store:main'); var postController = container.lookup('controller:post'); var store = container.lookup('store:main'); equal(postController.store, store); }); QUnit.test('An individual factory with a registered injection receives the injection', function () { var registry = new _container.Registry(); var container = registry.container(); var PostController = (0, _internalTestHelpers.factory)(); var Store = (0, _internalTestHelpers.factory)(); registry.register('controller:post', PostController); registry.register('store:main', Store); registry.injection('controller:post', 'store', 'store:main'); var postController = container.lookup('controller:post'); var store = container.lookup('store:main'); equal(postController.store, store, 'has the correct store injected'); }); QUnit.test('A factory with both type and individual injections', function () { var registry = new _container.Registry(); var container = registry.container(); var PostController = (0, _internalTestHelpers.factory)(); var Store = (0, _internalTestHelpers.factory)(); var Router = (0, _internalTestHelpers.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'); var postController = container.lookup('controller:post'); var store = container.lookup('store:main'); var router = container.lookup('router:main'); equal(postController.store, store); equal(postController.router, router); }); QUnit.test('A non-singleton instance is never cached', function () { var registry = new _container.Registry(); var container = registry.container(); var PostView = (0, _internalTestHelpers.factory)(); registry.register('view:post', PostView, { singleton: false }); var postView1 = container.lookup('view:post'); var postView2 = container.lookup('view:post'); ok(postView1 !== postView2, 'Non-singletons are not cached'); }); QUnit.test('A non-instantiated property is not instantiated', function () { var registry = new _container.Registry(); var container = registry.container(); var template = function () {}; registry.register('template:foo', template, { instantiate: false }); equal(container.lookup('template:foo'), template); }); QUnit.test('A failed lookup returns undefined', function () { var registry = new _container.Registry(); var container = registry.container(); equal(container.lookup('doesnot:exist'), undefined); }); QUnit.test('An invalid factory throws an error', function () { var registry = new _container.Registry(); var container = registry.container(); registry.register('controller:foo', {}); throws(function () { container.lookup('controller:foo'); }, /Failed to create an instance of \'controller:foo\'/); }); QUnit.test('Injecting a failed lookup raises an error', function () { var registry = new _container.Registry(); var container = registry.container(); var fooInstance = {}; var fooFactory = {}; registry.register('model:foo', { create: function () { return fooInstance; }, extend: function () { return fooFactory; } }); registry.injection('model:foo', 'store', 'store:main'); throws(function () { container.lookup('model:foo'); }); }); QUnit.test('Injecting a falsy value does not raise an error', function () { var registry = new _container.Registry(); var container = registry.container(); var ApplicationController = (0, _internalTestHelpers.factory)(); registry.register('controller:application', ApplicationController); registry.register('user:current', null, { instantiate: false }); registry.injection('controller:application', 'currentUser', 'user:current'); strictEqual(container.lookup('controller:application').currentUser, null); }); QUnit.test('The container returns same value each time even if the value is falsy', function () { var registry = new _container.Registry(); var container = registry.container(); registry.register('falsy:value', null, { instantiate: false }); strictEqual(container.lookup('falsy:value'), container.lookup('falsy:value')); }); QUnit.test('Destroying the container destroys any cached singletons', function () { var registry = new _container.Registry(); var container = registry.container(); var PostController = (0, _internalTestHelpers.factory)(); var PostView = (0, _internalTestHelpers.factory)(); registry.register('controller:post', PostController); registry.register('view:post', PostView, { singleton: false }); registry.register('template:post', function () {}, { instantiate: false }); registry.injection('controller:post', 'postView', 'view:post'); var postController = container.lookup('controller:post'); var postView = postController.postView; ok(postView instanceof PostView, 'The non-singleton was injected'); container.destroy(); ok(postController.isDestroyed, 'Singletons are destroyed'); ok(!postView.isDestroyed, 'Non-singletons are not destroyed'); }); QUnit.test('The container can use a registry hook to resolve factories lazily', function () { var registry = new _container.Registry(); var container = registry.container(); var PostController = (0, _internalTestHelpers.factory)(); registry.resolver = { resolve: function (fullName) { if (fullName === 'controller:post') { return PostController; } } }; var postController = container.lookup('controller:post'); ok(postController instanceof PostController, 'The correct factory was provided'); }); QUnit.test('The container normalizes names before resolving', function () { var registry = new _container.Registry(); var container = registry.container(); var PostController = (0, _internalTestHelpers.factory)(); registry.normalizeFullName = function () { return 'controller:post'; }; registry.register('controller:post', PostController); var postController = container.lookup('controller:normalized'); ok(postController instanceof PostController, 'Normalizes the name before resolving'); }); QUnit.test('The container normalizes names when looking factory up', function () { var registry = new _container.Registry(); var container = registry.container(); var PostController = (0, _internalTestHelpers.factory)(); registry.normalizeFullName = function () { return 'controller:post'; }; registry.register('controller:post', PostController); var fact = container.factoryFor('controller:normalized'); var factInstance = fact.create(); ok(factInstance instanceof PostController, 'Normalizes the name'); }); QUnit.test('Options can be registered that should be applied to a given factory', function () { var registry = new _container.Registry(); var container = registry.container(); var PostView = (0, _internalTestHelpers.factory)(); registry.resolver = { resolve: function (fullName) { if (fullName === 'view:post') { return PostView; } } }; registry.options('view:post', { instantiate: true, singleton: false }); var postView1 = container.lookup('view:post'); var postView2 = container.lookup('view:post'); ok(postView1 instanceof PostView, 'The correct factory was provided'); ok(postView2 instanceof PostView, 'The correct factory was provided'); ok(postView1 !== postView2, 'The two lookups are different'); }); QUnit.test('Options can be registered that should be applied to all factories for a given type', function () { var registry = new _container.Registry(); var container = registry.container(); var PostView = (0, _internalTestHelpers.factory)(); registry.resolver = { resolve: function (fullName) { if (fullName === 'view:post') { return PostView; } } }; registry.optionsForType('view', { singleton: false }); var postView1 = container.lookup('view:post'); var postView2 = container.lookup('view:post'); ok(postView1 instanceof PostView, 'The correct factory was provided'); ok(postView2 instanceof PostView, 'The correct factory was provided'); ok(postView1 !== postView2, 'The two lookups are different'); }); QUnit.test('An injected non-singleton instance is never cached', function () { var registry = new _container.Registry(); var container = registry.container(); var PostView = (0, _internalTestHelpers.factory)(); var PostViewHelper = (0, _internalTestHelpers.factory)(); registry.register('view:post', PostView, { singleton: false }); registry.register('view_helper:post', PostViewHelper, { singleton: false }); registry.injection('view:post', 'viewHelper', 'view_helper:post'); var postView1 = container.lookup('view:post'); var postView2 = container.lookup('view:post'); ok(postView1.viewHelper !== postView2.viewHelper, 'Injected non-singletons are not cached'); }); QUnit.test('Factory resolves are cached', function () { var registry = new _container.Registry(); var container = registry.container(); var PostController = (0, _internalTestHelpers.factory)(); var 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']); }); QUnit.test('factory for non extendables (MODEL) resolves are cached', function () { var registry = new _container.Registry(); var container = registry.container(); var PostController = (0, _internalTestHelpers.factory)(); var resolveWasCalled = []; registry.resolve = function (fullName) { resolveWasCalled.push(fullName); return PostController; }; deepEqual(resolveWasCalled, []); container.factoryFor('model:post'); deepEqual(resolveWasCalled, ['model:post']); container.factoryFor('model:post'); deepEqual(resolveWasCalled, ['model:post']); }); QUnit.test('factory for non extendables resolves are cached', function () { var registry = new _container.Registry(); var container = registry.container(); var PostController = {}; var resolveWasCalled = []; registry.resolve = function (fullName) { resolveWasCalled.push(fullName); return PostController; }; deepEqual(resolveWasCalled, []); container.factoryFor('foo:post'); deepEqual(resolveWasCalled, ['foo:post']); container.factoryFor('foo:post'); deepEqual(resolveWasCalled, ['foo:post']); }); QUnit.test('A factory\'s lazy injections are validated when first instantiated', function () { var registry = new _container.Registry(); var container = registry.container(); var Apple = (0, _internalTestHelpers.factory)(); var Orange = (0, _internalTestHelpers.factory)(); Apple.reopenClass({ _lazyInjections: function () { return ['orange:main', 'banana:main']; } }); registry.register('apple:main', Apple); registry.register('orange:main', Orange); throws(function () { container.lookup('apple:main'); }, /Attempting to inject an unknown injection: 'banana:main'/); }); QUnit.test('Lazy injection validations are cached', function () { expect(1); var registry = new _container.Registry(); var container = registry.container(); var Apple = (0, _internalTestHelpers.factory)(); var Orange = (0, _internalTestHelpers.factory)(); Apple.reopenClass({ _lazyInjections: function () { 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('An object with its owner pre-set should be returned from ownerInjection', function () { var owner = {}; var registry = new _container.Registry(); var container = registry.container({ owner: owner }); var result = container.ownerInjection(); equal(result[_emberUtils.OWNER], owner, 'owner is properly included'); }); QUnit.test('lookup passes options through to expandlocallookup', function (assert) { var registry = new _container.Registry(); var container = registry.container(); var PostController = (0, _internalTestHelpers.factory)(); registry.register('controller:post', PostController); registry.expandLocalLookup = function (fullName, options) { assert.ok(true, 'expandLocalLookup was called'); assert.equal(fullName, 'foo:bar'); assert.deepEqual(options, { source: 'baz:qux' }); return 'controller:post'; }; var PostControllerLookupResult = container.lookup('foo:bar', { source: 'baz:qux' }); assert.ok(PostControllerLookupResult instanceof PostController); }); QUnit.test('#factoryFor class is registered class', function (assert) { var registry = new _container.Registry(); var container = registry.container(); var Component = (0, _internalTestHelpers.factory)(); registry.register('component:foo-bar', Component); var factoryManager = container.factoryFor('component:foo-bar'); assert.deepEqual(factoryManager.class, Component, 'No double extend'); }); QUnit.test('#factoryFor must supply a fullname', function (assert) { var registry = new _container.Registry(); var container = registry.container(); assert.throws(function () { container.factoryFor('chad-bar'); }, /Invalid Fullname, expected: 'type:name' got: chad-bar/); }); QUnit.test('#factoryFor returns a factory manager', function (assert) { var registry = new _container.Registry(); var container = registry.container(); var Component = (0, _internalTestHelpers.factory)(); registry.register('component:foo-bar', Component); var factoryManager = container.factoryFor('component:foo-bar'); assert.ok(factoryManager.create); assert.ok(factoryManager.class); }); QUnit.test('#factoryFor returns a cached factory manager for the same type', function (assert) { var registry = new _container.Registry(); var container = registry.container(); var Component = (0, _internalTestHelpers.factory)(); registry.register('component:foo-bar', Component); registry.register('component:baz-bar', Component); var factoryManager1 = container.factoryFor('component:foo-bar'); var factoryManager2 = container.factoryFor('component:foo-bar'); var factoryManager3 = container.factoryFor('component:baz-bar'); assert.equal(factoryManager1, factoryManager2, 'cache hit'); assert.notEqual(factoryManager1, factoryManager3, 'cache miss'); }); QUnit.test('#factoryFor class returns the factory function', function (assert) { var registry = new _container.Registry(); var container = registry.container(); var Component = (0, _internalTestHelpers.factory)(); registry.register('component:foo-bar', Component); var factoryManager = container.factoryFor('component:foo-bar'); assert.deepEqual(factoryManager.class, Component, 'No double extend'); }); QUnit.test('#factoryFor instance have a common parent', function (assert) { var registry = new _container.Registry(); var container = registry.container(); var Component = (0, _internalTestHelpers.factory)(); registry.register('component:foo-bar', Component); var factoryManager1 = container.factoryFor('component:foo-bar'); var factoryManager2 = container.factoryFor('component:foo-bar'); var instance1 = factoryManager1.create({ foo: 'foo' }); var instance2 = factoryManager2.create({ bar: 'bar' }); assert.deepEqual(instance1.constructor, instance2.constructor); }); QUnit.test('#factoryFor created instances come with instance injections', function (assert) { var registry = new _container.Registry(); var container = registry.container(); var Component = (0, _internalTestHelpers.factory)(); var Ajax = (0, _internalTestHelpers.factory)(); registry.register('component:foo-bar', Component); registry.register('util:ajax', Ajax); registry.injection('component:foo-bar', 'ajax', 'util:ajax'); var componentFactory = container.factoryFor('component:foo-bar'); var component = componentFactory.create(); assert.ok(component.ajax); assert.ok(component.ajax instanceof Ajax); }); QUnit.test('#factoryFor options passed to create clobber injections', function (assert) { var registry = new _container.Registry(); var container = registry.container(); var Component = (0, _internalTestHelpers.factory)(); var Ajax = (0, _internalTestHelpers.factory)(); registry.register('component:foo-bar', Component); registry.register('util:ajax', Ajax); registry.injection('component:foo-bar', 'ajax', 'util:ajax'); var componentFactory = container.factoryFor('component:foo-bar'); var instrance = componentFactory.create({ ajax: 'fetch' }); assert.equal(instrance.ajax, 'fetch'); }); QUnit.test('#factoryFor does not add properties to the object being instantiated when _initFactory is present', function (assert) { var registry = new _container.Registry(); var container = registry.container(); var Component = function () { function Component() {} Component._initFactory = function (_factory) {}; Component.create = function (options) { var instance = new this(); (0, _emberUtils.assign)(instance, options); return instance; }; return Component; }(); registry.register('component:foo-bar', Component); var componentFactory = container.factoryFor('component:foo-bar'); var instance = componentFactory.create(); // note: _guid and isDestroyed are being set in the `factory` constructor // not via registry/container shenanigans assert.deepEqual(Object.keys(instance), []); }); // this is skipped until templates and the glimmer environment do not require `OWNER` to be // passed in as constructor args QUnit.skip('#factoryFor does not add properties to the object being instantiated', function (assert) { var registry = new _container.Registry(); var container = registry.container(); var Component = function () { function Component() {} Component.create = function (options) { var instance = new this(); (0, _emberUtils.assign)(instance, options); return instance; }; return Component; }(); registry.register('component:foo-bar', Component); var componentFactory = container.factoryFor('component:foo-bar'); var instance = componentFactory.create(); // note: _guid and isDestroyed are being set in the `factory` constructor // not via registry/container shenanigans assert.deepEqual(Object.keys(instance), []); }); }); enifed('container/tests/owner_test', ['ember-utils'], function (_emberUtils) { 'use strict'; QUnit.module('Owner', {}); QUnit.test('An owner can be set with `setOwner` and retrieved with `getOwner`', function () { var owner = {}; var obj = {}; strictEqual((0, _emberUtils.getOwner)(obj), undefined, 'owner has not been set'); (0, _emberUtils.setOwner)(obj, owner); strictEqual((0, _emberUtils.getOwner)(obj), owner, 'owner has been set'); strictEqual(obj[_emberUtils.OWNER], owner, 'owner has been set to the OWNER symbol'); }); }); enifed('container/tests/registry_test', ['container', 'internal-test-helpers'], function (_container, _internalTestHelpers) { 'use strict'; QUnit.module('Registry'); QUnit.test('A registered factory is returned from resolve', function () { var registry = new _container.Registry(); var PostController = (0, _internalTestHelpers.factory)(); registry.register('controller:post', PostController); var PostControllerFactory = registry.resolve('controller:post'); ok(PostControllerFactory, 'factory is returned'); ok(PostControllerFactory.create() instanceof PostController, 'The return of factory.create is an instance of PostController'); }); QUnit.test('The registered factory returned from resolve is the same factory each time', function () { var registry = new _container.Registry(); var PostController = (0, _internalTestHelpers.factory)(); registry.register('controller:post', PostController); deepEqual(registry.resolve('controller:post'), registry.resolve('controller:post'), 'The return of resolve is always the same'); }); QUnit.test('The registered value returned from resolve is the same value each time even if the value is falsy', function () { var registry = new _container.Registry(); registry.register('falsy:value', null, { instantiate: false }); strictEqual(registry.resolve('falsy:value'), registry.resolve('falsy:value'), 'The return of resolve is always the same'); }); QUnit.test('The value returned from resolver is the same value as the original value even if the value is falsy', function () { var registry = new _container.Registry({ resolver: { resolve: function (fullName) { if (fullName === 'falsy:value') { return null; } } } }); strictEqual(registry.resolve('falsy:value'), null); }); QUnit.test('A registered factory returns true for `has` if an item is registered', function () { var registry = new _container.Registry(); var PostController = (0, _internalTestHelpers.factory)(); registry.register('controller:post', PostController); equal(registry.has('controller:post'), true, 'The `has` method returned true for registered factories'); equal(registry.has('controller:posts'), false, 'The `has` method returned false for unregistered factories'); }); QUnit.test('Throw exception when trying to inject `type:thing` on all type(s)', function () { var registry = new _container.Registry(); var PostController = (0, _internalTestHelpers.factory)(); registry.register('controller:post', PostController); throws(function () { registry.typeInjection('controller', 'injected', 'controller:post'); }, /Cannot inject a 'controller:post' on other controller\(s\)\./); }); QUnit.test('The registry can take a hook to resolve factories lazily', function () { var PostController = (0, _internalTestHelpers.factory)(); var registry = new _container.Registry({ resolver: { resolve: function (fullName) { if (fullName === 'controller:post') { return PostController; } } } }); strictEqual(registry.resolve('controller:post'), PostController, 'The correct factory was provided'); }); QUnit.test('The registry respects the resolver hook for `has`', function () { var PostController = (0, _internalTestHelpers.factory)(); var registry = new _container.Registry({ resolver: { resolve: function (fullName) { if (fullName === 'controller:post') { return PostController; } } } }); ok(registry.has('controller:post'), 'the `has` method uses the resolver hook'); }); QUnit.test('The registry normalizes names when resolving', function () { var registry = new _container.Registry(); var PostController = (0, _internalTestHelpers.factory)(); registry.normalizeFullName = function () { return 'controller:post'; }; registry.register('controller:post', PostController); var type = registry.resolve('controller:normalized'); strictEqual(type, PostController, 'Normalizes the name when resolving'); }); QUnit.test('The registry normalizes names when checking if the factory is registered', function () { var registry = new _container.Registry(); var PostController = (0, _internalTestHelpers.factory)(); registry.normalizeFullName = function (fullName) { return fullName === 'controller:normalized' ? 'controller:post' : fullName; }; registry.register('controller:post', PostController); var isPresent = registry.has('controller:normalized'); equal(isPresent, true, 'Normalizes the name when checking if the factory or instance is present'); }); QUnit.test('validateFullName throws an error if name is incorrect', function () { expect(2); var registry = new _container.Registry(); var PostController = (0, _internalTestHelpers.factory)(); registry.normalize = function () { return 'controller:post'; }; registry.register('controller:post', PostController); throws(function () { registry.validateFullName('post'); }, /TypeError: Invalid Fullname, expected: 'type:name' got: post/); throws(function () { registry.validateFullName('route:http://foo.bar.com/baz'); }, /TypeError: Invalid Fullname, expected: 'type:name' got: route:http:\/\/foo.bar.com\/baz/); }); QUnit.test('The registry normalizes names when injecting', function () { var registry = new _container.Registry(); var PostController = (0, _internalTestHelpers.factory)(); var 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'); deepEqual(registry.resolve('controller:post'), user, 'Normalizes the name when injecting'); }); QUnit.test('cannot register an `undefined` factory', function () { var registry = new _container.Registry(); throws(function () { registry.register('controller:apple', undefined); }, ''); }); QUnit.test('can re-register a factory', function () { var registry = new _container.Registry(); var FirstApple = (0, _internalTestHelpers.factory)('first'); var SecondApple = (0, _internalTestHelpers.factory)('second'); registry.register('controller:apple', FirstApple); registry.register('controller:apple', SecondApple); ok(registry.resolve('controller:apple').create() instanceof SecondApple); }); QUnit.test('cannot re-register a factory if it has been resolved', function () { var registry = new _container.Registry(); var FirstApple = (0, _internalTestHelpers.factory)('first'); var SecondApple = (0, _internalTestHelpers.factory)('second'); registry.register('controller:apple', FirstApple); strictEqual(registry.resolve('controller:apple'), FirstApple); throws(function () { registry.register('controller:apple', SecondApple); }, /Cannot re-register: 'controller:apple', as it has already been resolved\./); strictEqual(registry.resolve('controller:apple'), FirstApple); }); QUnit.test('registry.has should not accidentally cause injections on that factory to be run. (Mitigate merely on observing)', function () { expect(1); var registry = new _container.Registry(); var FirstApple = (0, _internalTestHelpers.factory)('first'); var SecondApple = (0, _internalTestHelpers.factory)('second'); SecondApple.extend = function () { 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'); ok(registry.has('controller:apple')); }); QUnit.test('registry.has should not error for invalid fullNames)', function () { expect(1); var registry = new _container.Registry(); ok(!registry.has('foo:bar:baz')); }); QUnit.test('once resolved, always return the same result', function () { expect(1); var registry = new _container.Registry(); registry.resolver = { resolve: function () { return 'bar'; } }; var Bar = registry.resolve('models:bar'); registry.resolver = { resolve: function () { return 'not bar'; } }; equal(registry.resolve('models:bar'), Bar); }); QUnit.test('factory resolves are cached', function () { var registry = new _container.Registry(); var PostController = (0, _internalTestHelpers.factory)(); var resolveWasCalled = []; registry.resolver = { resolve: function (fullName) { resolveWasCalled.push(fullName); return PostController; } }; deepEqual(resolveWasCalled, []); registry.resolve('controller:post'); deepEqual(resolveWasCalled, ['controller:post']); registry.resolve('controller:post'); deepEqual(resolveWasCalled, ['controller:post']); }); QUnit.test('factory for non extendables (MODEL) resolves are cached', function () { var registry = new _container.Registry(); var PostController = (0, _internalTestHelpers.factory)(); var resolveWasCalled = []; registry.resolver = { resolve: function (fullName) { resolveWasCalled.push(fullName); return PostController; } }; deepEqual(resolveWasCalled, []); registry.resolve('model:post'); deepEqual(resolveWasCalled, ['model:post']); registry.resolve('model:post'); deepEqual(resolveWasCalled, ['model:post']); }); QUnit.test('factory for non extendables resolves are cached', function () { var registry = new _container.Registry(); var PostController = {}; var resolveWasCalled = []; registry.resolver = { resolve: function (fullName) { resolveWasCalled.push(fullName); return PostController; } }; deepEqual(resolveWasCalled, []); registry.resolve('foo:post'); deepEqual(resolveWasCalled, ['foo:post']); registry.resolve('foo:post'); deepEqual(resolveWasCalled, ['foo:post']); }); QUnit.test('registry.container creates a container', function () { var registry = new _container.Registry(); var PostController = (0, _internalTestHelpers.factory)(); registry.register('controller:post', PostController); var container = registry.container(); var postController = container.lookup('controller:post'); ok(postController instanceof PostController, 'The lookup is an instance of the registered factory'); }); QUnit.test('`describe` will be handled by the resolver, then by the fallback registry, if available', function () { var registry = new _container.Registry({ fallback: { describe: function (fullName) { return fullName + '-fallback'; } }, resolver: { lookupDescription: function (fullName) { return fullName + '-resolver'; } } }); equal(registry.describe('controller:post'), 'controller:post-resolver', '`describe` handled by the resolver first.'); registry.resolver = null; equal(registry.describe('controller:post'), 'controller:post-fallback', '`describe` handled by fallback registry next.'); registry.fallback = null; equal(registry.describe('controller:post'), 'controller:post', '`describe` by default returns argument.'); }); QUnit.test('`normalizeFullName` will be handled by the resolver, then by the fallback registry, if available', function () { var registry = new _container.Registry({ fallback: { normalizeFullName: function (fullName) { return fullName + '-fallback'; } }, resolver: { normalize: function (fullName) { return fullName + '-resolver'; } } }); equal(registry.normalizeFullName('controller:post'), 'controller:post-resolver', '`normalizeFullName` handled by the resolver first.'); registry.resolver = null; equal(registry.normalizeFullName('controller:post'), 'controller:post-fallback', '`normalizeFullName` handled by fallback registry next.'); registry.fallback = null; equal(registry.normalizeFullName('controller:post'), 'controller:post', '`normalizeFullName` by default returns argument.'); }); QUnit.test('`makeToString` will be handled by the resolver, then by the fallback registry, if available', function () { var registry = new _container.Registry({ fallback: { makeToString: function (fullName) { return fullName + '-fallback'; } }, resolver: { makeToString: function (fullName) { return fullName + '-resolver'; } } }); equal(registry.makeToString('controller:post'), 'controller:post-resolver', '`makeToString` handled by the resolver first.'); registry.resolver = null; equal(registry.makeToString('controller:post'), 'controller:post-fallback', '`makeToString` handled by fallback registry next.'); registry.fallback = null; equal(registry.makeToString('controller:post'), 'controller:post', '`makeToString` by default returns argument.'); }); QUnit.test('`resolve` can be handled by a fallback registry', function () { var fallback = new _container.Registry(); var registry = new _container.Registry({ fallback: fallback }); var PostController = (0, _internalTestHelpers.factory)(); fallback.register('controller:post', PostController); var PostControllerFactory = registry.resolve('controller:post'); ok(PostControllerFactory, 'factory is returned'); ok(PostControllerFactory.create() instanceof PostController, 'The return of factory.create is an instance of PostController'); }); QUnit.test('`has` can be handled by a fallback registry', function () { var fallback = new _container.Registry(); var registry = new _container.Registry({ fallback: fallback }); var PostController = (0, _internalTestHelpers.factory)(); fallback.register('controller:post', PostController); equal(registry.has('controller:post'), true, 'Fallback registry is checked for registration'); }); QUnit.test('`getInjections` includes injections from a fallback registry', function () { var fallback = new _container.Registry(); var registry = new _container.Registry({ fallback: fallback }); equal(registry.getInjections('model:user').length, 0, 'No injections in the primary registry'); fallback.injection('model:user', 'post', 'model:post'); equal(registry.getInjections('model:user').length, 1, 'Injections from the fallback registry are merged'); }); QUnit.test('`getTypeInjections` includes type injections from a fallback registry', function () { var fallback = new _container.Registry(); var registry = new _container.Registry({ fallback: fallback }); equal(registry.getTypeInjections('model').length, 0, 'No injections in the primary registry'); fallback.injection('model', 'source', 'source:main'); equal(registry.getTypeInjections('model').length, 1, 'Injections from the fallback registry are merged'); }); QUnit.test('`knownForType` contains keys for each item of a given type', function () { var registry = new _container.Registry(); registry.register('foo:bar-baz', 'baz'); registry.register('foo:qux-fez', 'fez'); var found = registry.knownForType('foo'); deepEqual(found, { 'foo:bar-baz': true, 'foo:qux-fez': true }); }); QUnit.test('`knownForType` includes fallback registry results', function () { var fallback = new _container.Registry(); var registry = new _container.Registry({ fallback: fallback }); registry.register('foo:bar-baz', 'baz'); registry.register('foo:qux-fez', 'fez'); fallback.register('foo:zurp-zorp', 'zorp'); var found = registry.knownForType('foo'); deepEqual(found, { 'foo:bar-baz': true, 'foo:qux-fez': true, 'foo:zurp-zorp': true }); }); QUnit.test('`knownForType` is called on the resolver if present', function () { expect(3); var registry = new _container.Registry({ resolver: { knownForType: function (type) { ok(true, 'knownForType called on the resolver'); equal(type, 'foo', 'the type was passed through'); return { 'foo:yorp': true }; } } }); registry.register('foo:bar-baz', 'baz'); var found = registry.knownForType('foo'); deepEqual(found, { 'foo:yorp': true, 'foo:bar-baz': true }); }); QUnit.test('A registry can be created with a deprecated `resolver` function instead of an object', function () { expect(2); var registry = void 0; expectDeprecation(function () { registry = new _container.Registry({ resolver: function (fullName) { return fullName + '-resolved'; } }); }, 'Passing a `resolver` function into a Registry is deprecated. Please pass in a Resolver object with a `resolve` method.'); equal(registry.resolve('foo:bar'), 'foo:bar-resolved', '`resolve` still calls the deprecated function'); }); QUnit.test('resolver.expandLocalLookup is not required', function (assert) { assert.expect(1); var registry = new _container.Registry({ resolver: {} }); var result = registry.expandLocalLookup('foo:bar', { source: 'baz:qux' }); assert.equal(result, null); }); QUnit.test('expandLocalLookup is called on the resolver if present', function (assert) { assert.expect(4); var registry = new _container.Registry({ resolver: { expandLocalLookup: function (targetFullName, sourceFullName) { assert.ok(true, 'expandLocalLookup is called on the resolver'); assert.equal(targetFullName, 'foo:bar', 'the targetFullName was passed through'); assert.equal(sourceFullName, 'baz:qux', 'the sourceFullName was passed through'); return 'foo:qux/bar'; } } }); var result = registry.expandLocalLookup('foo:bar', { source: 'baz:qux' }); assert.equal(result, 'foo:qux/bar'); }); QUnit.test('`expandLocalLookup` is handled by the resolver, then by the fallback registry, if available', function (assert) { assert.expect(9); var fallbackRegistry = new _container.Registry({ resolver: { expandLocalLookup: function (targetFullName, sourceFullName) { assert.ok(true, 'expandLocalLookup is called on the fallback resolver'); assert.equal(targetFullName, 'foo:bar', 'the targetFullName was passed through'); assert.equal(sourceFullName, 'baz:qux', 'the sourceFullName was passed through'); return 'foo:qux/bar-fallback'; } } }); var registry = new _container.Registry({ fallback: fallbackRegistry, resolver: { expandLocalLookup: function (targetFullName, sourceFullName) { assert.ok(true, 'expandLocalLookup is called on the resolver'); assert.equal(targetFullName, 'foo:bar', 'the targetFullName was passed through'); assert.equal(sourceFullName, 'baz:qux', 'the sourceFullName was passed through'); return 'foo:qux/bar-resolver'; } } }); var result = registry.expandLocalLookup('foo:bar', { source: 'baz:qux' }); assert.equal(result, 'foo:qux/bar-resolver', 'handled by the resolver'); registry.resolver = null; result = registry.expandLocalLookup('foo:bar', { source: 'baz:qux' }); assert.equal(result, 'foo:qux/bar-fallback', 'handled by the fallback registry'); registry.fallback = null; result = registry.expandLocalLookup('foo:bar', { source: 'baz:qux' }); assert.equal(result, null, 'null is returned by default when no resolver or fallback registry is present'); }); QUnit.test('resolver.expandLocalLookup result is cached', function (assert) { assert.expect(3); var result = void 0; var registry = new _container.Registry({ resolver: { expandLocalLookup: function () { assert.ok(true, 'expandLocalLookup is called on the resolver'); return 'foo:qux/bar'; } } }); result = registry.expandLocalLookup('foo:bar', { source: 'baz:qux' }); assert.equal(result, 'foo:qux/bar'); result = registry.expandLocalLookup('foo:bar', { source: 'baz:qux' }); assert.equal(result, 'foo:qux/bar'); }); QUnit.test('resolver.expandLocalLookup cache is busted when any unregister is called', function (assert) { assert.expect(4); var result = void 0; var registry = new _container.Registry({ resolver: { expandLocalLookup: function () { assert.ok(true, 'expandLocalLookup is called on the resolver'); return 'foo:qux/bar'; } } }); result = registry.expandLocalLookup('foo:bar', { source: 'baz:qux' }); assert.equal(result, 'foo:qux/bar'); registry.unregister('foo:bar'); result = registry.expandLocalLookup('foo:bar', { source: 'baz:qux' }); assert.equal(result, 'foo:qux/bar'); }); QUnit.test('resolve calls expandLocallookup when it receives options.source', function (assert) { assert.expect(3); var registry = new _container.Registry({ resolver: { resolve: function () {}, expandLocalLookup: function (targetFullName, sourceFullName) { assert.ok(true, 'expandLocalLookup is called on the resolver'); assert.equal(targetFullName, 'foo:bar', 'the targetFullName was passed through'); assert.equal(sourceFullName, 'baz:qux', 'the sourceFullName was passed through'); return 'foo:qux/bar'; } } }); registry.resolve('foo:bar', { source: 'baz:qux' }); }); QUnit.test('has uses expandLocalLookup', function (assert) { assert.expect(5); var resolvedFullNames = []; var result = void 0; var registry = new _container.Registry({ resolver: { resolve: function (name) { resolvedFullNames.push(name); return 'yippie!'; }, expandLocalLookup: function (targetFullName) { assert.ok(true, 'expandLocalLookup is called on the resolver'); if (targetFullName === 'foo:bar') { return 'foo:qux/bar'; } else { return null; } } } }); result = registry.has('foo:bar', { source: 'baz:qux' }); assert.ok(result, 'found foo:bar/qux'); result = registry.has('foo:baz', { source: 'baz:qux' }); assert.ok(!result, 'foo:baz/qux not found'); assert.deepEqual(['foo:qux/bar'], resolvedFullNames); }); QUnit.module('Registry privatize'); QUnit.test('valid format', function (assert) { var privatized = (0, _container.privatize)(['secret:factory']); var matched = privatized.match(/^([^:]+):([^:]+)-(\d+)$/); assert.ok(matched, 'privatized format was recognized'); assert.equal(matched[1], 'se