Fix InputProps supports data attributes (#34410)

* fix: add data-xx for inputProps and convert input/_tests/index.test.js to tsx file

* fix: run tests
This commit is contained in:
高喵喵 2022-03-10 19:26:01 +08:00 committed by GitHub
parent 4c666f5775
commit fbb98f2b4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 32 deletions

View File

@ -118,6 +118,7 @@ export interface InputProps
size?: SizeType; size?: SizeType;
status?: InputStatus; status?: InputStatus;
bordered?: boolean; bordered?: boolean;
[key: `data-${string}`]: string;
} }
const Input = forwardRef<InputRef, InputProps>((props, ref) => { const Input = forwardRef<InputRef, InputProps>((props, ref) => {

View File

@ -2,7 +2,7 @@ import React, { useState } from 'react';
import { mount } from 'enzyme'; import { mount } from 'enzyme';
// eslint-disable-next-line import/no-unresolved // eslint-disable-next-line import/no-unresolved
import Form from '../../form'; import Form from '../../form';
import Input from '..'; import Input, { InputProps, InputRef } from '..';
import mountTest from '../../../tests/shared/mountTest'; import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest'; import rtlTest from '../../../tests/shared/rtlTest';
@ -29,7 +29,7 @@ describe('Input', () => {
}); });
it('select()', () => { it('select()', () => {
const ref = React.createRef(); const ref = React.createRef<InputRef>();
mount(<Input ref={ref} />); mount(<Input ref={ref} />);
ref.current?.select(); ref.current?.select();
}); });
@ -55,7 +55,7 @@ describe('Input', () => {
describe('focus trigger warning', () => { describe('focus trigger warning', () => {
it('not trigger', () => { it('not trigger', () => {
const wrapper = mount(<Input suffix="bamboo" />); const wrapper = mount(<Input suffix="bamboo" />);
wrapper.find('input').instance().focus(); (wrapper.find('input').instance() as any).focus();
wrapper.setProps({ wrapper.setProps({
suffix: 'light', suffix: 'light',
}); });
@ -63,7 +63,7 @@ describe('Input', () => {
}); });
it('trigger warning', () => { it('trigger warning', () => {
const wrapper = mount(<Input />); const wrapper = mount(<Input />);
wrapper.find('input').first().getDOMNode().focus(); wrapper.find('input').first().getDOMNode<HTMLInputElement>().focus();
wrapper.setProps({ wrapper.setProps({
suffix: 'light', suffix: 'light',
}); });
@ -77,11 +77,11 @@ describe('Input', () => {
it('set mouse cursor position', () => { it('set mouse cursor position', () => {
const defaultValue = '11111'; const defaultValue = '11111';
const valLength = defaultValue.length; const valLength = defaultValue.length;
const ref = React.createRef(); const ref = React.createRef<InputRef>();
const wrapper = mount(<Input ref={ref} autoFocus defaultValue={defaultValue} />); const wrapper = mount(<Input ref={ref} autoFocus defaultValue={defaultValue} />);
ref.current?.setSelectionRange(valLength, valLength); ref.current?.setSelectionRange(valLength, valLength);
expect(wrapper.find('input').first().getDOMNode().selectionStart).toEqual(5); expect(wrapper.find('input').first().getDOMNode<HTMLInputElement>().selectionStart).toEqual(5);
expect(wrapper.find('input').first().getDOMNode().selectionEnd).toEqual(5); expect(wrapper.find('input').first().getDOMNode<HTMLInputElement>().selectionEnd).toEqual(5);
}); });
}); });
@ -106,8 +106,12 @@ describe('prefix and suffix', () => {
</>, </>,
); );
expect(wrapper.find('.prefix-with-hidden').at(0).getDOMNode().hidden).toBe(true); expect(wrapper.find('.prefix-with-hidden').at(0).getDOMNode<HTMLInputElement>().hidden).toBe(
expect(wrapper.find('.suffix-with-hidden').at(0).getDOMNode().hidden).toBe(true); true,
);
expect(wrapper.find('.suffix-with-hidden').at(0).getDOMNode<HTMLInputElement>().hidden).toBe(
true,
);
}); });
}); });
@ -143,6 +147,7 @@ describe('Input setting hidden', () => {
showCount showCount
allowClear allowClear
prefix="11" prefix="11"
// @ts-ignore
suffix="22" suffix="22"
addonBefore="http://" addonBefore="http://"
addonAfter=".com" addonAfter=".com"
@ -162,10 +167,10 @@ describe('Input setting hidden', () => {
</>, </>,
); );
expect(wrapper.find('.input').at(0).getDOMNode().hidden).toBe(true); expect(wrapper.find('.input').at(0).getDOMNode<HTMLInputElement>().hidden).toBe(true);
expect(wrapper.find('.input-search').at(0).getDOMNode().hidden).toBe(true); expect(wrapper.find('.input-search').at(0).getDOMNode<HTMLInputElement>().hidden).toBe(true);
expect(wrapper.find('.input-textarea').at(0).getDOMNode().hidden).toBe(true); expect(wrapper.find('.input-textarea').at(0).getDOMNode<HTMLInputElement>().hidden).toBe(true);
expect(wrapper.find('.input-password').at(0).getDOMNode().hidden).toBe(true); expect(wrapper.find('.input-password').at(0).getDOMNode<HTMLInputElement>().hidden).toBe(true);
}); });
}); });
@ -250,17 +255,18 @@ describe('Input allowClear', () => {
it('should change type when click', () => { it('should change type when click', () => {
const wrapper = mount(<Input allowClear />); const wrapper = mount(<Input allowClear />);
wrapper.find('input').simulate('change', { target: { value: '111' } }); wrapper.find('input').simulate('change', { target: { value: '111' } });
expect(wrapper.find('input').getDOMNode().value).toEqual('111'); expect(wrapper.find('input').getDOMNode<HTMLInputElement>().value).toEqual('111');
expect(wrapper.render()).toMatchSnapshot(); expect(wrapper.render()).toMatchSnapshot();
wrapper.find('.ant-input-clear-icon').at(0).simulate('click'); wrapper.find('.ant-input-clear-icon').at(0).simulate('click');
expect(wrapper.render()).toMatchSnapshot(); expect(wrapper.render()).toMatchSnapshot();
expect(wrapper.find('input').getDOMNode().value).toEqual(''); expect(wrapper.find('input').getDOMNode<HTMLInputElement>().value).toEqual('');
}); });
it('should not show icon if value is undefined, null or empty string', () => { it('should not show icon if value is undefined, null or empty string', () => {
// @ts-ignore
const wrappers = [null, undefined, ''].map(val => mount(<Input allowClear value={val} />)); const wrappers = [null, undefined, ''].map(val => mount(<Input allowClear value={val} />));
wrappers.forEach(wrapper => { wrappers.forEach(wrapper => {
expect(wrapper.find('input').getDOMNode().value).toEqual(''); expect(wrapper.find('input').getDOMNode<HTMLInputElement>().value).toEqual('');
expect(wrapper.find('.ant-input-clear-icon-hidden').exists()).toBeTruthy(); expect(wrapper.find('.ant-input-clear-icon-hidden').exists()).toBeTruthy();
expect(wrapper.render()).toMatchSnapshot(); expect(wrapper.render()).toMatchSnapshot();
}); });
@ -268,41 +274,43 @@ describe('Input allowClear', () => {
it('should not show icon if defaultValue is undefined, null or empty string', () => { it('should not show icon if defaultValue is undefined, null or empty string', () => {
const wrappers = [null, undefined, ''].map(val => const wrappers = [null, undefined, ''].map(val =>
// @ts-ignore
mount(<Input allowClear defaultValue={val} />), mount(<Input allowClear defaultValue={val} />),
); );
wrappers.forEach(wrapper => { wrappers.forEach(wrapper => {
expect(wrapper.find('input').getDOMNode().value).toEqual(''); expect(wrapper.find('input').getDOMNode<HTMLInputElement>().value).toEqual('');
expect(wrapper.find('.ant-input-clear-icon-hidden').exists()).toBeTruthy(); expect(wrapper.find('.ant-input-clear-icon-hidden').exists()).toBeTruthy();
expect(wrapper.render()).toMatchSnapshot(); expect(wrapper.render()).toMatchSnapshot();
}); });
}); });
it('should trigger event correctly', () => { it('should trigger event correctly', () => {
let argumentEventObject; let argumentEventObject: React.ChangeEvent<HTMLInputElement> | undefined;
let argumentEventObjectValue; let argumentEventObjectValue;
const onChange = e => { const onChange: InputProps['onChange'] = e => {
argumentEventObject = e; argumentEventObject = e;
argumentEventObjectValue = e.target.value; argumentEventObjectValue = e.target.value;
}; };
const wrapper = mount(<Input allowClear defaultValue="111" onChange={onChange} />); const wrapper = mount(<Input allowClear defaultValue="111" onChange={onChange} />);
wrapper.find('.ant-input-clear-icon').at(0).simulate('click'); wrapper.find('.ant-input-clear-icon').at(0).simulate('click');
expect(argumentEventObject.type).toBe('click'); expect(argumentEventObject?.type).toBe('click');
expect(argumentEventObjectValue).toBe(''); expect(argumentEventObjectValue).toBe('');
expect(wrapper.find('input').at(0).getDOMNode().value).toBe(''); expect(wrapper.find('input').at(0).getDOMNode<HTMLInputElement>().value).toBe('');
}); });
it('should trigger event correctly on controlled mode', () => { it('should trigger event correctly on controlled mode', () => {
let argumentEventObject; let argumentEventObject: React.ChangeEvent<HTMLInputElement> | undefined;
let argumentEventObjectValue; let argumentEventObjectValue;
const onChange = e => { const onChange: InputProps['onChange'] = e => {
argumentEventObject = e; argumentEventObject = e;
argumentEventObjectValue = e.target.value; argumentEventObjectValue = e.target.value;
}; };
const wrapper = mount(<Input allowClear value="111" onChange={onChange} />); const wrapper = mount(<Input allowClear value="111" onChange={onChange} />);
wrapper.find('.ant-input-clear-icon').at(0).simulate('click'); wrapper.find('.ant-input-clear-icon').at(0).simulate('click');
expect(argumentEventObject.type).toBe('click'); expect(argumentEventObject?.type).toBe('click');
expect(argumentEventObjectValue).toBe(''); expect(argumentEventObjectValue).toBe('');
expect(wrapper.find('input').at(0).getDOMNode().value).toBe('111'); expect(wrapper.find('input').at(0).getDOMNode<HTMLInputElement>().value).toBe('111');
}); });
it('should focus input after clear', () => { it('should focus input after clear', () => {
@ -332,12 +340,12 @@ describe('Input allowClear', () => {
const wrapper = mount(<Input allowClear defaultValue="value" onBlur={onBlur} />, { const wrapper = mount(<Input allowClear defaultValue="value" onBlur={onBlur} />, {
attachTo: document.body, attachTo: document.body,
}); });
wrapper.find('input').getDOMNode().focus(); wrapper.find('input').getDOMNode<HTMLInputElement>().focus();
wrapper.find('.ant-input-clear-icon').at(0).simulate('mouseDown'); wrapper.find('.ant-input-clear-icon').at(0).simulate('mouseDown');
wrapper.find('.ant-input-clear-icon').at(0).simulate('click'); wrapper.find('.ant-input-clear-icon').at(0).simulate('click');
wrapper.find('.ant-input-clear-icon').at(0).simulate('mouseUp'); wrapper.find('.ant-input-clear-icon').at(0).simulate('mouseUp');
wrapper.find('.ant-input-clear-icon').at(0).simulate('focus'); wrapper.find('.ant-input-clear-icon').at(0).simulate('focus');
wrapper.find('.ant-input-clear-icon').at(0).getDOMNode().click(); wrapper.find('.ant-input-clear-icon').at(0).getDOMNode<HTMLInputElement>().click();
expect(onBlur).not.toBeCalled(); expect(onBlur).not.toBeCalled();
wrapper.unmount(); wrapper.unmount();
}); });
@ -359,12 +367,12 @@ describe('Input allowClear', () => {
const wrapper = mount(<App />); const wrapper = mount(<App />);
wrapper.find('input').getDOMNode().focus(); wrapper.find('input').getDOMNode<HTMLInputElement>().focus();
wrapper.find('input').simulate('change', { target: { value: '111' } }); wrapper.find('input').simulate('change', { target: { value: '111' } });
expect(wrapper.find('input').getDOMNode().value).toEqual('111'); expect(wrapper.find('input').getDOMNode<HTMLInputElement>().value).toEqual('111');
wrapper.find('.ant-input-clear-icon').at(0).simulate('click'); wrapper.find('.ant-input-clear-icon').at(0).simulate('click');
expect(wrapper.find('input').getDOMNode().value).toEqual(''); expect(wrapper.find('input').getDOMNode<HTMLInputElement>().value).toEqual('');
wrapper.unmount(); wrapper.unmount();
}); });
@ -375,10 +383,11 @@ describe('Input allowClear', () => {
}); });
it('should display boolean value as string', () => { it('should display boolean value as string', () => {
// @ts-ignore
const wrapper = mount(<Input value />); const wrapper = mount(<Input value />);
expect(wrapper.find('input').first().getDOMNode().value).toBe('true'); expect(wrapper.find('input').first().getDOMNode<HTMLInputElement>().value).toBe('true');
wrapper.setProps({ value: false }); wrapper.setProps({ value: false });
expect(wrapper.find('input').first().getDOMNode().value).toBe('false'); expect(wrapper.find('input').first().getDOMNode<HTMLInputElement>().value).toBe('false');
}); });
it('should support custom clearIcon', () => { it('should support custom clearIcon', () => {
@ -386,3 +395,19 @@ describe('Input allowClear', () => {
expect(wrapper.find('.ant-input-clear-icon').text()).toBe('clear'); expect(wrapper.find('.ant-input-clear-icon').text()).toBe('clear');
}); });
}); });
describe('typescript types ', () => {
it('InputProps type should support data-* attributes', () => {
const props: InputProps = {
value: 123,
// expect no ts error here
'data-testid': 'test-id',
'data-id': '12345',
};
const wrapper = mount(<Input {...props} />);
const input = wrapper.find('input').first().getDOMNode();
expect(input.getAttribute('data-testid')).toBe('test-id');
expect(input.getAttribute('data-id')).toBe('12345');
});
});