Skip to content

test(material-experimental): add missing test coverage #20678

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion scripts/check-mdc-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function getTestNames(files: string[]): string[] {

sourceFile.forEachChild(function walk(node: ts.Node) {
if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) &&
node.expression.text === 'it') {
(node.expression.text === 'it' || node.expression.text === 'xit')) {
// Note that this is a little naive since it'll take the literal text of the test
// name expression which could include things like string concatenation. It's fine
// for the limited use cases of the script.
Expand Down
80 changes: 80 additions & 0 deletions src/material-experimental/mdc-menu/menu.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
QueryList,
Type,
Provider,
ChangeDetectionStrategy,
} from '@angular/core';
import {Direction, Directionality} from '@angular/cdk/bidi';
import {OverlayContainer, Overlay} from '@angular/cdk/overlay';
Expand Down Expand Up @@ -243,6 +244,42 @@ describe('MDC-based MatMenu', () => {
expect(backdrop.classList).toContain('custom-backdrop');
}));


it('should be able to set a custom class on the overlay panel', fakeAsync(() => {
const optionsProvider = {
provide: MAT_MENU_DEFAULT_OPTIONS,
useValue: {overlayPanelClass: 'custom-panel-class'}
};
const fixture = createComponent(SimpleMenu, [optionsProvider], [FakeIcon]);

fixture.detectChanges();
fixture.componentInstance.trigger.openMenu();
fixture.detectChanges();
tick(500);

const overlayPane = <HTMLElement>overlayContainerElement.querySelector('.cdk-overlay-pane');

expect(overlayPane.classList).toContain('custom-panel-class');
}));

it('should be able to set a custom classes on the overlay panel', fakeAsync(() => {
const optionsProvider = {
provide: MAT_MENU_DEFAULT_OPTIONS,
useValue: {overlayPanelClass: ['custom-panel-class-1', 'custom-panel-class-2']}
};
const fixture = createComponent(SimpleMenu, [optionsProvider], [FakeIcon]);

fixture.detectChanges();
fixture.componentInstance.trigger.openMenu();
fixture.detectChanges();
tick(500);

const overlayPane = <HTMLElement>overlayContainerElement.querySelector('.cdk-overlay-pane');

expect(overlayPane.classList).toContain('custom-panel-class-1');
expect(overlayPane.classList).toContain('custom-panel-class-2');
}));

