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();
 | |
|       });
 | |
|     });
 | |
|   });
 | |
| }
 |