diff --git a/site/test-coverage.js b/site/test-coverage.js index ef73210ab..83d3125bf 100644 --- a/site/test-coverage.js +++ b/site/test-coverage.js @@ -1,9 +1,9 @@ module.exports = { "Util": { - "statements": "41.74%", - "branches": "28.57%", - "functions": "50.83%", - "lines": "43.03%" + "statements": "50.4%", + "branches": "38.29%", + "functions": "60.17%", + "lines": "51.73%" }, "affix": { "statements": "87.3%", @@ -84,10 +84,10 @@ module.exports = { "lines": "96.05%" }, "colorPicker": { - "statements": "93.33%", + "statements": "100%", "branches": "100%", - "functions": "60%", - "lines": "93.1%" + "functions": "100%", + "lines": "100%" }, "comment": { "statements": "100%", @@ -114,10 +114,10 @@ module.exports = { "lines": "28.64%" }, "dialog": { - "statements": "85.9%", - "branches": "72.91%", + "statements": "85.43%", + "branches": "70.21%", "functions": "84.21%", - "lines": "88.32%" + "lines": "88.4%" }, "divider": { "statements": "100%", @@ -144,28 +144,34 @@ module.exports = { "lines": "47.94%" }, "grid": { - "statements": "61.05%", + "statements": "61.85%", "branches": "28.78%", "functions": "80%", - "lines": "61.05%" + "lines": "61.85%" + }, + "guide": { + "statements": "100%", + "branches": "94.11%", + "functions": "100%", + "lines": "100%" }, "hooks": { - "statements": "51.29%", + "statements": "47.5%", "branches": "27.41%", - "functions": "62.16%", - "lines": "52.14%" + "functions": "55.26%", + "lines": "47.91%" }, "image": { - "statements": "87.23%", + "statements": "87.5%", "branches": "86.2%", "functions": "83.33%", - "lines": "86.36%" + "lines": "86.66%" }, "imageViewer": { - "statements": "75%", + "statements": "75.53%", "branches": "77.19%", "functions": "65.71%", - "lines": "75.38%" + "lines": "75.93%" }, "input": { "statements": "93.63%", @@ -204,10 +210,10 @@ module.exports = { "lines": "89.47%" }, "locale": { - "statements": "73.07%", - "branches": "72.22%", + "statements": "80.76%", + "branches": "77.77%", "functions": "83.33%", - "lines": "73.91%" + "lines": "82.6%" }, "message": { "statements": "88.43%", @@ -252,10 +258,10 @@ module.exports = { "lines": "81.66%" }, "rangeInput": { - "statements": "74.02%", - "branches": "61.9%", - "functions": "46.15%", - "lines": "73.68%" + "statements": "76.62%", + "branches": "66.66%", + "functions": "50%", + "lines": "76.31%" }, "rate": { "statements": "64.15%", @@ -270,10 +276,10 @@ module.exports = { "lines": "100%" }, "selectInput": { - "statements": "83.83%", - "branches": "72.83%", - "functions": "69.56%", - "lines": "86.95%" + "statements": "97%", + "branches": "89.28%", + "functions": "100%", + "lines": "98.92%" }, "slider": { "statements": "89.47%", @@ -306,10 +312,10 @@ module.exports = { "lines": "96.15%" }, "table": { - "statements": "48.69%", - "branches": "34.26%", + "statements": "48.8%", + "branches": "34.32%", "functions": "45.56%", - "lines": "49.6%" + "lines": "49.67%" }, "tabs": { "statements": "90.85%", @@ -325,7 +331,7 @@ module.exports = { }, "tagInput": { "statements": "85.97%", - "branches": "81.69%", + "branches": "83.09%", "functions": "83.78%", "lines": "87.74%" }, @@ -336,10 +342,16 @@ module.exports = { "lines": "86.36%" }, "timePicker": { - "statements": "14.28%", - "branches": "0%", - "functions": "0%", - "lines": "14.94%" + "statements": "80.64%", + "branches": "67.16%", + "functions": "72.22%", + "lines": "82.02%" + }, + "timeline": { + "statements": "98.38%", + "branches": "88.13%", + "functions": "100%", + "lines": "98.33%" }, "tooltip": { "statements": "88.88%", @@ -354,16 +366,22 @@ module.exports = { "lines": "87.77%" }, "tree": { - "statements": "22.45%", - "branches": "4.23%", - "functions": "20.51%", - "lines": "22.9%" + "statements": "51.87%", + "branches": "34.16%", + "functions": "51.28%", + "lines": "52.79%" + }, + "treeSelect": { + "statements": "95.17%", + "branches": "86.44%", + "functions": "97.43%", + "lines": "95.62%" }, "upload": { - "statements": "14.28%", - "branches": "0%", - "functions": "0%", - "lines": "14.81%" + "statements": "96.55%", + "branches": "100%", + "functions": "88.88%", + "lines": "100%" }, "watermark": { "statements": "54.76%", @@ -372,9 +390,9 @@ module.exports = { "lines": "57.5%" }, "utils": { - "statements": "72.41%", - "branches": "63.63%", + "statements": "80%", + "branches": "75%", "functions": "100%", - "lines": "70.37%" + "lines": "79.54%" } }; diff --git a/src/time-picker/TimePicker.tsx b/src/time-picker/TimePicker.tsx index 202e3e8d2..63f20d0bf 100644 --- a/src/time-picker/TimePicker.tsx +++ b/src/time-picker/TimePicker.tsx @@ -10,7 +10,7 @@ import useConfig from '../hooks/useConfig'; import useGlobalIcon from '../hooks/useGlobalIcon'; import noop from '../_util/noop'; -import SelectInput from '../select-input'; +import SelectInput, { SelectInputValueChangeContext } from '../select-input'; import TimeRangePicker from './TimeRangePicker'; import TimePickerPanel from './panel/TimePickerPanel'; @@ -45,6 +45,7 @@ const TimePicker = forwardRefWithStatics( onClose = noop, onFocus = noop, onOpen = noop, + onInput = noop, } = props; const [value, onChange] = useControlled(props, 'value', props.onChange); @@ -73,8 +74,11 @@ const TimePicker = forwardRefWithStatics( onChange(null); }; - const handleInputChange = (value: string) => { + const handleInputChange = (value: string, context: SelectInputValueChangeContext) => { setCurrentValue(value); + if (allowInput) { + onInput({ value, e: context.e as React.FocusEvent }); + } }; const handleInputBlur = (value: string, { e }: { e: React.FocusEvent }) => { diff --git a/src/time-picker/__tests__/time-picker.test.tsx b/src/time-picker/__tests__/time-picker.test.tsx index 0da66d9b5..01ba2c97a 100644 --- a/src/time-picker/__tests__/time-picker.test.tsx +++ b/src/time-picker/__tests__/time-picker.test.tsx @@ -1,14 +1,135 @@ import MockDate from 'mockdate'; -// import { render } from '@test/utils'; -// import React from 'react'; -// import TimePicker from '../index'; +import { fireEvent, render, waitFor, vi } from '@test/utils'; +import React from 'react'; +import TimePicker from '../index'; // 固定时间,当使用 new Date() 时,返回固定时间,防止“当前时间”的副作用影响,导致 snapshot 变更,mockdate 插件见 https://github.com/boblauer/MockDate MockDate.set('2022-08-27'); // TODO -describe('Cascader 组件测试', () => { - test('dom', () => { - expect(true).toBe(true); +describe('Timepicker 组件测试', () => { + it('props.disabled works fine', () => { + // disabled default value is + const wrapper1 = render(); + const container1 = wrapper1.container.querySelector('.t-time-picker'); + expect(container1.querySelector('.t-is-disabled')).toBeFalsy(); + // disabled = true + const wrapper2 = render(); + const container2 = wrapper2.container.querySelector('.t-time-picker .t-input'); + expect(container2).toHaveClass('t-is-disabled'); + // disabled = false + const wrapper3 = render(); + const container3 = wrapper3.container.querySelector('.t-time-picker'); + expect(container3.querySelector('.t-is-disabled')).toBeFalsy(); + }); + + it('trigger panel works fine', async () => { + const { container } = render(); + expect(container.querySelectorAll('input').length).toBe(1); + fireEvent.click(document.querySelector('input')); + await waitFor(() => { + expect(document.querySelector('.t-time-picker__panel')).not.toBeNull(); + expect(document.querySelector('.t-time-picker__panel')).toHaveStyle({ + display: 'block', + }); + expect(document.querySelectorAll('.t-time-picker__panel-body-scroll').length).toBe(3); + }); + }); + + it('props.defaultValue works fine', async () => { + const { container } = render(); + expect(container.querySelectorAll('input').length).toBe(1); + expect(container.querySelectorAll('input').item(0)).toHaveValue('00:10:20'); + fireEvent.click(document.querySelector('input')); + await waitFor(() => { + const scrollPanels = document.querySelectorAll('.t-time-picker__panel-body-scroll'); + expect(scrollPanels.item(0).querySelectorAll('.t-is-current').item(0)).toHaveTextContent('00'); + expect(scrollPanels.item(1).querySelectorAll('.t-is-current').item(0)).toHaveTextContent('10'); + expect(scrollPanels.item(2).querySelectorAll('.t-is-current').item(0)).toHaveTextContent('20'); + }); + }); + + it('props.defaultValue for TimePicker works fine', async () => { + const { container } = render(); + expect(container.querySelectorAll('input').length).toBe(1); + expect(container.querySelectorAll('input').item(0)).toHaveValue('00:10:20'); + fireEvent.click(document.querySelector('input')); + await waitFor(() => { + const scrollPanels = document.querySelectorAll('.t-time-picker__panel-body-scroll'); + expect(scrollPanels.item(0).querySelectorAll('.t-is-current').item(0)).toHaveTextContent('00'); + expect(scrollPanels.item(1).querySelectorAll('.t-is-current').item(0)).toHaveTextContent('10'); + expect(scrollPanels.item(2).querySelectorAll('.t-is-current').item(0)).toHaveTextContent('20'); + }); + }); + + it('props.defaultValue for TimeRangePicker works fine', async () => { + const { container } = render(); + const inputs = container.querySelectorAll('input'); + expect(inputs.length).toBe(2); + expect(inputs.item(0)).toHaveValue('00:00:00'); + expect(inputs.item(1)).toHaveValue('00:10:20'); + fireEvent.click(inputs.item(1)); + await waitFor(() => { + const scrollPanels = document.querySelectorAll('.t-time-picker__panel-body-scroll'); + expect(scrollPanels.item(0).querySelectorAll('.t-is-current').item(0)).toHaveTextContent('00'); + expect(scrollPanels.item(1).querySelectorAll('.t-is-current').item(0)).toHaveTextContent('10'); + expect(scrollPanels.item(2).querySelectorAll('.t-is-current').item(0)).toHaveTextContent('20'); + }); + }); + + it('props.value for TimePickerPanel works fine', () => { + const onChange = vi.fn(); + const { container } = render(); + const scrollPanels = container.querySelectorAll('.t-time-picker__panel-body-scroll'); + expect(scrollPanels.item(0).querySelectorAll('.t-is-current').item(0)).toHaveTextContent('00'); + expect(scrollPanels.item(1).querySelectorAll('.t-is-current').item(0)).toHaveTextContent('10'); + expect(scrollPanels.item(2).querySelectorAll('.t-is-current').item(0)).toHaveTextContent('20'); + }); + + it('props.allowInput works fine', async () => { + const handleBlur = vi.fn(); + const handleInput = vi.fn(); + const handleFocus = vi.fn(); + const { container } = render( + , + ); + const InputDom = container.querySelector('.t-input__inner'); + fireEvent.focus(InputDom); + expect(handleFocus).toBeCalledTimes(1); + expect(handleInput).toBeCalledTimes(1); + fireEvent.blur(InputDom); + expect(handleBlur).toBeCalledTimes(1); + }); + + it('props.onInput&onBlur&onForus works fine', async () => { + const handleBlur = vi.fn(); + const handleInput = vi.fn(); + const handleFocus = vi.fn(); + const { container } = render( + , + ); + const inputs = container.querySelectorAll('input'); + fireEvent.focus(inputs[0]); + expect(handleFocus).toBeCalledTimes(1); + fireEvent.change(inputs[0], { target: { value: '00:10:20' } }); + expect(handleInput).toBeCalledTimes(1); + fireEvent.blur(inputs[0]); + expect(handleBlur).toBeCalledTimes(1); + }); + + it('click to pick', async () => { + const handleChange = vi.fn(); + const { container } = render(); + fireEvent.click(document.querySelector('input')); + await waitFor(async () => { + const confirmBtn = document.querySelectorAll('.t-time-picker__panel button').item(0); + expect(confirmBtn).toBeInTheDocument(); + const panelItem1 = document.querySelectorAll('.t-time-picker__panel-body-scroll').item(0); + // await fireEvent.scroll(panelItem1, { target: { scrollY: 24 } }); + fireEvent.click(panelItem1.querySelectorAll('.t-time-picker__panel-body-scroll-item').item(1)); + fireEvent.click(confirmBtn); + expect(container.querySelectorAll('input').item(0)).toHaveValue('01:00:00'); + expect(handleChange).toHaveBeenCalled(1); + }); }); }); diff --git a/src/time-picker/_example/keyboard.jsx b/src/time-picker/_example/keyboard.jsx index ea9637b46..2348ee095 100644 --- a/src/time-picker/_example/keyboard.jsx +++ b/src/time-picker/_example/keyboard.jsx @@ -9,12 +9,18 @@ export default function KeyboardTimePicker() { const handleInput = (param) => { console.log(param, 'onInput'); }; + + const handleFocus = (param) => { + console.log(param, 'onFocus'); + }; + return (