From 9dacf811ece73463e2bfafb8f2790cd431feca3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Sat, 9 Oct 2021 11:24:16 +0800 Subject: [PATCH] fix: DisabledDate should not crash by user typing (#300) * test: test driven * fix: Not crash when disabled by typing --- .eslintrc.js | 1 - src/Picker.tsx | 7 ++++- tests/picker.spec.tsx | 68 +++++++++++++++++++++++++------------------ 3 files changed, 45 insertions(+), 31 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 0265855..3e9f3d6 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -14,6 +14,5 @@ module.exports = { 'no-confusing-arrow': 0, 'jsx-a11y/no-autofocus': 0, 'jsx-a11y/heading-has-content': 0, - 'import/no-extraneous-dependencies': ['error', { packageDir: './' }], }, }; diff --git a/src/Picker.tsx b/src/Picker.tsx index 7ecd3ac..d6d0e3e 100644 --- a/src/Picker.tsx +++ b/src/Picker.tsx @@ -300,7 +300,12 @@ function InnerPicker(props: PickerProps) { target as HTMLElement, ), onSubmit: () => { - if (disabledDate && disabledDate(selectedValue)) { + if ( + // When user typing disabledDate with keyboard and enter, this value will be empty + !selectedValue || + // Normal disabled check + (disabledDate && disabledDate(selectedValue)) + ) { return false; } diff --git a/tests/picker.spec.tsx b/tests/picker.spec.tsx index 807cdaf..28da1ea 100644 --- a/tests/picker.spec.tsx +++ b/tests/picker.spec.tsx @@ -4,6 +4,7 @@ import { act } from 'react-dom/test-utils'; import { spyElementPrototypes } from 'rc-util/lib/test/domHook'; import KeyCode from 'rc-util/lib/KeyCode'; import { resetWarned } from 'rc-util/lib/warning'; +import moment from 'moment'; import type { Moment } from 'moment'; import type { PanelMode, PickerMode } from '../src/interface'; import { mount, getMoment, isSame, MomentPicker } from './util/commonUtil'; @@ -52,7 +53,7 @@ describe('Picker.Basic', () => { modeList.forEach(({ mode, componentNames }) => { it(mode, () => { const wrapper = mount(); - componentNames.forEach(componentName => { + componentNames.forEach((componentName) => { expect(wrapper.find(componentName).length).toBeTruthy(); }); }); @@ -90,7 +91,7 @@ describe('Picker.Basic', () => { modeList.forEach(({ picker, componentNames }) => { it(picker, () => { const wrapper = mount(); - componentNames.forEach(componentName => { + componentNames.forEach((componentName) => { expect(wrapper.find(componentName).length).toBeTruthy(); }); }); @@ -309,10 +310,7 @@ describe('Picker.Basic', () => { wrapper.openPicker(); const preventDefault = jest.fn(); - wrapper - .find('td') - .first() - .simulate('mouseDown', { preventDefault }); + wrapper.find('td').first().simulate('mouseDown', { preventDefault }); expect(preventDefault).toHaveBeenCalled(); }); @@ -415,12 +413,7 @@ describe('Picker.Basic', () => { wrapper.openPicker(); function selectColumn(colIndex: number, rowIndex: number) { - wrapper - .find('ul') - .at(colIndex) - .find('li') - .at(rowIndex) - .simulate('click'); + wrapper.find('ul').at(colIndex).find('li').at(rowIndex).simulate('click'); } selectColumn(0, 13); @@ -435,7 +428,7 @@ describe('Picker.Basic', () => { }); it('renderExtraFooter', () => { - const renderExtraFooter = jest.fn(mode =>
{mode}
); + const renderExtraFooter = jest.fn((mode) =>
{mode}
); const wrapper = mount(); function matchFooter(mode: string) { @@ -482,7 +475,7 @@ describe('Picker.Basic', () => { expect(onSelect).not.toHaveBeenCalled(); }); - ['decade', 'year', 'quarter', 'month', 'week'].forEach(name => { + ['decade', 'year', 'quarter', 'month', 'week'].forEach((name) => { it(`not works on ${name}`, () => { const wrapper = mount(); wrapper.openPicker(); @@ -623,7 +616,7 @@ describe('Picker.Basic', () => { it('click outside should also focus', () => { const onMouseUp = jest.fn(); const wrapper = mount(); - const inputElement = (wrapper.find('input').instance() as any) as HTMLInputElement; + const inputElement = wrapper.find('input').instance() as any as HTMLInputElement; inputElement.focus = jest.fn(); wrapper.find('.rc-picker').simulate('mouseUp'); @@ -706,13 +699,8 @@ describe('Picker.Basic', () => { }); it('dateRender', () => { - const wrapper = mount( date.format('YYYY-MM-DD')} />); - expect( - wrapper - .find('tbody td') - .last() - .text(), - ).toEqual('1990-10-06'); + const wrapper = mount( date.format('YYYY-MM-DD')} />); + expect(wrapper.find('tbody td').last().text()).toEqual('1990-10-06'); }); it('format', () => { @@ -898,10 +886,16 @@ describe('Picker.Basic', () => { function disabledDate(current: Moment) { return current <= getMoment('2020-12-28 00:00:00').endOf('day'); } - const wrapper = mount(); + const wrapper = mount( + , + ); // Date Panel Array.from({ - length: 31 + length: 31, }).forEach((v, i) => { const cell = wrapper.findCell(`${i + 1}`); // >= 29 @@ -914,7 +908,7 @@ describe('Picker.Basic', () => { wrapper.find('.rc-picker-month-btn').simulate('click'); // Month Panel Array.from({ - length: 12 + length: 12, }).forEach((v, i) => { const cell = wrapper.find('.rc-picker-cell-in-view').at(i); // >= 12 @@ -927,7 +921,7 @@ describe('Picker.Basic', () => { wrapper.find('.rc-picker-year-btn').simulate('click'); // Year Panel Array.from({ - length: 10 + length: 10, }).forEach((v, i) => { const cell = wrapper.find('.rc-picker-cell-in-view').at(i); // >= 2020 @@ -935,17 +929,24 @@ describe('Picker.Basic', () => { }); // Decade Panel Array.from({ - length: 8 + length: 8, }).forEach((v, i) => { const cell = wrapper.find('.rc-picker-cell-in-view').at(i); // >= 2020 expect(cell.hasClass('rc-picker-cell-disabled')).toBeFalsy(); }); - const quarterWrapper = mount(); + const quarterWrapper = mount( + , + ); // quarter Panel Array.from({ - length: 4 + length: 4, }).forEach((v, i) => { const cell = quarterWrapper.find('.rc-picker-cell-in-view').at(i); // >= 4 @@ -956,4 +957,13 @@ describe('Picker.Basic', () => { } }); }); + + it('disabledDate should not crash', () => { + const wrapper = mount( d.isAfter(Date.now())} />); + wrapper + .find('input') + .simulate('change', { target: { value: moment().add(1, 'year').format('YYYY-MM-DD') } }); + + wrapper.find('input').simulate('keyDown', { which: KeyCode.ENTER }); + }); });