ant-design/components/date-picker/__tests__/DatePicker.test.tsx
二货爱吃白萝卜 fe314589ed
refactor: New Picker interactive (#46685)
* chore: init

* chore: link picker

* chore: move files

* chore: update style

* chore: update types

* test: update snapshot

* test: update snapshot

* test: update snapshot

* test: update snapshot

* test: update snapshot

* test: fix test case

* test: update snapshot

* test: update snapshot

* test: update snapshot

* test: update snapshot

* chore: clesn up useless types

* chore: update types

* chore: fix types

* chore: fix types

* chore: fix types

* chore: fix types

* chore: fix types

* chore: fix types

* chore: fix types

* chore: fix types

* chore: fix types

* chore: update style

* chore: clean up

* chore: update types

* test: update snapshot

* test: update snapshot

* test: update snapshot

* test: update snapshot

* fix: format

* chore: update deps

* chore: feature merge master (#46794)

* fix: Fix typo s/Notificaiton/Notification/ (#46775)

* docs: supplement form preserve field description (#46788)

close https://github.com/ant-design/ant-design/issues/46773

* docs: tweak changelog drawer width in small screen (#46791)

* docs: Update compatible-style.zh-CN.md (#46790)

Signed-off-by: afc163 <afc163@gmail.com>

---------

Signed-off-by: afc163 <afc163@gmail.com>
Co-authored-by: hugo-syn <61210734+hugo-syn@users.noreply.github.com>
Co-authored-by: Shunze Chen <qianlonwork@outlook.com>
Co-authored-by: afc163 <afc163@gmail.com>

* chore: update locale size

* chore: lock dumi

* test: update snapshot

* test: update snapshot

* test: update snapshot

* test: update snapshot

* test: update snapshot

* test: update snapshot

* chore: bump version

* test: update snapshot

* test: update snapshot

* chore: bump version

* chore: update limit

* test: update snapshot

* docs: update 7 days sample

* chore: rm useless style

* chore: clean up style

* docs: add buddihist era demo

* refactor: interface

* chore: add multiple types

* docs: add demo

* chore: init style

* chore: init style

* chore: fill style

* chore: fill style

* chore: style

* chore: size of it

* chore: size style

* docs: add align demo

* docs: needConfirm

* chore: fix showWeek style

* test: update snapshot

* chore: fix ts

* chore: fix ts

* chore: fix ts

* chore: fix ts

* fix: week style

* docs: update dayjs note

* fix: style missing

* chore: fix footer extra style missing

* test: update snapshot

* test: update snapshot

* test: update snapshot

* test: update snapshot

---------

Signed-off-by: afc163 <afc163@gmail.com>
Signed-off-by: lijianan <574980606@qq.com>
Co-authored-by: hugo-syn <61210734+hugo-syn@users.noreply.github.com>
Co-authored-by: Shunze Chen <qianlonwork@outlook.com>
Co-authored-by: afc163 <afc163@gmail.com>
Co-authored-by: lijianan <574980606@qq.com>
2024-01-15 15:41:40 +08:00

452 lines
15 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import type { TriggerProps } from '@rc-component/trigger';
import dayjs from 'dayjs';
import 'dayjs/locale/mk'; // to test local in 'prop locale should works' test case
import React from 'react';
import { CloseCircleFilled } from '@ant-design/icons';
import userEvent from '@testing-library/user-event';
import customParseFormat from 'dayjs/plugin/customParseFormat';
import MockDate from 'mockdate';
import dayJsGenerateConfig from 'rc-picker/lib/generate/dayjs';
import DatePicker from '..';
import { resetWarned } from '../../_util/warning';
import focusTest from '../../../tests/shared/focusTest';
import { fireEvent, render, screen, waitFor } from '../../../tests/utils';
import type { PickerLocale } from '../generatePicker';
import { closeCircleByRole, expectCloseCircle } from './utils';
dayjs.extend(customParseFormat);
let triggerProps: TriggerProps;
jest.mock('@rc-component/trigger', () => {
let Trigger = jest.requireActual('@rc-component/trigger/lib/mock');
Trigger = Trigger.default || Trigger;
const h: typeof React = jest.requireActual('react');
return {
default: h.forwardRef<HTMLElement, TriggerProps>((props, ref) => {
triggerProps = props;
return h.createElement(Trigger, { ref, ...props });
}),
__esModule: true,
};
});
function getCell(text: string) {
const cells = Array.from(document.querySelectorAll('.ant-picker-cell'));
return cells.find((cell) => cell.textContent === text);
}
describe('DatePicker', () => {
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
focusTest(DatePicker, { refFocus: true });
beforeEach(() => {
MockDate.set(dayjs('2016-11-22').valueOf());
});
afterEach(() => {
MockDate.reset();
errorSpy.mockReset();
});
afterAll(() => {
errorSpy.mockRestore();
});
it('prop locale should works', () => {
const locale = {
lang: {
locale: 'mk',
placeholder: 'Избери дата',
rangePlaceholder: ['Начална дата', 'Крайна дата'],
today: 'Днес',
now: 'Сега',
backToToday: 'Към днес',
ok: 'Добре',
clear: 'Изчистване',
month: 'Месец',
year: 'Година',
timeSelect: 'Избор на час',
dateSelect: 'Избор на дата',
monthSelect: 'Избор на месец',
yearSelect: 'Избор на година',
decadeSelect: 'Десетилетие',
previousMonth: 'Предишен месец (PageUp)',
nextMonth: 'Следващ месец (PageDown)',
previousYear: 'Последна година (Control + left)',
nextYear: 'Следваща година (Control + right)',
previousDecade: 'Предишно десетилетие',
nextDecade: 'Следващо десетилетие',
previousCentury: 'Последен век',
nextCentury: 'Следващ век',
yearFormat: 'YYYY',
dateFormat: 'D M YYYY',
dayFormat: 'D',
dateTimeFormat: 'D M YYYY HH:mm:ss',
monthBeforeYear: true,
},
timePickerLocale: {
placeholder: 'Избор на час',
},
};
const birthday = dayjs('2000-01-01', 'YYYY-MM-DD');
const wrapper = render(<DatePicker open locale={locale as PickerLocale} value={birthday} />);
expect(Array.from(wrapper.container.children)).toMatchSnapshot();
});
it('disabled date', () => {
const disabledDate = (current: any) => current && current < dayjs().endOf('day');
render(<DatePicker disabledDate={disabledDate} open />);
expect(getCell('21')).toHaveClass('ant-picker-cell-disabled');
expect(getCell('23')).not.toHaveClass('ant-picker-cell-disabled');
});
it('placeholder', () => {
const wrapper = render(<DatePicker placeholder={undefined} />);
expect(wrapper.container.querySelector('input')?.placeholder).toEqual('Select date');
});
it('showTime={{ showHour: true, showMinute: true }}', () => {
const { container } = render(
<DatePicker
defaultValue={dayjs()}
showTime={{ showHour: true, showMinute: true }}
format="YYYY-MM-DD"
open
/>,
);
expect(container.querySelectorAll('.ant-picker-time-panel-column').length).toBe(2);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[0]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(24);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[1]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(60);
});
it('showTime={{ showMinute: true, showSecond: true }}', () => {
const { container } = render(
<DatePicker
defaultValue={dayjs()}
showTime={{ showMinute: true, showSecond: true }}
format="YYYY-MM-DD"
open
/>,
);
expect(container.querySelectorAll('.ant-picker-time-panel-column').length).toBe(2);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[0]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(60);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[1]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(60);
});
it('showTime={{ showHour: true, showMinute: true, showSecond: true }}', () => {
const { container } = render(
<DatePicker
defaultValue={dayjs()}
showTime={{ showHour: true, showMinute: true, showSecond: true }}
format="YYYY-MM-DD"
open
/>,
);
expect(container.querySelectorAll('.ant-picker-time-panel-column').length).toBe(3);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[0]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(24);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[1]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(60);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[2]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(60);
});
it('showTime={{ showHour: true, showSecond: true }}', () => {
const { container } = render(
<DatePicker
defaultValue={dayjs()}
showTime={{ showHour: true, showSecond: true }}
format="YYYY-MM-DD"
open
/>,
);
expect(container.querySelectorAll('.ant-picker-time-panel-column').length).toBe(2);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[0]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(24);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[1]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(60);
});
it('showTime={{ showSecond: true }}', () => {
const { container } = render(
<DatePicker
defaultValue={dayjs()}
showTime={{ showSecond: true }}
format="YYYY-MM-DD"
open
/>,
);
expect(container.querySelectorAll('.ant-picker-time-panel-column').length).toBe(1);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[0]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(60);
});
it('showTime={{ showMinute: true }}', () => {
const { container } = render(
<DatePicker
defaultValue={dayjs()}
showTime={{ showMinute: true }}
format="YYYY-MM-DD"
open
/>,
);
expect(container.querySelectorAll('.ant-picker-time-panel-column').length).toBe(1);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[0]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(60);
});
it('showTime={{ showHour: true }}', () => {
const { container } = render(
<DatePicker defaultValue={dayjs()} showTime={{ showHour: true }} format="YYYY-MM-DD" open />,
);
expect(container.querySelectorAll('.ant-picker-time-panel-column').length).toBe(1);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[0]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(24);
});
it('showTime={{ }} (no true args)', () => {
const { container } = render(
<DatePicker defaultValue={dayjs()} showTime={{}} format="YYYY-MM-DD" open />,
);
expect(container.querySelectorAll('.ant-picker-time-panel-column')).toHaveLength(3);
});
it('showTime should work correctly when format is custom function', () => {
const { container } = render(
<DatePicker
defaultValue={dayjs()}
showTime
format={(val) => val.format('YYYY-MM-DD')}
open
/>,
);
const focusEvent = () => {
fireEvent.focus(container.querySelector('input')!);
};
const mouseDownEvent = () => {
fireEvent.mouseDown(container.querySelector('input')!);
};
expect(focusEvent).not.toThrow();
expect(mouseDownEvent).not.toThrow();
});
it('showTime should work correctly when format is Array', () => {
const { container } = render(
<DatePicker defaultValue={dayjs()} showTime format={['YYYY-MM-DD HH:mm']} open />,
);
const fuousEvent = () => {
fireEvent.focus(container.querySelector('input')!);
};
const mouseDownEvent = () => {
fireEvent.mouseDown(container.querySelector('input')!);
};
expect(fuousEvent).not.toThrow();
expect(mouseDownEvent).not.toThrow();
});
it('12 hours', () => {
const { container } = render(
<DatePicker defaultValue={dayjs()} showTime format="YYYY-MM-DD HH:mm:ss A" open />,
);
expect(container.querySelectorAll('.ant-picker-time-panel-column').length).toBe(4);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[0]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(12);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[1]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(60);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[2]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(60);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[3]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(2);
});
it('24 hours', () => {
const { container } = render(
<DatePicker defaultValue={dayjs()} showTime format="YYYY-MM-DD HH:mm:ss" open />,
);
expect(container.querySelectorAll('.ant-picker-time-panel-column').length).toBe(3);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[0]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(24);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[1]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(60);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[2]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(60);
});
it('DatePicker.RangePicker with defaultValue and showTime', () => {
const startDate = dayjs('1982-02-12');
const endDate = dayjs('1982-02-22');
const { container } = render(
<DatePicker.RangePicker defaultValue={[startDate, endDate]} showTime open />,
);
const m = container.querySelector('.ant-picker-header-view .ant-picker-month-btn')?.innerHTML;
const y = container.querySelector('.ant-picker-header-view .ant-picker-year-btn')?.innerHTML;
expect(m).toBe(startDate.format('MMM'));
expect(y).toBe(startDate.format('YYYY'));
expect(container.querySelectorAll('.ant-picker-time-panel').length).toBe(1);
});
it('placement api work correctly', () => {
const { rerender } = render(<DatePicker.RangePicker open placement="topLeft" />);
expect(triggerProps?.builtinPlacements).toEqual(
expect.objectContaining({
topLeft: expect.objectContaining({ offset: [0, -4], points: ['bl', 'tl'] }),
}),
);
rerender(<DatePicker.RangePicker open placement="topRight" />);
expect(triggerProps?.builtinPlacements).toEqual(
expect.objectContaining({
topRight: expect.objectContaining({ offset: [0, -4], points: ['br', 'tr'] }),
}),
);
rerender(<DatePicker.RangePicker open placement="bottomLeft" />);
expect(triggerProps?.builtinPlacements).toEqual(
expect.objectContaining({
bottomLeft: expect.objectContaining({ offset: [0, 4], points: ['tl', 'bl'] }),
}),
);
rerender(<DatePicker.RangePicker open placement="bottomRight" />);
expect(triggerProps?.builtinPlacements).toEqual(
expect.objectContaining({
bottomRight: expect.objectContaining({ offset: [0, 4], points: ['tr', 'br'] }),
}),
);
});
it('legacy dropdownClassName', () => {
resetWarned();
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
const { container } = render(<DatePicker dropdownClassName="legacy" open />);
expect(errSpy).toHaveBeenCalledWith(
'Warning: [antd: DatePicker] `dropdownClassName` is deprecated. Please use `popupClassName` instead.',
);
expect(container.querySelector('.legacy')).toBeTruthy();
errSpy.mockRestore();
});
it('support DatePicker.generatePicker', () => {
const MyDatePicker = DatePicker.generatePicker(dayJsGenerateConfig);
const { container } = render(<MyDatePicker />);
expect(container.firstChild).toMatchSnapshot();
});
it('kk:mm format', () => {
const { container } = render(
<DatePicker defaultValue={dayjs()} format="kk:mm" showTime open />,
);
expect(container.querySelectorAll('.ant-picker-time-panel-column')).toHaveLength(2);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[0]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(24);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[1]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(60);
});
it('allows or prohibits clearing as applicable', async () => {
const somepoint = dayjs('2023-08-01');
const { rerender } = render(<DatePicker value={somepoint} />);
const { role, options } = closeCircleByRole;
await userEvent.hover(screen.getByRole(role, options));
await waitFor(() => expectCloseCircle(true));
rerender(<DatePicker value={somepoint} allowClear={false} />);
await waitFor(() => expectCloseCircle(false));
rerender(<DatePicker value={somepoint} allowClear={{ clearIcon: <CloseCircleFilled /> }} />);
await waitFor(() => expectCloseCircle(true));
rerender(
<DatePicker
value={somepoint}
allowClear={{ clearIcon: <div data-testid="custom-clear" /> }}
/>,
);
await waitFor(() => expectCloseCircle(false));
await userEvent.hover(screen.getByTestId('custom-clear'));
rerender(<DatePicker value={somepoint} allowClear={{}} />);
await waitFor(() => expectCloseCircle(true));
});
});