Skip to content

Commit ccfcecf

Browse files
feat: remove change and changeInput in favor of rerender (#378)
BREAKING CHANGE: Use `rerender` instead of `change`. Use `rerender` instead of `changechangeInput`. For more info see #365
1 parent 71c623f commit ccfcecf

File tree

7 files changed

+57
-281
lines changed

7 files changed

+57
-281
lines changed

apps/example-app-karma/src/app/issues/issue-222.spec.ts

-13
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,3 @@ it('https://github.com/testing-library/angular-testing-library/issues/222 with r
1313

1414
expect(screen.getByText('Hello Mark')).toBeTruthy();
1515
});
16-
17-
it('https://github.com/testing-library/angular-testing-library/issues/222 with change', async () => {
18-
const { change } = await render(`<div>Hello {{ name}}</div>`, {
19-
componentProperties: {
20-
name: 'Sarah',
21-
},
22-
});
23-
24-
expect(screen.getByText('Hello Sarah')).toBeTruthy();
25-
await change({ name: 'Mark' });
26-
27-
expect(screen.getByText('Hello Mark')).toBeTruthy();
28-
});

apps/example-app/src/app/examples/16-input-getter-setter.spec.ts

-14
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,6 @@ test('should run logic in the input setter and getter', async () => {
1010
expect(getterValueControl).toHaveTextContent('I am value from getter Angular');
1111
});
1212

13-
test('should run logic in the input setter and getter while changing', async () => {
14-
const { change } = await render(InputGetterSetter, { componentProperties: { value: 'Angular' } });
15-
const valueControl = screen.getByTestId('value');
16-
const getterValueControl = screen.getByTestId('value-getter');
17-
18-
expect(valueControl).toHaveTextContent('I am value from setter Angular');
19-
expect(getterValueControl).toHaveTextContent('I am value from getter Angular');
20-
21-
await change({ value: 'React' });
22-
23-
expect(valueControl).toHaveTextContent('I am value from setter React');
24-
expect(getterValueControl).toHaveTextContent('I am value from getter React');
25-
});
26-
2713
test('should run logic in the input setter and getter while re-rendering', async () => {
2814
const { rerender } = await render(InputGetterSetter, { componentProperties: { value: 'Angular' } });
2915

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

-16
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,6 @@ export interface RenderResult<ComponentType, WrapperType = ComponentType> extend
6363
'componentProperties' | 'componentInputs' | 'componentOutputs' | 'detectChangesOnRender'
6464
>,
6565
) => Promise<void>;
66-
/**
67-
* @deprecated
68-
* Use rerender instead. For more info see {@link https://github.com/testing-library/angular-testing-library/issues/365 GitHub Issue}
69-
*
70-
* @description
71-
* Keeps the current fixture intact and invokes ngOnChanges with the updated properties.
72-
*/
73-
change: (changedProperties: Partial<ComponentType>) => void;
74-
/**
75-
* @deprecated
76-
* Use rerender instead. For more info see {@link https://github.com/testing-library/angular-testing-library/issues/365 GitHub Issue}
77-
*
78-
* @description
79-
* Keeps the current fixture intact, update the @Input properties and invoke ngOnChanges with the updated properties.
80-
*/
81-
changeInput: (changedInputProperties: Partial<ComponentType>) => void;
8266
}
8367

