refactor: move angular source to /packages rather than modules/@angular
This commit is contained in:
21
packages/core/test/di/forward_ref_spec.ts
Normal file
21
packages/core/test/di/forward_ref_spec.ts
Normal file
@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Type} from '@angular/core';
|
||||
import {forwardRef, resolveForwardRef} from '@angular/core/src/di';
|
||||
import {describe, expect, it} from '@angular/core/testing/testing_internal';
|
||||
|
||||
export function main() {
|
||||
describe('forwardRef', function() {
|
||||
it('should wrap and unwrap the reference', () => {
|
||||
const ref = forwardRef(() => String);
|
||||
expect(ref instanceof Type).toBe(true);
|
||||
expect(resolveForwardRef(ref)).toBe(String);
|
||||
});
|
||||
});
|
||||
}
|
27
packages/core/test/di/injector_spec.ts
Normal file
27
packages/core/test/di/injector_spec.ts
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
|
||||
import {Injector} from '@angular/core';
|
||||
import {describe, expect, it} from '@angular/core/testing/testing_internal';
|
||||
|
||||
export function main() {
|
||||
describe('Injector.NULL', () => {
|
||||
it('should throw if no arg is given', () => {
|
||||
expect(() => Injector.NULL.get('someToken')).toThrowError('No provider for someToken!');
|
||||
});
|
||||
|
||||
it('should throw if THROW_IF_NOT_FOUND is given', () => {
|
||||
expect(() => Injector.NULL.get('someToken', Injector.THROW_IF_NOT_FOUND))
|
||||
.toThrowError('No provider for someToken!');
|
||||
});
|
||||
|
||||
it('should return the default value',
|
||||
() => { expect(Injector.NULL.get('someToken', 'notFound')).toEqual('notFound'); });
|
||||
});
|
||||
}
|
529
packages/core/test/di/reflective_injector_spec.ts
Normal file
529
packages/core/test/di/reflective_injector_spec.ts
Normal file
@ -0,0 +1,529 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Inject, Injectable, InjectionToken, Injector, Optional, Provider, ReflectiveInjector, ReflectiveKey, Self, forwardRef} from '@angular/core';
|
||||
import {ReflectiveInjector_} from '@angular/core/src/di/reflective_injector';
|
||||
import {ResolvedReflectiveProvider_} from '@angular/core/src/di/reflective_provider';
|
||||
import {getOriginalError} from '@angular/core/src/errors';
|
||||
import {expect} from '@angular/platform-browser/testing/matchers';
|
||||
import {stringify} from '../../src/util';
|
||||
|
||||
class Engine {}
|
||||
|
||||
class BrokenEngine {
|
||||
constructor() { throw new Error('Broken Engine'); }
|
||||
}
|
||||
|
||||
class DashboardSoftware {}
|
||||
|
||||
@Injectable()
|
||||
class Dashboard {
|
||||
constructor(software: DashboardSoftware) {}
|
||||
}
|
||||
|
||||
class TurboEngine extends Engine {}
|
||||
|
||||
@Injectable()
|
||||
class Car {
|
||||
constructor(public engine: Engine) {}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
class CarWithOptionalEngine {
|
||||
constructor(@Optional() public engine: Engine) {}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
class CarWithDashboard {
|
||||
engine: Engine;
|
||||
dashboard: Dashboard;
|
||||
constructor(engine: Engine, dashboard: Dashboard) {
|
||||
this.engine = engine;
|
||||
this.dashboard = dashboard;
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
class SportsCar extends Car {
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
class CarWithInject {
|
||||
constructor(@Inject(TurboEngine) public engine: Engine) {}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
class CyclicEngine {
|
||||
constructor(car: Car) {}
|
||||
}
|
||||
|
||||
class NoAnnotations {
|
||||
constructor(secretDependency: any) {}
|
||||
}
|
||||
|
||||
function factoryFn(a: any) {}
|
||||
|
||||
export function main() {
|
||||
const dynamicProviders = [
|
||||
{provide: 'provider0', useValue: 1}, {provide: 'provider1', useValue: 1},
|
||||
{provide: 'provider2', useValue: 1}, {provide: 'provider3', useValue: 1},
|
||||
{provide: 'provider4', useValue: 1}, {provide: 'provider5', useValue: 1},
|
||||
{provide: 'provider6', useValue: 1}, {provide: 'provider7', useValue: 1},
|
||||
{provide: 'provider8', useValue: 1}, {provide: 'provider9', useValue: 1},
|
||||
{provide: 'provider10', useValue: 1}
|
||||
];
|
||||
|
||||
function createInjector(
|
||||
providers: Provider[], parent: ReflectiveInjector = null): ReflectiveInjector_ {
|
||||
const resolvedProviders = ReflectiveInjector.resolve(providers.concat(dynamicProviders));
|
||||
if (parent != null) {
|
||||
return <ReflectiveInjector_>parent.createChildFromResolved(resolvedProviders);
|
||||
} else {
|
||||
return <ReflectiveInjector_>ReflectiveInjector.fromResolvedProviders(resolvedProviders);
|
||||
}
|
||||
}
|
||||
|
||||
describe(`injector`, () => {
|
||||
|
||||
it('should instantiate a class without dependencies', () => {
|
||||
const injector = createInjector([Engine]);
|
||||
const engine = injector.get(Engine);
|
||||
|
||||
expect(engine).toBeAnInstanceOf(Engine);
|
||||
});
|
||||
|
||||
it('should resolve dependencies based on type information', () => {
|
||||
const injector = createInjector([Engine, Car]);
|
||||
const car = injector.get(Car);
|
||||
|
||||
expect(car).toBeAnInstanceOf(Car);
|
||||
expect(car.engine).toBeAnInstanceOf(Engine);
|
||||
});
|
||||
|
||||
it('should resolve dependencies based on @Inject annotation', () => {
|
||||
const injector = createInjector([TurboEngine, Engine, CarWithInject]);
|
||||
const car = injector.get(CarWithInject);
|
||||
|
||||
expect(car).toBeAnInstanceOf(CarWithInject);
|
||||
expect(car.engine).toBeAnInstanceOf(TurboEngine);
|
||||
});
|
||||
|
||||
it('should throw when no type and not @Inject (class case)', () => {
|
||||
expect(() => createInjector([NoAnnotations]))
|
||||
.toThrowError(
|
||||
'Cannot resolve all parameters for \'NoAnnotations\'(?). ' +
|
||||
'Make sure that all the parameters are decorated with Inject or have valid type annotations ' +
|
||||
'and that \'NoAnnotations\' is decorated with Injectable.');
|
||||
});
|
||||
|
||||
it('should throw when no type and not @Inject (factory case)', () => {
|
||||
expect(() => createInjector([{provide: 'someToken', useFactory: factoryFn}]))
|
||||
.toThrowError(
|
||||
'Cannot resolve all parameters for \'factoryFn\'(?). ' +
|
||||
'Make sure that all the parameters are decorated with Inject or have valid type annotations ' +
|
||||
'and that \'factoryFn\' is decorated with Injectable.');
|
||||
});
|
||||
|
||||
it('should cache instances', () => {
|
||||
const injector = createInjector([Engine]);
|
||||
|
||||
const e1 = injector.get(Engine);
|
||||
const e2 = injector.get(Engine);
|
||||
|
||||
expect(e1).toBe(e2);
|
||||
});
|
||||
|
||||
it('should provide to a value', () => {
|
||||
const injector = createInjector([{provide: Engine, useValue: 'fake engine'}]);
|
||||
|
||||
const engine = injector.get(Engine);
|
||||
expect(engine).toEqual('fake engine');
|
||||
});
|
||||
|
||||
it('should inject dependencies instance of InjectionToken', () => {
|
||||
const TOKEN = new InjectionToken<string>('token');
|
||||
|
||||
const injector = createInjector([
|
||||
{provide: TOKEN, useValue: 'by token'},
|
||||
{provide: Engine, useFactory: (v: string) => v, deps: [[TOKEN]]},
|
||||
]);
|
||||
|
||||
const engine = injector.get(Engine);
|
||||
expect(engine).toEqual('by token');
|
||||
});
|
||||
|
||||
it('should provide to a factory', () => {
|
||||
function sportsCarFactory(e: any) { return new SportsCar(e); }
|
||||
|
||||
const injector =
|
||||
createInjector([Engine, {provide: Car, useFactory: sportsCarFactory, deps: [Engine]}]);
|
||||
|
||||
const car = injector.get(Car);
|
||||
expect(car).toBeAnInstanceOf(SportsCar);
|
||||
expect(car.engine).toBeAnInstanceOf(Engine);
|
||||
});
|
||||
|
||||
it('should supporting provider to null', () => {
|
||||
const injector = createInjector([{provide: Engine, useValue: null}]);
|
||||
const engine = injector.get(Engine);
|
||||
expect(engine).toBeNull();
|
||||
});
|
||||
|
||||
it('should provide to an alias', () => {
|
||||
const injector = createInjector([
|
||||
Engine, {provide: SportsCar, useClass: SportsCar}, {provide: Car, useExisting: SportsCar}
|
||||
]);
|
||||
|
||||
const car = injector.get(Car);
|
||||
const sportsCar = injector.get(SportsCar);
|
||||
expect(car).toBeAnInstanceOf(SportsCar);
|
||||
expect(car).toBe(sportsCar);
|
||||
});
|
||||
|
||||
it('should support multiProviders', () => {
|
||||
const injector = createInjector([
|
||||
Engine, {provide: Car, useClass: SportsCar, multi: true},
|
||||
{provide: Car, useClass: CarWithOptionalEngine, multi: true}
|
||||
]);
|
||||
|
||||
const cars = injector.get(Car);
|
||||
expect(cars.length).toEqual(2);
|
||||
expect(cars[0]).toBeAnInstanceOf(SportsCar);
|
||||
expect(cars[1]).toBeAnInstanceOf(CarWithOptionalEngine);
|
||||
});
|
||||
|
||||
it('should support multiProviders that are created using useExisting', () => {
|
||||
const injector =
|
||||
createInjector([Engine, SportsCar, {provide: Car, useExisting: SportsCar, multi: true}]);
|
||||
|
||||
const cars = injector.get(Car);
|
||||
expect(cars.length).toEqual(1);
|
||||
expect(cars[0]).toBe(injector.get(SportsCar));
|
||||
});
|
||||
|
||||
it('should throw when the aliased provider does not exist', () => {
|
||||
const injector = createInjector([{provide: 'car', useExisting: SportsCar}]);
|
||||
const e = `No provider for ${stringify(SportsCar)}! (car -> ${stringify(SportsCar)})`;
|
||||
expect(() => injector.get('car')).toThrowError(e);
|
||||
});
|
||||
|
||||
it('should handle forwardRef in useExisting', () => {
|
||||
const injector = createInjector([
|
||||
{provide: 'originalEngine', useClass: forwardRef(() => Engine)},
|
||||
{provide: 'aliasedEngine', useExisting: <any>forwardRef(() => 'originalEngine')}
|
||||
]);
|
||||
expect(injector.get('aliasedEngine')).toBeAnInstanceOf(Engine);
|
||||
});
|
||||
|
||||
it('should support overriding factory dependencies', () => {
|
||||
const injector = createInjector(
|
||||
[Engine, {provide: Car, useFactory: (e: Engine) => new SportsCar(e), deps: [Engine]}]);
|
||||
|
||||
const car = injector.get(Car);
|
||||
expect(car).toBeAnInstanceOf(SportsCar);
|
||||
expect(car.engine).toBeAnInstanceOf(Engine);
|
||||
});
|
||||
|
||||
it('should support optional dependencies', () => {
|
||||
const injector = createInjector([CarWithOptionalEngine]);
|
||||
|
||||
const car = injector.get(CarWithOptionalEngine);
|
||||
expect(car.engine).toEqual(null);
|
||||
});
|
||||
|
||||
it('should flatten passed-in providers', () => {
|
||||
const injector = createInjector([[[Engine, Car]]]);
|
||||
|
||||
const car = injector.get(Car);
|
||||
expect(car).toBeAnInstanceOf(Car);
|
||||
});
|
||||
|
||||
it('should use the last provider when there are multiple providers for same token', () => {
|
||||
const injector = createInjector(
|
||||
[{provide: Engine, useClass: Engine}, {provide: Engine, useClass: TurboEngine}]);
|
||||
|
||||
expect(injector.get(Engine)).toBeAnInstanceOf(TurboEngine);
|
||||
});
|
||||
|
||||
it('should use non-type tokens', () => {
|
||||
const injector = createInjector([{provide: 'token', useValue: 'value'}]);
|
||||
|
||||
expect(injector.get('token')).toEqual('value');
|
||||
});
|
||||
|
||||
it('should throw when given invalid providers', () => {
|
||||
expect(() => createInjector(<any>['blah']))
|
||||
.toThrowError(
|
||||
'Invalid provider - only instances of Provider and Type are allowed, got: blah');
|
||||
});
|
||||
|
||||
it('should provide itself', () => {
|
||||
const parent = createInjector([]);
|
||||
const child = parent.resolveAndCreateChild([]);
|
||||
|
||||
expect(child.get(Injector)).toBe(child);
|
||||
});
|
||||
|
||||
it('should throw when no provider defined', () => {
|
||||
const injector = createInjector([]);
|
||||
expect(() => injector.get('NonExisting')).toThrowError('No provider for NonExisting!');
|
||||
});
|
||||
|
||||
it('should show the full path when no provider', () => {
|
||||
const injector = createInjector([CarWithDashboard, Engine, Dashboard]);
|
||||
expect(() => injector.get(CarWithDashboard))
|
||||
.toThrowError(
|
||||
`No provider for DashboardSoftware! (${stringify(CarWithDashboard)} -> ${stringify(Dashboard)} -> DashboardSoftware)`);
|
||||
});
|
||||
|
||||
it('should throw when trying to instantiate a cyclic dependency', () => {
|
||||
const injector = createInjector([Car, {provide: Engine, useClass: CyclicEngine}]);
|
||||
|
||||
expect(() => injector.get(Car))
|
||||
.toThrowError(
|
||||
`Cannot instantiate cyclic dependency! (${stringify(Car)} -> ${stringify(Engine)} -> ${stringify(Car)})`);
|
||||
});
|
||||
|
||||
it('should show the full path when error happens in a constructor', () => {
|
||||
const providers =
|
||||
ReflectiveInjector.resolve([Car, {provide: Engine, useClass: BrokenEngine}]);
|
||||
const injector = new ReflectiveInjector_(providers);
|
||||
|
||||
try {
|
||||
injector.get(Car);
|
||||
throw 'Must throw';
|
||||
} catch (e) {
|
||||
expect(e.message).toContain(
|
||||
`Error during instantiation of Engine! (${stringify(Car)} -> Engine)`);
|
||||
expect(getOriginalError(e) instanceof Error).toBeTruthy();
|
||||
expect(e.keys[0].token).toEqual(Engine);
|
||||
}
|
||||
});
|
||||
|
||||
it('should instantiate an object after a failed attempt', () => {
|
||||
let isBroken = true;
|
||||
|
||||
const injector = createInjector([
|
||||
Car, {provide: Engine, useFactory: (() => isBroken ? new BrokenEngine() : new Engine())}
|
||||
]);
|
||||
|
||||
expect(() => injector.get(Car))
|
||||
.toThrowError('Broken Engine: Error during instantiation of Engine! (Car -> Engine).');
|
||||
|
||||
isBroken = false;
|
||||
|
||||
expect(injector.get(Car)).toBeAnInstanceOf(Car);
|
||||
});
|
||||
|
||||
it('should support null values', () => {
|
||||
const injector = createInjector([{provide: 'null', useValue: null}]);
|
||||
expect(injector.get('null')).toBe(null);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('child', () => {
|
||||
it('should load instances from parent injector', () => {
|
||||
const parent = ReflectiveInjector.resolveAndCreate([Engine]);
|
||||
const child = parent.resolveAndCreateChild([]);
|
||||
|
||||
const engineFromParent = parent.get(Engine);
|
||||
const engineFromChild = child.get(Engine);
|
||||
|
||||
expect(engineFromChild).toBe(engineFromParent);
|
||||
});
|
||||
|
||||
it('should not use the child providers when resolving the dependencies of a parent provider',
|
||||
() => {
|
||||
const parent = ReflectiveInjector.resolveAndCreate([Car, Engine]);
|
||||
const child = parent.resolveAndCreateChild([{provide: Engine, useClass: TurboEngine}]);
|
||||
|
||||
const carFromChild = child.get(Car);
|
||||
expect(carFromChild.engine).toBeAnInstanceOf(Engine);
|
||||
});
|
||||
|
||||
it('should create new instance in a child injector', () => {
|
||||
const parent = ReflectiveInjector.resolveAndCreate([Engine]);
|
||||
const child = parent.resolveAndCreateChild([{provide: Engine, useClass: TurboEngine}]);
|
||||
|
||||
const engineFromParent = parent.get(Engine);
|
||||
const engineFromChild = child.get(Engine);
|
||||
|
||||
expect(engineFromParent).not.toBe(engineFromChild);
|
||||
expect(engineFromChild).toBeAnInstanceOf(TurboEngine);
|
||||
});
|
||||
|
||||
it('should give access to parent', () => {
|
||||
const parent = ReflectiveInjector.resolveAndCreate([]);
|
||||
const child = parent.resolveAndCreateChild([]);
|
||||
expect(child.parent).toBe(parent);
|
||||
});
|
||||
});
|
||||
|
||||
describe('resolveAndInstantiate', () => {
|
||||
it('should instantiate an object in the context of the injector', () => {
|
||||
const inj = ReflectiveInjector.resolveAndCreate([Engine]);
|
||||
const car = inj.resolveAndInstantiate(Car);
|
||||
expect(car).toBeAnInstanceOf(Car);
|
||||
expect(car.engine).toBe(inj.get(Engine));
|
||||
});
|
||||
|
||||
it('should not store the instantiated object in the injector', () => {
|
||||
const inj = ReflectiveInjector.resolveAndCreate([Engine]);
|
||||
inj.resolveAndInstantiate(Car);
|
||||
expect(() => inj.get(Car)).toThrowError();
|
||||
});
|
||||
});
|
||||
|
||||
describe('instantiate', () => {
|
||||
it('should instantiate an object in the context of the injector', () => {
|
||||
const inj = ReflectiveInjector.resolveAndCreate([Engine]);
|
||||
const car = inj.instantiateResolved(ReflectiveInjector.resolve([Car])[0]);
|
||||
expect(car).toBeAnInstanceOf(Car);
|
||||
expect(car.engine).toBe(inj.get(Engine));
|
||||
});
|
||||
});
|
||||
|
||||
describe('depedency resolution', () => {
|
||||
describe('@Self()', () => {
|
||||
it('should return a dependency from self', () => {
|
||||
const inj = ReflectiveInjector.resolveAndCreate([
|
||||
Engine,
|
||||
{provide: Car, useFactory: (e: Engine) => new Car(e), deps: [[Engine, new Self()]]}
|
||||
]);
|
||||
|
||||
expect(inj.get(Car)).toBeAnInstanceOf(Car);
|
||||
});
|
||||
|
||||
it('should throw when not requested provider on self', () => {
|
||||
const parent = ReflectiveInjector.resolveAndCreate([Engine]);
|
||||
const child = parent.resolveAndCreateChild(
|
||||
[{provide: Car, useFactory: (e: Engine) => new Car(e), deps: [[Engine, new Self()]]}]);
|
||||
|
||||
expect(() => child.get(Car))
|
||||
.toThrowError(`No provider for Engine! (${stringify(Car)} -> ${stringify(Engine)})`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('default', () => {
|
||||
it('should not skip self', () => {
|
||||
const parent = ReflectiveInjector.resolveAndCreate([Engine]);
|
||||
const child = parent.resolveAndCreateChild([
|
||||
{provide: Engine, useClass: TurboEngine},
|
||||
{provide: Car, useFactory: (e: Engine) => new Car(e), deps: [Engine]}
|
||||
]);
|
||||
|
||||
expect(child.get(Car).engine).toBeAnInstanceOf(TurboEngine);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('resolve', () => {
|
||||
it('should resolve and flatten', () => {
|
||||
const providers = ReflectiveInjector.resolve([Engine, [BrokenEngine]]);
|
||||
providers.forEach(function(b) {
|
||||
if (!b) return; // the result is a sparse array
|
||||
expect(b instanceof ResolvedReflectiveProvider_).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('should support multi providers', () => {
|
||||
const provider = ReflectiveInjector.resolve([
|
||||
{provide: Engine, useClass: BrokenEngine, multi: true},
|
||||
{provide: Engine, useClass: TurboEngine, multi: true}
|
||||
])[0];
|
||||
|
||||
expect(provider.key.token).toBe(Engine);
|
||||
expect(provider.multiProvider).toEqual(true);
|
||||
expect(provider.resolvedFactories.length).toEqual(2);
|
||||
});
|
||||
|
||||
|
||||
it('should support providers as hash', () => {
|
||||
const provider = ReflectiveInjector.resolve([
|
||||
{provide: Engine, useClass: BrokenEngine, multi: true},
|
||||
{provide: Engine, useClass: TurboEngine, multi: true}
|
||||
])[0];
|
||||
|
||||
expect(provider.key.token).toBe(Engine);
|
||||
expect(provider.multiProvider).toEqual(true);
|
||||
expect(provider.resolvedFactories.length).toEqual(2);
|
||||
});
|
||||
|
||||
it('should support multi providers with only one provider', () => {
|
||||
const provider =
|
||||
ReflectiveInjector.resolve([{provide: Engine, useClass: BrokenEngine, multi: true}])[0];
|
||||
|
||||
expect(provider.key.token).toBe(Engine);
|
||||
expect(provider.multiProvider).toEqual(true);
|
||||
expect(provider.resolvedFactories.length).toEqual(1);
|
||||
});
|
||||
|
||||
it('should throw when mixing multi providers with regular providers', () => {
|
||||
expect(() => {
|
||||
ReflectiveInjector.resolve(
|
||||
[{provide: Engine, useClass: BrokenEngine, multi: true}, Engine]);
|
||||
}).toThrowError(/Cannot mix multi providers and regular providers/);
|
||||
|
||||
expect(() => {
|
||||
ReflectiveInjector.resolve(
|
||||
[Engine, {provide: Engine, useClass: BrokenEngine, multi: true}]);
|
||||
}).toThrowError(/Cannot mix multi providers and regular providers/);
|
||||
});
|
||||
|
||||
it('should resolve forward references', () => {
|
||||
const providers = ReflectiveInjector.resolve([
|
||||
forwardRef(() => Engine),
|
||||
[{provide: forwardRef(() => BrokenEngine), useClass: forwardRef(() => Engine)}], {
|
||||
provide: forwardRef(() => String),
|
||||
useFactory: () => 'OK',
|
||||
deps: [forwardRef(() => Engine)]
|
||||
}
|
||||
]);
|
||||
|
||||
const engineProvider = providers[0];
|
||||
const brokenEngineProvider = providers[1];
|
||||
const stringProvider = providers[2];
|
||||
|
||||
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(ReflectiveKey.get(Engine));
|
||||
});
|
||||
|
||||
it('should support overriding factory dependencies with dependency annotations', () => {
|
||||
const providers = ReflectiveInjector.resolve([{
|
||||
provide: 'token',
|
||||
useFactory: (e: any /** TODO #9100 */) => 'result',
|
||||
deps: [[new Inject('dep')]]
|
||||
}]);
|
||||
|
||||
const provider = providers[0];
|
||||
|
||||
expect(provider.resolvedFactories[0].dependencies[0].key.token).toEqual('dep');
|
||||
});
|
||||
|
||||
it('should allow declaring dependencies with flat arrays', () => {
|
||||
const resolved = ReflectiveInjector.resolve(
|
||||
[{provide: 'token', useFactory: (e: any) => e, deps: [new Inject('dep')]}]);
|
||||
const nestedResolved = ReflectiveInjector.resolve(
|
||||
[{provide: 'token', useFactory: (e: any) => e, deps: [[new Inject('dep')]]}]);
|
||||
expect(resolved[0].resolvedFactories[0].dependencies[0].key.token)
|
||||
.toEqual(nestedResolved[0].resolvedFactories[0].dependencies[0].key.token);
|
||||
});
|
||||
});
|
||||
|
||||
describe('displayName', () => {
|
||||
it('should work', () => {
|
||||
expect((<ReflectiveInjector_>ReflectiveInjector.resolveAndCreate([Engine, BrokenEngine]))
|
||||
.displayName)
|
||||
.toEqual('ReflectiveInjector(providers: [ "Engine" , "BrokenEngine" ])');
|
||||
});
|
||||
});
|
||||
}
|
27
packages/core/test/di/reflective_key_spec.ts
Normal file
27
packages/core/test/di/reflective_key_spec.ts
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {KeyRegistry} from '@angular/core/src/di/reflective_key';
|
||||
|
||||
export function main() {
|
||||
describe('key', function() {
|
||||
let registry: KeyRegistry;
|
||||
|
||||
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')); });
|
||||
|
||||
});
|
||||
}
|
Reference in New Issue
Block a user