From 4b6e491cf7f748f828f66589239651f7f0818f55 Mon Sep 17 00:00:00 2001 From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> Date: Thu, 18 Mar 2021 19:01:21 +0100 Subject: [PATCH] fix: invoke ngOnChanges when initial value is not set (#189) Closes #188 --- .../src/lib/testing-library.ts | 13 ++++------ .../testing-library/tests/issues/188.spec.ts | 24 +++++++++++++++++++ projects/testing-library/tests/render.spec.ts | 8 +++---- 3 files changed, 33 insertions(+), 12 deletions(-) create mode 100644 projects/testing-library/tests/issues/188.spec.ts diff --git a/projects/testing-library/src/lib/testing-library.ts b/projects/testing-library/src/lib/testing-library.ts index b2654a9f..55c4d275 100644 --- a/projects/testing-library/src/lib/testing-library.ts +++ b/projects/testing-library/src/lib/testing-library.ts @@ -110,7 +110,7 @@ export async function render( // Call ngOnChanges on initial render if (hasOnChangesHook(fixture.componentInstance)) { - const changes = getChangesObj(null, fixture.componentInstance); + const changes = getChangesObj(null, componentProperties); fixture.componentInstance.ngOnChanges(changes); } @@ -205,13 +205,13 @@ function setComponentProperties( { componentProperties = {} }: Pick, 'componentProperties'>, ) { for (const key of Object.keys(componentProperties)) { - let _value = componentProperties[key]; + let _value = componentProperties[key]; Object.defineProperty(fixture.componentInstance, key, { - get: () => _value , + get: () => _value, set: (value) => { _value = value; fixture.detectChanges(); - } + }, }); } return fixture; @@ -241,10 +241,7 @@ function addAutoDeclarations( excludeComponentDeclaration, template, wrapper, - }: Pick< - RenderDirectiveOptions, - 'declarations' | 'excludeComponentDeclaration' | 'template' | 'wrapper' - >, + }: Pick, 'declarations' | 'excludeComponentDeclaration' | 'template' | 'wrapper'>, ) { const wrappers = () => { return template ? [wrapper] : []; diff --git a/projects/testing-library/tests/issues/188.spec.ts b/projects/testing-library/tests/issues/188.spec.ts new file mode 100644 index 00000000..c972aad0 --- /dev/null +++ b/projects/testing-library/tests/issues/188.spec.ts @@ -0,0 +1,24 @@ +// https://github.com/testing-library/angular-testing-library/issues/188 +import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; +import { render } from '../../src/public_api'; + +@Component({ + template: `

Hello {{ formattedName }}

`, +}) +export class BugOnChangeComponent implements OnChanges { + @Input() name: string; + + formattedName: string; + + ngOnChanges(changes: SimpleChanges) { + if (changes.name) { + this.formattedName = changes.name.currentValue.toUpperCase(); + } + } +} + +it('should output formatted name after rendering', async () => { + const { getByText } = await render(BugOnChangeComponent, { componentProperties: { name: 'name' } }); + + getByText('Hello NAME'); +}); diff --git a/projects/testing-library/tests/render.spec.ts b/projects/testing-library/tests/render.spec.ts index 22d6567e..292b97ab 100644 --- a/projects/testing-library/tests/render.spec.ts +++ b/projects/testing-library/tests/render.spec.ts @@ -87,7 +87,7 @@ describe('Angular component life-cycle hooks', () => { template: ` {{ name }} `, }) class FixtureWithNgOnChangesComponent implements OnInit, OnChanges { - @Input() name = 'Sarah'; + @Input() name = 'Initial'; @Input() nameInitialized?: (name: string) => void; @Input() nameChanged?: (name: string, isFirstChange: boolean) => void; @@ -109,14 +109,14 @@ describe('Angular component life-cycle hooks', () => { const componentProperties = { nameInitialized }; const component = await render(FixtureWithNgOnChangesComponent, { componentProperties }); - component.getByText('Sarah'); - expect(nameInitialized).toBeCalledWith('Sarah'); + component.getByText('Initial'); + expect(nameInitialized).toBeCalledWith('Initial'); }); test('will call ngOnChanges on initial render before ngOnInit', async () => { const nameInitialized = jest.fn(); const nameChanged = jest.fn(); - const componentProperties = { nameInitialized, nameChanged }; + const componentProperties = { nameInitialized, nameChanged, name: 'Sarah' }; const component = await render(FixtureWithNgOnChangesComponent, { componentProperties }); component.getByText('Sarah');