import { AsyncTestCompleter, beforeEach, ddescribe, describe, expect, iit, inject, it, xit, } from 'angular2/test_lib'; import {Injector, bind, Key} from 'angular2/di'; import {Inject, InjectPromise} from 'angular2/src/di/annotations_impl'; import {Promise, PromiseWrapper} from 'angular2/src/facade/async'; class UserList { } function fetchUsers() { return PromiseWrapper.resolve(new UserList()); } class SynchronousUserList { } class UserController { list:UserList; constructor(list:UserList) { this.list = list; } } 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! (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('Cannot instantiate UserList synchronously. It is provided as a promise! (UserController -> UserList)'); }); 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(); }); }); }); }