Skip to content

Commit 85a81a6

Browse files
authored
refactor(cdk/table): switch tests away from fakeAsync (#33456)
Reworks the CDK table tests not to depend on `fakeAsync` and `waitForAsync` anymore.
1 parent 72fb9d2 commit 85a81a6

1 file changed

Lines changed: 69 additions & 76 deletions

File tree

src/cdk/table/table.spec.ts

Lines changed: 69 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,7 @@ import {
1616
signal,
1717
} from '@angular/core';
1818
import {By} from '@angular/platform-browser';
19-
import {
20-
ComponentFixture,
21-
TestBed,
22-
fakeAsync,
23-
flush,
24-
tick,
25-
waitForAsync,
26-
} from '@angular/core/testing';
19+
import {ComponentFixture, fakeAsync, flush, TestBed} from '@angular/core/testing';
2720
import {BehaviorSubject, Observable, combineLatest, of as observableOf} from 'rxjs';
2821
import {map} from 'rxjs/operators';
2922
import {CdkColumnDef} from './cell';
@@ -331,15 +324,15 @@ describe('CdkTable', () => {
331324
});
332325
});
333326

334-
it('should render no rows when the data is null', fakeAsync(() => {
327+
it('should render no rows when the data is null', () => {
335328
setupTableTestApp(NullDataCdkTableApp);
336329
fixture.detectChanges();
337330

338331
expect(getRows(tableElement).length).toBe(0);
339332

340333
// Emits that the data rows are changed even when the result is empty.
341334
expect(component.contentChangedCount).toBe(1);
342-
}));
335+
});
343336

344337
it('should be able to render multiple header and footer rows', () => {
345338
setupTableTestApp(MultipleHeaderFooterRowsCdkTableApp);
@@ -353,17 +346,17 @@ describe('CdkTable', () => {
353346
]);
354347
});
355348

356-
it('should be able to project a caption', fakeAsync(() => {
349+
it('should be able to project a caption', () => {
357350
setupTableTestApp(NativeHtmlTableWithCaptionApp);
358351
fixture.detectChanges();
359352

360353
const caption = tableElement.querySelector('caption');
361354

362355
expect(caption).toBeTruthy();
363356
expect(tableElement.firstElementChild).toBe(caption);
364-
}));
357+
});
365358

