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;
status?: InputStatus;
bordered?: boolean;
[key: `data-${string}`]: string;
}
const Input = forwardRef<InputRef, InputProps>((props, ref) => {

View File

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