2011-07-17 08:05:43 +00:00
|
|
|
'use strict';
|
|
|
|
|
|
2011-10-07 18:27:49 +00:00
|
|
|
describe('injector', function() {
|
Introduced injector and $new to scope, and injection into link methods and controllers
- added angular.injector(scope, services, instanceCache) which returns inject
- inject method can return, instance, or call function which have $inject
property
- initialize services with $creation=[eager|eager-publish] this means that
only some of the services are now globally accessible
- upgraded $become on scope to use injector hence respect the $inject property
for injection
- $become should not be run multiple times and will most likely be removed
in future version
- added $new on scope to create a child scope
- $inject is respected on constructor function
- simplified scopes so that they no longer have separate __proto__ for
parent, api, behavior and instance this should speed up execution since
scope will now create one __proto__ chain per scope (not three).
BACKWARD COMPATIBILITY WARNING:
- services now need to have $inject instead of inject property for proper
injection this breaks backward compatibility
- not all services are now published into root scope
(only: $location, $cookie, $window)
- if you have widget/directive which uses services on scope
(such as this.$xhr), you will now have to inject that service in
(as it is not published on the root scope anymore)
2010-10-09 00:30:13 +00:00
|
|
|
var providers;
|
2011-04-18 23:33:30 +00:00
|
|
|
var injector;
|
Introduced injector and $new to scope, and injection into link methods and controllers
- added angular.injector(scope, services, instanceCache) which returns inject
- inject method can return, instance, or call function which have $inject
property
- initialize services with $creation=[eager|eager-publish] this means that
only some of the services are now globally accessible
- upgraded $become on scope to use injector hence respect the $inject property
for injection
- $become should not be run multiple times and will most likely be removed
in future version
- added $new on scope to create a child scope
- $inject is respected on constructor function
- simplified scopes so that they no longer have separate __proto__ for
parent, api, behavior and instance this should speed up execution since
scope will now create one __proto__ chain per scope (not three).
BACKWARD COMPATIBILITY WARNING:
- services now need to have $inject instead of inject property for proper
injection this breaks backward compatibility
- not all services are now published into root scope
(only: $location, $cookie, $window)
- if you have widget/directive which uses services on scope
(such as this.$xhr), you will now have to inject that service in
(as it is not published on the root scope anymore)
2010-10-09 00:30:13 +00:00
|
|
|
|
2011-11-02 04:09:54 +00:00
|
|
|
beforeEach(inject(function($injector, $provide) {
|
|
|
|
|
providers = function(name, factory, decoration){
|
|
|
|
|
$provide.factory(name, extend(factory, decoration||{}));
|
|
|
|
|
};
|
|
|
|
|
injector = $injector;
|
|
|
|
|
}));
|
Introduced injector and $new to scope, and injection into link methods and controllers
- added angular.injector(scope, services, instanceCache) which returns inject
- inject method can return, instance, or call function which have $inject
property
- initialize services with $creation=[eager|eager-publish] this means that
only some of the services are now globally accessible
- upgraded $become on scope to use injector hence respect the $inject property
for injection
- $become should not be run multiple times and will most likely be removed
in future version
- added $new on scope to create a child scope
- $inject is respected on constructor function
- simplified scopes so that they no longer have separate __proto__ for
parent, api, behavior and instance this should speed up execution since
scope will now create one __proto__ chain per scope (not three).
BACKWARD COMPATIBILITY WARNING:
- services now need to have $inject instead of inject property for proper
injection this breaks backward compatibility
- not all services are now published into root scope
(only: $location, $cookie, $window)
- if you have widget/directive which uses services on scope
(such as this.$xhr), you will now have to inject that service in
(as it is not published on the root scope anymore)
2010-10-09 00:30:13 +00:00
|
|
|
|
2011-10-07 18:27:49 +00:00
|
|
|
it("should return same instance from calling provider", function() {
|
2011-10-17 23:56:56 +00:00
|
|
|
var instance = {},
|
|
|
|
|
original = instance;
|
|
|
|
|
providers('instance', function() { return instance; });
|
|
|
|
|
expect(injector('instance')).toEqual(instance);
|
|
|
|
|
instance = 'deleted';
|
|
|
|
|
expect(injector('instance')).toEqual(original);
|
Introduced injector and $new to scope, and injection into link methods and controllers
- added angular.injector(scope, services, instanceCache) which returns inject
- inject method can return, instance, or call function which have $inject
property
- initialize services with $creation=[eager|eager-publish] this means that
only some of the services are now globally accessible
- upgraded $become on scope to use injector hence respect the $inject property
for injection
- $become should not be run multiple times and will most likely be removed
in future version
- added $new on scope to create a child scope
- $inject is respected on constructor function
- simplified scopes so that they no longer have separate __proto__ for
parent, api, behavior and instance this should speed up execution since
scope will now create one __proto__ chain per scope (not three).
BACKWARD COMPATIBILITY WARNING:
- services now need to have $inject instead of inject property for proper
injection this breaks backward compatibility
- not all services are now published into root scope
(only: $location, $cookie, $window)
- if you have widget/directive which uses services on scope
(such as this.$xhr), you will now have to inject that service in
(as it is not published on the root scope anymore)
2010-10-09 00:30:13 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
2011-10-07 18:27:49 +00:00
|
|
|
it('should inject providers', function() {
|
2011-10-17 23:56:56 +00:00
|
|
|
providers('a', function() {return 'Mi';});
|
2011-10-31 22:33:52 +00:00
|
|
|
providers('b', function(mi) {return mi+'sko';}, {$inject:['a']});
|
2011-04-18 23:33:30 +00:00
|
|
|
expect(injector('b')).toEqual('Misko');
|
Introduced injector and $new to scope, and injection into link methods and controllers
- added angular.injector(scope, services, instanceCache) which returns inject
- inject method can return, instance, or call function which have $inject
property
- initialize services with $creation=[eager|eager-publish] this means that
only some of the services are now globally accessible
- upgraded $become on scope to use injector hence respect the $inject property
for injection
- $become should not be run multiple times and will most likely be removed
in future version
- added $new on scope to create a child scope
- $inject is respected on constructor function
- simplified scopes so that they no longer have separate __proto__ for
parent, api, behavior and instance this should speed up execution since
scope will now create one __proto__ chain per scope (not three).
BACKWARD COMPATIBILITY WARNING:
- services now need to have $inject instead of inject property for proper
injection this breaks backward compatibility
- not all services are now published into root scope
(only: $location, $cookie, $window)
- if you have widget/directive which uses services on scope
(such as this.$xhr), you will now have to inject that service in
(as it is not published on the root scope anymore)
2010-10-09 00:30:13 +00:00
|
|
|
});
|
|
|
|
|
|
2011-02-28 00:19:21 +00:00
|
|
|
|
2011-10-07 18:27:49 +00:00
|
|
|
it('should resolve dependency graph and instantiate all services just once', function() {
|
2011-02-28 00:19:21 +00:00
|
|
|
var log = [];
|
|
|
|
|
|
2011-11-02 04:09:54 +00:00
|
|
|
// s1
|
|
|
|
|
// / | \
|
|
|
|
|
// / s2 \
|
|
|
|
|
// / / | \ \
|
2011-02-28 00:19:21 +00:00
|
|
|
// /s3 < s4 > s5
|
|
|
|
|
// //
|
|
|
|
|
// s6
|
|
|
|
|
|
|
|
|
|
|
2011-10-07 18:27:49 +00:00
|
|
|
providers('s1', function() { log.push('s1'); }, {$inject: ['s2', 's5', 's6']});
|
|
|
|
|
providers('s2', function() { log.push('s2'); }, {$inject: ['s3', 's4', 's5']});
|
|
|
|
|
providers('s3', function() { log.push('s3'); }, {$inject: ['s6']});
|
|
|
|
|
providers('s4', function() { log.push('s4'); }, {$inject: ['s3', 's5']});
|
|
|
|
|
providers('s5', function() { log.push('s5'); });
|
|
|
|
|
providers('s6', function() { log.push('s6'); });
|
2011-02-28 00:19:21 +00:00
|
|
|
|
2011-04-18 23:33:30 +00:00
|
|
|
injector('s1');
|
2011-02-28 00:19:21 +00:00
|
|
|
|
2011-04-18 23:33:30 +00:00
|
|
|
expect(log).toEqual(['s6', 's5', 's3', 's4', 's2', 's1']);
|
2011-02-28 00:19:21 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
2011-10-26 04:28:48 +00:00
|
|
|
it('should provide useful message if no provider', function() {
|
2011-10-07 18:27:49 +00:00
|
|
|
expect(function() {
|
2011-04-18 23:33:30 +00:00
|
|
|
injector('idontexist');
|
|
|
|
|
}).toThrow("Unknown provider for 'idontexist'.");
|
Introduced injector and $new to scope, and injection into link methods and controllers
- added angular.injector(scope, services, instanceCache) which returns inject
- inject method can return, instance, or call function which have $inject
property
- initialize services with $creation=[eager|eager-publish] this means that
only some of the services are now globally accessible
- upgraded $become on scope to use injector hence respect the $inject property
for injection
- $become should not be run multiple times and will most likely be removed
in future version
- added $new on scope to create a child scope
- $inject is respected on constructor function
- simplified scopes so that they no longer have separate __proto__ for
parent, api, behavior and instance this should speed up execution since
scope will now create one __proto__ chain per scope (not three).
BACKWARD COMPATIBILITY WARNING:
- services now need to have $inject instead of inject property for proper
injection this breaks backward compatibility
- not all services are now published into root scope
(only: $location, $cookie, $window)
- if you have widget/directive which uses services on scope
(such as this.$xhr), you will now have to inject that service in
(as it is not published on the root scope anymore)
2010-10-09 00:30:13 +00:00
|
|
|
});
|
|
|
|
|
|
2011-10-31 22:33:52 +00:00
|
|
|
it('should proved path to the missing provider', function() {
|
2011-11-02 04:09:54 +00:00
|
|
|
providers('a', function(idontexist) {return 1;});
|
|
|
|
|
providers('b', function(a) {return 2;});
|
2011-10-26 04:28:48 +00:00
|
|
|
expect(function() {
|
2011-11-02 04:09:54 +00:00
|
|
|
injector('b');
|
2011-10-26 04:28:48 +00:00
|
|
|
}).toThrow("Unknown provider for 'idontexist' <- 'a' <- 'b'.");
|
|
|
|
|
});
|
|
|
|
|
|
2011-10-07 18:27:49 +00:00
|
|
|
it('should autostart eager services', function() {
|
Introduced injector and $new to scope, and injection into link methods and controllers
- added angular.injector(scope, services, instanceCache) which returns inject
- inject method can return, instance, or call function which have $inject
property
- initialize services with $creation=[eager|eager-publish] this means that
only some of the services are now globally accessible
- upgraded $become on scope to use injector hence respect the $inject property
for injection
- $become should not be run multiple times and will most likely be removed
in future version
- added $new on scope to create a child scope
- $inject is respected on constructor function
- simplified scopes so that they no longer have separate __proto__ for
parent, api, behavior and instance this should speed up execution since
scope will now create one __proto__ chain per scope (not three).
BACKWARD COMPATIBILITY WARNING:
- services now need to have $inject instead of inject property for proper
injection this breaks backward compatibility
- not all services are now published into root scope
(only: $location, $cookie, $window)
- if you have widget/directive which uses services on scope
(such as this.$xhr), you will now have to inject that service in
(as it is not published on the root scope anymore)
2010-10-09 00:30:13 +00:00
|
|
|
var log = '';
|
2011-11-02 04:09:54 +00:00
|
|
|
injector = createInjector([function($provide){
|
|
|
|
|
$provide.service('eager', function() {
|
|
|
|
|
this.$eager = true;
|
|
|
|
|
this.$get = function(){
|
|
|
|
|
log += 'eager;';
|
|
|
|
|
return 'foo';
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
}]);
|
Introduced injector and $new to scope, and injection into link methods and controllers
- added angular.injector(scope, services, instanceCache) which returns inject
- inject method can return, instance, or call function which have $inject
property
- initialize services with $creation=[eager|eager-publish] this means that
only some of the services are now globally accessible
- upgraded $become on scope to use injector hence respect the $inject property
for injection
- $become should not be run multiple times and will most likely be removed
in future version
- added $new on scope to create a child scope
- $inject is respected on constructor function
- simplified scopes so that they no longer have separate __proto__ for
parent, api, behavior and instance this should speed up execution since
scope will now create one __proto__ chain per scope (not three).
BACKWARD COMPATIBILITY WARNING:
- services now need to have $inject instead of inject property for proper
injection this breaks backward compatibility
- not all services are now published into root scope
(only: $location, $cookie, $window)
- if you have widget/directive which uses services on scope
(such as this.$xhr), you will now have to inject that service in
(as it is not published on the root scope anymore)
2010-10-09 00:30:13 +00:00
|
|
|
expect(log).toEqual('eager;');
|
2011-04-18 23:33:30 +00:00
|
|
|
expect(injector('eager')).toBe('foo');
|
Introduced injector and $new to scope, and injection into link methods and controllers
- added angular.injector(scope, services, instanceCache) which returns inject
- inject method can return, instance, or call function which have $inject
property
- initialize services with $creation=[eager|eager-publish] this means that
only some of the services are now globally accessible
- upgraded $become on scope to use injector hence respect the $inject property
for injection
- $become should not be run multiple times and will most likely be removed
in future version
- added $new on scope to create a child scope
- $inject is respected on constructor function
- simplified scopes so that they no longer have separate __proto__ for
parent, api, behavior and instance this should speed up execution since
scope will now create one __proto__ chain per scope (not three).
BACKWARD COMPATIBILITY WARNING:
- services now need to have $inject instead of inject property for proper
injection this breaks backward compatibility
- not all services are now published into root scope
(only: $location, $cookie, $window)
- if you have widget/directive which uses services on scope
(such as this.$xhr), you will now have to inject that service in
(as it is not published on the root scope anymore)
2010-10-09 00:30:13 +00:00
|
|
|
});
|
2011-02-17 00:18:35 +00:00
|
|
|
|
2011-10-31 22:33:52 +00:00
|
|
|
describe('invoke', function() {
|
2011-10-27 03:54:45 +00:00
|
|
|
var args;
|
|
|
|
|
|
2011-10-31 22:33:52 +00:00
|
|
|
beforeEach(function() {
|
2011-10-27 03:54:45 +00:00
|
|
|
args = null;
|
|
|
|
|
providers('a', function() {return 1;});
|
|
|
|
|
providers('b', function() {return 2;});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function fn(a, b, c, d) {
|
|
|
|
|
args = [this, a, b, c, d];
|
2011-10-27 04:36:19 +00:00
|
|
|
return a + b + c + d;
|
2011-10-27 03:54:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('should call function', function() {
|
2011-11-02 04:09:54 +00:00
|
|
|
fn.$inject = ['a', 'b', 'c', 'd'];
|
|
|
|
|
injector.invoke({name:"this"}, fn, {c:3, d:4});
|
2011-10-27 03:54:45 +00:00
|
|
|
expect(args).toEqual([{name:'this'}, 1, 2, 3, 4]);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
2011-10-31 22:33:52 +00:00
|
|
|
it('should treat array as annotations', function() {
|
2011-11-02 04:09:54 +00:00
|
|
|
injector.invoke({name:"this"}, ['a', 'b', 'c', 'd', fn], {c:3, d:4});
|
2011-10-27 03:54:45 +00:00
|
|
|
expect(args).toEqual([{name:'this'}, 1, 2, 3, 4]);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
2011-10-27 04:36:19 +00:00
|
|
|
it('should invoke the passed in function with all of the dependencies as arguments', function(){
|
2011-11-02 04:09:54 +00:00
|
|
|
providers('c', function() {return 3;});
|
|
|
|
|
providers('d', function() {return 4;});
|
|
|
|
|
expect(injector(['a', 'b', 'c', 'd', fn])).toEqual(10);
|
2011-10-27 04:36:19 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
2011-10-31 22:33:52 +00:00
|
|
|
it('should fail with errors if not function or array', function() {
|
|
|
|
|
expect(function() {
|
2011-10-27 03:54:45 +00:00
|
|
|
injector.invoke({}, {});
|
|
|
|
|
}).toThrow("Argument 'fn' is not a function, got Object");
|
2011-10-31 22:33:52 +00:00
|
|
|
expect(function() {
|
2011-10-27 03:54:45 +00:00
|
|
|
injector.invoke({}, ['a', 123]);
|
|
|
|
|
}).toThrow("Argument 'fn' is not a function, got number");
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2011-10-07 18:27:49 +00:00
|
|
|
describe('annotation', function() {
|
|
|
|
|
it('should return $inject', function() {
|
|
|
|
|
function fn() {}
|
2011-02-17 00:18:35 +00:00
|
|
|
fn.$inject = ['a'];
|
2011-08-02 20:29:12 +00:00
|
|
|
expect(inferInjectionArgs(fn)).toBe(fn.$inject);
|
2011-10-07 18:27:49 +00:00
|
|
|
expect(inferInjectionArgs(function() {})).toEqual([]);
|
|
|
|
|
expect(inferInjectionArgs(function () {})).toEqual([]);
|
|
|
|
|
expect(inferInjectionArgs(function () {})).toEqual([]);
|
|
|
|
|
expect(inferInjectionArgs(function /* */ () {})).toEqual([]);
|
2011-02-17 00:18:35 +00:00
|
|
|
});
|
|
|
|
|
|
2011-10-07 18:27:49 +00:00
|
|
|
it('should create $inject', function() {
|
2011-02-17 00:18:35 +00:00
|
|
|
// keep the multi-line to make sure we can handle it
|
2011-02-18 21:19:59 +00:00
|
|
|
function $f_n0 /*
|
|
|
|
|
*/(
|
2011-02-17 00:18:35 +00:00
|
|
|
$a, // x, <-- looks like an arg but it is a comment
|
|
|
|
|
b_, /* z, <-- looks like an arg but it is a
|
|
|
|
|
multi-line comment
|
2011-10-31 22:33:52 +00:00
|
|
|
function (a, b) {}
|
2011-02-17 00:18:35 +00:00
|
|
|
*/
|
2011-04-18 23:33:30 +00:00
|
|
|
_c,
|
2011-10-31 22:33:52 +00:00
|
|
|
/* {some type} */ d) { extraParans();}
|
2011-08-02 20:29:12 +00:00
|
|
|
expect(inferInjectionArgs($f_n0)).toEqual(['$a', 'b_', '_c', 'd']);
|
2011-04-18 23:33:30 +00:00
|
|
|
expect($f_n0.$inject).toEqual(['$a', 'b_', '_c', 'd']);
|
2011-02-17 00:18:35 +00:00
|
|
|
});
|
|
|
|
|
|
2011-10-07 18:27:49 +00:00
|
|
|
it('should handle no arg functions', function() {
|
|
|
|
|
function $f_n0() {}
|
2011-08-02 20:29:12 +00:00
|
|
|
expect(inferInjectionArgs($f_n0)).toEqual([]);
|
2011-02-17 00:18:35 +00:00
|
|
|
expect($f_n0.$inject).toEqual([]);
|
|
|
|
|
});
|
|
|
|
|
|
2011-10-07 18:27:49 +00:00
|
|
|
it('should handle args with both $ and _', function() {
|
2011-10-31 22:33:52 +00:00
|
|
|
function $f_n0($a_) {}
|
2011-08-02 20:29:12 +00:00
|
|
|
expect(inferInjectionArgs($f_n0)).toEqual(['$a_']);
|
2011-04-18 23:33:30 +00:00
|
|
|
expect($f_n0.$inject).toEqual(['$a_']);
|
2011-02-17 00:18:35 +00:00
|
|
|
});
|
|
|
|
|
|
2011-10-07 18:27:49 +00:00
|
|
|
it('should throw on non function arg', function() {
|
|
|
|
|
expect(function() {
|
2011-08-02 20:29:12 +00:00
|
|
|
inferInjectionArgs({});
|
2011-02-17 00:18:35 +00:00
|
|
|
}).toThrow();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
});
|
2011-10-31 22:33:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
it('should have $injector', function() {
|
2011-11-02 04:09:54 +00:00
|
|
|
var $injector = createInjector();
|
2011-10-31 22:33:52 +00:00
|
|
|
expect($injector('$injector')).toBe($injector);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('should define module', function() {
|
|
|
|
|
var log = '';
|
2011-11-02 04:09:54 +00:00
|
|
|
var injector = createInjector([function($provide) {
|
2011-10-31 22:33:52 +00:00
|
|
|
$provide.value('value', 'value;');
|
|
|
|
|
$provide.factory('fn', valueFn('function;'));
|
|
|
|
|
$provide.service('service', function() {
|
|
|
|
|
this.$get = valueFn('service;');
|
|
|
|
|
});
|
|
|
|
|
}, function(valueProvider, fnProvider, serviceProvider) {
|
|
|
|
|
log += valueProvider.$get() + fnProvider.$get() + serviceProvider.$get();
|
|
|
|
|
}])(function(value, fn, service) {
|
|
|
|
|
log += '->' + value + fn + service;
|
|
|
|
|
});
|
|
|
|
|
expect(log).toEqual('value;function;service;->value;function;service;');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
describe('module', function() {
|
|
|
|
|
it('should provide $injector and $provide even when no module is requested', function() {
|
|
|
|
|
var $provide,
|
2011-11-02 04:09:54 +00:00
|
|
|
$injector = createInjector([
|
2011-10-31 22:33:52 +00:00
|
|
|
angular.extend(function(p) { $provide = p; }, {$inject: ['$provide']})
|
|
|
|
|
]);
|
|
|
|
|
expect($injector('$injector')).toBe($injector);
|
|
|
|
|
expect($injector('$provide')).toBe($provide);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('should load multiple function modules and infer inject them', function() {
|
|
|
|
|
var a = 'junk';
|
2011-11-02 04:09:54 +00:00
|
|
|
var $injector = createInjector([
|
2011-10-31 22:33:52 +00:00
|
|
|
function() {
|
|
|
|
|
a = 'A'; // reset to prove we ran
|
|
|
|
|
},
|
|
|
|
|
function($provide) {
|
|
|
|
|
$provide.value('a', a);
|
|
|
|
|
},
|
|
|
|
|
angular.extend(function(p, serviceA) {
|
|
|
|
|
p.value('b', serviceA.$get() + 'B' );
|
|
|
|
|
}, {$inject:['$provide', 'aProvider']}),
|
|
|
|
|
['$provide', 'bProvider', function(p, serviceB) {
|
|
|
|
|
p.value('c', serviceB.$get() + 'C');
|
|
|
|
|
}]
|
|
|
|
|
]);
|
|
|
|
|
expect($injector('a')).toEqual('A');
|
|
|
|
|
expect($injector('b')).toEqual('AB');
|
|
|
|
|
expect($injector('c')).toEqual('ABC');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('should run symbolic modules', function() {
|
2011-11-02 04:09:54 +00:00
|
|
|
var $injector = createInjector(['myModule'], {
|
2011-10-31 22:33:52 +00:00
|
|
|
myModule: ['$provide', function(provide) {
|
|
|
|
|
provide.value('a', 'abc');
|
|
|
|
|
}]
|
|
|
|
|
});
|
|
|
|
|
expect($injector('a')).toEqual('abc');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
describe('$provide', function() {
|
|
|
|
|
describe('value', function(){
|
|
|
|
|
it('should configure $provide values', function() {
|
2011-11-02 04:09:54 +00:00
|
|
|
expect(createInjector([function($provide) {
|
2011-10-31 22:33:52 +00:00
|
|
|
$provide.value('value', 'abc');
|
|
|
|
|
}])('value')).toEqual('abc');
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
describe('factory', function(){
|
|
|
|
|
it('should configure $provide factory function', function() {
|
2011-11-02 04:09:54 +00:00
|
|
|
expect(createInjector([function($provide) {
|
2011-10-31 22:33:52 +00:00
|
|
|
$provide.factory('value', valueFn('abc'));
|
|
|
|
|
}])('value')).toEqual('abc');
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
describe('service', function(){
|
|
|
|
|
it('should configure $provide service object', function() {
|
2011-11-02 04:09:54 +00:00
|
|
|
expect(createInjector([function($provide) {
|
2011-10-31 22:33:52 +00:00
|
|
|
$provide.service('value', {
|
|
|
|
|
$get: valueFn('abc')
|
|
|
|
|
});
|
|
|
|
|
}])('value')).toEqual('abc');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('should configure $provide service type', function() {
|
|
|
|
|
function Type() {};
|
|
|
|
|
Type.prototype.$get = function() {
|
|
|
|
|
expect(this instanceof Type).toBe(true);
|
|
|
|
|
return 'abc';
|
|
|
|
|
};
|
2011-11-02 04:09:54 +00:00
|
|
|
expect(createInjector([function($provide) {
|
2011-10-31 22:33:52 +00:00
|
|
|
$provide.service('value', Type);
|
|
|
|
|
}])('value')).toEqual('abc');
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
describe('error handling', function() {
|
|
|
|
|
it('should handle wrong argument type', function() {
|
|
|
|
|
expect(function() {
|
2011-11-02 04:09:54 +00:00
|
|
|
createInjector([
|
2011-10-31 22:33:52 +00:00
|
|
|
{}
|
|
|
|
|
], {});
|
|
|
|
|
}).toThrow("Argument 'module' is not a function, got Object");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('should handle exceptions', function() {
|
|
|
|
|
expect(function() {
|
2011-11-02 04:09:54 +00:00
|
|
|
createInjector([function() {
|
2011-10-31 22:33:52 +00:00
|
|
|
throw 'MyError';
|
|
|
|
|
}], {});
|
|
|
|
|
}).toThrow('MyError');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('should handle no module alias', function() {
|
|
|
|
|
expect(function() {
|
2011-11-02 04:09:54 +00:00
|
|
|
createInjector([function(dontExist) {
|
2011-10-31 22:33:52 +00:00
|
|
|
}], {});
|
|
|
|
|
}).toThrow("Unknown provider for 'dontExist'.");
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
describe('retrieval', function() {
|
|
|
|
|
var instance,
|
|
|
|
|
$injector,
|
|
|
|
|
$provide;
|
|
|
|
|
|
|
|
|
|
beforeEach(function() {
|
2011-11-02 04:09:54 +00:00
|
|
|
$injector = createInjector([ ['$provide', function(provide) {
|
2011-10-31 22:33:52 +00:00
|
|
|
($provide = provide).value('instance', instance = {name:'angular'});
|
|
|
|
|
}]]);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('should retrieve by name and cache instance', function() {
|
|
|
|
|
expect(instance).toEqual({name: 'angular'});
|
|
|
|
|
expect($injector('instance')).toBe(instance);
|
|
|
|
|
expect($injector('instance')).toBe(instance);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('should call functions and infer arguments', function() {
|
|
|
|
|
expect($injector(function(instance) { return instance; })).toBe(instance);
|
|
|
|
|
expect($injector(function(instance) { return instance; })).toBe(instance);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
describe('method invoking', function() {
|
|
|
|
|
var $injector;
|
|
|
|
|
|
|
|
|
|
beforeEach(function() {
|
2011-11-02 04:09:54 +00:00
|
|
|
$injector = createInjector([ function($provide) {
|
2011-10-31 22:33:52 +00:00
|
|
|
$provide.value('book', 'moby');
|
|
|
|
|
$provide.value('author', 'melville');
|
|
|
|
|
}]);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('should invoke method', function() {
|
|
|
|
|
expect($injector(function(book, author) { return author + ':' + book;})).toEqual('melville:moby');
|
|
|
|
|
expect($injector.invoke($injector, function(book, author) {
|
|
|
|
|
expect(this).toEqual($injector);
|
|
|
|
|
return author + ':' + book;})).toEqual('melville:moby');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
2011-11-02 04:09:54 +00:00
|
|
|
it('should invoke method with locals', function() {
|
|
|
|
|
expect($injector(function(book, author) { return author + ':' + book;})).toEqual('melville:moby');
|
|
|
|
|
expect($injector.invoke($injector,
|
|
|
|
|
function(book, author, chapter) {
|
|
|
|
|
expect(this).toEqual($injector);
|
|
|
|
|
return author + ':' + book + '-' + chapter;
|
|
|
|
|
}, {author:'m', chapter:'ch1'})).toEqual('m:moby-ch1');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
2011-10-31 22:33:52 +00:00
|
|
|
it('should invoke method which is annotated', function() {
|
|
|
|
|
expect($injector(extend(function(b, a) { return a + ':' + b}, {$inject:['book', 'author']}))).
|
|
|
|
|
toEqual('melville:moby');
|
|
|
|
|
expect($injector.invoke($injector, extend(function(b, a) {
|
|
|
|
|
expect(this).toEqual($injector);
|
|
|
|
|
return a + ':' + b;
|
|
|
|
|
}, {$inject:['book', 'author']}))).toEqual('melville:moby');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('should invoke method which is an array of annotation', function() {
|
|
|
|
|
expect($injector(function(book, author) { return author + ':' + book;})).toEqual('melville:moby');
|
|
|
|
|
expect($injector.invoke($injector, function(book, author) {
|
|
|
|
|
expect(this).toEqual($injector);
|
|
|
|
|
return author + ':' + book;
|
|
|
|
|
})).toEqual('melville:moby');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('should throw usefull error on wrong argument type]', function() {
|
|
|
|
|
expect(function(){
|
|
|
|
|
$injector.invoke(null, {});
|
|
|
|
|
}).toThrow("Argument 'fn' is not a function, got Object");
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('service instantiation', function() {
|
|
|
|
|
var $injector;
|
|
|
|
|
|
|
|
|
|
beforeEach(function() {
|
2011-11-02 04:09:54 +00:00
|
|
|
$injector = createInjector([ function($provide) {
|
2011-10-31 22:33:52 +00:00
|
|
|
$provide.value('book', 'moby');
|
|
|
|
|
$provide.value('author', 'melville');
|
|
|
|
|
}]);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function Type(book, author) {
|
|
|
|
|
this.book = book;
|
|
|
|
|
this.author = author;
|
|
|
|
|
}
|
|
|
|
|
Type.prototype.title = function() {
|
|
|
|
|
return this.author + ': ' + this.book;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('should instantiate object and preserve constructor property and be instanceof', function() {
|
|
|
|
|
var t = $injector.instantiate(Type);
|
|
|
|
|
expect(t.book).toEqual('moby');
|
|
|
|
|
expect(t.author).toEqual('melville');
|
|
|
|
|
expect(t.title()).toEqual('melville: moby');
|
|
|
|
|
expect(t instanceof Type).toBe(true);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('should allow constructor to return different object', function() {
|
|
|
|
|
var t = $injector.instantiate(function() { return 'ABC'; });
|
|
|
|
|
expect(t).toBe('ABC');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('should handle constructor exception', function() {
|
|
|
|
|
expect(function() {
|
|
|
|
|
$injector.instantiate(function() { throw 'MyError'; });
|
|
|
|
|
}).toThrow('MyError');
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2011-11-02 04:09:54 +00:00
|
|
|
describe('$eager', function(){
|
|
|
|
|
it('should eagerly instantiate a service if $eager is true', function() {
|
|
|
|
|
var log = [];
|
|
|
|
|
createInjector([function($provide){
|
|
|
|
|
$provide.service('svc1', function() {
|
|
|
|
|
this.$get = function(){
|
|
|
|
|
log.push('svc1');
|
|
|
|
|
}
|
|
|
|
|
this.$eager = true;
|
|
|
|
|
});
|
|
|
|
|
}]);
|
|
|
|
|
expect(log).toEqual(['svc1']);
|
|
|
|
|
});
|
2011-10-31 22:33:52 +00:00
|
|
|
});
|
2011-11-02 04:09:54 +00:00
|
|
|
|
2011-10-31 22:33:52 +00:00
|
|
|
});
|