179 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
		
		
			
		
	
	
			179 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
|  | import { | ||
|  |   AsyncTestCompleter, | ||
|  |   beforeEach, | ||
|  |   ddescribe, | ||
|  |   describe, | ||
|  |   expect, | ||
|  |   iit, | ||
|  |   inject, | ||
|  |   it, | ||
|  |   xit, | ||
|  | } from 'angular2/test_lib'; | ||
|  | import {Injector, bind, Key} from 'angular2/di'; | ||
|  | import {Inject, InjectPromise, Injectable} from 'angular2/src/di/decorators'; | ||
|  | import {Promise, PromiseWrapper} from 'angular2/src/facade/async'; | ||
|  | import {stringify} from 'angular2/src/facade/lang'; | ||
|  | 
 | ||
|  | class UserList {} | ||
|  | 
 | ||
|  | function fetchUsers() { | ||
|  |   return PromiseWrapper.resolve(new UserList()); | ||
|  | } | ||
|  | 
 | ||
|  | class SynchronousUserList {} | ||
|  | 
 | ||
|  | @Injectable() | ||
|  | class UserController { | ||
|  |   list: UserList; | ||
|  |   constructor(list: UserList) { this.list = list; } | ||
|  | } | ||
|  | 
 | ||
|  | @Injectable() | ||
|  | class AsyncUserController { | ||
|  |   userList; | ||
|  |   constructor(@InjectPromise(UserList) userList) { this.userList = userList; } | ||
|  | } | ||
|  | 
 | ||
