| 
									
										
										
										
											2015-04-20 15:35:16 +02:00
										 |  |  | import {isBlank, BaseException} from 'angular2/src/facade/lang'; | 
					
						
							| 
									
										
										
										
											2015-02-05 13:08:05 -08:00
										 |  |  | import {describe, ddescribe, it, iit, expect, beforeEach} from 'angular2/test_lib'; | 
					
						
							| 
									
										
										
										
											2015-05-13 15:54:46 -07:00
										 |  |  | import {Injector, bind, ResolvedBinding, Key, forwardRef} from 'angular2/di'; | 
					
						
							| 
									
										
										
										
											2015-05-04 11:11:22 -07:00
										 |  |  | import {Optional, Inject, InjectLazy} from 'angular2/src/di/annotations_impl'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-07 10:34:07 -04:00
										 |  |  | class Engine { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-06 10:13:33 -04:00
										 |  |  | class BrokenEngine { | 
					
						
							|  |  |  |   constructor() { | 
					
						
							| 
									
										
										
										
											2015-04-20 15:35:16 +02:00
										 |  |  |     throw new BaseException("Broken Engine"); | 
					
						
							| 
									
										
										
										
											2014-10-06 10:13:33 -04:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-10-07 10:34:07 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | class DashboardSoftware { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-03 17:26:49 -04:00
										 |  |  | class Dashboard { | 
					
						
							| 
									
										
										
										
											2014-10-07 10:34:07 -04:00
										 |  |  |   constructor(software: DashboardSoftware) {} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TurboEngine extends Engine { | 
					
						
							| 
									
										
										
										
											2014-10-03 17:26:49 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | class Car { | 
					
						
							| 
									
										
										
										
											2014-11-21 21:19:23 -08:00
										 |  |  |   engine:Engine; | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  |   constructor(engine:Engine) { | 
					
						
							|  |  |  |     this.engine = engine; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-06 13:45:24 -04:00
										 |  |  | class CarWithLazyEngine { | 
					
						
							| 
									
										
										
										
											2014-11-21 21:19:23 -08:00
										 |  |  |   engineFactory; | 
					
						
							| 
									
										
										
										
											2014-10-06 13:45:24 -04:00
										 |  |  |   constructor(@InjectLazy(Engine) engineFactory) { | 
					
						
							|  |  |  |     this.engineFactory = engineFactory; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-27 07:42:51 -08:00
										 |  |  | class CarWithOptionalEngine { | 
					
						
							|  |  |  |   engine; | 
					
						
							|  |  |  |   constructor(@Optional() engine:Engine) { | 
					
						
							|  |  |  |     this.engine = engine; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  | class CarWithDashboard { | 
					
						
							| 
									
										
										
										
											2014-11-21 21:19:23 -08:00
										 |  |  |   engine:Engine; | 
					
						
							|  |  |  |   dashboard:Dashboard; | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  |   constructor(engine:Engine, dashboard:Dashboard) { | 
					
						
							|  |  |  |     this.engine = engine; | 
					
						
							|  |  |  |     this.dashboard = dashboard; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class SportsCar extends Car { | 
					
						
							| 
									
										
										
										
											2014-11-21 21:19:23 -08:00
										 |  |  |   engine:Engine; | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  |   constructor(engine:Engine) { | 
					
						
							|  |  |  |     super(engine); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class CarWithInject { | 
					
						
							| 
									
										
										
										
											2014-11-21 21:19:23 -08:00
										 |  |  |   engine:Engine; | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  |   constructor(@Inject(TurboEngine) engine:Engine) { | 
					
						
							|  |  |  |     this.engine = engine; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-06 10:13:33 -04:00
										 |  |  | class CyclicEngine { | 
					
						
							| 
									
										
										
										
											2014-10-07 10:34:07 -04:00
										 |  |  |   constructor(car:Car) {} | 
					
						
							| 
									
										
										
										
											2014-10-06 10:13:33 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-05 16:25:42 -04:00
										 |  |  | class NoAnnotations { | 
					
						
							| 
									
										
										
										
											2014-10-07 10:34:07 -04:00
										 |  |  |   constructor(secretDependency) {} | 
					
						
							| 
									
										
										
										
											2014-10-05 16:25:42 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  | export function main() { | 
					
						
							| 
									
										
										
										
											2014-10-07 10:34:07 -04:00
										 |  |  |   describe('injector', function () { | 
					
						
							| 
									
										
										
										
											2015-04-24 15:19:11 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-07 10:34:07 -04:00
										 |  |  |     it('should instantiate a class without dependencies', function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |       var injector = Injector.resolveAndCreate([Engine]); | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  |       var engine = injector.get(Engine); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(engine).toBeAnInstanceOf(Engine); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-07 10:34:07 -04:00
										 |  |  |     it('should resolve dependencies based on type information', function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |       var injector = Injector.resolveAndCreate([Engine, Car]); | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  |       var car = injector.get(Car); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(car).toBeAnInstanceOf(Car); | 
					
						
							|  |  |  |       expect(car.engine).toBeAnInstanceOf(Engine); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-07 10:34:07 -04:00
										 |  |  |     it('should resolve dependencies based on @Inject annotation', function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |       var injector = Injector.resolveAndCreate([TurboEngine, Engine, CarWithInject]); | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  |       var car = injector.get(CarWithInject); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(car).toBeAnInstanceOf(CarWithInject); | 
					
						
							|  |  |  |       expect(car.engine).toBeAnInstanceOf(TurboEngine); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-05 16:25:42 -04:00
										 |  |  |     it('should throw when no type and not @Inject', function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |       expect(() => Injector.resolveAndCreate([NoAnnotations])).toThrowError( | 
					
						
							| 
									
										
										
										
											2015-04-13 10:05:11 -07:00
										 |  |  |         'Cannot resolve all parameters for NoAnnotations. '+ | 
					
						
							|  |  |  |         'Make sure they all have valid type or annotations.'); | 
					
						
							| 
									
										
										
										
											2014-10-05 16:25:42 -04:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-07 10:34:07 -04:00
										 |  |  |     it('should cache instances', function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |       var injector = Injector.resolveAndCreate([Engine]); | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |       var e1 = injector.get(Engine); | 
					
						
							|  |  |  |       var e2 = injector.get(Engine); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(e1).toBe(e2); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-07 10:34:07 -04:00
										 |  |  |     it('should bind to a value', function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |       var injector = Injector.resolveAndCreate([ | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  |         bind(Engine).toValue("fake engine") | 
					
						
							|  |  |  |       ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var engine = injector.get(Engine); | 
					
						
							|  |  |  |       expect(engine).toEqual("fake engine"); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-07 10:34:07 -04:00
										 |  |  |     it('should bind to a factory', function () { | 
					
						
							| 
									
										
										
										
											2014-10-09 11:35:13 -04:00
										 |  |  |       function sportsCarFactory(e:Engine) { | 
					
						
							|  |  |  |         return new SportsCar(e); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |       var injector = Injector.resolveAndCreate([ | 
					
						
							| 
									
										
										
										
											2014-10-09 11:35:13 -04:00
										 |  |  |         Engine, | 
					
						
							|  |  |  |         bind(Car).toFactory(sportsCarFactory) | 
					
						
							|  |  |  |       ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var car = injector.get(Car); | 
					
						
							|  |  |  |       expect(car).toBeAnInstanceOf(SportsCar); | 
					
						
							|  |  |  |       expect(car.engine).toBeAnInstanceOf(Engine); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-21 15:18:06 +01:00
										 |  |  |     it('should bind to an alias', function() { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |       var injector = Injector.resolveAndCreate([ | 
					
						
							| 
									
										
										
										
											2015-02-21 15:18:06 +01:00
										 |  |  |         Engine, | 
					
						
							|  |  |  |         bind(SportsCar).toClass(SportsCar), | 
					
						
							|  |  |  |         bind(Car).toAlias(SportsCar) | 
					
						
							|  |  |  |       ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var car = injector.get(Car); | 
					
						
							|  |  |  |       var sportsCar = injector.get(SportsCar); | 
					
						
							|  |  |  |       expect(car).toBeAnInstanceOf(SportsCar); | 
					
						
							|  |  |  |       expect(car).toBe(sportsCar); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should throw when the aliased binding does not exist', function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |       var injector = Injector.resolveAndCreate([ | 
					
						
							| 
									
										
										
										
											2015-02-21 15:18:06 +01:00
										 |  |  |         bind('car').toAlias(SportsCar) | 
					
						
							|  |  |  |       ]); | 
					
						
							|  |  |  |       expect(() => injector.get('car')).toThrowError('No provider for SportsCar! (car -> SportsCar)'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-09 11:35:13 -04:00
										 |  |  |     it('should support overriding factory dependencies', function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |       var injector = Injector.resolveAndCreate([ | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  |         Engine, | 
					
						
							| 
									
										
										
										
											2014-10-10 09:56:43 -04:00
										 |  |  |         bind(Car).toFactory((e) => new SportsCar(e), [Engine]) | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  |       ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var car = injector.get(Car); | 
					
						
							|  |  |  |       expect(car).toBeAnInstanceOf(SportsCar); | 
					
						
							|  |  |  |       expect(car.engine).toBeAnInstanceOf(Engine); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-27 07:42:51 -08:00
										 |  |  |     it('should support optional dependencies', function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |       var injector = Injector.resolveAndCreate([ | 
					
						
							| 
									
										
										
										
											2015-02-27 07:42:51 -08:00
										 |  |  |         CarWithOptionalEngine | 
					
						
							|  |  |  |       ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var car = injector.get(CarWithOptionalEngine); | 
					
						
							|  |  |  |       expect(car.engine).toEqual(null); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-09 12:18:35 -04:00
										 |  |  |     it("should flatten passed-in bindings", function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |       var injector = Injector.resolveAndCreate([ | 
					
						
							| 
									
										
										
										
											2014-10-09 12:18:35 -04:00
										 |  |  |         [[Engine, Car]] | 
					
						
							|  |  |  |       ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var car = injector.get(Car); | 
					
						
							|  |  |  |       expect(car).toBeAnInstanceOf(Car); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-08 09:11:33 -08:00
										 |  |  |     it("should use the last binding "+ | 
					
						
							|  |  |  |       "when there are mutliple bindings for same token", function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |       var injector = Injector.resolveAndCreate([ | 
					
						
							| 
									
										
										
										
											2015-01-08 09:11:33 -08:00
										 |  |  |         bind(Engine).toClass(Engine), | 
					
						
							|  |  |  |         bind(Engine).toClass(TurboEngine) | 
					
						
							|  |  |  |       ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(injector.get(Engine)).toBeAnInstanceOf(TurboEngine); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-07 10:34:07 -04:00
										 |  |  |     it('should use non-type tokens', function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |       var injector = Injector.resolveAndCreate([ | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  |         bind('token').toValue('value') | 
					
						
							|  |  |  |       ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(injector.get('token')).toEqual('value'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-07 10:34:07 -04:00
										 |  |  |     it('should throw when given invalid bindings', function () { | 
					
						
							| 
									
										
										
										
											2015-04-28 14:24:20 +02:00
										 |  |  |       expect(() => Injector.resolveAndCreate(["blah"])) | 
					
						
							|  |  |  |         .toThrowError('Invalid binding - only instances of Binding and Type are allowed, got: blah'); | 
					
						
							|  |  |  |       expect(() => Injector.resolveAndCreate([bind("blah")])) | 
					
						
							|  |  |  |         .toThrowError('Invalid binding - only instances of Binding and Type are allowed, ' + | 
					
						
							| 
									
										
										
										
											2015-04-24 15:19:11 -07:00
										 |  |  |         'got: blah'); | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-07 10:34:07 -04:00
										 |  |  |     it('should provide itself', function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |       var parent = Injector.resolveAndCreate([]); | 
					
						
							|  |  |  |       var child = parent.resolveAndCreateChild([]); | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |       expect(child.get(Injector)).toBe(child); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-07 10:34:07 -04:00
										 |  |  |     it('should throw when no provider defined', function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |       var injector = Injector.resolveAndCreate([]); | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  |       expect(() => injector.get('NonExisting')).toThrowError('No provider for NonExisting!'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-07 10:34:07 -04:00
										 |  |  |     it('should show the full path when no provider', function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |       var injector = Injector.resolveAndCreate([CarWithDashboard, Engine, Dashboard]); | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  |       expect(() => injector.get(CarWithDashboard)). | 
					
						
							| 
									
										
										
										
											2014-10-03 17:26:49 -04:00
										 |  |  |         toThrowError('No provider for DashboardSoftware! (CarWithDashboard -> Dashboard -> DashboardSoftware)'); | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2014-10-06 10:13:33 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-07 10:34:07 -04:00
										 |  |  |     it('should throw when trying to instantiate a cyclic dependency', function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |       var injector = Injector.resolveAndCreate([ | 
					
						
							| 
									
										
										
										
											2014-10-06 10:13:33 -04:00
										 |  |  |         Car, | 
					
						
							|  |  |  |         bind(Engine).toClass(CyclicEngine) | 
					
						
							|  |  |  |       ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(() => injector.get(Car)) | 
					
						
							|  |  |  |         .toThrowError('Cannot instantiate cyclic dependency! (Car -> Engine -> Car)'); | 
					
						
							| 
									
										
										
										
											2014-10-06 16:24:12 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |       expect(() => injector.asyncGet(Car)) | 
					
						
							|  |  |  |         .toThrowError('Cannot instantiate cyclic dependency! (Car -> Engine -> Car)'); | 
					
						
							| 
									
										
										
										
											2014-10-06 10:13:33 -04:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-07 10:34:07 -04:00
										 |  |  |     it('should show the full path when error happens in a constructor', function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |       var injector = Injector.resolveAndCreate([ | 
					
						
							| 
									
										
										
										
											2014-10-06 10:13:33 -04:00
										 |  |  |         Car, | 
					
						
							|  |  |  |         bind(Engine).toClass(BrokenEngine) | 
					
						
							|  |  |  |       ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       try { | 
					
						
							|  |  |  |         injector.get(Car); | 
					
						
							|  |  |  |         throw "Must throw"; | 
					
						
							|  |  |  |       } catch (e) { | 
					
						
							|  |  |  |         expect(e.message).toContain("Error during instantiation of Engine! (Car -> Engine)"); | 
					
						
							| 
									
										
										
										
											2015-04-20 15:35:16 +02:00
										 |  |  |         expect(e.cause instanceof BaseException).toBeTruthy(); | 
					
						
							|  |  |  |         expect(e.causeKey.token).toEqual(Engine); | 
					
						
							| 
									
										
										
										
											2014-10-06 10:13:33 -04:00
										 |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2014-10-06 13:45:24 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-09 11:03:36 -04:00
										 |  |  |     it('should instantiate an object after a failed attempt', function () { | 
					
						
							|  |  |  |       var isBroken = true; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |       var injector = Injector.resolveAndCreate([ | 
					
						
							| 
									
										
										
										
											2014-10-09 11:03:36 -04:00
										 |  |  |         Car, | 
					
						
							| 
									
										
										
										
											2014-10-09 11:35:13 -04:00
										 |  |  |         bind(Engine).toFactory(() => isBroken ? new BrokenEngine() : new Engine()) | 
					
						
							| 
									
										
										
										
											2014-10-09 11:03:36 -04:00
										 |  |  |       ]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-10 10:00:23 -04:00
										 |  |  |       expect(() => injector.get(Car)).toThrowError(new RegExp("Error")); | 
					
						
							| 
									
										
										
										
											2014-10-09 11:03:36 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |       isBroken = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(injector.get(Car)).toBeAnInstanceOf(Car); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-11 15:14:16 +01:00
										 |  |  |     it('should support null values', () => { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |       var injector = Injector.resolveAndCreate([bind('null').toValue(null)]); | 
					
						
							| 
									
										
										
										
											2015-03-11 15:14:16 +01:00
										 |  |  |       expect(injector.get('null')).toBe(null); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-10 11:36:06 -04:00
										 |  |  |     describe("default bindings", function () { | 
					
						
							|  |  |  |       it("should be used when no matching binding found", function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |         var injector = Injector.resolveAndCreate([], {defaultBindings: true}); | 
					
						
							| 
									
										
										
										
											2014-10-10 11:36:06 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         var car = injector.get(Car); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(car).toBeAnInstanceOf(Car); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it("should use the matching binding when it is available", function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |         var injector = Injector.resolveAndCreate([ | 
					
						
							| 
									
										
										
										
											2014-10-10 11:36:06 -04:00
										 |  |  |           bind(Car).toClass(SportsCar) | 
					
						
							|  |  |  |         ], {defaultBindings: true}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         var car = injector.get(Car); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(car).toBeAnInstanceOf(SportsCar); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2014-10-06 13:45:24 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     describe("child", function () { | 
					
						
							| 
									
										
										
										
											2014-10-07 10:34:07 -04:00
										 |  |  |       it('should load instances from parent injector', function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |         var parent = Injector.resolveAndCreate([Engine]); | 
					
						
							|  |  |  |         var child = parent.resolveAndCreateChild([]); | 
					
						
							| 
									
										
										
										
											2014-10-06 13:45:24 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         var engineFromParent = parent.get(Engine); | 
					
						
							|  |  |  |         var engineFromChild = child.get(Engine); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(engineFromChild).toBe(engineFromParent); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-05 09:44:50 -08:00
										 |  |  |       it("should not use the child bindings when resolving the dependencies of a parent binding", function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |         var parent = Injector.resolveAndCreate([ | 
					
						
							| 
									
										
										
										
											2015-02-05 09:44:50 -08:00
										 |  |  |           Car, Engine | 
					
						
							|  |  |  |         ]); | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |         var child = parent.resolveAndCreateChild([ | 
					
						
							| 
									
										
										
										
											2015-02-05 09:44:50 -08:00
										 |  |  |           bind(Engine).toClass(TurboEngine) | 
					
						
							|  |  |  |         ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         var carFromChild = child.get(Car); | 
					
						
							|  |  |  |         expect(carFromChild.engine).toBeAnInstanceOf(Engine); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-07 10:34:07 -04:00
										 |  |  |       it('should create new instance in a child injector', function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |         var parent = Injector.resolveAndCreate([Engine]); | 
					
						
							|  |  |  |         var child = parent.resolveAndCreateChild([ | 
					
						
							| 
									
										
										
										
											2014-10-06 13:45:24 -04:00
										 |  |  |           bind(Engine).toClass(TurboEngine) | 
					
						
							|  |  |  |         ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         var engineFromParent = parent.get(Engine); | 
					
						
							|  |  |  |         var engineFromChild = child.get(Engine); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(engineFromParent).not.toBe(engineFromChild); | 
					
						
							|  |  |  |         expect(engineFromChild).toBeAnInstanceOf(TurboEngine); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2014-10-10 11:36:06 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it("should create child injectors without default bindings", function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |         var parent = Injector.resolveAndCreate([], {defaultBindings: true}); | 
					
						
							|  |  |  |         var child = parent.resolveAndCreateChild([]); | 
					
						
							| 
									
										
										
										
											2014-10-10 11:36:06 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         //child delegates to parent the creation of Car
 | 
					
						
							|  |  |  |         var childCar = child.get(Car); | 
					
						
							|  |  |  |         var parentCar = parent.get(Car); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(childCar).toBe(parentCar); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2015-05-08 16:24:17 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it("should give access to direct parent", () => { | 
					
						
							|  |  |  |         var parent = Injector.resolveAndCreate([]); | 
					
						
							|  |  |  |         var child = parent.resolveAndCreateChild([]); | 
					
						
							|  |  |  |         expect(child.parent).toBe(parent); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2014-10-06 13:45:24 -04:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     describe("lazy", function () { | 
					
						
							|  |  |  |       it("should create dependencies lazily", function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |         var injector = Injector.resolveAndCreate([ | 
					
						
							| 
									
										
										
										
											2014-10-06 13:45:24 -04:00
										 |  |  |           Engine, | 
					
						
							|  |  |  |           CarWithLazyEngine | 
					
						
							|  |  |  |         ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         var car = injector.get(CarWithLazyEngine); | 
					
						
							|  |  |  |         expect(car.engineFactory()).toBeAnInstanceOf(Engine); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it("should cache instance created lazily", function () { | 
					
						
							| 
									
										
										
										
											2015-04-10 17:05:31 -07:00
										 |  |  |         var injector = Injector.resolveAndCreate([ | 
					
						
							| 
									
										
										
										
											2014-10-06 13:45:24 -04:00
										 |  |  |           Engine, | 
					
						
							|  |  |  |           CarWithLazyEngine | 
					
						
							|  |  |  |         ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         var car = injector.get(CarWithLazyEngine); | 
					
						
							|  |  |  |         var e1 = car.engineFactory(); | 
					
						
							|  |  |  |         var e2 = car.engineFactory(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(e1).toBe(e2); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-04-11 16:57:42 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     describe('resolve', function() { | 
					
						
							| 
									
										
										
										
											2015-05-13 15:54:46 -07:00
										 |  |  |       it('should resolve and flatten', () => { | 
					
						
							| 
									
										
										
										
											2015-04-11 16:57:42 -07:00
										 |  |  |         var bindings = Injector.resolve([Engine, [BrokenEngine]]); | 
					
						
							|  |  |  |         bindings.forEach(function(b) { | 
					
						
							|  |  |  |           if (isBlank(b)) return;  // the result is a sparse array
 | 
					
						
							|  |  |  |           expect(b instanceof ResolvedBinding).toBe(true); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2015-05-13 15:54:46 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it('should resolve forward references', () => { | 
					
						
							|  |  |  |         var bindings = Injector.resolve([ | 
					
						
							|  |  |  |           forwardRef(() => Engine), | 
					
						
							|  |  |  |           [ bind(forwardRef(() => BrokenEngine)).toClass(forwardRef(() => Engine)) ], | 
					
						
							|  |  |  |           bind(forwardRef(() => String)).toFactory(() => 'OK', [forwardRef(() => Engine)]), | 
					
						
							|  |  |  |           bind(forwardRef(() => DashboardSoftware)).toAsyncFactory(() => 123, [forwardRef(() => BrokenEngine)]) | 
					
						
							|  |  |  |         ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         var engineBinding = bindings[Key.get(Engine).id]; | 
					
						
							|  |  |  |         var brokenEngineBinding = bindings[Key.get(BrokenEngine).id]; | 
					
						
							|  |  |  |         var stringBinding = bindings[Key.get(String).id]; | 
					
						
							|  |  |  |         var dashboardSoftwareBinding = bindings[Key.get(DashboardSoftware).id]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(engineBinding.factory() instanceof Engine).toBe(true); | 
					
						
							|  |  |  |         expect(brokenEngineBinding.factory() instanceof Engine).toBe(true); | 
					
						
							|  |  |  |         expect(stringBinding.dependencies[0].key).toEqual(Key.get(Engine)); | 
					
						
							|  |  |  |         expect(dashboardSoftwareBinding.dependencies[0].key).toEqual(Key.get(BrokenEngine)); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2015-04-11 16:57:42 -07:00
										 |  |  |     }); | 
					
						
							| 
									
										
										
										
											2014-09-30 14:56:33 -04:00
										 |  |  |   }); | 
					
						
							| 
									
										
										
										
											2015-02-21 15:18:06 +01:00
										 |  |  | } |