Skip to content

test(material-experimental/mdc-list): add missing test coverage #20771

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 1 commit into from
Oct 14, 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
12 changes: 12 additions & 0 deletions src/material-experimental/mdc-checkbox/checkbox.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ describe('MDC-based MatCheckbox', () => {
expect(inputElement.checked).toBe(false);
}));

it('should expose the ripple instance', () => {
expect(checkboxInstance.ripple).toBeTruthy();
});

it('should toggle checkbox ripple disabledness correctly', fakeAsync(() => {
const rippleSelector = '.mat-ripple-element:not(.mat-checkbox-persistent-ripple)';
Expand Down Expand Up @@ -189,6 +192,15 @@ describe('MDC-based MatCheckbox', () => {
expect(testComponent.isIndeterminate).toBe(true);
}));

it('should change native element checked when check programmatically', () => {
expect(inputElement.checked).toBe(false);

checkboxInstance.checked = true;
fixture.detectChanges();

expect(inputElement.checked).toBe(true);
});

it('should toggle checked state on click', fakeAsync(() => {
expect(checkboxInstance.checked).toBe(false);

Expand Down
4 changes: 4 additions & 0 deletions src/material-experimental/mdc-checkbox/checkbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
mixinDisabled,
CanColor,
CanDisable,
MatRipple,
} from '@angular/material-experimental/mdc-core';
import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations';
import {MDCCheckboxAdapter, MDCCheckboxFoundation} from '@material/checkbox';
Expand Down Expand Up @@ -190,6 +191,9 @@ export class MatCheckbox extends _MatCheckboxMixinBase implements AfterViewInit,
/** The native label element. */
@ViewChild('label') _label: ElementRef<HTMLElement>;

/** Reference to the ripple instance of the checkbox. */
@ViewChild(MatRipple) ripple: MatRipple;

/** Returns the unique id for the visual hidden input. */
get inputId(): string {
return `${this.id || this._uniqueId}-input`;
Expand Down
10 changes: 10 additions & 0 deletions src/material-experimental/mdc-list/list-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion';
import {Platform} from '@angular/cdk/platform';
import {
AfterContentInit,
ContentChildren,
Directive,
ElementRef,
HostBinding,
Expand All @@ -24,6 +25,7 @@ import {
RippleTarget,
setLines,
} from '@angular/material-experimental/mdc-core';
import {MatListAvatarCssMatStyler, MatListIconCssMatStyler} from './list-styling';
import {Subscription} from 'rxjs';
import {startWith} from 'rxjs/operators';

Expand All @@ -47,6 +49,9 @@ export abstract class MatListItemBase implements AfterContentInit, OnDestroy, Ri
/** Host element for the list item. */
_hostElement: HTMLElement;

@ContentChildren(MatListAvatarCssMatStyler, {descendants: false}) _avatars: QueryList<never>;
@ContentChildren(MatListIconCssMatStyler, {descendants: false}) _icons: QueryList<never>;

@Input()
get disableRipple(): boolean {
return this.disabled || this._disableRipple || this._listBase.disableRipple;
Expand Down Expand Up @@ -110,6 +115,11 @@ export abstract class MatListItemBase implements AfterContentInit, OnDestroy, Ri
return this._itemText ? (this._itemText.nativeElement.textContent || '') : '';
}

/** Whether the list item has icons or avatars. */
_hasIconOrAvatar() {
return this._avatars.length || this._icons.length;
}

private _initInteractiveListItem() {
this._hostElement.classList.add('mat-mdc-list-item-interactive');
this._rippleRenderer =
Expand Down
9 changes: 0 additions & 9 deletions src/material-experimental/mdc-list/list-option.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import {
ViewEncapsulation
} from '@angular/core';
import {MatLine, ThemePalette} from '@angular/material-experimental/mdc-core';
import {MatListAvatarCssMatStyler, MatListIconCssMatStyler} from './list';
import {MatListBase, MatListItemBase} from './list-base';

/**
Expand Down Expand Up @@ -87,9 +86,6 @@ export class MatListOption extends MatListItemBase implements OnInit, OnDestroy
@ContentChildren(MatLine, {read: ElementRef, descendants: true}) lines:
QueryList<ElementRef<Element>>;

@ContentChildren(MatListAvatarCssMatStyler, {descendants: false}) _avatars: QueryList<never>;
@ContentChildren(MatListIconCssMatStyler, {descendants: false}) _icons: QueryList<never>;

/** Unique id for the text. Used for describing the underlying checkbox input. */
_optionTextId: string = `mat-mdc-list-option-text-${uniqueId++}`;

Expand Down Expand Up @@ -194,11 +190,6 @@ export class MatListOption extends MatListItemBase implements OnInit, OnDestroy
return this._selectionList.multiple;
}

/** Whether the list-option has icons or avatars. */
_hasIconOrAvatar() {
return this._avatars.length || this._icons.length;
}

_handleBlur() {
this._selectionList._onTouched();
}
Expand Down
42 changes: 42 additions & 0 deletions src/material-experimental/mdc-list/list-styling.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {Directive} from '@angular/core';

/**
* Directive whose purpose is to add the mat- CSS styling to this selector.
* @docs-private
*/
@Directive({
selector: '[mat-list-avatar], [matListAvatar]',
host: {'class': 'mat-mdc-list-avatar mdc-list-item__graphic'}
})
export class MatListAvatarCssMatStyler {}

/**
* Directive whose purpose is to add the mat- CSS styling to this selector.
* @docs-private
*/
@Directive({
selector: '[mat-list-icon], [matListIcon]',
host: {'class': 'mat-mdc-list-icon mdc-list-item__graphic'}
})
export class MatListIconCssMatStyler {}

/**
* Directive whose purpose is to add the mat- CSS styling to this selector.
* @docs-private
*/
@Directive({
selector: '[mat-subheader], [matSubheader]',
// TODO(mmalerba): MDC's subheader font looks identical to the list item font, figure out why and
// make a change in one of the repos to visually distinguish.
host: {'class': 'mat-mdc-subheader mdc-list-group__subheader'}
})
export class MatListSubheaderCssMatStyler {}

15 changes: 12 additions & 3 deletions src/material-experimental/mdc-list/list.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ describe('MDC-based MatList', () => {
expect(listItem.nativeElement.classList).toContain('mat-mdc-list-item-single-line');
});

it('should apply mat-mdc-2-line class to lists with two lines', () => {
it('should apply a particular class to lists with two lines', () => {
const fixture = TestBed.createComponent(ListWithTwoLineItem);
fixture.detectChanges();

Expand All @@ -42,7 +42,7 @@ describe('MDC-based MatList', () => {
expect(listItems[1].nativeElement.className).toContain('mat-mdc-2-line');
});

it('should apply mat-mdc-3-line class to lists with three lines', () => {
it('should apply a particular class to lists with three lines', () => {
const fixture = TestBed.createComponent(ListWithThreeLineItem);
fixture.detectChanges();

Expand All @@ -51,7 +51,7 @@ describe('MDC-based MatList', () => {
expect(listItems[1].nativeElement.className).toContain('mat-mdc-3-line');
});

it('should apply mat-mdc-multi-line class to lists with more than 3 lines', () => {
it('should apply a particular class to lists with more than 3 lines', () => {
const fixture = TestBed.createComponent(ListWithManyLines);
fixture.detectChanges();

Expand All @@ -60,6 +60,15 @@ describe('MDC-based MatList', () => {
expect(listItems[1].nativeElement.className).toContain('mat-mdc-multi-line');
});

it('should apply a class to list items with avatars', () => {
const fixture = TestBed.createComponent(ListWithAvatar);
fixture.detectChanges();

const listItems = fixture.debugElement.children[0].queryAll(By.css('mat-list-item'));
expect(listItems[0].nativeElement.className).toContain('mat-mdc-list-item-with-avatar');
expect(listItems[1].nativeElement.className).not.toContain('mat-mdc-list-item-with-avatar');
});

it('should have a strong focus indicator configured for all list-items', () => {
const fixture = TestBed.createComponent(ListWithManyLines);
fixture.detectChanges();
Expand Down
34 changes: 1 addition & 33 deletions src/material-experimental/mdc-list/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
ChangeDetectionStrategy,
Component,
ContentChildren,
Directive,
ElementRef,
NgZone,
QueryList, ViewChild,
Expand All @@ -20,38 +19,6 @@ import {
import {MatLine} from '@angular/material-experimental/mdc-core';
import {MatListBase, MatListItemBase} from './list-base';

/**
* Directive whose purpose is to add the mat- CSS styling to this selector.
* @docs-private
*/
@Directive({
selector: '[mat-list-avatar], [matListAvatar]',
host: {'class': 'mat-mdc-list-avatar mdc-list-item__graphic'}
})
export class MatListAvatarCssMatStyler {}

/**
* Directive whose purpose is to add the mat- CSS styling to this selector.
* @docs-private
*/
@Directive({
selector: '[mat-list-icon], [matListIcon]',
host: {'class': 'mat-mdc-list-icon mdc-list-item__graphic'}
})
export class MatListIconCssMatStyler {}

/**
* Directive whose purpose is to add the mat- CSS styling to this selector.
* @docs-private
*/
@Directive({
selector: '[mat-subheader], [matSubheader]',
// TODO(mmalerba): MDC's subheader font looks identical to the list item font, figure out why and
// make a change in one of the repos to visually distinguish.
host: {'class': 'mat-mdc-subheader mdc-list-group__subheader'}
})
export class MatListSubheaderCssMatStyler {}

@Component({
selector: 'mat-list',
exportAs: 'matList',
Expand All @@ -73,6 +40,7 @@ export class MatList extends MatListBase {}
exportAs: 'matListItem',
host: {
'class': 'mat-mdc-list-item mdc-list-item',
'[class.mat-mdc-list-item-with-avatar]': '_hasIconOrAvatar()',
},
templateUrl: 'list-item.html',
encapsulation: ViewEncapsulation.None,
Expand Down
8 changes: 5 additions & 3 deletions src/material-experimental/mdc-list/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@ import {MatDividerModule} from '@angular/material/divider';
import {MatActionList} from './action-list';
import {
MatList,
MatListAvatarCssMatStyler,
MatListIconCssMatStyler,
MatListItem,
MatListSubheaderCssMatStyler,
} from './list';
import {MatNavList} from './nav-list';
import {MatSelectionList} from './selection-list';
import {MatListOption} from './list-option';
import {
MatListAvatarCssMatStyler,
MatListIconCssMatStyler,
MatListSubheaderCssMatStyler,
} from './list-styling';

@NgModule({
imports: [
Expand Down
1 change: 1 addition & 0 deletions src/material-experimental/mdc-list/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ export * from './nav-list';
export * from './selection-list';
export * from './module';
export * from './list-option';
export * from './list-styling';
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,42 @@ describe('MDC-based MatProgressSpinner', () => {
.toBe('0 0 130 130', 'Expected the viewBox to be adjusted based on the stroke width.');
});

it('should allow floating point values for custom diameter', () => {
const fixture = TestBed.createComponent(ProgressSpinnerCustomDiameter);

fixture.componentInstance.diameter = 32.5;
fixture.detectChanges();

const spinner = fixture.debugElement.query(By.css('mat-progress-spinner'))!.nativeElement;
const svgElement: HTMLElement = fixture.nativeElement.querySelector('svg');

expect(parseFloat(spinner.style.width))
.toBe(32.5, 'Expected the custom diameter to be applied to the host element width.');
expect(parseFloat(spinner.style.height))
.toBe(32.5, 'Expected the custom diameter to be applied to the host element height.');
expect(Math.ceil(svgElement.clientWidth))
.toBe(33, 'Expected the custom diameter to be applied to the svg element width.');
expect(Math.ceil(svgElement.clientHeight))
.toBe(33, 'Expected the custom diameter to be applied to the svg element height.');
expect(svgElement.getAttribute('viewBox'))
.toBe('0 0 25.75 25.75', 'Expected the custom diameter to be applied to the svg viewBox.');
});

it('should allow floating point values for custom stroke width', () => {
const fixture = TestBed.createComponent(ProgressSpinnerCustomStrokeWidth);

fixture.componentInstance.strokeWidth = 40.5;
fixture.detectChanges();

const circleElement = fixture.nativeElement.querySelector('circle');
const svgElement = fixture.nativeElement.querySelector('svg');

expect(parseFloat(circleElement.style.strokeWidth)).toBe(40.5, 'Expected the custom stroke ' +
'width to be applied to the circle element as a percentage of the element size.');
expect(svgElement.getAttribute('viewBox'))
.toBe('0 0 130.5 130.5', 'Expected the viewBox to be adjusted based on the stroke width.');
});

it('should expand the host element if the stroke width is greater than the default', () => {
const fixture = TestBed.createComponent(ProgressSpinnerCustomStrokeWidth);
const element = fixture.debugElement.nativeElement.querySelector('.mat-mdc-progress-spinner');
Expand Down
14 changes: 13 additions & 1 deletion src/material-experimental/mdc-snack-bar/snack-bar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ describe('MatSnackBar', () => {
.toBe('polite', 'Expected snack bar container live region to have aria-live="polite"');
});

it('should remove the role if the politeness is turned off', () => {
it('should have aria-live of `off` if the politeness is turned off', () => {
snackBar.openFromComponent(BurritosNotification, {politeness: 'off'});
viewContainerFixture.detectChanges();

Expand Down Expand Up @@ -502,6 +502,18 @@ describe('MatSnackBar', () => {
expect(foundation.destroy).toHaveBeenCalled();
}));

it('should cap the timeout to the maximum accepted delay in setTimeout', fakeAsync(() => {
snackBar.open('content', 'test', {duration: Infinity});
viewContainerFixture.detectChanges();
tick(100);
spyOn(window, 'setTimeout').and.callThrough();
tick(100);

expect(window.setTimeout).toHaveBeenCalledWith(jasmine.any(Function), Math.pow(2, 31) - 1);

flush();
}));

describe('with custom component', () => {
it('should open a custom component', () => {
const snackBarRef = snackBar.openFromComponent(BurritosNotification);
Expand Down
2 changes: 1 addition & 1 deletion src/material/checkbox/checkbox.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1214,7 +1214,7 @@ describe('MatCheckboxDefaultOptions', () => {
TestBed.compileComponents();
});

it('should override default color in Component', () => {
it('should override default color in component', () => {
const fixture: ComponentFixture<SimpleCheckbox> =
TestBed.createComponent(SimpleCheckbox);
fixture.detectChanges();
Expand Down
6 changes: 3 additions & 3 deletions src/material/list/list.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe('MatList', () => {
expect(listItem.nativeElement.classList).toContain('mat-focus-indicator');
});

it('should apply mat-2-line class to lists with two lines', () => {
it('should apply a particular class to lists with two lines', () => {
const fixture = TestBed.createComponent(ListWithTwoLineItem);
fixture.detectChanges();

Expand All @@ -43,7 +43,7 @@ describe('MatList', () => {
expect(listItems[1].nativeElement.className).toContain('mat-2-line');
});

it('should apply mat-3-line class to lists with three lines', () => {
it('should apply a particular class to lists with three lines', () => {
const fixture = TestBed.createComponent(ListWithThreeLineItem);
fixture.detectChanges();

Expand All @@ -52,7 +52,7 @@ describe('MatList', () => {
expect(listItems[1].nativeElement.className).toContain('mat-3-line');
});

it('should apply mat-multi-line class to lists with more than 3 lines', () => {
it('should apply a particular class to lists with more than 3 lines', () => {
const fixture = TestBed.createComponent(ListWithManyLines);
fixture.detectChanges();

Expand Down