@@ -15,11 +15,12 @@ import {
1515 stopHandlingAutoChangeDetectionStatus ,
1616 TestElement ,
1717} from '../../testing' ;
18- import { ComponentFixture , flush } from '@angular/core/testing' ;
18+ import { ComponentFixture , DirectiveFixture , flush , TestBed } from '@angular/core/testing' ;
1919import { Observable } from 'rxjs' ;
2020import { takeWhile } from 'rxjs/operators' ;
2121import { TaskState , TaskStateZoneInterceptor } from './task-state-zone-interceptor' ;
2222import { UnitTestElement } from './unit-test-element' ;
23+ import { DestroyRef } from '@angular/core' ;
2324
2425/** Options to configure the environment. */
2526export interface TestbedHarnessEnvironmentOptions {
@@ -32,19 +33,22 @@ const defaultEnvironmentOptions: TestbedHarnessEnvironmentOptions = {
3233 queryFn : ( selector : string , root : Element ) => root . querySelectorAll ( selector ) ,
3334} ;
3435
36+ /** Covers all fixtures supported by `TestBed`. */
37+ export type Fixture < T = unknown > = ComponentFixture < T > | DirectiveFixture < T > ;
38+
3539/** Whether auto change detection is currently disabled. */
3640let disableAutoChangeDetection = false ;
3741
3842/**
3943 * The set of non-destroyed fixtures currently being used by `TestbedHarnessEnvironment` instances.
4044 */
41- const activeFixtures = new Set < ComponentFixture < unknown > > ( ) ;
45+ const activeFixtures = new Set < Fixture > ( ) ;
4246
4347/**
4448 * Installs a handler for change detection batching status changes for a specific fixture.
4549 * @param fixture The fixture to handle change detection batching for.
4650 */
47- function installAutoChangeDetectionStatusHandler ( fixture : ComponentFixture < unknown > ) {
51+ function installAutoChangeDetectionStatusHandler ( fixture : Fixture ) {
4852 if ( ! activeFixtures . size ) {
4953 handleAutoChangeDetectionStatus ( ( { isDisabled, onDetectChangesNow} ) => {
5054 disableAutoChangeDetection = isDisabled ;
@@ -60,7 +64,7 @@ function installAutoChangeDetectionStatusHandler(fixture: ComponentFixture<unkno
6064 * Uninstalls a handler for change detection batching status changes for a specific fixture.
6165 * @param fixture The fixture to stop handling change detection batching for.
6266 */
63- function uninstallAutoChangeDetectionStatusHandler ( fixture : ComponentFixture < unknown > ) {
67+ function uninstallAutoChangeDetectionStatusHandler ( fixture : Fixture ) {
6468 activeFixtures . delete ( fixture ) ;
6569 if ( ! activeFixtures . size ) {
6670 stopHandlingAutoChangeDetectionStatus ( ) ;
@@ -76,7 +80,7 @@ function isInFakeAsyncZone() {
7680 * Triggers change detection for a specific fixture.
7781 * @param fixture The fixture to trigger change detection for.
7882 */
79- async function detectChanges ( fixture : ComponentFixture < unknown > ) {
83+ async function detectChanges ( fixture : Fixture ) {
8084 fixture . detectChanges ( ) ;
8185 if ( isInFakeAsyncZone ( ) ) {
8286 flush ( ) ;
@@ -101,7 +105,7 @@ export class TestbedHarnessEnvironment extends HarnessEnvironment<Element> {
101105
102106 protected constructor (
103107 rawRootElement : Element ,
104- private _fixture : ComponentFixture < unknown > ,
108+ private _fixture : Fixture ,
105109 options ?: TestbedHarnessEnvironmentOptions ,
106110 ) {
107111 super ( rawRootElement ) ;
@@ -111,17 +115,22 @@ export class TestbedHarnessEnvironment extends HarnessEnvironment<Element> {
111115 }
112116 this . _stabilizeCallback = ( ) => this . forceStabilize ( ) ;
113117 installAutoChangeDetectionStatusHandler ( _fixture ) ;
114- _fixture . componentRef . onDestroy ( ( ) => {
118+
119+ const onDestroy = ( ) => {
115120 uninstallAutoChangeDetectionStatusHandler ( _fixture ) ;
116121 this . _destroyed = true ;
117- } ) ;
122+ } ;
123+
124+ if ( _fixture instanceof ComponentFixture ) {
125+ _fixture . componentRef . onDestroy ( onDestroy ) ;
126+ } else {
127+ // TODO(crisbeto): use host ref in directive fixture once it's available.
128+ TestBed . inject ( DestroyRef ) . onDestroy ( onDestroy ) ;
129+ }
118130 }
119131
120132 /** Creates a `HarnessLoader` rooted at the given fixture's root element. */
121- static loader (
122- fixture : ComponentFixture < unknown > ,
123- options ?: TestbedHarnessEnvironmentOptions ,
124- ) : HarnessLoader {
133+ static loader ( fixture : Fixture , options ?: TestbedHarnessEnvironmentOptions ) : HarnessLoader {
125134 return new TestbedHarnessEnvironment ( fixture . nativeElement , fixture , options ) ;
126135 }
127136
@@ -130,7 +139,7 @@ export class TestbedHarnessEnvironment extends HarnessEnvironment<Element> {
130139 * located outside of a fixture (e.g. overlays appended to the document body).
131140 */
132141 static documentRootLoader (
133- fixture : ComponentFixture < unknown > ,
142+ fixture : Fixture ,
134143 options ?: TestbedHarnessEnvironmentOptions ,
135144 ) : HarnessLoader {
136145 return new TestbedHarnessEnvironment ( document . body , fixture , options ) ;
@@ -151,7 +160,7 @@ export class TestbedHarnessEnvironment extends HarnessEnvironment<Element> {
151160 * of the fixture.
152161 */
153162 static async harnessForFixture < T extends ComponentHarness > (
154- fixture : ComponentFixture < unknown > ,
163+ fixture : Fixture ,
155164 harnessType : ComponentHarnessConstructor < T > ,
156165 options ?: TestbedHarnessEnvironmentOptions ,
157166 ) : Promise < T > {
0 commit comments