fix(ivy): apply all overrides from TestBed, not the last one only (#27734)

In some cases in our tests we can define multiple overrides for a given class. As a result, only the last override is actually applied due to the fact that we store overrides in a Type<->Override map. This update changes the logic to keep all overrides defined in a given test for a Type (i.e. Type<->Override[] map) and applies them one by one at resolution phase. This behavior is more inline with the previous TestBed.

PR Close #27734
This commit is contained in:
Andrew Kushnir 2018-12-18 10:30:14 -08:00 committed by Matias Niemelä
parent cdd737e28b
commit 509aa61619
2 changed files with 16 additions and 11 deletions

View File

@ -22,14 +22,18 @@ export interface Resolver<T> { resolve(type: Type<any>): T|null; }
* Allows to override ivy metadata for tests (via the `TestBed`). * Allows to override ivy metadata for tests (via the `TestBed`).
*/ */
abstract class OverrideResolver<T> implements Resolver<T> { abstract class OverrideResolver<T> implements Resolver<T> {
private overrides = new Map<Type<any>, MetadataOverride<T>>(); private overrides = new Map<Type<any>, MetadataOverride<T>[]>();
private resolved = new Map<Type<any>, T|null>(); private resolved = new Map<Type<any>, T|null>();
abstract get type(): any; abstract get type(): any;
setOverrides(overrides: Array<[Type<any>, MetadataOverride<T>]>) { setOverrides(overrides: Array<[Type<any>, MetadataOverride<T>]>) {
this.overrides.clear(); this.overrides.clear();
overrides.forEach(([type, override]) => this.overrides.set(type, override)); overrides.forEach(([type, override]) => {
const overrides = this.overrides.get(type) || [];
overrides.push(override);
this.overrides.set(type, overrides);
});
} }
getAnnotation(type: Type<any>): T|null { getAnnotation(type: Type<any>): T|null {
@ -42,10 +46,12 @@ abstract class OverrideResolver<T> implements Resolver<T> {
if (!resolved) { if (!resolved) {
resolved = this.getAnnotation(type); resolved = this.getAnnotation(type);
if (resolved) { if (resolved) {
const override = this.overrides.get(type); const overrides = this.overrides.get(type);
if (override) { if (overrides) {
const overrider = new MetadataOverrider(); const overrider = new MetadataOverrider();
resolved = overrider.overrideMetadata(this.type, resolved, override); overrides.forEach(override => {
resolved = overrider.overrideMetadata(this.type, resolved !, override);
});
} }
} }
this.resolved.set(type, resolved); this.resolved.set(type, resolved);

View File

@ -388,12 +388,11 @@ class CompWithUrlTemplate {
.overridePipe(SomePipe, {set: {name: 'somePipe'}}) .overridePipe(SomePipe, {set: {name: 'somePipe'}})
.overridePipe(SomePipe, {add: {pure: false}}); .overridePipe(SomePipe, {add: {pure: false}});
}); });
fixmeIvy('FW-788: Support metadata override in TestBed (for AOT-compiled components)') it('should work', () => {
.it('should work', () => { const compFixture = TestBed.createComponent(SomeComponent);
const compFixture = TestBed.createComponent(SomeComponent); compFixture.detectChanges();
compFixture.detectChanges(); expect(compFixture.nativeElement).toHaveText('transformed hello');
expect(compFixture.nativeElement).toHaveText('transformed hello'); });
});
}); });
describe('template', () => { describe('template', () => {