diff --git a/modules/angular2/src/di/forward_ref.ts b/modules/angular2/src/di/forward_ref.ts index 0c393d63fc..2db7d4983e 100644 --- a/modules/angular2/src/di/forward_ref.ts +++ b/modules/angular2/src/di/forward_ref.ts @@ -1,6 +1,6 @@ import {Type} from 'angular2/src/facade/lang'; -export interface ForwardRefFn { (): Type; } +export interface ForwardRefFn { (): any; } /** * Allows to refer to references which are not yet defined. diff --git a/modules/angular2/src/test_lib/test_lib.ts b/modules/angular2/src/test_lib/test_lib.ts index 8b1d742cce..adb6a14861 100644 --- a/modules/angular2/src/test_lib/test_lib.ts +++ b/modules/angular2/src/test_lib/test_lib.ts @@ -21,7 +21,7 @@ export var afterEach = _global.afterEach; export interface NgMatchers extends jasmine.Matchers { toBe(expected: any): boolean; toEqual(expected: any): boolean; - toBePromise(expected: any): boolean; + toBePromise(): boolean; toBeAnInstanceOf(expected: any): boolean; toHaveText(expected: any): boolean; toImplement(expected: any): boolean; diff --git a/modules/angular2/src/util/decorators.ts b/modules/angular2/src/util/decorators.ts index b2e63ae296..44cbc35b6a 100644 --- a/modules/angular2/src/util/decorators.ts +++ b/modules/angular2/src/util/decorators.ts @@ -9,6 +9,7 @@ export function makeDecorator(annotationCls) { var annotationInstance = Object.create(annotationCls.prototype); annotationCls.apply(annotationInstance, args); return function(cls) { + var annotations = Reflect.getMetadata('annotations', cls); annotations = annotations || []; annotations.push(annotationInstance); diff --git a/modules/angular2/test/di/async_spec.js b/modules/angular2/test/di/async_spec.js deleted file mode 100644 index 11533438ba..0000000000 --- a/modules/angular2/test/di/async_spec.js +++ /dev/null @@ -1,194 +0,0 @@ -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(); - }); - }); - }); -} diff --git a/modules/angular2/test/di/async_spec.ts b/modules/angular2/test/di/async_spec.ts new file mode 100644 index 0000000000..4e2980745c --- /dev/null +++ b/modules/angular2/test/di/async_spec.ts @@ -0,0 +1,178 @@ +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(); + }); + }); + }); +} diff --git a/modules/angular2/test/di/forward_ref_spec.js b/modules/angular2/test/di/forward_ref_spec.ts similarity index 92% rename from modules/angular2/test/di/forward_ref_spec.js rename to modules/angular2/test/di/forward_ref_spec.ts index df00947c45..779ecf8a3d 100644 --- a/modules/angular2/test/di/forward_ref_spec.js +++ b/modules/angular2/test/di/forward_ref_spec.ts @@ -13,7 +13,7 @@ import {forwardRef, resolveForwardRef} from 'angular2/di'; import {Type} from 'angular2/src/facade/lang'; export function main() { - describe("forwardRef", function () { + describe("forwardRef", function() { it('should wrap and unwrap the reference', () => { var ref = forwardRef(() => String); expect(ref instanceof Type).toBe(true); diff --git a/modules/angular2/test/di/injector_spec.js b/modules/angular2/test/di/injector_spec.ts similarity index 51% rename from modules/angular2/test/di/injector_spec.js rename to modules/angular2/test/di/injector_spec.ts index c88c7667be..95442ca476 100644 --- a/modules/angular2/test/di/injector_spec.js +++ b/modules/angular2/test/di/injector_spec.ts @@ -1,76 +1,77 @@ -import {isBlank, BaseException} from 'angular2/src/facade/lang'; +import {isBlank, BaseException, stringify} from 'angular2/src/facade/lang'; import {describe, ddescribe, it, iit, expect, beforeEach} from 'angular2/test_lib'; -import {Injector, bind, ResolvedBinding, Key, forwardRef, DependencyAnnotation} from 'angular2/di'; -import {Optional, Inject, InjectLazy} from 'angular2/src/di/annotations_impl'; +import { + Injector, + bind, + ResolvedBinding, + Key, + forwardRef, + DependencyAnnotation, + Injectable +} from 'angular2/di'; +import {Optional, Inject, InjectLazy} from 'angular2/src/di/decorators'; +import * as ann from 'angular2/src/di/annotations_impl'; -class CustomDependencyAnnotation extends DependencyAnnotation { -} +class CustomDependencyAnnotation extends DependencyAnnotation {} -class Engine { -} +class Engine {} class BrokenEngine { - constructor() { - throw new BaseException("Broken Engine"); - } + constructor() { throw new BaseException("Broken Engine"); } } -class DashboardSoftware { -} +class DashboardSoftware {} +@Injectable() class Dashboard { constructor(software: DashboardSoftware) {} } -class TurboEngine extends Engine { -} +class TurboEngine extends Engine {} +@Injectable() class Car { - engine:Engine; - constructor(engine:Engine) { - this.engine = engine; - } + engine: Engine; + constructor(engine: Engine) { this.engine = engine; } } +@Injectable() class CarWithLazyEngine { engineFactory; - constructor(@InjectLazy(Engine) engineFactory) { - this.engineFactory = engineFactory; - } + constructor(@InjectLazy(Engine) engineFactory) { this.engineFactory = engineFactory; } } +@Injectable() class CarWithOptionalEngine { engine; - constructor(@Optional() engine:Engine) { - this.engine = engine; - } + constructor(@Optional() engine: Engine) { this.engine = engine; } } +@Injectable() class CarWithDashboard { - engine:Engine; - dashboard:Dashboard; - constructor(engine:Engine, dashboard:Dashboard) { + engine: Engine; + dashboard: Dashboard; + constructor(engine: Engine, dashboard: Dashboard) { this.engine = engine; this.dashboard = dashboard; } } +@Injectable() class SportsCar extends Car { - engine:Engine; - constructor(engine:Engine) { - super(engine); - } + engine: Engine; + constructor(engine: Engine) { super(engine); } } +@Injectable() class CarWithInject { - engine:Engine; - constructor(@Inject(TurboEngine) engine:Engine) { - this.engine = engine; - } + engine: Engine; + constructor(@Inject(TurboEngine) engine: Engine) { this.engine = engine; } } +@Injectable() class CyclicEngine { - constructor(car:Car) {} + constructor(car: Car) {} } class NoAnnotations { @@ -78,16 +79,16 @@ class NoAnnotations { } export function main() { - describe('injector', function () { + describe('injector', function() { - it('should instantiate a class without dependencies', function () { + it('should instantiate a class without dependencies', function() { var injector = Injector.resolveAndCreate([Engine]); var engine = injector.get(Engine); expect(engine).toBeAnInstanceOf(Engine); }); - it('should resolve dependencies based on type information', function () { + it('should resolve dependencies based on type information', function() { var injector = Injector.resolveAndCreate([Engine, Car]); var car = injector.get(Car); @@ -95,7 +96,7 @@ export function main() { expect(car.engine).toBeAnInstanceOf(Engine); }); - it('should resolve dependencies based on @Inject annotation', function () { + it('should resolve dependencies based on @Inject annotation', function() { var injector = Injector.resolveAndCreate([TurboEngine, Engine, CarWithInject]); var car = injector.get(CarWithInject); @@ -103,13 +104,13 @@ export function main() { expect(car.engine).toBeAnInstanceOf(TurboEngine); }); - it('should throw when no type and not @Inject', function () { - expect(() => Injector.resolveAndCreate([NoAnnotations])).toThrowError( - 'Cannot resolve all parameters for NoAnnotations. '+ - 'Make sure they all have valid type or annotations.'); + it('should throw when no type and not @Inject', function() { + expect(() => Injector.resolveAndCreate([NoAnnotations])) + .toThrowError('Cannot resolve all parameters for NoAnnotations. ' + + 'Make sure they all have valid type or annotations.'); }); - it('should cache instances', function () { + it('should cache instances', function() { var injector = Injector.resolveAndCreate([Engine]); var e1 = injector.get(Engine); @@ -118,24 +119,18 @@ export function main() { expect(e1).toBe(e2); }); - it('should bind to a value', function () { - var injector = Injector.resolveAndCreate([ - bind(Engine).toValue("fake engine") - ]); + it('should bind to a value', function() { + var injector = Injector.resolveAndCreate([bind(Engine).toValue("fake engine")]); var engine = injector.get(Engine); expect(engine).toEqual("fake engine"); }); - it('should bind to a factory', function () { - function sportsCarFactory(e:Engine) { - return new SportsCar(e); - } + it('should bind to a factory', function() { + function sportsCarFactory(e) { return new SportsCar(e); } - var injector = Injector.resolveAndCreate([ - Engine, - bind(Car).toFactory(sportsCarFactory) - ]); + var injector = + Injector.resolveAndCreate([Engine, bind(Car).toFactory(sportsCarFactory, [Engine])]); var car = injector.get(Car); expect(car).toBeAnInstanceOf(SportsCar); @@ -143,11 +138,8 @@ export function main() { }); it('should bind to an alias', function() { - var injector = Injector.resolveAndCreate([ - Engine, - bind(SportsCar).toClass(SportsCar), - bind(Car).toAlias(SportsCar) - ]); + var injector = Injector.resolveAndCreate( + [Engine, bind(SportsCar).toClass(SportsCar), bind(Car).toAlias(SportsCar)]); var car = injector.get(Car); var sportsCar = injector.get(SportsCar); @@ -155,130 +147,118 @@ export function main() { expect(car).toBe(sportsCar); }); - it('should throw when the aliased binding does not exist', function () { - var injector = Injector.resolveAndCreate([ - bind('car').toAlias(SportsCar) - ]); - expect(() => injector.get('car')).toThrowError('No provider for SportsCar! (car -> SportsCar)'); + it('should throw when the aliased binding does not exist', function() { + var injector = Injector.resolveAndCreate([bind('car').toAlias(SportsCar)]); + var e = `No provider for ${stringify(SportsCar)}! (car -> ${stringify(SportsCar)})`; + expect(() => injector.get('car')).toThrowError(e); }); - it('should handle forwardRef in toAlias', function () { + it('should handle forwardRef in toAlias', function() { var injector = Injector.resolveAndCreate([ - bind('originalEngine').toClass(forwardRef(() => Engine)), + bind('originalEngine') + .toClass(forwardRef(() => Engine)), bind('aliasedEngine').toAlias(forwardRef(() => 'originalEngine')) ]); expect(injector.get('aliasedEngine')).toBeAnInstanceOf(Engine); }); - it('should support overriding factory dependencies', function () { - var injector = Injector.resolveAndCreate([ - Engine, - bind(Car).toFactory((e) => new SportsCar(e), [Engine]) - ]); + it('should support overriding factory dependencies', function() { + var injector = + Injector + .resolveAndCreate([Engine, bind(Car).toFactory((e) => new SportsCar(e), [Engine])]); var car = injector.get(Car); expect(car).toBeAnInstanceOf(SportsCar); expect(car.engine).toBeAnInstanceOf(Engine); }); - it('should support optional dependencies', function () { - var injector = Injector.resolveAndCreate([ - CarWithOptionalEngine - ]); + it('should support optional dependencies', function() { + var injector = Injector.resolveAndCreate([CarWithOptionalEngine]); var car = injector.get(CarWithOptionalEngine); expect(car.engine).toEqual(null); }); - it("should flatten passed-in bindings", function () { - var injector = Injector.resolveAndCreate([ - [[Engine, Car]] - ]); + it("should flatten passed-in bindings", function() { + var injector = Injector.resolveAndCreate([[[Engine, Car]]]); var car = injector.get(Car); expect(car).toBeAnInstanceOf(Car); }); - it("should use the last binding "+ - "when there are mutliple bindings for same token", function () { - var injector = Injector.resolveAndCreate([ - bind(Engine).toClass(Engine), - bind(Engine).toClass(TurboEngine) - ]); + it("should use the last binding " + "when there are multiple bindings for same token", + function() { + var injector = Injector.resolveAndCreate( + [bind(Engine).toClass(Engine), bind(Engine).toClass(TurboEngine)]); - expect(injector.get(Engine)).toBeAnInstanceOf(TurboEngine); - }); + expect(injector.get(Engine)).toBeAnInstanceOf(TurboEngine); + }); - it('should use non-type tokens', function () { - var injector = Injector.resolveAndCreate([ - bind('token').toValue('value') - ]); + it('should use non-type tokens', function() { + var injector = Injector.resolveAndCreate([bind('token').toValue('value')]); expect(injector.get('token')).toEqual('value'); }); - it('should throw when given invalid bindings', function () { - 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, ' + - 'got: blah'); + it('should throw when given invalid bindings', function() { + 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, ' + + 'got: blah'); }); - it('should provide itself', function () { + it('should provide itself', function() { var parent = Injector.resolveAndCreate([]); var child = parent.resolveAndCreateChild([]); expect(child.get(Injector)).toBe(child); }); - it('should throw when no provider defined', function () { + it('should throw when no provider defined', function() { var injector = Injector.resolveAndCreate([]); expect(() => injector.get('NonExisting')).toThrowError('No provider for NonExisting!'); }); - it('should show the full path when no provider', function () { + it('should show the full path when no provider', function() { var injector = Injector.resolveAndCreate([CarWithDashboard, Engine, Dashboard]); - expect(() => injector.get(CarWithDashboard)). - toThrowError('No provider for DashboardSoftware! (CarWithDashboard -> Dashboard -> DashboardSoftware)'); + expect(() => injector.get(CarWithDashboard)) + .toThrowError( + `No provider for DashboardSoftware! (${stringify(CarWithDashboard)} -> ${stringify(Dashboard)} -> DashboardSoftware)`); }); - it('should throw when trying to instantiate a cyclic dependency', function () { - var injector = Injector.resolveAndCreate([ - Car, - bind(Engine).toClass(CyclicEngine) - ]); + it('should throw when trying to instantiate a cyclic dependency', function() { + var injector = Injector.resolveAndCreate([Car, bind(Engine).toClass(CyclicEngine)]); expect(() => injector.get(Car)) - .toThrowError('Cannot instantiate cyclic dependency! (Car -> Engine -> Car)'); + .toThrowError( + `Cannot instantiate cyclic dependency! (${stringify(Car)} -> ${stringify(Engine)} -> ${stringify(Car)})`); expect(() => injector.asyncGet(Car)) - .toThrowError('Cannot instantiate cyclic dependency! (Car -> Engine -> Car)'); + .toThrowError( + `Cannot instantiate cyclic dependency! (${stringify(Car)} -> ${stringify(Engine)} -> ${stringify(Car)})`); }); - it('should show the full path when error happens in a constructor', function () { - var injector = Injector.resolveAndCreate([ - Car, - bind(Engine).toClass(BrokenEngine) - ]); + it('should show the full path when error happens in a constructor', function() { + var injector = Injector.resolveAndCreate([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)"); + expect(e.message) + .toContain(`Error during instantiation of Engine! (${stringify(Car)} -> Engine)`); expect(e.cause instanceof BaseException).toBeTruthy(); expect(e.causeKey.token).toEqual(Engine); } }); - it('should instantiate an object after a failed attempt', function () { + it('should instantiate an object after a failed attempt', function() { var isBroken = true; - var injector = Injector.resolveAndCreate([ - Car, - bind(Engine).toFactory(() => isBroken ? new BrokenEngine() : new Engine()) - ]); + var injector = Injector.resolveAndCreate( + [Car, bind(Engine).toFactory(() => isBroken ? new BrokenEngine() : new Engine())]); expect(() => injector.get(Car)).toThrowError(new RegExp("Error")); @@ -292,19 +272,18 @@ export function main() { expect(injector.get('null')).toBe(null); }); - describe("default bindings", function () { - it("should be used when no matching binding found", function () { - var injector = Injector.resolveAndCreate([], {defaultBindings: true}); + describe("default bindings", function() { + it("should be used when no matching binding found", function() { + var injector = Injector.resolveAndCreate([], { defaultBindings: true }); var car = injector.get(Car); expect(car).toBeAnInstanceOf(Car); }); - it("should use the matching binding when it is available", function () { - var injector = Injector.resolveAndCreate([ - bind(Car).toClass(SportsCar) - ], {defaultBindings: true}); + it("should use the matching binding when it is available", function() { + var injector = + Injector.resolveAndCreate([bind(Car).toClass(SportsCar)], {defaultBindings: true}); var car = injector.get(Car); @@ -312,8 +291,8 @@ export function main() { }); }); - describe("child", function () { - it('should load instances from parent injector', function () { + describe("child", function() { + it('should load instances from parent injector', function() { var parent = Injector.resolveAndCreate([Engine]); var child = parent.resolveAndCreateChild([]); @@ -323,23 +302,18 @@ export function main() { expect(engineFromChild).toBe(engineFromParent); }); - it("should not use the child bindings when resolving the dependencies of a parent binding", function () { - var parent = Injector.resolveAndCreate([ - Car, Engine - ]); - var child = parent.resolveAndCreateChild([ - bind(Engine).toClass(TurboEngine) - ]); + it("should not use the child bindings when resolving the dependencies of a parent binding", + function() { + var parent = Injector.resolveAndCreate([Car, Engine]); + var child = parent.resolveAndCreateChild([bind(Engine).toClass(TurboEngine)]); - var carFromChild = child.get(Car); - expect(carFromChild.engine).toBeAnInstanceOf(Engine); - }); + var carFromChild = child.get(Car); + expect(carFromChild.engine).toBeAnInstanceOf(Engine); + }); - it('should create new instance in a child injector', function () { + it('should create new instance in a child injector', function() { var parent = Injector.resolveAndCreate([Engine]); - var child = parent.resolveAndCreateChild([ - bind(Engine).toClass(TurboEngine) - ]); + var child = parent.resolveAndCreateChild([bind(Engine).toClass(TurboEngine)]); var engineFromParent = parent.get(Engine); var engineFromChild = child.get(Engine); @@ -348,11 +322,11 @@ export function main() { expect(engineFromChild).toBeAnInstanceOf(TurboEngine); }); - it("should create child injectors without default bindings", function () { - var parent = Injector.resolveAndCreate([], {defaultBindings: true}); + it("should create child injectors without default bindings", function() { + var parent = Injector.resolveAndCreate([], { defaultBindings: true }); var child = parent.resolveAndCreateChild([]); - //child delegates to parent the creation of Car + // child delegates to parent the creation of Car var childCar = child.get(Car); var parentCar = parent.get(Car); @@ -366,22 +340,16 @@ export function main() { }); }); - describe("lazy", function () { - it("should create dependencies lazily", function () { - var injector = Injector.resolveAndCreate([ - Engine, - CarWithLazyEngine - ]); + describe("lazy", function() { + it("should create dependencies lazily", function() { + var injector = Injector.resolveAndCreate([Engine, CarWithLazyEngine]); var car = injector.get(CarWithLazyEngine); expect(car.engineFactory()).toBeAnInstanceOf(Engine); }); - it("should cache instance created lazily", function () { - var injector = Injector.resolveAndCreate([ - Engine, - CarWithLazyEngine - ]); + it("should cache instance created lazily", function() { + var injector = Injector.resolveAndCreate([Engine, CarWithLazyEngine]); var car = injector.get(CarWithLazyEngine); var e1 = car.engineFactory(); @@ -403,9 +371,10 @@ export function main() { it('should resolve forward references', () => { var bindings = Injector.resolve([ forwardRef(() => Engine), - [ bind(forwardRef(() => BrokenEngine)).toClass(forwardRef(() => Engine)) ], + [bind(forwardRef(() => BrokenEngine)).toClass(forwardRef(() => Engine))], bind(forwardRef(() => String)).toFactory(() => 'OK', [forwardRef(() => Engine)]), - bind(forwardRef(() => DashboardSoftware)).toAsyncFactory(() => 123, [forwardRef(() => BrokenEngine)]) + bind(forwardRef(() => DashboardSoftware)) + .toAsyncFactory(() => 123, [forwardRef(() => BrokenEngine)]) ]); var engineBinding = bindings[Key.get(Engine).id]; @@ -419,13 +388,14 @@ export function main() { expect(dashboardSoftwareBinding.dependencies[0].key).toEqual(Key.get(BrokenEngine)); }); - it('should support overriding factory dependencies with dependency annotations', function () { - var bindings = Injector.resolve([ - bind("token").toFactory((e) => "result", [[new Inject("dep"), new CustomDependencyAnnotation()]]) - ]); + it('should support overriding factory dependencies with dependency annotations', function() { + var bindings = Injector.resolve( + [bind("token") + .toFactory((e) => "result", + [[new ann.Inject("dep"), new CustomDependencyAnnotation()]])]); var binding = bindings[Key.get("token").id]; - expect(binding.dependencies[0].key).toEqual(Key.get("dep")); + expect(binding.dependencies[0].key.token).toEqual("dep"); expect(binding.dependencies[0].properties).toEqual([new CustomDependencyAnnotation()]); }); }); diff --git a/modules/angular2/test/di/key_spec.js b/modules/angular2/test/di/key_spec.js deleted file mode 100644 index 62f5cee561..0000000000 --- a/modules/angular2/test/di/key_spec.js +++ /dev/null @@ -1,25 +0,0 @@ -import {describe, iit, it, expect, beforeEach} from 'angular2/test_lib'; -import {Key, KeyRegistry} from 'angular2/di'; - -export function main() { - describe("key", function () { - var registry; - - beforeEach(function () { - registry = new KeyRegistry(); - }); - - it('should be equal to another key if type is the same', function () { - expect(registry.get('car')).toBe(registry.get('car')); - }); - - it('should not be equal to another key if types are different', function () { - expect(registry.get('car')).not.toBe(registry.get('porsche')); - }); - - it('should return the passed in key', function () { - expect(registry.get(registry.get('car'))).toBe(registry.get('car')); - }); - - }); -} \ No newline at end of file diff --git a/modules/angular2/test/di/key_spec.ts b/modules/angular2/test/di/key_spec.ts new file mode 100644 index 0000000000..0ac101c909 --- /dev/null +++ b/modules/angular2/test/di/key_spec.ts @@ -0,0 +1,20 @@ +import {describe, iit, it, expect, beforeEach} from 'angular2/test_lib'; +import {Key, KeyRegistry} from 'angular2/di'; + +export function main() { + describe("key", function() { + var registry; + + beforeEach(function() { registry = new KeyRegistry(); }); + + it('should be equal to another key if type is the same', + function() { expect(registry.get('car')).toBe(registry.get('car')); }); + + it('should not be equal to another key if types are different', + function() { expect(registry.get('car')).not.toBe(registry.get('porsche')); }); + + it('should return the passed in key', + function() { expect(registry.get(registry.get('car'))).toBe(registry.get('car')); }); + + }); +} \ No newline at end of file