Skip to content

Commit 4b6e491

Browse files
fix: invoke ngOnChanges when initial value is not set (#189)
Closes #188
1 parent cccdf03 commit 4b6e491

File tree

3 files changed

+33
-12
lines changed

3 files changed

+33
-12
lines changed

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

+5-8
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ export async function render<SutType, WrapperType = SutType>(
110110

111111
// Call ngOnChanges on initial render
112112
if (hasOnChangesHook(fixture.componentInstance)) {
113-
const changes = getChangesObj(null, fixture.componentInstance);
113+
const changes = getChangesObj(null, componentProperties);
114114
fixture.componentInstance.ngOnChanges(changes);
115115
}
116116

@@ -205,13 +205,13 @@ function setComponentProperties<SutType>(
205205
{ componentProperties = {} }: Pick<RenderDirectiveOptions<SutType, any>, 'componentProperties'>,
206206
) {
207207
for (const key of Object.keys(componentProperties)) {
208-
let _value = componentProperties[key];
208+
let _value = componentProperties[key];
209209
Object.defineProperty(fixture.componentInstance, key, {
210-
get: () => _value ,
210+
get: () => _value,
211211
set: (value) => {
212212
_value = value;
213213
fixture.detectChanges();
214-
}
214+
},
215215
});
216216
}
217217
return fixture;
@@ -241,10 +241,7 @@ function addAutoDeclarations<SutType>(
241241
excludeComponentDeclaration,
242242
template,
243243
wrapper,
244-
}: Pick<
245-
RenderDirectiveOptions<any>,
246-
'declarations' | 'excludeComponentDeclaration' | 'template' | 'wrapper'
247-
>,
244+
}: Pick<RenderDirectiveOptions<any>, 'declarations' | 'excludeComponentDeclaration' | 'template' | 'wrapper'>,
248245
) {
249246
const wrappers = () => {
250247
return template ? [wrapper] : [];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// https://github.com/testing-library/angular-testing-library/issues/188
2+
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
3+
import { render } from '../../src/public_api';
4+
5+
@Component({
6+
template: `<h1>Hello {{ formattedName }}</h1>`,
7+
})
8+
export class BugOnChangeComponent implements OnChanges {
9+
@Input() name: string;
10+
11+
formattedName: string;
12+
13+
ngOnChanges(changes: SimpleChanges) {
14+
if (changes.name) {
15+
this.formattedName = changes.name.currentValue.toUpperCase();
16+
}
17+
}
18+
}
19+
20+
it('should output formatted name after rendering', async () => {
21+
const { getByText } = await render(BugOnChangeComponent, { componentProperties: { name: 'name' } });
22+
23+
getByText('Hello NAME');
24+
});

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

+4-4
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ describe('Angular component life-cycle hooks', () => {
8787
template: ` {{ name }} `,
8888
})
8989
class FixtureWithNgOnChangesComponent implements OnInit, OnChanges {
90-
@Input() name = 'Sarah';
90+
@Input() name = 'Initial';
9191
@Input() nameInitialized?: (name: string) => void;
9292
@Input() nameChanged?: (name: string, isFirstChange: boolean) => void;
9393

@@ -109,14 +109,14 @@ describe('Angular component life-cycle hooks', () => {
109109
const componentProperties = { nameInitialized };
110110
const component = await render(FixtureWithNgOnChangesComponent, { componentProperties });
111111

112-
component.getByText('Sarah');
113-
expect(nameInitialized).toBeCalledWith('Sarah');
112+
component.getByText('Initial');
113+
expect(nameInitialized).toBeCalledWith('Initial');
114114
});
115115

116116
test('will call ngOnChanges on initial render before ngOnInit', async () => {
117117
const nameInitialized = jest.fn();
118118
const nameChanged = jest.fn();
119-
const componentProperties = { nameInitialized, nameChanged };
119+
const componentProperties = { nameInitialized, nameChanged, name: 'Sarah' };
120120
const component = await render(FixtureWithNgOnChangesComponent, { componentProperties });
121121

122122
component.getByText('Sarah');

0 commit comments

Comments
 (0)