Skip to content

Commit 8ab3642

Browse files
authored
test: Convert some material tests to zoneless (angular#29278)
1 parent 5f7680f commit 8ab3642

File tree

16 files changed

+501
-173
lines changed

16 files changed

+501
-173
lines changed

src/material/dialog/dialog.spec.ts

Lines changed: 15 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import {
3030
ViewEncapsulation,
3131
createNgModuleRef,
3232
forwardRef,
33-
provideZoneChangeDetection,
3433
signal,
3534
} from '@angular/core';
3635
import {
@@ -84,8 +83,6 @@ describe('MDC-based MatDialog', () => {
8483
ComponentWithContentElementTemplateRef,
8584
],
8685
providers: [
87-
provideZoneChangeDetection(),
88-
provideZoneChangeDetection(),
8986
{provide: Location, useClass: SpyLocation},
9087
{
9188
provide: ScrollDispatcher,
@@ -137,6 +134,7 @@ describe('MDC-based MatDialog', () => {
137134
it('should open a dialog with a template', () => {
138135
const templateRefFixture = TestBed.createComponent(ComponentWithTemplateRef);
139136
templateRefFixture.componentInstance.localValue = 'Bees';
137+
templateRefFixture.changeDetectorRef.markForCheck();
140138
templateRefFixture.detectChanges();
141139

142140
const data = {value: 'Knees'};
@@ -233,24 +231,6 @@ describe('MDC-based MatDialog', () => {
233231
expect(overlayContainerElement.querySelector('mat-dialog-container')).toBeNull();
234232
}));
235233

236-
it('should invoke the afterClosed callback inside the NgZone', fakeAsync(
237-
inject([NgZone], (zone: NgZone) => {
238-
const dialogRef = dialog.open(PizzaMsg, {viewContainerRef: testViewContainerRef});
239-
const afterCloseCallback = jasmine.createSpy('afterClose callback');
240-
241-
dialogRef.afterClosed().subscribe(() => {
242-
afterCloseCallback(NgZone.isInAngularZone());
243-
});
244-
zone.run(() => {
245-
dialogRef.close();
246-
viewContainerFixture.detectChanges();
247-
flush();
248-
});
249-
250-
expect(afterCloseCallback).toHaveBeenCalledWith(true);
251-
}),
252-
));
253-
254234
it('should dispose of dialog if view container is destroyed while animating', fakeAsync(() => {
255235
const dialogRef = dialog.open(PizzaMsg, {viewContainerRef: testViewContainerRef});
256236

@@ -1077,8 +1057,8 @@ describe('MDC-based MatDialog', () => {
10771057
autoFocus: 'first-heading',
10781058
});
10791059

1060+
flush();
10801061
viewContainerFixture.detectChanges();
1081-
flushMicrotasks();
10821062

10831063
let backdrop = overlayContainerElement.querySelector('.cdk-overlay-backdrop') as HTMLElement;
10841064
let firstHeader = overlayContainerElement.querySelector(
@@ -1110,8 +1090,8 @@ describe('MDC-based MatDialog', () => {
11101090
autoFocus: 'button',
11111091
});
11121092

1093+
flush();
11131094
viewContainerFixture.detectChanges();
1114-
flushMicrotasks();
11151095

11161096
let backdrop = overlayContainerElement.querySelector('.cdk-overlay-backdrop') as HTMLElement;
11171097
let firstButton = overlayContainerElement.querySelector(
@@ -1228,8 +1208,8 @@ describe('MDC-based MatDialog', () => {
12281208
autoFocus: 'first-heading',
12291209
});
12301210

1211+
flush();
12311212
viewContainerFixture.detectChanges();
1232-
flushMicrotasks();
12331213

12341214
let firstHeader = overlayContainerElement.querySelector(
12351215
'h2[tabindex="-1"]',
@@ -1284,8 +1264,8 @@ describe('MDC-based MatDialog', () => {
12841264
dialog.open(PizzaMsg, {viewContainerRef: testViewContainerRef}),
12851265
);
12861266

1287-
viewContainerFixture.detectChanges();
12881267
flush();
1268+
viewContainerFixture.detectChanges();
12891269

12901270
expect(document.activeElement!.id).not.toBe(
12911271
'dialog-trigger',
@@ -1546,8 +1526,8 @@ describe('MDC-based MatDialog', () => {
15461526
}),
15471527
);
15481528

1549-
viewContainerFixture.detectChanges();
15501529
flush();
1530+
viewContainerFixture.detectChanges();
15511531

15521532
expect(document.activeElement!.id).not.toBe(
15531533
'dialog-trigger',
@@ -1581,8 +1561,8 @@ describe('MDC-based MatDialog', () => {
15811561
dialog.open(PizzaMsg, {viewContainerRef: testViewContainerRef}),
15821562
);
15831563

1584-
viewContainerFixture.detectChanges();
15851564
flush();
1565+
viewContainerFixture.detectChanges();
15861566

15871567
expect(document.activeElement!.id).not.toBe(
15881568
'dialog-trigger',
@@ -1681,8 +1661,9 @@ describe('MDC-based MatDialog', () => {
16811661

16821662
const hostFixture = TestBed.createComponent(OnPushHost);
16831663
hostFixture.componentInstance.child.open();
1684-
hostFixture.autoDetectChanges();
1664+
hostFixture.detectChanges();
16851665
flush();
1666+
hostFixture.detectChanges();
16861667

16871668
const overlayContainer = TestBed.inject(OverlayContainer);
16881669
const title = overlayContainer.getContainerElement().querySelector('[mat-dialog-title]')!;
@@ -1696,6 +1677,7 @@ describe('MDC-based MatDialog', () => {
16961677
hostFixture.componentInstance.child.dialogRef?.componentInstance.showTitle.set(false);
16971678
hostFixture.detectChanges();
16981679
flush();
1680+
hostFixture.detectChanges();
16991681
expect(container.getAttribute('aria-labelledby')).toBe(null);
17001682
}));
17011683

@@ -1779,6 +1761,7 @@ describe('MDC-based MatDialog', () => {
17791761
expect(container.getAttribute('aria-labelledby')).toBe(title.id);
17801762

17811763
hostInstance.shownTitle = 'second';
1764+
viewContainerFixture.changeDetectorRef.markForCheck();
17821765
viewContainerFixture.detectChanges();
17831766
flush();
17841767
viewContainerFixture.detectChanges();
@@ -1793,6 +1776,7 @@ describe('MDC-based MatDialog', () => {
17931776
const container = overlayContainerElement.querySelector('mat-dialog-container')!;
17941777

17951778
hostInstance.shownTitle = 'all';
1779+
viewContainerFixture.changeDetectorRef.markForCheck();
17961780
viewContainerFixture.detectChanges();
17971781
flush();
17981782
viewContainerFixture.detectChanges();
@@ -1803,6 +1787,7 @@ describe('MDC-based MatDialog', () => {
18031787
expect(container.getAttribute('aria-labelledby')).toBe(titles[0].id);
18041788

18051789
hostInstance.shownTitle = 'second';
1790+
viewContainerFixture.changeDetectorRef.markForCheck();
18061791
viewContainerFixture.detectChanges();
18071792
flush();
18081793
viewContainerFixture.detectChanges();
@@ -1906,6 +1891,7 @@ describe('MDC-based MatDialog', () => {
19061891

19071892
dialogRef.close();
19081893
viewContainerFixture.componentInstance.showChildView = false;
1894+
viewContainerFixture.changeDetectorRef.markForCheck();
19091895
viewContainerFixture.detectChanges();
19101896
flush();
19111897

@@ -1923,7 +1909,6 @@ describe('MDC-based MatDialog with a parent MatDialog', () => {
19231909
TestBed.configureTestingModule({
19241910
imports: [MatDialogModule, NoopAnimationsModule, ComponentThatProvidesMatDialog],
19251911
providers: [
1926-
provideZoneChangeDetection(),
19271912
{
19281913
provide: OverlayContainer,
19291914
useFactory: () => {
@@ -2041,10 +2026,7 @@ describe('MDC-based MatDialog with default options', () => {
20412026
ComponentWithChildViewContainer,
20422027
DirectiveWithViewContainer,
20432028
],
2044-
providers: [
2045-
{provide: MAT_DIALOG_DEFAULT_OPTIONS, useValue: defaultConfig},
2046-
provideZoneChangeDetection(),
2047-
],
2029+
providers: [{provide: MAT_DIALOG_DEFAULT_OPTIONS, useValue: defaultConfig}],
20482030
});
20492031

20502032
TestBed.compileComponents();
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
import {Directionality} from '@angular/cdk/bidi';
2+
import {ScrollDispatcher} from '@angular/cdk/scrolling';
3+
import {SpyLocation} from '@angular/common/testing';
4+
import {
5+
Component,
6+
Directive,
7+
Injector,
8+
NgZone,
9+
ViewChild,
10+
ViewContainerRef,
11+
provideZoneChangeDetection,
12+
} from '@angular/core';
13+
import {ComponentFixture, TestBed, fakeAsync, flush, inject} from '@angular/core/testing';
14+
import {MatDialog, MatDialogModule, MatDialogRef} from '@angular/material/dialog';
15+
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
16+
import {Subject} from 'rxjs';
17+
18+
describe('MDC-based MatDialog', () => {
19+
let dialog: MatDialog;
20+
let scrolledSubject = new Subject();
21+
22+
let testViewContainerRef: ViewContainerRef;
23+
let viewContainerFixture: ComponentFixture<ComponentWithChildViewContainer>;
24+
25+
beforeEach(fakeAsync(() => {
26+
TestBed.configureTestingModule({
27+
imports: [
28+
MatDialogModule,
29+
NoopAnimationsModule,
30+
ComponentWithChildViewContainer,
31+
PizzaMsg,
32+
DirectiveWithViewContainer,
33+
],
34+
providers: [
35+
provideZoneChangeDetection(),
36+
{provide: Location, useClass: SpyLocation},
37+
{
38+
provide: ScrollDispatcher,
39+
useFactory: () => ({
40+
scrolled: () => scrolledSubject,
41+
register: () => {},
42+
deregister: () => {},
43+
}),
44+
},
45+
],
46+
});
47+
48+
TestBed.compileComponents();
49+
}));
50+
51+
beforeEach(inject([MatDialog], (d: MatDialog) => {
52+
dialog = d;
53+
}));
54+
55+
beforeEach(() => {
56+
viewContainerFixture = TestBed.createComponent(ComponentWithChildViewContainer);
57+
58+
viewContainerFixture.detectChanges();
59+
testViewContainerRef = viewContainerFixture.componentInstance.childViewContainer;
60+
});
61+
62+
it('should invoke the afterClosed callback inside the NgZone', fakeAsync(
63+
inject([NgZone], (zone: NgZone) => {
64+
const dialogRef = dialog.open(PizzaMsg, {viewContainerRef: testViewContainerRef});
65+
const afterCloseCallback = jasmine.createSpy('afterClose callback');
66+
67+
dialogRef.afterClosed().subscribe(() => {
68+
afterCloseCallback(NgZone.isInAngularZone());
69+
});
70+
zone.run(() => {
71+
dialogRef.close();
72+
viewContainerFixture.detectChanges();
73+
flush();
74+
});
75+
76+
expect(afterCloseCallback).toHaveBeenCalledWith(true);
77+
}),
78+
));
79+
});
80+
81+
@Directive({
82+
selector: 'dir-with-view-container',
83+
standalone: true,
84+
})
85+
class DirectiveWithViewContainer {
86+
constructor(public viewContainerRef: ViewContainerRef) {}
87+
}
88+
89+
@Component({
90+
selector: 'arbitrary-component',
91+
template: `@if (showChildView) {<dir-with-view-container></dir-with-view-container>}`,
92+
standalone: true,
93+
imports: [DirectiveWithViewContainer],
94+
})
95+
class ComponentWithChildViewContainer {
96+
showChildView = true;
97+
98+
@ViewChild(DirectiveWithViewContainer) childWithViewContainer: DirectiveWithViewContainer;
99+
100+
get childViewContainer() {
101+
return this.childWithViewContainer.viewContainerRef;
102+
}
103+
}
104+
105+
/** Simple component for testing ComponentPortal. */
106+
@Component({
107+
template: '<p>Pizza</p> <input> <button>Close</button>',
108+
standalone: true,
109+
})
110+
class PizzaMsg {
111+
constructor(
112+
public dialogRef: MatDialogRef<PizzaMsg>,
113+
public dialogInjector: Injector,
114+
public directionality: Directionality,
115+
) {}
116+
}

src/material/expansion/accordion.spec.ts

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,20 @@
1-
import {waitForAsync, TestBed, inject} from '@angular/core/testing';
1+
import {FocusMonitor} from '@angular/cdk/a11y';
2+
import {DOWN_ARROW, END, HOME, UP_ARROW} from '@angular/cdk/keycodes';
23
import {
3-
Component,
4-
ViewChild,
5-
QueryList,
6-
ViewChildren,
7-
provideZoneChangeDetection,
8-
} from '@angular/core';
4+
createKeyboardEvent,
5+
dispatchEvent,
6+
dispatchKeyboardEvent,
7+
} from '@angular/cdk/testing/private';
8+
import {Component, QueryList, ViewChild, ViewChildren} from '@angular/core';
9+
import {TestBed, inject, waitForAsync} from '@angular/core/testing';
910
import {By} from '@angular/platform-browser';
1011
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
1112
import {
12-
MatExpansionModule,
1313
MatAccordion,
14+
MatExpansionModule,
1415
MatExpansionPanel,
1516
MatExpansionPanelHeader,
1617
} from './index';
17-
import {
18-
dispatchKeyboardEvent,
19-
createKeyboardEvent,
20-
dispatchEvent,
21-
} from '@angular/cdk/testing/private';
22-
import {DOWN_ARROW, UP_ARROW, HOME, END} from '@angular/cdk/keycodes';
23-
import {FocusMonitor} from '@angular/cdk/a11y';
2418

2519
describe('MatAccordion', () => {
2620
let focusMonitor: FocusMonitor;
@@ -36,7 +30,6 @@ describe('MatAccordion', () => {
3630
SetOfItems,
3731
NestedAccordions,
3832
],
39-
providers: [provideZoneChangeDetection()],
4033
});
4134
TestBed.compileComponents();
4235

@@ -66,6 +59,7 @@ describe('MatAccordion', () => {
6659
it('should allow multiple items to be expanded simultaneously', () => {
6760
const fixture = TestBed.createComponent(SetOfItems);
6861
fixture.componentInstance.multi = true;
62+
fixture.changeDetectorRef.markForCheck();
6963
fixture.detectChanges();
7064

7165
const panels = fixture.debugElement.queryAll(By.css('.mat-expansion-panel'));
@@ -86,6 +80,7 @@ describe('MatAccordion', () => {
8680

8781
fixture.componentInstance.multi = true;
8882
fixture.componentInstance.panels.toArray()[1].expanded = true;
83+
fixture.changeDetectorRef.markForCheck();
8984
fixture.detectChanges();
9085
expect(panels[0].classes['mat-expanded']).toBeFalsy();
9186
expect(panels[1].classes['mat-expanded']).toBeTruthy();
@@ -109,6 +104,7 @@ describe('MatAccordion', () => {
109104

110105
fixture.componentInstance.multi = true;
111106
fixture.componentInstance.panels.toArray()[1].disabled = true;
107+
fixture.changeDetectorRef.markForCheck();
112108
fixture.detectChanges();
113109
fixture.componentInstance.accordion.openAll();
114110
fixture.detectChanges();
@@ -142,6 +138,7 @@ describe('MatAccordion', () => {
142138
.toBeTruthy();
143139

144140
fixture.componentInstance.hideToggle = true;
141+
fixture.changeDetectorRef.markForCheck();
145142
fixture.detectChanges();
146143

147144
expect(panel.nativeElement.querySelector('.mat-expansion-indicator'))
@@ -160,6 +157,7 @@ describe('MatAccordion', () => {
160157
.toBeTruthy();
161158

162159
fixture.componentInstance.togglePosition = 'before';
160+
fixture.changeDetectorRef.markForCheck();
163161
fixture.detectChanges();
164162

165163
expect(panel.nativeElement.querySelector('.mat-expansion-toggle-indicator-before'))
@@ -231,6 +229,7 @@ describe('MatAccordion', () => {
231229
focusMonitor.focusVia(headerElements[0].nativeElement, 'keyboard');
232230
headers.forEach(header => spyOn(header, 'focus'));
233231
panels[1].disabled = true;
232+
fixture.changeDetectorRef.markForCheck();
234233
fixture.detectChanges();
235234

236235
dispatchKeyboardEvent(headerElements[0].nativeElement, 'keydown', DOWN_ARROW);

0 commit comments

Comments
 (0)