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
JavaScript
(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