Skip to content

Commit

Permalink
[@mantine/form] Add first part of uncontrolled form tests
Browse files Browse the repository at this point in the history
  • Loading branch information
rtivital committed Apr 6, 2024
1 parent 3c55e3e commit db06a89
Show file tree
Hide file tree
Showing 15 changed files with 388 additions and 193 deletions.
67 changes: 67 additions & 0 deletions packages/@mantine/form/src/stories/Form.lists.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,70 @@ export function Lists() {
</FormBase>
);
}

export function ListsUncontrolled() {
const form = useForm({
mode: 'uncontrolled',
initialValues: {
employees: [
{ name: '', active: false, key: randomId() },
{ name: '', active: false, key: randomId() },
{ name: '', active: false, key: randomId() },
],
},

validate: {
employees: {
name: (value) => (value.length < 2 ? 'Too short' : null),
},
},
});

const fields = form.values.employees.map((item, index) => (
<Group key={item.key} mt="xs">
<TextInput
placeholder="John Doe"
style={{ flex: 1 }}
{...form.getInputProps(`employees.${index}.name`)}
/>
<Switch
label="Active"
{...form.getInputProps(`employees.${index}.active`, { type: 'checkbox' })}
/>
<ActionIcon color="red" onClick={() => form.removeListItem('employees', index)}>
$
</ActionIcon>
</Group>
));

return (
<FormBase form={form}>
{fields.length > 0 ? (
<Group mb="xs">
<Text fw={500} size="sm" style={{ flex: 1 }}>
Name
</Text>
<Text fw={500} size="sm" pr={90}>
Status
</Text>
</Group>
) : (
<Text c="dimmed" ta="center">
No one here...
</Text>
)}

{fields}

<Group justify="center" mt="md">
<Button
onClick={() =>
form.insertListItem('employees', { name: '', active: false, key: randomId() })
}
>
Add employee
</Button>
</Group>
</FormBase>
);
}
13 changes: 11 additions & 2 deletions packages/@mantine/form/src/tests/clearErrors.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import { act, renderHook } from '@testing-library/react';
import { FormMode } from '../types';
import { useForm } from '../use-form';

describe('@mantine/form/clearErrors', () => {
function tests(mode: FormMode) {
it('clears errors when clearErrors handler is called', () => {
const hook = renderHook(() => useForm({ initialErrors: { a: 1, b: 2 } }));
const hook = renderHook(() => useForm({ mode, initialErrors: { a: 1, b: 2 } }));
expect(hook.result.current.errors).toStrictEqual({ a: 1, b: 2 });
act(() => hook.result.current.clearErrors());
expect(hook.result.current.errors).toStrictEqual({});
});
}

describe('@mantine/form/clearErrors-controlled', () => {
tests('controlled');
});

describe('@mantine/form/clearErrors-uncontrolled', () => {
tests('uncontrolled');
});
13 changes: 11 additions & 2 deletions packages/@mantine/form/src/tests/clearFieldError.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { act, renderHook } from '@testing-library/react';
import { FormMode } from '../types';
import { useForm } from '../use-form';

describe('@mantine/form/clearFieldError', () => {
function tests(mode: FormMode) {
it('clears error of given field with clearFieldError handler', () => {
const hook = renderHook(() => useForm({ initialErrors: { a: 1, b: 2 } }));
const hook = renderHook(() => useForm({ mode, initialErrors: { a: 1, b: 2 } }));
expect(hook.result.current.errors).toStrictEqual({ a: 1, b: 2 });

act(() => hook.result.current.clearFieldError('a'));
Expand All @@ -12,4 +13,12 @@ describe('@mantine/form/clearFieldError', () => {
act(() => hook.result.current.clearFieldError('b'));
expect(hook.result.current.errors).toStrictEqual({});
});
}

describe('@mantine/form/clearFieldError-controlled', () => {
tests('controlled');
});

describe('@mantine/form/clearFieldError-uncontrolled', () => {
tests('uncontrolled');
});
19 changes: 14 additions & 5 deletions packages/@mantine/form/src/tests/dirty.test.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { act, renderHook } from '@testing-library/react';
import { FormMode } from '../types';
import { useForm } from '../use-form';

describe('@mantine/form/dirty', () => {
function tests(mode: FormMode) {
it('accepts initial dirty state', () => {
const hook = renderHook(() => useForm({ initialDirty: { a: true, b: false } }));
const hook = renderHook(() => useForm({ mode, initialDirty: { a: true, b: false } }));
expect(hook.result.current.isDirty('a')).toBe(true);
expect(hook.result.current.isDirty('b')).toBe(false);
expect(hook.result.current.isDirty()).toBe(true);
});

it('sets field as dirty if value changes', () => {
const hook = renderHook(() => useForm({ initialValues: { a: 1 } }));
const hook = renderHook(() => useForm({ mode, initialValues: { a: 1 } }));
expect(hook.result.current.isDirty('a')).toBe(false);
expect(hook.result.current.isDirty()).toBe(false);

Expand All @@ -34,15 +35,15 @@ describe('@mantine/form/dirty', () => {
});

it('resets status with resetDirty handler', () => {
const hook = renderHook(() => useForm({ initialDirty: { a: true } }));
const hook = renderHook(() => useForm({ mode, initialDirty: { a: true } }));
expect(hook.result.current.isDirty()).toBe(true);

act(() => hook.result.current.resetDirty());
expect(hook.result.current.isDirty()).toBe(false);
});

it('sets list field as dirty if list item changes', () => {
const hook = renderHook(() => useForm({ initialValues: { a: [{ b: 1 }, { b: 2 }] } }));
const hook = renderHook(() => useForm({ mode, initialValues: { a: [{ b: 1 }, { b: 2 }] } }));
act(() => hook.result.current.setFieldValue('a.0', 3));
expect(hook.result.current.isDirty('a.0')).toBe(true);
expect(hook.result.current.isDirty('a')).toBe(true);
Expand All @@ -59,4 +60,12 @@ describe('@mantine/form/dirty', () => {
expect(hook.result.current.isDirty('a.2')).toBe(false);
expect(hook.result.current.isDirty('a')).toBe(false);
});
}

describe('@mantine/form/dirty-controlled', () => {
tests('controlled');
});

describe('@mantine/form/dirty-uncontrolled', () => {
tests('uncontrolled');
});

0 comments on commit db06a89

Please sign in to comment.