sass-references/angular-material/material/timepicker/testing/timepicker-input-harness.sp...

182 lines
6.6 KiB
TypeScript
Raw Permalink Normal View History

2024-12-06 10:42:08 +08:00
import {HarnessLoader, parallel} from '@angular/cdk/testing';
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
import {Component, signal} from '@angular/core';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {DateAdapter, provideNativeDateAdapter} from '@angular/material/core';
import {MatTimepicker, MatTimepickerInput} from '@angular/material/timepicker';
import {MatTimepickerHarness} from './timepicker-harness';
import {MatTimepickerInputHarness} from './timepicker-input-harness';
describe('MatTimepickerInputHarness', () => {
let fixture: ComponentFixture<TimepickerInputHarnessTest>;
let loader: HarnessLoader;
let adapter: DateAdapter<Date>;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [provideNativeDateAdapter()],
imports: [NoopAnimationsModule, TimepickerInputHarnessTest],
});
adapter = TestBed.inject(DateAdapter);
adapter.setLocale('en-US');
fixture = TestBed.createComponent(TimepickerInputHarnessTest);
fixture.detectChanges();
loader = TestbedHarnessEnvironment.loader(fixture);
});
it('should load all timepicker input harnesses', async () => {
const inputs = await loader.getAllHarnesses(MatTimepickerInputHarness);
expect(inputs.length).toBe(2);
});
it('should filter inputs based on their value', async () => {
fixture.componentInstance.value.set(createTime(15, 10));
fixture.changeDetectorRef.markForCheck();
const inputs = await loader.getAllHarnesses(MatTimepickerInputHarness.with({value: /3:10/}));
expect(inputs.length).toBe(1);
});
it('should filter inputs based on their placeholder', async () => {
const inputs = await loader.getAllHarnesses(
MatTimepickerInputHarness.with({
placeholder: /^Pick/,
}),
);
expect(inputs.length).toBe(1);
});
it('should get whether the input is disabled', async () => {
const input = await loader.getHarness(MatTimepickerInputHarness.with({selector: '#bound'}));
expect(await input.isDisabled()).toBe(false);
fixture.componentInstance.disabled.set(true);
expect(await input.isDisabled()).toBe(true);
});
it('should get whether the input is required', async () => {
const input = await loader.getHarness(MatTimepickerInputHarness.with({selector: '#bound'}));
expect(await input.isRequired()).toBe(false);
fixture.componentInstance.required.set(true);
expect(await input.isRequired()).toBe(true);
});
it('should get the input value', async () => {
const input = await loader.getHarness(MatTimepickerInputHarness.with({selector: '#bound'}));
fixture.componentInstance.value.set(createTime(15, 10));
fixture.changeDetectorRef.markForCheck();
expect(await input.getValue()).toBe('3:10 PM');
});
it('should set the input value', async () => {
const input = await loader.getHarness(MatTimepickerInputHarness.with({selector: '#bound'}));
expect(await input.getValue()).toBeFalsy();
await input.setValue('3:10 PM');
expect(await input.getValue()).toBe('3:10 PM');
});
it('should set the input value based on date adapter validation and formatting', async () => {
const input = await loader.getHarness(MatTimepickerInputHarness.with({selector: '#bound'}));
const validValues: any[] = [createTime(15, 10), '', 0, false];
const invalidValues: any[] = [null, undefined];
spyOn(adapter, 'format').and.returnValue('FORMATTED_VALUE');
spyOn(adapter, 'isValid').and.callFake(value => validValues.includes(value));
spyOn(adapter, 'deserialize').and.callFake(value =>
validValues.includes(value) ? value : null,
);
spyOn(adapter, 'getValidDateOrNull').and.callFake((value: Date) =>
adapter.isValid(value) ? value : null,
);
for (let value of validValues) {
fixture.componentInstance.value.set(value);
fixture.changeDetectorRef.markForCheck();
expect(await input.getValue()).toBe('FORMATTED_VALUE');
}
for (let value of invalidValues) {
fixture.componentInstance.value.set(value);
fixture.changeDetectorRef.markForCheck();
expect(await input.getValue()).toBe('');
}
});
it('should get the input placeholder', async () => {
const inputs = await loader.getAllHarnesses(MatTimepickerInputHarness);
expect(await parallel(() => inputs.map(input => input.getPlaceholder()))).toEqual([
'Pick a time',
'Select a time',
]);
});
it('should be able to change the input focused state', async () => {
const input = await loader.getHarness(MatTimepickerInputHarness.with({selector: '#bound'}));
expect(await input.isFocused()).toBe(false);
await input.focus();
expect(await input.isFocused()).toBe(true);
await input.blur();
expect(await input.isFocused()).toBe(false);
});
it('should be able to open and close a timepicker', async () => {
const input = await loader.getHarness(MatTimepickerInputHarness.with({selector: '#bound'}));
expect(await input.isTimepickerOpen()).toBe(false);
await input.openTimepicker();
expect(await input.isTimepickerOpen()).toBe(true);
await input.closeTimepicker();
expect(await input.isTimepickerOpen()).toBe(false);
});
it('should be able to get the harness for the associated timepicker', async () => {
const input = await loader.getHarness(MatTimepickerInputHarness.with({selector: '#bound'}));
await input.openTimepicker();
expect(await input.getTimepicker()).toBeInstanceOf(MatTimepickerHarness);
});
it('should emit the `valueChange` event when the value is changed', async () => {
const input = await loader.getHarness(MatTimepickerInputHarness.with({selector: '#bound'}));
expect(fixture.componentInstance.changeCount).toBe(0);
await input.setValue('3:15 PM');
expect(fixture.componentInstance.changeCount).toBeGreaterThan(0);
});
function createTime(hours: number, minutes: number): Date {
return adapter.setTime(adapter.today(), hours, minutes, 0);
}
});
@Component({
template: `
<input
[matTimepicker]="boundPicker"
[value]="value()"
[disabled]="disabled()"
[required]="required()"
(valueChange)="changeCount = changeCount + 1"
placeholder="Pick a time"
id="bound">
<mat-timepicker #boundPicker/>
<input [matTimepicker]="basicPicker" id="basic" placeholder="Select a time">
<mat-timepicker #basicPicker/>
`,
standalone: true,
imports: [MatTimepickerInput, MatTimepicker],
})
class TimepickerInputHarnessTest {
readonly value = signal<Date | null>(null);
readonly disabled = signal(false);
readonly required = signal(false);
changeCount = 0;
}