sass-references/angular-material/material/datepicker/testing/calendar-harness.spec.ts

357 lines
14 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import {HarnessLoader, parallel} from '@angular/cdk/testing';
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
import {Component} from '@angular/core';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {MatNativeDateModule} from '@angular/material/core';
import {
DateRange,
DefaultMatCalendarRangeStrategy,
MAT_DATE_RANGE_SELECTION_STRATEGY,
MatDatepickerModule,
} from '@angular/material/datepicker';
import {CalendarView, MatCalendarHarness} from './calendar-harness';
/** Date at which the calendars are set. */
const calendarDate = new Date(2020, 7, 1);
describe('MatCalendarHarness', () => {
let fixture: ComponentFixture<CalendarHarnessTest>;
let loader: HarnessLoader;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [MatNativeDateModule, MatDatepickerModule, CalendarHarnessTest],
providers: [
{
// Usually it's the date range picker that provides the default range selection strategy,
// but since we're testing the calendar on its own, we have to provide it manually.
provide: MAT_DATE_RANGE_SELECTION_STRATEGY,
useClass: DefaultMatCalendarRangeStrategy,
},
],
});
fixture = TestBed.createComponent(CalendarHarnessTest);
fixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(fixture);
});
it('should load all calendar harnesses', async () => {
const calendars = await loader.getAllHarnesses(MatCalendarHarness);
expect(calendars.length).toBe(2);
});
it('should go to a different view', async () => {
const calendar = await loader.getHarness(MatCalendarHarness.with({selector: '#single'}));
expect(await calendar.getCurrentView()).toBe(CalendarView.MONTH);
await calendar.changeView();
expect(await calendar.getCurrentView()).toBe(CalendarView.MULTI_YEAR);
});
it('should get the current view label', async () => {
const calendar = await loader.getHarness(MatCalendarHarness.with({selector: '#single'}));
expect(await calendar.getCurrentViewLabel()).toBe('AUG 2020');
await calendar.changeView();
expect(await calendar.getCurrentViewLabel()).toBe('2016 2039');
});
it('should go to the next page in the view', async () => {
const calendar = await loader.getHarness(MatCalendarHarness.with({selector: '#single'}));
expect(await calendar.getCurrentViewLabel()).toBe('AUG 2020');
await calendar.next();
expect(await calendar.getCurrentViewLabel()).toBe('SEP 2020');
});
it('should go to the previous page in the view', async () => {
const calendar = await loader.getHarness(MatCalendarHarness.with({selector: '#single'}));
expect(await calendar.getCurrentViewLabel()).toBe('AUG 2020');
await calendar.previous();
expect(await calendar.getCurrentViewLabel()).toBe('JUL 2020');
});
it('should get all of the date cells inside the calendar', async () => {
const calendar = await loader.getHarness(MatCalendarHarness.with({selector: '#single'}));
expect((await calendar.getCells()).length).toBe(31);
});
it('should get the text of a calendar cell', async () => {
const calendar = await loader.getHarness(MatCalendarHarness.with({selector: '#single'}));
const cells = await calendar.getCells();
expect(await cells[0].getText()).toBe('1');
expect(await cells[15].getText()).toBe('16');
expect(await cells[30].getText()).toBe('31');
});
it('should be able to select a specific cell through the calendar', async () => {
const calendar = await loader.getHarness(MatCalendarHarness.with({selector: '#single'}));
const targetCell = (await calendar.getCells({text: '16'}))[0];
expect(await targetCell.isSelected()).toBe(false);
await calendar.selectCell({text: '16'});
expect(await targetCell.isSelected()).toBe(true);
});
it('should get the aria-label of a cell', async () => {
const calendar = await loader.getHarness(MatCalendarHarness.with({selector: '#single'}));
const cells = await calendar.getCells();
expect(await cells[0].getAriaLabel()).toBe('August 1, 2020');
expect(await cells[15].getAriaLabel()).toBe('August 16, 2020');
expect(await cells[30].getAriaLabel()).toBe('August 31, 2020');
});
it('should get the disabled state of a cell', async () => {
fixture.componentInstance.minDate = new Date(
calendarDate.getFullYear(),
calendarDate.getMonth(),
20,
);
fixture.changeDetectorRef.markForCheck();
const calendar = await loader.getHarness(MatCalendarHarness.with({selector: '#single'}));
const cells = await calendar.getCells();
expect(await cells[0].isDisabled()).toBe(true);
expect(await cells[15].isDisabled()).toBe(true);
expect(await cells[30].isDisabled()).toBe(false);
});
it('should select a cell', async () => {
const calendar = await loader.getHarness(MatCalendarHarness.with({selector: '#single'}));
const cell = (await calendar.getCells())[10];
expect(await cell.isSelected()).toBe(false);
await cell.select();
expect(await cell.isSelected()).toBe(true);
});
it('should get whether a cell is active', async () => {
const calendar = await loader.getHarness(MatCalendarHarness.with({selector: '#single'}));
const cells = await calendar.getCells();
expect(await cells[0].isActive()).toBe(true);
expect(await cells[15].isActive()).toBe(false);
});
it('should get the state of the cell within the main range', async () => {
const calendar = await loader.getHarness(MatCalendarHarness.with({selector: '#range'}));
const allCells = await calendar.getCells();
const [initialStartStates, initialInRangeStates, initialEndStates] = await parallel(() => [
parallel(() => allCells.map(cell => cell.isRangeStart())),
parallel(() => allCells.map(cell => cell.isInRange())),
parallel(() => allCells.map(cell => cell.isRangeEnd())),
]);
expect(initialStartStates.every(state => state === false)).toBe(true);
expect(initialInRangeStates.every(state => state === false)).toBe(true);
expect(initialEndStates.every(state => state === false)).toBe(true);
await (await calendar.getCells({text: '5'}))[0].select();
await (await calendar.getCells({text: '8'}))[0].select();
expect(await allCells[4].isRangeStart()).toBe(true);
expect(await allCells[4].isInRange()).toBe(true);
expect(await allCells[4].isRangeEnd()).toBe(false);
expect(await allCells[5].isRangeStart()).toBe(false);
expect(await allCells[5].isInRange()).toBe(true);
expect(await allCells[5].isRangeEnd()).toBe(false);
expect(await allCells[6].isRangeStart()).toBe(false);
expect(await allCells[6].isInRange()).toBe(true);
expect(await allCells[6].isRangeEnd()).toBe(false);
expect(await allCells[7].isRangeStart()).toBe(false);
expect(await allCells[7].isInRange()).toBe(true);
expect(await allCells[7].isRangeEnd()).toBe(true);
});
it('should get the state of the cell within the comparison range', async () => {
const calendar = await loader.getHarness(MatCalendarHarness.with({selector: '#range'}));
const allCells = await calendar.getCells();
const [initialStartStates, initialInRangeStates, initialEndStates] = await parallel(() => [
parallel(() => allCells.map(cell => cell.isComparisonRangeStart())),
parallel(() => allCells.map(cell => cell.isInComparisonRange())),
parallel(() => allCells.map(cell => cell.isComparisonRangeEnd())),
]);
expect(initialStartStates.every(state => state === false)).toBe(true);
expect(initialInRangeStates.every(state => state === false)).toBe(true);
expect(initialEndStates.every(state => state === false)).toBe(true);
fixture.componentInstance.comparisonStart = new Date(
calendarDate.getFullYear(),
calendarDate.getMonth(),
5,
);
fixture.componentInstance.comparisonEnd = new Date(
calendarDate.getFullYear(),
calendarDate.getMonth(),
8,
);
fixture.changeDetectorRef.markForCheck();
expect(await allCells[4].isComparisonRangeStart()).toBe(true);
expect(await allCells[4].isInComparisonRange()).toBe(true);
expect(await allCells[4].isComparisonRangeEnd()).toBe(false);
expect(await allCells[5].isComparisonRangeStart()).toBe(false);
expect(await allCells[5].isInComparisonRange()).toBe(true);
expect(await allCells[5].isComparisonRangeEnd()).toBe(false);
expect(await allCells[6].isComparisonRangeStart()).toBe(false);
expect(await allCells[6].isInComparisonRange()).toBe(true);
expect(await allCells[6].isComparisonRangeEnd()).toBe(false);
expect(await allCells[7].isComparisonRangeStart()).toBe(false);
expect(await allCells[7].isInComparisonRange()).toBe(true);
expect(await allCells[7].isComparisonRangeEnd()).toBe(true);
});
it('should get the state of the cell within the preview range', async () => {
const calendar = await loader.getHarness(MatCalendarHarness.with({selector: '#range'}));
const allCells = await calendar.getCells();
const [initialStartStates, initialInRangeStates, initialEndStates] = await parallel(() => [
parallel(() => allCells.map(cell => cell.isPreviewRangeStart())),
parallel(() => allCells.map(cell => cell.isInPreviewRange())),
parallel(() => allCells.map(cell => cell.isPreviewRangeEnd())),
]);
expect(initialStartStates.every(state => state === false)).toBe(true);
expect(initialInRangeStates.every(state => state === false)).toBe(true);
expect(initialEndStates.every(state => state === false)).toBe(true);
await (await calendar.getCells({text: '5'}))[0].select();
await (await calendar.getCells({text: '8'}))[0].hover();
expect(await allCells[4].isPreviewRangeStart()).toBe(true);
expect(await allCells[4].isInPreviewRange()).toBe(true);
expect(await allCells[4].isPreviewRangeEnd()).toBe(false);
expect(await allCells[5].isPreviewRangeStart()).toBe(false);
expect(await allCells[5].isInPreviewRange()).toBe(true);
expect(await allCells[5].isPreviewRangeEnd()).toBe(false);
expect(await allCells[6].isPreviewRangeStart()).toBe(false);
expect(await allCells[6].isInPreviewRange()).toBe(true);
expect(await allCells[6].isPreviewRangeEnd()).toBe(false);
expect(await allCells[7].isPreviewRangeStart()).toBe(false);
expect(await allCells[7].isInPreviewRange()).toBe(true);
expect(await allCells[7].isPreviewRangeEnd()).toBe(true);
});
it('should filter cells by their text', async () => {
const calendar = await loader.getHarness(MatCalendarHarness.with({selector: '#single'}));
const cells = await calendar.getCells({text: /^3/});
expect(await parallel(() => cells.map(cell => cell.getText()))).toEqual(['3', '30', '31']);
});
it('should filter cells by their selected state', async () => {
const calendar = await loader.getHarness(MatCalendarHarness.with({selector: '#single'}));
const allCells = await calendar.getCells();
await allCells[0].select();
const selectedCells = await calendar.getCells({selected: true});
expect(await parallel(() => selectedCells.map(cell => cell.getText()))).toEqual(['1']);
});
it('should filter cells by their active state', async () => {
const calendar = await loader.getHarness(MatCalendarHarness.with({selector: '#single'}));
const cells = await calendar.getCells({active: true});
expect(await parallel(() => cells.map(cell => cell.getText()))).toEqual(['1']);
});
it('should filter cells by their disabled state', async () => {
fixture.componentInstance.minDate = new Date(
calendarDate.getFullYear(),
calendarDate.getMonth(),
3,
);
fixture.changeDetectorRef.markForCheck();
const calendar = await loader.getHarness(MatCalendarHarness.with({selector: '#single'}));
const cells = await calendar.getCells({disabled: true});
expect(await parallel(() => cells.map(cell => cell.getText()))).toEqual(['1', '2']);
});
it('should filter cells based on whether they are inside the comparison range', async () => {
const calendar = await loader.getHarness(MatCalendarHarness.with({selector: '#range'}));
fixture.componentInstance.comparisonStart = new Date(
calendarDate.getFullYear(),
calendarDate.getMonth(),
5,
);
fixture.componentInstance.comparisonEnd = new Date(
calendarDate.getFullYear(),
calendarDate.getMonth(),
8,
);
fixture.changeDetectorRef.markForCheck();
const cells = await calendar.getCells({inComparisonRange: true});
expect(await parallel(() => cells.map(cell => cell.getText()))).toEqual(['5', '6', '7', '8']);
});
it('should filter cells based on whether they are inside the preview range', async () => {
const calendar = await loader.getHarness(MatCalendarHarness.with({selector: '#range'}));
await (await calendar.getCells({text: '5'}))[0].select();
await (await calendar.getCells({text: '8'}))[0].hover();
const cells = await calendar.getCells({inPreviewRange: true});
expect(await parallel(() => cells.map(cell => cell.getText()))).toEqual(['5', '6', '7', '8']);
});
});
@Component({
template: `
<mat-calendar
id="single"
[startAt]="startAt"
[minDate]="minDate"
[selected]="singleValue"
(selectedChange)="singleValue = $event"></mat-calendar>
<mat-calendar
id="range"
[startAt]="startAt"
[minDate]="minDate"
[selected]="rangeValue"
[comparisonStart]="comparisonStart"
[comparisonEnd]="comparisonEnd"
(selectedChange)="rangeChanged($event)"></mat-calendar>
`,
standalone: true,
imports: [MatNativeDateModule, MatDatepickerModule],
})
class CalendarHarnessTest {
// Start the datepickers off at a specific date so tests
// run consistently no matter what the current date is.
readonly startAt = new Date(calendarDate);
minDate: Date | null;
singleValue: Date | null = null;
rangeValue = new DateRange<Date>(null, null);
comparisonStart: Date | null = null;
comparisonEnd: Date | null = null;
rangeChanged(selectedDate: Date) {
let {start, end} = this.rangeValue;
if (start == null || end != null) {
start = selectedDate;
} else if (end == null) {
end = selectedDate;
}
this.rangeValue = new DateRange<Date>(start, end);
}
}