it('should restore focus to the root trigger when the menu was opened by mouse', fakeAsync(() => {
const fixture = createComponent(SimpleMenu, [], [FakeIcon]);
fixture.detectChanges();
Expand Down Expand Up @@ -906,6 +943,25 @@ describe('MDC-based MatMenu', () => {
flush();
}));

it('should open submenus when the menu is inside an OnPush component', fakeAsync(() => {
const fixture = createComponent(LazyMenuWithOnPush);
fixture.detectChanges();

// Open the top-level menu
fixture.componentInstance.rootTrigger.nativeElement.click();
fixture.detectChanges();
flush();

// Dispatch a `mouseenter` on the menu item to open the submenu.
// This will only work if the top-level menu is aware the this menu item exists.
dispatchMouseEvent(fixture.componentInstance.menuItemWithSubmenu.nativeElement, 'mouseenter');
fixture.detectChanges();
flush();

expect(overlayContainerElement.querySelectorAll('.mat-mdc-menu-item').length)
.toBe(2, 'Expected two open menus');
}));

it('should focus the menu panel if all items are disabled', fakeAsync(() => {
const fixture = createComponent(SimpleMenuWithRepeater, [], [FakeIcon]);
fixture.componentInstance.items.forEach(item => item.disabled = true);
Expand Down Expand Up @@ -2588,6 +2644,30 @@ class SimpleMenuWithRepeaterInLazyContent {
}


@Component({
template: `
<button [matMenuTriggerFor]="menu" #triggerEl>Toggle menu</button>

<mat-menu #menu="matMenu">
<ng-template matMenuContent>
<button [matMenuTriggerFor]="menu2" mat-menu-item #menuItem>Item</button>
</ng-template>
</mat-menu>

<mat-menu #menu2="matMenu">
<ng-template matMenuContent>
<button mat-menu-item #subMenuItem>Sub item</button>
</ng-template>
</mat-menu>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
class LazyMenuWithOnPush {
@ViewChild('triggerEl', {read: ElementRef}) rootTrigger: ElementRef;
@ViewChild('menuItem', {read: ElementRef}) menuItemWithSubmenu: ElementRef;
}


@Component({
template: `
<mat-menu #menu="matMenu">
Expand Down
10 changes: 10 additions & 0 deletions src/material-experimental/mdc-radio/radio.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,16 @@ describe('MDC-based MatRadio', () => {
.toBe(4, 'Expected the tabindex to be set to "4".');
});

it('should remove the tabindex from the host element', () => {
const predefinedFixture = TestBed.createComponent(RadioButtonWithPredefinedTabindex);
predefinedFixture.detectChanges();

const radioButtonEl =
predefinedFixture.debugElement.query(By.css('.mat-mdc-radio-button'))!.nativeElement;

expect(radioButtonEl.getAttribute('tabindex')).toBe('-1');
});

it('should set the tabindex to -1 on the host element', () => {
const predefinedFixture = TestBed.createComponent(RadioButtonWithPredefinedTabindex);
predefinedFixture.detectChanges();
Expand Down
71 changes: 71 additions & 0 deletions src/material-experimental/mdc-table/table.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ describe('MDC-based MatTable', () => {
MatTableApp,
MatTableWithWhenRowApp,
ArrayDataSourceMatTableApp,
NativeHtmlTableApp,
MatTableWithSortApp,
MatTableWithPaginatorApp,
StickyTableApp,
Expand Down Expand Up @@ -81,6 +82,21 @@ describe('MDC-based MatTable', () => {
]);
});

it('should be able to render a table correctly with native elements', () => {
let fixture = TestBed.createComponent(NativeHtmlTableApp);
fixture.detectChanges();

const tableElement = fixture.nativeElement.querySelector('table');
const data = fixture.componentInstance.dataSource!.data;
expectTableToMatchContent(tableElement, [
['Column A', 'Column B', 'Column C'],
[data[0].a, data[0].b, data[0].c],
[data[1].a, data[1].b, data[1].c],
[data[2].a, data[2].b, data[2].c],
[data[3].a, data[3].b, data[3].c],
]);
});

it('should be able to nest tables', () => {
const fixture = TestBed.createComponent(NestedTableApp);
fixture.detectChanges();
Expand All @@ -96,6 +112,28 @@ describe('MDC-based MatTable', () => {
expect(innerRows.map(row => row.cells.length)).toEqual([3, 3, 3, 3]);
});

it('should be able to show a message when no data is being displayed in a native table', () => {
const fixture = TestBed.createComponent(NativeHtmlTableApp);
fixture.detectChanges();

// Assert that the data is inside the tbody specifically.
const tbody = fixture.nativeElement.querySelector('tbody')!;
const dataSource = fixture.componentInstance.dataSource!;
const initialData = dataSource.data;

expect(tbody.textContent.trim()).not.toContain('No data');

dataSource.data = [];
fixture.detectChanges();

expect(tbody.textContent.trim()).toContain('No data');

dataSource.data = initialData;
fixture.detectChanges();

expect(tbody.textContent.trim()).not.toContain('No data');
});

it('should be able to show a message when no data is being displayed', () => {
const fixture = TestBed.createComponent(MatTableApp);
fixture.detectChanges();
Expand Down Expand Up @@ -601,6 +639,39 @@ class MatTableApp {
@ViewChild(MatTable) table: MatTable<TestData>;
}

@Component({
template: `
<table mat-table [dataSource]="dataSource">
<ng-container matColumnDef="column_a">
<th mat-header-cell *matHeaderCellDef> Column A</th>
<td mat-cell *matCellDef="let row"> {{row.a}}</td>
</ng-container>

<ng-container matColumnDef="column_b">
<th mat-header-cell *matHeaderCellDef> Column B</th>
<td mat-cell *matCellDef="let row"> {{row.b}}</td>
</ng-container>

<ng-container matColumnDef="column_c">
<th mat-header-cell *matHeaderCellDef> Column C</th>
<td mat-cell *matCellDef="let row"> {{row.c}}</td>
</ng-container>

<tr mat-header-row *matHeaderRowDef="columnsToRender"></tr>
<tr mat-row *matRowDef="let row; columns: columnsToRender"></tr>
<tr *matNoDataRow>
<td>No data</td>
</tr>
</table>
`
})
class NativeHtmlTableApp {
dataSource: FakeDataSource | null = new FakeDataSource();
columnsToRender = ['column_a', 'column_b', 'column_c'];

@ViewChild(MatTable) table: MatTable<TestData>;
}

@Component({
template: `
<table mat-table [dataSource]="dataSource">
Expand Down
16 changes: 16 additions & 0 deletions src/material-experimental/mdc-tabs/tab-nav-bar/tab-nav-bar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,22 @@ describe('MDC-based MatTabNavBar', () => {
expect(tabLink.tabIndex).toBe(3, 'Expected the tabIndex to be have been set to 3.');
});

it('should select the proper tab, if the tabs come in after init', () => {
const fixture = TestBed.createComponent(SimpleTabNavBarTestApp);
const instance = fixture.componentInstance;

instance.tabs = [];
instance.activeIndex = 1;
fixture.detectChanges();

expect(instance.tabNavBar.selectedIndex).toBe(-1);

instance.tabs = [0, 1, 2];
fixture.detectChanges();

expect(instance.tabNavBar.selectedIndex).toBe(1);
});

describe('ripples', () => {
let fixture: ComponentFixture<SimpleTabNavBarTestApp>;

Expand Down