diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index fe84dfe90..191a56dc9 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1 +1 @@
-* @radekmie @wadamek65
+* @wadamek65 @kestarumper
diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml
index 23d5cfac2..d5ea7fe2f 100644
--- a/.github/workflows/CI.yml
+++ b/.github/workflows/CI.yml
@@ -1,5 +1,6 @@
name: CI
on:
+ workflow_dispatch:
pull_request:
push:
branches:
diff --git a/docs/uth-autofield-algorithm.md b/docs/uth-autofield-algorithm.md
index 158bea9d0..8e14e70a0 100644
--- a/docs/uth-autofield-algorithm.md
+++ b/docs/uth-autofield-algorithm.md
@@ -46,7 +46,7 @@ const AutoField = createAutoField(props => {
## Overriding `AutoField`
-To make it possible, all `AutoFields` created with the `createAutoField` are configurable. To adjust the components, use the React context available in `AutoField.componentDetectorContext`. You can use it as often as needed - in most apps once will be enough. Example:
+If you want to alter the default behavior of `AutoField` and render a different component based on the props, you can do it using the React context available in `AutoField.componentDetectorContext`. You can use it as often as needed - once will be enough in most apps. Example:
```tsx
/* ... */}>
@@ -54,7 +54,7 @@ To make it possible, all `AutoFields` created with the `createAutoField` are con
```
-If you want to add an exception and then fallback to the existing algorithm, use `AutoField.defaultComponentDetector`. Example:
+If you want to change the detector only partially, i.e., to render one additional field, and in other cases, use the default algorithm as a fallback, return `AutoField.defaultComponentDetector`. Example:
```tsx
- renders ListAddField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListAddField)).toHaveLength(1);
- expect(wrapper.find(ListAddField).prop('name')).toBe('$');
-});
-
-test(' - renders correct label and info (specified)', () => {
- const element = (
-
- );
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(Tooltip)).toHaveLength(1);
- expect(wrapper.find(Tooltip).prop('title')).toBe('ListFieldInfo');
-});
-
-test(' - renders correct label (specified)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find('div > div').at(0).text()).toEqual(
- expect.stringContaining('ListFieldLabel'),
- );
-});
-
-test(' - renders correct numer of items with model (specified)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined, undefined],
- }),
- );
-
- expect(wrapper.find('input')).toHaveLength(3);
-});
-
-test(' - passes itemProps to its children', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined],
- }),
- );
-
- expect(wrapper.find(ListItemField).first().prop('data-xyz')).toBe(1);
-});
-
-test(' - renders children (specified)', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
- PlainText
-
- );
- mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(Child).toHaveBeenCalledTimes(2);
-});
-
-test(' - renders children with correct name (children)', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
-
- );
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(wrapper.find(Child).at(0).prop('name')).toBe('0');
- expect(wrapper.find(Child).at(1).prop('name')).toBe('1');
-});
-
-test(' - renders children with correct name (value)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(wrapper.find(ListItemField).at(0).prop('name')).toBe('0');
- expect(wrapper.find(ListItemField).at(1).prop('name')).toBe('1');
-});
-
-test(' - renders correct error text (specified)', () => {
- const error = new Error();
- const element = (
-
- );
- const wrapper = mount(
- element,
- createContext({ x: { type: Array, label: '' }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find('div > div').at(0).text()).toBe('Error');
-});
-
-test(' - renders correct error style', () => {
- const error = new Error();
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find('div').at(0).prop('style')).toHaveProperty(
- 'borderColor',
- 'rgb(255, 85, 0)',
- );
-});
-
-test(' - renders correct error style (with specified style prop)', () => {
- const error = new Error();
- const element = (
-
- );
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find('div').at(0).prop('style')).toHaveProperty(
- 'marginLeft',
- '8px',
- );
-});
-
-test(' - renders proper number of optional values after add new value', () => {
- const element = ;
- const onChange = jest.fn();
- const wrapper = mount(
- element,
- createContext(
- { x: { type: Array, optional: true }, 'x.$': { type: String } },
- { onChange },
- {
- x: [undefined, undefined, undefined],
- },
- ),
- );
-
- expect(wrapper.find(ListAddField).simulate('click')).toBeTruthy();
- expect(onChange).toHaveBeenNthCalledWith(1, 'x', [
- undefined,
- undefined,
- undefined,
- undefined,
- ]);
-});
diff --git a/packages/uniforms-antd/__tests__/ListItemField.tsx b/packages/uniforms-antd/__tests__/ListItemField.tsx
deleted file mode 100644
index 1a68cea18..000000000
--- a/packages/uniforms-antd/__tests__/ListItemField.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import React from 'react';
-import { AutoField, ListDelField, ListItemField } from 'uniforms-antd';
-
-import createContext from './_createContext';
-import mount from './_mount';
-
-test(' - works', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListItemField)).toHaveLength(1);
-});
-
-test(' - renders ListDelField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListDelField)).toHaveLength(1);
- expect(wrapper.find(ListDelField).childAt(0).prop('name')).toBe('x.1');
-});
-
-test(' - renders AutoField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(AutoField)).toHaveLength(1);
-});
-
-test(' - renders children if specified', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
-
- );
- mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(Child).toHaveBeenCalledTimes(1);
-});
diff --git a/packages/uniforms-antd/__tests__/index.ts b/packages/uniforms-antd/__tests__/index.ts
index 8f0fbdb8b..0d5c364bc 100644
--- a/packages/uniforms-antd/__tests__/index.ts
+++ b/packages/uniforms-antd/__tests__/index.ts
@@ -47,7 +47,10 @@ describe('@RTL', () => {
suites.testListDelField(theme.ListDelField);
suites.testListField(theme.ListField, {
getListAddField: screen => screen.getByRole('img', { name: 'plus-square' }),
+ testTooltip: true,
+ testStyle: true,
});
+ suites.testListItemField(theme.ListItemField);
suites.testLongTextField(theme.LongTextField);
// FIXME: AntD number input doesn't work with new RTL test implementation
// suites.testNumField(antd.NumField);
diff --git a/packages/uniforms-bootstrap3/__tests__/ListField.tsx b/packages/uniforms-bootstrap3/__tests__/ListField.tsx
deleted file mode 100644
index 81e67ced7..000000000
--- a/packages/uniforms-bootstrap3/__tests__/ListField.tsx
+++ /dev/null
@@ -1,175 +0,0 @@
-import React from 'react';
-import { ListAddField, ListField, ListItemField } from 'uniforms-bootstrap3';
-
-import createContext from './_createContext';
-import mount from './_mount';
-
-test(' - works', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListField)).toHaveLength(1);
-});
-
-test(' - renders ListAddField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListAddField)).toHaveLength(1);
- expect(wrapper.find(ListAddField).prop('name')).toBe('$');
-});
-
-test(' - renders correct label (specified)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find('label')).toHaveLength(1);
- expect(wrapper.find('label').text()).toEqual(
- expect.stringContaining('ListFieldLabel'),
- );
-});
-
-test(' - renders correct numer of items with model (specified)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined, undefined],
- }),
- );
-
- expect(wrapper.find('input')).toHaveLength(3);
-});
-
-test(' - passes itemProps to its children', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined],
- }),
- );
-
- expect(wrapper.find(ListItemField).first().prop('data-xyz')).toBe(1);
-});
-
-test(' - renders children (specified)', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
- PlainText
-
- );
- mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(Child).toHaveBeenCalledTimes(2);
-});
-
-test(' - renders children with correct name (children)', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
-
- );
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(wrapper.find(Child).at(0).prop('name')).toBe('0');
- expect(wrapper.find(Child).at(1).prop('name')).toBe('1');
-});
-
-test(' - renders children with correct name (value)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(wrapper.find(ListItemField).at(0).prop('name')).toBe('0');
- expect(wrapper.find(ListItemField).at(1).prop('name')).toBe('1');
-});
-
-test(' - renders correct error text (specified)', () => {
- const error = new Error();
- const element = (
-
- );
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find('.help-block').text()).toBe('Error');
-});
-
-test(' - renders correct error text (showInlineError=false)', () => {
- const error = new Error();
- const element = (
-
- );
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find('.help-block')).toHaveLength(0);
-});
-
-test(' - renders proper number of optional values after add new value', () => {
- const element = ;
- const onChange = jest.fn();
- const wrapper = mount(
- element,
- createContext(
- { x: { type: Array, optional: true }, 'x.$': { type: String } },
- { onChange },
- {
- x: [undefined, undefined, undefined],
- },
- ),
- );
-
- expect(wrapper.find(ListAddField).simulate('click')).toBeTruthy();
- expect(onChange).toHaveBeenNthCalledWith(1, 'x', [
- undefined,
- undefined,
- undefined,
- undefined,
- ]);
-});
diff --git a/packages/uniforms-bootstrap3/__tests__/ListItemField.tsx b/packages/uniforms-bootstrap3/__tests__/ListItemField.tsx
deleted file mode 100644
index b8f55cafb..000000000
--- a/packages/uniforms-bootstrap3/__tests__/ListItemField.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import React from 'react';
-import { AutoField, ListDelField, ListItemField } from 'uniforms-bootstrap3';
-
-import createContext from './_createContext';
-import mount from './_mount';
-
-test(' - works', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListItemField)).toHaveLength(1);
-});
-
-test(' - renders ListDelField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListDelField)).toHaveLength(1);
- expect(wrapper.find(ListDelField).childAt(0).prop('name')).toBe('x.1');
-});
-
-test(' - renders AutoField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(AutoField)).toHaveLength(1);
-});
-
-test(' - renders children if specified', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
-
- );
- mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(Child).toHaveBeenCalledTimes(1);
-});
diff --git a/packages/uniforms-bootstrap3/__tests__/index.ts b/packages/uniforms-bootstrap3/__tests__/index.ts
index 83ab14a6d..fb7d76594 100644
--- a/packages/uniforms-bootstrap3/__tests__/index.ts
+++ b/packages/uniforms-bootstrap3/__tests__/index.ts
@@ -47,7 +47,9 @@ describe('@RTL', () => {
suites.testListDelField(theme.ListDelField);
suites.testListField(theme.ListField, {
getListAddField: screen => screen.getByRole('button'),
+ disableInlineError: true,
});
+ suites.testListItemField(theme.ListItemField);
suites.testLongTextField(theme.LongTextField);
suites.testNestField(theme.NestField);
suites.testNumField(theme.NumField);
diff --git a/packages/uniforms-bootstrap4/__tests__/ListField.tsx b/packages/uniforms-bootstrap4/__tests__/ListField.tsx
deleted file mode 100644
index 4f6215222..000000000
--- a/packages/uniforms-bootstrap4/__tests__/ListField.tsx
+++ /dev/null
@@ -1,175 +0,0 @@
-import React from 'react';
-import { ListAddField, ListField, ListItemField } from 'uniforms-bootstrap4';
-
-import createContext from './_createContext';
-import mount from './_mount';
-
-test(' - works', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListField)).toHaveLength(1);
-});
-
-test(' - renders ListAddField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListAddField)).toHaveLength(1);
- expect(wrapper.find(ListAddField).prop('name')).toBe('$');
-});
-
-test(' - renders correct label (specified)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find('label')).toHaveLength(1);
- expect(wrapper.find('label').text()).toEqual(
- expect.stringContaining('ListFieldLabel'),
- );
-});
-
-test(' - renders correct numer of items with model (specified)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined, undefined],
- }),
- );
-
- expect(wrapper.find('input')).toHaveLength(3);
-});
-
-test(' - passes itemProps to its children', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined],
- }),
- );
-
- expect(wrapper.find(ListItemField).first().prop('data-xyz')).toBe(1);
-});
-
-test(' - renders children (specified)', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
- PlainText
-
- );
- mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(Child).toHaveBeenCalledTimes(2);
-});
-
-test(' - renders children with correct name (children)', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
-
- );
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(wrapper.find(Child).at(0).prop('name')).toBe('0');
- expect(wrapper.find(Child).at(1).prop('name')).toBe('1');
-});
-
-test(' - renders children with correct name (value)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(wrapper.find(ListItemField).at(0).prop('name')).toBe('0');
- expect(wrapper.find(ListItemField).at(1).prop('name')).toBe('1');
-});
-
-test(' - renders correct error text (specified)', () => {
- const error = new Error();
- const element = (
-
- );
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find('.text-danger').text()).toBe('Error');
-});
-
-test(' - renders correct error text (showInlineError=false)', () => {
- const error = new Error();
- const element = (
-
- );
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find('.text-danger')).toHaveLength(0);
-});
-
-test(' - renders proper number of optional values after add new value', () => {
- const element = ;
- const onChange = jest.fn();
- const wrapper = mount(
- element,
- createContext(
- { x: { type: Array, optional: true }, 'x.$': { type: String } },
- { onChange },
- {
- x: [undefined, undefined, undefined],
- },
- ),
- );
-
- expect(wrapper.find(ListAddField).simulate('click')).toBeTruthy();
- expect(onChange).toHaveBeenNthCalledWith(1, 'x', [
- undefined,
- undefined,
- undefined,
- undefined,
- ]);
-});
diff --git a/packages/uniforms-bootstrap4/__tests__/ListItemField.tsx b/packages/uniforms-bootstrap4/__tests__/ListItemField.tsx
deleted file mode 100644
index 3bc76866e..000000000
--- a/packages/uniforms-bootstrap4/__tests__/ListItemField.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import React from 'react';
-import { AutoField, ListDelField, ListItemField } from 'uniforms-bootstrap4';
-
-import createContext from './_createContext';
-import mount from './_mount';
-
-test(' - works', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListItemField)).toHaveLength(1);
-});
-
-test(' - renders ListDelField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListDelField)).toHaveLength(1);
- expect(wrapper.find(ListDelField).childAt(0).prop('name')).toBe('x.1');
-});
-
-test(' - renders AutoField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(AutoField)).toHaveLength(1);
-});
-
-test(' - renders children if specified', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
-
- );
- mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(Child).toHaveBeenCalledTimes(1);
-});
diff --git a/packages/uniforms-bootstrap4/__tests__/index.ts b/packages/uniforms-bootstrap4/__tests__/index.ts
index 0d7ded864..31e0a2b56 100644
--- a/packages/uniforms-bootstrap4/__tests__/index.ts
+++ b/packages/uniforms-bootstrap4/__tests__/index.ts
@@ -47,7 +47,9 @@ describe('@RTL', () => {
suites.testListDelField(theme.ListDelField);
suites.testListField(theme.ListField, {
getListAddField: screen => screen.getByRole('button'),
+ disableInlineError: true,
});
+ suites.testListItemField(theme.ListItemField);
suites.testLongTextField(theme.LongTextField);
suites.testNestField(theme.NestField);
suites.testNumField(theme.NumField);
diff --git a/packages/uniforms-bootstrap5/__tests__/ListField.tsx b/packages/uniforms-bootstrap5/__tests__/ListField.tsx
deleted file mode 100644
index 72efa14fc..000000000
--- a/packages/uniforms-bootstrap5/__tests__/ListField.tsx
+++ /dev/null
@@ -1,175 +0,0 @@
-import React from 'react';
-import { ListAddField, ListField, ListItemField } from 'uniforms-bootstrap5';
-
-import createContext from './_createContext';
-import mount from './_mount';
-
-test(' - works', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListField)).toHaveLength(1);
-});
-
-test(' - renders ListAddField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListAddField)).toHaveLength(1);
- expect(wrapper.find(ListAddField).prop('name')).toBe('$');
-});
-
-test(' - renders correct label (specified)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find('label')).toHaveLength(1);
- expect(wrapper.find('label').text()).toEqual(
- expect.stringContaining('ListFieldLabel'),
- );
-});
-
-test(' - renders correct numer of items with model (specified)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined, undefined],
- }),
- );
-
- expect(wrapper.find('input')).toHaveLength(3);
-});
-
-test(' - passes itemProps to its children', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined],
- }),
- );
-
- expect(wrapper.find(ListItemField).first().prop('data-xyz')).toBe(1);
-});
-
-test(' - renders children (specified)', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
- PlainText
-
- );
- mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(Child).toHaveBeenCalledTimes(2);
-});
-
-test(' - renders children with correct name (children)', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
-
- );
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(wrapper.find(Child).at(0).prop('name')).toBe('0');
- expect(wrapper.find(Child).at(1).prop('name')).toBe('1');
-});
-
-test(' - renders children with correct name (value)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(wrapper.find(ListItemField).at(0).prop('name')).toBe('0');
- expect(wrapper.find(ListItemField).at(1).prop('name')).toBe('1');
-});
-
-test(' - renders correct error text (specified)', () => {
- const error = new Error();
- const element = (
-
- );
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find('.text-danger').text()).toBe('Error');
-});
-
-test(' - renders correct error text (showInlineError=false)', () => {
- const error = new Error();
- const element = (
-
- );
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find('.text-danger')).toHaveLength(0);
-});
-
-test(' - renders proper number of optional values after add new value', () => {
- const element = ;
- const onChange = jest.fn();
- const wrapper = mount(
- element,
- createContext(
- { x: { type: Array, optional: true }, 'x.$': { type: String } },
- { onChange },
- {
- x: [undefined, undefined, undefined],
- },
- ),
- );
-
- expect(wrapper.find(ListAddField).simulate('click')).toBeTruthy();
- expect(onChange).toHaveBeenNthCalledWith(1, 'x', [
- undefined,
- undefined,
- undefined,
- undefined,
- ]);
-});
diff --git a/packages/uniforms-bootstrap5/__tests__/ListItemField.tsx b/packages/uniforms-bootstrap5/__tests__/ListItemField.tsx
deleted file mode 100644
index c105a0ba2..000000000
--- a/packages/uniforms-bootstrap5/__tests__/ListItemField.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import React from 'react';
-import { AutoField, ListDelField, ListItemField } from 'uniforms-bootstrap5';
-
-import createContext from './_createContext';
-import mount from './_mount';
-
-test(' - works', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListItemField)).toHaveLength(1);
-});
-
-test(' - renders ListDelField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListDelField)).toHaveLength(1);
- expect(wrapper.find(ListDelField).childAt(0).prop('name')).toBe('x.1');
-});
-
-test(' - renders AutoField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(AutoField)).toHaveLength(1);
-});
-
-test(' - renders children if specified', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
-
- );
- mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(Child).toHaveBeenCalledTimes(1);
-});
diff --git a/packages/uniforms-bootstrap5/__tests__/index.ts b/packages/uniforms-bootstrap5/__tests__/index.ts
index bd1096e57..6e036c834 100644
--- a/packages/uniforms-bootstrap5/__tests__/index.ts
+++ b/packages/uniforms-bootstrap5/__tests__/index.ts
@@ -47,7 +47,9 @@ describe('@RTL', () => {
suites.testListDelField(theme.ListDelField);
suites.testListField(theme.ListField, {
getListAddField: screen => screen.getByRole('button'),
+ disableInlineError: true,
});
+ suites.testListItemField(theme.ListItemField);
suites.testLongTextField(theme.LongTextField, {
testMinMaxLength: true,
});
diff --git a/packages/uniforms-material/__tests__/ListField.tsx b/packages/uniforms-material/__tests__/ListField.tsx
deleted file mode 100644
index 046235db6..000000000
--- a/packages/uniforms-material/__tests__/ListField.tsx
+++ /dev/null
@@ -1,138 +0,0 @@
-import IconButton from '@material-ui/core/IconButton';
-import ListSubheader from '@material-ui/core/ListSubheader';
-import React from 'react';
-import { ListAddField, ListField, ListItemField } from 'uniforms-material';
-
-import createContext from './_createContext';
-import mount from './_mount';
-
-test(' - works', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListField)).toHaveLength(1);
-});
-
-test(' - renders ListAddField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListAddField)).toHaveLength(1);
- expect(wrapper.find(ListAddField).prop('name')).toBe('$');
-});
-
-test(' - renders correct label (specified)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListSubheader)).toHaveLength(1);
- expect(wrapper.find(ListSubheader).text()).toBe('ListFieldLabel');
-});
-
-test(' - renders correct number of items with model', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined, undefined],
- }),
- );
-
- expect(wrapper.find(ListItemField)).toHaveLength(3);
-});
-
-test(' - passes itemProps to its children', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined],
- }),
- );
-
- expect(wrapper.find(ListItemField).first().prop('data-xyz')).toBe(1);
-});
-
-test(' - renders children (specified)', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
- PlainText
-
- );
- mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(Child).toHaveBeenCalledTimes(2);
-});
-
-test(' - renders children with correct name (children)', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
-
- );
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(wrapper.find(Child).at(0).prop('name')).toBe('0');
- expect(wrapper.find(Child).at(1).prop('name')).toBe('1');
-});
-
-test(' - renders children with correct name (value)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(wrapper.find(ListItemField).at(0).prop('name')).toBe('0');
- expect(wrapper.find(ListItemField).at(1).prop('name')).toBe('1');
-});
-
-test(' - renders proper number of optional values after add new value', () => {
- const element = ;
- const onChange = jest.fn();
- const wrapper = mount(
- element,
- createContext(
- { x: { type: Array, optional: true }, 'x.$': { type: String } },
- { onChange },
- {
- x: [undefined, undefined, undefined],
- },
- ),
- );
- expect(
- wrapper.find(ListAddField).find(IconButton).simulate('click'),
- ).toBeTruthy();
- expect(onChange).toHaveBeenNthCalledWith(1, 'x', [
- undefined,
- undefined,
- undefined,
- undefined,
- ]);
-});
diff --git a/packages/uniforms-material/__tests__/ListItemField.tsx b/packages/uniforms-material/__tests__/ListItemField.tsx
deleted file mode 100644
index 996d39dbb..000000000
--- a/packages/uniforms-material/__tests__/ListItemField.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import React from 'react';
-import { AutoField, ListDelField, ListItemField } from 'uniforms-material';
-
-import createContext from './_createContext';
-import mount from './_mount';
-
-test(' - works', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListItemField)).toHaveLength(1);
-});
-
-test(' - renders ListDelField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListDelField)).toHaveLength(1);
- expect(wrapper.find(ListDelField).childAt(0).prop('name')).toBe('x.1');
-});
-
-test(' - renders AutoField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(AutoField)).toHaveLength(1);
-});
-
-test(' - renders children if specified', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
-
- );
- mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(Child).toHaveBeenCalledTimes(1);
-});
diff --git a/packages/uniforms-material/__tests__/index.ts b/packages/uniforms-material/__tests__/index.ts
index 5d81b6d44..a74821372 100644
--- a/packages/uniforms-material/__tests__/index.ts
+++ b/packages/uniforms-material/__tests__/index.ts
@@ -49,7 +49,9 @@ describe('@RTL', () => {
suites.testListDelField(theme.ListDelField);
suites.testListField(theme.ListField, {
getListAddField: screen => screen.getByText(/\+/),
+ testError: false,
});
+ suites.testListItemField(theme.ListItemField);
suites.testLongTextField(theme.LongTextField);
suites.testNestField(theme.NestField, { skipInMuiTests: true });
suites.testNumField(theme.NumField);
diff --git a/packages/uniforms-mui/__tests__/ListField.tsx b/packages/uniforms-mui/__tests__/ListField.tsx
deleted file mode 100644
index 4c10074d0..000000000
--- a/packages/uniforms-mui/__tests__/ListField.tsx
+++ /dev/null
@@ -1,138 +0,0 @@
-import IconButton from '@mui/material/IconButton';
-import ListSubheader from '@mui/material/ListSubheader';
-import React from 'react';
-import { ListAddField, ListField, ListItemField } from 'uniforms-mui';
-
-import createContext from './_createContext';
-import mount from './_mount';
-
-test(' - works', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListField)).toHaveLength(1);
-});
-
-test(' - renders ListAddField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListAddField)).toHaveLength(1);
- expect(wrapper.find(ListAddField).prop('name')).toBe('$');
-});
-
-test(' - renders correct label (specified)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListSubheader)).toHaveLength(1);
- expect(wrapper.find(ListSubheader).text()).toBe('ListFieldLabel');
-});
-
-test(' - renders correct number of items with model (specified)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined, undefined],
- }),
- );
-
- expect(wrapper.find(ListItemField)).toHaveLength(3);
-});
-
-test(' - passes itemProps to its children', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined],
- }),
- );
-
- expect(wrapper.find(ListItemField).first().prop('data-xyz')).toBe(1);
-});
-
-test(' - renders children (specified)', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
- PlainText
-
- );
- mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(Child).toHaveBeenCalledTimes(2);
-});
-
-test(' - renders children with correct name (children)', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
-
- );
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(wrapper.find(Child).at(0).prop('name')).toBe('0');
- expect(wrapper.find(Child).at(1).prop('name')).toBe('1');
-});
-
-test(' - renders children with correct name (value)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(wrapper.find(ListItemField).at(0).prop('name')).toBe('0');
- expect(wrapper.find(ListItemField).at(1).prop('name')).toBe('1');
-});
-
-// Strange enzyme behavior
-// TypeError: Cannot read properties of null (reading '__reactFiber$my72orhzzz9')
-test.skip(' - renders proper number of optional values after add new value (with initialCount)', async () => {
- const element = ;
- const onChange = jest.fn();
- const wrapper = mount(
- element,
- createContext(
- { x: { type: Array, optional: true }, 'x.$': { type: String } },
- { onChange },
- ),
- );
-
- expect(
- wrapper.find(ListAddField).find(IconButton).simulate('click'),
- ).toBeTruthy();
- expect(onChange).toHaveBeenNthCalledWith(1, 'x', [
- undefined,
- undefined,
- undefined,
- undefined,
- ]);
-});
diff --git a/packages/uniforms-mui/__tests__/ListItemField.tsx b/packages/uniforms-mui/__tests__/ListItemField.tsx
deleted file mode 100644
index 25de0fd8e..000000000
--- a/packages/uniforms-mui/__tests__/ListItemField.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import React from 'react';
-import { AutoField, ListDelField, ListItemField } from 'uniforms-mui';
-
-import createContext from './_createContext';
-import mount from './_mount';
-
-test(' - works', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListItemField)).toHaveLength(1);
-});
-
-test(' - renders ListDelField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListDelField)).toHaveLength(1);
- expect(wrapper.find(ListDelField).childAt(0).prop('name')).toBe('x.1');
-});
-
-test(' - renders AutoField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(AutoField)).toHaveLength(1);
-});
-
-test(' - renders children if specified', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
-
- );
- mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(Child).toHaveBeenCalledTimes(1);
-});
diff --git a/packages/uniforms-mui/__tests__/index.ts b/packages/uniforms-mui/__tests__/index.ts
index bb7fdb5b8..db660ef77 100644
--- a/packages/uniforms-mui/__tests__/index.ts
+++ b/packages/uniforms-mui/__tests__/index.ts
@@ -46,7 +46,9 @@ describe('@RTL', () => {
suites.testListDelField(theme.ListDelField);
suites.testListField(theme.ListField, {
getListAddField: screen => screen.getByText(/\+/),
+ testError: false,
});
+ suites.testListItemField(theme.ListItemField);
suites.testLongTextField(theme.LongTextField);
suites.testNestField(theme.NestField, { skipInMuiTests: true });
suites.testNumField(theme.NumField);
diff --git a/packages/uniforms-semantic/__tests__/ListField.tsx b/packages/uniforms-semantic/__tests__/ListField.tsx
deleted file mode 100644
index 2efb22d0f..000000000
--- a/packages/uniforms-semantic/__tests__/ListField.tsx
+++ /dev/null
@@ -1,167 +0,0 @@
-import React from 'react';
-import { ListAddField, ListField, ListItemField } from 'uniforms-semantic';
-
-import createContext from './_createContext';
-import mount from './_mount';
-
-test(' - works', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListField)).toHaveLength(1);
-});
-
-test(' - renders ListAddField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListAddField)).toHaveLength(1);
- expect(wrapper.find(ListAddField).prop('name')).toBe('$');
-});
-
-test(' - renders correct label (specified)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find('label')).toHaveLength(1);
- expect(wrapper.find('label').text()).toEqual(
- expect.stringContaining('ListFieldLabel'),
- );
-});
-
-test(' - renders correct number of items with model (specified)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined, undefined],
- }),
- );
-
- expect(wrapper.find('input')).toHaveLength(3);
-});
-
-test(' - passes itemProps to its children', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined],
- }),
- );
-
- expect(wrapper.find(ListItemField).first().prop('data-xyz')).toBe(1);
-});
-
-test(' - renders children (specified)', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
- PlainText
-
- );
- mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(Child).toHaveBeenCalledTimes(2);
-});
-
-test(' - renders children with correct name (children)', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
-
- );
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(wrapper.find(Child).at(0).prop('name')).toBe('0');
- expect(wrapper.find(Child).at(1).prop('name')).toBe('1');
-});
-
-test(' - renders children with correct name (value)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(wrapper.find(ListItemField).at(0).prop('name')).toBe('0');
- expect(wrapper.find(ListItemField).at(1).prop('name')).toBe('1');
-});
-
-test(' - renders correct error text (specified)', () => {
- const error = new Error();
- const element = (
-
- );
- const wrapper = mount(
- element,
- createContext({ x: { type: Array, label: '' }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.children().first().text()).toBe('Error');
-});
-
-test(' - renders correct error text (showInlineError=false)', () => {
- const error = new Error();
- const element = (
-
- );
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.children().first().text()).not.toBe('Error');
-});
-
-test(' - renders proper number of optional values after add new value', () => {
- const element = ;
- const onChange = jest.fn();
- const wrapper = mount(
- element,
- createContext(
- { x: { type: Array, optional: true }, 'x.$': { type: String } },
- { onChange },
- {
- x: [undefined, undefined, undefined],
- },
- ),
- );
- expect(wrapper.find(ListAddField).simulate('click')).toBeTruthy();
- expect(onChange).toHaveBeenNthCalledWith(1, 'x', [
- undefined,
- undefined,
- undefined,
- undefined,
- ]);
-});
diff --git a/packages/uniforms-semantic/__tests__/ListItemField.tsx b/packages/uniforms-semantic/__tests__/ListItemField.tsx
deleted file mode 100644
index 2c4224268..000000000
--- a/packages/uniforms-semantic/__tests__/ListItemField.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import React from 'react';
-import { AutoField, ListDelField, ListItemField } from 'uniforms-semantic';
-
-import createContext from './_createContext';
-import mount from './_mount';
-
-test(' - works', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListItemField)).toHaveLength(1);
-});
-
-test(' - renders ListDelField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListDelField)).toHaveLength(1);
- expect(wrapper.find(ListDelField).childAt(0).prop('name')).toBe('x.1');
-});
-
-test(' - renders AutoField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(AutoField)).toHaveLength(1);
-});
-
-test(' - renders children if specified', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
-
- );
- mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(Child).toHaveBeenCalledTimes(1);
-});
diff --git a/packages/uniforms-semantic/__tests__/index.ts b/packages/uniforms-semantic/__tests__/index.ts
index 1c5817f1a..0713cec2f 100644
--- a/packages/uniforms-semantic/__tests__/index.ts
+++ b/packages/uniforms-semantic/__tests__/index.ts
@@ -45,7 +45,9 @@ describe('@RTL', () => {
suites.testListDelField(theme.ListDelField);
suites.testListField(theme.ListField, {
getListAddField: screen => screen.getByRole('button'),
+ disableInlineError: true,
});
+ suites.testListItemField(theme.ListItemField);
suites.testLongTextField(theme.LongTextField);
suites.testNestField(theme.NestField);
suites.testNumField(theme.NumField);
diff --git a/packages/uniforms-unstyled/__tests__/ListField.tsx b/packages/uniforms-unstyled/__tests__/ListField.tsx
deleted file mode 100644
index 7c8dd726a..000000000
--- a/packages/uniforms-unstyled/__tests__/ListField.tsx
+++ /dev/null
@@ -1,136 +0,0 @@
-import React from 'react';
-import { ListAddField, ListField, ListItemField } from 'uniforms-unstyled';
-
-import createContext from './_createContext';
-import mount from './_mount';
-
-test(' - works', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListField)).toHaveLength(1);
-});
-
-test(' - renders ListAddField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListAddField)).toHaveLength(1);
- expect(wrapper.find(ListAddField).prop('name')).toBe('$');
-});
-
-test(' - renders correct label (specified)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find('label')).toHaveLength(1);
- expect(wrapper.find('label').text()).toEqual(
- expect.stringContaining('ListFieldLabel'),
- );
-});
-
-test(' - renders correct numer of items with model (specified)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined, undefined],
- }),
- );
-
- expect(wrapper.find('input')).toHaveLength(3);
-});
-
-test(' - passes itemProps to its children', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined],
- }),
- );
-
- expect(wrapper.find(ListItemField).first().prop('data-xyz')).toBe(1);
-});
-
-test(' - renders children (specified)', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
- PlainText
-
- );
- mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(Child).toHaveBeenCalledTimes(2);
-});
-
-test(' - renders children with correct name (children)', () => {
- const Child = jest.fn(() => ) as React.FC;
-
- const element = (
-
-
-
- );
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(wrapper.find(Child).at(0).prop('name')).toBe('0');
- expect(wrapper.find(Child).at(1).prop('name')).toBe('1');
-});
-
-test(' - renders children with correct name (value)', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }, undefined, {
- x: [undefined, undefined],
- }),
- );
-
- expect(wrapper.find(ListItemField).at(0).prop('name')).toBe('0');
- expect(wrapper.find(ListItemField).at(1).prop('name')).toBe('1');
-});
-
-test(' - renders proper number of optional values after add new value', () => {
- const element = ;
- const onChange = jest.fn();
- const wrapper = mount(
- element,
- createContext(
- { x: { type: Array, optional: true }, 'x.$': { type: String } },
- { onChange },
- {
- x: [undefined, undefined, undefined],
- },
- ),
- );
- expect(wrapper.find(ListAddField).simulate('click')).toBeTruthy();
- expect(onChange).toHaveBeenNthCalledWith(1, 'x', [
- undefined,
- undefined,
- undefined,
- undefined,
- ]);
-});
diff --git a/packages/uniforms-unstyled/__tests__/ListItemField.tsx b/packages/uniforms-unstyled/__tests__/ListItemField.tsx
deleted file mode 100644
index 6e9970e9b..000000000
--- a/packages/uniforms-unstyled/__tests__/ListItemField.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-import React from 'react';
-import { AutoField, ListDelField, ListItemField } from 'uniforms-unstyled';
-
-import createContext from './_createContext';
-import mount from './_mount';
-
-test(' - works', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListItemField)).toHaveLength(1);
-});
-
-test(' - renders ListDelField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(ListDelField)).toHaveLength(1);
- expect(wrapper.find(ListDelField).childAt(0).prop('name')).toBe('x.1');
-});
-
-test(' - renders AutoField', () => {
- const element = ;
- const wrapper = mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(wrapper.find(AutoField)).toHaveLength(1);
-});
-
-test(' - renders children if specified', () => {
- const Child: () => null = jest.fn(() => null);
-
- const element = (
-
-
-
- );
- mount(
- element,
- createContext({ x: { type: Array }, 'x.$': { type: String } }),
- );
-
- expect(Child).toHaveBeenCalledTimes(1);
-});
diff --git a/packages/uniforms-unstyled/__tests__/index.ts b/packages/uniforms-unstyled/__tests__/index.ts
index 98de11a8e..7df73ce41 100644
--- a/packages/uniforms-unstyled/__tests__/index.ts
+++ b/packages/uniforms-unstyled/__tests__/index.ts
@@ -45,7 +45,9 @@ describe('@RTL', () => {
suites.testListDelField(theme.ListDelField);
suites.testListField(theme.ListField, {
getListAddField: screen => screen.getByRole('button'),
+ testError: false,
});
+ suites.testListItemField(theme.ListItemField);
suites.testLongTextField(theme.LongTextField, {
skipShowInlineErrorTests: true,
});
diff --git a/packages/uniforms/__suites__/BaseForm.tsx b/packages/uniforms/__suites__/BaseForm.tsx
index 1a2f49e9e..89c887748 100644
--- a/packages/uniforms/__suites__/BaseForm.tsx
+++ b/packages/uniforms/__suites__/BaseForm.tsx
@@ -4,10 +4,10 @@ import { ZodBridge } from 'uniforms-bridge-zod';
import z from 'zod';
export function testBaseForm(BaseForm: ComponentType) {
+ const schema = new ZodBridge({ schema: z.object({}) });
+
test(' - renders', () => {
- const schema = z.object({});
- const bridge = new ZodBridge({ schema });
- const screen = render();
- expect(screen.getByTestId('form')).toBeInTheDocument();
+ const { container } = render();
+ expect(container.getElementsByTagName('form')).toHaveLength(1);
});
}
diff --git a/packages/uniforms/__suites__/ListField.tsx b/packages/uniforms/__suites__/ListField.tsx
index 1ff7fd040..3c534102d 100644
--- a/packages/uniforms/__suites__/ListField.tsx
+++ b/packages/uniforms/__suites__/ListField.tsx
@@ -6,7 +6,19 @@ import { render } from './render';
export function testListField(
ListField: ComponentType,
- { getListAddField }: { getListAddField: (screen: Screen) => HTMLElement },
+ {
+ getListAddField,
+ disableInlineError,
+ testError = true,
+ testStyle,
+ testTooltip,
+ }: {
+ getListAddField: (screen: Screen) => HTMLElement;
+ disableInlineError?: boolean;
+ testError?: boolean;
+ testStyle?: boolean;
+ testTooltip?: boolean;
+ },
) {
test(' - renders ListAddField', () => {
render(, {
@@ -27,7 +39,66 @@ export function testListField(
expect(screen.getByText(/ListFieldLabel.*/)).toBeInTheDocument();
});
- test(' - renders correct numer of items with model (specified)', () => {
+ if (testStyle) {
+ test(' - renders correct error style', () => {
+ const error = new Error();
+
+ render(
+ ,
+ {
+ x: Array,
+ 'x.$': String,
+ },
+ );
+
+ expect(screen.getByTestId('field')).toHaveStyle(
+ 'borderColor: rgb(255, 85, 0)',
+ );
+ });
+
+ test(' - renders correct error style (with specified style prop)', () => {
+ const error = new Error();
+
+ render(
+ ,
+ {
+ x: Array,
+ 'x.$': String,
+ },
+ );
+
+ expect(screen.getByTestId('field')).toHaveStyle('marginLeft: 8px');
+ });
+ }
+
+ if (testTooltip) {
+ test(' - renders correct info (specified)', () => {
+ const { container } = render(
+ ,
+ {
+ x: Array,
+ 'x.$': String,
+ },
+ );
+
+ expect(
+ container.getElementsByClassName('anticon-question-circle').length,
+ ).toBe(1);
+ });
+ }
+
+ test(' - renders correct number of items with model (specified)', () => {
render(
,
{
@@ -74,7 +145,7 @@ export function testListField(
});
test(' - renders children with correct name (children)', () => {
- const Child = jest.fn(() => ) as FC;
+ const Child = jest.fn(() => ) as FC;
render(
@@ -116,4 +187,46 @@ export function testListField(
expect(onChange).toHaveBeenCalledTimes(1);
expect(onChange).toHaveBeenLastCalledWith('x', [undefined]);
});
+
+ if (testError) {
+ test(' - renders correct error text (specified)', async () => {
+ const error = new Error();
+
+ render(
+ ,
+ {
+ x: Array,
+ 'x.$': String,
+ },
+ );
+
+ expect(screen.getByText(/^Error$/)).toBeInTheDocument();
+ });
+ }
+
+ if (disableInlineError) {
+ test(' - renders correct error text (showInlineError=false)', async () => {
+ const error = new Error();
+
+ render(
+ ,
+ {
+ x: Array,
+ 'x.$': String,
+ },
+ );
+
+ expect(screen.queryByText(/^Error$/)).not.toBeInTheDocument();
+ });
+ }
}
diff --git a/packages/uniforms/__suites__/ListItemField.tsx b/packages/uniforms/__suites__/ListItemField.tsx
new file mode 100644
index 000000000..14eb4b34a
--- /dev/null
+++ b/packages/uniforms/__suites__/ListItemField.tsx
@@ -0,0 +1,40 @@
+import { screen } from '@testing-library/react';
+import React, { ComponentType } from 'react';
+import z from 'zod';
+
+import { renderWithZod } from './render-zod';
+
+export function testListItemField(ListItemField: ComponentType) {
+ test(' - works', () => {
+ renderWithZod({
+ element: ,
+ schema: z.object({ field: z.string().optional() }),
+ });
+
+ expect(screen.getByLabelText('Field')).toBeInTheDocument();
+ });
+
+ test(' - renders ListDelField', () => {
+ renderWithZod({
+ element: ,
+ schema: z.object({ field: z.string() }),
+ });
+
+ expect(screen.getByRole('button')).toBeInTheDocument();
+ });
+
+ test(' - renders children if specified', () => {
+ const Child = jest.fn(() => ) as React.FC;
+
+ renderWithZod({
+ element: (
+
+
+
+ ),
+ schema: z.object({ field: z.string() }),
+ });
+
+ expect(Child).toHaveBeenCalledTimes(1);
+ });
+}
diff --git a/packages/uniforms/__suites__/QuickForm.tsx b/packages/uniforms/__suites__/QuickForm.tsx
index a13b0a6ef..c0f17e639 100644
--- a/packages/uniforms/__suites__/QuickForm.tsx
+++ b/packages/uniforms/__suites__/QuickForm.tsx
@@ -4,10 +4,10 @@ import { ZodBridge } from 'uniforms-bridge-zod';
import z from 'zod';
export function testQuickForm(QuickForm: ComponentType) {
+ const bridge = new ZodBridge({ schema: z.object({}) });
+
test(' - renders', () => {
- const schema = z.object({});
- const bridge = new ZodBridge({ schema });
- const screen = render();
- expect(screen.getByTestId('form')).toBeInTheDocument();
+ const { container } = render();
+ expect(container.getElementsByTagName('form')).toHaveLength(1);
});
}
diff --git a/packages/uniforms/__suites__/index.ts b/packages/uniforms/__suites__/index.ts
index 20a088254..04d72395f 100644
--- a/packages/uniforms/__suites__/index.ts
+++ b/packages/uniforms/__suites__/index.ts
@@ -10,6 +10,7 @@ export * from './HiddenField';
export * from './ListAddField';
export * from './ListDelField';
export * from './ListField';
+export * from './ListItemField';
export * from './LongTextField';
export * from './NestField';
export * from './NumField';
diff --git a/packages/uniforms/__tests__/BaseForm.tsx b/packages/uniforms/__tests__/BaseForm.tsx
index be29a930f..4ab9cdb62 100644
--- a/packages/uniforms/__tests__/BaseForm.tsx
+++ b/packages/uniforms/__tests__/BaseForm.tsx
@@ -1,182 +1,68 @@
-import { ReactWrapper } from 'enzyme';
-import React from 'react';
-import { BaseForm, Bridge, Context, useField } from 'uniforms';
-
-import mount from './_mount';
-
-jest.mock('meteor/aldeed:simple-schema');
-jest.mock('meteor/check');
+import { fireEvent, render, screen } from '@testing-library/react';
+import React, { useContext } from 'react';
+import { BaseForm, context } from 'uniforms';
+import { ZodBridge } from 'uniforms-bridge-zod';
+import { AutoField } from 'uniforms-unstyled';
+import z from 'zod';
describe('BaseForm', () => {
- const error = new Error();
const model = { $: [1], _: 1 };
- const schema: Bridge = {
- getError() {},
- getErrorMessage: () => '',
- getErrorMessages: () => [],
- getField: () => ({}),
- getInitialValue() {},
- getProps: () => ({}),
- getSubfields: () => [],
- getType() {},
- getValidator: () => () => {},
- };
+ const schema = new ZodBridge({
+ schema: z.object({ a: z.string().optional() }),
+ });
const onChange = jest.fn();
const onSubmit = jest.fn();
-
afterEach(() => {
onChange.mockClear();
onSubmit.mockClear();
});
- it('have correct context', () => {
- const wrapper = mount>(
- ,
- );
-
- const context = wrapper.instance().getContext();
- expect(context).toEqual>({
- changed: false,
- changedMap: {},
- error,
- model,
- name: [],
- onChange: expect.any(Function),
- onSubmit: expect.any(Function),
- randomId: expect.any(Function),
- schema,
- state: {
- disabled: false,
- readOnly: false,
- showInlineError: false,
- },
- submitted: false,
- submitting: false,
- validating: false,
- formRef: expect.any(BaseForm),
- });
- });
-
describe('when rendered', () => {
- const wrapper = mount>(
-
-
-
-
- ,
- );
-
it('is