Skip to content

Commit 96b87fe

Browse files
committed
test(multiple): remove most remaining fakeAsync usages (#33748)
Removes most of the `fakeAsync` usages left in Material. There are still a handful that we need to handle separately. (cherry picked from commit 0411926)
1 parent 9ff8a7c commit 96b87fe

7 files changed

Lines changed: 97 additions & 123 deletions

File tree

src/material/list/selection-list.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,6 +1339,7 @@ describe('MatSelectionList with forms', () => {
13391339
.toBe(false);
13401340
});
13411341

1342+
// TODO: this seems tricky to switch away from `fakeAsync` for some reason.
13421343
it('should remove a selected option from the value on destroy', fakeAsync(() => {
13431344
listOptions[1].selected = true;
13441345
listOptions[2].selected = true;

src/material/menu/context-menu-trigger.spec.ts

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {Component, signal, ViewChild, ChangeDetectionStrategy} from '@angular/core';
2-
import {ComponentFixture, fakeAsync, flush, TestBed} from '@angular/core/testing';
2+
import {ComponentFixture, TestBed} from '@angular/core/testing';
3+
import {MATERIAL_ANIMATIONS} from '../core';
34
import {MatContextMenuTrigger} from './context-menu-trigger';
45
import {MatMenu} from './menu';
56
import {MatMenuItem} from './menu-item';
@@ -8,6 +9,10 @@ import {dispatchFakeEvent, dispatchMouseEvent} from '@angular/cdk/testing/privat
89
describe('context menu trigger', () => {
910
let fixture: ComponentFixture<ContextMenuTest>;
1011

12+
function wait(milliseconds: number) {
13+
return new Promise(resolve => setTimeout(resolve, milliseconds));
14+
}
15+
1116
function getTrigger(): HTMLElement {
1217
return fixture.nativeElement.querySelector('.area');
1318
}
@@ -21,6 +26,9 @@ describe('context menu trigger', () => {
2126
}
2227

2328
beforeEach(() => {
29+
TestBed.configureTestingModule({
30+
providers: [{provide: MATERIAL_ANIMATIONS, useValue: {animationsDisabled: true}}],
31+
});
2432
fixture = TestBed.createComponent(ContextMenuTest);
2533
fixture.detectChanges();
2634
});
@@ -32,16 +40,16 @@ describe('context menu trigger', () => {
3240
expect(getMenu()).toBeTruthy();
3341
});
3442

35-
it('should close the menu when clicking outside the trigger', fakeAsync(() => {
43+
it('should close the menu when clicking outside the trigger', async () => {
3644
dispatchMouseEvent(getTrigger(), 'contextmenu', 10, 10);
3745
fixture.detectChanges();
3846
expect(getMenu()).toBeTruthy();
3947

4048
document.body.click();
4149
fixture.detectChanges();
42-
flush();
50+
await wait(50);
4351
expect(getMenu()).toBe(null);
44-
}));
52+
});
4553

4654
it('should reposition the menu when right-clicking within the area', () => {
4755
dispatchMouseEvent(getTrigger(), 'contextmenu', 10, 10);
@@ -57,43 +65,43 @@ describe('context menu trigger', () => {
5765
expect(menuRect.left).toBe(50);
5866
});
5967

60-
it('should ignore the first auxclick after opening', fakeAsync(() => {
68+
it('should ignore the first auxclick after opening', async () => {
6169
dispatchMouseEvent(getTrigger(), 'contextmenu', 10, 10);
6270
fixture.detectChanges();
6371
expect(getMenu()).toBeTruthy();
6472

6573
dispatchMouseEvent(document.body, 'auxclick');
6674
fixture.detectChanges();
67-
flush();
75+
await wait(50);
6876
expect(getMenu()).toBeTruthy();
6977

7078
dispatchMouseEvent(document.body, 'auxclick');
7179
fixture.detectChanges();
72-
flush();
80+
await wait(50);
7381
expect(getMenu()).toBe(null);
74-
}));
82+
});
7583

76-
it('should close on `contextmenu` events outside the trigger', fakeAsync(() => {
84+
it('should close on `contextmenu` events outside the trigger', async () => {
7785
dispatchMouseEvent(getTrigger(), 'contextmenu', 10, 10);
7886
fixture.detectChanges();
7987
expect(getMenu()).toBeTruthy();
8088

8189
dispatchMouseEvent(document.body, 'contextmenu');
8290
fixture.detectChanges();
83-
flush();
91+
await wait(50);
8492
expect(getMenu()).toBe(null);
85-
}));
93+
});
8694

87-
it('should not close on `contextmenu` events from inside the menu', fakeAsync(() => {
95+
it('should not close on `contextmenu` events from inside the menu', async () => {
8896
dispatchMouseEvent(getTrigger(), 'contextmenu', 10, 10);
8997
fixture.detectChanges();
9098
expect(getMenu()).toBeTruthy();
9199

92100
dispatchMouseEvent(getMenu()!, 'contextmenu');
93101
fixture.detectChanges();
94-
flush();
102+
await wait(50);
95103
expect(getMenu()).toBeTruthy();
96-
}));
104+
});
97105

98106
it('should set aria-controls on the trigger while the menu is open', () => {
99107
expect(getTrigger().getAttribute('aria-controls')).toBe(null);
@@ -124,7 +132,7 @@ describe('context menu trigger', () => {
124132
scroller.remove();
125133
});
126134

127-
it('should emit events when the menu is opened and closed', fakeAsync(() => {
135+
it('should emit events when the menu is opened and closed', async () => {
128136
const {opened, closed} = fixture.componentInstance;
129137
expect(opened).toHaveBeenCalledTimes(0);
130138
expect(closed).toHaveBeenCalledTimes(0);
@@ -136,21 +144,21 @@ describe('context menu trigger', () => {
136144

137145
document.body.click();
138146
fixture.detectChanges();
139-
flush();
147+
await wait(50);
140148
expect(opened).toHaveBeenCalledTimes(1);
141149
expect(closed).toHaveBeenCalledTimes(1);
142-
}));
150+
});
143151

144-
it('should close the menu if the trigger is destroyed', fakeAsync(() => {
152+
it('should close the menu if the trigger is destroyed', async () => {
145153
dispatchMouseEvent(getTrigger(), 'contextmenu', 10, 10);
146154
fixture.detectChanges();
147155
expect(getMenu()).toBeTruthy();
148156

149157
fixture.componentInstance.showTrigger.set(false);
150158
fixture.detectChanges();
151-
flush();
159+
await wait(50);
152160
expect(getMenu()).toBe(null);
153-
}));
161+
});
154162

155163
it('should not open when clicking on a disabled context menu trigger', () => {
156164
fixture.componentInstance.disabled.set(true);

src/material/paginator/paginator.spec.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
inject,
88
ChangeDetectionStrategy,
99
} from '@angular/core';
10-
import {ComponentFixture, TestBed, fakeAsync, tick} from '@angular/core/testing';
10+
import {ComponentFixture, TestBed} from '@angular/core/testing';
1111
import {ThemePalette} from '../core';
1212
import {MatSelect} from '../select';
1313
import {By} from '@angular/platform-browser';
@@ -205,16 +205,15 @@ describe('MatPaginator', () => {
205205
expect(getLastButton(fixture)).withContext('Expected last button to be rendered.').toBeTruthy();
206206
});
207207

208-
it('should mark itself as initialized', fakeAsync(() => {
208+
it('should mark itself as initialized', () => {
209209
const fixture = createComponent(MatPaginatorApp);
210210
const component = fixture.componentInstance;
211211
const paginator = component.paginator;
212212
let isMarkedInitialized = false;
213213
paginator.initialized.subscribe(() => (isMarkedInitialized = true));
214214

215-
tick();
216215
expect(isMarkedInitialized).toBeTruthy();
217-
}));
216+
});
218217

219218
it('should not allow a negative pageSize', () => {
220219
const fixture = createComponent(MatPaginatorApp);

src/material/radio/radio.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {dispatchFakeEvent} from '@angular/cdk/testing/private';
22
import {Component, DebugElement, ViewChild, ChangeDetectionStrategy} from '@angular/core';
3-
import {ComponentFixture, TestBed, fakeAsync, tick, waitForAsync} from '@angular/core/testing';
3+
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
44
import {FormControl, FormsModule, NgModel, ReactiveFormsModule} from '@angular/forms';
55
import {By} from '@angular/platform-browser';
66
import {
@@ -442,8 +442,8 @@ describe('MatRadio', () => {
442442
});
443443

444444
it('should have a focus indicator', () => {
445-
const radioRippleNativeElements = radioNativeElements.map(
446-
element => element.querySelector('.mat-radio-ripple')!,
445+
const radioRippleNativeElements = radioNativeElements.map(element =>
446+
element.querySelector('.mat-radio-ripple')!,
447447
);
448448

449449
expect(
@@ -610,17 +610,17 @@ describe('MatRadio', () => {
610610
expect(groupNgModel.touched).toBe(true);
611611
});
612612

613-
it('should write to the radio button based on ngModel', fakeAsync(() => {
613+
it('should write to the radio button based on ngModel', async () => {
614614
testComponent.modelValue = 'chocolate';
615615
fixture.changeDetectorRef.markForCheck();
616616

617617
fixture.detectChanges();
618-
tick();
618+
await fixture.whenStable();
619619
fixture.detectChanges();
620620

621621
expect(innerRadios[1].nativeElement.checked).toBe(true);
622622
expect(radioInstances[1].checked).toBe(true);
623-
}));
623+
});
624624

625625
it('should update the ngModel value when selecting a radio button', () => {
626626
dispatchFakeEvent(innerRadios[1].nativeElement, 'change');

src/material/table/table-data-source.spec.ts

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import {MatTableDataSource} from './table-data-source';
2-
import {ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing';
2+
import {ComponentFixture, TestBed} from '@angular/core/testing';
33
import {MatSort, MatSortModule} from '@angular/material/sort';
44
import {Component, ViewChild, ChangeDetectionStrategy} from '@angular/core';
55

66
describe('MatTableDataSource', () => {
77
describe('sort', () => {
8-
let dataSource: MatTableDataSource<{'prop': string | number}>;
8+
let dataSource: MatTableDataSource<{prop: string | number}>;
99
let fixture: ComponentFixture<MatSortApp>;
1010
let sort: MatSort;
1111

@@ -23,7 +23,7 @@ describe('MatTableDataSource', () => {
2323
// the sort should be performed over a particular key.
2424
// Map the values into an array of objects where each value is keyed by "prop"
2525
// e.g. [0, 1, 2] -> [{prop: 0}, {prop: 1}, {prop: 2}]
26-
const data = values.map(v => ({'prop': v}));
26+
const data = values.map(v => ({prop: v}));
2727

2828
// Set the active sort to be on the "prop" key
2929
sort.active = 'prop';
@@ -73,45 +73,43 @@ describe('MatTableDataSource', () => {
7373
});
7474

7575
it('should update filteredData even if the data source is disconnected', () => {
76-
dataSource.data = [{'prop': 1}, {'prop': 2}, {'prop': 3}];
77-
expect(dataSource.filteredData).toEqual([{'prop': 1}, {'prop': 2}, {'prop': 3}]);
76+
dataSource.data = [{prop: 1}, {prop: 2}, {prop: 3}];
77+
expect(dataSource.filteredData).toEqual([{prop: 1}, {prop: 2}, {prop: 3}]);
7878

7979
dataSource.disconnect();
80-
dataSource.data = [{'prop': 3}, {'prop': 2}, {'prop': 1}];
81-
expect(dataSource.filteredData).toEqual([{'prop': 3}, {'prop': 2}, {'prop': 1}]);
80+
dataSource.data = [{prop: 3}, {prop: 2}, {prop: 1}];
81+
expect(dataSource.filteredData).toEqual([{prop: 3}, {prop: 2}, {prop: 1}]);
8282
});
8383

8484
it('should filter data', () => {
85-
dataSource.data = [{'prop': 1}, {'prop': 'foo'}, {'prop': 'banana'}];
85+
dataSource.data = [{prop: 1}, {prop: 'foo'}, {prop: 'banana'}];
8686
dataSource.filter = 'b';
87-
expect(dataSource.filteredData).toEqual([{'prop': 'banana'}]);
87+
expect(dataSource.filteredData).toEqual([{prop: 'banana'}]);
8888
});
8989

90-
it('does not warn in non-dev mode when filtering non-object data', fakeAsync(() => {
90+
it('does not warn in non-dev mode when filtering non-object data', () => {
9191
const warnSpy = spyOn(console, 'warn');
9292
(window as any).ngDevMode = null;
93-
dataSource.data = [1, 2, 3, 4, 5] as unknown as {'prop': number}[];
93+
dataSource.data = [1, 2, 3, 4, 5] as unknown as {prop: number}[];
9494

9595
dataSource.filter = '1';
96-
tick();
9796

9897
expect(warnSpy).not.toHaveBeenCalled();
9998
expect(dataSource.filteredData).toEqual([]);
100-
}));
99+
});
101100

102-
it('displays the warning in dev mode when filtering non-object data', fakeAsync(() => {
101+
it('displays the warning in dev mode when filtering non-object data', () => {
103102
const warnSpy = spyOn(console, 'warn');
104103
(window as any).ngDevMode = {};
105-
dataSource.data = [1, 2, 3, 4, 5] as unknown as {'prop': number}[];
104+
dataSource.data = [1, 2, 3, 4, 5] as unknown as {prop: number}[];
106105

107106
dataSource.filter = '1';
108-
tick();
109107

110108
expect(warnSpy).toHaveBeenCalledWith(
111109
jasmine.stringContaining('requires data to be a non-null object'),
112110
);
113111
expect(dataSource.filteredData).toEqual([]);
114-
}));
112+
});
115113
});
116114
});
117115

0 commit comments

Comments
 (0)