Skip to content

Commit 2851147

Browse files
committed
refactor(material/datepicker): switch tests away from fakeAsync (#32903)
Reworks the datepicker tests not to depend on `fakeAsync`. (cherry picked from commit 0affe5a)
1 parent 2a330b8 commit 2851147

File tree

3 files changed

+322
-535
lines changed

3 files changed

+322
-535
lines changed

src/material/datepicker/date-range-input.spec.ts

Lines changed: 29 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
provideFakeDirectionality,
88
} from '@angular/cdk/testing/private';
99
import {Component, Directive, ElementRef, Provider, Type, ViewChild} from '@angular/core';
10-
import {ComponentFixture, fakeAsync, flush, TestBed, tick} from '@angular/core/testing';
10+
import {ComponentFixture, TestBed} from '@angular/core/testing';
1111
import {
1212
FormControl,
1313
FormGroup,
@@ -183,7 +183,7 @@ describe('MatDateRangeInput', () => {
183183
expect(rangeInput.getAttribute('aria-describedby')).toBe(labelId);
184184
});
185185

186-
it('should preserve aria-describedby set directly in the DOM', fakeAsync(() => {
186+
it('should preserve aria-describedby set directly in the DOM', () => {
187187
const fixture = createComponent(StandardRangePicker);
188188
const rangeInput = fixture.nativeElement.querySelector('.mat-date-range-input');
189189

@@ -193,7 +193,7 @@ describe('MatDateRangeInput', () => {
193193
const hint = fixture.nativeElement.querySelector('.mat-mdc-form-field-hint');
194194

195195
expect(rangeInput.getAttribute('aria-describedby')).toBe(`${hint.getAttribute('id')} custom`);
196-
}));
196+
});
197197

198198
it('should not set aria-labelledby if the form field does not have a label', () => {
199199
const fixture = createComponent(RangePickerNoLabel);
@@ -204,7 +204,7 @@ describe('MatDateRangeInput', () => {
204204
expect(end.nativeElement.getAttribute('aria-labelledby')).toBeFalsy();
205205
});
206206

207-
it('should set aria-labelledby of the overlay to the form field label', fakeAsync(() => {
207+
it('should set aria-labelledby of the overlay to the form field label', () => {
208208
const fixture = createComponent(StandardRangePicker);
209209
fixture.detectChanges();
210210

@@ -214,12 +214,11 @@ describe('MatDateRangeInput', () => {
214214

215215
fixture.componentInstance.rangePicker.open();
216216
fixture.detectChanges();
217-
tick();
218217

219218
const popup = document.querySelector('.cdk-overlay-pane .mat-datepicker-content-container')!;
220219
expect(popup).toBeTruthy();
221220
expect(popup.getAttribute('aria-labelledby')).toBe(label.getAttribute('id'));
222-
}));
221+
});
223222

224223
it('should float the form field label when either input is focused', () => {
225224
const fixture = createComponent(StandardRangePicker);
@@ -262,10 +261,9 @@ describe('MatDateRangeInput', () => {
262261
expect(rangeInput.empty).toBe(false);
263262
});
264263

265-
it('should mark the range controls as invalid if the start value is after the end value', fakeAsync(() => {
264+
it('should mark the range controls as invalid if the start value is after the end value', () => {
266265
const fixture = createComponent(StandardRangePicker);
267266
fixture.detectChanges();
268-
tick();
269267
const {start, end} = fixture.componentInstance.range.controls;
270268

271269
// The default error state matcher only checks if the controls have been touched.
@@ -289,7 +287,7 @@ describe('MatDateRangeInput', () => {
289287
expect(fixture.componentInstance.rangeInput.errorState).toBe(false);
290288
expect(start.errors?.['matStartDateInvalid']).toBeFalsy();
291289
expect(end.errors?.['matEndDateInvalid']).toBeFalsy();
292-
}));
290+
});
293291

294292
it('should pass the minimum date from the range input to the inner inputs', () => {
295293
const fixture = createComponent(StandardRangePicker);
@@ -434,10 +432,9 @@ describe('MatDateRangeInput', () => {
434432
expect(startInput.focus).toHaveBeenCalled();
435433
});
436434

437-
it('should focus the end input when clicking on the form field when start has a value', fakeAsync(() => {
435+
it('should focus the end input when clicking on the form field when start has a value', () => {
438436
const fixture = createComponent(StandardRangePicker);
439437
fixture.detectChanges();
440-
tick();
441438
const endInput = fixture.componentInstance.end.nativeElement;
442439
const formFieldContainer = fixture.nativeElement.querySelector('.mat-mdc-text-field-wrapper');
443440

@@ -448,10 +445,9 @@ describe('MatDateRangeInput', () => {
448445

449446
formFieldContainer.click();
450447
fixture.detectChanges();
451-
tick();
452448

453449
expect(endInput.focus).toHaveBeenCalled();
454-
}));
450+
});
455451

456452
it('should revalidate if a validation field changes', () => {
457453
const fixture = createComponent(StandardRangePicker);
@@ -526,18 +522,16 @@ describe('MatDateRangeInput', () => {
526522
expect(end.nativeElement.getAttribute('max')).toContain('2020');
527523
});
528524

529-
it('should pass the range input value through to the calendar', fakeAsync(() => {
525+
it('should pass the range input value through to the calendar', () => {
530526
const fixture = createComponent(StandardRangePicker);
531527
const {start, end} = fixture.componentInstance.range.controls;
532528
const overlayContainerElement = TestBed.inject(OverlayContainer).getContainerElement();
533529
start.setValue(new Date(2020, 1, 2));
534530
end.setValue(new Date(2020, 1, 5));
535531
fixture.detectChanges();
536-
tick();
537532

538533
fixture.componentInstance.rangePicker.open();
539534
fixture.detectChanges();
540-
tick();
541535

542536
const rangeTexts = Array.from(
543537
overlayContainerElement!.querySelectorAll(
@@ -550,21 +544,19 @@ describe('MatDateRangeInput', () => {
550544
).map(cell => cell.textContent!.trim());
551545

552546
expect(rangeTexts).toEqual(['2', '3', '4', '5']);
553-
}));
547+
});
554548

555-
it("should have aria-desciredby on start and end date cells that point to the <input/>'s accessible name", fakeAsync(() => {
549+
it("should have aria-desciredby on start and end date cells that point to the <input/>'s accessible name", () => {
556550
const fixture = createComponent(StandardRangePicker);
557551
const {start, end} = fixture.componentInstance.range.controls;
558552
const overlayContainerElement = TestBed.inject(OverlayContainer).getContainerElement();
559553

560554
start.setValue(new Date(2020, 1, 2));
561555
end.setValue(new Date(2020, 1, 5));
562556
fixture.detectChanges();
563-
tick();
564557

565558
fixture.componentInstance.rangePicker.open();
566559
fixture.detectChanges();
567-
tick();
568560

569561
const rangeStart = overlayContainerElement!.querySelector('.mat-calendar-body-range-start');
570562
const rangeEnd = overlayContainerElement!.querySelector('.mat-calendar-body-range-end');
@@ -607,9 +599,9 @@ describe('MatDateRangeInput', () => {
607599
.join(' ')
608600
.trim(),
609601
).toEqual('End date');
610-
}));
602+
});
611603

612-
it('should pass the comparison range through to the calendar', fakeAsync(() => {
604+
it('should pass the comparison range through to the calendar', () => {
613605
const fixture = createComponent(StandardRangePicker);
614606
const overlayContainerElement = TestBed.inject(OverlayContainer).getContainerElement();
615607

@@ -625,7 +617,6 @@ describe('MatDateRangeInput', () => {
625617

626618
fixture.componentInstance.rangePicker.open();
627619
fixture.detectChanges();
628-
tick();
629620

630621
const rangeTexts = Array.from(
631622
overlayContainerElement!.querySelectorAll(
@@ -638,31 +629,27 @@ describe('MatDateRangeInput', () => {
638629
).map(cell => cell.textContent!.trim());
639630

640631
expect(rangeTexts).toEqual(['2', '3', '4', '5']);
641-
}));
632+
});
642633

643-
it('should preserve the preselected values when assigning through ngModel', fakeAsync(() => {
634+
it('should preserve the preselected values when assigning through ngModel', () => {
644635
const start = new Date(2020, 1, 2);
645636
const end = new Date(2020, 1, 2);
646637
const fixture = createComponent(RangePickerNgModel);
647638
fixture.componentInstance.start = start;
648639
fixture.componentInstance.end = end;
649640
fixture.changeDetectorRef.markForCheck();
650641
fixture.detectChanges();
651-
tick();
652-
fixture.detectChanges();
653642

654643
expect(fixture.componentInstance.start).toBe(start);
655644
expect(fixture.componentInstance.end).toBe(end);
656-
}));
645+
});
657646

658-
it('should preserve the values when assigning both together through ngModel', fakeAsync(() => {
647+
it('should preserve the values when assigning both together through ngModel', () => {
659648
const assignAndAssert = (start: Date, end: Date) => {
660649
fixture.componentInstance.start = start;
661650
fixture.componentInstance.end = end;
662651
fixture.changeDetectorRef.markForCheck();
663652
fixture.detectChanges();
664-
tick();
665-
fixture.detectChanges();
666653
expect(fixture.componentInstance.start).toBe(start);
667654
expect(fixture.componentInstance.end).toBe(end);
668655
};
@@ -672,42 +659,39 @@ describe('MatDateRangeInput', () => {
672659

673660
assignAndAssert(new Date(2020, 1, 2), new Date(2020, 1, 5));
674661
assignAndAssert(new Date(2020, 2, 2), new Date(2020, 2, 5));
675-
}));
662+
});
676663

677-
it('should not be dirty on init when there is no value', fakeAsync(() => {
664+
it('should not be dirty on init when there is no value', () => {
678665
const fixture = createComponent(RangePickerNgModel);
679666
fixture.detectChanges();
680-
flush();
681667
const {startModel, endModel} = fixture.componentInstance;
682668

683669
expect(startModel.dirty).toBe(false);
684670
expect(startModel.touched).toBe(false);
685671
expect(endModel.dirty).toBe(false);
686672
expect(endModel.touched).toBe(false);
687-
}));
673+
});
688674

689-
it('should not be dirty on init when there is a value', fakeAsync(() => {
675+
it('should not be dirty on init when there is a value', () => {
690676
const fixture = createComponent(RangePickerNgModel);
691677
fixture.componentInstance.start = new Date(2020, 1, 2);
692678
fixture.componentInstance.end = new Date(2020, 2, 2);
693679
fixture.changeDetectorRef.markForCheck();
694680
fixture.detectChanges();
695-
flush();
696681
const {startModel, endModel} = fixture.componentInstance;
697682

698683
expect(startModel.dirty).toBe(false);
699684
expect(startModel.touched).toBe(false);
700685
expect(endModel.dirty).toBe(false);
701686
expect(endModel.touched).toBe(false);
702-
}));
687+
});
703688

704-
it('should mark the input as dirty once the user types in it', fakeAsync(() => {
689+
it('should mark the input as dirty once the user types in it', () => {
705690
const fixture = createComponent(RangePickerNgModel);
706691
fixture.componentInstance.start = new Date(2020, 1, 2);
707692
fixture.componentInstance.end = new Date(2020, 2, 2);
708693
fixture.changeDetectorRef.markForCheck();
709694
fixture.detectChanges();
710-
flush();
711695
const {startModel, endModel, startInput, endInput} = fixture.componentInstance;
712696

713697
expect(startModel.dirty).toBe(false);
@@ -716,26 +700,21 @@ describe('MatDateRangeInput', () => {
716700
endInput.nativeElement.value = '30/12/2020';
717701
dispatchFakeEvent(endInput.nativeElement, 'input');
718702
fixture.detectChanges();
719-
flush();
720-
fixture.detectChanges();
721703

722704
expect(startModel.dirty).toBe(false);
723705
expect(endModel.dirty).toBe(true);
724706

725707
startInput.nativeElement.value = '12/12/2020';
726708
dispatchFakeEvent(startInput.nativeElement, 'input');
727709
fixture.detectChanges();
728-
flush();
729-
fixture.detectChanges();
730710

731711
expect(startModel.dirty).toBe(true);
732712
expect(endModel.dirty).toBe(true);
733-
}));
713+
});
734714

735-
it('should mark both inputs as touched when the range picker is closed', fakeAsync(() => {
715+
it('should mark both inputs as touched when the range picker is closed', () => {
736716
const fixture = createComponent(RangePickerNgModel);
737717
fixture.detectChanges();
738-
flush();
739718
const {startModel, endModel, rangePicker} = fixture.componentInstance;
740719

741720
expect(startModel.dirty).toBe(false);
@@ -745,8 +724,6 @@ describe('MatDateRangeInput', () => {
745724

746725
rangePicker.open();
747726
fixture.detectChanges();
748-
tick();
749-
flush();
750727

751728
expect(startModel.dirty).toBe(false);
752729
expect(startModel.touched).toBe(false);
@@ -755,13 +732,12 @@ describe('MatDateRangeInput', () => {
755732

756733
rangePicker.close();
757734
fixture.detectChanges();
758-
flush();
759735

760736
expect(startModel.dirty).toBe(false);
761737
expect(startModel.touched).toBe(true);
762738
expect(endModel.dirty).toBe(false);
763739
expect(endModel.touched).toBe(true);
764-
}));
740+
});
765741

766742
it('should move focus to the start input when pressing backspace on an empty end input', () => {
767743
const fixture = createComponent(StandardRangePicker);
@@ -1050,24 +1026,21 @@ describe('MatDateRangeInput', () => {
10501026
expect(endInput.errorStateMatcher).toBe(matcher);
10511027
});
10521028

1053-
it('should only update model for input that changed', fakeAsync(() => {
1029+
it('should only update model for input that changed', () => {
10541030
const fixture = createComponent(RangePickerNgModel);
10551031

10561032
fixture.detectChanges();
1057-
tick();
10581033

10591034
expect(fixture.componentInstance.startDateModelChangeCount).toBe(0);
10601035
expect(fixture.componentInstance.endDateModelChangeCount).toBe(0);
10611036

10621037
fixture.componentInstance.rangePicker.open();
10631038
fixture.detectChanges();
1064-
tick();
10651039

10661040
const fromDate = new Date(2020, 0, 1);
10671041
const toDate = new Date(2020, 0, 2);
10681042
fixture.componentInstance.rangePicker.select(fromDate);
10691043
fixture.detectChanges();
1070-
tick();
10711044

10721045
expect(fixture.componentInstance.startDateModelChangeCount)
10731046
.withContext('Start Date set once')
@@ -1078,7 +1051,6 @@ describe('MatDateRangeInput', () => {
10781051

10791052
fixture.componentInstance.rangePicker.select(toDate);
10801053
fixture.detectChanges();
1081-
tick();
10821054

10831055
expect(fixture.componentInstance.startDateModelChangeCount)
10841056
.withContext('Start Date unchanged (set once)')
@@ -1089,13 +1061,11 @@ describe('MatDateRangeInput', () => {
10891061

10901062
fixture.componentInstance.rangePicker.open();
10911063
fixture.detectChanges();
1092-
tick();
10931064

10941065
const fromDate2 = new Date(2021, 0, 1);
10951066
const toDate2 = new Date(2021, 0, 2);
10961067
fixture.componentInstance.rangePicker.select(fromDate2);
10971068
fixture.detectChanges();
1098-
tick();
10991069

11001070
expect(fixture.componentInstance.startDateModelChangeCount)
11011071
.withContext('Start Date set twice')
@@ -1106,15 +1076,14 @@ describe('MatDateRangeInput', () => {
11061076

11071077
fixture.componentInstance.rangePicker.select(toDate2);
11081078
fixture.detectChanges();
1109-
tick();
11101079

11111080
expect(fixture.componentInstance.startDateModelChangeCount)
11121081
.withContext('Start Date unchanged (set twice)')
11131082
.toBe(2);
11141083
expect(fixture.componentInstance.endDateModelChangeCount)
11151084
.withContext('End date set three times')
11161085
.toBe(3);
1117-
}));
1086+
});
11181087

11191088
it('should mark the range picker as required when the entire group has the required validator', () => {
11201089
const fixture = createComponent(StandardRangePicker);

0 commit comments

Comments
 (0)