ant-design/components/form/__tests__/list.test.js

236 lines
6.3 KiB
JavaScript

import React from 'react';
import { mount } from 'enzyme';
import { act } from 'react-dom/test-utils';
import Form from '..';
import Input from '../../input';
import Button from '../../button';
import { sleep } from '../../../tests/utils';
describe('Form.List', () => {
async function change(wrapper, index, value) {
wrapper.find(Input).at(index).simulate('change', { target: { value } });
await sleep();
wrapper.update();
}
function testList(name, renderField) {
it(name, async () => {
jest.useFakeTimers();
const wrapper = mount(
<Form>
<Form.List name="list">
{(fields, { add, remove }) => (
<>
{fields.map(field => renderField(field))}
<Button className="add" onClick={add}>
Add
</Button>
<Button
className="remove-0"
onClick={() => {
remove(0);
}}
/>
<Button
className="remove-1"
onClick={() => {
remove(1);
}}
/>
</>
)}
</Form.List>
</Form>,
);
function operate(className) {
act(() => {
wrapper.find(className).last().simulate('click');
jest.runAllTimers();
});
wrapper.update();
}
operate('.add');
expect(wrapper.find(Input).length).toBe(1);
operate('.add');
expect(wrapper.find(Input).length).toBe(2);
operate('.add');
expect(wrapper.find(Input).length).toBe(3);
await change(wrapper, 2, '');
act(() => {
jest.runAllTimers();
});
wrapper.update();
expect(wrapper.find('.ant-form-item-explain div').length).toBe(1);
operate('.remove-0');
expect(wrapper.find(Input).length).toBe(2);
expect(wrapper.find('.ant-form-item-explain div').length).toBe(1);
operate('.remove-1');
expect(wrapper.find(Input).length).toBe(1);
expect(wrapper.find('.ant-form-item-explain div').length).toBe(0);
jest.useRealTimers();
});
}
testList('operation correctly', field => (
<Form.Item {...field} rules={[{ required: true }]}>
<Input />
</Form.Item>
));
testList('nest noStyle', field => (
<Form.Item key={field.key}>
<Form.Item noStyle {...field} rules={[{ required: true }]}>
<Input />
</Form.Item>
</Form.Item>
));
it('correct onFinish values', async () => {
async function click(wrapper, className) {
wrapper.find(className).last().simulate('click');
await sleep();
wrapper.update();
}
const onFinish = jest.fn().mockImplementation(() => {});
const wrapper = mount(
<Form
onFinish={v => {
if (typeof v.list[0] === 'object') {
/* old version led to SyntheticEvent be passed as an value here
that led to weird infinite loop somewhere and OutOfMemory crash */
v = new Error('We expect value to be a primitive here');
}
onFinish(v);
}}
>
<Form.List name="list">
{(fields, { add, remove }) => (
<>
{fields.map(field => (
// key is in a field
// eslint-disable-next-line react/jsx-key
<Form.Item {...field}>
<Input />
</Form.Item>
))}
<Button className="add" onClick={add}>
Add
</Button>
<Button className="remove" onClick={() => remove(0)}>
Remove
</Button>
</>
)}
</Form.List>
</Form>,
);
await click(wrapper, '.add');
await change(wrapper, 0, 'input1');
wrapper.find('form').simulate('submit');
await sleep();
expect(onFinish).toHaveBeenLastCalledWith({ list: ['input1'] });
await click(wrapper, '.add');
await change(wrapper, 1, 'input2');
await click(wrapper, '.add');
await change(wrapper, 2, 'input3');
wrapper.find('form').simulate('submit');
await sleep();
expect(onFinish).toHaveBeenLastCalledWith({ list: ['input1', 'input2', 'input3'] });
await click(wrapper, '.remove'); // will remove first input
wrapper.find('form').simulate('submit');
await sleep();
expect(onFinish).toHaveBeenLastCalledWith({ list: ['input2', 'input3'] });
});
it('list errors', async () => {
jest.useFakeTimers();
let operation;
const wrapper = mount(
<Form>
<Form.List
name="list"
rules={[
{
validator: async (_, value) => {
if (value.length < 2) {
return Promise.reject(new Error('At least 2'));
}
},
},
]}
>
{(_, opt, { errors }) => {
operation = opt;
return <Form.ErrorList errors={errors} />;
}}
</Form.List>
</Form>,
);
async function addItem() {
await act(async () => {
operation.add();
await sleep(100);
jest.runAllTimers();
wrapper.update();
});
}
await addItem();
expect(wrapper.find('.ant-form-item-explain div').text()).toEqual('At least 2');
await addItem();
expect(wrapper.find('.ant-form-item-explain div')).toHaveLength(0);
jest.useRealTimers();
});
describe('ErrorList component', () => {
it('should trigger onDomErrorVisibleChange by motion end', async () => {
jest.useFakeTimers();
const onDomErrorVisibleChange = jest.fn();
const wrapper = mount(
<Form.ErrorList
errors={['bamboo is light']}
onDomErrorVisibleChange={onDomErrorVisibleChange}
/>,
);
await act(async () => {
await sleep();
jest.runAllTimers();
wrapper.update();
});
act(() => {
wrapper.find('CSSMotion').props().onLeaveEnd();
});
expect(onDomErrorVisibleChange).toHaveBeenCalledWith(false);
jest.useRealTimers();
});
});
it('should render empty without errors', () => {
const wrapper = mount(<Form.ErrorList />);
expect(wrapper.render()).toMatchSnapshot();
});
});