feat(di): rename Binding into Provider

Closes #4416

Closes #4654
This commit is contained in:
vsavkin
2015-10-10 22:11:13 -07:00
committed by Victor Savkin
parent 7c6130c2c5
commit 1eb0162cde
190 changed files with 2071 additions and 1816 deletions
+15 -15
View File
@@ -17,7 +17,7 @@ import {Component, Directive, View} from 'angular2/core';
import {DOM} from 'angular2/src/core/dom/dom_adapter';
import {DOCUMENT} from 'angular2/render';
import {PromiseWrapper} from 'angular2/src/core/facade/async';
import {bind, Inject, Injector, LifeCycle} from 'angular2/core';
import {provide, Inject, Injector, LifeCycle} from 'angular2/core';
import {ExceptionHandler} from 'angular2/src/core/facade/exceptions';
import {Testability, TestabilityRegistry} from 'angular2/src/core/testability/testability';
import {IS_DART} from '../platform';
@@ -77,7 +77,7 @@ class _ArrayLogger {
export function main() {
var fakeDoc, el, el2, testBindings, lightDom;
var fakeDoc, el, el2, testProviders, lightDom;
describe('bootstrap factory method', () => {
beforeEach(() => {
@@ -89,7 +89,7 @@ export function main() {
DOM.appendChild(fakeDoc.body, el2);
DOM.appendChild(el, lightDom);
DOM.setText(lightDom, 'loading');
testBindings = [bind(DOCUMENT).toValue(fakeDoc)];
testProviders = [provide(DOCUMENT, {asValue: fakeDoc})];
});
it('should throw if bootstrapped Directive is not a Component',
@@ -98,7 +98,7 @@ export function main() {
var exceptionHandler = new ExceptionHandler(logger, false);
var refPromise =
bootstrap(HelloRootDirectiveIsNotCmp,
[testBindings, bind(ExceptionHandler).toValue(exceptionHandler)]);
[testProviders, provide(ExceptionHandler, {asValue: exceptionHandler})]);
PromiseWrapper.then(refPromise, null, (exception) => {
expect(exception).toContainError(
@@ -114,7 +114,7 @@ export function main() {
var exceptionHandler = new ExceptionHandler(logger, IS_DART ? false : true);
var refPromise =
bootstrap(HelloRootCmp, [bind(ExceptionHandler).toValue(exceptionHandler)]);
bootstrap(HelloRootCmp, [provide(ExceptionHandler, {asValue: exceptionHandler})]);
PromiseWrapper.then(refPromise, null, (reason) => {
expect(reason.message).toContain('The selector "hello-app" did not match any elements');
async.done();
@@ -129,7 +129,7 @@ export function main() {
var exceptionHandler = new ExceptionHandler(logger, IS_DART ? false : true);
var refPromise =
bootstrap(HelloRootCmp, [bind(ExceptionHandler).toValue(exceptionHandler)]);
bootstrap(HelloRootCmp, [provide(ExceptionHandler, {asValue: exceptionHandler})]);
PromiseWrapper.then(refPromise, null, (reason) => {
expect(logger.res.join(""))
.toContain('The selector "hello-app" did not match any elements');
@@ -140,12 +140,12 @@ export function main() {
}
it('should create an injector promise', () => {
var refPromise = bootstrap(HelloRootCmp, testBindings);
var refPromise = bootstrap(HelloRootCmp, testProviders);
expect(refPromise).not.toBe(null);
});
it('should display hello world', inject([AsyncTestCompleter], (async) => {
var refPromise = bootstrap(HelloRootCmp, testBindings);
var refPromise = bootstrap(HelloRootCmp, testProviders);
refPromise.then((ref) => {
expect(el).toHaveText('hello world!');
async.done();
@@ -153,8 +153,8 @@ export function main() {
}));
it('should support multiple calls to bootstrap', inject([AsyncTestCompleter], (async) => {
var refPromise1 = bootstrap(HelloRootCmp, testBindings);
var refPromise2 = bootstrap(HelloRootCmp2, testBindings);
var refPromise1 = bootstrap(HelloRootCmp, testProviders);
var refPromise2 = bootstrap(HelloRootCmp2, testProviders);
PromiseWrapper.all([refPromise1, refPromise2])
.then((refs) => {
expect(el).toHaveText('hello world!');
@@ -165,8 +165,8 @@ export function main() {
it("should make the provided bindings available to the application component",
inject([AsyncTestCompleter], (async) => {
var refPromise =
bootstrap(HelloRootCmp3, [testBindings, bind("appBinding").toValue("BoundValue")]);
var refPromise = bootstrap(
HelloRootCmp3, [testProviders, provide("appBinding", {asValue: "BoundValue"})]);
refPromise.then((ref) => {
expect(ref.hostComponent.appBinding).toEqual("BoundValue");
@@ -176,7 +176,7 @@ export function main() {
it("should avoid cyclic dependencies when root component requires Lifecycle through DI",
inject([AsyncTestCompleter], (async) => {
var refPromise = bootstrap(HelloRootCmp4, testBindings);
var refPromise = bootstrap(HelloRootCmp4, testProviders);
refPromise.then((ref) => {
expect(ref.hostComponent.lc).toBe((<ComponentRef_>ref).injector.get(LifeCycle));
@@ -186,8 +186,8 @@ export function main() {
it('should register each application with the testability registry',
inject([AsyncTestCompleter], (async) => {
var refPromise1 = bootstrap(HelloRootCmp, testBindings);
var refPromise2 = bootstrap(HelloRootCmp2, testBindings);
var refPromise1 = bootstrap(HelloRootCmp, testProviders);
var refPromise2 = bootstrap(HelloRootCmp2, testProviders);
PromiseWrapper.all([refPromise1, refPromise2])
.then((refs: ApplicationRef[]) => {
@@ -1,7 +1,7 @@
import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach} from 'angular2/test_lib';
import {SpyIterableDifferFactory} from '../../spies';
import {IterableDiffers} from 'angular2/src/core/change_detection/differs/iterable_differs';
import {Injector, bind} from 'angular2/core';
import {Injector, provide} from 'angular2/core';
export function main() {
describe('IterableDiffers', function() {
@@ -50,7 +50,7 @@ export function main() {
it('should extend di-inherited diffesr', () => {
var parent = new IterableDiffers([factory1]);
var injector = Injector.resolveAndCreate([bind(IterableDiffers).toValue(parent)]);
var injector = Injector.resolveAndCreate([provide(IterableDiffers, {asValue: parent})]);
var childInjector = injector.resolveAndCreateChild([IterableDiffers.extend([factory2])]);
expect(injector.get(IterableDiffers).factories).toEqual([factory1]);
@@ -37,11 +37,11 @@ import {
} from 'angular2/src/core/compiler/change_definition_factory';
import {TestDirective, TestDispatcher, TestPipes} from './change_detector_mocks';
import {TEST_BINDINGS} from './test_bindings';
import {TEST_PROVIDERS} from './test_bindings';
export function main() {
describe('ChangeDefinitionFactory', () => {
beforeEachBindings(() => TEST_BINDINGS);
beforeEachBindings(() => TEST_PROVIDERS);
var parser: TemplateParser;
var dispatcher: TestDispatcher;
@@ -12,7 +12,7 @@ import {
inject,
beforeEachBindings
} from 'angular2/test_lib';
import {bind} from 'angular2/src/core/di';
import {provide} from 'angular2/src/core/di';
import {CONST_EXPR, stringify} from 'angular2/src/core/facade/lang';
import {MapWrapper} from 'angular2/src/core/facade/collection';
@@ -45,7 +45,7 @@ import {
import {evalModule} from './eval_module';
import {TEST_BINDINGS} from './test_bindings';
import {TEST_PROVIDERS} from './test_bindings';
import {TestDispatcher, TestPipes} from './change_detector_mocks';
import {
codeGenValueFn,
@@ -60,7 +60,7 @@ var THIS_MODULE_REF = moduleRef(THIS_MODULE_URL);
export function main() {
describe('ChangeDetectorCompiler', () => {
beforeEachBindings(() => TEST_BINDINGS);
beforeEachBindings(() => TEST_PROVIDERS);
var parser: TemplateParser;
var compiler: ChangeDetectionCompiler;
@@ -83,8 +83,8 @@ export function main() {
describe('no jit', () => {
beforeEachBindings(() => [
bind(ChangeDetectorGenConfig)
.toValue(new ChangeDetectorGenConfig(true, true, false, false))
provide(ChangeDetectorGenConfig,
{asValue: new ChangeDetectorGenConfig(true, true, false, false)})
]);
it('should watch element properties', () => {
expect(detectChanges(compiler, '<div [el-prop]="someProp">'))
@@ -94,8 +94,8 @@ export function main() {
describe('jit', () => {
beforeEachBindings(() => [
bind(ChangeDetectorGenConfig)
.toValue(new ChangeDetectorGenConfig(true, true, false, true))
provide(ChangeDetectorGenConfig,
{asValue: new ChangeDetectorGenConfig(true, true, false, true)})
]);
it('should watch element properties', () => {
expect(detectChanges(compiler, '<div [el-prop]="someProp">'))
@@ -43,7 +43,7 @@ import {
codeGenExportVariable,
MODULE_SUFFIX
} from 'angular2/src/core/compiler/util';
import {TEST_BINDINGS} from './test_bindings';
import {TEST_PROVIDERS} from './test_bindings';
const BEGIN_ELEMENT = 'BEGIN_ELEMENT';
const END_ELEMENT = 'END_ELEMENT';
@@ -78,7 +78,7 @@ var NESTED_COMPONENT = new CompiledTemplate(45, () => []);
export function main() {
describe('CommandCompiler', () => {
beforeEachBindings(() => TEST_BINDINGS);
beforeEachBindings(() => TEST_PROVIDERS);
var parser: TemplateParser;
var commandCompiler: CommandCompiler;
@@ -13,7 +13,7 @@ import {
beforeEachBindings
} from 'angular2/test_lib';
import {Component, View, bind} from 'angular2/core';
import {Component, View, provide} from 'angular2/core';
import {PromiseWrapper} from 'angular2/src/core/facade/async';
import {SpyProtoViewFactory} from '../spies';
import {
@@ -39,7 +39,7 @@ export function main() {
protoViewFactorySpy = new SpyProtoViewFactory();
someProtoView = new AppProtoView(null, null, null, null, null, null);
protoViewFactorySpy.spy('createHost').andReturn(someProtoView);
return [bind(ProtoViewFactory).toValue(protoViewFactorySpy)];
return [provide(ProtoViewFactory, {asValue: protoViewFactorySpy})];
});
it('should compile the template via TemplateCompiler',
@@ -33,12 +33,12 @@ import {
SimpleChange
} from 'angular2/core';
import {TEST_BINDINGS} from './test_bindings';
import {TEST_PROVIDERS} from './test_bindings';
import {MODULE_SUFFIX, IS_DART} from 'angular2/src/core/compiler/util';
export function main() {
describe('RuntimeMetadataResolver', () => {
beforeEachBindings(() => TEST_BINDINGS);
beforeEachBindings(() => TEST_PROVIDERS);
describe('getMetadata', () => {
it('should read metadata',
@@ -12,7 +12,7 @@ import {
inject,
beforeEachBindings
} from 'angular2/test_lib';
import {bind} from 'angular2/src/core/di';
import {provide} from 'angular2/src/core/di';
import {SpyXHR} from '../spies';
import {XHR} from 'angular2/src/core/compiler/xhr';
import {BaseException, WrappedException} from 'angular2/src/core/facade/exceptions';
@@ -28,7 +28,7 @@ import {
} from 'angular2/src/core/compiler/directive_metadata';
import {SourceExpression, SourceModule} from 'angular2/src/core/compiler/source_module';
import {ViewEncapsulation} from 'angular2/src/core/metadata/view';
import {TEST_BINDINGS} from './test_bindings';
import {TEST_PROVIDERS} from './test_bindings';
import {
codeGenValueFn,
codeGenExportVariable,
@@ -51,7 +51,7 @@ export function main() {
beforeEachBindings(() => {
xhr = <any>new SpyXHR();
return [TEST_BINDINGS, bind(XHR).toValue(xhr)];
return [TEST_PROVIDERS, provide(XHR, {asValue: xhr})];
});
var compiler: StyleCompiler;
@@ -42,9 +42,9 @@ import {
CompiledTemplate
} from 'angular2/src/core/linker/template_commands';
import {Component, View, Directive, bind} from 'angular2/core';
import {Component, View, Directive, provide} from 'angular2/core';
import {TEST_BINDINGS} from './test_bindings';
import {TEST_PROVIDERS} from './test_bindings';
import {TestDispatcher, TestPipes} from './change_detector_mocks';
import {
codeGenValueFn,
@@ -64,7 +64,7 @@ export function main() {
var compiler: TemplateCompiler;
var runtimeMetadataResolver: RuntimeMetadataResolver;
beforeEachBindings(() => [bind(APP_ID).toValue(APP_ID_VALUE), TEST_BINDINGS]);
beforeEachBindings(() => [provide(APP_ID, {asValue: APP_ID_VALUE}), TEST_PROVIDERS]);
beforeEach(inject([TemplateCompiler, RuntimeMetadataResolver],
(_compiler, _runtimeMetadataResolver) => {
compiler = _compiler;
@@ -22,13 +22,13 @@ import {ViewEncapsulation} from 'angular2/src/core/metadata/view';
import {TemplateNormalizer} from 'angular2/src/core/compiler/template_normalizer';
import {XHR} from 'angular2/src/core/compiler/xhr';
import {MockXHR} from 'angular2/src/core/compiler/xhr_mock';
import {TEST_BINDINGS} from './test_bindings';
import {TEST_PROVIDERS} from './test_bindings';
export function main() {
describe('TemplateNormalizer', () => {
var dirType: CompileTypeMetadata;
beforeEachBindings(() => TEST_BINDINGS);
beforeEachBindings(() => TEST_PROVIDERS);
beforeEach(() => {
dirType = new CompileTypeMetadata({moduleUrl: 'package:some/module/a.js', name: 'SomeComp'});
@@ -10,9 +10,9 @@ import {
inject,
beforeEachBindings
} from 'angular2/test_lib';
import {bind} from 'angular2/src/core/di';
import {provide} from 'angular2/src/core/di';
import {TEST_BINDINGS} from './test_bindings';
import {TEST_PROVIDERS} from './test_bindings';
import {isPresent} from 'angular2/src/core/facade/lang';
import {TemplateParser, splitClasses} from 'angular2/src/core/compiler/template_parser';
import {
@@ -48,9 +48,12 @@ var expressionUnparser = new Unparser();
export function main() {
describe('TemplateParser', () => {
beforeEachBindings(() => [
TEST_BINDINGS,
bind(ElementSchemaRegistry)
.toValue(new MockSchemaRegistry({'invalidProp': false}, {'mappedAttr': 'mappedProp'}))
TEST_PROVIDERS,
provide(ElementSchemaRegistry,
{
asValue: new MockSchemaRegistry({'invalidProp': false},
{'mappedAttr': 'mappedProp'})
})
]);
var parser: TemplateParser;
@@ -1,5 +1,6 @@
import {bind, Binding} from 'angular2/src/core/di';
import {provide, Provider} from 'angular2/src/core/di';
import {MockSchemaRegistry} from './schema_registry_mock';
import {ElementSchemaRegistry} from 'angular2/src/core/compiler/schema/element_schema_registry';
export var TEST_BINDINGS = [bind(ElementSchemaRegistry).toValue(new MockSchemaRegistry({}, {}))];
export var TEST_PROVIDERS =
[provide(ElementSchemaRegistry, {asValue: new MockSchemaRegistry({}, {})})];
@@ -61,7 +61,7 @@ class ChildComp {
constructor() { this.childBinding = 'Original'; }
}
@Component({selector: 'parent-comp', viewBindings: [Logger]})
@Component({selector: 'parent-comp', viewProviders: [Logger]})
@View({
template: `<div class="parent" message="parent">
<span class="parentnested" message="nestedparent">Parent</span>
@@ -105,7 +105,7 @@ class EventsComp {
handleCustom() { this.customed = true; }
}
@Component({selector: 'using-for', viewBindings: [Logger]})
@Component({selector: 'using-for', viewProviders: [Logger]})
@View({
template: `<span *ng-for="#thing of stuff" [inner-html]="thing"></span>
<ul message="list">
@@ -15,7 +15,7 @@ import {
} from 'angular2/test_lib';
import {global} from 'angular2/src/core/facade/lang';
import {APP_VIEW_POOL_CAPACITY} from 'angular2/src/core/linker/view_pool';
import {bind, Component, Directive, Injectable, View} from 'angular2/core';
import {provide, Component, Directive, Injectable, View} from 'angular2/core';
import {inspectNativeElement} from 'angular2/src/core/debug';
import {IS_DART} from '../../platform';
@@ -28,7 +28,7 @@ class MyComp {
export function main() {
describe('element probe', function() {
beforeEachBindings(() => [bind(APP_VIEW_POOL_CAPACITY).toValue(0)]);
beforeEachBindings(() => [provide(APP_VIEW_POOL_CAPACITY, {asValue: 0})]);
it('should return a TestElement from a dom element',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
@@ -10,21 +10,21 @@ import {
xit,
} from 'angular2/test_lib';
import {bind} from 'angular2/core';
import {bind, provide} from 'angular2/core';
export function main() {
describe('binding', () => {
describe('provider', () => {
describe('type errors', () => {
it('should throw when trying to create a class binding and not passing a class', () => {
it('should throw when trying to create a class provider and not passing a class', () => {
expect(() => { bind('foo').toClass(<any>0); })
.toThrowError('Trying to create a class binding but "0" is not a class!');
.toThrowError('Trying to create a class provider but "0" is not a class!');
});
it('should throw when trying to create a factory binding and not passing a function', () => {
it('should throw when trying to create a factory provider and not passing a function', () => {
expect(() => { bind('foo').toFactory(<any>0); })
.toThrowError('Trying to create a factory binding but "0" is not a function!');
.toThrowError('Trying to create a factory provider but "0" is not a function!');
});
});
});
+137 -139
View File
@@ -4,8 +4,8 @@ import {describe, ddescribe, it, iit, expect, beforeEach} from 'angular2/test_li
import {SpyDependencyProvider} from '../spies';
import {
Injector,
bind,
ResolvedBinding,
provide,
ResolvedProvider,
Key,
forwardRef,
Injectable,
@@ -15,16 +15,16 @@ import {
SkipSelfMetadata,
Optional,
Inject,
Binding
Provider
} from 'angular2/core';
import {DependencyMetadata} from 'angular2/src/core/di/metadata';
import {ResolvedBinding_} from 'angular2/src/core/di/binding';
import {ResolvedProvider_} from 'angular2/src/core/di/provider';
import {
InjectorInlineStrategy,
InjectorDynamicStrategy,
ProtoInjector,
BindingWithVisibility,
ProviderWithVisibility,
Visibility
} from 'angular2/src/core/di/injector';
@@ -89,29 +89,28 @@ class NoAnnotations {
}
export function main() {
var dynamicBindings = [
bind('binding0')
.toValue(1),
bind('binding1').toValue(1),
bind('binding2').toValue(1),
bind('binding3').toValue(1),
bind('binding4').toValue(1),
bind('binding5').toValue(1),
bind('binding6').toValue(1),
bind('binding7').toValue(1),
bind('binding8').toValue(1),
bind('binding9').toValue(1),
bind('binding10').toValue(1)
var dynamicProviders = [
provide('provider0', {asValue: 1}),
provide('provider1', {asValue: 1}),
provide('provider2', {asValue: 1}),
provide('provider3', {asValue: 1}),
provide('provider4', {asValue: 1}),
provide('provider5', {asValue: 1}),
provide('provider6', {asValue: 1}),
provide('provider7', {asValue: 1}),
provide('provider8', {asValue: 1}),
provide('provider9', {asValue: 1}),
provide('provider10', {asValue: 1})
];
[{strategy: 'inline', bindings: [], strategyClass: InjectorInlineStrategy},
[{strategy: 'inline', providers: [], strategyClass: InjectorInlineStrategy},
{
strategy: 'dynamic',
bindings: dynamicBindings,
providers: dynamicProviders,
strategyClass: InjectorDynamicStrategy
}].forEach((context) => {
function createInjector(bindings: any[]) {
return Injector.resolveAndCreate(bindings.concat(context['bindings']));
function createInjector(providers: any[]) {
return Injector.resolveAndCreate(providers.concat(context['providers']));
}
describe(`injector ${context['strategy']}`, () => {
@@ -158,32 +157,33 @@ export function main() {
expect(e1).toBe(e2);
});
it('should bind to a value', () => {
var injector = createInjector([bind(Engine).toValue("fake engine")]);
it('should provide to a value', () => {
var injector = createInjector([provide(Engine, {asValue: "fake engine"})]);
var engine = injector.get(Engine);
expect(engine).toEqual("fake engine");
});
it('should bind to a factory', () => {
it('should provide to a factory', () => {
function sportsCarFactory(e) { return new SportsCar(e); }
var injector = createInjector([Engine, bind(Car).toFactory(sportsCarFactory, [Engine])]);
var injector =
createInjector([Engine, provide(Car, {asFactory: sportsCarFactory, deps: [Engine]})]);
var car = injector.get(Car);
expect(car).toBeAnInstanceOf(SportsCar);
expect(car.engine).toBeAnInstanceOf(Engine);
});
it('should supporting binding to null', () => {
var injector = createInjector([bind(Engine).toValue(null)]);
it('should supporting provider to null', () => {
var injector = createInjector([provide(Engine, {asValue: null})]);
var engine = injector.get(Engine);
expect(engine).toBeNull();
});
it('should bind to an alias', () => {
it('should provide to an alias', () => {
var injector = createInjector(
[Engine, bind(SportsCar).toClass(SportsCar), bind(Car).toAlias(SportsCar)]);
[Engine, provide(SportsCar, {asClass: SportsCar}), provide(Car, {asAlias: SportsCar})]);
var car = injector.get(Car);
var sportsCar = injector.get(SportsCar);
@@ -191,11 +191,11 @@ export function main() {
expect(car).toBe(sportsCar);
});
it('should support multibindings', () => {
it('should support multiProviders', () => {
var injector = createInjector([
Engine,
new Binding(Car, {toClass: SportsCar, multi: true}),
new Binding(Car, {toClass: CarWithOptionalEngine, multi: true})
new Provider(Car, {toClass: SportsCar, multi: true}),
new Provider(Car, {toClass: CarWithOptionalEngine, multi: true})
]);
var cars = injector.get(Car);
@@ -204,37 +204,32 @@ export function main() {
expect(cars[1]).toBeAnInstanceOf(CarWithOptionalEngine);
});
it('should support multibindings that are created using toAlias', () => {
it('should support multiProviders that are created using toAlias', () => {
var injector = createInjector(
[Engine, SportsCar, new Binding(Car, {toAlias: SportsCar, multi: true})]);
[Engine, SportsCar, new Provider(Car, {toAlias: SportsCar, multi: true})]);
var cars = injector.get(Car);
expect(cars.length).toEqual(1);
expect(cars[0]).toBe(injector.get(SportsCar));
});
it('should throw when the aliased binding does not exist', () => {
var injector = createInjector([bind('car').toAlias(SportsCar)]);
it('should throw when the aliased provider does not exist', () => {
var injector = createInjector([provide('car', {asAlias: SportsCar})]);
var e = `No provider for ${stringify(SportsCar)}! (car -> ${stringify(SportsCar)})`;
expect(() => injector.get('car')).toThrowError(e);
});
it('should throw with a meaningful message when the aliased binding is blank', () => {
expect(() => bind('car').toAlias(null)).toThrowError('Can not alias car to a blank value!');
});
it('should handle forwardRef in toAlias', () => {
var injector = createInjector([
bind('originalEngine')
.toClass(forwardRef(() => Engine)),
bind('aliasedEngine').toAlias(<any>forwardRef(() => 'originalEngine'))
provide('originalEngine', {asClass: forwardRef(() => Engine)}),
provide('aliasedEngine', {asAlias:<any>forwardRef(() => 'originalEngine')})
]);
expect(injector.get('aliasedEngine')).toBeAnInstanceOf(Engine);
});
it('should support overriding factory dependencies', () => {
var injector =
createInjector([Engine, bind(Car).toFactory((e) => new SportsCar(e), [Engine])]);
var injector = createInjector(
[Engine, provide(Car, {asFactory: (e) => new SportsCar(e), deps: [Engine]})]);
var car = injector.get(Car);
expect(car).toBeAnInstanceOf(SportsCar);
@@ -248,33 +243,30 @@ export function main() {
expect(car.engine).toEqual(null);
});
it("should flatten passed-in bindings", () => {
it("should flatten passed-in providers", () => {
var injector = createInjector([[[Engine, Car]]]);
var car = injector.get(Car);
expect(car).toBeAnInstanceOf(Car);
});
it("should use the last binding when there are multiple bindings for same token", () => {
var injector =
createInjector([bind(Engine).toClass(Engine), bind(Engine).toClass(TurboEngine)]);
it("should use the last provider when there are multiple providers for same token", () => {
var injector = createInjector(
[provide(Engine, {asClass: Engine}), provide(Engine, {asClass: TurboEngine})]);
expect(injector.get(Engine)).toBeAnInstanceOf(TurboEngine);
});
it('should use non-type tokens', () => {
var injector = createInjector([bind('token').toValue('value')]);
var injector = createInjector([provide('token', {asValue: 'value'})]);
expect(injector.get('token')).toEqual('value');
});
it('should throw when given invalid bindings', () => {
it('should throw when given invalid providers', () => {
expect(() => createInjector(<any>["blah"]))
.toThrowError(
'Invalid binding - only instances of Binding and Type are allowed, got: blah');
expect(() => createInjector(<any>[bind("blah")]))
.toThrowError('Invalid binding - only instances of Binding and Type are allowed, ' +
'got: blah');
'Invalid provider - only instances of Provider and Type are allowed, got: blah');
});
it('should provide itself', () => {
@@ -297,7 +289,7 @@ export function main() {
});
it('should throw when trying to instantiate a cyclic dependency', () => {
var injector = createInjector([Car, bind(Engine).toClass(CyclicEngine)]);
var injector = createInjector([Car, provide(Engine, {asClass: CyclicEngine})]);
expect(() => injector.get(Car))
.toThrowError(
@@ -305,10 +297,10 @@ export function main() {
});
it('should show the full path when error happens in a constructor', () => {
var bindings = Injector.resolve([Car, bind(Engine).toClass(BrokenEngine)]);
var providers = Injector.resolve([Car, provide(Engine, {asClass: BrokenEngine})]);
var proto = new ProtoInjector([
new BindingWithVisibility(bindings[0], Visibility.Public),
new BindingWithVisibility(bindings[1], Visibility.Public)
new ProviderWithVisibility(providers[0], Visibility.Public),
new ProviderWithVisibility(providers[1], Visibility.Public)
]);
var injector = new Injector(proto, null, null);
@@ -324,13 +316,13 @@ export function main() {
});
it('should provide context when throwing an exception ', () => {
var engineBinding = Injector.resolve([bind(Engine).toClass(BrokenEngine)])[0];
var engineProvider = Injector.resolve([provide(Engine, {asClass: BrokenEngine})])[0];
var protoParent =
new ProtoInjector([new BindingWithVisibility(engineBinding, Visibility.Public)]);
new ProtoInjector([new ProviderWithVisibility(engineProvider, Visibility.Public)]);
var carBinding = Injector.resolve([Car])[0];
var carProvider = Injector.resolve([Car])[0];
var protoChild =
new ProtoInjector([new BindingWithVisibility(carBinding, Visibility.Public)]);
new ProtoInjector([new ProviderWithVisibility(carProvider, Visibility.Public)]);
var parent = new Injector(protoParent, null, null, () => "parentContext");
var child = new Injector(protoChild, parent, null, () => "childContext");
@@ -346,8 +338,10 @@ export function main() {
it('should instantiate an object after a failed attempt', () => {
var isBroken = true;
var injector = createInjector(
[Car, bind(Engine).toFactory(() => isBroken ? new BrokenEngine() : new Engine())]);
var injector = createInjector([
Car,
provide(Engine, {asFactory: (() => isBroken ? new BrokenEngine() : new Engine())})
]);
expect(() => injector.get(Car)).toThrowError(new RegExp("Error"));
@@ -357,7 +351,7 @@ export function main() {
});
it('should support null values', () => {
var injector = createInjector([bind('null').toValue(null)]);
var injector = createInjector([provide('null', {asValue: null})]);
expect(injector.get('null')).toBe(null);
});
@@ -367,14 +361,15 @@ export function main() {
var depProvider = <any>new SpyDependencyProvider();
depProvider.spy("getDependency").andReturn(e);
var bindings = Injector.resolve([Car]);
var proto = new ProtoInjector([new BindingWithVisibility(bindings[0], Visibility.Public)]);
var providers = Injector.resolve([Car]);
var proto =
new ProtoInjector([new ProviderWithVisibility(providers[0], Visibility.Public)]);
var injector = new Injector(proto, null, depProvider);
expect(injector.get(Car).engine).toEqual(e);
expect(depProvider.spy("getDependency"))
.toHaveBeenCalledWith(injector, bindings[0],
bindings[0].resolvedFactories[0].dependencies[0]);
.toHaveBeenCalledWith(injector, providers[0],
providers[0].resolvedFactories[0].dependencies[0]);
});
});
@@ -390,10 +385,10 @@ export function main() {
expect(engineFromChild).toBe(engineFromParent);
});
it("should not use the child bindings when resolving the dependencies of a parent binding",
it("should not use the child providers when resolving the dependencies of a parent provider",
() => {
var parent = Injector.resolveAndCreate([Car, Engine]);
var child = parent.resolveAndCreateChild([bind(Engine).toClass(TurboEngine)]);
var child = parent.resolveAndCreateChild([provide(Engine, {asClass: TurboEngine})]);
var carFromChild = child.get(Car);
expect(carFromChild.engine).toBeAnInstanceOf(Engine);
@@ -401,7 +396,7 @@ export function main() {
it('should create new instance in a child injector', () => {
var parent = Injector.resolveAndCreate([Engine]);
var child = parent.resolveAndCreateChild([bind(Engine).toClass(TurboEngine)]);
var child = parent.resolveAndCreateChild([provide(Engine, {asClass: TurboEngine})]);
var engineFromParent = parent.get(Engine);
var engineFromChild = child.get(Engine);
@@ -444,16 +439,18 @@ export function main() {
describe("depedency resolution", () => {
describe("@Self()", () => {
it("should return a dependency from self", () => {
var inj = Injector.resolveAndCreate(
[Engine, bind(Car).toFactory((e) => new Car(e), [[Engine, new SelfMetadata()]])]);
var inj = Injector.resolveAndCreate([
Engine,
provide(Car, {asFactory: (e) => new Car(e), deps: [[Engine, new SelfMetadata()]]})
]);
expect(inj.get(Car)).toBeAnInstanceOf(Car);
});
it("should throw when not requested binding on self", () => {
it("should throw when not requested provider on self", () => {
var parent = Injector.resolveAndCreate([Engine]);
var child = parent.resolveAndCreateChild(
[bind(Car).toFactory((e) => new Car(e), [[Engine, new SelfMetadata()]])]);
[provide(Car, {asFactory: (e) => new Car(e), deps: [[Engine, new SelfMetadata()]]})]);
expect(() => child.get(Car))
.toThrowError(`No provider for Engine! (${stringify(Car)} -> ${stringify(Engine)})`);
@@ -464,7 +461,7 @@ export function main() {
it("should return a dependency from same host", () => {
var parent = Injector.resolveAndCreate([Engine]);
var child = parent.resolveAndCreateChild(
[bind(Car).toFactory((e) => new Car(e), [[Engine, new HostMetadata()]])]);
[provide(Car, {asFactory: (e) => new Car(e), deps: [[Engine, new HostMetadata()]]})]);
expect(child.get(Car)).toBeAnInstanceOf(Car);
});
@@ -472,11 +469,11 @@ export function main() {
it("should return a private dependency declared at the host", () => {
var engine = Injector.resolve([Engine])[0];
var protoParent =
new ProtoInjector([new BindingWithVisibility(engine, Visibility.Private)]);
new ProtoInjector([new ProviderWithVisibility(engine, Visibility.Private)]);
var parent = new Injector(protoParent);
var child = Injector.resolveAndCreate(
[bind(Car).toFactory((e) => new Car(e), [[Engine, new HostMetadata()]])]);
[provide(Car, {asFactory: (e) => new Car(e), deps: [[Engine, new HostMetadata()]]})]);
child.internalStrategy.attach(parent, true); // host
@@ -486,11 +483,11 @@ export function main() {
it("should not return a public dependency declared at the host", () => {
var engine = Injector.resolve([Engine])[0];
var protoParent =
new ProtoInjector([new BindingWithVisibility(engine, Visibility.Public)]);
new ProtoInjector([new ProviderWithVisibility(engine, Visibility.Public)]);
var parent = new Injector(protoParent);
var child = Injector.resolveAndCreate(
[bind(Car).toFactory((e) => new Car(e), [[Engine, new HostMetadata()]])]);
[provide(Car, {asFactory: (e) => new Car(e), deps: [[Engine, new HostMetadata()]]})]);
child.internalStrategy.attach(parent, true); // host
@@ -501,9 +498,8 @@ export function main() {
it("should not skip self", () => {
var parent = Injector.resolveAndCreate([Engine]);
var child = parent.resolveAndCreateChild([
bind(Engine)
.toClass(TurboEngine),
bind(Car).toFactory((e) => new Car(e), [[Engine, new HostMetadata()]])
provide(Engine, {asClass: TurboEngine}),
provide(Car, {asFactory: (e) => new Car(e), deps: [[Engine, new HostMetadata()]]})
]);
expect(child.get(Car).engine).toBeAnInstanceOf(TurboEngine);
@@ -514,13 +510,13 @@ export function main() {
it("should return a private dependency declared at the host", () => {
var engine = Injector.resolve([Engine])[0];
var protoParent =
new ProtoInjector([new BindingWithVisibility(engine, Visibility.Private)]);
new ProtoInjector([new ProviderWithVisibility(engine, Visibility.Private)]);
var parent = new Injector(protoParent);
var child = Injector.resolveAndCreate([
bind(Engine)
.toClass(BrokenEngine),
bind(Car).toFactory((e) => new Car(e), [[Engine, new SkipSelfMetadata()]])
provide(Engine, {asClass: BrokenEngine}),
provide(Car,
{asFactory: (e) => new Car(e), deps: [[Engine, new SkipSelfMetadata()]]})
]);
child.internalStrategy.attach(parent, true); // boundary
@@ -530,13 +526,13 @@ export function main() {
it("should return a public dependency declared at the host", () => {
var engine = Injector.resolve([Engine])[0];
var protoParent =
new ProtoInjector([new BindingWithVisibility(engine, Visibility.Public)]);
new ProtoInjector([new ProviderWithVisibility(engine, Visibility.Public)]);
var parent = new Injector(protoParent);
var child = Injector.resolveAndCreate([
bind(Engine)
.toClass(BrokenEngine),
bind(Car).toFactory((e) => new Car(e), [[Engine, new SkipSelfMetadata()]])
provide(Engine, {asClass: BrokenEngine}),
provide(Car,
{asFactory: (e) => new Car(e), deps: [[Engine, new SkipSelfMetadata()]]})
]);
child.internalStrategy.attach(parent, true); // boundary
@@ -546,13 +542,13 @@ export function main() {
it("should not return a private dependency declared NOT at the host", () => {
var engine = Injector.resolve([Engine])[0];
var protoParent =
new ProtoInjector([new BindingWithVisibility(engine, Visibility.Private)]);
new ProtoInjector([new ProviderWithVisibility(engine, Visibility.Private)]);
var parent = new Injector(protoParent);
var child = Injector.resolveAndCreate([
bind(Engine)
.toClass(BrokenEngine),
bind(Car).toFactory((e) => new Car(e), [[Engine, new SkipSelfMetadata()]])
provide(Engine, {asClass: BrokenEngine}),
provide(Car,
{asFactory: (e) => new Car(e), deps: [[Engine, new SkipSelfMetadata()]]})
]);
child.internalStrategy.attach(parent, false);
@@ -563,9 +559,8 @@ export function main() {
it("should not skip self", () => {
var parent = Injector.resolveAndCreate([Engine]);
var child = parent.resolveAndCreateChild([
bind(Engine)
.toClass(TurboEngine),
bind(Car).toFactory((e) => new Car(e), [Engine])
provide(Engine, {asClass: TurboEngine}),
provide(Car, {asFactory: (e) => new Car(e), deps: [Engine]})
]);
expect(child.get(Car).engine).toBeAnInstanceOf(TurboEngine);
@@ -575,70 +570,73 @@ export function main() {
describe('resolve', () => {
it('should resolve and flatten', () => {
var bindings = Injector.resolve([Engine, [BrokenEngine]]);
bindings.forEach(function(b) {
var providers = Injector.resolve([Engine, [BrokenEngine]]);
providers.forEach(function(b) {
if (isBlank(b)) return; // the result is a sparse array
expect(b instanceof ResolvedBinding_).toBe(true);
expect(b instanceof ResolvedProvider_).toBe(true);
});
});
it("should support multi bindings", () => {
var binding = Injector.resolve([
new Binding(Engine, {toClass: BrokenEngine, multi: true}),
new Binding(Engine, {toClass: TurboEngine, multi: true})
it("should support multi providers", () => {
var provider = Injector.resolve([
new Provider(Engine, {toClass: BrokenEngine, multi: true}),
new Provider(Engine, {toClass: TurboEngine, multi: true})
])[0];
expect(binding.key.token).toBe(Engine);
expect(binding.multiBinding).toEqual(true);
expect(binding.resolvedFactories.length).toEqual(2);
expect(provider.key.token).toBe(Engine);
expect(provider.multiProvider).toEqual(true);
expect(provider.resolvedFactories.length).toEqual(2);
});
it("should support multi bindings with only one binding", () => {
var binding =
Injector.resolve([new Binding(Engine, {toClass: BrokenEngine, multi: true})])[0];
it("should support multi providers with only one provider", () => {
var provider =
Injector.resolve([new Provider(Engine, {toClass: BrokenEngine, multi: true})])[0];
expect(binding.key.token).toBe(Engine);
expect(binding.multiBinding).toEqual(true);
expect(binding.resolvedFactories.length).toEqual(1);
expect(provider.key.token).toBe(Engine);
expect(provider.multiProvider).toEqual(true);
expect(provider.resolvedFactories.length).toEqual(1);
});
it("should throw when mixing multi bindings with regular bindings", () => {
it("should throw when mixing multi providers with regular providers", () => {
expect(() => {
Injector.resolve([new Binding(Engine, {toClass: BrokenEngine, multi: true}), Engine]);
}).toThrowErrorWith("Cannot mix multi bindings and regular bindings");
Injector.resolve([new Provider(Engine, {toClass: BrokenEngine, multi: true}), Engine]);
}).toThrowErrorWith("Cannot mix multi providers and regular providers");
expect(() => {
Injector.resolve([Engine, new Binding(Engine, {toClass: BrokenEngine, multi: true})]);
}).toThrowErrorWith("Cannot mix multi bindings and regular bindings");
Injector.resolve([Engine, new Provider(Engine, {toClass: BrokenEngine, multi: true})]);
}).toThrowErrorWith("Cannot mix multi providers and regular providers");
});
it('should resolve forward references', () => {
var bindings = Injector.resolve([
var providers = Injector.resolve([
forwardRef(() => Engine),
[bind(forwardRef(() => BrokenEngine)).toClass(forwardRef(() => Engine))],
bind(forwardRef(() => String)).toFactory(() => 'OK', [forwardRef(() => Engine)])
[provide(forwardRef(() => BrokenEngine), {asClass: forwardRef(() => Engine)})],
provide(forwardRef(() => String),
{asFactory: () => 'OK', deps: [forwardRef(() => Engine)]})
]);
var engineBinding = bindings[0];
var brokenEngineBinding = bindings[1];
var stringBinding = bindings[2];
var engineProvider = providers[0];
var brokenEngineProvider = providers[1];
var stringProvider = providers[2];
expect(engineBinding.resolvedFactories[0].factory() instanceof Engine).toBe(true);
expect(brokenEngineBinding.resolvedFactories[0].factory() instanceof Engine).toBe(true);
expect(stringBinding.resolvedFactories[0].dependencies[0].key).toEqual(Key.get(Engine));
expect(engineProvider.resolvedFactories[0].factory() instanceof Engine).toBe(true);
expect(brokenEngineProvider.resolvedFactories[0].factory() instanceof Engine).toBe(true);
expect(stringProvider.resolvedFactories[0].dependencies[0].key).toEqual(Key.get(Engine));
});
it('should support overriding factory dependencies with dependency annotations', () => {
var bindings = Injector.resolve([
bind("token")
.toFactory((e) => "result",
[[new InjectMetadata("dep"), new CustomDependencyMetadata()]])
var providers = Injector.resolve([
provide("token",
{
asFactory: (e) => "result",
deps: [[new InjectMetadata("dep"), new CustomDependencyMetadata()]]
})
]);
var binding = bindings[0];
var provider = providers[0];
expect(binding.resolvedFactories[0].dependencies[0].key.token).toEqual("dep");
expect(binding.resolvedFactories[0].dependencies[0].properties)
expect(provider.resolvedFactories[0].dependencies[0].key.token).toEqual("dep");
expect(provider.resolvedFactories[0].dependencies[0].properties)
.toEqual([new CustomDependencyMetadata()]);
});
});
@@ -646,7 +644,7 @@ export function main() {
describe("displayName", () => {
it("should work", () => {
expect(Injector.resolveAndCreate([Engine, BrokenEngine]).displayName)
.toEqual('Injector(bindings: [ "Engine" , "BrokenEngine" ])');
.toEqual('Injector(providers: [ "Engine" , "BrokenEngine" ])');
});
});
});
@@ -15,7 +15,7 @@ import {
xit,
} from 'angular2/test_lib';
import {ListWrapper, StringMapWrapper} from 'angular2/src/core/facade/collection';
import {Component, View, NgFor, bind} from 'angular2/angular2';
import {Component, View, NgFor, provide} from 'angular2/angular2';
import {NgClass} from 'angular2/src/core/directives/ng_class';
import {APP_VIEW_POOL_CAPACITY} from 'angular2/src/core/linker/view_pool';
@@ -29,7 +29,7 @@ export function main() {
describe('binding to CSS class list', () => {
describe('viewpool support', () => {
beforeEachBindings(() => { return [bind(APP_VIEW_POOL_CAPACITY).toValue(100)]; });
beforeEachBindings(() => { return [provide(APP_VIEW_POOL_CAPACITY, {asValue: 100})]; });
it('should clean up when the directive is destroyed',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
@@ -12,6 +12,7 @@ import {
} from 'angular2/test_lib';
import {
bind,
provide,
forwardRef,
resolveForwardRef,
Component,
@@ -39,7 +40,7 @@ export function main() {
});
}
@Component({selector: 'app', viewBindings: [forwardRef(() => Frame)]})
@Component({selector: 'app', viewProviders: [forwardRef(() => Frame)]})
@View({
template: `<door><lock></lock></door>`,
directives: [forwardRef(() => Door), forwardRef(() => Lock)]
@@ -13,7 +13,7 @@ import {
beforeEachBindings
} from 'angular2/test_lib';
import {Component, View, bind} from 'angular2/core';
import {Component, View, provide} from 'angular2/core';
import {SpyProtoViewFactory} from '../spies';
import {
CompiledHostTemplate,
@@ -37,10 +37,10 @@ export function main() {
protoViewFactorySpy = new SpyProtoViewFactory();
someProtoView = new AppProtoView(null, null, null, null, null, null);
protoViewFactorySpy.spy('createHost').andReturn(someProtoView);
var factoryBinding = bind(ProtoViewFactory).toValue(protoViewFactorySpy);
var classBinding = bind(Compiler).toClass(Compiler_);
var bindings = [factoryBinding, classBinding];
return bindings;
var factory = provide(ProtoViewFactory, {asValue: protoViewFactorySpy});
var classProvider = provide(Compiler, {asClass: Compiler_});
var providers = [factory, classProvider];
return providers;
});
beforeEach(inject([Compiler], (_compiler) => {
@@ -47,8 +47,6 @@ class SomeDirectiveWithProperties {
class SomeDirectiveWithEvents {
}
@Directive({selector: 'someDirective'})
class SomeDirectiveWithSetterProps {
@Input("renamed")
@@ -143,11 +141,6 @@ export function main() {
expect(directiveMetadata.inputs).toEqual(['a: renamed']);
});
it('should use properties as inputs', () => {
var directiveMetadata = resolver.resolve(SomeDirectiveWithProperties);
expect(directiveMetadata.inputs).toEqual(['a']);
});
});
describe('outputs', () => {
@@ -160,11 +153,6 @@ export function main() {
var directiveMetadata = resolver.resolve(SomeDirectiveWithGetterOutputs);
expect(directiveMetadata.outputs).toEqual(['a: renamed']);
});
it('should use events as outputs', () => {
var directiveMetadata = resolver.resolve(SomeDirectiveWithEvents);
expect(directiveMetadata.outputs).toEqual(['a']);
});
});
describe('host', () => {
@@ -270,7 +270,7 @@ class ChildComp {
class DynamicallyCreatedComponentService {}
@Component({selector: 'hello-cmp', viewBindings: [DynamicallyCreatedComponentService]})
@Component({selector: 'hello-cmp', viewProviders: [DynamicallyCreatedComponentService]})
@View({template: "{{greeting}}"})
class DynamicallyCreatedCmp implements OnDestroy {
greeting: string;
@@ -27,7 +27,7 @@ import {
ProtoElementInjector,
ElementInjector,
PreBuiltObjects,
DirectiveBinding,
DirectiveProvider,
TreeNode
} from 'angular2/src/core/linker/element_injector';
import {
@@ -38,7 +38,7 @@ import {
DirectiveMetadata
} from 'angular2/src/core/metadata';
import {OnDestroy} from 'angular2/lifecycle_hooks';
import {bind, Injector, Binding, Optional, Inject, Injectable, Self, SkipSelf, InjectMetadata, Host, HostMetadata, SkipSelfMetadata} from 'angular2/core';
import {provide, Injector, Provider, Optional, Inject, Injectable, Self, SkipSelf, InjectMetadata, Host, HostMetadata, SkipSelfMetadata} from 'angular2/core';
import {ViewContainerRef, ViewContainerRef_} from 'angular2/src/core/linker/view_container_ref';
import {TemplateRef, TemplateRef_} from 'angular2/src/core/linker/template_ref';
import {ElementRef} from 'angular2/src/core/linker/element_ref';
@@ -228,25 +228,25 @@ class DirectiveWithDestroy implements OnDestroy {
export function main() {
var defaultPreBuiltObjects = new PreBuiltObjects(null, createDummyView(), <any>new SpyElementRef(), null);
// An injector with more than 10 bindings will switch to the dynamic strategy
var dynamicBindings = [];
// An injector with more than 10 providers will switch to the dynamic strategy
var dynamicProviders = [];
for (var i = 0; i < 20; i++) {
dynamicBindings.push(bind(i).toValue(i));
dynamicProviders.push(provide(i, {asValue: i}));
}
function createPei(parent, index, bindings: any[], distance = 1, hasShadowRoot = false, dirVariableBindings = null) {
var directiveBinding = bindings.map(b => {
if (b instanceof DirectiveBinding) return b;
if (b instanceof Binding) return DirectiveBinding.createFromBinding(b, null);
return DirectiveBinding.createFromType(b, null);
function createPei(parent, index, providers: any[], distance = 1, hasShadowRoot = false, dirVariableBindings = null) {
var directiveProvider = providers.map(b => {
if (b instanceof DirectiveProvider) return b;
if (b instanceof Provider) return DirectiveProvider.createFromProvider(b, null);
return DirectiveProvider.createFromType(b, null);
});
return ProtoElementInjector.create(parent, index, directiveBinding, hasShadowRoot, distance, dirVariableBindings);
return ProtoElementInjector.create(parent, index, directiveProvider, hasShadowRoot, distance, dirVariableBindings);
}
function injector(bindings, imperativelyCreatedInjector = null, isComponent: boolean = false,
function injector(providers, imperativelyCreatedInjector = null, isComponent: boolean = false,
preBuiltObjects = null, attributes = null, dirVariableBindings = null) {
var proto = createPei(null, 0, bindings, 0, isComponent, dirVariableBindings);
var proto = createPei(null, 0, providers, 0, isComponent, dirVariableBindings);
proto.attributes = attributes;
var inj = proto.instantiate(null);
@@ -255,28 +255,28 @@ export function main() {
return inj;
}
function parentChildInjectors(parentBindings, childBindings, parentPreBuildObjects = null, imperativelyCreatedInjector = null) {
function parentChildInjectors(parentProviders, childProviders, parentPreBuildObjects = null, imperativelyCreatedInjector = null) {
if (isBlank(parentPreBuildObjects)) parentPreBuildObjects = defaultPreBuiltObjects;
var protoParent = createPei(null, 0, parentBindings);
var protoParent = createPei(null, 0, parentProviders);
var parent = protoParent.instantiate(null);
parent.hydrate(null, null, parentPreBuildObjects);
var protoChild = createPei(protoParent, 1, childBindings, 1, false);
var protoChild = createPei(protoParent, 1, childProviders, 1, false);
var child = protoChild.instantiate(parent);
child.hydrate(imperativelyCreatedInjector, null, defaultPreBuiltObjects);
return child;
}
function hostShadowInjectors(hostBindings: any[],
shadowBindings: any[], imperativelyCreatedInjector = null): ElementInjector {
var protoHost = createPei(null, 0, hostBindings, 0, true);
function hostShadowInjectors(hostProviders: any[],
shadowProviders: any[], imperativelyCreatedInjector = null): ElementInjector {
var protoHost = createPei(null, 0, hostProviders, 0, true);
var host = protoHost.instantiate(null);
host.hydrate(null, null, defaultPreBuiltObjects);
var protoShadow = createPei(null, 0, shadowBindings, 0, false);
var protoShadow = createPei(null, 0, shadowProviders, 0, false);
var shadow = protoShadow.instantiate(null);
shadow.hydrate(imperativelyCreatedInjector, host, null);
@@ -321,33 +321,33 @@ export function main() {
});
describe('inline strategy', () => {
it("should allow for direct access using getBindingAtIndex", () => {
var proto = createPei(null, 0, [bind(SimpleDirective).toClass(SimpleDirective)]);
it("should allow for direct access using getProviderAtIndex", () => {
var proto = createPei(null, 0, [provide(SimpleDirective, {asClass: SimpleDirective})]);
expect(proto.getBindingAtIndex(0)).toBeAnInstanceOf(DirectiveBinding);
expect(() => proto.getBindingAtIndex(-1)).toThrowError('Index -1 is out-of-bounds.');
expect(() => proto.getBindingAtIndex(10)).toThrowError('Index 10 is out-of-bounds.');
expect(proto.getProviderAtIndex(0)).toBeAnInstanceOf(DirectiveProvider);
expect(() => proto.getProviderAtIndex(-1)).toThrowError('Index -1 is out-of-bounds.');
expect(() => proto.getProviderAtIndex(10)).toThrowError('Index 10 is out-of-bounds.');
});
});
describe('dynamic strategy', () => {
it("should allow for direct access using getBindingAtIndex", () => {
var proto = createPei(null, 0, dynamicBindings);
it("should allow for direct access using getProviderAtIndex", () => {
var proto = createPei(null, 0, dynamicProviders);
expect(proto.getBindingAtIndex(0)).toBeAnInstanceOf(DirectiveBinding);
expect(() => proto.getBindingAtIndex(-1)).toThrowError('Index -1 is out-of-bounds.');
expect(() => proto.getBindingAtIndex(dynamicBindings.length - 1)).not.toThrow();
expect(() => proto.getBindingAtIndex(dynamicBindings.length))
.toThrowError(`Index ${dynamicBindings.length} is out-of-bounds.`);
expect(proto.getProviderAtIndex(0)).toBeAnInstanceOf(DirectiveProvider);
expect(() => proto.getProviderAtIndex(-1)).toThrowError('Index -1 is out-of-bounds.');
expect(() => proto.getProviderAtIndex(dynamicProviders.length - 1)).not.toThrow();
expect(() => proto.getProviderAtIndex(dynamicProviders.length))
.toThrowError(`Index ${dynamicProviders.length} is out-of-bounds.`);
});
});
describe('event emitters', () => {
it('should return a list of event accessors', () => {
var binding = DirectiveBinding.createFromType(HasEventEmitter,
var provider = DirectiveProvider.createFromType(HasEventEmitter,
new DirectiveMetadata({outputs: ['emitter']}));
var inj = createPei(null, 0, [binding]);
var inj = createPei(null, 0, [provider]);
expect(inj.eventEmitterAccessors.length).toEqual(1);
var accessor = inj.eventEmitterAccessors[0][0];
@@ -356,10 +356,10 @@ export function main() {
});
it('should allow a different event vs field name', () => {
var binding = DirectiveBinding.createFromType(HasEventEmitter,
var provider = DirectiveProvider.createFromType(HasEventEmitter,
new DirectiveMetadata({outputs: ['emitter: publicEmitter']}));
var inj = createPei(null, 0, [binding]);
var inj = createPei(null, 0, [provider]);
expect(inj.eventEmitterAccessors.length).toEqual(1);
var accessor = inj.eventEmitterAccessors[0][0];
@@ -369,53 +369,53 @@ export function main() {
});
describe(".create", () => {
it("should collect bindings from all directives", () => {
it("should collect providers from all directives", () => {
var pei = createPei(null, 0, [
DirectiveBinding.createFromType(
DirectiveProvider.createFromType(
SimpleDirective,
new ComponentMetadata({bindings: [bind('injectable1').toValue('injectable1')]})),
DirectiveBinding.createFromType(SomeOtherDirective, new ComponentMetadata({
bindings: [bind('injectable2').toValue('injectable2')]
new ComponentMetadata({providers: [provide('injectable1', {asValue: 'injectable1'})]})),
DirectiveProvider.createFromType(SomeOtherDirective, new ComponentMetadata({
providers: [provide('injectable2', {asValue: 'injectable2'})]
}))
]);
expect(pei.getBindingAtIndex(0).key.token).toBe(SimpleDirective);
expect(pei.getBindingAtIndex(1).key.token).toBe(SomeOtherDirective);
expect(pei.getBindingAtIndex(2).key.token).toEqual("injectable1");
expect(pei.getBindingAtIndex(3).key.token).toEqual("injectable2");
expect(pei.getProviderAtIndex(0).key.token).toBe(SimpleDirective);
expect(pei.getProviderAtIndex(1).key.token).toBe(SomeOtherDirective);
expect(pei.getProviderAtIndex(2).key.token).toEqual("injectable1");
expect(pei.getProviderAtIndex(3).key.token).toEqual("injectable2");
});
it("should collect view bindings from the component", () => {
it("should collect view providers from the component", () => {
var pei = createPei(null, 0,
[DirectiveBinding.createFromType(SimpleDirective, new ComponentMetadata({
viewBindings: [bind('injectable1').toValue('injectable1')]
[DirectiveProvider.createFromType(SimpleDirective, new ComponentMetadata({
viewProviders: [provide('injectable1', {asValue: 'injectable1'})]
}))],
0, true);
expect(pei.getBindingAtIndex(0).key.token).toBe(SimpleDirective);
expect(pei.getBindingAtIndex(1).key.token).toEqual("injectable1");
expect(pei.getProviderAtIndex(0).key.token).toBe(SimpleDirective);
expect(pei.getProviderAtIndex(1).key.token).toEqual("injectable1");
});
it("should flatten nested arrays", () => {
var pei = createPei(null, 0, [
DirectiveBinding.createFromType(
DirectiveProvider.createFromType(
SimpleDirective,
new ComponentMetadata({
viewBindings: [[[bind('view').toValue('view')]]],
bindings: [[[bind('host').toValue('host')]]]
viewProviders: [[[provide('view', {asValue: 'view'})]]],
providers: [[[provide('host', {asValue: 'host'})]]]
}))
], 0, true);
expect(pei.getBindingAtIndex(0).key.token).toBe(SimpleDirective);
expect(pei.getBindingAtIndex(1).key.token).toEqual("view");
expect(pei.getBindingAtIndex(2).key.token).toEqual("host");
expect(pei.getProviderAtIndex(0).key.token).toBe(SimpleDirective);
expect(pei.getProviderAtIndex(1).key.token).toEqual("view");
expect(pei.getProviderAtIndex(2).key.token).toEqual("host");
});
it('should support an arbitrary number of bindings', () => {
var pei = createPei(null, 0, dynamicBindings);
it('should support an arbitrary number of providers', () => {
var pei = createPei(null, 0, dynamicProviders);
for (var i = 0; i < dynamicBindings.length; i++) {
expect(pei.getBindingAtIndex(i).key.token).toBe(i);
for (var i = 0; i < dynamicProviders.length; i++) {
expect(pei.getProviderAtIndex(i).key.token).toBe(i);
}
});
});
@@ -463,7 +463,7 @@ export function main() {
});
describe("hasBindings", () => {
it("should be true when there are bindings", () => {
it("should be true when there are providers", () => {
var p = createPei(null, 0, [SimpleDirective]);
expect(p.hasBindings).toBeTruthy();
});
@@ -482,22 +482,22 @@ export function main() {
() => { expect(injector([SimpleDirective]).hasInstances()).toBe(true); });
});
[{ strategy: 'inline', bindings: [] }, { strategy: 'dynamic',
bindings: dynamicBindings }].forEach((context) => {
[{ strategy: 'inline', providers: [] }, { strategy: 'dynamic',
providers: dynamicProviders }].forEach((context) => {
var extraBindings = context['bindings'];
var extraProviders = context['providers'];
describe(`${context['strategy']} strategy`, () => {
describe("hydrate", () => {
it("should instantiate directives that have no dependencies", () => {
var bindings = ListWrapper.concat([SimpleDirective], extraBindings);
var inj = injector(bindings);
var providers = ListWrapper.concat([SimpleDirective], extraProviders);
var inj = injector(providers);
expect(inj.get(SimpleDirective)).toBeAnInstanceOf(SimpleDirective);
});
it("should instantiate directives that depend on an arbitrary number of directives", () => {
var bindings = ListWrapper.concat([SimpleDirective, NeedsDirective], extraBindings);
var inj = injector(bindings);
var providers = ListWrapper.concat([SimpleDirective, NeedsDirective], extraProviders);
var inj = injector(providers);
var d = inj.get(NeedsDirective);
@@ -505,80 +505,74 @@ export function main() {
expect(d.dependency).toBeAnInstanceOf(SimpleDirective);
});
it("should instantiate bindings that have dependencies with set visibility",
it("should instantiate providers that have dependencies with set visibility",
function() {
var childInj = parentChildInjectors(
ListWrapper.concat(
[DirectiveBinding.createFromType(SimpleDirective, new ComponentMetadata({
bindings: [bind('injectable1').toValue('injectable1')]
[DirectiveProvider.createFromType(SimpleDirective, new ComponentMetadata({
providers: [provide('injectable1', {asValue: 'injectable1'})]
}))],
extraBindings),
[DirectiveBinding.createFromType(SimpleDirective, new ComponentMetadata({
bindings: [
bind('injectable1')
.toValue('new-injectable1'),
bind('injectable2')
.toFactory(
extraProviders),
[DirectiveProvider.createFromType(SimpleDirective, new ComponentMetadata({
providers: [
provide('injectable1', {asValue:'new-injectable1'}),
provide('injectable2', {asFactory:
(val) => `${val}-injectable2`,
[[new InjectMetadata('injectable1'), new SkipSelfMetadata()]])
deps: [[new InjectMetadata('injectable1'), new SkipSelfMetadata()]]})
]
}))]);
expect(childInj.get('injectable2')).toEqual('injectable1-injectable2');
});
it("should instantiate bindings that have dependencies", () => {
var bindings = [
bind('injectable1')
.toValue('injectable1'),
bind('injectable2')
.toFactory(
it("should instantiate providers that have dependencies", () => {
var providers = [
provide('injectable1', {asValue: 'injectable1'}),
provide('injectable2', {asFactory:
(val) => `${val}-injectable2`,
['injectable1'])
deps: ['injectable1']})
];
var inj = injector(ListWrapper.concat(
[DirectiveBinding.createFromType(SimpleDirective,
new DirectiveMetadata({bindings: bindings}))],
extraBindings));
[DirectiveProvider.createFromType(SimpleDirective,
new DirectiveMetadata({providers: providers}))],
extraProviders));
expect(inj.get('injectable2')).toEqual('injectable1-injectable2');
});
it("should instantiate viewBindings that have dependencies", () => {
var viewBindings = [
bind('injectable1')
.toValue('injectable1'),
bind('injectable2')
.toFactory(
(val) => `${val}-injectable2`,
['injectable1'])
it("should instantiate viewProviders that have dependencies", () => {
var viewProviders = [
provide('injectable1', {asValue: 'injectable1'}),
provide('injectable2', {asFactory:
(val) => `${val}-injectable2`,
deps: ['injectable1']})
];
var inj = injector(ListWrapper.concat(
[DirectiveBinding.createFromType(SimpleDirective, new ComponentMetadata({
viewBindings: viewBindings}))], extraBindings),
[DirectiveProvider.createFromType(SimpleDirective, new ComponentMetadata({
viewProviders: viewProviders}))], extraProviders),
null, true);
expect(inj.get('injectable2')).toEqual('injectable1-injectable2');
});
it("should instantiate components that depend on viewBindings bindings", () => {
it("should instantiate components that depend on viewProviders providers", () => {
var inj = injector(
ListWrapper.concat([DirectiveBinding.createFromType(NeedsService, new ComponentMetadata({
viewBindings: [bind('service').toValue('service')]
ListWrapper.concat([DirectiveProvider.createFromType(NeedsService, new ComponentMetadata({
viewProviders: [provide('service', {asValue: 'service'})]
}))],
extraBindings),
extraProviders),
null, true);
expect(inj.get(NeedsService).service).toEqual('service');
});
it("should instantiate bindings lazily", () => {
it("should instantiate providers lazily", () => {
var created = false;
var inj = injector(
ListWrapper.concat([DirectiveBinding.createFromType(SimpleDirective, new ComponentMetadata({
bindings: [bind('service').toFactory(() => created = true)]
ListWrapper.concat([DirectiveProvider.createFromType(SimpleDirective, new ComponentMetadata({
providers: [provide('service', {asFactory: () => created = true})]
}))],
extraBindings),
extraProviders),
null, true);
expect(created).toBe(false);
@@ -588,13 +582,13 @@ export function main() {
expect(created).toBe(true);
});
it("should instantiate view bindings lazily", () => {
it("should instantiate view providers lazily", () => {
var created = false;
var inj = injector(
ListWrapper.concat([DirectiveBinding.createFromType(SimpleDirective, new ComponentMetadata({
viewBindings: [bind('service').toFactory(() => created = true)]
ListWrapper.concat([DirectiveProvider.createFromType(SimpleDirective, new ComponentMetadata({
viewProviders: [provide('service', {asFactory: () => created = true})]
}))],
extraBindings),
extraProviders),
null, true);
expect(created).toBe(false);
@@ -604,31 +598,31 @@ export function main() {
expect(created).toBe(true);
});
it("should not instantiate other directives that depend on viewBindings bindings",
it("should not instantiate other directives that depend on viewProviders providers",
() => {
var directiveAnnotation = new ComponentMetadata({
viewBindings: ListWrapper.concat([bind("service").toValue("service")], extraBindings)
viewProviders: ListWrapper.concat([provide("service", {asValue: "service"})], extraProviders)
});
var componentDirective =
DirectiveBinding.createFromType(SimpleDirective, directiveAnnotation);
DirectiveProvider.createFromType(SimpleDirective, directiveAnnotation);
expect(() => { injector([componentDirective, NeedsService], null); })
.toThrowError(containsRegexp(
`No provider for service! (${stringify(NeedsService) } -> service)`));
});
it("should instantiate directives that depend on bindings of other directives", () => {
it("should instantiate directives that depend on providers of other directives", () => {
var shadowInj = hostShadowInjectors(
ListWrapper.concat([DirectiveBinding.createFromType(SimpleDirective, new ComponentMetadata({
bindings: [bind('service').toValue('hostService')]})
)], extraBindings),
ListWrapper.concat([NeedsService], extraBindings)
ListWrapper.concat([DirectiveProvider.createFromType(SimpleDirective, new ComponentMetadata({
providers: [provide('service', {asValue: 'hostService'})]})
)], extraProviders),
ListWrapper.concat([NeedsService], extraProviders)
);
expect(shadowInj.get(NeedsService).service).toEqual('hostService');
});
it("should instantiate directives that depend on imperatively created injector bindings (bootstrap)", () => {
it("should instantiate directives that depend on imperatively created injector providers (bootstrap)", () => {
var imperativelyCreatedInjector = Injector.resolveAndCreate([
bind("service").toValue('appService')
provide("service", {asValue: 'appService'})
]);
var inj = injector([NeedsService], imperativelyCreatedInjector);
expect(inj.get(NeedsService).service).toEqual('appService');
@@ -636,81 +630,81 @@ export function main() {
expect(() => injector([NeedsServiceFromHost], imperativelyCreatedInjector)).toThrowError();
});
it("should instantiate directives that depend on imperatively created injector bindings (root injector)", () => {
it("should instantiate directives that depend on imperatively created injector providers (root injector)", () => {
var imperativelyCreatedInjector = Injector.resolveAndCreate([
bind("service").toValue('appService')
provide("service", {asValue: 'appService'})
]);
var inj = hostShadowInjectors([SimpleDirective], [NeedsService, NeedsServiceFromHost], imperativelyCreatedInjector);
expect(inj.get(NeedsService).service).toEqual('appService');
expect(inj.get(NeedsServiceFromHost).service).toEqual('appService');
});
it("should instantiate directives that depend on imperatively created injector bindings (child injector)", () => {
it("should instantiate directives that depend on imperatively created injector providers (child injector)", () => {
var imperativelyCreatedInjector = Injector.resolveAndCreate([
bind("service").toValue('appService')
provide("service", {asValue: 'appService'})
]);
var inj = parentChildInjectors([], [NeedsService, NeedsServiceFromHost], null, imperativelyCreatedInjector);
expect(inj.get(NeedsService).service).toEqual('appService');
expect(inj.get(NeedsServiceFromHost).service).toEqual('appService');
});
it("should prioritize viewBindings over bindings for the same binding", () => {
it("should prioritize viewProviders over providers for the same provider", () => {
var inj = injector(
ListWrapper.concat([DirectiveBinding.createFromType(NeedsService, new ComponentMetadata({
bindings: [bind('service').toValue('hostService')],
viewBindings: [bind('service').toValue('viewService')]})
)], extraBindings), null, true);
ListWrapper.concat([DirectiveProvider.createFromType(NeedsService, new ComponentMetadata({
providers: [provide('service', {asValue: 'hostService'})],
viewProviders: [provide('service', {asValue: 'viewService'})]})
)], extraProviders), null, true);
expect(inj.get(NeedsService).service).toEqual('viewService');
});
it("should prioritize directive bindings over component bindings", () => {
var component = DirectiveBinding.createFromType(NeedsService, new ComponentMetadata({
bindings: [bind('service').toValue('compService')]}));
var directive = DirectiveBinding.createFromType(SomeOtherDirective, new DirectiveMetadata({
bindings: [bind('service').toValue('dirService')]}));
var inj = injector(ListWrapper.concat([component, directive], extraBindings), null, true);
it("should prioritize directive providers over component providers", () => {
var component = DirectiveProvider.createFromType(NeedsService, new ComponentMetadata({
providers: [provide('service', {asValue: 'compService'})]}));
var directive = DirectiveProvider.createFromType(SomeOtherDirective, new DirectiveMetadata({
providers: [provide('service', {asValue: 'dirService'})]}));
var inj = injector(ListWrapper.concat([component, directive], extraProviders), null, true);
expect(inj.get(NeedsService).service).toEqual('dirService');
});
it("should not instantiate a directive in a view that has a host dependency on bindings"+
it("should not instantiate a directive in a view that has a host dependency on providers"+
" of the component", () => {
expect(() => {
hostShadowInjectors(
ListWrapper.concat([
DirectiveBinding.createFromType(SomeOtherDirective, new DirectiveMetadata({
bindings: [bind('service').toValue('hostService')]})
)], extraBindings),
ListWrapper.concat([NeedsServiceFromHost], extraBindings)
DirectiveProvider.createFromType(SomeOtherDirective, new DirectiveMetadata({
providers: [provide('service', {asValue: 'hostService'})]})
)], extraProviders),
ListWrapper.concat([NeedsServiceFromHost], extraProviders)
);
}).toThrowError(new RegExp("No provider for service!"));
});
it("should not instantiate a directive in a view that has a host dependency on bindings"+
it("should not instantiate a directive in a view that has a host dependency on providers"+
" of a decorator directive", () => {
expect(() => {
hostShadowInjectors(
ListWrapper.concat([
SimpleDirective,
DirectiveBinding.createFromType(SomeOtherDirective, new DirectiveMetadata({
bindings: [bind('service').toValue('hostService')]})
)], extraBindings),
DirectiveProvider.createFromType(SomeOtherDirective, new DirectiveMetadata({
providers: [provide('service', {asValue: 'hostService'})]})
)], extraProviders),
ListWrapper.concat([NeedsServiceFromHost], extraBindings)
ListWrapper.concat([NeedsServiceFromHost], extraProviders)
);
}).toThrowError(new RegExp("No provider for service!"));
});
it("should instantiate directives that depend on pre built objects", () => {
var templateRef = new TemplateRef_(<any>new SpyElementRef());
var bindings = ListWrapper.concat([NeedsTemplateRef], extraBindings);
var inj = injector(bindings, null, false, new PreBuiltObjects(null, null, null, templateRef));
var providers = ListWrapper.concat([NeedsTemplateRef], extraProviders);
var inj = injector(providers, null, false, new PreBuiltObjects(null, null, null, templateRef));
expect(inj.get(NeedsTemplateRef).templateRef).toEqual(templateRef);
});
it("should get directives", () => {
var child = hostShadowInjectors(
ListWrapper.concat([SomeOtherDirective, SimpleDirective], extraBindings),
ListWrapper.concat([SomeOtherDirective, SimpleDirective], extraProviders),
[NeedsDirectiveFromHostShadowDom]);
var d = child.get(NeedsDirectiveFromHostShadowDom);
@@ -720,7 +714,7 @@ export function main() {
});
it("should get directives from the host", () => {
var child = parentChildInjectors(ListWrapper.concat([SimpleDirective], extraBindings),
var child = parentChildInjectors(ListWrapper.concat([SimpleDirective], extraProviders),
[NeeedsDirectiveFromHost]);
var d = child.get(NeeedsDirectiveFromHost);
@@ -730,30 +724,30 @@ export function main() {
});
it("should throw when a dependency cannot be resolved", () => {
expect(() => injector(ListWrapper.concat([NeeedsDirectiveFromHost], extraBindings)))
expect(() => injector(ListWrapper.concat([NeeedsDirectiveFromHost], extraProviders)))
.toThrowError(containsRegexp(
`No provider for ${stringify(SimpleDirective) }! (${stringify(NeeedsDirectiveFromHost) } -> ${stringify(SimpleDirective) })`));
});
it("should inject null when an optional dependency cannot be resolved", () => {
var inj = injector(ListWrapper.concat([OptionallyNeedsDirective], extraBindings));
var inj = injector(ListWrapper.concat([OptionallyNeedsDirective], extraProviders));
var d = inj.get(OptionallyNeedsDirective);
expect(d.dependency).toEqual(null);
});
it("should accept bindings instead of types", () => {
it("should accept providers instead of types", () => {
var inj = injector(
ListWrapper.concat([bind(SimpleDirective).toClass(SimpleDirective)], extraBindings));
ListWrapper.concat([provide(SimpleDirective, {asClass: SimpleDirective})], extraProviders));
expect(inj.get(SimpleDirective)).toBeAnInstanceOf(SimpleDirective);
});
it("should allow for direct access using getDirectiveAtIndex", () => {
var bindings =
ListWrapper.concat([bind(SimpleDirective).toClass(SimpleDirective)], extraBindings);
var providers =
ListWrapper.concat([provide(SimpleDirective, {asClass: SimpleDirective})], extraProviders);
var inj = injector(bindings);
var inj = injector(providers);
var firsIndexOut = bindings.length > 10 ? bindings.length : 10;
var firsIndexOut = providers.length > 10 ? providers.length : 10;
expect(inj.getDirectiveAtIndex(0)).toBeAnInstanceOf(SimpleDirective);
expect(() => inj.getDirectiveAtIndex(-1)).toThrowError('Index -1 is out-of-bounds.');
@@ -762,9 +756,9 @@ export function main() {
});
it("should instantiate directives that depend on the containing component", () => {
var directiveBinding =
DirectiveBinding.createFromType(SimpleDirective, new ComponentMetadata());
var shadow = hostShadowInjectors(ListWrapper.concat([directiveBinding], extraBindings),
var directiveProvider =
DirectiveProvider.createFromType(SimpleDirective, new ComponentMetadata());
var shadow = hostShadowInjectors(ListWrapper.concat([directiveProvider], extraProviders),
[NeeedsDirectiveFromHost]);
var d = shadow.get(NeeedsDirectiveFromHost);
@@ -774,12 +768,12 @@ export function main() {
it("should not instantiate directives that depend on other directives in the containing component's ElementInjector",
() => {
var directiveBinding =
DirectiveBinding.createFromType(SomeOtherDirective, new ComponentMetadata());
var directiveProvider =
DirectiveProvider.createFromType(SomeOtherDirective, new ComponentMetadata());
expect(() =>
{
hostShadowInjectors(
ListWrapper.concat([directiveBinding, SimpleDirective], extraBindings),
ListWrapper.concat([directiveProvider, SimpleDirective], extraProviders),
[NeedsDirective]);
})
.toThrowError(containsRegexp(
@@ -789,12 +783,12 @@ export function main() {
describe("getRootViewInjectors", () => {
it("should return an empty array if there is no nested view", () => {
var inj = injector(extraBindings);
var inj = injector(extraProviders);
expect(inj.getRootViewInjectors()).toEqual([]);
});
it("should return an empty array on a dehydrated view", () => {
var inj = injector(extraBindings);
var inj = injector(extraProviders);
inj.dehydrate();
expect(inj.getRootViewInjectors()).toEqual([]);
});
@@ -810,19 +804,19 @@ export function main() {
}
it("should handle repeated hydration / dehydration", () => {
var inj = injector(extraBindings);
var inj = injector(extraProviders);
cycleHydrate(inj);
});
it("should handle repeated hydration / dehydration with query present", () => {
var inj = injector(ListWrapper.concat([NeedsQuery], extraBindings));
var inj = injector(ListWrapper.concat([NeedsQuery], extraProviders));
cycleHydrate(inj);
});
it("should handle repeated hydration / dehydration with view query present", () => {
var inj = injector(extraBindings);
var host = injector(ListWrapper.concat([NeedsViewQuery], extraBindings));
var inj = injector(extraProviders);
var host = injector(ListWrapper.concat([NeedsViewQuery], extraProviders));
cycleHydrate(inj, host);
});
@@ -831,9 +825,9 @@ export function main() {
describe("lifecycle", () => {
it("should call onDestroy on directives subscribed to this event", () => {
var inj = injector(ListWrapper.concat(
[DirectiveBinding.createFromType(DirectiveWithDestroy,
[DirectiveProvider.createFromType(DirectiveWithDestroy,
new DirectiveMetadata())],
extraBindings));
extraProviders));
var destroy = inj.get(DirectiveWithDestroy);
inj.dehydrate();
expect(destroy.onDestroyCounter).toBe(1);
@@ -841,9 +835,9 @@ export function main() {
it("should work with services", () => {
var inj = injector(ListWrapper.concat(
[DirectiveBinding.createFromType(
SimpleDirective, new DirectiveMetadata({bindings: [SimpleService]}))],
extraBindings));
[DirectiveProvider.createFromType(
SimpleDirective, new DirectiveMetadata({providers: [SimpleService]}))],
extraProviders));
inj.dehydrate();
});
});
@@ -854,7 +848,7 @@ export function main() {
attributes.set( 'type', 'text');
attributes.set( 'title', '');
var inj = injector(ListWrapper.concat([NeedsAttribute], extraBindings), null, false, null,
var inj = injector(ListWrapper.concat([NeedsAttribute], extraProviders), null, false, null,
attributes);
var needsAttribute = inj.get(NeedsAttribute);
@@ -867,7 +861,7 @@ export function main() {
var attributes = new Map();
attributes.set( 'foo', 'bar');
var inj = injector(ListWrapper.concat([NeedsAttributeNoType], extraBindings), null, false,
var inj = injector(ListWrapper.concat([NeedsAttributeNoType], extraProviders), null, false,
null, attributes);
var needsAttribute = inj.get(NeedsAttributeNoType);
@@ -877,7 +871,7 @@ export function main() {
describe("refs", () => {
it("should inject ElementRef", () => {
var inj = injector(ListWrapper.concat([NeedsElementRef], extraBindings));
var inj = injector(ListWrapper.concat([NeedsElementRef], extraProviders));
expect(inj.get(NeedsElementRef).elementRef).toBe(defaultPreBuiltObjects.elementRef);
});
@@ -886,8 +880,8 @@ export function main() {
var view = <any>createDummyView();
var childView = createDummyView(cd);
view.spy('getNestedView').andReturn(childView);
var binding = DirectiveBinding.createFromType(ComponentNeedsChangeDetectorRef, new ComponentMetadata());
var inj = injector(ListWrapper.concat([binding], extraBindings), null, true,
var provider = DirectiveProvider.createFromType(ComponentNeedsChangeDetectorRef, new ComponentMetadata());
var inj = injector(ListWrapper.concat([provider], extraProviders), null, true,
new PreBuiltObjects(null, view, <any>new SpyElementRef(), null));
expect(inj.get(ComponentNeedsChangeDetectorRef).changeDetectorRef).toBe(cd.ref);
@@ -896,34 +890,34 @@ export function main() {
it("should inject ChangeDetectorRef of the containing component into directives", () => {
var cd = new DynamicChangeDetector(null, null, 0, [], [], null, [], [], [], null);
var view = createDummyView(cd);
var binding = DirectiveBinding.createFromType(DirectiveNeedsChangeDetectorRef, new DirectiveMetadata());
var inj = injector(ListWrapper.concat([binding], extraBindings), null, false,
var provider = DirectiveProvider.createFromType(DirectiveNeedsChangeDetectorRef, new DirectiveMetadata());
var inj = injector(ListWrapper.concat([provider], extraProviders), null, false,
new PreBuiltObjects(null, view, <any>new SpyElementRef(), null));
expect(inj.get(DirectiveNeedsChangeDetectorRef).changeDetectorRef).toBe(cd.ref);
});
it('should inject ViewContainerRef', () => {
var inj = injector(ListWrapper.concat([NeedsViewContainer], extraBindings));
var inj = injector(ListWrapper.concat([NeedsViewContainer], extraProviders));
expect(inj.get(NeedsViewContainer).viewContainer).toBeAnInstanceOf(ViewContainerRef_);
});
it("should inject TemplateRef", () => {
var templateRef = new TemplateRef_(<any>new SpyElementRef());
var inj = injector(ListWrapper.concat([NeedsTemplateRef], extraBindings), null, false,
var inj = injector(ListWrapper.concat([NeedsTemplateRef], extraProviders), null, false,
new PreBuiltObjects(null, null, null, templateRef));
expect(inj.get(NeedsTemplateRef).templateRef).toEqual(templateRef);
});
it("should throw if there is no TemplateRef", () => {
expect(() => injector(ListWrapper.concat([NeedsTemplateRef], extraBindings)))
expect(() => injector(ListWrapper.concat([NeedsTemplateRef], extraProviders)))
.toThrowError(
`No provider for TemplateRef! (${stringify(NeedsTemplateRef) } -> TemplateRef)`);
});
it('should inject null if there is no TemplateRef when the dependency is optional', () => {
var inj = injector(ListWrapper.concat([OptionallyInjectsTemplateRef], extraBindings));
var inj = injector(ListWrapper.concat([OptionallyInjectsTemplateRef], extraProviders));
var instance = inj.get(OptionallyInjectsTemplateRef);
expect(instance.templateRef).toBeNull();
});
@@ -950,7 +944,7 @@ export function main() {
it('should be injectable', () => {
var inj =
injector(ListWrapper.concat([NeedsQuery], extraBindings), null, false, preBuildObjects);
injector(ListWrapper.concat([NeedsQuery], extraProviders), null, false, preBuildObjects);
expect(inj.get(NeedsQuery).query).toBeAnInstanceOf(QueryList);
});
@@ -958,7 +952,7 @@ export function main() {
var inj = injector(ListWrapper.concat([
NeedsQuery,
CountingDirective
], extraBindings), null,
], extraProviders), null,
false, preBuildObjects);
addInj(dummyView, inj);
@@ -971,7 +965,7 @@ export function main() {
var preBuiltObjects = new PreBuiltObjects(null, dummyView, null, new TemplateRef_(<any>new SpyElementRef()));
var inj = injector(ListWrapper.concat([
NeedsTemplateRefQuery
], extraBindings), null,
], extraProviders), null,
false, preBuiltObjects);
addInj(dummyView, inj);
@@ -980,14 +974,14 @@ export function main() {
expect(inj.get(NeedsTemplateRefQuery).query.first).toBe(preBuiltObjects.templateRef);
});
it('should contain the element when no directives are bound to the var binding', () => {
it('should contain the element when no directives are bound to the var provider', () => {
var dirs = [NeedsQueryByVarBindings];
var dirVariableBindings = MapWrapper.createFromStringMap({
"one": null // element
});
var inj = injector(dirs.concat(extraBindings), null,
var inj = injector(dirs.concat(extraProviders), null,
false, preBuildObjects, null, dirVariableBindings);
addInj(dummyView, inj);
@@ -996,8 +990,8 @@ export function main() {
expect(inj.get(NeedsQueryByVarBindings).query.first).toBe(preBuildObjects.elementRef);
});
it('should contain directives on the same injector when querying by variable bindings' +
'in the order of var bindings specified in the query', () => {
it('should contain directives on the same injector when querying by variable providers' +
'in the order of var providers specified in the query', () => {
var dirs = [NeedsQueryByVarBindings, NeedsDirective, SimpleDirective];
var dirVariableBindings = MapWrapper.createFromStringMap({
@@ -1005,7 +999,7 @@ export function main() {
"two": 1 // 1 is the index of NeedsDirective
});
var inj = injector(dirs.concat(extraBindings), null,
var inj = injector(dirs.concat(extraProviders), null,
false, preBuildObjects, null, dirVariableBindings);
addInj(dummyView, inj);
@@ -1019,7 +1013,7 @@ export function main() {
it('should contain directives on the same and a child injector in construction order', () => {
var protoParent = createPei(null, 0, [NeedsQuery, CountingDirective]);
var protoChild =
createPei(protoParent, 1, ListWrapper.concat([CountingDirective], extraBindings));
createPei(protoParent, 1, ListWrapper.concat([CountingDirective], extraProviders));
var parent = protoParent.instantiate(null);
var child = protoChild.instantiate(parent);
@@ -46,8 +46,9 @@ import {
import {
Injector,
bind,
provide,
Injectable,
Binding,
Provider,
forwardRef,
OpaqueToken,
Inject,
@@ -96,7 +97,7 @@ const ANCHOR_ELEMENT = CONST_EXPR(new OpaqueToken('AnchorElement'));
export function main() {
describe('integration tests', function() {
beforeEachBindings(() => [bind(ANCHOR_ELEMENT).toValue(el('<div></div>'))]);
beforeEachBindings(() => [provide(ANCHOR_ELEMENT, {asValue: el('<div></div>')})]);
describe('react to record changes', function() {
it('should consume text node changes',
@@ -1081,7 +1082,7 @@ export function main() {
});
}));
it("should support viewBindings",
it("should support viewProviders",
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
tcb.overrideView(DirectiveProvidingInjectableInView, new ViewMetadata({
template: `
@@ -1515,8 +1516,8 @@ export function main() {
describe('logging property updates', () => {
beforeEachBindings(() => [
bind(ChangeDetectorGenConfig)
.toValue(new ChangeDetectorGenConfig(true, true, true, false))
provide(ChangeDetectorGenConfig,
{asValue: new ChangeDetectorGenConfig(true, true, true, false)})
]);
it('should reflect property values as attributes',
@@ -1740,7 +1741,7 @@ class DynamicViewport {
var myService = new MyService();
myService.greeting = 'dynamic greet';
var bindings = Injector.resolve([bind(MyService).toValue(myService)]);
var bindings = Injector.resolve([provide(MyService, {asValue: myService})]);
this.done = compiler.compileInHost(ChildCompUsingService)
.then((hostPv) => {vc.createHostView(hostPv, 0, bindings)});
}
@@ -1841,7 +1842,7 @@ class MyComp {
throwError() { throw 'boom'; }
}
@Component({selector: 'child-cmp', inputs: ['dirProp'], viewBindings: [MyService]})
@Component({selector: 'child-cmp', inputs: ['dirProp'], viewProviders: [MyService]})
@View({directives: [MyDir], template: '{{ctxProp}}'})
@Injectable()
class ChildComp {
@@ -1883,7 +1884,7 @@ class CompWithHost {
constructor(@Host() someComp: SomeDirective) { this.myHost = someComp; }
}
@Component({selector: '[child-cmp2]', viewBindings: [MyService]})
@Component({selector: '[child-cmp2]', viewProviders: [MyService]})
@Injectable()
class ChildComp2 {
ctxProp: string;
@@ -2025,7 +2026,7 @@ class PublicApi {
@Directive({
selector: '[public-api]',
bindings: [new Binding(PublicApi, {toAlias: PrivateImpl, deps: []})]
providers: [new Provider(PublicApi, {toAlias: PrivateImpl, deps: []})]
})
@Injectable()
class PrivateImpl extends PublicApi {
@@ -2092,8 +2093,9 @@ function createInjectableWithLogging(inj: Injector) {
@Component({
selector: 'component-providing-logging-injectable',
bindings:
[new Binding(InjectableService, {toFactory: createInjectableWithLogging, deps: [Injector]})]
providers: [
new Provider(InjectableService, {toFactory: createInjectableWithLogging, deps: [Injector]})
]
})
@View({template: ''})
@Injectable()
@@ -2102,12 +2104,12 @@ class ComponentProvidingLoggingInjectable {
}
@Directive({selector: 'directive-providing-injectable', bindings: [[InjectableService]]})
@Directive({selector: 'directive-providing-injectable', providers: [[InjectableService]]})
@Injectable()
class DirectiveProvidingInjectable {
}
@Component({selector: 'directive-providing-injectable', viewBindings: [[InjectableService]]})
@Component({selector: 'directive-providing-injectable', viewProviders: [[InjectableService]]})
@View({template: ''})
@Injectable()
class DirectiveProvidingInjectableInView {
@@ -2115,8 +2117,8 @@ class DirectiveProvidingInjectableInView {
@Component({
selector: 'directive-providing-injectable',
bindings: [new Binding(InjectableService, {toValue: 'host'})],
viewBindings: [new Binding(InjectableService, {toValue: 'view'})]
providers: [new Provider(InjectableService, {toValue: 'host'})],
viewProviders: [new Provider(InjectableService, {toValue: 'view'})]
})
@View({template: ''})
@Injectable()
@@ -2168,7 +2170,7 @@ class EventBus {
@Directive({
selector: 'grand-parent-providing-event-bus',
bindings: [new Binding(EventBus, {toValue: new EventBus(null, "grandparent")})]
providers: [new Provider(EventBus, {toValue: new EventBus(null, "grandparent")})]
})
class GrandParentProvidingEventBus {
bus: EventBus;
@@ -2182,9 +2184,9 @@ function createParentBus(peb) {
@Component({
selector: 'parent-providing-event-bus',
bindings: [
new Binding(EventBus,
{toFactory: createParentBus, deps: [[EventBus, new SkipSelfMetadata()]]})
providers: [
new Provider(EventBus,
{toFactory: createParentBus, deps: [[EventBus, new SkipSelfMetadata()]]})
]
})
@View({
@@ -25,6 +25,7 @@ import {AppViewListener} from 'angular2/src/core/linker/view_listener';
import {
bind,
provide,
forwardRef,
Component,
Directive,
@@ -39,7 +40,7 @@ import {By} from 'angular2/src/core/debug';
export function main() {
describe('projection', () => {
beforeEachBindings(() => [bind(AppViewListener).toClass(AppViewListener)]);
beforeEachBindings(() => [provide(AppViewListener, {asClass: AppViewListener})]);
it('should support simple components',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
@@ -14,7 +14,7 @@ import {
xit
} from 'angular2/test_lib';
import {SpyRenderer, SpyAppViewPool, SpyAppViewListener, SpyProtoViewFactory} from '../spies';
import {Injector, bind} from 'angular2/core';
import {Injector, provide} from 'angular2/core';
import {AppProtoView, AppView, AppViewContainer, ViewType} from 'angular2/src/core/linker/view';
import {
@@ -23,7 +23,7 @@ import {
SpyPreBuiltObjects
} from '../spies';
import {Injector, bind} from 'angular2/core';
import {Injector, provide} from 'angular2/core';
import {isBlank, isPresent} from 'angular2/src/core/facade/lang';
import {
@@ -34,7 +34,7 @@ import {
} from 'angular2/src/core/linker/view';
import {ElementBinder} from 'angular2/src/core/linker/element_binder';
import {
DirectiveBinding,
DirectiveProvider,
ElementInjector,
PreBuiltObjects,
ProtoElementInjector
@@ -238,12 +238,12 @@ export function createEmptyElBinder(parent: ElementBinder = null) {
}
export function createNestedElBinder(nestedProtoView: AppProtoView) {
var componentBinding = null;
var componentProvider = null;
if (nestedProtoView.type === ViewType.COMPONENT) {
var annotation = new DirectiveResolver().resolve(SomeComponent);
componentBinding = DirectiveBinding.createFromType(SomeComponent, annotation);
componentProvider = DirectiveProvider.createFromType(SomeComponent, annotation);
}
return new ElementBinder(0, null, 0, createProtoElInjector(), componentBinding, nestedProtoView);
return new ElementBinder(0, null, 0, createProtoElInjector(), componentProvider, nestedProtoView);
}
function _createProtoView(type: ViewType, binders: ElementBinder[] = null) {
@@ -10,17 +10,17 @@ import {
afterEach
} from 'angular2/test_lib';
import {PipeBinding} from 'angular2/src/core/pipes/pipe_binding';
import {PipeProvider} from 'angular2/src/core/pipes/pipe_provider';
import {Pipe} from 'angular2/src/core/metadata';
class MyPipe {}
export function main() {
describe("PipeBinding", () => {
it('should create a binding out of a type', () => {
var binding = PipeBinding.createFromType(MyPipe, new Pipe({name: 'my-pipe'}));
expect(binding.name).toEqual('my-pipe');
expect(binding.key.token).toEqual(MyPipe);
describe("PipeProvider", () => {
it('should create a provider out of a type', () => {
var provider = PipeProvider.createFromType(MyPipe, new Pipe({name: 'my-pipe'}));
expect(provider.name).toEqual('my-pipe');
expect(provider.key.token).toEqual(MyPipe);
});
});
}
+10 -10
View File
@@ -10,9 +10,9 @@ import {
afterEach
} from 'angular2/test_lib';
import {Injector, Inject, bind, Pipe, PipeTransform} from 'angular2/core';
import {Injector, Inject, provide, Pipe, PipeTransform} from 'angular2/core';
import {ProtoPipes, Pipes} from 'angular2/src/core/pipes/pipes';
import {PipeBinding} from 'angular2/src/core/pipes/pipe_binding';
import {PipeProvider} from 'angular2/src/core/pipes/pipe_provider';
class PipeA implements PipeTransform {
transform(a, b) {}
@@ -31,32 +31,32 @@ export function main() {
var injector;
beforeEach(
() => { injector = Injector.resolveAndCreate([bind('dep').toValue('dependency')]); });
() => { injector = Injector.resolveAndCreate([provide('dep', {asValue: 'dependency'})]); });
it('should instantiate a pipe', () => {
var proto =
ProtoPipes.fromBindings([PipeBinding.createFromType(PipeA, new Pipe({name: 'a'}))]);
ProtoPipes.fromProviders([PipeProvider.createFromType(PipeA, new Pipe({name: 'a'}))]);
var pipes = new Pipes(proto, injector);
expect(pipes.get("a").pipe).toBeAnInstanceOf(PipeA);
});
it('should throw when no pipe found', () => {
var proto = ProtoPipes.fromBindings([]);
var proto = ProtoPipes.fromProviders([]);
var pipes = new Pipes(proto, injector);
expect(() => pipes.get("invalid")).toThrowErrorWith("Cannot find pipe 'invalid'");
});
it('should inject dependencies from the provided injector', () => {
var proto =
ProtoPipes.fromBindings([PipeBinding.createFromType(PipeB, new Pipe({name: 'b'}))]);
ProtoPipes.fromProviders([PipeProvider.createFromType(PipeB, new Pipe({name: 'b'}))]);
var pipes = new Pipes(proto, injector);
expect((<any>pipes.get("b").pipe).dep).toEqual("dependency");
});
it('should cache pure pipes', () => {
var proto = ProtoPipes.fromBindings(
[PipeBinding.createFromType(PipeA, new Pipe({name: 'a', pure: true}))]);
var proto = ProtoPipes.fromProviders(
[PipeProvider.createFromType(PipeA, new Pipe({name: 'a', pure: true}))]);
var pipes = new Pipes(proto, injector);
expect(pipes.get("a").pure).toEqual(true);
@@ -64,8 +64,8 @@ export function main() {
});
it('should NOT cache impure pipes', () => {
var proto = ProtoPipes.fromBindings(
[PipeBinding.createFromType(PipeA, new Pipe({name: 'a', pure: false}))]);
var proto = ProtoPipes.fromProviders(
[PipeProvider.createFromType(PipeA, new Pipe({name: 'a', pure: false}))]);
var pipes = new Pipes(proto, injector);
expect(pipes.get("a").pure).toEqual(false);