Skip to content

Commit

Permalink
fix: component setter is overwritten when component properties are set (
Browse files Browse the repository at this point in the history
#192)

Closes #191
  • Loading branch information
GlebIrovich authored Mar 25, 2021
1 parent 4b6e491 commit 0143973
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 5 deletions.
25 changes: 25 additions & 0 deletions apps/example-app/app/examples/16-input-getter-setter.spec.ts
Original file line number Diff line number Diff line change
@@ -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');
});
22 changes: 22 additions & 0 deletions apps/example-app/app/examples/16-input-getter-setter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Component, Input } from '@angular/core';

@Component({
selector: 'app-fixture',
template: `
<span data-testid="value">{{ derivedValue }}</span>
<span data-testid="value-getter">{{ value }}</span>
`,
})
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;
}
20 changes: 15 additions & 5 deletions projects/testing-library/src/lib/testing-library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,14 +205,24 @@ function setComponentProperties<SutType>(
{ componentProperties = {} }: Pick<RenderDirectiveOptions<SutType, any>, '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;
}
Expand Down

0 comments on commit 0143973

Please sign in to comment.