Unified
Split
Showing
with
31 additions
and 9 deletions.
- +12 −8 src/auto/injector.js
- +19 −1 test/auto/injectorSpec.js
| @@ -179,6 +179,7 @@ function annotate(fn, strictDi, name) { | ||
| * Return an instance of the service. | ||
| * | ||
| * @param {string} name The name of the instance to retrieve. | ||
| * @param {string} caller An optional string to provide the origin of the function call for error messages. | ||
| * @return {*} The instance. | ||
| */ | ||
|
|
||
| @@ -629,14 +630,17 @@ function createInjector(modulesToLoad, strictDi) { | ||
| } | ||
| }, | ||
| providerInjector = (providerCache.$injector = | ||
| createInternalInjector(providerCache, function() { | ||
| createInternalInjector(providerCache, function(serviceName, caller) { | ||
| if (angular.isString(caller)) { | ||
| path.push(caller); | ||
| } | ||
| throw $injectorMinErr('unpr', "Unknown provider: {0}", path.join(' <- ')); | ||
| })), | ||
| instanceCache = {}, | ||
| instanceInjector = (instanceCache.$injector = | ||
| createInternalInjector(instanceCache, function(servicename) { | ||
| var provider = providerInjector.get(servicename + providerSuffix); | ||
| return instanceInjector.invoke(provider.$get, provider, undefined, servicename); | ||
| createInternalInjector(instanceCache, function(serviceName, caller) { | ||
| var provider = providerInjector.get(serviceName + providerSuffix, caller); | ||
| return instanceInjector.invoke(provider.$get, provider, undefined, serviceName); | ||
| })); | ||
|
|
||
|
|
||
| @@ -671,7 +675,7 @@ function createInjector(modulesToLoad, strictDi) { | ||
|
|
||
| function enforceReturnValue(name, factory) { | ||
| return function enforcedReturnValue() { | ||
| var result = instanceInjector.invoke(factory, this, undefined, name); | ||
| var result = instanceInjector.invoke(factory, this); | ||
| if (isUndefined(result)) { | ||
| throw $injectorMinErr('undef', "Provider '{0}' must return a value from $get factory method.", name); | ||
| } | ||
| @@ -766,7 +770,7 @@ function createInjector(modulesToLoad, strictDi) { | ||
|
|
||
| function createInternalInjector(cache, factory) { | ||
|
|
||
| function getService(serviceName) { | ||
| function getService(serviceName, caller) { | ||
| if (cache.hasOwnProperty(serviceName)) { | ||
| if (cache[serviceName] === INSTANTIATING) { | ||
| throw $injectorMinErr('cdep', 'Circular dependency found: {0}', | ||
| @@ -777,7 +781,7 @@ function createInjector(modulesToLoad, strictDi) { | ||
| try { | ||
| path.unshift(serviceName); | ||
| cache[serviceName] = INSTANTIATING; | ||
| return cache[serviceName] = factory(serviceName); | ||
| return cache[serviceName] = factory(serviceName, caller); | ||
| } catch (err) { | ||
| if (cache[serviceName] === INSTANTIATING) { | ||
| delete cache[serviceName]; | ||
| @@ -809,7 +813,7 @@ function createInjector(modulesToLoad, strictDi) { | ||
| args.push( | ||
| locals && locals.hasOwnProperty(key) | ||
| ? locals[key] | ||
| : getService(key) | ||
| : getService(key, serviceName) | ||
| ); | ||
| } | ||
| if (isArray(fn)) { | ||
| @@ -4,12 +4,14 @@ describe('injector', function() { | ||
| var providers; | ||
| var injector; | ||
| var providerInjector; | ||
| var controllerProvider; | ||
|
|
||
| beforeEach(module(function($provide, $injector) { | ||
| beforeEach(module(function($provide, $injector, $controllerProvider) { | ||
| providers = function(name, factory, annotations) { | ||
| $provide.factory(name, extend(factory, annotations || {})); | ||
| }; | ||
| providerInjector = $injector; | ||
| controllerProvider = $controllerProvider; | ||
| })); | ||
| beforeEach(inject(function($injector) { | ||
| injector = $injector; | ||
| @@ -74,6 +76,22 @@ describe('injector', function() { | ||
| }); | ||
|
|
||
|
|
||
| it('should provide the caller name if given', function(done) { | ||
| expect(function() { | ||
| injector.get('idontexist', 'callerName'); | ||
| }).toThrowMinErr("$injector", "unpr", "Unknown provider: idontexistProvider <- idontexist <- callerName"); | ||
| }); | ||
|
|
||
|
|
||
| it('should provide the caller name for controllers', function(done) { | ||
| controllerProvider.register('myCtrl', function(idontexist) {}); | ||
| var $controller = injector.get('$controller'); | ||
| expect(function() { | ||
| $controller('myCtrl', {$scope: {}}); | ||
| }).toThrowMinErr("$injector", "unpr", "Unknown provider: idontexistProvider <- idontexist <- myCtrl"); | ||
| }); | ||
|
|
||
|
|
||
| it('should not corrupt the cache when an object fails to get instantiated', function() { | ||
| expect(function() { | ||
| injector.get('idontexist'); | ||