From 6608b191815915e633891c7445e3301a91131259 Mon Sep 17 00:00:00 2001 From: zombiej Date: Sat, 21 Mar 2020 12:47:22 +0800 Subject: [PATCH 1/5] add quarter --- examples/panel.tsx | 12 ++-- src/PickerPanel.tsx | 64 ++++++++----------- src/interface.ts | 17 ++--- src/panels/QuarterPanel/QuarterBody.tsx | 59 ++++++++++++++++++ src/panels/QuarterPanel/QuarterHeader.tsx | 44 +++++++++++++ src/panels/QuarterPanel/index.tsx | 76 +++++++++++++++++++++++ src/utils/dateUtil.ts | 29 +++++++-- src/utils/uiUtil.ts | 27 ++++---- 8 files changed, 249 insertions(+), 79 deletions(-) create mode 100644 src/panels/QuarterPanel/QuarterBody.tsx create mode 100644 src/panels/QuarterPanel/QuarterHeader.tsx create mode 100644 src/panels/QuarterPanel/index.tsx diff --git a/examples/panel.tsx b/examples/panel.tsx index d7d9fdf67..70e0c1cb0 100644 --- a/examples/panel.tsx +++ b/examples/panel.tsx @@ -68,6 +68,11 @@ export default () => { {...sharedProps} locale={zhCN} picker="month" /> +
+

Quarter Picker

+ {...sharedProps} locale={zhCN} picker="quarter" /> +
+

Week Picker US

{...sharedProps} locale={enUS} picker="week" /> @@ -79,12 +84,7 @@ export default () => {

Uncontrolled

- - {...sharedProps} - locale={jaJP} - value={undefined} - picker="time" - /> + {...sharedProps} locale={jaJP} value={undefined} picker="time" />

Time AM/PM

diff --git a/src/PickerPanel.tsx b/src/PickerPanel.tsx index c7e04f584..8c8102dfd 100644 --- a/src/PickerPanel.tsx +++ b/src/PickerPanel.tsx @@ -17,6 +17,7 @@ import DatetimePanel from './panels/DatetimePanel'; import DatePanel from './panels/DatePanel'; import WeekPanel from './panels/WeekPanel'; import MonthPanel from './panels/MonthPanel'; +import QuarterPanel from './panels/QuarterPanel'; import YearPanel from './panels/YearPanel'; import DecadePanel from './panels/DecadePanel'; import { GenerateConfig } from './generate'; @@ -84,13 +85,11 @@ export interface PickerPanelSharedProps { components?: Components; } -export interface PickerPanelBaseProps - extends PickerPanelSharedProps { +export interface PickerPanelBaseProps extends PickerPanelSharedProps { picker: Exclude; } -export interface PickerPanelDateProps - extends PickerPanelSharedProps { +export interface PickerPanelDateProps extends PickerPanelSharedProps { picker?: 'date'; showToday?: boolean; @@ -149,18 +148,11 @@ function PickerPanel(props: PickerPanelProps) { direction, } = props as MergedPickerPanelProps; - const needConfirmButton: boolean = - (picker === 'date' && !!showTime) || picker === 'time'; + const needConfirmButton: boolean = (picker === 'date' && !!showTime) || picker === 'time'; if (process.env.NODE_ENV !== 'production') { - warning( - !value || generateConfig.isValidate(value), - 'Invalidate date pass to `value`.', - ); - warning( - !value || generateConfig.isValidate(value), - 'Invalidate date pass to `defaultValue`.', - ); + warning(!value || generateConfig.isValidate(value), 'Invalidate date pass to `value`.'); + warning(!value || generateConfig.isValidate(value), 'Invalidate date pass to `defaultValue`.'); } // ============================ State ============================= @@ -174,12 +166,7 @@ function PickerPanel(props: PickerPanelProps) { defaultOpenValue, } = panelContext; - const { - inRange, - panelPosition, - rangedValue, - hoverRangedValue, - } = React.useContext(RangeContext); + const { inRange, panelPosition, rangedValue, hoverRangedValue } = React.useContext(RangeContext); const panelRef = React.useRef({}); // Handle init logic @@ -198,10 +185,7 @@ function PickerPanel(props: PickerPanelProps) { }); // View date control - const [viewDate, setInnerViewDate] = useMergedState< - DateType | null, - DateType - >(null, { + const [viewDate, setInnerViewDate] = useMergedState(null, { value: pickerValue, defaultValue: defaultPickerValue || mergedValue, postState: date => date || generateConfig.getNow(), @@ -237,22 +221,14 @@ function PickerPanel(props: PickerPanelProps) { }, ); - const [sourceMode, setSourceMode] = React.useState( - () => mergedMode, - ); + const [sourceMode, setSourceMode] = React.useState(() => mergedMode); - const onInternalPanelChange = ( - newMode: PanelMode | null, - viewValue: DateType, - ) => { + const onInternalPanelChange = (newMode: PanelMode | null, viewValue: DateType) => { const nextMode = getInternalNextMode(newMode || mergedMode); setSourceMode(mergedMode); setInnerMode(nextMode); - if ( - onPanelChange && - (mergedMode !== nextMode || isEqual(generateConfig, viewDate, viewDate)) - ) { + if (onPanelChange && (mergedMode !== nextMode || isEqual(generateConfig, viewDate, viewDate))) { onPanelChange(viewValue, nextMode); } }; @@ -392,6 +368,18 @@ function PickerPanel(props: PickerPanelProps) { ); break; + case 'quarter': + panelNode = ( + + {...pickerProps} + onSelect={(date, type) => { + setViewDate(date); + triggerSelect(date, type); + }} + /> + ); + break; + case 'week': panelNode = ( (props: PickerPanelProps) { (props: PickerPanelProps) {
; @@ -51,10 +52,7 @@ export interface PanelRefProps { export type NullableDateType = DateType | null | undefined; -export type OnSelect = ( - value: DateType, - type: 'key' | 'mouse' | 'submit', -) => void; +export type OnSelect = (value: DateType, type: 'key' | 'mouse' | 'submit') => void; export interface PanelSharedProps { prefixCls: string; @@ -91,15 +89,10 @@ export interface DisabledTimes { export type DisabledTime = (date: DateType | null) => DisabledTimes; -export type OnPanelChange = ( - value: DateType, - mode: PanelMode, -) => void; +export type OnPanelChange = (value: DateType, mode: PanelMode) => void; export type EventValue = DateType | null; -export type RangeValue = - | [EventValue, EventValue] - | null; +export type RangeValue = [EventValue, EventValue] | null; export interface Components { button?: React.ComponentType | string; diff --git a/src/panels/QuarterPanel/QuarterBody.tsx b/src/panels/QuarterPanel/QuarterBody.tsx new file mode 100644 index 000000000..5398612ed --- /dev/null +++ b/src/panels/QuarterPanel/QuarterBody.tsx @@ -0,0 +1,59 @@ +import * as React from 'react'; +import { GenerateConfig } from '../../generate'; +import { Locale } from '../../interface'; +import { isSameQuarter } from '../../utils/dateUtil'; +import RangeContext from '../../RangeContext'; +import useCellClassName from '../../hooks/useCellClassName'; +import PanelBody from '../PanelBody'; + +export const QUARTER_COL_COUNT = 4; +const QUARTER_ROW_COUNT = 1; + +export interface QuarterBodyProps { + prefixCls: string; + locale: Locale; + generateConfig: GenerateConfig; + value?: DateType | null; + viewDate: DateType; + disabledDate?: (date: DateType) => boolean; + onSelect: (value: DateType) => void; +} + +function QuarterBody(props: QuarterBodyProps) { + const { prefixCls, locale, value, viewDate, generateConfig } = props; + + const { rangedValue, hoverRangedValue } = React.useContext(RangeContext); + + const cellPrefixCls = `${prefixCls}-cell`; + + const getCellClassName = useCellClassName({ + cellPrefixCls, + value, + generateConfig, + rangedValue, + hoverRangedValue, + isSameCell: (current, target) => isSameQuarter(generateConfig, current, target), + isInView: () => true, + offsetCell: (date, offset) => generateConfig.addMonth(date, offset * 3), + }); + + const baseQuarter = generateConfig.setDate(generateConfig.setMonth(viewDate, 0), 1); + + return ( + + // generateConfig.locale.format(locale.locale, date, locale.quarterFormat || '\\QQ') + generateConfig.locale.format(locale.locale, date, 'MM') + } + getCellClassName={getCellClassName} + getCellDate={(date, offset) => generateConfig.addMonth(date, offset * 3)} + titleCell={date => generateConfig.locale.format(locale.locale, date, 'YYYY-\\QQ')} + /> + ); +} + +export default QuarterBody; diff --git a/src/panels/QuarterPanel/QuarterHeader.tsx b/src/panels/QuarterPanel/QuarterHeader.tsx new file mode 100644 index 000000000..5a288ca69 --- /dev/null +++ b/src/panels/QuarterPanel/QuarterHeader.tsx @@ -0,0 +1,44 @@ +import * as React from 'react'; +import Header from '../Header'; +import { Locale } from '../../interface'; +import { GenerateConfig } from '../../generate'; +import PanelContext from '../../PanelContext'; + +export interface QuarterHeaderProps { + prefixCls: string; + viewDate: DateType; + locale: Locale; + generateConfig: GenerateConfig; + + onPrevYear: () => void; + onNextYear: () => void; + onYearClick: () => void; +} + +function QuarterHeader(props: QuarterHeaderProps) { + const { + prefixCls, + generateConfig, + locale, + viewDate, + onNextYear, + onPrevYear, + onYearClick, + } = props; + const { hideHeader } = React.useContext(PanelContext); + if (hideHeader) { + return null; + } + + const headerPrefixCls = `${prefixCls}-header`; + + return ( +
+ +
+ ); +} + +export default QuarterHeader; diff --git a/src/panels/QuarterPanel/index.tsx b/src/panels/QuarterPanel/index.tsx new file mode 100644 index 000000000..b21434ccd --- /dev/null +++ b/src/panels/QuarterPanel/index.tsx @@ -0,0 +1,76 @@ +import * as React from 'react'; +import QuarterHeader from './QuarterHeader'; +import QuarterBody, { QUARTER_COL_COUNT } from './QuarterBody'; +import { PanelSharedProps } from '../../interface'; +import { createKeyDownHandler } from '../../utils/uiUtil'; + +export interface MonthPanelProps extends PanelSharedProps {} + +function MonthPanel(props: MonthPanelProps) { + const { + prefixCls, + operationRef, + onViewDateChange, + generateConfig, + value, + viewDate, + onPanelChange, + onSelect, + } = props; + + const panelPrefixCls = `${prefixCls}-month-panel`; + + // ======================= Keyboard ======================= + operationRef.current = { + onKeyDown: event => + createKeyDownHandler(event, { + onLeftRight: diff => { + onSelect(generateConfig.addMonth(value || viewDate, diff), 'key'); + }, + onCtrlLeftRight: diff => { + onSelect(generateConfig.addYear(value || viewDate, diff), 'key'); + }, + onUpDown: diff => { + onSelect(generateConfig.addMonth(value || viewDate, diff * QUARTER_COL_COUNT), 'key'); + }, + onEnter: () => { + onPanelChange('date', value || viewDate); + }, + }), + }; + + // ==================== View Operation ==================== + const onYearChange = (diff: number) => { + const newDate = generateConfig.addYear(viewDate, diff); + onViewDateChange(newDate); + onPanelChange(null, newDate); + }; + + return ( +
+ { + onYearChange(-1); + }} + onNextYear={() => { + onYearChange(1); + }} + onYearClick={() => { + onPanelChange('year', viewDate); + }} + /> + + {...props} + prefixCls={prefixCls} + onSelect={date => { + onSelect(date, 'mouse'); + onPanelChange('date', date); + }} + /> +
+ ); +} + +export default MonthPanel; diff --git a/src/utils/dateUtil.ts b/src/utils/dateUtil.ts index 56c428269..b14cb7d9f 100644 --- a/src/utils/dateUtil.ts +++ b/src/utils/dateUtil.ts @@ -42,6 +42,27 @@ export function isSameYear( return generateConfig.getYear(year1!) === generateConfig.getYear(year2!); } +export function getQuarter(generateConfig: GenerateConfig, date: DateType) { + const quota = Math.floor(generateConfig.getMonth(date) / 3); + return quota + 1; +} + +export function isSameQuarter( + generateConfig: GenerateConfig, + quarter1: NullableDateType, + quarter2: NullableDateType, +) { + const equal = isNullEqual(quarter1, quarter2); + if (typeof equal === 'boolean') { + return equal; + } + + return ( + isSameYear(generateConfig, quarter1, quarter2) && + getQuarter(generateConfig, quarter1!) === getQuarter(generateConfig, quarter2!) + ); +} + export function isSameMonth( generateConfig: GenerateConfig, month1: NullableDateType, @@ -104,8 +125,7 @@ export function isSameWeek( } return ( - generateConfig.locale.getWeek(locale, date1!) === - generateConfig.locale.getWeek(locale, date2!) + generateConfig.locale.getWeek(locale, date1!) === generateConfig.locale.getWeek(locale, date2!) ); } @@ -114,10 +134,7 @@ export function isEqual( value1: NullableDateType, value2: NullableDateType, ) { - return ( - isSameDate(generateConfig, value1, value2) && - isSameTime(generateConfig, value1, value2) - ); + return isSameDate(generateConfig, value1, value2) && isSameTime(generateConfig, value1, value2); } /** Between in date but not equal of date */ diff --git a/src/utils/uiUtil.ts b/src/utils/uiUtil.ts index a294b8550..a868bebb3 100644 --- a/src/utils/uiUtil.ts +++ b/src/utils/uiUtil.ts @@ -44,13 +44,7 @@ export interface KeyboardConfig { } export function createKeyDownHandler( event: React.KeyboardEvent, - { - onLeftRight, - onCtrlLeftRight, - onUpDown, - onPageUpDown, - onEnter, - }: KeyboardConfig, + { onLeftRight, onCtrlLeftRight, onUpDown, onPageUpDown, onEnter }: KeyboardConfig, ): boolean { const { which, ctrlKey, metaKey } = event; @@ -170,11 +164,7 @@ let globalClickFunc: ClickEventHandler | null = null; const clickCallbacks = new Set(); export function addGlobalMouseDownEvent(callback: ClickEventHandler) { - if ( - !globalClickFunc && - typeof window !== 'undefined' && - window.addEventListener - ) { + if (!globalClickFunc && typeof window !== 'undefined' && window.addEventListener) { globalClickFunc = (e: MouseEvent) => { // Clone a new list to avoid repeat trigger events [...clickCallbacks].forEach(queueFunc => { @@ -210,6 +200,13 @@ const getMonthNextMode = (next: PanelMode): PanelMode => { return next; }; +const getQuarterNextMode = (next: PanelMode): PanelMode => { + if (next === 'month' || next === 'date') { + return 'quarter'; + } + return next; +}; + const getWeekNextMode = (next: PanelMode): PanelMode => { if (next === 'date') { return 'week'; @@ -217,12 +214,10 @@ const getWeekNextMode = (next: PanelMode): PanelMode => { return next; }; -export const PickerModeMap: Record< - PickerMode, - ((next: PanelMode) => PanelMode) | null -> = { +export const PickerModeMap: Record PanelMode) | null> = { year: getYearNextMode, month: getMonthNextMode, + quarter: getQuarterNextMode, week: getWeekNextMode, time: null, date: null, From b5cb23bae825e34eb0f6fce957ffd3050139daf9 Mon Sep 17 00:00:00 2001 From: zombiej Date: Sat, 21 Mar 2020 13:17:31 +0800 Subject: [PATCH 2/5] picker support quarter --- examples/basic.tsx | 17 ++++++----------- src/panels/QuarterPanel/QuarterBody.tsx | 3 +-- src/utils/uiUtil.ts | 4 ++++ 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/examples/basic.tsx b/examples/basic.tsx index 0649d07ee..ec0106076 100644 --- a/examples/basic.tsx +++ b/examples/basic.tsx @@ -102,11 +102,11 @@ export default () => {

Week

- - generateConfig={momentGenerateConfig} - locale={enUS} - picker="week" - /> + generateConfig={momentGenerateConfig} locale={enUS} picker="week" /> +
+
+

Quarter

+ generateConfig={momentGenerateConfig} locale={enUS} picker="quarter" />

Time

@@ -114,12 +114,7 @@ export default () => {

Time 12

- - {...sharedProps} - locale={zhCN} - picker="time" - use12Hours - /> + {...sharedProps} locale={zhCN} picker="time" use12Hours />

Year

diff --git a/src/panels/QuarterPanel/QuarterBody.tsx b/src/panels/QuarterPanel/QuarterBody.tsx index 5398612ed..f6607852e 100644 --- a/src/panels/QuarterPanel/QuarterBody.tsx +++ b/src/panels/QuarterPanel/QuarterBody.tsx @@ -46,8 +46,7 @@ function QuarterBody(props: QuarterBodyProps) { colNum={QUARTER_COL_COUNT} baseDate={baseQuarter} getCellText={date => - // generateConfig.locale.format(locale.locale, date, locale.quarterFormat || '\\QQ') - generateConfig.locale.format(locale.locale, date, 'MM') + generateConfig.locale.format(locale.locale, date, locale.quarterFormat || '\\QQ') } getCellClassName={getCellClassName} getCellDate={(date, offset) => generateConfig.addMonth(date, offset * 3)} diff --git a/src/utils/uiUtil.ts b/src/utils/uiUtil.ts index a868bebb3..6d1a772df 100644 --- a/src/utils/uiUtil.ts +++ b/src/utils/uiUtil.ts @@ -141,6 +141,10 @@ export function getDefaultFormat( mergedFormat = 'YYYY-MM'; break; + case 'quarter': + mergedFormat = 'YYYY-\\QQ'; + break; + case 'year': mergedFormat = 'YYYY'; break; From 2e8ae7bfd553e063a97a331b496c7e84bcc7ede4 Mon Sep 17 00:00:00 2001 From: zombiej Date: Sat, 21 Mar 2020 13:29:32 +0800 Subject: [PATCH 3/5] test case --- src/panels/QuarterPanel/index.tsx | 8 ++++---- tests/panel.spec.tsx | 24 +++++++++++++----------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/panels/QuarterPanel/index.tsx b/src/panels/QuarterPanel/index.tsx index b21434ccd..98703fd6f 100644 --- a/src/panels/QuarterPanel/index.tsx +++ b/src/panels/QuarterPanel/index.tsx @@ -4,9 +4,9 @@ import QuarterBody, { QUARTER_COL_COUNT } from './QuarterBody'; import { PanelSharedProps } from '../../interface'; import { createKeyDownHandler } from '../../utils/uiUtil'; -export interface MonthPanelProps extends PanelSharedProps {} +export interface QuarterPanelProps extends PanelSharedProps {} -function MonthPanel(props: MonthPanelProps) { +function QuarterPanel(props: QuarterPanelProps) { const { prefixCls, operationRef, @@ -18,7 +18,7 @@ function MonthPanel(props: MonthPanelProps) { onSelect, } = props; - const panelPrefixCls = `${prefixCls}-month-panel`; + const panelPrefixCls = `${prefixCls}-quarter-panel`; // ======================= Keyboard ======================= operationRef.current = { @@ -73,4 +73,4 @@ function MonthPanel(props: MonthPanelProps) { ); } -export default MonthPanel; +export default QuarterPanel; diff --git a/tests/panel.spec.tsx b/tests/panel.spec.tsx index 0feebc879..67e1a67b6 100644 --- a/tests/panel.spec.tsx +++ b/tests/panel.spec.tsx @@ -69,20 +69,22 @@ describe('Picker.Panel', () => { expect(wrapper.find('.rc-picker-year-panel').length).toBeTruthy(); }); - it('month', () => { - const wrapper = mount(); - wrapper.find('.rc-picker-year-btn').simulate('click'); - wrapper.find('.rc-picker-decade-btn').simulate('click'); - expect(wrapper.find('.rc-picker-decade-panel').length).toBeTruthy(); + [['month', 'Aug'], ['quarter', 'Q3']].forEach(([picker, cell]) => { + it(picker, () => { + const wrapper = mount(); + wrapper.find('.rc-picker-year-btn').simulate('click'); + wrapper.find('.rc-picker-decade-btn').simulate('click'); + expect(wrapper.find('.rc-picker-decade-panel').length).toBeTruthy(); - wrapper.selectCell('1990-1999'); - expect(wrapper.find('.rc-picker-year-panel').length).toBeTruthy(); + wrapper.selectCell('1990-1999'); + expect(wrapper.find('.rc-picker-year-panel').length).toBeTruthy(); - wrapper.selectCell('1999'); - expect(wrapper.find('.rc-picker-month-panel').length).toBeTruthy(); + wrapper.selectCell('1999'); + expect(wrapper.find(`.rc-picker-${picker}-panel`).length).toBeTruthy(); - wrapper.selectCell('Aug'); - expect(wrapper.find('.rc-picker-month-panel').length).toBeTruthy(); + wrapper.selectCell(cell); + expect(wrapper.find(`.rc-picker-${picker}-panel`).length).toBeTruthy(); + }); }); }); From 69c1f17b27e12b2be8c9ae24548b04f402762bd7 Mon Sep 17 00:00:00 2001 From: zombiej Date: Sat, 21 Mar 2020 19:54:52 +0800 Subject: [PATCH 4/5] coverag --- src/panels/QuarterPanel/index.tsx | 10 +-- tests/keyboard.spec.tsx | 115 ++++++++++++------------------ tests/panel.spec.tsx | 20 +++--- 3 files changed, 58 insertions(+), 87 deletions(-) diff --git a/src/panels/QuarterPanel/index.tsx b/src/panels/QuarterPanel/index.tsx index 98703fd6f..673e4ff3e 100644 --- a/src/panels/QuarterPanel/index.tsx +++ b/src/panels/QuarterPanel/index.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import QuarterHeader from './QuarterHeader'; -import QuarterBody, { QUARTER_COL_COUNT } from './QuarterBody'; +import QuarterBody from './QuarterBody'; import { PanelSharedProps } from '../../interface'; import { createKeyDownHandler } from '../../utils/uiUtil'; @@ -25,16 +25,13 @@ function QuarterPanel(props: QuarterPanelProps) { onKeyDown: event => createKeyDownHandler(event, { onLeftRight: diff => { - onSelect(generateConfig.addMonth(value || viewDate, diff), 'key'); + onSelect(generateConfig.addMonth(value || viewDate, diff * 3), 'key'); }, onCtrlLeftRight: diff => { onSelect(generateConfig.addYear(value || viewDate, diff), 'key'); }, onUpDown: diff => { - onSelect(generateConfig.addMonth(value || viewDate, diff * QUARTER_COL_COUNT), 'key'); - }, - onEnter: () => { - onPanelChange('date', value || viewDate); + onSelect(generateConfig.addYear(value || viewDate, diff), 'key'); }, }), }; @@ -66,7 +63,6 @@ function QuarterPanel(props: QuarterPanelProps) { prefixCls={prefixCls} onSelect={date => { onSelect(date, 'mouse'); - onPanelChange('date', date); }} />
diff --git a/tests/keyboard.spec.tsx b/tests/keyboard.spec.tsx index dc781587f..16f02ff86 100644 --- a/tests/keyboard.spec.tsx +++ b/tests/keyboard.spec.tsx @@ -14,9 +14,7 @@ import { describe('Picker.Keyboard', () => { function panelKeyDown(wrapper: Wrapper, keyCode: number, info?: object) { - wrapper - .find('.rc-picker-panel') - .simulate('keyDown', { which: keyCode, ...info }); + wrapper.find('.rc-picker-panel').simulate('keyDown', { which: keyCode, ...info }); } beforeAll(() => { @@ -30,9 +28,7 @@ describe('Picker.Keyboard', () => { it('open to select', () => { const onChange = jest.fn(); const onSelect = jest.fn(); - const wrapper = mount( - , - ); + const wrapper = mount(); wrapper.find('input').simulate('focus'); wrapper.keyDown(KeyCode.ENTER); expect(wrapper.isOpen()).toBeTruthy(); @@ -195,77 +191,45 @@ describe('Picker.Keyboard', () => { ].forEach(({ name, operate }) => { it(name, () => { const onSelect = jest.fn(); - const wrapper = mount( - , - ); + const wrapper = mount(); // Focus Panel wrapper.find('.rc-picker-panel').simulate('focus'); // Focus Date Panel operate(wrapper); - expect( - wrapper.find('.rc-picker-date-panel-active').length, - ).toBeTruthy(); + expect(wrapper.find('.rc-picker-date-panel-active').length).toBeTruthy(); // Select panelKeyDown(wrapper, KeyCode.DOWN); - expect( - isSame(onSelect.mock.calls[0][0], '1990-09-10'), - ).toBeTruthy(); + expect(isSame(onSelect.mock.calls[0][0], '1990-09-10')).toBeTruthy(); // Focus Time Panel panelKeyDown(wrapper, KeyCode.TAB); - expect( - wrapper.find('.rc-picker-time-panel-active').length, - ).toBeTruthy(); + expect(wrapper.find('.rc-picker-time-panel-active').length).toBeTruthy(); // Select onSelect.mockReset(); panelKeyDown(wrapper, KeyCode.UP); panelKeyDown(wrapper, KeyCode.DOWN); - expect( - isSame( - onSelect.mock.calls[0][0], - '1990-09-10 01:00:00', - 'second', - ), - ).toBeTruthy(); + expect(isSame(onSelect.mock.calls[0][0], '1990-09-10 01:00:00', 'second')).toBeTruthy(); // Next column select onSelect.mockReset(); panelKeyDown(wrapper, KeyCode.RIGHT); panelKeyDown(wrapper, KeyCode.UP); - expect( - isSame( - onSelect.mock.calls[0][0], - '1990-09-10 01:59:00', - 'second', - ), - ).toBeTruthy(); + expect(isSame(onSelect.mock.calls[0][0], '1990-09-10 01:59:00', 'second')).toBeTruthy(); // Enter to exit column edit onSelect.mockReset(); - expect( - wrapper.find('.rc-picker-time-panel-column-active').length, - ).toBeTruthy(); + expect(wrapper.find('.rc-picker-time-panel-column-active').length).toBeTruthy(); panelKeyDown(wrapper, KeyCode.ENTER); - expect( - wrapper.find('.rc-picker-time-panel-column-active').length, - ).toBeFalsy(); - expect( - isSame( - onSelect.mock.calls[0][0], - '1990-09-10 01:59:00', - 'second', - ), - ).toBeTruthy(); + expect(wrapper.find('.rc-picker-time-panel-column-active').length).toBeFalsy(); + expect(isSame(onSelect.mock.calls[0][0], '1990-09-10 01:59:00', 'second')).toBeTruthy(); // Close should not focus wrapper.find('.rc-picker-panel').simulate('blur'); - expect( - wrapper.find('.rc-picker-time-panel-active').length, - ).toBeFalsy(); + expect(wrapper.find('.rc-picker-time-panel-active').length).toBeFalsy(); }); }); }); @@ -295,13 +259,9 @@ describe('Picker.Keyboard', () => { it('time enter will trigger onSelect', () => { const onSelect = jest.fn(); - const wrapper = mount( - , - ); + const wrapper = mount(); panelKeyDown(wrapper, KeyCode.ENTER); - expect( - isSame(onSelect.mock.calls[0][0], '1990-09-03 00:00:00', 'second'), - ).toBeTruthy(); + expect(isSame(onSelect.mock.calls[0][0], '1990-09-03 00:00:00', 'second')).toBeTruthy(); }); describe('arrow trigger onSelect', () => { @@ -331,6 +291,31 @@ describe('Picker.Keyboard', () => { expect(isSame(onSelect.mock.calls[0][0], '1991-11-03')).toBeTruthy(); }); + it('quarter', () => { + const onSelect = jest.fn(); + const wrapper = mount( + , + ); + + // Left + panelKeyDown(wrapper, KeyCode.LEFT); + expect(isSame(onSelect.mock.calls[0][0], '1990-06-03')).toBeTruthy(); + + // Control + Right + onSelect.mockReset(); + panelKeyDown(wrapper, KeyCode.RIGHT, { ctrlKey: true }); + expect(isSame(onSelect.mock.calls[0][0], '1991-06-03')).toBeTruthy(); + + // Down + onSelect.mockReset(); + panelKeyDown(wrapper, KeyCode.DOWN); + expect(isSame(onSelect.mock.calls[0][0], '1992-06-03')).toBeTruthy(); + }); + it('year', () => { const onSelect = jest.fn(); const wrapper = mount( @@ -369,25 +354,19 @@ describe('Picker.Keyboard', () => { // Left panelKeyDown(wrapper, KeyCode.LEFT); panelKeyDown(wrapper, KeyCode.ENTER); - expect( - isSame(onPanelChange.mock.calls[0][0], '1980', 'year'), - ).toBeTruthy(); + expect(isSame(onPanelChange.mock.calls[0][0], '1980', 'year')).toBeTruthy(); // Control + Right onPanelChange.mockReset(); panelKeyDown(wrapper, KeyCode.RIGHT, { ctrlKey: true }); panelKeyDown(wrapper, KeyCode.ENTER); - expect( - isSame(onPanelChange.mock.calls[0][0], '2080', 'year'), - ).toBeTruthy(); + expect(isSame(onPanelChange.mock.calls[0][0], '2080', 'year')).toBeTruthy(); // Down onPanelChange.mockReset(); panelKeyDown(wrapper, KeyCode.DOWN); panelKeyDown(wrapper, KeyCode.ENTER); - expect( - isSame(onPanelChange.mock.calls[0][0], '2110', 'year'), - ).toBeTruthy(); + expect(isSame(onPanelChange.mock.calls[0][0], '2110', 'year')).toBeTruthy(); }); }); @@ -397,10 +376,7 @@ describe('Picker.Keyboard', () => { const onCalendarChange = jest.fn(); const onChange = jest.fn(); const wrapper = mount( - , + , ); // Start Date @@ -434,10 +410,7 @@ describe('Picker.Keyboard', () => { wrapper.keyDown(KeyCode.TAB, {}, 1); wrapper.keyDown(KeyCode.DOWN, {}, 1); wrapper.keyDown(KeyCode.ENTER, {}, 1); - expect(onCalendarChange.mock.calls[0][1]).toEqual([ - '1990-01-08', - '2000-01-08', - ]); + expect(onCalendarChange.mock.calls[0][1]).toEqual(['1990-01-08', '2000-01-08']); expect(onChange.mock.calls[0][1]).toEqual(['1990-01-08', '2000-01-08']); jest.useRealTimers(); diff --git a/tests/panel.spec.tsx b/tests/panel.spec.tsx index 67e1a67b6..d6e0ce377 100644 --- a/tests/panel.spec.tsx +++ b/tests/panel.spec.tsx @@ -156,16 +156,18 @@ describe('Picker.Panel', () => { expect(wrapper.find('.rc-picker-header-view').text()).toEqual('Sep1990'); }); - it('month', () => { - const wrapper = mount( - , - ); + ['month', 'quarter'].forEach(picker => { + it(picker, () => { + const wrapper = mount( + , + ); - wrapper.clickButton('super-prev'); - expect(wrapper.find('.rc-picker-header-view').text()).toEqual('1989'); + wrapper.clickButton('super-prev'); + expect(wrapper.find('.rc-picker-header-view').text()).toEqual('1989'); - wrapper.clickButton('super-next'); - expect(wrapper.find('.rc-picker-header-view').text()).toEqual('1990'); + wrapper.clickButton('super-next'); + expect(wrapper.find('.rc-picker-header-view').text()).toEqual('1990'); + }); }); it('year', () => { @@ -385,7 +387,7 @@ describe('Picker.Panel', () => { }); describe('hideHeader', () => { - ['decade', 'year', 'month', 'date', 'time'].forEach(mode => { + ['decade', 'year', 'month', 'quarter', 'date', 'time'].forEach(mode => { it(mode, () => { const wrapper = mount(); expect(wrapper.find('.rc-picker-header')).toHaveLength(0); From 453a9513cb1e61d9325532dc2572145da7ab2535 Mon Sep 17 00:00:00 2001 From: zombiej Date: Sat, 21 Mar 2020 20:04:40 +0800 Subject: [PATCH 5/5] full coverage --- tests/picker.spec.tsx | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tests/picker.spec.tsx b/tests/picker.spec.tsx index 68059c993..00ccc8260 100644 --- a/tests/picker.spec.tsx +++ b/tests/picker.spec.tsx @@ -26,6 +26,10 @@ describe('Picker.Basic', () => { mode: 'year', componentNames: ['YearPanel', 'YearHeader', 'YearBody'], }, + { + mode: 'quarter', + componentNames: ['QuarterPanel', 'QuarterHeader', 'QuarterBody'], + }, { mode: 'month', componentNames: ['MonthPanel', 'MonthHeader', 'MonthBody'], @@ -60,6 +64,10 @@ describe('Picker.Basic', () => { picker: 'year', componentNames: ['YearPanel', 'YearHeader', 'YearBody'], }, + { + picker: 'quarter', + componentNames: ['QuarterPanel', 'QuarterHeader', 'QuarterBody'], + }, { picker: 'month', componentNames: ['MonthPanel', 'MonthHeader', 'MonthBody'], @@ -459,7 +467,7 @@ describe('Picker.Basic', () => { expect(isSame(onSelect.mock.calls[0][0], '1990-09-03')).toBeTruthy(); }); - ['decade', 'year', 'month', 'week'].forEach(name => { + ['decade', 'year', 'quarter', 'month', 'week'].forEach(name => { it(`not works on ${name}`, () => { const wrapper = mount(); wrapper.openPicker(); @@ -584,7 +592,12 @@ describe('Picker.Basic', () => { ); expect(wrapper.find('input').props().value).toEqual('1999-09-03 00:00:00'); - [['date', '1999-09-03'], ['month', '1999-09'], ['year', '1999']].forEach(([picker, text]) => { + [ + ['date', '1999-09-03'], + ['month', '1999-09'], + ['quarter', '1999-Q3'], + ['year', '1999'], + ].forEach(([picker, text]) => { wrapper.setProps({ picker, showTime: false }); wrapper.update(); expect(wrapper.find('input').props().value).toEqual(text);