import React from 'react';
import { act } from 'react-dom/test-utils';
import Form from '..';
import { fireEvent, render, sleep } from '../../../tests/utils';
import Button from '../../button';
import Input from '../../input';
describe('Form.List', () => {
async function change(wrapper, index, value) {
fireEvent.change(wrapper.getElementsByClassName('ant-input')[index], { target: { value } });
await sleep();
}
function testList(name, renderField) {
it(name, async () => {
jest.useFakeTimers();
const { container } = render(
{(fields, { add, remove }) => (
<>
{fields.map(field => renderField(field))}
,
);
function operate(className) {
act(() => {
fireEvent.click(container.querySelector(className));
jest.runAllTimers();
});
}
operate('.add');
expect(container.getElementsByClassName('ant-input').length).toBe(1);
operate('.add');
expect(container.getElementsByClassName('ant-input').length).toBe(2);
operate('.add');
expect(container.getElementsByClassName('ant-input').length).toBe(3);
await change(container, 2, '');
for (let i = 0; i < 10; i += 1) {
act(() => {
jest.runAllTimers();
});
}
expect(container.getElementsByClassName('ant-form-item-explain').length).toBe(1);
operate('.remove-0');
expect(container.getElementsByClassName('ant-input').length).toBe(2);
expect(container.getElementsByClassName('ant-form-item-explain').length).toBe(1);
operate('.remove-1');
expect(container.getElementsByClassName('ant-input').length).toBe(1);
expect(container.getElementsByClassName('ant-form-item-explain').length).toBe(0);
jest.useRealTimers();
});
}
testList('operation correctly', field => (
));
// FIXME: @zombieJ React 18 StrictMode
testList('nest noStyle', field => (
));
it('correct onFinish values', async () => {
async function click(wrapper, className) {
fireEvent.click(wrapper.querySelector(className));
}
const onFinish = jest.fn().mockImplementation(() => {});
const { container } = render(
{(fields, { add, remove }) => (
<>
{fields.map(field => (
// key is in a field
// eslint-disable-next-line react/jsx-key
))}
Add
remove(0)}>
Remove
>
)}
,
);
await click(container, '.add');
await change(container, 0, 'input1');
fireEvent.submit(container.querySelector('form'));
await sleep();
expect(onFinish).toHaveBeenLastCalledWith({ list: ['input1'] });
await click(container, '.add');
await change(container, 1, 'input2');
await click(container, '.add');
await change(container, 2, 'input3');
fireEvent.submit(container.querySelector('form'));
await sleep();
expect(onFinish).toHaveBeenLastCalledWith({ list: ['input1', 'input2', 'input3'] });
await click(container, '.remove'); // will remove first input
fireEvent.submit(container.querySelector('form'));
await sleep();
expect(onFinish).toHaveBeenLastCalledWith({ list: ['input2', 'input3'] });
});
it('list errors', async () => {
jest.useFakeTimers();
let operation;
const { container } = render(
{
if (value.length < 2) {
return Promise.reject(new Error('At least 2'));
}
},
},
]}
>
{(_, opt, { errors }) => {
operation = opt;
return ;
}}
,
);
async function addItem() {
await act(async () => {
operation.add();
await sleep(100);
jest.runAllTimers();
});
act(() => {
jest.runAllTimers();
});
}
await addItem();
expect(container.querySelector('.ant-form-item-explain div').innerHTML).toEqual('At least 2');
await addItem();
expect(container.getElementsByClassName('ant-form-item-explain div')).toHaveLength(0);
jest.useRealTimers();
});
it('should render empty without errors', () => {
const { container } = render();
expect(container.firstChild).toMatchSnapshot();
});
it('no warning when reset in validate', async () => {
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
const Demo = () => {
const [form] = Form.useForm();
React.useEffect(() => {
form.setFieldsValue({
list: [1],
});
}, []);
return (
{fields =>
fields.map(field => (
))
}
{
form.validateFields().then(() => {
form.resetFields();
});
}}
>
Validate
);
};
const { container } = render();
fireEvent.click(container.querySelector('button'));
await sleep();
expect(errorSpy).not.toHaveBeenCalled();
errorSpy.mockRestore();
});
});