ant-design/components/input/__tests__/index.test.js
Rustin 767d2d0638 feat: Add allowClear to TextArea (#19310)
* add allow clear to textarea

revert textarea md

refactor textarea css

fix textarea props bug

add test and update snapshot

update doc

add margin

refactor textarea to reuse fixControlledValue and setValue method

add clearable input to reuse code

refactor clearable input

finish refactor

refactor clearable input

refactor input and textArea

finish refactor

update test snapshots

fix input props bug

fix dom issue

fix textarea dom issue

fix textarea test bug

fix textarea dom issue

refactor code and fix textarea dom issue

fix input dom issue

fix typo error

update test snapshots

fix ci failed issues

adjust margin

* remove useless code fix ci failed issue

* fix textarea padding issue

* update snapshots

* fix padding issue
2019-11-01 18:19:29 +08:00

418 lines
13 KiB
JavaScript

import React from 'react';
import { mount } from 'enzyme';
// eslint-disable-next-line import/no-unresolved
import Form from '../../form';
import Input from '..';
import focusTest from '../../../tests/shared/focusTest';
import mountTest from '../../../tests/shared/mountTest';
import calculateNodeHeight, { calculateNodeStyling } from '../calculateNodeHeight';
const { TextArea } = Input;
describe('Input', () => {
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
afterEach(() => {
errorSpy.mockReset();
});
afterAll(() => {
errorSpy.mockRestore();
});
focusTest(Input);
mountTest(Input);
mountTest(Input.Group);
it('should support maxLength', () => {
const wrapper = mount(<Input maxLength={3} />);
expect(wrapper).toMatchSnapshot();
});
it('select()', () => {
const wrapper = mount(<Input />);
wrapper.instance().select();
});
describe('focus trigger warning', () => {
it('not trigger', () => {
const wrapper = mount(<Input suffix="bamboo" />);
wrapper
.find('input')
.instance()
.focus();
wrapper.setProps({
suffix: 'light',
});
expect(errorSpy).not.toHaveBeenCalled();
});
it('trigger warning', () => {
const wrapper = mount(<Input />);
wrapper
.find('input')
.instance()
.focus();
wrapper.setProps({
suffix: 'light',
});
expect(errorSpy).toHaveBeenCalledWith(
'Warning: [antd: Input] When Input is focused, dynamic add or remove prefix / suffix will make it lose focus caused by dom structure change. Read more: https://ant.design/components/input/#FAQ',
);
});
});
});
focusTest(TextArea);
describe('TextArea', () => {
beforeAll(() => {
jest.useFakeTimers();
});
afterAll(() => {
jest.useRealTimers();
});
it('should auto calculate height according to content length', () => {
const wrapper = mount(<TextArea value="" readOnly autoSize />);
const mockFunc = jest.spyOn(wrapper.instance().resizableTextArea, 'resizeTextarea');
wrapper.setProps({ value: '1111\n2222\n3333' });
jest.runAllTimers();
expect(mockFunc).toHaveBeenCalledTimes(1);
wrapper.setProps({ value: '1111' });
jest.runAllTimers();
expect(mockFunc).toHaveBeenCalledTimes(2);
wrapper.update();
expect(wrapper.find('textarea').props().style.overflow).toBeFalsy();
});
it('should support onPressEnter and onKeyDown', () => {
const fakeHandleKeyDown = jest.fn();
const fakeHandlePressEnter = jest.fn();
const wrapper = mount(
<TextArea onKeyDown={fakeHandleKeyDown} onPressEnter={fakeHandlePressEnter} />,
);
/** keyCode 65 is A */
wrapper.find('textarea').simulate('keydown', { keyCode: 65 });
expect(fakeHandleKeyDown).toHaveBeenCalledTimes(1);
expect(fakeHandlePressEnter).toHaveBeenCalledTimes(0);
/** keyCode 13 is Enter */
wrapper.find('textarea').simulate('keydown', { keyCode: 13 });
expect(fakeHandleKeyDown).toHaveBeenCalledTimes(2);
expect(fakeHandlePressEnter).toHaveBeenCalledTimes(1);
});
it('should support disabled', () => {
const wrapper = mount(<TextArea disabled />);
expect(wrapper).toMatchSnapshot();
});
it('should support maxLength', () => {
const wrapper = mount(<TextArea maxLength={10} />);
expect(wrapper).toMatchSnapshot();
});
it('calculateNodeStyling works correctly', () => {
const wrapper = document.createElement('textarea');
wrapper.id = 'test';
wrapper.wrap = 'wrap';
calculateNodeStyling(wrapper, true);
const value = calculateNodeStyling(wrapper, true);
expect(value).toEqual({
borderSize: 2,
boxSizing: '',
paddingSize: 4,
sizingStyle:
'letter-spacing:normal;line-height:normal;padding-top:2px;padding-bottom:2px;font-family:-webkit-small-control;font-weight:;font-size:;font-variant:;text-rendering:auto;text-transform:none;width:;text-indent:0;padding-left:2px;padding-right:2px;border-width:1px;box-sizing:',
});
});
it('boxSizing === "border-box"', () => {
const wrapper = document.createElement('textarea');
wrapper.style.boxSizing = 'border-box';
const { height } = calculateNodeHeight(wrapper);
expect(height).toBe(2);
});
it('boxSizing === "content-box"', () => {
const wrapper = document.createElement('textarea');
wrapper.style.boxSizing = 'content-box';
const { height } = calculateNodeHeight(wrapper);
expect(height).toBe(-4);
});
it('minRows or maxRows is not null', () => {
const wrapper = document.createElement('textarea');
expect(calculateNodeHeight(wrapper, 1, 1)).toEqual({
height: 0,
maxHeight: 9007199254740991,
minHeight: -4,
overflowY: undefined,
});
wrapper.style.boxSizing = 'content-box';
expect(calculateNodeHeight(wrapper, 1, 1)).toEqual({
height: -4,
maxHeight: 9007199254740991,
minHeight: -4,
overflowY: undefined,
});
});
it('when prop value not in this.props, resizeTextarea should be called', () => {
const wrapper = mount(<TextArea aria-label="textarea" />);
const resizeTextarea = jest.spyOn(wrapper.instance().resizableTextArea, 'resizeTextarea');
wrapper.find('textarea').simulate('change', 'test');
expect(resizeTextarea).toHaveBeenCalled();
});
it('handleKeyDown', () => {
const onPressEnter = jest.fn();
const onKeyDown = jest.fn();
const wrapper = mount(
<TextArea onPressEnter={onPressEnter} onKeyDown={onKeyDown} aria-label="textarea" />,
);
wrapper.instance().handleKeyDown({ keyCode: 13 });
expect(onPressEnter).toHaveBeenCalled();
expect(onKeyDown).toHaveBeenCalled();
});
});
describe('As Form Control', () => {
it('should be reset when wrapped in form.getFieldDecorator without initialValue', () => {
class Demo extends React.Component {
reset = () => {
const { form } = this.props;
form.resetFields();
};
render() {
const {
form: { getFieldDecorator },
} = this.props;
return (
<Form>
<Form.Item>{getFieldDecorator('input')(<Input />)}</Form.Item>
<Form.Item>{getFieldDecorator('textarea')(<Input.TextArea />)}</Form.Item>
<button type="button" onClick={this.reset}>
reset
</button>
</Form>
);
}
}
const DemoForm = Form.create()(Demo);
const wrapper = mount(<DemoForm />);
wrapper.find('input').simulate('change', { target: { value: '111' } });
wrapper.find('textarea').simulate('change', { target: { value: '222' } });
expect(wrapper.find('input').prop('value')).toBe('111');
expect(wrapper.find('textarea').prop('value')).toBe('222');
wrapper.find('button').simulate('click');
expect(wrapper.find('input').prop('value')).toBe('');
expect(wrapper.find('textarea').prop('value')).toBe('');
});
});
describe('Input.Search', () => {
it('should support suffix', () => {
const wrapper = mount(<Input.Search suffix="suffix" />);
expect(wrapper).toMatchSnapshot();
});
});
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).toMatchSnapshot();
wrapper
.find('.ant-input-clear-icon')
.at(0)
.simulate('click');
expect(wrapper).toMatchSnapshot();
expect(wrapper.find('input').getDOMNode().value).toEqual('');
});
it('should not show icon if value is undefined, null or empty string', () => {
const wrappers = [null, undefined, ''].map(val => mount(<Input allowClear value={val} />));
wrappers.forEach(wrapper => {
expect(wrapper.find('input').getDOMNode().value).toEqual('');
expect(wrapper.find('.ant-input-clear-icon').exists()).toEqual(false);
expect(wrapper).toMatchSnapshot();
});
});
it('should not show icon if defaultValue is undefined, null or empty string', () => {
const wrappers = [null, undefined, ''].map(val =>
mount(<Input allowClear defaultValue={val} />),
);
wrappers.forEach(wrapper => {
expect(wrapper.find('input').getDOMNode().value).toEqual('');
expect(wrapper.find('.ant-input-clear-icon').exists()).toEqual(false);
expect(wrapper).toMatchSnapshot();
});
});
it('should trigger event correctly', () => {
let argumentEventObject;
let argumentEventObjectValue;
const 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(argumentEventObjectValue).toBe('');
expect(
wrapper
.find('input')
.at(0)
.getDOMNode().value,
).toBe('');
});
it('should trigger event correctly on controlled mode', () => {
let argumentEventObject;
let argumentEventObjectValue;
const 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(argumentEventObjectValue).toBe('');
expect(
wrapper
.find('input')
.at(0)
.getDOMNode().value,
).toBe('111');
});
it('should focus input after clear', () => {
const wrapper = mount(<Input allowClear defaultValue="111" />);
wrapper
.find('.ant-input-clear-icon')
.at(0)
.simulate('click');
expect(document.activeElement).toBe(
wrapper
.find('input')
.at(0)
.getDOMNode(),
);
});
it('should not support allowClear when it is disabled', () => {
const wrapper = mount(<Input allowClear defaultValue="111" disabled />);
expect(wrapper.find('.ant-input-clear-icon').length).toBe(0);
});
});
describe('TextArea allowClear', () => {
it('should change type when click', () => {
const wrapper = mount(<TextArea allowClear />);
wrapper.find('textarea').simulate('change', { target: { value: '111' } });
expect(wrapper.find('textarea').getDOMNode().value).toEqual('111');
expect(wrapper).toMatchSnapshot();
wrapper
.find('.ant-input-textarea-clear-icon')
.at(0)
.simulate('click');
expect(wrapper).toMatchSnapshot();
expect(wrapper.find('textarea').getDOMNode().value).toEqual('');
});
it('should not show icon if value is undefined, null or empty string', () => {
const wrappers = [null, undefined, ''].map(val => mount(<TextArea allowClear value={val} />));
wrappers.forEach(wrapper => {
expect(wrapper.find('textarea').getDOMNode().value).toEqual('');
expect(wrapper.find('.ant-input-textarea-clear-icon').exists()).toEqual(false);
expect(wrapper).toMatchSnapshot();
});
});
it('should not show icon if defaultValue is undefined, null or empty string', () => {
const wrappers = [null, undefined, ''].map(val =>
mount(<TextArea allowClear defaultValue={val} />),
);
wrappers.forEach(wrapper => {
expect(wrapper.find('textarea').getDOMNode().value).toEqual('');
expect(wrapper.find('.ant-textarea-clear-icon').exists()).toEqual(false);
expect(wrapper).toMatchSnapshot();
});
});
it('should trigger event correctly', () => {
let argumentEventObject;
let argumentEventObjectValue;
const onChange = e => {
argumentEventObject = e;
argumentEventObjectValue = e.target.value;
};
const wrapper = mount(<TextArea allowClear defaultValue="111" onChange={onChange} />);
wrapper
.find('.ant-input-textarea-clear-icon')
.at(0)
.simulate('click');
expect(argumentEventObject.type).toBe('click');
expect(argumentEventObjectValue).toBe('');
expect(
wrapper
.find('textarea')
.at(0)
.getDOMNode().value,
).toBe('');
});
it('should trigger event correctly on controlled mode', () => {
let argumentEventObject;
let argumentEventObjectValue;
const onChange = e => {
argumentEventObject = e;
argumentEventObjectValue = e.target.value;
};
const wrapper = mount(<TextArea allowClear value="111" onChange={onChange} />);
wrapper
.find('.ant-input-textarea-clear-icon')
.at(0)
.simulate('click');
expect(argumentEventObject.type).toBe('click');
expect(argumentEventObjectValue).toBe('');
expect(
wrapper
.find('textarea')
.at(0)
.getDOMNode().value,
).toBe('111');
});
it('should focus textarea after clear', () => {
const wrapper = mount(<TextArea allowClear defaultValue="111" />);
wrapper
.find('.ant-input-textarea-clear-icon')
.at(0)
.simulate('click');
expect(document.activeElement).toBe(
wrapper
.find('textarea')
.at(0)
.getDOMNode(),
);
});
it('should not support allowClear when it is disabled', () => {
const wrapper = mount(<TextArea allowClear defaultValue="111" disabled />);
expect(wrapper.find('.ant-input-textarea-clear-icon').length).toBe(0);
});
});