Skip to content

Commit 2dbbc0d

Browse files
authored
test(material-experimental): add missing test coverage (#20678)
* test(material-experimental/mdc-menu): add missing test coverage Adds tests that were missing from the `mdc-menu` module. * test(material-experimental/mdc-radio): add missing test coverage Adds tests that were missing from the `mdc-radio` module. * test(material-experimental/mdc-table): add missing test coverage Adds tests that were missing from the `mdc-table` module. * test(material-experimental/mdc-tabs): add missing test coverage Adds tests that were missing from the `mdc-tabs` module.
1 parent 55b74e3 commit 2dbbc0d

File tree

5 files changed

+178
-1
lines changed

5 files changed

+178
-1
lines changed

scripts/check-mdc-tests.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ function getTestNames(files: string[]): string[] {
6464

6565
sourceFile.forEachChild(function walk(node: ts.Node) {
6666
if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) &&
67-
node.expression.text === 'it') {
67+
(node.expression.text === 'it' || node.expression.text === 'xit')) {
6868
// Note that this is a little naive since it'll take the literal text of the test
6969
// name expression which could include things like string concatenation. It's fine
7070
// for the limited use cases of the script.

src/material-experimental/mdc-menu/menu.spec.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
QueryList,
1515
Type,
1616
Provider,
17+
ChangeDetectionStrategy,
1718
} from '@angular/core';
1819
import {Direction, Directionality} from '@angular/cdk/bidi';
1920
import {OverlayContainer, Overlay} from '@angular/cdk/overlay';
@@ -243,6 +244,42 @@ describe('MDC-based MatMenu', () => {
243244
expect(backdrop.classList).toContain('custom-backdrop');
244245
}));
245246

247+
248+
it('should be able to set a custom class on the overlay panel', fakeAsync(() => {
249+
const optionsProvider = {
250+
provide: MAT_MENU_DEFAULT_OPTIONS,
251+
useValue: {overlayPanelClass: 'custom-panel-class'}
252+
};
253+
const fixture = createComponent(SimpleMenu, [optionsProvider], [FakeIcon]);
254+
255+
fixture.detectChanges();
256+
fixture.componentInstance.trigger.openMenu();
257+
fixture.detectChanges();
258+
tick(500);
259+
260+
const overlayPane = <HTMLElement>overlayContainerElement.querySelector('.cdk-overlay-pane');
261+
262+
expect(overlayPane.classList).toContain('custom-panel-class');
263+
}));
264+
265+
it('should be able to set a custom classes on the overlay panel', fakeAsync(() => {
266+
const optionsProvider = {
267+
provide: MAT_MENU_DEFAULT_OPTIONS,
268+
useValue: {overlayPanelClass: ['custom-panel-class-1', 'custom-panel-class-2']}
269+
};
270+
const fixture = createComponent(SimpleMenu, [optionsProvider], [FakeIcon]);
271+
272+
fixture.detectChanges();
273+
fixture.componentInstance.trigger.openMenu();
274+
fixture.detectChanges();
275+
tick(500);
276+
277+
const overlayPane = <HTMLElement>overlayContainerElement.querySelector('.cdk-overlay-pane');
278+
279+
expect(overlayPane.classList).toContain('custom-panel-class-1');
280+
expect(overlayPane.classList).toContain('custom-panel-class-2');
281+
}));
282+
246283
it('should restore focus to the root trigger when the menu was opened by mouse', fakeAsync(() => {
247284
const fixture = createComponent(SimpleMenu, [], [FakeIcon]);
248285
fixture.detectChanges();
@@ -906,6 +943,25 @@ describe('MDC-based MatMenu', () => {
906943
flush();
907944
}));
908945

946+
it('should open submenus when the menu is inside an OnPush component', fakeAsync(() => {
947+
const fixture = createComponent(LazyMenuWithOnPush);
948+
fixture.detectChanges();
949+
950+
// Open the top-level menu
951+
fixture.componentInstance.rootTrigger.nativeElement.click();
952+
fixture.detectChanges();
953+
flush();
954+
955+
// Dispatch a `mouseenter` on the menu item to open the submenu.
956+
// This will only work if the top-level menu is aware the this menu item exists.
957+
dispatchMouseEvent(fixture.componentInstance.menuItemWithSubmenu.nativeElement, 'mouseenter');
958+
fixture.detectChanges();
959+
flush();
960+
961+
expect(overlayContainerElement.querySelectorAll('.mat-mdc-menu-item').length)
962+
.toBe(2, 'Expected two open menus');
963+
}));
964+
909965
it('should focus the menu panel if all items are disabled', fakeAsync(() => {
910966
const fixture = createComponent(SimpleMenuWithRepeater, [], [FakeIcon]);
911967
fixture.componentInstance.items.forEach(item => item.disabled = true);
@@ -2588,6 +2644,30 @@ class SimpleMenuWithRepeaterInLazyContent {
25882644
}
25892645

25902646

2647+
@Component({
2648+
template: `
2649+
<button [matMenuTriggerFor]="menu" #triggerEl>Toggle menu</button>
2650+
2651+
<mat-menu #menu="matMenu">
2652+
<ng-template matMenuContent>
2653+
<button [matMenuTriggerFor]="menu2" mat-menu-item #menuItem>Item</button>
2654+
</ng-template>
2655+
</mat-menu>
2656+
2657+
<mat-menu #menu2="matMenu">
2658+
<ng-template matMenuContent>
2659+
<button mat-menu-item #subMenuItem>Sub item</button>
2660+
</ng-template>
2661+
</mat-menu>
2662+
`,
2663+
changeDetection: ChangeDetectionStrategy.OnPush,
2664+
})
2665+
class LazyMenuWithOnPush {
2666+
@ViewChild('triggerEl', {read: ElementRef}) rootTrigger: ElementRef;
2667+
@ViewChild('menuItem', {read: ElementRef}) menuItemWithSubmenu: ElementRef;
2668+
}
2669+
2670+
25912671
@Component({
25922672
template: `
25932673
<mat-menu #menu="matMenu">

src/material-experimental/mdc-radio/radio.spec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,16 @@ describe('MDC-based MatRadio', () => {
784784
.toBe(4, 'Expected the tabindex to be set to "4".');
785785
});
786786

787+
it('should remove the tabindex from the host element', () => {
788+
const predefinedFixture = TestBed.createComponent(RadioButtonWithPredefinedTabindex);
789+
predefinedFixture.detectChanges();
790+
791+
const radioButtonEl =
792+
predefinedFixture.debugElement.query(By.css('.mat-mdc-radio-button'))!.nativeElement;
793+
794+
expect(radioButtonEl.getAttribute('tabindex')).toBe('-1');
795+
});
796+
787797
it('should set the tabindex to -1 on the host element', () => {
788798
const predefinedFixture = TestBed.createComponent(RadioButtonWithPredefinedTabindex);
789799
predefinedFixture.detectChanges();

src/material-experimental/mdc-table/table.spec.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ describe('MDC-based MatTable', () => {
2323
MatTableApp,
2424
MatTableWithWhenRowApp,
2525
ArrayDataSourceMatTableApp,
26+
NativeHtmlTableApp,
2627
MatTableWithSortApp,
2728
MatTableWithPaginatorApp,
2829
StickyTableApp,
@@ -81,6 +82,21 @@ describe('MDC-based MatTable', () => {
8182
]);
8283
});
8384

85+
it('should be able to render a table correctly with native elements', () => {
86+
let fixture = TestBed.createComponent(NativeHtmlTableApp);
87+
fixture.detectChanges();
88+
89+
const tableElement = fixture.nativeElement.querySelector('table');
90+
const data = fixture.componentInstance.dataSource!.data;
91+
expectTableToMatchContent(tableElement, [
92+
['Column A', 'Column B', 'Column C'],
93+
[data[0].a, data[0].b, data[0].c],
94+
[data[1].a, data[1].b, data[1].c],
95+
[data[2].a, data[2].b, data[2].c],
96+
[data[3].a, data[3].b, data[3].c],
97+
]);
98+
});
99+
84100
it('should be able to nest tables', () => {
85101
const fixture = TestBed.createComponent(NestedTableApp);
86102
fixture.detectChanges();
@@ -96,6 +112,28 @@ describe('MDC-based MatTable', () => {
96112
expect(innerRows.map(row => row.cells.length)).toEqual([3, 3, 3, 3]);
97113
});
98114

115+
it('should be able to show a message when no data is being displayed in a native table', () => {
116+
const fixture = TestBed.createComponent(NativeHtmlTableApp);
117+
fixture.detectChanges();
118+
119+
// Assert that the data is inside the tbody specifically.
120+
const tbody = fixture.nativeElement.querySelector('tbody')!;
121+
const dataSource = fixture.componentInstance.dataSource!;
122+
const initialData = dataSource.data;
123+
124+
expect(tbody.textContent.trim()).not.toContain('No data');
125+
126+
dataSource.data = [];
127+
fixture.detectChanges();
128+
129+
expect(tbody.textContent.trim()).toContain('No data');
130+
131+
dataSource.data = initialData;
132+
fixture.detectChanges();
133+
134+
expect(tbody.textContent.trim()).not.toContain('No data');
135+
});
136+
99137
it('should be able to show a message when no data is being displayed', () => {
100138
const fixture = TestBed.createComponent(MatTableApp);
101139
fixture.detectChanges();
@@ -601,6 +639,39 @@ class MatTableApp {
601639
@ViewChild(MatTable) table: MatTable<TestData>;
602640
}
603641

642+
@Component({
643+
template: `
644+
<table mat-table [dataSource]="dataSource">
645+
<ng-container matColumnDef="column_a">
646+
<th mat-header-cell *matHeaderCellDef> Column A</th>
647+
<td mat-cell *matCellDef="let row"> {{row.a}}</td>
648+
</ng-container>
649+
650+
<ng-container matColumnDef="column_b">
651+
<th mat-header-cell *matHeaderCellDef> Column B</th>
652+
<td mat-cell *matCellDef="let row"> {{row.b}}</td>
653+
</ng-container>
654+
655+
<ng-container matColumnDef="column_c">
656+
<th mat-header-cell *matHeaderCellDef> Column C</th>
657+
<td mat-cell *matCellDef="let row"> {{row.c}}</td>
658+
</ng-container>
659+
660+
<tr mat-header-row *matHeaderRowDef="columnsToRender"></tr>
661+
<tr mat-row *matRowDef="let row; columns: columnsToRender"></tr>
662+
<tr *matNoDataRow>
663+
<td>No data</td>
664+
</tr>
665+
</table>
666+
`
667+
})
668+
class NativeHtmlTableApp {
669+
dataSource: FakeDataSource | null = new FakeDataSource();
670+
columnsToRender = ['column_a', 'column_b', 'column_c'];
671+
672+
@ViewChild(MatTable) table: MatTable<TestData>;
673+
}
674+
604675
@Component({
605676
template: `
606677
<table mat-table [dataSource]="dataSource">

src/material-experimental/mdc-tabs/tab-nav-bar/tab-nav-bar.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,22 @@ describe('MDC-based MatTabNavBar', () => {
260260
expect(tabLink.tabIndex).toBe(3, 'Expected the tabIndex to be have been set to 3.');
261261
});
262262

263+
it('should select the proper tab, if the tabs come in after init', () => {
264+
const fixture = TestBed.createComponent(SimpleTabNavBarTestApp);
265+
const instance = fixture.componentInstance;
266+
267+
instance.tabs = [];
268+
instance.activeIndex = 1;
269+
fixture.detectChanges();
270+
271+
expect(instance.tabNavBar.selectedIndex).toBe(-1);
272+
273+
instance.tabs = [0, 1, 2];
274+
fixture.detectChanges();
275+
276+
expect(instance.tabNavBar.selectedIndex).toBe(1);
277+
});
278+
263279
describe('ripples', () => {
264280
let fixture: ComponentFixture<SimpleTabNavBarTestApp>;
265281

0 commit comments

Comments
 (0)