|  | export function main() { | ||
|  |   describe("async injection", function() { | ||
|  | 
 | ||
|  |     describe("asyncGet", function() { | ||
|  |       it('should return a promise', function() { | ||
|  |         var injector = Injector.resolveAndCreate([bind(UserList).toAsyncFactory(fetchUsers)]); | ||
|  |         var p = injector.asyncGet(UserList); | ||
|  |         expect(p).toBePromise(); | ||
|  |       }); | ||
|  | 
 | ||
|  |       it('should return a promise when the binding is sync', function() { | ||
|  |         var injector = Injector.resolveAndCreate([SynchronousUserList]); | ||
|  |         var p = injector.asyncGet(SynchronousUserList); | ||
|  |         expect(p).toBePromise(); | ||
|  |       }); | ||
|  | 
 | ||
|  |       it("should return a promise when the binding is sync (from cache)", function() { | ||
|  |         var injector = Injector.resolveAndCreate([UserList]); | ||
|  |         expect(injector.get(UserList)).toBeAnInstanceOf(UserList); | ||
|  |         expect(injector.asyncGet(UserList)).toBePromise(); | ||
|  |       }); | ||
|  | 
 | ||
|  |       it('should return the injector', inject([AsyncTestCompleter], (async) => { | ||
|  |            var injector = Injector.resolveAndCreate([]); | ||
|  |            var p = injector.asyncGet(Injector); | ||
|  |            p.then(function(injector) { | ||
|  |              expect(injector).toBe(injector); | ||
|  |              async.done(); | ||
|  |            }); | ||
|  |          })); | ||
|  | 
 | ||
|  |       it('should return a promise when instantiating a sync binding ' + | ||
|  |              'with an async dependency', | ||
|  |          inject([AsyncTestCompleter], (async) => { | ||
|  |            var injector = | ||
|  |                Injector | ||
|  |                    .resolveAndCreate([bind(UserList).toAsyncFactory(fetchUsers), UserController]); | ||
|  | 
 | ||
|  |            injector.asyncGet(UserController) | ||
|  |                .then(function(userController) { | ||
|  |                  expect(userController).toBeAnInstanceOf(UserController); | ||
|  |                  expect(userController.list).toBeAnInstanceOf(UserList); | ||
|  |                  async.done(); | ||
|  |                }); | ||
|  |          })); | ||
|  | 
 | ||
|  |       it("should create only one instance (async + async)", | ||
|  |          inject([AsyncTestCompleter], (async) => { | ||
|  |            var injector = Injector.resolveAndCreate([bind(UserList).toAsyncFactory(fetchUsers)]); | ||
|  | 
 | ||
|  |            var ul1 = injector.asyncGet(UserList); | ||
|  |            var ul2 = injector.asyncGet(UserList); | ||
|  | 
 | ||
|  |            PromiseWrapper.all([ul1, ul2]) | ||
|  |                .then(function(uls) { | ||
|  |                  expect(uls[0]).toBe(uls[1]); | ||
|  |                  async.done(); | ||
|  |                }); | ||
|  |          })); | ||
|  | 
 | ||
|  |       it("should create only one instance (sync + async)", inject([AsyncTestCompleter], (async) => { | ||
|  |            var injector = Injector.resolveAndCreate([UserList]); | ||
|  | 
 | ||
|  |            var promise = injector.asyncGet(UserList); | ||
|  |            var ul = injector.get(UserList); | ||
|  | 
 | ||
|  |            expect(promise).toBePromise(); | ||
|  |            expect(ul).toBeAnInstanceOf(UserList); | ||
|  | 
 | ||
|  |            promise.then(function(ful) { | ||
|  |              expect(ful).toBe(ul); | ||
|  |              async.done(); | ||
|  |            }); | ||
|  |          })); | ||
|  | 
 | ||
|  |       it('should show the full path when error happens in a constructor', | ||
|  |          inject([AsyncTestCompleter], (async) => { | ||
|  |            var injector = Injector.resolveAndCreate([ | ||
|  |              UserController, | ||
|  |              bind(UserList).toAsyncFactory(function() { throw "Broken UserList"; }) | ||
|  |            ]); | ||
|  | 
 | ||
|  |            var promise = injector.asyncGet(UserController); | ||
|  |            PromiseWrapper.then(promise, null, function(e) { | ||
|  |              expect(e.message).toContain( | ||
|  |                  `Error during instantiation of UserList! (${stringify(UserController)} -> UserList)`); | ||
|  |              async.done(); | ||
|  |            }); | ||
|  |          })); | ||
|  |     }); | ||
|  | 
 | ||
|  |     describe("get", function() { | ||
|  |       it('should throw when instantiating an async binding', function() { | ||
|  |         var injector = Injector.resolveAndCreate([bind(UserList).toAsyncFactory(fetchUsers)]); | ||
|  | 
 | ||
|  |         expect(() => injector.get(UserList)) | ||
|  |             .toThrowError( | ||
|  |                 'Cannot instantiate UserList synchronously. It is provided as a promise!'); | ||
|  |       }); | ||
|  | 
 | ||
|  |       it('should throw when instantiating a sync binding with an async dependency', function() { | ||
|  |         var injector = | ||
|  |             Injector.resolveAndCreate([bind(UserList).toAsyncFactory(fetchUsers), UserController]); | ||
|  | 
 | ||
|  |         expect(() => injector.get(UserController)) | ||
|  |             .toThrowError(new RegExp( | ||
|  |                 'Cannot instantiate UserList synchronously. It is provided as a promise!')); | ||
|  |       }); | ||
|  | 
 | ||
|  |       it('should not throw when instantiating a sync binding with a resolved async dependency', | ||
|  |          inject([AsyncTestCompleter], (async) => { | ||
|  |            var injector = | ||
|  |                Injector | ||
|  |                    .resolveAndCreate([bind(UserList).toAsyncFactory(fetchUsers), UserController]); | ||
|  | 
 | ||
|  |            injector.asyncGet(UserList).then((_) => { | ||
|  |              expect(() => { injector.get(UserController); }).not.toThrow(); | ||
|  |              async.done(); | ||
|  |            }); | ||
|  |          })); | ||
|  | 
 | ||
|  |       it('should resolve synchronously when an async dependency requested as a promise', | ||
|  |          function() { | ||
|  |            var injector = Injector.resolveAndCreate( | ||
|  |                [bind(UserList).toAsyncFactory(fetchUsers), AsyncUserController]); | ||
|  |            var controller = injector.get(AsyncUserController); | ||
|  | 
 | ||
|  |            expect(controller).toBeAnInstanceOf(AsyncUserController); | ||
|  |            expect(controller.userList).toBePromise(); | ||
|  |          }); | ||
|  | 
 | ||
|  |       it('should wrap sync dependencies into promises if required', function() { | ||
|  |         var injector = Injector.resolveAndCreate( | ||
|  |             [bind(UserList).toFactory(() => new UserList()), AsyncUserController]); | ||
|  |         var controller = injector.get(AsyncUserController); | ||
|  | 
 | ||
|  |         expect(controller).toBeAnInstanceOf(AsyncUserController); | ||
|  |         expect(controller.userList).toBePromise(); | ||
|  |       }); | ||
|  |     }); | ||
|  |   }); | ||
|  | } |