From 8a6fe171c683da2a6c473781ad3dbaf963537943 Mon Sep 17 00:00:00 2001 From: Gregor Woiwode Date: Tue, 3 Sep 2019 14:50:42 +0200 Subject: [PATCH] feat: add detectChanges function (#45) --- projects/testing-library/src/lib/models.ts | 9 +++- .../src/lib/testing-library.ts | 13 +++--- .../tests/detect-changes.spec.ts | 43 +++++++++++++++++++ 3 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 projects/testing-library/tests/detect-changes.spec.ts diff --git a/projects/testing-library/src/lib/models.ts b/projects/testing-library/src/lib/models.ts index 7211a12e..d87720d0 100644 --- a/projects/testing-library/src/lib/models.ts +++ b/projects/testing-library/src/lib/models.ts @@ -1,6 +1,6 @@ import { Type } from '@angular/core'; import { ComponentFixture } from '@angular/core/testing'; -import { FireObject, Queries, queries, BoundFunction } from '@testing-library/dom'; +import { BoundFunction, FireObject, Queries, queries } from '@testing-library/dom'; import { UserEvents } from './user-events'; export type RenderResultQueries = { [P in keyof Q]: BoundFunction }; @@ -21,6 +21,13 @@ export interface RenderResult extends RenderResultQueries, FireObject, UserEvent * element: The to be printed HTML element, if not provided it will log the whole component's DOM */ debug: (element?: HTMLElement) => void; + /** + * @description + * Trigger a change detection cycle for the component. + * + * For more info see https://angular.io/api/core/testing/ComponentFixture#detectChanges + */ + detectChanges: () => void; /** * @description * The Angular `ComponentFixture` of the component. diff --git a/projects/testing-library/src/lib/testing-library.ts b/projects/testing-library/src/lib/testing-library.ts index 41c5c50f..1b8b43ff 100644 --- a/projects/testing-library/src/lib/testing-library.ts +++ b/projects/testing-library/src/lib/testing-library.ts @@ -1,10 +1,10 @@ -import { Component, OnInit, ElementRef, Type, DebugElement } from '@angular/core'; +import { Component, DebugElement, ElementRef, OnInit, Type } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; -import { NoopAnimationsModule, BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { TestBed, ComponentFixture } from '@angular/core/testing'; -import { getQueriesForElement, prettyDOM, fireEvent, FireObject, FireFunction } from '@testing-library/dom'; -import { RenderResult, RenderOptions } from './models'; -import { createType, createSelectOptions } from './user-events'; +import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations'; +import { fireEvent, FireFunction, FireObject, getQueriesForElement, prettyDOM } from '@testing-library/dom'; +import { RenderOptions, RenderResult } from './models'; +import { createSelectOptions, createType } from './user-events'; @Component({ selector: 'wrapper-component', template: '' }) class WrapperComponent implements OnInit { @@ -84,6 +84,7 @@ export async function render( fixture, container: fixture.nativeElement, debug: (element = fixture.nativeElement) => console.log(prettyDOM(element)), + detectChanges: () => fixture.detectChanges(), ...getQueriesForElement(fixture.nativeElement, queries), ...eventsWithDetectChanges, type: createType(eventsWithDetectChanges), diff --git a/projects/testing-library/tests/detect-changes.spec.ts b/projects/testing-library/tests/detect-changes.spec.ts new file mode 100644 index 00000000..40f68812 --- /dev/null +++ b/projects/testing-library/tests/detect-changes.spec.ts @@ -0,0 +1,43 @@ +import { Component, OnInit } from '@angular/core'; +import { fakeAsync, tick } from '@angular/core/testing'; +import { FormControl, ReactiveFormsModule } from '@angular/forms'; +import { delay } from 'rxjs/operators'; +import { render } from '../src/public_api'; + +@Component({ + selector: 'fixture', + template: ` + + + `, +}) +class FixtureComponent implements OnInit { + inputControl = new FormControl(); + caption = 'Button'; + + ngOnInit() { + this.inputControl.valueChanges.pipe(delay(400)).subscribe(() => (this.caption = 'Button updated after 400ms')); + } +} + +describe('detectChanges', () => { + test('does not recognize change if execution is delayed', async () => { + const { getByTestId, type } = await render(FixtureComponent, { imports: [ReactiveFormsModule] }); + + type(getByTestId('input'), 'What a great day!'); + expect(getByTestId('button').innerHTML).toBe('Button'); + }); + + test('exposes detectChanges triggering a change detection cycle', fakeAsync(async () => { + const { getByTestId, type, detectChanges } = await render(FixtureComponent, { + imports: [ReactiveFormsModule], + }); + + type(getByTestId('input'), 'What a great day!'); + + tick(500); + detectChanges(); + + expect(getByTestId('button').innerHTML).toBe('Button updated after 400ms'); + })); +});