Skip to content

Commit 7f2238b

Browse files
committed
feat: add rerender function
1 parent e41c034 commit 7f2238b

File tree

4 files changed

+45
-12
lines changed

4 files changed

+45
-12
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ export interface RenderResult<ComponentType, WrapperType = ComponentType>
3232
* For more info see https://angular.io/api/core/testing/ComponentFixture#detectChanges
3333
*/
3434
detectChanges: () => void;
35+
/**
36+
* @description
37+
* Re-render the same component with different props.
38+
*/
39+
rerender: (componentProperties?: Partial<ComponentType>) => void;
3540
/**
3641
* @description
3742
* The Angular `ComponentFixture` of the component or the wrapper.

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

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,14 @@ export async function render<SutType, WrapperType = SutType>(
9191
{} as FireFunction & FireObject,
9292
);
9393

94+
const rerender = (rerenderedProperties?: Partial<SutType>) => {
95+
setComponentProperties(fixture, { componentProperties: rerenderedProperties });
96+
detectChanges();
97+
};
98+
9499
let router = routes ? (TestBed.get<Router>(Router) as Router) : null;
95100
const zone = TestBed.get<NgZone>(NgZone) as NgZone;
96-
97-
async function navigate(elementOrPath: Element | string, basePath = '') {
101+
const navigate = async (elementOrPath: Element | string, basePath = '') => {
98102
if (!router) {
99103
router = TestBed.get<Router>(Router) as Router;
100104
}
@@ -105,20 +109,20 @@ export async function render<SutType, WrapperType = SutType>(
105109
await zone.run(() => (result = router.navigate([basePath + href])));
106110
detectChanges();
107111
return result;
108-
}
109-
const debugElement = fixture.debugElement.query(By.directive(sut));
112+
};
110113

111114
return {
112115
fixture,
113-
debugElement,
116+
detectChanges,
117+
navigate,
118+
rerender,
119+
debugElement: fixture.debugElement.query(By.directive(sut)),
114120
container: fixture.nativeElement,
115121
debug: (element = fixture.nativeElement) => console.log(prettyDOM(element)),
116-
detectChanges,
117-
...getQueriesForElement(fixture.nativeElement, queries),
118-
...eventsWithDetectChanges,
119122
type: createType(eventsWithDetectChanges),
120123
selectOptions: createSelectOptions(eventsWithDetectChanges),
121-
navigate,
124+
...getQueriesForElement(fixture.nativeElement, queries),
125+
...eventsWithDetectChanges,
122126
};
123127
}
124128

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ test('creates queries and events', async () => {
2525
})
2626
export class FixtureModule {}
2727
describe('excludeComponentDeclaration', () => {
28-
test('should not throw if component is declared in an import', async () => {
28+
test('will throw if component is declared in an import', async () => {
2929
await render(FixtureComponent, {
3030
imports: [FixtureModule],
3131
excludeComponentDeclaration: true,
@@ -34,13 +34,13 @@ describe('excludeComponentDeclaration', () => {
3434
});
3535

3636
describe('animationModule', () => {
37-
test('should add NoopAnimationsModule by default', async () => {
37+
test('adds NoopAnimationsModule by default', async () => {
3838
await render(FixtureComponent);
3939
const noopAnimationsModule = TestBed.get<NoopAnimationsModule>(NoopAnimationsModule);
4040
expect(noopAnimationsModule).toBeDefined();
4141
});
4242

43-
test('should not add NoopAnimationsModule if BrowserAnimationsModule is an import', async () => {
43+
test('does not add NoopAnimationsModule if BrowserAnimationsModule is an import', async () => {
4444
await render(FixtureComponent, {
4545
imports: [BrowserAnimationsModule],
4646
});
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Component, Input } from '@angular/core';
2+
import { render } from '../src/public_api';
3+
4+
@Component({
5+
selector: 'fixture',
6+
template: `
7+
{{ name }}
8+
`,
9+
})
10+
class FixtureComponent {
11+
@Input() name = 'Sarah';
12+
}
13+
14+
test('will rerender the component with updated props', async () => {
15+
const component = await render(FixtureComponent);
16+
component.getByText('Sarah');
17+
18+
const name = 'Mark';
19+
component.rerender({
20+
name,
21+
});
22+
23+
component.getByText(name);
24+
});

0 commit comments

Comments
 (0)