-
,
@@ -90,7 +77,7 @@ describe('Form.List', () => {
// Not a array
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
resetWarned();
- mount(
+ render(
{() => null}
,
@@ -100,22 +87,22 @@ describe('Form.List', () => {
});
it('operation', async () => {
- let operation;
- const [wrapper, getList] = generateForm((fields, opt) => {
+ let operation: ListOperations;
+ const [container] = generateForm((fields, opt) => {
operation = opt;
return (
{fields.map(field => (
-
-
+
+
))}
);
});
- function matchKey(index, key) {
- expect(getList().find(Field).at(index).key()).toEqual(key);
+ function matchKey(index: number, key: React.Key) {
+ expect(getInput(container, index)).toHaveAttribute('data-key', String(key));
}
// Add
@@ -131,11 +118,8 @@ describe('Form.List', () => {
operation.add();
});
- wrapper.update();
- expect(getList().find(Field).length).toEqual(3);
- expect(form.getFieldsValue()).toEqual({
- list: [undefined, '2', undefined],
- });
+ expect(container.querySelectorAll('input')).toHaveLength(3);
+ expect(form.current?.getFieldsValue()).toEqual({ list: [undefined, '2', undefined] });
matchKey(0, '0');
matchKey(1, '1');
@@ -145,7 +129,6 @@ describe('Form.List', () => {
act(() => {
operation.move(2, 0);
});
- wrapper.update();
matchKey(0, '2');
matchKey(1, '0');
matchKey(2, '1');
@@ -154,7 +137,6 @@ describe('Form.List', () => {
act(() => {
operation.move(-1, 0);
});
- wrapper.update();
matchKey(0, '2');
matchKey(1, '0');
matchKey(2, '1');
@@ -164,7 +146,6 @@ describe('Form.List', () => {
operation.move(0, 10);
});
- wrapper.update();
matchKey(0, '2');
matchKey(1, '0');
matchKey(2, '1');
@@ -174,7 +155,6 @@ describe('Form.List', () => {
operation.move(-1, 10);
});
- wrapper.update();
matchKey(0, '2');
matchKey(1, '0');
matchKey(2, '1');
@@ -183,7 +163,6 @@ describe('Form.List', () => {
act(() => {
operation.move(0, 0);
});
- wrapper.update();
matchKey(0, '2');
matchKey(1, '0');
matchKey(2, '1');
@@ -192,19 +171,18 @@ describe('Form.List', () => {
act(() => {
operation.move(0, 2);
});
- wrapper.update();
matchKey(0, '0');
matchKey(1, '1');
matchKey(2, '2');
// Modify
- await changeValue(getField(getList(), 1), '222');
- expect(form.getFieldsValue()).toEqual({
+ await changeValue(getInput(container, 1), '222');
+ expect(form.current?.getFieldsValue()).toEqual({
list: [undefined, '222', undefined],
});
- expect(form.isFieldTouched(['list', 0])).toBeFalsy();
- expect(form.isFieldTouched(['list', 1])).toBeTruthy();
- expect(form.isFieldTouched(['list', 2])).toBeFalsy();
+ expect(form.current?.isFieldTouched(['list', 0])).toBeFalsy();
+ expect(form.current?.isFieldTouched(['list', 1])).toBeTruthy();
+ expect(form.current?.isFieldTouched(['list', 2])).toBeFalsy();
matchKey(0, '0');
matchKey(1, '1');
@@ -214,13 +192,12 @@ describe('Form.List', () => {
act(() => {
operation.remove(1);
});
- wrapper.update();
- expect(getList().find(Field).length).toEqual(2);
- expect(form.getFieldsValue()).toEqual({
+ expect(container.querySelectorAll('input')).toHaveLength(2);
+ expect(form.current?.getFieldsValue()).toEqual({
list: [undefined, undefined],
});
- expect(form.isFieldTouched(['list', 0])).toBeFalsy();
- expect(form.isFieldTouched(['list', 2])).toBeFalsy();
+ expect(form.current?.isFieldTouched(['list', 0])).toBeFalsy();
+ expect(form.current?.isFieldTouched(['list', 2])).toBeFalsy();
matchKey(0, '0');
matchKey(1, '2');
@@ -229,7 +206,6 @@ describe('Form.List', () => {
act(() => {
operation.remove(-1);
});
- wrapper.update();
matchKey(0, '0');
matchKey(1, '2');
@@ -238,29 +214,28 @@ describe('Form.List', () => {
act(() => {
operation.remove(99);
});
- wrapper.update();
matchKey(0, '0');
matchKey(1, '2');
});
it('remove when the param is Array', () => {
- let operation;
- const [wrapper, getList] = generateForm((fields, opt) => {
+ let operation: ListOperations;
+ const [container] = generateForm((fields, opt) => {
operation = opt;
return (
{fields.map(field => (
-
-
+
+
))}
);
});
- function matchKey(index, key) {
- expect(getList().find(Field).at(index).key()).toEqual(key);
+ function matchKey(index: number, key: React.Key) {
+ expect(getInput(container, index)).toHaveAttribute('data-key', String(key));
}
act(() => {
@@ -271,24 +246,20 @@ describe('Form.List', () => {
operation.add();
});
- wrapper.update();
- expect(getList().find(Field).length).toEqual(2);
+ expect(container.querySelectorAll('input')).toHaveLength(2);
// remove empty array
act(() => {
operation.remove([]);
});
- wrapper.update();
-
matchKey(0, '0');
matchKey(1, '1');
- // remove not esist element in array
+ // remove not exist element in array
act(() => {
operation.remove([-1, 99]);
});
- wrapper.update();
matchKey(0, '0');
matchKey(1, '1');
@@ -297,8 +268,7 @@ describe('Form.List', () => {
operation.remove([0]);
});
- wrapper.update();
- expect(getList().find(Field).length).toEqual(1);
+ expect(container.querySelectorAll('input')).toHaveLength(1);
matchKey(0, '1');
act(() => {
@@ -309,7 +279,6 @@ describe('Form.List', () => {
operation.add();
});
- wrapper.update();
matchKey(0, '1');
matchKey(1, '2');
matchKey(2, '3');
@@ -318,19 +287,18 @@ describe('Form.List', () => {
operation.remove([0, 1]);
});
- wrapper.update();
matchKey(0, '3');
});
it('add when the second param is number', () => {
- let operation;
+ let operation: ListOperations;
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
- const [wrapper, getList] = generateForm((fields, opt) => {
+ const [container] = generateForm((fields, opt) => {
operation = opt;
return (
{fields.map(field => (
-
+
))}
@@ -354,9 +322,8 @@ describe('Form.List', () => {
);
errorSpy.mockRestore();
- wrapper.update();
- expect(getList().find(Field).length).toEqual(3);
- expect(form.getFieldsValue()).toEqual({
+ expect(container.querySelectorAll('input')).toHaveLength(3);
+ expect(form.current?.getFieldsValue()).toEqual({
list: [undefined, '1', '2'],
});
@@ -367,20 +334,19 @@ describe('Form.List', () => {
operation.add('4', 3);
});
- wrapper.update();
- expect(getList().find(Field).length).toEqual(5);
- expect(form.getFieldsValue()).toEqual({
+ expect(container.querySelectorAll('input')).toHaveLength(5);
+ expect(form.current?.getFieldsValue()).toEqual({
list: ['0', undefined, '1', '4', '2'],
});
});
describe('validate', () => {
it('basic', async () => {
- const [, getList] = generateForm(
+ const [container] = generateForm(
fields => (
{fields.map(field => (
-
+
))}
@@ -391,17 +357,17 @@ describe('Form.List', () => {
},
);
- await changeValue(getField(getList()), '');
+ await changeValue(getInput(container), ['bamboo', '']);
- expect(form.getFieldError(['list', 0])).toEqual(["'list.0' is required"]);
+ expect(form.current?.getFieldError(['list', 0])).toEqual(["'list.0' is required"]);
});
it('remove should keep error', async () => {
- const [wrapper, getList] = generateForm(
+ const [container] = generateForm(
(fields, { remove }) => (
{fields.map(field => (
-
+
))}
@@ -419,23 +385,22 @@ describe('Form.List', () => {
},
);
- expect(wrapper.find(Input)).toHaveLength(2);
- await changeValue(getField(getList(), 1), '');
- expect(form.getFieldError(['list', 1])).toEqual(["'list.1' is required"]);
+ expect(container.querySelectorAll('input')).toHaveLength(2);
+ await changeValue(getInput(container, 1), ['bamboo', '']);
+ expect(form.current?.getFieldError(['list', 1])).toEqual(["'list.1' is required"]);
- wrapper.find('button').simulate('click');
- wrapper.update();
+ fireEvent.click(container.querySelector('button')!);
- expect(wrapper.find(Input)).toHaveLength(1);
- expect(form.getFieldError(['list', 0])).toEqual(["'list.1' is required"]);
+ expect(container.querySelectorAll('input')).toHaveLength(1);
+ expect(form.current?.getFieldError(['list', 0])).toEqual(["'list.1' is required"]);
});
it('when param of remove is array', async () => {
- const [wrapper, getList] = generateForm(
+ const [container] = generateForm(
(fields, { remove }) => (
{fields.map(field => (
-
+
))}
@@ -453,30 +418,33 @@ describe('Form.List', () => {
},
);
- expect(wrapper.find(Input)).toHaveLength(3);
- await changeValue(getField(getList(), 0), '');
- expect(form.getFieldError(['list', 0])).toEqual(["'list.0' is required"]);
+ expect(container.querySelectorAll('input')).toHaveLength(3);
+ await changeValue(getInput(container, 0), ['bamboo', '']);
+ expect(form.current?.getFieldError(['list', 0])).toEqual(["'list.0' is required"]);
- await changeValue(getField(getList(), 1), 'test');
- expect(form.getFieldError(['list', 1])).toEqual(["'list.1' must be at least 5 characters"]);
+ await changeValue(getInput(container, 1), 'test');
+ expect(form.current?.getFieldError(['list', 1])).toEqual([
+ "'list.1' must be at least 5 characters",
+ ]);
- await changeValue(getField(getList(), 2), '');
- expect(form.getFieldError(['list', 2])).toEqual(["'list.2' is required"]);
+ await changeValue(getInput(container, 2), ['bamboo', '']);
+ expect(form.current?.getFieldError(['list', 2])).toEqual(["'list.2' is required"]);
- wrapper.find('button').simulate('click');
- wrapper.update();
+ fireEvent.click(container.querySelector('button')!);
- expect(wrapper.find(Input)).toHaveLength(1);
- expect(form.getFieldError(['list', 0])).toEqual(["'list.1' must be at least 5 characters"]);
- expect(wrapper.find('input').props().value).toEqual('test');
+ expect(container.querySelectorAll('input')).toHaveLength(1);
+ expect(form.current?.getFieldError(['list', 0])).toEqual([
+ "'list.1' must be at least 5 characters",
+ ]);
+ expect(getInput(container).value).toEqual('test');
});
it('when add() second param is number', async () => {
- const [wrapper, getList] = generateForm(
+ const [container] = generateForm(
(fields, { add }) => (
{fields.map(field => (
-
+
))}
@@ -503,18 +471,20 @@ describe('Form.List', () => {
},
);
- expect(wrapper.find(Input)).toHaveLength(3);
- await changeValue(getField(getList(), 0), '');
- expect(form.getFieldError(['list', 0])).toEqual(["'list.0' is required"]);
+ expect(container.querySelectorAll('input')).toHaveLength(3);
+ await changeValue(getInput(container, 0), ['bamboo', '']);
+ expect(form.current?.getFieldError(['list', 0])).toEqual(["'list.0' is required"]);
- wrapper.find('.button').simulate('click');
- wrapper.find('.button1').simulate('click');
+ fireEvent.click(container.querySelector('.button')!);
+ fireEvent.click(container.querySelector('.button1')!);
- expect(wrapper.find(Input)).toHaveLength(5);
- expect(form.getFieldError(['list', 1])).toEqual(["'list.0' is required"]);
+ expect(container.querySelectorAll('input')).toHaveLength(5);
+ expect(form.current?.getFieldError(['list', 1])).toEqual(["'list.0' is required"]);
- await changeValue(getField(getList(), 1), 'test');
- expect(form.getFieldError(['list', 1])).toEqual(["'list.1' must be at least 5 characters"]);
+ await changeValue(getInput(container, 1), 'test');
+ expect(form.current?.getFieldError(['list', 1])).toEqual([
+ "'list.1' must be at least 5 characters",
+ ]);
});
});
@@ -530,14 +500,14 @@ describe('Form.List', () => {
// https://github.com/ant-design/ant-design/issues/25584
it('preserve should not break list', async () => {
- let operation;
- const [wrapper] = generateForm(
+ let operation: ListOperations;
+ const [container] = generateForm(
(fields, opt) => {
operation = opt;
return (
{fields.map(field => (
-
+
))}
@@ -551,30 +521,27 @@ describe('Form.List', () => {
act(() => {
operation.add();
});
- wrapper.update();
- expect(wrapper.find(Input)).toHaveLength(1);
+ expect(container.querySelectorAll('input')).toHaveLength(1);
// Remove
act(() => {
operation.remove(0);
});
- wrapper.update();
- expect(wrapper.find(Input)).toHaveLength(0);
+ expect(container.querySelectorAll('input')).toHaveLength(0);
// Add
act(() => {
operation.add();
});
- wrapper.update();
- expect(wrapper.find(Input)).toHaveLength(1);
+ expect(container.querySelectorAll('input')).toHaveLength(1);
});
it('list support validator', async () => {
- let operation;
- let currentMeta;
- let currentValue;
+ let operation: ListOperations;
+ let currentMeta: Meta;
+ let currentValue: any;
- const [wrapper] = generateForm(
+ generateForm(
(_, opt, meta) => {
operation = opt;
currentMeta = meta;
@@ -597,7 +564,6 @@ describe('Form.List', () => {
await act(async () => {
operation.add();
await timeout();
- wrapper.update();
});
expect(currentValue).toEqual([undefined]);
@@ -607,11 +573,11 @@ describe('Form.List', () => {
it('Nest list remove should trigger correct onValuesChange', () => {
const onValuesChange = jest.fn();
- const [wrapper] = generateForm(
+ const [container] = generateForm(
(fields, operation) => (
{fields.map(field => (
-
+
))}
@@ -631,14 +597,61 @@ describe('Form.List', () => {
},
);
- wrapper.find('button').simulate('click');
+ fireEvent.click(container.querySelector('button')!);
+ expect(onValuesChange).toHaveBeenCalledWith(expect.anything(), { list: [{ first: 'light' }] });
+ });
+
+ it('Nest list remove should trigger correct onValuesChange when no spread field props', () => {
+ const onValuesChange = jest.fn();
+
+ const [container] = generateForm(
+ (fields, operation) => (
+
+ ),
+ {
+ onValuesChange,
+ initialValues: {
+ list: [{ first: 'light' }],
+ },
+ },
+ );
+ fireEvent.click(container.querySelector('.add-btn')!);
+ expect(onValuesChange).toHaveBeenCalledWith(expect.anything(), {
+ list: [{ first: 'light' }, undefined],
+ });
+ fireEvent.click(container.querySelector('.remove-btn')!);
expect(onValuesChange).toHaveBeenCalledWith(expect.anything(), { list: [{ first: 'light' }] });
});
describe('isFieldTouched edge case', () => {
- it('virtual object', () => {
+ it('virtual object', async () => {
const formRef = React.createRef();
- const wrapper = mount(
+ const { container } = render(
@@ -650,58 +663,50 @@ describe('Form.List', () => {
);
// Not changed
- expect(formRef.current.isFieldTouched('user')).toBeFalsy();
- expect(formRef.current.isFieldsTouched(['user'], false)).toBeFalsy();
- expect(formRef.current.isFieldsTouched(['user'], true)).toBeFalsy();
+ expect(formRef.current?.isFieldTouched('user')).toBeFalsy();
+ expect(formRef.current?.isFieldsTouched(['user'], false)).toBeFalsy();
+ expect(formRef.current?.isFieldsTouched(['user'], true)).toBeFalsy();
// Changed
- wrapper
- .find('input')
- .first()
- .simulate('change', { target: { value: '' } });
+ await changeValue(getInput(container, 0), ['bamboo', '']);
- expect(formRef.current.isFieldTouched('user')).toBeTruthy();
- expect(formRef.current.isFieldsTouched(['user'], false)).toBeTruthy();
- expect(formRef.current.isFieldsTouched(['user'], true)).toBeTruthy();
+ expect(formRef.current?.isFieldTouched('user')).toBeTruthy();
+ expect(formRef.current?.isFieldsTouched(['user'], false)).toBeTruthy();
+ expect(formRef.current?.isFieldsTouched(['user'], true)).toBeTruthy();
});
- it('List children change', () => {
- const [wrapper] = generateForm(
+ it('List children change', async () => {
+ const [container] = generateForm(
fields => (
{fields.map(field => (
-
+
))}
),
- {
- initialValues: { list: ['light', 'bamboo'] },
- },
+ { initialValues: { list: ['light', 'bamboo'] } },
);
// Not changed yet
- expect(form.isFieldTouched('list')).toBeFalsy();
- expect(form.isFieldsTouched(['list'], false)).toBeFalsy();
- expect(form.isFieldsTouched(['list'], true)).toBeFalsy();
+ expect(form.current?.isFieldTouched('list')).toBeFalsy();
+ expect(form.current?.isFieldsTouched(['list'], false)).toBeFalsy();
+ expect(form.current?.isFieldsTouched(['list'], true)).toBeFalsy();
// Change children value
- wrapper
- .find('input')
- .first()
- .simulate('change', { target: { value: 'little' } });
+ await changeValue(getInput(container, 0), 'little');
- expect(form.isFieldTouched('list')).toBeTruthy();
- expect(form.isFieldsTouched(['list'], false)).toBeTruthy();
- expect(form.isFieldsTouched(['list'], true)).toBeTruthy();
+ expect(form.current?.isFieldTouched('list')).toBeTruthy();
+ expect(form.current?.isFieldsTouched(['list'], false)).toBeTruthy();
+ expect(form.current?.isFieldsTouched(['list'], true)).toBeTruthy();
});
it('List self change', () => {
- const [wrapper] = generateForm((fields, opt) => (
+ const [container] = generateForm((fields, opt) => (
{fields.map(field => (
-
+
))}
@@ -715,16 +720,16 @@ describe('Form.List', () => {
));
// Not changed yet
- expect(form.isFieldTouched('list')).toBeFalsy();
- expect(form.isFieldsTouched(['list'], false)).toBeFalsy();
- expect(form.isFieldsTouched(['list'], true)).toBeFalsy();
+ expect(form.current?.isFieldTouched('list')).toBeFalsy();
+ expect(form.current?.isFieldsTouched(['list'], false)).toBeFalsy();
+ expect(form.current?.isFieldsTouched(['list'], true)).toBeFalsy();
// Change children value
- wrapper.find('button').simulate('click');
+ fireEvent.click(container.querySelector('button')!);
- expect(form.isFieldTouched('list')).toBeTruthy();
- expect(form.isFieldsTouched(['list'], false)).toBeTruthy();
- expect(form.isFieldsTouched(['list'], true)).toBeTruthy();
+ expect(form.current?.isFieldTouched('list')).toBeTruthy();
+ expect(form.current?.isFieldsTouched(['list'], false)).toBeTruthy();
+ expect(form.current?.isFieldsTouched(['list'], true)).toBeTruthy();
});
});
@@ -733,7 +738,7 @@ describe('Form.List', () => {
fields => (
{fields.map(field => (
-
+
))}
@@ -743,7 +748,7 @@ describe('Form.List', () => {
{ initialValue: ['light', 'bamboo'] },
);
- expect(form.getFieldsValue()).toEqual({
+ expect(form.current?.getFieldsValue()).toEqual({
list: ['light', 'bamboo'],
});
});
@@ -765,7 +770,7 @@ describe('Form.List', () => {
);
};
- const [wrapper] = generateForm(
+ const [container] = generateForm(
fields => (
{fields.map(field => {
@@ -780,8 +785,64 @@ describe('Form.List', () => {
},
);
- expect(wrapper.find('.internal-key').text()).toEqual('0');
- expect(wrapper.find('.internal-rest').text()).toEqual('user');
- expect(wrapper.find('input').prop('value')).toEqual('bamboo');
+ expect(container.querySelector('.internal-key')!.textContent).toEqual('0');
+ expect(container.querySelector('.internal-rest')!.textContent).toEqual('user');
+ expect(getInput(container).value).toEqual('bamboo');
+ });
+
+ it('list should not pass context', async () => {
+ const onValuesChange = jest.fn();
+
+ const InnerForm = () => (
+
+ );
+
+ const { container } = render(
+
{() => }
+ ,
+ );
+
+ await changeValue(getInput(container, 0), 'little');
+
+ expect(onValuesChange).toHaveBeenCalledWith({ name: 'little' }, { name: 'little', age: 2 });
+ });
+
+ it('getFieldsValue with Strict mode', () => {
+ const formRef = React.createRef
();
+
+ const initialValues = { list: [{ bamboo: 1, light: 3 }], little: 9 };
+
+ render(
+
+
+ {fields =>
+ fields.map(field => (
+
+
+
+ ))
+ }
+
+
+ ,
+ );
+
+ // Strict only return field not list
+ expect(formRef.current.getFieldsValue({ strict: true })).toEqual({
+ list: [{ bamboo: 1 }],
+ little: 9,
+ });
});
});
diff --git a/tests/nameTypeCheck.test.tsx b/tests/nameTypeCheck.test.tsx
new file mode 100644
index 00000000..9179a9ac
--- /dev/null
+++ b/tests/nameTypeCheck.test.tsx
@@ -0,0 +1,107 @@
+/* eslint-disable @typescript-eslint/no-unused-vars */
+import React, { useMemo } from 'react';
+import { render } from '@testing-library/react';
+import Form, { Field, List } from '../src';
+import type { NamePath } from '../src/interface';
+
+describe('nameTypeCheck', () => {
+ it('typescript', () => {
+ type FieldType = {
+ a: string;
+ b?: string[];
+ c?: { c1?: string; c2?: string[]; c3?: boolean[] }[];
+ d?: { d1?: string[]; d2?: string };
+ e?: { e1?: { e2?: string; e3?: string[]; e4: { e5: { e6: string } } } };
+ list?: { age?: string }[];
+ };
+
+ type fieldType = NamePath;
+
+ const Demo: React.FC = () => {
+ return (
+
+ );
+ };
+ render();
+ });
+ it('type inference', () => {
+ interface Props {
+ data?: T[];
+ list?: { name?: NamePath }[];
+ }
+ function func(props: Props) {
+ return props;
+ }
+ func({ data: [{ a: { b: 'c' } }], list: [{ name: ['a', 'b'] }] });
+ });
+ it('more type', () => {
+ // Moment
+ type t1 = NamePath<{ a: { b: string; func: Moment } }>;
+ // Function
+ type t2 = NamePath<{ a: { b: string; func: () => { c: string } } }>;
+ // known
+ const t3: NamePath = 'a';
+
+ interface Moment {
+ func2: Function;
+ format: (format?: string) => string;
+ }
+ });
+ it('tree', () => {
+ type t1 = NamePath<{ a: TreeNode }>;
+
+ interface TreeNode {
+ child: TreeNode[];
+ }
+ });
+});
diff --git a/tests/preserve.test.tsx b/tests/preserve.test.tsx
index 042c14dc..e4951f2d 100644
--- a/tests/preserve.test.tsx
+++ b/tests/preserve.test.tsx
@@ -1,23 +1,12 @@
-/* eslint-disable no-template-curly-in-string, arrow-body-style */
-import { mount } from 'enzyme';
import React from 'react';
+import { render, fireEvent } from '@testing-library/react';
import type { FormInstance } from '../src';
import Form from '../src';
import InfoField, { Input } from './common/InfoField';
import timeout from './common/timeout';
describe('Form.Preserve', () => {
- const Demo = ({
- removeField,
- formPreserve,
- fieldPreserve,
- onFinish,
- }: {
- removeField: boolean;
- formPreserve?: boolean;
- fieldPreserve?: boolean;
- onFinish: (values: object) => void;
- }) => (
+ const Demo: React.FC = ({ removeField, formPreserve, fieldPreserve, onFinish }) => (
- );
- };
+ const KeepDemo: React.FC = ({ onFinish, keep }) => (
+
+
+ {() => (
+ <>
+ {keep && }
+
+ >
+ )}
+
+
+ );
const onFinish = jest.fn();
- const wrapper = mount();
+ const { container, rerender } = render();
// Change value
- wrapper
- .find('input')
- .first()
- .simulate('change', { target: { value: 'light' } });
+ fireEvent.change(container.querySelector('input'), {
+ target: { value: 'light' },
+ });
- formRef.current.submit();
+ formRef.current?.submit();
await timeout();
expect(onFinish).toHaveBeenCalledWith({ test: 'light' });
onFinish.mockReset();
// Remove preserve should not change the value
- wrapper.setProps({ keep: false });
+ rerender();
await timeout();
- formRef.current.submit();
+ formRef.current?.submit();
await timeout();
expect(onFinish).toHaveBeenCalledWith({ test: 'light' });
});
it('form preserve but field !preserve', async () => {
const onFinish = jest.fn();
- const wrapper = mount(
+ const { container, rerender } = render(
,
);
-
- async function matchTest(removeField: boolean, match: object) {
+ const matchTest = async (removeField: boolean, match: object) => {
onFinish.mockReset();
- wrapper.setProps({ removeField });
- wrapper.find('form').simulate('submit');
+ rerender(
+ ,
+ );
+ fireEvent.submit(container.querySelector('form'));
await timeout();
expect(onFinish).toHaveBeenCalledWith(match);
- }
-
+ };
await matchTest(true, { keep: 233 });
await matchTest(false, { keep: 233, remove: 666 });
});
describe('Form.List', () => {
it('form preserve should not crash', async () => {
- let form: FormInstance;
-
- const wrapper = mount(
- {
- form = instance;
- }}
- >
+ const form = React.createRef();
+
+ const { container } = render(
+
{(fields, { remove }) => {
return (
{fields.map(field => (
-
+
))}
-
);
}}
,
);
-
- wrapper.find('button').simulate('click');
- wrapper.update();
-
- expect(form.getFieldsValue()).toEqual({ list: ['bamboo', 'little'] });
+ fireEvent.click(container.querySelector('button'));
+ expect(form.current?.getFieldsValue()).toEqual({ list: ['bamboo', 'little'] });
});
it('warning when Form.List use preserve', () => {
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
- let form: FormInstance;
-
- const wrapper = mount(
- {
- form = instance;
- }}
- initialValues={{ list: ['bamboo'] }}
- >
+ const form = React.createRef();
+ const { container } = render(
+
{(fields, { remove }) => (
<>
{fields.map(field => (
-
+
))}
@@ -197,106 +161,84 @@ describe('Form.Preserve', () => {
errorSpy.mockRestore();
// Remove should not work
- wrapper.find('button').simulate('click');
- expect(form.getFieldsValue()).toEqual({ list: [] });
+ fireEvent.click(container.querySelector('button'));
+ expect(form.current?.getFieldsValue()).toEqual({ list: [] });
});
it('multiple level field can use preserve', async () => {
- let form: FormInstance;
-
- const wrapper = mount(
- {
- form = instance;
- }}
- >
+ const form = React.createRef();
+
+ const { container } = render(
+
- {(fields, { remove }) => {
- return (
- <>
- {fields.map(field => (
-
-
-
-
-
- {(_, __, { getFieldValue }) =>
- getFieldValue(['list', field.name, 'type']) === 'light' ? (
-
-
-
- ) : (
-
-
-
- )
- }
-
-
- ))}
- {
- remove(0);
- }}
- >
- Remove
-
- >
- );
- }}
+ {(fields, { remove }) => (
+ <>
+ {fields.map(field => (
+
+
+
+
+
+ {(_, __, { getFieldValue }) =>
+ getFieldValue(['list', field.name, 'type']) === 'light' ? (
+
+
+
+ ) : (
+
+
+
+ )
+ }
+
+
+ ))}
+ remove(0)}>Remove
+ >
+ )}
,
);
// Change light value
- wrapper
- .find('input')
- .last()
- .simulate('change', { target: { value: '1128' } });
+ fireEvent.change(container.querySelectorAll('input')[1], {
+ target: { value: '1128' },
+ });
// Change type
- wrapper
- .find('input')
- .first()
- .simulate('change', { target: { value: 'bamboo' } });
+ fireEvent.change(container.querySelectorAll('input')[0], {
+ target: { value: 'bamboo' },
+ });
- // Change bamboo value
- wrapper
- .find('input')
- .last()
- .simulate('change', { target: { value: '903' } });
+ // Change type
+ fireEvent.change(container.querySelectorAll('input')[1], {
+ target: { value: '903' },
+ });
- expect(form.getFieldsValue()).toEqual({ list: [{ type: 'bamboo', bamboo: '903' }] });
+ expect(form.current?.getFieldsValue()).toEqual({ list: [{ type: 'bamboo', bamboo: '903' }] });
// ============== Remove Test ==============
// Remove field
- wrapper.find('button').simulate('click');
- expect(form.getFieldsValue()).toEqual({ list: [] });
+ fireEvent.click(container.querySelector('button'));
+ expect(form.current?.getFieldsValue()).toEqual({ list: [] });
});
});
it('nest render props should not clean full store', () => {
- let form: FormInstance;
+ const form = React.createRef();
- const wrapper = mount(
- {
- form = instance;
- }}
- >
+ const { container, unmount } = render(
+
@@ -308,79 +250,76 @@ describe('Form.Preserve', () => {
,
);
- wrapper.find('input').simulate('change', { target: { value: 'bamboo' } });
- expect(form.getFieldsValue()).toEqual({ light: 'bamboo' });
+ fireEvent.change(container.querySelector('input'), {
+ target: { value: 'bamboo' },
+ });
+ expect(form.current?.getFieldsValue()).toEqual({ light: 'bamboo' });
- wrapper.find('input').simulate('change', { target: { value: 'little' } });
- expect(form.getFieldsValue()).toEqual({ light: 'little' });
+ fireEvent.change(container.querySelector('input'), {
+ target: { value: 'little' },
+ });
+ expect(form.current?.getFieldsValue()).toEqual({ light: 'little' });
- wrapper.unmount();
+ unmount();
});
// https://github.com/ant-design/ant-design/issues/31297
describe('A -> B -> C should keep trigger refresh', () => {
it('shouldUpdate', () => {
- const DepDemo = () => {
+ const DepDemo: React.FC = () => {
const [form] = Form.useForm();
-
return (
-
- {() => {
- return form.getFieldValue('name') === '1' ? (
+ {() =>
+ form.getFieldValue('name') === '1' ? (
- ) : null;
- }}
+ ) : null
+ }
-
- {() => {
- const password = form.getFieldValue('password');
- return password ? (
+ {() =>
+ form.getFieldValue('password') ? (
- ) : null;
- }}
+ ) : null
+ }
);
};
- const wrapper = mount();
+ const { container } = render();
// Input name to show password
- wrapper
- .find('#name')
- .last()
- .simulate('change', { target: { value: '1' } });
- expect(wrapper.exists('#password')).toBeTruthy();
- expect(wrapper.exists('#password2')).toBeFalsy();
+ fireEvent.change(container.querySelector('#name'), {
+ target: { value: '1' },
+ });
+ expect(container.querySelector('#password')).toBeTruthy();
+ expect(container.querySelector('#password2')).toBeFalsy();
// Input password to show password2
- wrapper
- .find('#password')
- .last()
- .simulate('change', { target: { value: '1' } });
- expect(wrapper.exists('#password2')).toBeTruthy();
+ fireEvent.change(container.querySelector('#password'), {
+ target: { value: '1' },
+ });
+ expect(container.querySelector('#password2')).toBeTruthy();
// Change name to hide password
- wrapper
- .find('#name')
- .last()
- .simulate('change', { target: { value: '2' } });
- expect(wrapper.exists('#password')).toBeFalsy();
- expect(wrapper.exists('#password2')).toBeFalsy();
+ fireEvent.change(container.querySelector('#name'), {
+ target: { value: '2' },
+ });
+ expect(container.querySelector('#password')).toBeFalsy();
+ expect(container.querySelector('#password2')).toBeFalsy();
});
it('dependencies', () => {
- const DepDemo = () => {
+ const DepDemo: React.FC = () => {
const [form] = Form.useForm();
return (
@@ -413,37 +352,34 @@ describe('Form.Preserve', () => {
);
};
- const wrapper = mount();
+ const { container } = render();
// Input name to show password
- wrapper
- .find('#name')
- .last()
- .simulate('change', { target: { value: '1' } });
- expect(wrapper.exists('#password')).toBeTruthy();
- expect(wrapper.exists('#password2')).toBeFalsy();
+ fireEvent.change(container.querySelector('#name'), {
+ target: { value: '1' },
+ });
+ expect(container.querySelector('#password')).toBeTruthy();
+ expect(container.querySelector('#password2')).toBeFalsy();
// Input password to show password2
- wrapper
- .find('#password')
- .last()
- .simulate('change', { target: { value: '1' } });
- expect(wrapper.exists('#password2')).toBeTruthy();
+ fireEvent.change(container.querySelector('#password'), {
+ target: { value: '1' },
+ });
+ expect(container.querySelector('#password2')).toBeTruthy();
// Change name to hide password
- wrapper
- .find('#name')
- .last()
- .simulate('change', { target: { value: '2' } });
- expect(wrapper.exists('#password')).toBeFalsy();
- expect(wrapper.exists('#password2')).toBeFalsy();
+ fireEvent.change(container.querySelector('#name'), {
+ target: { value: '2' },
+ });
+ expect(container.querySelector('#password')).toBeFalsy();
+ expect(container.querySelector('#password2')).toBeFalsy();
});
});
it('should correct calculate preserve state', () => {
let instance: FormInstance;
- const VisibleDemo = ({ visible = true }: { visible?: boolean }) => {
+ const VisibleDemo: React.FC<{ visible?: boolean }> = ({ visible = true }) => {
const [form] = Form.useForm();
instance = form;
@@ -458,18 +394,55 @@ describe('Form.Preserve', () => {
);
};
- const wrapper = mount();
+ const { container, rerender } = render();
- wrapper.setProps({
- visible: false,
- });
+ rerender();
instance.setFieldsValue({ name: 'bamboo' });
- wrapper.setProps({
- visible: true,
- });
+ rerender();
+
+ expect(container.querySelector('input')?.value).toEqual('bamboo');
+ });
+
+ it('nest Form.List should clear correctly', async () => {
+ const { container } = render(
+
+
+ {(fields, { remove }) => {
+ return fields.map(field => (
+