8468
export interface RenderComponentOptions<ComponentType, Q extends Queries = typeof queries> {

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

+20-44
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,7 @@ export async function render<SutType, WrapperType = SutType>(
133133
>,
134134
) => {
135135
const newComponentInputs = properties?.componentInputs ?? {};
136-
for (const inputKey of renderedInputKeys) {
137-
if (!Object.prototype.hasOwnProperty.call(newComponentInputs, inputKey)) {
138-
delete (fixture.componentInstance as any)[inputKey];
139-
}
140-
}
141-
setComponentInputs(fixture, newComponentInputs);
136+
const changesInComponentInput = update(fixture, renderedInputKeys, newComponentInputs, setComponentInputs);
142137
renderedInputKeys = Object.keys(newComponentInputs);
143138

144139
const newComponentOutputs = properties?.componentOutputs ?? {};
@@ -151,43 +146,21 @@ export async function render<SutType, WrapperType = SutType>(
151146
renderedOutputKeys = Object.keys(newComponentOutputs);
152147

153148
const newComponentProps = properties?.componentProperties ?? {};
154-
const changes = updateProps(fixture, renderedPropKeys, newComponentProps);
149+
const changesInComponentProps = update(fixture, renderedPropKeys, newComponentProps, setComponentProperties);
150+
renderedPropKeys = Object.keys(newComponentProps);
151+
155152
if (hasOnChangesHook(fixture.componentInstance)) {
156-
fixture.componentInstance.ngOnChanges(changes);
153+
fixture.componentInstance.ngOnChanges({
154+
...changesInComponentInput,
155+
...changesInComponentProps,
156+
});
157157
}
158-
renderedPropKeys = Object.keys(newComponentProps);
159158

160159
if (properties?.detectChangesOnRender !== false) {
161160
fixture.componentRef.injector.get(ChangeDetectorRef).detectChanges();
162161
}
163162
};
164163

165-
const changeInput = (changedInputProperties: Partial<SutType>) => {
166-
if (Object.keys(changedInputProperties).length === 0) {
167-
return;
168-
}
169-
170-
setComponentInputs(fixture, changedInputProperties);
171-
172-
fixture.detectChanges();
173-
};
174-
175-
const change = (changedProperties: Partial<SutType>) => {
176-
if (Object.keys(changedProperties).length === 0) {
177-
return;
178-
}
179-
180-
const changes = getChangesObj(fixture.componentInstance as Record<string, any>, changedProperties);
181-
182-
setComponentProperties(fixture, changedProperties);
183-
184-
if (hasOnChangesHook(fixture.componentInstance)) {
185-
fixture.componentInstance.ngOnChanges(changes);
186-
}
187-
188-
fixture.componentRef.injector.get(ChangeDetectorRef).detectChanges();
189-
};
190-
191164
const navigate = async (elementOrPath: Element | string, basePath = ''): Promise<boolean> => {
192165
const href = typeof elementOrPath === 'string' ? elementOrPath : elementOrPath.getAttribute('href');
193166
const [path, params] = (basePath + href).split('?');
@@ -234,8 +207,6 @@ export async function render<SutType, WrapperType = SutType>(
234207
detectChanges: () => detectChanges(),
235208
navigate,
236209
rerender,
237-
change,
238-
changeInput,
239210
// @ts-ignore: fixture assigned
240211
debugElement: fixture.debugElement,
241212
// @ts-ignore: fixture assigned
@@ -389,27 +360,32 @@ function getChangesObj(oldProps: Record<string, any> | null, newProps: Record<st
389360
);
390361
}
391362

392-
function updateProps<SutType>(
363+
function update<SutType>(
393364
fixture: ComponentFixture<SutType>,
394-
prevRenderedPropsKeys: string[],
395-
newProps: Record<string, any>,
365+
prevRenderedKeys: string[],
366+
newValues: Record<string, any>,
367+
updateFunction: (
368+
fixture: ComponentFixture<SutType>,
369+
values: RenderTemplateOptions<SutType>['componentInputs' | 'componentProperties'],
370+
) => void,
396371
) {
397372
const componentInstance = fixture.componentInstance as Record<string, any>;
398373
const simpleChanges: SimpleChanges = {};
399374

400-
for (const key of prevRenderedPropsKeys) {
401-
if (!Object.prototype.hasOwnProperty.call(newProps, key)) {
375+
for (const key of prevRenderedKeys) {
376+
if (!Object.prototype.hasOwnProperty.call(newValues, key)) {
402377
simpleChanges[key] = new SimpleChange(componentInstance[key], undefined, false);
403378
delete componentInstance[key];
404379
}
405380
}
406381

407-
for (const [key, value] of Object.entries(newProps)) {
382+
for (const [key, value] of Object.entries(newValues)) {
408383
if (value !== componentInstance[key]) {
409384
simpleChanges[key] = new SimpleChange(componentInstance[key], value, false);
410385
}
411386
}
412-
setComponentProperties(fixture, newProps);
387+
388+
updateFunction(fixture, newValues);
413389

414390
return simpleChanges;
415391
}

projects/testing-library/tests/change.spec.ts

-96
This file was deleted.

projects/testing-library/tests/changeInputs.spec.ts

-97
This file was deleted.

0 commit comments

Comments
 (0)