diff --git a/apps/example-app/app/examples/16-input-getter-setter.spec.ts b/apps/example-app/app/examples/16-input-getter-setter.spec.ts new file mode 100644 index 00000000..10e0e276 --- /dev/null +++ b/apps/example-app/app/examples/16-input-getter-setter.spec.ts @@ -0,0 +1,25 @@ +import { render, screen } from '@testing-library/angular'; +import { InputGetterSetter } from './16-input-getter-setter'; + +test('should run logic in the input setter and getter', async () => { + await render(InputGetterSetter, { componentProperties: { value: 'Angular' } }); + const valueControl = screen.getByTestId('value'); + const getterValueControl = screen.getByTestId('value-getter'); + + expect(valueControl.textContent).toBe('I am value from setter Angular'); + expect(getterValueControl.textContent).toBe('I am value from getter Angular'); +}); + +test('should run logic in the input setter and getter while re-rendering', async () => { + const component = await render(InputGetterSetter, { componentProperties: { value: 'Angular' } }); + const valueControl = screen.getByTestId('value'); + const getterValueControl = screen.getByTestId('value-getter'); + + expect(valueControl.textContent).toBe('I am value from setter Angular'); + expect(getterValueControl.textContent).toBe('I am value from getter Angular'); + + await component.rerender({ value: 'React' }); + + expect(valueControl.textContent).toBe('I am value from setter React'); + expect(getterValueControl.textContent).toBe('I am value from getter React'); +}); diff --git a/apps/example-app/app/examples/16-input-getter-setter.ts b/apps/example-app/app/examples/16-input-getter-setter.ts new file mode 100644 index 00000000..d79f4fb9 --- /dev/null +++ b/apps/example-app/app/examples/16-input-getter-setter.ts @@ -0,0 +1,22 @@ +import { Component, Input } from '@angular/core'; + +@Component({ + selector: 'app-fixture', + template: ` + {{ derivedValue }} + {{ value }} + `, +}) +export class InputGetterSetter { + @Input() set value(value: string) { + this.originalValue = value; + this.derivedValue = 'I am value from setter ' + value; + } + + get value() { + return 'I am value from getter ' + this.originalValue; + } + + private originalValue: string; + derivedValue: string; +} diff --git a/projects/testing-library/src/lib/testing-library.ts b/projects/testing-library/src/lib/testing-library.ts index 55c4d275..642b86c7 100644 --- a/projects/testing-library/src/lib/testing-library.ts +++ b/projects/testing-library/src/lib/testing-library.ts @@ -205,14 +205,24 @@ function setComponentProperties( { componentProperties = {} }: Pick, 'componentProperties'>, ) { for (const key of Object.keys(componentProperties)) { + const descriptor: PropertyDescriptor = Object.getOwnPropertyDescriptor( + fixture.componentInstance.constructor.prototype, + key, + ); let _value = componentProperties[key]; + const defaultGetter = () => _value; + const extendedSetter = (value) => { + _value = value; + descriptor?.set?.call(fixture.componentInstance, _value); + fixture.detectChanges(); + }; + Object.defineProperty(fixture.componentInstance, key, { - get: () => _value, - set: (value) => { - _value = value; - fixture.detectChanges(); - }, + get: descriptor?.get || defaultGetter, + set: extendedSetter, }); + + descriptor?.set?.call(fixture.componentInstance, _value); } return fixture; }