Skip to content

Commit 23914be

Browse files
authored
refactor(material/button-toggle): switch tests away from fakeAsync (#33302)
Reworks the button toggle tests not to depend on `fakeAsync`.
1 parent 01cc137 commit 23914be

1 file changed

Lines changed: 35 additions & 63 deletions

File tree

‎src/material/button-toggle/button-toggle.spec.ts‎

Lines changed: 35 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,7 @@ import {
88
ViewChildren,
99
ChangeDetectionStrategy,
1010
} from '@angular/core';
11-
import {
12-
ComponentFixture,
13-
TestBed,
14-
fakeAsync,
15-
flush,
16-
tick,
17-
waitForAsync,
18-
} from '@angular/core/testing';
11+
import {ComponentFixture, TestBed} from '@angular/core/testing';
1912
import {FormControl, FormsModule, NgModel, ReactiveFormsModule} from '@angular/forms';
2013
import {By} from '@angular/platform-browser';
2114
import {
@@ -33,15 +26,15 @@ describe('MatButtonToggle with forms', () => {
3326
let groupInstance: MatButtonToggleGroup;
3427
let testComponent: ButtonToggleGroupWithFormControl;
3528

36-
beforeEach(fakeAsync(() => {
29+
beforeEach(() => {
3730
fixture = TestBed.createComponent(ButtonToggleGroupWithFormControl);
3831
fixture.detectChanges();
3932

4033
testComponent = fixture.debugElement.componentInstance;
4134

4235
groupDebugElement = fixture.debugElement.query(By.directive(MatButtonToggleGroup))!;
4336
groupInstance = groupDebugElement.injector.get<MatButtonToggleGroup>(MatButtonToggleGroup);
44-
}));
37+
});
4538

4639
it('should toggle the disabled state', () => {
4740
testComponent.control.disable();
@@ -99,17 +92,16 @@ describe('MatButtonToggle with forms', () => {
9992
);
10093
});
10194

102-
it('should update the model before firing change event', fakeAsync(() => {
95+
it('should update the model before firing change event', () => {
10396
expect(testComponent.modelValue).toBeUndefined();
10497
expect(testComponent.lastEvent).toBeUndefined();
10598

10699
innerButtons[0].click();
107100
fixture.detectChanges();
108101

109-
tick();
110102
expect(testComponent.modelValue).toBe('red');
111103
expect(testComponent.lastEvent.value).toBe('red');
112-
}));
104+
});
113105

114106
it('should set individual radio names based on the group name', () => {
115107
expect(groupInstance.name).toBeTruthy();
@@ -166,36 +158,32 @@ describe('MatButtonToggle with forms', () => {
166158
expect(selected.value).toBe(groupInstance.value);
167159
});
168160

169-
it('should have the correct FormControl state initially and after interaction', fakeAsync(() => {
161+
it('should have the correct FormControl state initially and after interaction', () => {
170162
expect(groupNgModel.valid).toBe(true);
171163
expect(groupNgModel.pristine).toBe(true);
172164
expect(groupNgModel.touched).toBe(false);
173165

174166
buttonToggleInstances[1].checked = true;
175167
fixture.detectChanges();
176-
tick();
177168

178169
expect(groupNgModel.valid).toBe(true);
179170
expect(groupNgModel.pristine).toBe(true);
180171
expect(groupNgModel.touched).toBe(false);
181172

182173
innerButtons[2].click();
183174
fixture.detectChanges();
184-
tick();
185175

186176
expect(groupNgModel.valid).toBe(true);
187177
expect(groupNgModel.pristine).toBe(false);
188178
expect(groupNgModel.touched).toBe(true);
189-
}));
179+
});
190180

191-
it('should update the ngModel value when selecting a button toggle', fakeAsync(() => {
181+
it('should update the ngModel value when selecting a button toggle', () => {
192182
innerButtons[1].click();
193183
fixture.detectChanges();
194184

195-
tick();
196-
197185
expect(testComponent.modelValue).toBe('green');
198-
}));
186+
});
199187

200188
it('should show a ripple on label click', () => {
201189
const groupElement = groupDebugElement.nativeElement;
@@ -226,7 +214,7 @@ describe('MatButtonToggle with forms', () => {
226214
it(
227215
'should maintain the selected value when swapping out the list of toggles with one ' +
228216
'that still contains the value',
229-
fakeAsync(() => {
217+
() => {
230218
expect(buttonToggleInstances[0].checked).toBe(false);
231219
expect(fixture.componentInstance.modelValue).toBeFalsy();
232220
expect(groupInstance.value).toBeFalsy();
@@ -239,19 +227,18 @@ describe('MatButtonToggle with forms', () => {
239227

240228
fixture.componentInstance.options = [...fixture.componentInstance.options];
241229
fixture.detectChanges();
242-
tick();
243230
fixture.detectChanges();
244231

245232
buttonToggleDebugElements = fixture.debugElement.queryAll(By.directive(MatButtonToggle));
246233
buttonToggleInstances = buttonToggleDebugElements.map(debugEl => debugEl.componentInstance);
247234

248235
expect(buttonToggleInstances[0].checked).toBe(true);
249236
expect(groupInstance.value).toBe('red');
250-
}),
237+
},
251238
);
252239
});
253240

254-
it('should be able to pick up toggles that are not direct descendants', fakeAsync(() => {
241+
it('should be able to pick up toggles that are not direct descendants', () => {
255242
const fixture = TestBed.createComponent(ButtonToggleGroupWithIndirectDescendantToggles);
256243
fixture.detectChanges();
257244

@@ -262,12 +249,11 @@ describe('MatButtonToggle with forms', () => {
262249

263250
button.click();
264251
fixture.detectChanges();
265-
tick();
266252

267253
expect(groupInstance.value).toBe('red');
268254
expect(fixture.componentInstance.control.value).toBe('red');
269255
expect(groupInstance._buttonToggles.length).toBe(3);
270-
}));
256+
});
271257

272258
it('should preserve the selection if the pre-selected option is removed and re-added', () => {
273259
const fixture = TestBed.createComponent(ButtonToggleGroupWithFormControlAndDynamicButtons);
@@ -312,17 +298,16 @@ describe('MatButtonToggle with forms', () => {
312298
expect(instance.toggles.map(t => t.checked)).toEqual([true, false, false]);
313299
});
314300

315-
it('should set the initial tabindex when using ngModel with a static list of options where none match the value', fakeAsync(() => {
301+
it('should set the initial tabindex when using ngModel with a static list of options where none match the value', () => {
316302
const fixture = TestBed.createComponent(ButtonToggleGroupWithNgModelAndStaticOptions);
317303
fixture.detectChanges();
318-
tick();
319304
const indexes = Array.from(
320305
fixture.nativeElement.querySelectorAll('button'),
321306
(button: HTMLElement) => button.getAttribute('tabindex'),
322307
);
323308

324309
expect(indexes).toEqual(['0', '-1', '-1']);
325-
}));
310+
});
326311
});
327312

328313
describe('MatButtonToggle without forms', () => {
@@ -494,41 +479,37 @@ describe('MatButtonToggle without forms', () => {
494479
expect(groupNativeElement.classList).toContain('mat-button-toggle-vertical');
495480
});
496481

497-
it('should emit a change event from button toggles', fakeAsync(() => {
482+
it('should emit a change event from button toggles', () => {
498483
expect(buttonToggleInstances[0].checked).toBe(false);
499484

500485
const changeSpy = jasmine.createSpy('button-toggle change listener');
501486
buttonToggleInstances[0].change.subscribe(changeSpy);
502487

503488
innerButtons[0].click();
504489
fixture.detectChanges();
505-
tick();
506490
expect(changeSpy).toHaveBeenCalledTimes(1);
507491

508492
innerButtons[0].click();
509493
fixture.detectChanges();
510-
tick();
511494

512495
// Always emit change event when button toggle is clicked
513496
expect(changeSpy).toHaveBeenCalledTimes(2);
514-
}));
497+
});
515498

516-
it('should emit a change event from the button toggle group', fakeAsync(() => {
499+
it('should emit a change event from the button toggle group', () => {
517500
expect(groupInstance.value).toBeFalsy();
518501

519502
const changeSpy = jasmine.createSpy('button-toggle-group change listener');
520503
groupInstance.change.subscribe(changeSpy);
521504

522505
innerButtons[0].click();
523506
fixture.detectChanges();
524-
tick();
525507
expect(changeSpy).toHaveBeenCalled();
526508

527509
innerButtons[1].click();
528510
fixture.detectChanges();
529-
tick();
530511
expect(changeSpy).toHaveBeenCalledTimes(2);
531-
}));
512+
});
532513

533514
it('should update the group and button toggles when updating the group value', () => {
534515
expect(groupInstance.value).toBeFalsy();
@@ -562,7 +543,7 @@ describe('MatButtonToggle without forms', () => {
562543
expect(buttonToggleInstances.every(toggle => !toggle.checked)).toBe(true);
563544
});
564545

565-
it('should update the model if a selected toggle is removed', fakeAsync(() => {
546+
it('should update the model if a selected toggle is removed', () => {
566547
expect(groupInstance.value).toBeFalsy();
567548
innerButtons[0].click();
568549
fixture.detectChanges();
@@ -573,11 +554,10 @@ describe('MatButtonToggle without forms', () => {
573554
testComponent.renderFirstToggle = false;
574555
fixture.changeDetectorRef.markForCheck();
575556
fixture.detectChanges();
576-
tick();
577557

578558
expect(groupInstance.value).toBeFalsy();
579559
expect(groupInstance.selected).toBeFalsy();
580-
}));
560+
});
581561

582562
it('should show checkmark indicator by default', () => {
583563
innerButtons[0].click();
@@ -596,12 +576,12 @@ describe('MatButtonToggle without forms', () => {
596576
let UP_ARROW_EVENT: KeyboardEvent;
597577
let DOWN_ARROW_EVENT: KeyboardEvent;
598578

599-
beforeEach(waitForAsync(async () => {
579+
beforeEach(() => {
600580
LEFT_ARROW_EVENT = createKeyboardEvent('keydown', LEFT_ARROW);
601581
RIGHT_ARROW_EVENT = createKeyboardEvent('keydown', RIGHT_ARROW);
602582
UP_ARROW_EVENT = createKeyboardEvent('keydown', UP_ARROW);
603583
DOWN_ARROW_EVENT = createKeyboardEvent('keydown', DOWN_ARROW);
604-
}));
584+
});
605585

606586
it('should not change selection on arrow key press with a modifier key', () => {
607587
expect(groupInstance.value).toBeFalsy();
@@ -709,7 +689,7 @@ describe('MatButtonToggle without forms', () => {
709689
let buttonToggleInstances: MatButtonToggle[];
710690
let testComponent: ButtonTogglesInsideButtonToggleGroupMultiple;
711691

712-
beforeEach(fakeAsync(() => {
692+
beforeEach(() => {
713693
fixture = TestBed.createComponent(ButtonTogglesInsideButtonToggleGroupMultiple);
714694
fixture.detectChanges();
715695

@@ -725,7 +705,7 @@ describe('MatButtonToggle without forms', () => {
725705
.queryAll(By.css('button'))
726706
.map(debugEl => debugEl.nativeElement);
727707
buttonToggleInstances = buttonToggleDebugElements.map(debugEl => debugEl.componentInstance);
728-
}));
708+
});
729709

730710
it('should disable click interactions when the group is disabled', () => {
731711
testComponent.isGroupDisabled = true;
@@ -786,44 +766,40 @@ describe('MatButtonToggle without forms', () => {
786766
expect(groupNativeElement.classList).toContain('mat-button-toggle-vertical');
787767
});
788768

789-
it('should deselect a button toggle when selected twice', fakeAsync(() => {
769+
it('should deselect a button toggle when selected twice', () => {
790770
buttonToggleLabelElements[0].click();
791771
fixture.detectChanges();
792-
tick();
793772

794773
expect(buttonToggleInstances[0].checked).toBe(true);
795774
expect(groupInstance.value).toEqual(['eggs']);
796775

797776
buttonToggleLabelElements[0].click();
798777
fixture.detectChanges();
799-
tick();
800778

801779
expect(groupInstance.value).toEqual([]);
802780
expect(buttonToggleInstances[0].checked).toBe(false);
803-
}));
781+
});
804782

805-
it('should emit a change event for state changes', fakeAsync(() => {
783+
it('should emit a change event for state changes', () => {
806784
expect(buttonToggleInstances[0].checked).toBe(false);
807785

808786
const changeSpy = jasmine.createSpy('button-toggle change listener');
809787
buttonToggleInstances[0].change.subscribe(changeSpy);
810788

811789
buttonToggleLabelElements[0].click();
812790
fixture.detectChanges();
813-
tick();
814791
expect(changeSpy).toHaveBeenCalled();
815792
expect(groupInstance.value).toEqual(['eggs']);
816793

817794
buttonToggleLabelElements[0].click();
818795
fixture.detectChanges();
819-
tick();
820796
expect(groupInstance.value).toEqual([]);
821797

822798
// The default browser behavior is to emit an event, when the value was set
823799
// to false. That's because the current input type is set to `checkbox` when
824800
// using the multiple mode.
825801
expect(changeSpy).toHaveBeenCalledTimes(2);
826-
}));
802+
});
827803

828804
it('should throw when attempting to assign a non-array value', () => {
829805
expect(() => {
@@ -852,7 +828,7 @@ describe('MatButtonToggle without forms', () => {
852828
let buttonToggleInstance: MatButtonToggle;
853829
let buttonToggleButtonElement: HTMLButtonElement;
854830

855-
beforeEach(fakeAsync(() => {
831+
beforeEach(() => {
856832
fixture = TestBed.createComponent(StandaloneButtonToggle);
857833
fixture.detectChanges();
858834

@@ -865,41 +841,37 @@ describe('MatButtonToggle without forms', () => {
865841
buttonToggleButtonElement = buttonToggleNativeElement.querySelector(
866842
'button',
867843
)! as HTMLButtonElement;
868-
}));
844+
});
869845

870-
it('should toggle when clicked', fakeAsync(() => {
846+
it('should toggle when clicked', () => {
871847
buttonToggleLabelElement.click();
872848
fixture.detectChanges();
873-
flush();
874849

875850
expect(buttonToggleInstance.checked).toBe(true);
876851

877852
buttonToggleLabelElement.click();
878853
fixture.detectChanges();
879-
flush();
880854

881855
expect(buttonToggleInstance.checked).toBe(false);
882-
}));
856+
});
883857

884-
it('should emit a change event for state changes', fakeAsync(() => {
858+
it('should emit a change event for state changes', () => {
885859
expect(buttonToggleInstance.checked).toBe(false);
886860

887861
const changeSpy = jasmine.createSpy('button-toggle change listener');
888862
buttonToggleInstance.change.subscribe(changeSpy);
889863

890864
buttonToggleLabelElement.click();
891865
fixture.detectChanges();
892-
tick();
893866
expect(changeSpy).toHaveBeenCalled();
894867

895868
buttonToggleLabelElement.click();
896869
fixture.detectChanges();
897-
tick();
898870

899871
// The default browser behavior is to emit an event, when the value was set
900872
// to false. That's because the current input type is set to `checkbox`.
901873
expect(changeSpy).toHaveBeenCalledTimes(2);
902-
}));
874+
});
903875

904876
it('should focus on underlying input element when focus() is called', () => {
905877
const nativeButton = buttonToggleDebugElement.query(By.css('button'))!.nativeElement;

0 commit comments

Comments
 (0)