Skip to content

Commit 0143973

Browse files
authored
fix: component setter is overwritten when component properties are set (#192)
Closes #191
1 parent 4b6e491 commit 0143973

File tree

3 files changed

+62
-5
lines changed

3 files changed

+62
-5
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { render, screen } from '@testing-library/angular';
2+
import { InputGetterSetter } from './16-input-getter-setter';
3+
4+
test('should run logic in the input setter and getter', async () => {
5+
await render(InputGetterSetter, { componentProperties: { value: 'Angular' } });
6+
const valueControl = screen.getByTestId('value');
7+
const getterValueControl = screen.getByTestId('value-getter');
8+
9+
expect(valueControl.textContent).toBe('I am value from setter Angular');
10+
expect(getterValueControl.textContent).toBe('I am value from getter Angular');
11+
});
12+
13+
test('should run logic in the input setter and getter while re-rendering', async () => {
14+
const component = await render(InputGetterSetter, { componentProperties: { value: 'Angular' } });
15+
const valueControl = screen.getByTestId('value');
16+
const getterValueControl = screen.getByTestId('value-getter');
17+
18+
expect(valueControl.textContent).toBe('I am value from setter Angular');
19+
expect(getterValueControl.textContent).toBe('I am value from getter Angular');
20+
21+
await component.rerender({ value: 'React' });
22+
23+
expect(valueControl.textContent).toBe('I am value from setter React');
24+
expect(getterValueControl.textContent).toBe('I am value from getter React');
25+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Component, Input } from '@angular/core';
2+
3+
@Component({
4+
selector: 'app-fixture',
5+
template: `
6+
<span data-testid="value">{{ derivedValue }}</span>
7+
<span data-testid="value-getter">{{ value }}</span>
8+
`,
9+
})
10+
export class InputGetterSetter {
11+
@Input() set value(value: string) {
12+
this.originalValue = value;
13+
this.derivedValue = 'I am value from setter ' + value;
14+
}
15+
16+
get value() {
17+
return 'I am value from getter ' + this.originalValue;
18+
}
19+
20+
private originalValue: string;
21+
derivedValue: string;
22+
}

projects/testing-library/src/lib/testing-library.ts

+15-5
Original file line numberDiff line numberDiff line change
@@ -205,14 +205,24 @@ function setComponentProperties<SutType>(
205205
{ componentProperties = {} }: Pick<RenderDirectiveOptions<SutType, any>, 'componentProperties'>,
206206
) {
207207
for (const key of Object.keys(componentProperties)) {
208+
const descriptor: PropertyDescriptor = Object.getOwnPropertyDescriptor(
209+
fixture.componentInstance.constructor.prototype,
210+
key,
211+
);
208212
let _value = componentProperties[key];
213+
const defaultGetter = () => _value;
214+
const extendedSetter = (value) => {
215+
_value = value;
216+
descriptor?.set?.call(fixture.componentInstance, _value);
217+
fixture.detectChanges();
218+
};
219+
209220
Object.defineProperty(fixture.componentInstance, key, {
210-
get: () => _value,
211-
set: (value) => {
212-
_value = value;
213-
fixture.detectChanges();
214-
},
221+
get: descriptor?.get || defaultGetter,
222+
set: extendedSetter,
215223
});
224+
225+
descriptor?.set?.call(fixture.componentInstance, _value);
216226
}
217227
return fixture;
218228
}

0 commit comments

Comments
 (0)