fix(testing): override metadata subclasses properly (#10767)
This fixes an issue where `TestBed.overrideComponent(MyComp, {})` would remove some properties including `providers` from the component. This was due to the override not properly dealing with getter fields on subclasses.
This commit is contained in:
parent
9317056138
commit
87fe47737a
|
@ -15,6 +15,10 @@ interface SomeMetadataType {
|
||||||
arrayProp?: any[];
|
arrayProp?: any[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface OtherMetadataType extends SomeMetadataType {
|
||||||
|
otherPlainProp?: string;
|
||||||
|
}
|
||||||
|
|
||||||
class SomeMetadata implements SomeMetadataType {
|
class SomeMetadata implements SomeMetadataType {
|
||||||
plainProp: string;
|
plainProp: string;
|
||||||
private _getterProp: string;
|
private _getterProp: string;
|
||||||
|
@ -28,6 +32,20 @@ class SomeMetadata implements SomeMetadataType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class OtherMetadata extends SomeMetadata implements OtherMetadataType {
|
||||||
|
otherPlainProp: string;
|
||||||
|
|
||||||
|
constructor(options: OtherMetadataType) {
|
||||||
|
super({
|
||||||
|
plainProp: options.plainProp,
|
||||||
|
getterProp: options.getterProp,
|
||||||
|
arrayProp: options.arrayProp
|
||||||
|
});
|
||||||
|
|
||||||
|
this.otherPlainProp = options.otherPlainProp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('metadata overrider', () => {
|
describe('metadata overrider', () => {
|
||||||
let overrider: MetadataOverrider;
|
let overrider: MetadataOverrider;
|
||||||
|
@ -112,5 +130,23 @@ export function main() {
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('subclasses', () => {
|
||||||
|
it('should set individual properties and keep others', () => {
|
||||||
|
const oldInstance = new OtherMetadata({
|
||||||
|
plainProp: 'somePlainProp',
|
||||||
|
getterProp: 'someGetterProp',
|
||||||
|
otherPlainProp: 'newOtherProp'
|
||||||
|
});
|
||||||
|
const newInstance = overrider.overrideMetadata(
|
||||||
|
OtherMetadata, oldInstance, {set: {plainProp: 'newPlainProp'}});
|
||||||
|
expect(newInstance).toEqual(new OtherMetadata({
|
||||||
|
plainProp: 'newPlainProp',
|
||||||
|
getterProp: 'someGetterProp',
|
||||||
|
otherPlainProp: 'newOtherProp'
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,13 +118,16 @@ function _valueProps(obj: any): string[] {
|
||||||
props.push(prop);
|
props.push(prop);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
const proto = Object.getPrototypeOf(obj);
|
let proto = obj;
|
||||||
Object.keys(proto).forEach((protoProp) => {
|
while (proto = Object.getPrototypeOf(proto)) {
|
||||||
var desc = Object.getOwnPropertyDescriptor(proto, protoProp);
|
Object.keys(proto).forEach((protoProp) => {
|
||||||
if (!protoProp.startsWith('_') && desc && 'get' in desc) {
|
var desc = Object.getOwnPropertyDescriptor(proto, protoProp);
|
||||||
props.push(protoProp);
|
if (!protoProp.startsWith('_') && desc && 'get' in desc) {
|
||||||
}
|
props.push(protoProp);
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue