Skip to content

Commit dc56ba6

Browse files
authored
test: Convert some material tests to zoneless (angular#29311)
1 parent f67ffa5 commit dc56ba6

File tree

7 files changed

+155
-131
lines changed

7 files changed

+155
-131
lines changed

src/material/stepper/stepper.spec.ts

Lines changed: 59 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ import {
3131
ViewChild,
3232
ViewChildren,
3333
ViewEncapsulation,
34-
provideZoneChangeDetection,
34+
inject,
3535
signal,
3636
} from '@angular/core';
37-
import {ComponentFixture, TestBed, fakeAsync, flush, inject} from '@angular/core/testing';
37+
import {ComponentFixture, TestBed, fakeAsync, flush} from '@angular/core/testing';
3838
import {
3939
AbstractControl,
4040
AsyncValidatorFn,
@@ -480,23 +480,20 @@ describe('MatStepper', () => {
480480
i18nFixture.detectChanges();
481481
});
482482

483-
it('should re-render when the i18n labels change', inject(
484-
[MatStepperIntl],
485-
(intl: MatStepperIntl) => {
486-
const header = i18nFixture.debugElement.queryAll(By.css('mat-step-header'))[2]
487-
.nativeElement;
488-
const optionalLabel = header.querySelector('.mat-step-optional');
483+
it('should re-render when the i18n labels change', () => {
484+
const intl = TestBed.inject(MatStepperIntl);
485+
const header = i18nFixture.debugElement.queryAll(By.css('mat-step-header'))[2].nativeElement;
486+
const optionalLabel = header.querySelector('.mat-step-optional');
489487

490-
expect(optionalLabel).toBeTruthy();
491-
expect(optionalLabel.textContent).toBe('Optional');
488+
expect(optionalLabel).toBeTruthy();
489+
expect(optionalLabel.textContent).toBe('Optional');
492490

493-
intl.optionalLabel = 'Valgfri';
494-
intl.changes.next();
495-
i18nFixture.detectChanges();
491+
intl.optionalLabel = 'Valgfri';
492+
intl.changes.next();
493+
i18nFixture.detectChanges();
496494

497-
expect(optionalLabel.textContent).toBe('Valgfri');
498-
},
499-
));
495+
expect(optionalLabel.textContent).toBe('Valgfri');
496+
});
500497
});
501498

502499
describe('basic stepper with completed label change', () => {
@@ -507,29 +504,27 @@ describe('MatStepper', () => {
507504
fixture.detectChanges();
508505
});
509506

510-
it('should re-render when the completed labels change', inject(
511-
[MatStepperIntl],
512-
(intl: MatStepperIntl) => {
513-
const stepperDebugElement = fixture.debugElement.query(By.directive(MatStepper))!;
514-
const stepperComponent: MatStepper = stepperDebugElement.componentInstance;
507+
it('should re-render when the completed labels change', () => {
508+
const intl = TestBed.inject(MatStepperIntl);
509+
const stepperDebugElement = fixture.debugElement.query(By.directive(MatStepper))!;
510+
const stepperComponent: MatStepper = stepperDebugElement.componentInstance;
515511

516-
stepperComponent.steps.toArray()[0].editable = false;
517-
stepperComponent.next();
518-
fixture.detectChanges();
512+
stepperComponent.steps.toArray()[0].editable = false;
513+
stepperComponent.next();
514+
fixture.detectChanges();
519515

520-
const header = stepperDebugElement.nativeElement.querySelector('mat-step-header');
521-
const completedLabel = header.querySelector('.cdk-visually-hidden');
516+
const header = stepperDebugElement.nativeElement.querySelector('mat-step-header');
517+
const completedLabel = header.querySelector('.cdk-visually-hidden');
522518

523-
expect(completedLabel).toBeTruthy();
524-
expect(completedLabel.textContent).toBe('Completed');
519+
expect(completedLabel).toBeTruthy();
520+
expect(completedLabel.textContent).toBe('Completed');
525521

526-
intl.completedLabel = 'Completada';
527-
intl.changes.next();
528-
fixture.detectChanges();
522+
intl.completedLabel = 'Completada';
523+
intl.changes.next();
524+
fixture.detectChanges();
529525

530-
expect(completedLabel.textContent).toBe('Completada');
531-
},
532-
));
526+
expect(completedLabel.textContent).toBe('Completada');
527+
});
533528
});
534529

535530
describe('basic stepper with editable label change', () => {
@@ -540,29 +535,27 @@ describe('MatStepper', () => {
540535
fixture.detectChanges();
541536
});
542537

543-
it('should re-render when the editable label changes', inject(
544-
[MatStepperIntl],
545-
(intl: MatStepperIntl) => {
546-
const stepperDebugElement = fixture.debugElement.query(By.directive(MatStepper))!;
547-
const stepperComponent: MatStepper = stepperDebugElement.componentInstance;
538+
it('should re-render when the editable label changes', () => {
539+
const intl = TestBed.inject(MatStepperIntl);
540+
const stepperDebugElement = fixture.debugElement.query(By.directive(MatStepper))!;
541+
const stepperComponent: MatStepper = stepperDebugElement.componentInstance;
548542

549-
stepperComponent.steps.toArray()[0].editable = true;
550-
stepperComponent.next();
551-
fixture.detectChanges();
543+
stepperComponent.steps.toArray()[0].editable = true;
544+
stepperComponent.next();
545+
fixture.detectChanges();
552546

553-
const header = stepperDebugElement.nativeElement.querySelector('mat-step-header');
554-
const editableLabel = header.querySelector('.cdk-visually-hidden');
547+
const header = stepperDebugElement.nativeElement.querySelector('mat-step-header');
548+
const editableLabel = header.querySelector('.cdk-visually-hidden');
555549

556-
expect(editableLabel).toBeTruthy();
557-
expect(editableLabel.textContent).toBe('Editable');
550+
expect(editableLabel).toBeTruthy();
551+
expect(editableLabel.textContent).toBe('Editable');
558552

559-
intl.editableLabel = 'Modificabile';
560-
intl.changes.next();
561-
fixture.detectChanges();
553+
intl.editableLabel = 'Modificabile';
554+
intl.changes.next();
555+
fixture.detectChanges();
562556

563-
expect(editableLabel.textContent).toBe('Modificabile');
564-
},
565-
));
557+
expect(editableLabel.textContent).toBe('Modificabile');
558+
});
566559
});
567560

568561
describe('icon overrides', () => {
@@ -647,7 +640,7 @@ describe('MatStepper', () => {
647640
let stepperComponent: MatStepper;
648641

649642
beforeEach(() => {
650-
fixture = createComponent(LinearMatVerticalStepperApp);
643+
fixture = createComponent(LinearMatVerticalStepperApp, [], [], undefined, []);
651644
fixture.detectChanges();
652645

653646
testComponent = fixture.componentInstance;
@@ -1792,15 +1785,12 @@ function createComponent<T>(
17921785
providers: Provider[] = [],
17931786
imports: any[] = [],
17941787
encapsulation?: ViewEncapsulation,
1788+
declarations = [component],
17951789
): ComponentFixture<T> {
17961790
TestBed.configureTestingModule({
17971791
imports: [MatStepperModule, NoopAnimationsModule, ReactiveFormsModule, ...imports],
1798-
providers: [
1799-
provideZoneChangeDetection(),
1800-
{provide: Directionality, useFactory: () => dir},
1801-
...providers,
1802-
],
1803-
declarations: [component],
1792+
providers: [{provide: Directionality, useFactory: () => dir}, ...providers],
1793+
declarations,
18041794
});
18051795

18061796
if (encapsulation != null) {
@@ -1843,12 +1833,12 @@ function createComponent<T>(
18431833
`,
18441834
})
18451835
class MatHorizontalStepperWithErrorsApp {
1836+
private readonly _formBuilder = inject(FormBuilder);
1837+
18461838
formGroup = this._formBuilder.group({
18471839
firstNameCtrl: ['', Validators.required],
18481840
lastNameCtrl: ['', Validators.required],
18491841
});
1850-
1851-
constructor(private _formBuilder: FormBuilder) {}
18521842
}
18531843

18541844
@Component({
@@ -1931,15 +1921,16 @@ class SimpleMatVerticalStepperApp {
19311921
}
19321922

19331923
@Component({
1924+
standalone: true,
19341925
template: `
19351926
<mat-stepper orientation="vertical" linear>
19361927
<mat-step [stepControl]="oneGroup">
19371928
<form [formGroup]="oneGroup">
19381929
<ng-template matStepLabel>Step one</ng-template>
19391930
<input formControlName="oneCtrl" required>
19401931
<div>
1941-
<button mat-button matStepperPrevious>Back</button>
1942-
<button mat-button matStepperNext>Next</button>
1932+
<button matStepperPrevious>Back</button>
1933+
<button matStepperNext>Next</button>
19431934
</div>
19441935
</form>
19451936
</mat-step>
@@ -1948,8 +1939,8 @@ class SimpleMatVerticalStepperApp {
19481939
<ng-template matStepLabel>Step two</ng-template>
19491940
<input formControlName="twoCtrl" required>
19501941
<div>
1951-
<button mat-button matStepperPrevious>Back</button>
1952-
<button mat-button matStepperNext>Next</button>
1942+
<button matStepperPrevious>Back</button>
1943+
<button matStepperNext>Next</button>
19531944
</div>
19541945
</form>
19551946
</mat-step>
@@ -1958,8 +1949,8 @@ class SimpleMatVerticalStepperApp {
19581949
<ng-template matStepLabel>Step two</ng-template>
19591950
<input formControlName="threeCtrl">
19601951
<div>
1961-
<button mat-button matStepperPrevious>Back</button>
1962-
<button mat-button matStepperNext>Next</button>
1952+
<button matStepperPrevious>Back</button>
1953+
<button matStepperNext>Next</button>
19631954
</div>
19641955
</form>
19651956
</mat-step>
@@ -1968,6 +1959,7 @@ class SimpleMatVerticalStepperApp {
19681959
</mat-step>
19691960
</mat-stepper>
19701961
`,
1962+
imports: [ReactiveFormsModule, MatStepperModule],
19711963
})
19721964
class LinearMatVerticalStepperApp {
19731965
validationTrigger = new Subject<void>();

src/material/tabs/tab-body.spec.ts

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,26 @@
11
import {Direction, Directionality} from '@angular/cdk/bidi';
22
import {PortalModule, TemplatePortal} from '@angular/cdk/portal';
3+
import {CdkScrollable, ScrollingModule} from '@angular/cdk/scrolling';
34
import {CommonModule} from '@angular/common';
45
import {
5-
AfterContentInit,
6+
AfterViewInit,
67
Component,
78
TemplateRef,
89
ViewChild,
910
ViewContainerRef,
10-
provideZoneChangeDetection,
11+
inject,
12+
signal,
1113
} from '@angular/core';
12-
import {waitForAsync, ComponentFixture, TestBed} from '@angular/core/testing';
14+
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
1315
import {MatRippleModule} from '@angular/material/core';
14-
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
15-
import {CdkScrollable, ScrollingModule} from '@angular/cdk/scrolling';
16-
import {MatTabBody, MatTabBodyPortal} from './tab-body';
1716
import {By} from '@angular/platform-browser';
17+
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
1818
import {Subject} from 'rxjs';
19+
import {MatTabBody, MatTabBodyPortal} from './tab-body';
1920

2021
describe('MDC-based MatTabBody', () => {
2122
let dir: Direction = 'ltr';
2223
let dirChange: Subject<Direction> = new Subject<Direction>();
23-
beforeEach(() => {
24-
TestBed.configureTestingModule({
25-
providers: [provideZoneChangeDetection()],
26-
});
27-
});
2824

2925
beforeEach(waitForAsync(() => {
3026
dir = 'ltr';
@@ -125,20 +121,23 @@ describe('MDC-based MatTabBody', () => {
125121

126122
it('to be left position with negative position', () => {
127123
fixture.componentInstance.position = -1;
124+
fixture.changeDetectorRef.markForCheck();
128125
fixture.detectChanges();
129126

130127
expect(fixture.componentInstance.tabBody._position).toBe('left');
131128
});
132129

133130
it('to be center position with zero position', () => {
134131
fixture.componentInstance.position = 0;
132+
fixture.changeDetectorRef.markForCheck();
135133
fixture.detectChanges();
136134

137135
expect(fixture.componentInstance.tabBody._position).toBe('center');
138136
});
139137

140138
it('to be left position with positive position', () => {
141139
fixture.componentInstance.position = 1;
140+
fixture.changeDetectorRef.markForCheck();
142141
fixture.detectChanges();
143142

144143
expect(fixture.componentInstance.tabBody._position).toBe('right');
@@ -156,20 +155,23 @@ describe('MDC-based MatTabBody', () => {
156155

157156
it('to be right position with negative position', () => {
158157
fixture.componentInstance.position = -1;
158+
fixture.changeDetectorRef.markForCheck();
159159
fixture.detectChanges();
160160

161161
expect(fixture.componentInstance.tabBody._position).toBe('right');
162162
});
163163

164164
it('to be center position with zero position', () => {
165165
fixture.componentInstance.position = 0;
166+
fixture.changeDetectorRef.markForCheck();
166167
fixture.detectChanges();
167168

168169
expect(fixture.componentInstance.tabBody._position).toBe('center');
169170
});
170171

171172
it('to be left position with positive position', () => {
172173
fixture.componentInstance.position = 1;
174+
fixture.changeDetectorRef.markForCheck();
173175
fixture.detectChanges();
174176

175177
expect(fixture.componentInstance.tabBody._position).toBe('left');
@@ -218,22 +220,22 @@ describe('MDC-based MatTabBody', () => {
218220
@Component({
219221
template: `
220222
<ng-template>Tab Body Content</ng-template>
221-
<mat-tab-body [content]="content" [position]="position" [origin]="origin"></mat-tab-body>
223+
<mat-tab-body [content]="content()" [position]="position" [origin]="origin"></mat-tab-body>
222224
`,
223225
standalone: true,
224226
imports: [CommonModule, PortalModule, MatRippleModule, MatTabBody],
225227
})
226-
class SimpleTabBodyApp implements AfterContentInit {
227-
content: TemplatePortal;
228+
class SimpleTabBodyApp implements AfterViewInit {
229+
content = signal<TemplatePortal | undefined>(undefined);
228230
position: number;
229231
origin: number | null;
230232

231233
@ViewChild(MatTabBody) tabBody: MatTabBody;
232234
@ViewChild(TemplateRef) template: TemplateRef<any>;
233235

234-
constructor(private _viewContainerRef: ViewContainerRef) {}
236+
private readonly _viewContainerRef = inject(ViewContainerRef);
235237

236-
ngAfterContentInit() {
237-
this.content = new TemplatePortal(this.template, this._viewContainerRef);
238+
ngAfterViewInit() {
239+
this.content.set(new TemplatePortal(this.template, this._viewContainerRef));
238240
}
239241
}

src/material/tabs/tab-body.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
import {AnimationEvent} from '@angular/animations';
10+
import {Direction, Directionality} from '@angular/cdk/bidi';
11+
import {CdkPortalOutlet, TemplatePortal} from '@angular/cdk/portal';
12+
import {CdkScrollable} from '@angular/cdk/scrolling';
13+
import {DOCUMENT} from '@angular/common';
914
import {
1015
ChangeDetectionStrategy,
1116
ChangeDetectorRef,
@@ -25,14 +30,9 @@ import {
2530
ViewContainerRef,
2631
ViewEncapsulation,
2732
} from '@angular/core';
28-
import {CdkPortalOutlet, TemplatePortal} from '@angular/cdk/portal';
29-
import {Direction, Directionality} from '@angular/cdk/bidi';
30-
import {DOCUMENT} from '@angular/common';
3133
import {Subject, Subscription} from 'rxjs';
3234
import {distinctUntilChanged, startWith} from 'rxjs/operators';
33-
import {AnimationEvent} from '@angular/animations';
3435
import {matTabsAnimations} from './tabs-animations';
35-
import {CdkScrollable} from '@angular/cdk/scrolling';
3636

3737
/**
3838
* The portal host directive for the contents of the tab.
@@ -64,7 +64,7 @@ export class MatTabBodyPortal extends CdkPortalOutlet implements OnInit, OnDestr
6464
this._centeringSub = this._host._beforeCentering
6565
.pipe(startWith(this._host._isCenterPosition(this._host._position)))
6666
.subscribe((isCentering: boolean) => {
67-
if (isCentering && !this.hasAttached()) {
67+
if (this._host._content && isCentering && !this.hasAttached()) {
6868
this.attach(this._host._content);
6969
}
7070
});

0 commit comments

Comments
 (0)