366-
it('should be able to project colgroup and col', fakeAsync(() => {
359+
it('should be able to project colgroup and col', () => {
367360
setupTableTestApp(NativeHtmlTableWithColgroupAndCol);
368361
fixture.detectChanges();
369362

@@ -373,7 +366,7 @@ describe('CdkTable', () => {
373366
expect(colgroupsAndCols[0].childNodes[0]).toBe(colgroupsAndCols[1]);
374367
expect(colgroupsAndCols[2].parentNode!.nodeName.toLowerCase()).toBe('table');
375368
expect(colgroupsAndCols.map(e => e.nodeName.toLowerCase())).toEqual(['colgroup', 'col', 'col']);
376-
}));
369+
});
377370

378371
it('should not throw if `renderRows` is called too early', () => {
379372
// Note that we don't call `detectChanges` here, because we're testing specifically
@@ -820,13 +813,12 @@ describe('CdkTable', () => {
820813
}).toThrowError(getTableMissingMatchingRowDefError(data[0]).message);
821814
}));
822815

823-
it('should fail when multiple rows match data without multiTemplateDataRows', fakeAsync(() => {
816+
it('should fail when multiple rows match data without multiTemplateDataRows', () => {
824817
let whenFixture = TestBed.createComponent(WhenRowMultipleDefaultsCdkTableApp);
825818
expect(() => {
826819
whenFixture.detectChanges();
827-
flush();
828820
}).toThrowError(getTableMultipleDefaultRowDefsError().message);
829-
}));
821+
});
830822

831823
describe('with multiTemplateDataRows', () => {
832824
it('should be able to render multiple rows per data object', () => {
@@ -991,7 +983,7 @@ describe('CdkTable', () => {
991983
dataRows = getRows(tableElement);
992984
});
993985

994-
it('should stick and unstick headers in flex layout', waitForAsync(async () => {
986+
it('should stick and unstick headers in flex layout', async () => {
995987
component.stickyHeaders = ['header-1', 'header-3'];
996988
fixture.changeDetectorRef.markForCheck();
997989
fixture.detectChanges();
@@ -1038,9 +1030,9 @@ describe('CdkTable', () => {
10381030
});
10391031
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
10401032
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
1041-
}));
1033+
});
10421034

1043-
it('should stick and unstick footers in flex layout', waitForAsync(async () => {
1035+
it('should stick and unstick footers in flex layout', async () => {
10441036
component.stickyFooters = ['footer-1', 'footer-3'];
10451037
fixture.changeDetectorRef.markForCheck();
10461038
fixture.detectChanges();
@@ -1087,9 +1079,9 @@ describe('CdkTable', () => {
10871079
});
10881080
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
10891081
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
1090-
}));
1082+
});
10911083

1092-
it('should stick the correct footer row', waitForAsync(async () => {
1084+
it('should stick the correct footer row', async () => {
10931085
component.stickyFooters = ['footer-3'];
10941086
fixture.changeDetectorRef.markForCheck();
10951087
fixture.detectChanges();
@@ -1098,9 +1090,9 @@ describe('CdkTable', () => {
10981090
expectStickyStyles(footerRows[2], '10', {bottom: '0px'});
10991091
expectStickyBorderClass(footerRows[2], {bottom: true});
11001092
expectNoStickyStyles([footerRows[0], footerRows[1]]);
1101-
}));
1093+
});
11021094

1103-
it('should stick and unstick left columns in flex layout', waitForAsync(async () => {
1095+
it('should stick and unstick left columns in flex layout', async () => {
11041096
component.stickyStartColumns = ['column-1', 'column-3'];
11051097
fixture.changeDetectorRef.markForCheck();
11061098
fixture.detectChanges();
@@ -1168,9 +1160,9 @@ describe('CdkTable', () => {
11681160
});
11691161
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
11701162
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
1171-
}));
1163+
});
11721164

1173-
it('should stick and unstick right columns in flex layout', waitForAsync(async () => {
1165+
it('should stick and unstick right columns in flex layout', async () => {
11741166
component.stickyEndColumns = ['column-4', 'column-6'];
11751167
fixture.changeDetectorRef.markForCheck();
11761168
fixture.detectChanges();
@@ -1238,9 +1230,9 @@ describe('CdkTable', () => {
12381230
});
12391231
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
12401232
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
1241-
}));
1233+
});
12421234

1243-
it('should reverse directions for sticky columns in rtl', waitForAsync(async () => {
1235+
it('should reverse directions for sticky columns in rtl', async () => {
12441236
component.dir = 'rtl';
12451237
component.stickyStartColumns = ['column-1', 'column-2'];
12461238
component.stickyEndColumns = ['column-5', 'column-6'];
@@ -1282,9 +1274,9 @@ describe('CdkTable', () => {
12821274
expectStickyBorderClass(footerCells[4], {left: true});
12831275
expectStickyStyles(footerCells[5], '1', {left: '0px'});
12841276
expectStickyBorderClass(footerCells[5]);
1285-
}));
1277+
});
12861278

1287-
it('should stick and unstick combination of sticky header, footer, and columns in flex layout', waitForAsync(async () => {
1279+
it('should stick and unstick combination of sticky header, footer, and columns in flex layout', async () => {
12881280
component.stickyHeaders = ['header-1'];
12891281
component.stickyFooters = ['footer-3'];
12901282
component.stickyStartColumns = ['column-1'];
@@ -1363,7 +1355,7 @@ describe('CdkTable', () => {
13631355
});
13641356
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
13651357
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
1366-
}));
1358+
});
13671359
});
13681360

13691361
describe('on native table layout', () => {
@@ -1379,7 +1371,7 @@ describe('CdkTable', () => {
13791371
dataRows = getRows(tableElement);
13801372
});
13811373

1382-
it('should stick and unstick headers in native layout', waitForAsync(async () => {
1374+
it('should stick and unstick headers in native layout', async () => {
13831375
component.stickyHeaders = ['header-1', 'header-3'];
13841376
fixture.changeDetectorRef.markForCheck();
13851377
fixture.detectChanges();
@@ -1431,9 +1423,9 @@ describe('CdkTable', () => {
14311423
});
14321424
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
14331425
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
1434-
}));
1426+
});
14351427

1436-
it('should stick and unstick footers in native layout', waitForAsync(async () => {
1428+
it('should stick and unstick footers in native layout', async () => {
14371429
component.stickyFooters = ['footer-1', 'footer-3'];
14381430
fixture.changeDetectorRef.markForCheck();
14391431
fixture.detectChanges();
@@ -1485,9 +1477,9 @@ describe('CdkTable', () => {
14851477
});
14861478
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
14871479
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
1488-
}));
1480+
});
14891481

1490-
it('should stick tfoot when all rows are stuck', waitForAsync(async () => {
1482+
it('should stick tfoot when all rows are stuck', async () => {
14911483
const tfoot = tableElement.querySelector('tfoot');
14921484
component.stickyFooters = ['footer-1'];
14931485
fixture.changeDetectorRef.markForCheck();
@@ -1507,9 +1499,9 @@ describe('CdkTable', () => {
15071499
fixture.detectChanges();
15081500
await new Promise(r => setTimeout(r));
15091501
expectNoStickyStyles([tfoot]);
1510-
}));
1502+
});
15111503

1512-
it('should stick and unstick left columns in native layout', waitForAsync(async () => {
1504+
it('should stick and unstick left columns in native layout', async () => {
15131505
component.stickyStartColumns = ['column-1', 'column-3'];
15141506
fixture.changeDetectorRef.markForCheck();
15151507
fixture.detectChanges();
@@ -1577,9 +1569,9 @@ describe('CdkTable', () => {
15771569
});
15781570
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
15791571
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
1580-
}));
1572+
});
15811573

1582-
it('should stick and unstick right columns in native layout', waitForAsync(async () => {
1574+
it('should stick and unstick right columns in native layout', async () => {
15831575
component.stickyEndColumns = ['column-4', 'column-6'];
15841576
fixture.changeDetectorRef.markForCheck();
15851577
fixture.detectChanges();
@@ -1647,9 +1639,9 @@ describe('CdkTable', () => {
16471639
});
16481640
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
16491641
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
1650-
}));
1642+
});
16511643

1652-
it('should stick and unstick combination of sticky header, footer, and columns in native layout', waitForAsync(async () => {
1644+
it('should stick and unstick combination of sticky header, footer, and columns in native layout', async () => {
16531645
component.stickyHeaders = ['header-1'];
16541646
component.stickyFooters = ['footer-3'];
16551647
component.stickyStartColumns = ['column-1'];
@@ -1738,7 +1730,7 @@ describe('CdkTable', () => {
17381730
});
17391731
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
17401732
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
1741-
}));
1733+
});
17421734
});
17431735
});
17441736

@@ -2006,19 +1998,20 @@ describe('CdkTable', () => {
20061998
});
20071999

20082000
describe('virtual scrolling', () => {
2009-
function createVirtualScroll<T>(component: Type<T>): {
2001+
async function createVirtualScroll<T>(component: Type<T>): Promise<{
20102002
fixture: ComponentFixture<T>;
20112003
table: HTMLTableElement;
2012-
} {
2004+
}> {
20132005
const fixture = TestBed.createComponent(component);
20142006

20152007
// Init logic copied from the virtual scroll tests.
20162008
fixture.detectChanges();
2017-
flush();
2009+
await fixture.whenStable();
20182010
fixture.detectChanges();
2019-
flush();
2020-
tick(16);
2021-
flush();
2011+
await fixture.whenStable();
2012+
2013+
await new Promise(resolve => requestAnimationFrame(resolve));
2014+
await fixture.whenStable();
20222015
fixture.detectChanges();
20232016

20242017
return {
@@ -2027,38 +2020,38 @@ describe('CdkTable', () => {
20272020
};
20282021
}
20292022

2030-
function triggerScroll(
2023+
async function triggerScroll(
20312024
fixture: ComponentFixture<{viewport: CdkVirtualScrollViewport}>,
20322025
offset: number,
20332026
) {
20342027
const viewport = fixture.componentInstance.viewport;
20352028
viewport.scrollToOffset(offset);
20362029
dispatchFakeEvent(viewport.scrollable!.getElementRef().nativeElement, 'scroll');
2037-
tick(16);
2030+
await new Promise(resolve => setTimeout(resolve, 50));
20382031
}
20392032

2040-
it('should not render the full data set when using virtual scrolling', fakeAsync(() => {
2041-
const {fixture, table} = createVirtualScroll(TableWithVirtualScroll);
2033+
it('should not render the full data set when using virtual scrolling', async () => {
2034+
const {fixture, table} = await createVirtualScroll(TableWithVirtualScroll);
20422035
expect(fixture.componentInstance.dataSource.data.length).toBeGreaterThan(2000);
20432036
expect(getRows(table).length).toBe(10);
2044-
}));
2037+
});
20452038

2046-
it('should maintain a limited amount of data as the user is scrolling', fakeAsync(() => {
2047-
const {fixture, table} = createVirtualScroll(TableWithVirtualScroll);
2039+
it('should maintain a limited amount of data as the user is scrolling', async () => {
2040+
const {fixture, table} = await createVirtualScroll(TableWithVirtualScroll);
20482041
expect(getRows(table).length).toBe(10);
20492042

2050-
triggerScroll(fixture, 500);
2043+
await triggerScroll(fixture, 500);
20512044
expect(getRows(table).length).toBe(13);
20522045

2053-
triggerScroll(fixture, 500);
2046+
await triggerScroll(fixture, 500);
20542047
expect(getRows(table).length).toBe(13);
20552048

2056-
triggerScroll(fixture, 1000);
2049+
await triggerScroll(fixture, 1000);
20572050
expect(getRows(table).length).toBe(12);
2058-
}));
2051+
});
20592052

2060-
it('should update the table data as the user is scrolling', fakeAsync(() => {
2061-
const {fixture, table} = createVirtualScroll(TableWithVirtualScroll);
2053+
it('should update the table data as the user is scrolling', async () => {
2054+
const {fixture, table} = await createVirtualScroll(TableWithVirtualScroll);
20622055

20632056
expectTableToMatchContent(table, [
20642057
['Column A', 'Column B', 'Column C'],
@@ -2075,7 +2068,7 @@ describe('CdkTable', () => {
20752068
['Footer A', 'Footer B', 'Footer C'],
20762069
]);
20772070

2078-
triggerScroll(fixture, 1000);
2071+
await triggerScroll(fixture, 1000);
20792072

20802073
expectTableToMatchContent(table, [
20812074
['Column A', 'Column B', 'Column C'],
@@ -2093,38 +2086,38 @@ describe('CdkTable', () => {
20932086
['a_29', 'b_29', 'c_29'],
20942087
['Footer A', 'Footer B', 'Footer C'],
20952088
]);
2096-
}));
2089+
});
20972090

2098-
it('should update the position of sticky cells as the user is scrolling', fakeAsync(() => {
2099-
const {fixture, table} = createVirtualScroll(TableWithVirtualScroll);
2091+
it('should update the position of sticky cells as the user is scrolling', async () => {
2092+
const {fixture, table} = await createVirtualScroll(TableWithVirtualScroll);
21002093
const assertStickyOffsets = (position: number) => {
21012094
getHeaderCells(table).forEach(cell => expect(cell.style.top).toBe(`${position * -1}px`));
21022095
getFooterCells(table).forEach(cell => expect(cell.style.bottom).toBe(`${position}px`));
21032096
};
21042097

21052098
assertStickyOffsets(0);
2106-
triggerScroll(fixture, 1000);
2099+
await triggerScroll(fixture, 1000);
21072100
assertStickyOffsets(884);
2108-
}));
2101+
});
21092102

2110-
it('should force tables with virtual scrolling to have a fixed layout', fakeAsync(() => {
2111-
const {fixture, table} = createVirtualScroll(TableWithVirtualScroll);
2103+
it('should force tables with virtual scrolling to have a fixed layout', async () => {
2104+
const {fixture, table} = await createVirtualScroll(TableWithVirtualScroll);
21122105
expect(fixture.componentInstance.isFixedLayout()).toBe(true);
21132106
expect(table.classList).toContain('cdk-table-fixed-layout');
21142107

21152108
fixture.componentInstance.isFixedLayout.set(false);
21162109
fixture.detectChanges();
21172110

21182111
expect(table.classList).toContain('cdk-table-fixed-layout');
2119-
}));
2112+
});
21202113

2121-
it('should throw if multiple row templates are used with virtual scrolling', fakeAsync(() => {
2122-
expect(() => {
2123-
createVirtualScroll(TableWithVirtualScrollAndMultipleDefinitions);
2124-
}).toThrowError(
2114+
it('should throw if multiple row templates are used with virtual scrolling', async () => {
2115+
await expectAsync(
2116+
createVirtualScroll(TableWithVirtualScrollAndMultipleDefinitions),
2117+
).toBeRejectedWithError(
21252118
/Conditional row definitions via the `when` input are not supported when virtual scrolling is enabled/,
21262119
);
2127-
}));
2120+
});
21282121
});
21292122
});
21302123

0 commit comments

Comments
 (0)