From b1d64739b25331830c62e6669190647a206d0520 Mon Sep 17 00:00:00 2001 From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> Date: Mon, 22 Jan 2024 09:57:00 +0100 Subject: [PATCH] feat: add DeferBlockBehavior --- projects/testing-library/src/lib/models.ts | 12 +++++- .../src/lib/testing-library.ts | 32 ++++++++-------- .../tests/defer-blocks.spec.ts | 38 +++++++++++++++++-- 3 files changed, 63 insertions(+), 19 deletions(-) diff --git a/projects/testing-library/src/lib/models.ts b/projects/testing-library/src/lib/models.ts index 257bef0..fad3394 100644 --- a/projects/testing-library/src/lib/models.ts +++ b/projects/testing-library/src/lib/models.ts @@ -1,5 +1,5 @@ import { Type, DebugElement } from '@angular/core'; -import { ComponentFixture, DeferBlockState, TestBed } from '@angular/core/testing'; +import {ComponentFixture, DeferBlockBehavior, DeferBlockState, TestBed} from '@angular/core/testing'; import { Routes } from '@angular/router'; import { BoundFunction, Queries, queries, Config as dtlConfig, PrettyDOMOptions } from '@testing-library/dom'; @@ -369,7 +369,17 @@ export interface RenderComponentOptions void; + /** + * @description + * Set the initial state of a deferrable block. + */ deferBlockStates?: DeferBlockState | { deferBlockState: DeferBlockState; deferBlockIndex: number }[]; + + /** + * @description + * Set the defer blocks behavior. + */ + deferBlockBehavior?: DeferBlockBehavior } export interface ComponentOverride { diff --git a/projects/testing-library/src/lib/testing-library.ts b/projects/testing-library/src/lib/testing-library.ts index 1be2f22..2b3ac75 100644 --- a/projects/testing-library/src/lib/testing-library.ts +++ b/projects/testing-library/src/lib/testing-library.ts @@ -1,32 +1,32 @@ import { + ApplicationInitStatus, ChangeDetectorRef, Component, - Type, + isStandalone, NgZone, - SimpleChange, OnChanges, + SimpleChange, SimpleChanges, - ApplicationInitStatus, - isStandalone, + Type, } from '@angular/core'; -import { ComponentFixture, DeferBlockState, TestBed, tick } from '@angular/core/testing'; -import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { NavigationExtras, Router } from '@angular/router'; -import { RouterTestingModule } from '@angular/router/testing'; +import {ComponentFixture, DeferBlockState, TestBed, tick} from '@angular/core/testing'; +import {BrowserAnimationsModule, NoopAnimationsModule} from '@angular/platform-browser/animations'; +import {NavigationExtras, Router} from '@angular/router'; +import {RouterTestingModule} from '@angular/router/testing'; +import type {BoundFunctions, Queries} from '@testing-library/dom'; import { + configure as dtlConfigure, getQueriesForElement as dtlGetQueriesForElement, prettyDOM as dtlPrettyDOM, + queries as dtlQueries, + screen as dtlScreen, waitFor as dtlWaitFor, waitForElementToBeRemoved as dtlWaitForElementToBeRemoved, - screen as dtlScreen, - within as dtlWithin, waitForOptions as dtlWaitForOptions, - configure as dtlConfigure, - queries as dtlQueries, + within as dtlWithin, } from '@testing-library/dom'; -import type { Queries, BoundFunctions } from '@testing-library/dom'; -import { RenderComponentOptions, RenderTemplateOptions, RenderResult, ComponentOverride } from './models'; -import { getConfig } from './config'; +import {ComponentOverride, RenderComponentOptions, RenderResult, RenderTemplateOptions} from './models'; +import {getConfig} from './config'; const mountedFixtures = new Set>(); const safeInject = TestBed.inject || TestBed.get; @@ -66,6 +66,7 @@ export async function render( defaultImports = [], initialRoute = '', deferBlockStates = undefined, + deferBlockBehavior = undefined, configureTestBed = () => { /* noop*/ }, @@ -94,6 +95,7 @@ export async function render( }), providers: [...providers], schemas: [...schemas], + deferBlockBehavior: deferBlockBehavior as any }); overrideComponentImports(sut, componentImports); overrideChildComponentProviders(childComponentOverrides); diff --git a/projects/testing-library/tests/defer-blocks.spec.ts b/projects/testing-library/tests/defer-blocks.spec.ts index 9c2985b..147c5c7 100644 --- a/projects/testing-library/tests/defer-blocks.spec.ts +++ b/projects/testing-library/tests/defer-blocks.spec.ts @@ -1,6 +1,7 @@ -import { Component } from '@angular/core'; -import { DeferBlockState } from '@angular/core/testing'; -import { render, screen } from '../src/public_api'; +import {Component} from '@angular/core'; +import {DeferBlockBehavior, DeferBlockState} from '@angular/core/testing'; +import {render, screen} from '../src/public_api'; +import {fireEvent} from "@testing-library/dom"; test('renders a defer block in different states using the official API', async () => { const { fixture } = await render(FixtureComponent); @@ -28,6 +29,26 @@ test('renders a defer block in different states using ATL', async () => { expect(screen.queryByText(/load/i)).not.toBeInTheDocument(); }); +test('renders a defer block in different states using DeferBlockBehavior.Playthrough', async () => { + await render(FixtureComponent, { + deferBlockBehavior: DeferBlockBehavior.Playthrough + }); + + expect(await screen.findByText(/loading/i)).toBeInTheDocument(); + expect(await screen.findByText(/Defer block content/i)).toBeInTheDocument(); +}); + +test('renders a defer block in different states using DeferBlockBehavior.Playthrough event', async () => { + await render(FixtureComponentWithEvents, { + deferBlockBehavior: DeferBlockBehavior.Playthrough + }); + + const button = screen.getByRole('button', {name: /click/i}); + fireEvent.click(button) + + expect(screen.getByText(/empty defer block/i)).toBeInTheDocument(); +}); + test('renders a defer block initially in the loading state', async () => { await render(FixtureComponent, { deferBlockStates: DeferBlockState.Loading, @@ -65,3 +86,14 @@ test('renders a defer block in an initial state using the array syntax', async ( `, }) class FixtureComponent {} + +@Component({ + template: ` + + @defer(on interaction(trigger)) { +
empty defer block
+ } + `, +}) +class FixtureComponentWithEvents {} +