Skip to content

Commit 5006b41

Browse files
authored
test(multiple): address remaining fakeAsync usages in CDK (#33721)
Removes the remaining usages of `fakeAsync` in the CDK that don't require any special handling.
1 parent ef620d8 commit 5006b41

6 files changed

Lines changed: 75 additions & 73 deletions

File tree

src/aria/combobox/combobox.zone.spec.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import {Component, computed, signal, provideZoneChangeDetection} from '@angular/core';
10-
import {ComponentFixture, TestBed, fakeAsync, tick} from '@angular/core/testing';
10+
import {ComponentFixture, TestBed} from '@angular/core/testing';
1111
import {By} from '@angular/platform-browser';
1212
import {Combobox} from './combobox';
1313
import {ComboboxPopup} from './combobox-popup';
@@ -49,11 +49,11 @@ describe('Combobox Zone.js integration', () => {
4949
return options.find(option => option.textContent?.trim() === text) || null;
5050
}
5151

52-
it('should relay ArrowDown to the listbox and update active descendant', fakeAsync(() => {
52+
it('should relay ArrowDown to the listbox and update active descendant', async () => {
5353
// Open the popup (sets active descendant to Alabama via default state)
5454
keydown('ArrowDown');
55-
tick();
5655
fixture.detectChanges();
56+
await fixture.whenStable();
5757

5858
// Check if expanded is true
5959
expect(inputElement.getAttribute('aria-expanded')).toBe('true');
@@ -63,12 +63,12 @@ describe('Combobox Zone.js integration', () => {
6363

6464
// Press ArrowDown again to move to Alaska
6565
keydown('ArrowDown');
66-
tick();
6766
fixture.detectChanges();
67+
await fixture.whenStable();
6868

6969
const alaska = getOption('Alaska')!;
7070
expect(inputElement.getAttribute('aria-activedescendant')).toBe(alaska.id);
71-
}));
71+
});
7272
});
7373

7474
@Component({

src/cdk/bidi/directionality.spec.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {waitForAsync, fakeAsync, TestBed, flush} from '@angular/core/testing';
1+
import {waitForAsync, TestBed} from '@angular/core/testing';
22
import {Component, ViewChild, signal, inject, ChangeDetectionStrategy} from '@angular/core';
33
import {By} from '@angular/platform-browser';
44
import {BidiModule, Directionality, Dir, Direction, DIR_DOCUMENT} from './index';
@@ -78,7 +78,7 @@ describe('Directionality', () => {
7878
expect(injectedDirectionality.value).toBe('rtl');
7979
});
8080

81-
it('should emit a change event when the value changes', fakeAsync(() => {
81+
it('should emit a change event when the value changes', () => {
8282
const fixture = TestBed.createComponent(ElementWithDir);
8383
const injectedDirectionality = fixture.debugElement.query(
8484
By.directive(InjectsDirectionality),
@@ -102,9 +102,9 @@ describe('Directionality', () => {
102102
expect(direction).toBe('ltr');
103103
expect(injectedDirectionality.value).toBe('ltr');
104104
expect(fixture.componentInstance.changeCount).toBe(1);
105-
}));
105+
});
106106

107-
it('should complete the change stream on destroy', fakeAsync(() => {
107+
it('should complete the change stream on destroy', () => {
108108
const fixture = TestBed.createComponent(ElementWithDir);
109109
const dir = fixture.debugElement.query(By.directive(InjectsDirectionality))!.componentInstance
110110
.dir;
@@ -114,8 +114,7 @@ describe('Directionality', () => {
114114
fixture.destroy();
115115
expect(spy).toHaveBeenCalled();
116116
subscription.unsubscribe();
117-
flush();
118-
}));
117+
});
119118

120119
it('should default to ltr if an invalid value is passed in', () => {
121120
const fixture = TestBed.createComponent(ElementWithDir);

src/cdk/coercion/private/observable.spec.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import {Observable, ReplaySubject} from 'rxjs';
22
import {coerceObservable} from './observable';
3-
import {fakeAsync} from '@angular/core/testing';
43

54
describe('coerceObservable', () => {
65
it('should return the Observable, if an Observable is passed in', () => {
@@ -13,12 +12,12 @@ describe('coerceObservable', () => {
1312
expect(coerceObservable(observable)).toBe(observable);
1413
});
1514

16-
it('should wrap non-Observables in Observables', fakeAsync(() => {
15+
it('should wrap non-Observables in Observables', () => {
1716
const observable = coerceObservable(3);
1817
let emittedValue = 0;
1918
observable.subscribe(value => {
2019
emittedValue = value;
2120
});
2221
expect(emittedValue).toBe(3);
23-
}));
22+
});
2423
});

src/cdk/listbox/listbox.spec.ts

Lines changed: 28 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {A, B, DOWN_ARROW, END, HOME, LEFT_ARROW, RIGHT_ARROW, SPACE, UP_ARROW} from '../keycodes';
22
import {Component, Type, signal, ChangeDetectionStrategy} from '@angular/core';
3-
import {TestBed, fakeAsync, tick} from '@angular/core/testing';
3+
import {TestBed} from '@angular/core/testing';
44
import {FormControl, ReactiveFormsModule} from '@angular/forms';
55
import {By} from '@angular/platform-browser';
66
import {dispatchFakeEvent, dispatchKeyboardEvent, dispatchMouseEvent} from '../testing/private';
@@ -23,6 +23,10 @@ function setupComponent<T, O = string>(component: Type<T>) {
2323
};
2424
}
2525

26+
function wait(milliseconds: number): Promise<void> {
27+
return new Promise(resolve => setTimeout(resolve, milliseconds));
28+
}
29+
2630
describe('CdkOption and CdkListbox', () => {
2731
describe('id', () => {
2832
it('should generate unique ids', () => {
@@ -449,20 +453,18 @@ describe('CdkOption and CdkListbox', () => {
449453
expect(fixture.componentInstance.changedOption).toBe(null);
450454
});
451455

452-
it('should not handle type ahead on a disabled listbox', async (...args: unknown[]) => {
456+
it('should not handle type ahead on a disabled listbox', async () => {
453457
const {fixture, testComponent, listboxEl, options} = setupComponent(ListboxWithOptions);
454-
await fakeAsync(() => {
455-
testComponent.isListboxDisabled.set(true);
456-
fixture.detectChanges();
458+
testComponent.isListboxDisabled.set(true);
459+
fixture.detectChanges();
457460

458-
dispatchKeyboardEvent(listboxEl, 'keydown', B);
459-
fixture.detectChanges();
460-
tick(200);
461+
dispatchKeyboardEvent(listboxEl, 'keydown', B);
462+
fixture.detectChanges();
463+
await wait(200);
461464

462-
for (let option of options) {
463-
expect(option.isActive()).toBeFalse();
464-
}
465-
})(args);
465+
for (let option of options) {
466+
expect(option.isActive()).toBeFalse();
467+
}
466468
});
467469

468470
it('should skip disabled options when navigating with arrow keys', () => {
@@ -561,32 +563,28 @@ describe('CdkOption and CdkListbox', () => {
561563
expect(optionEls[0].classList).toContain('cdk-option-active');
562564
});
563565

564-
it('should change active item using type ahead', async (...args: unknown[]) => {
566+
it('should change active item using type ahead', async () => {
565567
const {fixture, listbox, listboxEl, options} = setupComponent(ListboxWithOptions);
566-
await fakeAsync(() => {
567-
listbox.focus();
568-
fixture.detectChanges();
568+
listbox.focus();
569+
fixture.detectChanges();
569570

570-
dispatchKeyboardEvent(listboxEl, 'keydown', B);
571-
fixture.detectChanges();
572-
tick(200);
571+
dispatchKeyboardEvent(listboxEl, 'keydown', B);
572+
fixture.detectChanges();
573+
await wait(200);
573574

574-
expect(options[2].isActive()).toBeTrue();
575-
})(args);
575+
expect(options[2].isActive()).toBeTrue();
576576
});
577577

578-
it('should allow custom type ahead label', async (...args: unknown[]) => {
578+
it('should allow custom type ahead label', async () => {
579579
const {fixture, listbox, listboxEl, options} = setupComponent(ListboxWithCustomTypeahead);
580-
await fakeAsync(() => {
581-
listbox.focus();
582-
fixture.detectChanges();
580+
listbox.focus();
581+
fixture.detectChanges();
583582

584-
dispatchKeyboardEvent(listboxEl, 'keydown', B);
585-
fixture.detectChanges();
586-
tick(200);
583+
dispatchKeyboardEvent(listboxEl, 'keydown', B);
584+
fixture.detectChanges();
585+
await wait(200);
587586

588-
expect(options[2].isActive()).toBeTrue();
589-
})(args);
587+
expect(options[2].isActive()).toBeTrue();
590588
});
591589

592590
it('should focus and toggle the next item when pressing SHIFT + DOWN_ARROW', () => {

src/cdk/text-field/autosize.spec.ts

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {Component, ViewChild, ChangeDetectionStrategy} from '@angular/core';
2-
import {ComponentFixture, TestBed, fakeAsync, flush, tick} from '@angular/core/testing';
2+
import {ComponentFixture, TestBed} from '@angular/core/testing';
33
import {FormsModule} from '@angular/forms';
44
import {By} from '@angular/platform-browser';
55
import {dispatchFakeEvent} from '../testing/private';
@@ -264,7 +264,7 @@ describe('CdkTextareaAutosize', () => {
264264
.toBe(textarea.scrollHeight);
265265
});
266266

267-
it('should resize when an associated form control value changes', fakeAsync(() => {
267+
it('should resize when an associated form control value changes', async () => {
268268
const fixtureWithForms = TestBed.createComponent(AutosizeTextareaWithNgModel);
269269
textarea = fixtureWithForms.nativeElement.querySelector('textarea');
270270
fixtureWithForms.detectChanges();
@@ -280,15 +280,15 @@ describe('CdkTextareaAutosize', () => {
280280
This it is and nothing more.” `;
281281
fixtureWithForms.changeDetectorRef.markForCheck();
282282
fixtureWithForms.detectChanges();
283-
flush();
283+
await wait(50);
284284
fixtureWithForms.detectChanges();
285285

286286
expect(textarea.clientHeight)
287287
.withContext('Expected increased height when ngModel is updated.')
288288
.toBeGreaterThan(previousHeight);
289-
}));
289+
});
290290

291-
it('should resize when the textarea value is changed programmatically', fakeAsync(() => {
291+
it('should resize when the textarea value is changed programmatically', () => {
292292
const previousHeight = textarea.clientHeight;
293293

294294
textarea.value = `
@@ -298,24 +298,22 @@ describe('CdkTextareaAutosize', () => {
298298

299299
fixture.changeDetectorRef.markForCheck();
300300
fixture.detectChanges();
301-
flush();
302-
fixture.detectChanges();
303301

304302
expect(textarea.clientHeight)
305303
.withContext('Expected the textarea height to have increased.')
306304
.toBeGreaterThan(previousHeight);
307-
}));
305+
});
308306

309-
it('should trigger a resize when the window is resized', fakeAsync(() => {
307+
it('should trigger a resize when the window is resized', async () => {
310308
spyOn(autosize, 'resizeToFitContent');
311309

312310
dispatchFakeEvent(window, 'resize');
313-
tick(16);
311+
await wait(100);
314312

315313
expect(autosize.resizeToFitContent).toHaveBeenCalled();
316-
}));
314+
});
317315

318-
it('should not trigger a resize when it is disabled', fakeAsync(() => {
316+
it('should not trigger a resize when it is disabled', () => {
319317
const fixtureWithoutAutosize = TestBed.createComponent(AutosizeTextareaWithoutAutosize);
320318
textarea = fixtureWithoutAutosize.nativeElement.querySelector('textarea');
321319
autosize = fixtureWithoutAutosize.debugElement
@@ -363,7 +361,7 @@ describe('CdkTextareaAutosize', () => {
363361
expect(textarea.clientHeight)
364362
.withContext('Expected textarea to have a scrollbar.')
365363
.toBeLessThan(textarea.scrollHeight);
366-
}));
364+
});
367365

368366
it('should handle an undefined placeholder', () => {
369367
fixture.componentInstance.placeholder = undefined!;
@@ -374,6 +372,10 @@ describe('CdkTextareaAutosize', () => {
374372
});
375373
});
376374

375+
function wait(milliseconds: number) {
376+
return new Promise(resolve => setTimeout(resolve, milliseconds));
377+
}
378+
377379
// Styles to reset padding and border to make measurement comparisons easier.
378380
const textareaStyleReset = `
379381
textarea {

src/cdk/tree/tree.spec.ts

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
signal,
2020
ChangeDetectionStrategy,
2121
} from '@angular/core';
22-
import {ComponentFixture, TestBed, fakeAsync, tick} from '@angular/core/testing';
22+
import {ComponentFixture, TestBed} from '@angular/core/testing';
2323
import {AsyncPipe} from '@angular/common';
2424

2525
import {BehaviorSubject, Observable, combineLatest, of} from 'rxjs';
@@ -1407,13 +1407,13 @@ describe('CdkTree', () => {
14071407
component = fixture.componentInstance;
14081408
});
14091409
describe(`when pressing 'b' with default configuration`, () => {
1410-
beforeEach(fakeAsync(() => {
1410+
beforeEach(async () => {
14111411
component.tree.nativeElement.dispatchEvent(
14121412
createKeyboardEvent('keydown', undefined, 'b'),
14131413
);
14141414
fixture.detectChanges();
1415-
tick(1000);
1416-
}));
1415+
await wait(1000);
1416+
});
14171417

14181418
it('focuses banana', () => {
14191419
expect(document.activeElement)
@@ -1435,35 +1435,35 @@ describe('CdkTree', () => {
14351435
});
14361436

14371437
describe(`when pressing 'b' with typeahead label binding`, () => {
1438-
beforeEach(fakeAsync(() => {
1438+
beforeEach(async () => {
14391439
component.tree.nativeElement.dispatchEvent(
14401440
createKeyboardEvent('keydown', undefined, 'b'),
14411441
);
14421442
fixture.detectChanges();
1443-
tick(1000);
1444-
}));
1443+
await wait(1000);
1444+
});
14451445

1446-
it('focuses banana', fakeAsync(() => {
1446+
it('focuses banana', async () => {
14471447
component.tree.nativeElement.dispatchEvent(
14481448
createKeyboardEvent('keydown', undefined, 'b'),
14491449
);
14501450
fixture.detectChanges();
1451-
tick(1000);
1451+
await wait(1000);
14521452

14531453
expect(document.activeElement)
14541454
.withContext('expecting banana to be focused')
14551455
.toBe(component.treeNodes.get(1)?.nativeElement!);
1456-
}));
1456+
});
14571457
});
14581458

14591459
describe(`when pressing 'c'`, () => {
1460-
beforeEach(fakeAsync(() => {
1460+
beforeEach(async () => {
14611461
component.tree.nativeElement.dispatchEvent(
14621462
createKeyboardEvent('keydown', undefined, 'c'),
14631463
);
14641464
fixture.detectChanges();
1465-
tick(1000);
1466-
}));
1465+
await wait(1000);
1466+
});
14671467
it('does not move focus', () => {
14681468
expect(document.activeElement)
14691469
.withContext('expecting document body to be focused')
@@ -1472,13 +1472,13 @@ describe('CdkTree', () => {
14721472
});
14731473

14741474
describe(`when pressing 't'`, () => {
1475-
beforeEach(fakeAsync(() => {
1475+
beforeEach(async () => {
14761476
component.tree.nativeElement.dispatchEvent(
14771477
createKeyboardEvent('keydown', undefined, 't'),
14781478
);
14791479
fixture.detectChanges();
1480-
tick(1000);
1481-
}));
1480+
await wait(1000);
1481+
});
14821482
it('focuses focuses cherry', () => {
14831483
expect(document.activeElement)
14841484
.withContext('expecting cherry to be focused')
@@ -1632,6 +1632,10 @@ function getExpandedNodes<T>(nodes: T[] | undefined, tree: CdkTree<T>): T[] {
16321632
return nodes?.filter(node => tree.isExpanded(node)) ?? [];
16331633
}
16341634

1635+
function wait(milliseconds: number) {
1636+
return new Promise(resolve => setTimeout(resolve, milliseconds));
1637+
}
1638+
16351639
function expectFlatTreeToMatch(
16361640
treeElement: Element,
16371641
expectedPaddingIndent = 28,

0 commit comments

Comments
 (0)