From 652a96f1c4cd25bdef51b81efc9cdbf7db36d6da Mon Sep 17 00:00:00 2001 From: Adrian Mucha Date: Fri, 9 Feb 2024 10:53:21 +0100 Subject: [PATCH 01/10] WIP: Move antd bootstrap3 TextField tests to suite --- .../uniforms-antd/__tests__/TextField.tsx | 193 ------------------ .../__tests__/TextField.tsx | 189 ----------------- packages/uniforms/__suites__/TextField.tsx | 35 ++++ 3 files changed, 35 insertions(+), 382 deletions(-) delete mode 100644 packages/uniforms-antd/__tests__/TextField.tsx delete mode 100644 packages/uniforms-bootstrap3/__tests__/TextField.tsx diff --git a/packages/uniforms-antd/__tests__/TextField.tsx b/packages/uniforms-antd/__tests__/TextField.tsx deleted file mode 100644 index fcaaa22ec..000000000 --- a/packages/uniforms-antd/__tests__/TextField.tsx +++ /dev/null @@ -1,193 +0,0 @@ -import { screen } from '@testing-library/react'; -import Input from 'antd/lib/input'; -import React from 'react'; -import { TextField } from 'uniforms-antd'; -import { render } from 'uniforms/__suites__'; - -import createContext from './_createContext'; -import mount from './_mount'; - -describe('@RTL - TextField tests', () => { - test(' - renders component with unknown props', () => { - const props = { - 'data-x': 'x', - 'data-y': 'y', - 'data-z': 'z', - }; - render(, { x: String }); - - const input = screen.getByRole('textbox'); - Object.entries(props).forEach(([key, value]) => - expect(input).toHaveAttribute(key, value), - ); - }); -}); - -test(' - renders an input', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(Input)).toHaveLength(1); -}); - -test(' - renders an input with correct disabled state', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(Input)).toHaveLength(1); - expect(wrapper.find(Input).prop('disabled')).toBe(true); -}); - -test(' - renders an input with correct readOnly state', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(Input)).toHaveLength(1); - expect(wrapper.find(Input).prop('readOnly')).toBe(true); -}); - -test(' - renders an input with correct id (inherited)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(Input)).toHaveLength(1); - expect(wrapper.find(Input).prop('id')).toBeTruthy(); -}); - -test(' - renders an input with correct id (specified)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(Input)).toHaveLength(1); - expect(wrapper.find(Input).prop('id')).toBe('y'); -}); - -test(' - renders an input with correct name', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(Input)).toHaveLength(1); - expect(wrapper.find(Input).prop('name')).toBe('x'); -}); - -test(' - renders an input with correct placeholder', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(Input)).toHaveLength(1); - expect(wrapper.find(Input).prop('placeholder')).toBe('y'); -}); - -test(' - renders an input with correct type', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(Input)).toHaveLength(1); - expect(wrapper.find(Input).prop('type')).toBe('text'); -}); - -test(' - renders an input with correct value (default)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(Input)).toHaveLength(1); - expect(wrapper.find(Input).prop('value')).toBe(''); -}); - -test(' - renders an input with correct value (model)', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { model: { x: 'y' } }), - ); - - expect(wrapper.find(Input)).toHaveLength(1); - expect(wrapper.find(Input).prop('value')).toBe('y'); -}); - -test(' - renders an input with correct value (specified)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(Input)).toHaveLength(1); - expect(wrapper.find(Input).prop('value')).toBe('y'); -}); - -test(' - renders an input which correctly reacts on change', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { onChange }), - ); - - expect(wrapper.find(Input)).toHaveLength(1); - expect( - wrapper.find(Input).simulate('change', { target: { value: 'y' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', 'y'); -}); - -test(' - renders an input which correctly reacts on change (empty)', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { onChange }), - ); - - expect(wrapper.find(Input)).toHaveLength(1); - expect( - wrapper.find(Input).simulate('change', { target: { value: '' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', ''); -}); - -test(' - renders an input which correctly reacts on change (same value)', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { model: { x: 'y' }, onChange }), - ); - - expect(wrapper.find(Input)).toHaveLength(1); - expect( - wrapper.find(Input).simulate('change', { target: { value: 'y' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', 'y'); -}); - -test(' - renders a label', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('label')).toHaveLength(1); - expect(wrapper.find('label').text()).toBe('y'); -}); - -test(' - renders a wrapper with unknown props', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(Input).prop('data-x')).toBe('x'); - expect(wrapper.find(Input).prop('data-y')).toBe('y'); - expect(wrapper.find(Input).prop('data-z')).toBe('z'); -}); - -test(' - renders a input with correct type prop', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(Input).prop('type')).toBe('password'); -}); - -test(' - renders a input with autocomplete turned off', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(Input).prop('autoComplete')).toBe('off'); -}); diff --git a/packages/uniforms-bootstrap3/__tests__/TextField.tsx b/packages/uniforms-bootstrap3/__tests__/TextField.tsx deleted file mode 100644 index 749c200de..000000000 --- a/packages/uniforms-bootstrap3/__tests__/TextField.tsx +++ /dev/null @@ -1,189 +0,0 @@ -import { screen } from '@testing-library/react'; -import React from 'react'; -import { TextField } from 'uniforms-bootstrap3'; -import { render } from 'uniforms/__suites__'; - -import createContext from './_createContext'; -import mount from './_mount'; - -describe('@RTL - TextField tests', () => { - test(' - renders a wrapper with unknown props', () => { - const props = { - 'data-x': 'x', - 'data-y': 'y', - 'data-z': 'z', - }; - render(, { x: String }); - - const wrapper = screen.getByRole('textbox').closest('div'); - Object.entries(props).forEach(([key, value]) => - expect(wrapper).toHaveAttribute(key, value), - ); - }); -}); - -test(' - renders an input', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); -}); - -test(' - renders an input with correct disabled state', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('disabled')).toBe(true); -}); - -test(' - renders an input with correct readOnly state', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('readOnly')).toBe(true); -}); - -test(' - renders an input with correct id (inherited)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('id')).toBeTruthy(); -}); - -test(' - renders an input with correct id (specified)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('id')).toBe('y'); -}); - -test(' - renders an input with correct name', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('name')).toBe('x'); -}); - -test(' - renders an input with correct placeholder', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('placeholder')).toBe('y'); -}); - -test(' - renders an input with correct type', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('type')).toBe('text'); -}); - -test(' - renders an input with correct value (default)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('value')).toBe(''); -}); - -test(' - renders an input with correct value (model)', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { model: { x: 'y' } }), - ); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('value')).toBe('y'); -}); - -test(' - renders an input with correct value (specified)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('value')).toBe('y'); -}); - -test(' - renders an input which correctly reacts on change', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { onChange }), - ); - - expect(wrapper.find('input')).toHaveLength(1); - expect( - wrapper.find('input').simulate('change', { target: { value: 'y' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', 'y'); -}); - -test(' - renders an input which correctly reacts on change (empty)', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { onChange }), - ); - - expect(wrapper.find('input')).toHaveLength(1); - expect( - wrapper.find('input').simulate('change', { target: { value: '' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', ''); -}); - -test(' - renders an input which correctly reacts on change (same value)', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { model: { x: 'y' }, onChange }), - ); - - expect(wrapper.find('input')).toHaveLength(1); - expect( - wrapper.find('input').simulate('change', { target: { value: 'y' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', 'y'); -}); - -test(' - renders a label', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('label')).toHaveLength(1); - expect(wrapper.find('label').text()).toBe('y'); - expect(wrapper.find('label').prop('htmlFor')).toBe( - wrapper.find('input').prop('id'), - ); -}); - -test(' - renders a wrapper with unknown props', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('div').at(0).prop('data-x')).toBe('x'); - expect(wrapper.find('div').at(0).prop('data-y')).toBe('y'); - expect(wrapper.find('div').at(0).prop('data-z')).toBe('z'); -}); - -test(' - renders a input with autocomplete turned off', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('div').at(0).prop('autoComplete')).toBeFalsy(); - expect(wrapper.find('input').prop('autoComplete')).toBe('off'); -}); diff --git a/packages/uniforms/__suites__/TextField.tsx b/packages/uniforms/__suites__/TextField.tsx index 718bd8d06..68b906c62 100644 --- a/packages/uniforms/__suites__/TextField.tsx +++ b/packages/uniforms/__suites__/TextField.tsx @@ -6,6 +6,14 @@ import z from 'zod'; import { renderWithZod } from './render-zod'; export function testTextField(TextField: ComponentType) { + test(' - renders an input', () => { + renderWithZod({ + element: , + schema: z.object({ x: z.string() }), + }); + expect(screen.getByRole('textbox')).toBeTruthy(); + }); + test(' - renders an input with correct disabled state', () => { renderWithZod({ element: , @@ -133,4 +141,31 @@ export function testTextField(TextField: ComponentType) { }); expect(screen.getByLabelText(/^Y/)).toBeInTheDocument(); }); + + test(' - renders a wrapper with unknown props', () => { + const props = { + 'data-x': 'x', + 'data-y': 'y', + 'data-z': 'z', + }; + renderWithZod({ + element: , + schema: z.object({ x: z.string() }), + }); + + const querySelectorParams = Object.entries(props) + .map(([key, value]) => `[${key}="${value}"]`) + .join(''); + const wrapper = screen.getByRole('textbox').closest(querySelectorParams); + expect(wrapper).toBeTruthy(); + }); + + test(' - renders a input with correct type prop (password)', () => { + renderWithZod({ + element: , + schema: z.object({ x: z.string() }), + }); + const wrapper = screen.getByLabelText(/^X( \*)?$/); + expect(wrapper).toHaveAttribute('type', 'password'); + }); } From 600f53f4dd42f1630138481fb0e34e6fdd6d4baf Mon Sep 17 00:00:00 2001 From: Adrian Mucha Date: Fri, 9 Feb 2024 13:53:00 +0100 Subject: [PATCH 02/10] Remove uniforms-mui TextField enzyme test --- packages/uniforms-mui/__tests__/TextField.tsx | 179 ------------------ 1 file changed, 179 deletions(-) delete mode 100644 packages/uniforms-mui/__tests__/TextField.tsx diff --git a/packages/uniforms-mui/__tests__/TextField.tsx b/packages/uniforms-mui/__tests__/TextField.tsx deleted file mode 100644 index ae18aca3d..000000000 --- a/packages/uniforms-mui/__tests__/TextField.tsx +++ /dev/null @@ -1,179 +0,0 @@ -import TextFieldMaterial from '@mui/material/TextField'; -import React from 'react'; -import { TextField } from 'uniforms-mui'; - -import createContext from './_createContext'; -import mount from './_mount'; - -test(' - renders an TextField', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); -}); - -test(' - renders a TextField with correct disabled state', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('disabled')).toBe(true); -}); - -test(' - renders a TextField with correct readOnly state', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('inputProps')!.readOnly).toBe( - true, - ); -}); - -test(' - renders a TextField with correct id (inherited)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('id')).toBeTruthy(); -}); - -test(' - renders a TextField with correct id (specified)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('id')).toBe('y'); -}); - -test(' - renders a TextField with correct name', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('name')).toBe('x'); -}); - -test(' - renders a TextField with correct placeholder', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('placeholder')).toBe('y'); -}); - -test(' - renders a TextField with correct value (default)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('value')).toBe(''); -}); - -test(' - renders a TextField with correct value (model)', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { model: { x: 'y' } }), - ); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('value')).toBe('y'); -}); - -test(' - renders a TextField with correct value (specified)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('value')).toBe('y'); -}); - -test(' - renders a TextField which correctly reacts on change', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { onChange }), - ); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect( - wrapper.find('input').simulate('change', { target: { value: 'y' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', 'y'); -}); - -test(' - renders a TextField which correctly reacts on change (empty)', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { onChange }), - ); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect( - wrapper.find('input').simulate('change', { target: { value: '' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', ''); -}); - -test(' - renders a TextField which correctly reacts on change (same value)', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { model: { x: 'y' }, onChange }), - ); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect( - wrapper.find('input').simulate('change', { target: { value: 'y' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', 'y'); -}); - -test(' - renders a label', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('label')).toBe('y'); -}); - -test(' - renders a TextField with correct error text (specified)', () => { - const error = new Error(); - const element = ( - - ); - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial).prop('helperText')).toBe('Error'); -}); - -test(' - renders a TextField with correct error text (showInlineError=false)', () => { - const error = new Error(); - const element = ( - - ); - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial).prop('helperText')).toBeUndefined(); -}); - -test(' - renders a input with autocomplete off', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('autoComplete')).toBe('off'); -}); From 8efd14794277fa51fe1ddef9bf8e5ff0fdad0841 Mon Sep 17 00:00:00 2001 From: Adrian Mucha Date: Fri, 9 Feb 2024 15:51:50 +0100 Subject: [PATCH 03/10] Remove uniforms-material uniforms-unstyled TextField enzyme test --- .../uniforms-material/__tests__/TextField.tsx | 272 ------------------ .../__tests__/{index.ts => index.tsx} | 20 +- .../uniforms-unstyled/__tests__/TextField.tsx | 171 ----------- packages/uniforms-unstyled/__tests__/index.ts | 2 +- packages/uniforms/__suites__/TextField.tsx | 124 +++++++- 5 files changed, 142 insertions(+), 447 deletions(-) delete mode 100644 packages/uniforms-material/__tests__/TextField.tsx rename packages/uniforms-material/__tests__/{index.ts => index.tsx} (79%) delete mode 100644 packages/uniforms-unstyled/__tests__/TextField.tsx diff --git a/packages/uniforms-material/__tests__/TextField.tsx b/packages/uniforms-material/__tests__/TextField.tsx deleted file mode 100644 index bda931460..000000000 --- a/packages/uniforms-material/__tests__/TextField.tsx +++ /dev/null @@ -1,272 +0,0 @@ -import TextFieldMaterial from '@material-ui/core/TextField'; -import createMuiTheme from '@material-ui/core/styles/createMuiTheme'; -import ThemeProvider from '@material-ui/styles/ThemeProvider/ThemeProvider'; -import { screen } from '@testing-library/react'; -import React from 'react'; -import { TextField } from 'uniforms-material'; -import { render } from 'uniforms/__suites__'; - -import createContext from './_createContext'; -import mount from './_mount'; - -describe('@RTL - TextField tests', () => { - test(' - renders a TextField with correct error text (specified)', () => { - const errorMessage = 'Error'; - render( - , - { x: String }, - ); - - expect(screen.getByText(errorMessage)).toBeInTheDocument(); - }); - - test(' - renders a TextField with correct error text (showInlineError=false)', () => { - const errorMessage = 'Error'; - render( - , - { x: String }, - ); - - expect(screen.queryByText(errorMessage)).not.toBeInTheDocument(); - }); - - test(' - default props are not passed when MUI theme props are specified', () => { - const theme = createMuiTheme({ - props: { MuiTextField: { fullWidth: false, margin: 'normal' } }, - }); - const { container } = render( - - - , - { x: { type: String } }, - ); - - const elements = container.getElementsByClassName( - 'MuiFormControl-marginNormal', - ); - expect(elements).toHaveLength(1); - expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); - }); - - test(' - default props are passed when MUI theme props are absent', () => { - const theme = createMuiTheme({}); - const { container } = render( - - - , - { x: { type: String } }, - ); - - const elements = container.getElementsByClassName( - 'MuiFormControl-marginDense', - ); - expect(elements).toHaveLength(1); - expect(elements[0]).toHaveClass('MuiFormControl-fullWidth'); - }); - - test(' - explicit props are passed when MUI theme props are specified', () => { - const theme = createMuiTheme({ - props: { MuiTextField: { fullWidth: true, margin: 'dense' } }, - }); - const explicitProps = { - fullWidth: false, - margin: 'normal' as const, - }; - - const { container } = render( - - - , - { x: { type: String } }, - ); - - const elements = container.getElementsByClassName( - 'MuiFormControl-marginNormal', - ); - expect(elements).toHaveLength(1); - expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); - }); -}); - -test(' - renders an TextField', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); -}); - -test(' - renders a TextField with correct disabled state', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('disabled')).toBe(true); -}); - -test(' - renders a TextField with correct readOnly state', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('inputProps')!.readOnly).toBe( - true, - ); -}); - -test(' - renders a TextField with correct id (inherited)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('id')).toBeTruthy(); -}); - -test(' - renders a TextField with correct id (specified)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('id')).toBe('y'); -}); - -test(' - renders a TextField with correct name', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('name')).toBe('x'); -}); - -test(' - renders a TextField with correct placeholder', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('placeholder')).toBe('y'); -}); - -test(' - renders a TextField with correct value (default)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('value')).toBe(''); -}); - -test(' - renders a TextField with correct value (model)', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { model: { x: 'y' } }), - ); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('value')).toBe('y'); -}); - -test(' - renders a TextField with correct value (specified)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('value')).toBe('y'); -}); - -test(' - renders a TextField which correctly reacts on change', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { onChange }), - ); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect( - wrapper.find('input').simulate('change', { target: { value: 'y' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', 'y'); -}); - -test(' - renders a TextField which correctly reacts on change (empty)', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { onChange }), - ); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect( - wrapper.find('input').simulate('change', { target: { value: '' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', ''); -}); - -test(' - renders a TextField which correctly reacts on change (same value)', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { model: { x: 'y' }, onChange }), - ); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect( - wrapper.find('input').simulate('change', { target: { value: 'y' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', 'y'); -}); - -test(' - renders a label', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('label')).toBe('y'); -}); - -test(' - renders a TextField with correct error text (specified)', () => { - const error = new Error(); - const element = ( - - ); - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial).prop('helperText')).toBe('Error'); -}); - -test(' - renders a TextField with correct error text (showInlineError=false)', () => { - const error = new Error(); - const element = ( - - ); - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial).prop('helperText')).toBeUndefined(); -}); - -test(' - renders a input with autocomplete off', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find(TextFieldMaterial)).toHaveLength(1); - expect(wrapper.find(TextFieldMaterial).prop('autoComplete')).toBe('off'); -}); diff --git a/packages/uniforms-material/__tests__/index.ts b/packages/uniforms-material/__tests__/index.tsx similarity index 79% rename from packages/uniforms-material/__tests__/index.ts rename to packages/uniforms-material/__tests__/index.tsx index 5d81b6d44..1415a3a54 100644 --- a/packages/uniforms-material/__tests__/index.ts +++ b/packages/uniforms-material/__tests__/index.tsx @@ -1,3 +1,8 @@ +import createMuiTheme, { + ThemeOptions, +} from '@material-ui/core/styles/createMuiTheme'; +import ThemeProvider from '@material-ui/styles/ThemeProvider/ThemeProvider'; +import React, { PropsWithChildren } from 'react'; import * as theme from 'uniforms-material'; import * as suites from 'uniforms/__suites__'; @@ -56,7 +61,20 @@ describe('@RTL', () => { suites.testQuickForm(theme.QuickForm); suites.testRadioField(theme.RadioField); suites.testSubmitField(theme.SubmitField); - suites.testTextField(theme.TextField); + suites.testTextField(theme.TextField, { + testPassThemeProps: { + ThemeProvider({ + themeOptions, + ...props + }: PropsWithChildren<{ themeOptions: ThemeOptions }>) { + return ( + + {props.children} + + ); + }, + }, + }); suites.testValidatedForm(theme.ValidatedForm); suites.testValidatedQuickForm(theme.ValidatedQuickForm); }); diff --git a/packages/uniforms-unstyled/__tests__/TextField.tsx b/packages/uniforms-unstyled/__tests__/TextField.tsx deleted file mode 100644 index 16240266f..000000000 --- a/packages/uniforms-unstyled/__tests__/TextField.tsx +++ /dev/null @@ -1,171 +0,0 @@ -import React from 'react'; -import { TextField } from 'uniforms-unstyled'; - -import createContext from './_createContext'; -import mount from './_mount'; - -test(' - renders an input', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); -}); - -test(' - renders an input with correct disabled state', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('disabled')).toBe(true); -}); - -test(' - renders an input with correct readOnly state', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('readOnly')).toBe(true); -}); - -test(' - renders an input with correct id (inherited)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('id')).toBeTruthy(); -}); - -test(' - renders an input with correct id (specified)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('id')).toBe('y'); -}); - -test(' - renders an input with correct name', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('name')).toBe('x'); -}); - -test(' - renders an input with correct placeholder', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('placeholder')).toBe('y'); -}); - -test(' - renders an input with correct type', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('type')).toBe('text'); -}); - -test(' - renders an input with correct value (default)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('value')).toBe(''); -}); - -test(' - renders an input with correct value (model)', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { model: { x: 'y' } }), - ); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('value')).toBe('y'); -}); - -test(' - renders an input with correct value (specified)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('value')).toBe('y'); -}); - -test(' - renders an input which correctly reacts on change', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { onChange }), - ); - - expect(wrapper.find('input')).toHaveLength(1); - expect( - wrapper.find('input').simulate('change', { target: { value: 'y' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', 'y'); -}); - -test(' - renders an input which correctly reacts on change (empty)', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { onChange }), - ); - - expect(wrapper.find('input')).toHaveLength(1); - expect( - wrapper.find('input').simulate('change', { target: { value: '' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', ''); -}); - -test(' - renders an input which correctly reacts on change (same value)', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { model: { x: 'y' }, onChange }), - ); - - expect(wrapper.find('input')).toHaveLength(1); - expect( - wrapper.find('input').simulate('change', { target: { value: 'y' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', 'y'); -}); - -test(' - renders a label', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('label')).toHaveLength(1); - expect(wrapper.find('label').text()).toBe('y'); - expect(wrapper.find('label').prop('htmlFor')).toBe( - wrapper.find('input').prop('id'), - ); -}); - -test(' - renders a wrapper with unknown props', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('div').at(0).prop('data-x')).toBe('x'); - expect(wrapper.find('div').at(0).prop('data-y')).toBe('y'); - expect(wrapper.find('div').at(0).prop('data-z')).toBe('z'); -}); - -test(' - renders an input with autocomplete turned off', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('autoComplete')).toBe('off'); -}); diff --git a/packages/uniforms-unstyled/__tests__/index.ts b/packages/uniforms-unstyled/__tests__/index.ts index 98de11a8e..d6e2206c0 100644 --- a/packages/uniforms-unstyled/__tests__/index.ts +++ b/packages/uniforms-unstyled/__tests__/index.ts @@ -57,7 +57,7 @@ describe('@RTL', () => { suites.testQuickForm(theme.QuickForm); suites.testRadioField(theme.RadioField); suites.testSubmitField(theme.SubmitField); - suites.testTextField(theme.TextField); + suites.testTextField(theme.TextField, { testShowInlineError: false }); suites.testValidatedForm(theme.ValidatedForm); suites.testValidatedQuickForm(theme.ValidatedQuickForm); }); diff --git a/packages/uniforms/__suites__/TextField.tsx b/packages/uniforms/__suites__/TextField.tsx index 68b906c62..c08a31ab1 100644 --- a/packages/uniforms/__suites__/TextField.tsx +++ b/packages/uniforms/__suites__/TextField.tsx @@ -1,11 +1,25 @@ import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import React, { ComponentType } from 'react'; +import React, { ComponentType, PropsWithChildren } from 'react'; import z from 'zod'; import { renderWithZod } from './render-zod'; -export function testTextField(TextField: ComponentType) { +type TestTextFieldOptions = { + testShowInlineError?: boolean; + testPassThemeProps?: { + ThemeProvider: ( + props: PropsWithChildren<{ themeOptions: any }>, + ) => JSX.Element; + }; +}; + +export function testTextField( + TextField: ComponentType, + options: TestTextFieldOptions = { + testShowInlineError: true, + }, +) { test(' - renders an input', () => { renderWithZod({ element: , @@ -168,4 +182,110 @@ export function testTextField(TextField: ComponentType) { const wrapper = screen.getByLabelText(/^X( \*)?$/); expect(wrapper).toHaveAttribute('type', 'password'); }); + + if (options.testShowInlineError) { + test(' - renders a TextField with correct error text (specified)', () => { + const errorMessage = 'Error'; + renderWithZod({ + element: ( + + ), + schema: z.object({ x: z.string() }), + }); + + expect(screen.getByText(errorMessage)).toBeInTheDocument(); + }); + + test(' - renders a TextField with correct error text (showInlineError=false)', () => { + const errorMessage = 'Error'; + renderWithZod({ + element: ( + + ), + schema: z.object({ x: z.string() }), + }); + + expect(screen.queryByText(errorMessage)).not.toBeInTheDocument(); + }); + } + + if (options.testPassThemeProps) { + const { ThemeProvider } = options.testPassThemeProps; + if (!ThemeProvider) { + throw new Error('Missing ThemeProvider for testPassThemeProps'); + } + + test(' - default props are not passed when MUI theme props are specified', () => { + const themeOptions = { + props: { MuiTextField: { fullWidth: false, margin: 'normal' } }, + }; + const { container } = renderWithZod({ + element: ( + + + + ), + schema: z.object({ x: z.string() }), + }); + + const elements = container.getElementsByClassName( + 'MuiFormControl-marginNormal', + ); + expect(elements).toHaveLength(1); + expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); + }); + + test(' - default props are passed when MUI theme props are absent', () => { + const themeOptions = {}; + const { container } = renderWithZod({ + element: ( + + + + ), + schema: z.object({ x: z.string() }), + }); + + const elements = container.getElementsByClassName( + 'MuiFormControl-marginDense', + ); + expect(elements).toHaveLength(1); + expect(elements[0]).toHaveClass('MuiFormControl-fullWidth'); + }); + + test(' - explicit props are passed when MUI theme props are specified', () => { + const themeOptions = { + props: { MuiTextField: { fullWidth: true, margin: 'dense' } }, + }; + const explicitProps = { + fullWidth: false, + margin: 'normal' as const, + }; + + const { container } = renderWithZod({ + element: ( + + + + ), + schema: z.object({ x: z.string() }), + }); + + const elements = container.getElementsByClassName( + 'MuiFormControl-marginNormal', + ); + expect(elements).toHaveLength(1); + expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); + }); + } } From 0bdea39ced043449188eb9fe0ec548f28ad800e6 Mon Sep 17 00:00:00 2001 From: Adrian Mucha Date: Fri, 9 Feb 2024 17:00:28 +0100 Subject: [PATCH 04/10] Refactor --- packages/uniforms/__suites__/TextField.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/uniforms/__suites__/TextField.tsx b/packages/uniforms/__suites__/TextField.tsx index c08a31ab1..01ccf9299 100644 --- a/packages/uniforms/__suites__/TextField.tsx +++ b/packages/uniforms/__suites__/TextField.tsx @@ -221,9 +221,6 @@ export function testTextField( if (options.testPassThemeProps) { const { ThemeProvider } = options.testPassThemeProps; - if (!ThemeProvider) { - throw new Error('Missing ThemeProvider for testPassThemeProps'); - } test(' - default props are not passed when MUI theme props are specified', () => { const themeOptions = { From 2aa385f08b970bd22356d14f10469cccddef66a6 Mon Sep 17 00:00:00 2001 From: Adrian Mucha Date: Fri, 9 Feb 2024 17:22:57 +0100 Subject: [PATCH 05/10] Remove uniforms-semantic TextField enzyme test --- .../uniforms-bootstrap3/__tests__/index.ts | 2 +- .../uniforms-bootstrap4/__tests__/index.ts | 2 +- .../uniforms-bootstrap5/__tests__/index.ts | 2 +- .../uniforms-semantic/__tests__/TextField.tsx | 284 ------------------ packages/uniforms-semantic/__tests__/index.ts | 5 +- packages/uniforms/__suites__/TextField.tsx | 27 ++ 6 files changed, 34 insertions(+), 288 deletions(-) delete mode 100644 packages/uniforms-semantic/__tests__/TextField.tsx diff --git a/packages/uniforms-bootstrap3/__tests__/index.ts b/packages/uniforms-bootstrap3/__tests__/index.ts index 83ab14a6d..1429d2d40 100644 --- a/packages/uniforms-bootstrap3/__tests__/index.ts +++ b/packages/uniforms-bootstrap3/__tests__/index.ts @@ -54,7 +54,7 @@ describe('@RTL', () => { suites.testQuickForm(theme.QuickForm); suites.testRadioField(theme.RadioField); suites.testSubmitField(theme.SubmitField); - suites.testTextField(theme.TextField); + suites.testTextField(theme.TextField, { testWrapClassName: true }); suites.testValidatedForm(theme.ValidatedForm); suites.testValidatedQuickForm(theme.ValidatedQuickForm); }); diff --git a/packages/uniforms-bootstrap4/__tests__/index.ts b/packages/uniforms-bootstrap4/__tests__/index.ts index 0d7ded864..8582f1d45 100644 --- a/packages/uniforms-bootstrap4/__tests__/index.ts +++ b/packages/uniforms-bootstrap4/__tests__/index.ts @@ -54,7 +54,7 @@ describe('@RTL', () => { suites.testQuickForm(theme.QuickForm); suites.testRadioField(theme.RadioField); suites.testSubmitField(theme.SubmitField); - suites.testTextField(theme.TextField); + suites.testTextField(theme.TextField, { testWrapClassName: true }); suites.testValidatedForm(theme.ValidatedForm); suites.testValidatedQuickForm(theme.ValidatedQuickForm); }); diff --git a/packages/uniforms-bootstrap5/__tests__/index.ts b/packages/uniforms-bootstrap5/__tests__/index.ts index bd1096e57..66d5c3e3d 100644 --- a/packages/uniforms-bootstrap5/__tests__/index.ts +++ b/packages/uniforms-bootstrap5/__tests__/index.ts @@ -56,7 +56,7 @@ describe('@RTL', () => { suites.testQuickForm(theme.QuickForm); suites.testRadioField(theme.RadioField); suites.testSubmitField(theme.SubmitField); - suites.testTextField(theme.TextField); + suites.testTextField(theme.TextField, { testWrapClassName: true }); suites.testValidatedForm(theme.ValidatedForm); suites.testValidatedQuickForm(theme.ValidatedQuickForm); }); diff --git a/packages/uniforms-semantic/__tests__/TextField.tsx b/packages/uniforms-semantic/__tests__/TextField.tsx deleted file mode 100644 index 7f482bfed..000000000 --- a/packages/uniforms-semantic/__tests__/TextField.tsx +++ /dev/null @@ -1,284 +0,0 @@ -import { screen } from '@testing-library/react'; -import React from 'react'; -import { TextField } from 'uniforms-semantic'; -import { render } from 'uniforms/__suites__'; - -import createContext from './_createContext'; -import mount from './_mount'; - -describe('@RTL - TextField tests', () => { - test(' - renders a wrapper with unknown props', () => { - const props = { - 'data-x': 'x', - 'data-y': 'y', - 'data-z': 'z', - }; - render(, { x: String }); - - const wrapper = screen.getByRole('textbox').closest('div')?.parentElement; - Object.entries(props).forEach(([key, value]) => - expect(wrapper).toHaveAttribute(key, value), - ); - }); - - test(' - renders a TextField with correct error text (specified)', () => { - const errorMessage = 'Error'; - render( - , - { x: String }, - ); - - expect(screen.getByText(errorMessage)).toBeInTheDocument(); - }); - - test(' - renders a TextField with correct error text (showInlineError=false)', () => { - const errorMessage = 'Error'; - render( - , - { x: String }, - ); - - expect(screen.queryByText(errorMessage)).not.toBeInTheDocument(); - }); - - test(' - renders an icon', () => { - const { container } = render(, { - x: String, - }); - - expect(container.querySelector('i')).toBeInTheDocument(); - }); - - test(' - renders with a custom wrapClassName', () => { - const testClassName = 'test-class-name'; - render(, { x: String }); - - expect(screen.getByRole('textbox').closest('div')).toHaveClass( - testClassName, - ); - }); -}); - -test(' - renders an input', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); -}); - -test(' - renders an input with correct disabled state', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('disabled')).toBe(true); -}); - -test(' - renders an input with correct readOnly state', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('readOnly')).toBe(true); -}); - -test(' - renders an input with correct id (inherited)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('id')).toBeTruthy(); -}); - -test(' - renders an input with correct id (specified)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('id')).toBe('y'); -}); - -test(' - renders an input with correct name', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('name')).toBe('x'); -}); - -test(' - renders an input with correct placeholder', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('placeholder')).toBe('y'); -}); - -test(' - renders an input with correct type', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('type')).toBe('text'); -}); - -test(' - renders an input with correct value (default)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('value')).toBe(''); -}); - -test(' - renders an input with correct value (model)', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { model: { x: 'y' } }), - ); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('value')).toBe('y'); -}); - -test(' - renders an input with correct value (specified)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('value')).toBe('y'); -}); - -test(' - renders an input which correctly reacts on change', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { onChange }), - ); - - expect(wrapper.find('input')).toHaveLength(1); - expect( - wrapper.find('input').simulate('change', { target: { value: 'y' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', 'y'); -}); - -test(' - renders an input which correctly reacts on change (empty)', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { onChange }), - ); - - expect(wrapper.find('input')).toHaveLength(1); - expect( - wrapper.find('input').simulate('change', { target: { value: '' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', ''); -}); - -test(' - renders an input which correctly reacts on change (same value)', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { model: { x: 'y' }, onChange }), - ); - - expect(wrapper.find('input')).toHaveLength(1); - expect( - wrapper.find('input').simulate('change', { target: { value: 'y' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', 'y'); -}); - -test(' - renders a label', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('label')).toHaveLength(1); - expect(wrapper.find('label').text()).toBe('y'); - expect(wrapper.find('label').prop('htmlFor')).toBe( - wrapper.find('input').prop('id'), - ); -}); - -test(' - renders a wrapper with unknown props', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('div').at(0).prop('data-x')).toBe('x'); - expect(wrapper.find('div').at(0).prop('data-y')).toBe('y'); - expect(wrapper.find('div').at(0).prop('data-z')).toBe('z'); -}); - -test(' - renders correct error text (specified)', () => { - const error = new Error(); - const element = ( - - ); - const wrapper = mount( - element, - createContext({ x: { type: String, label: '' } }), - ); - - expect(wrapper.children().last().text()).toBe('Error'); -}); - -test(' - renders correct error text (showInlineError=false)', () => { - const error = new Error(); - const element = ( - - ); - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.children().last().text()).not.toBe('Error'); -}); - -test(' - renders a icon', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('i')).toHaveLength(1); -}); - -test(' - renders a icon', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('i')).toHaveLength(1); -}); - -test(' - renders with a custom wrapClassName', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('.ui.input.test-class-name')).toHaveLength(1); -}); - -test(' - renders a input with autocomplete turned off', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input').prop('autoComplete')).toBe('off'); -}); diff --git a/packages/uniforms-semantic/__tests__/index.ts b/packages/uniforms-semantic/__tests__/index.ts index 1c5817f1a..504702cb3 100644 --- a/packages/uniforms-semantic/__tests__/index.ts +++ b/packages/uniforms-semantic/__tests__/index.ts @@ -52,7 +52,10 @@ describe('@RTL', () => { suites.testQuickForm(theme.QuickForm); suites.testRadioField(theme.RadioField); suites.testSubmitField(theme.SubmitField); - suites.testTextField(theme.TextField); + suites.testTextField(theme.TextField, { + testWrapClassName: true, + testRenderIcon: true, + }); suites.testValidatedForm(theme.ValidatedForm); suites.testValidatedQuickForm(theme.ValidatedQuickForm); }); diff --git a/packages/uniforms/__suites__/TextField.tsx b/packages/uniforms/__suites__/TextField.tsx index 01ccf9299..db2905e30 100644 --- a/packages/uniforms/__suites__/TextField.tsx +++ b/packages/uniforms/__suites__/TextField.tsx @@ -12,6 +12,8 @@ type TestTextFieldOptions = { props: PropsWithChildren<{ themeOptions: any }>, ) => JSX.Element; }; + testWrapClassName?: boolean; + testRenderIcon?: boolean; }; export function testTextField( @@ -285,4 +287,29 @@ export function testTextField( expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); }); } + + if (options.testRenderIcon) { + test(' - renders an icon', () => { + const { container } = renderWithZod({ + element: , + schema: z.object({ x: z.string() }), + }); + + expect(container.querySelector('i')).toBeInTheDocument(); + }); + } + + if (options.testWrapClassName) { + test(' - renders with a custom wrapClassName', () => { + const testClassName = 'test-class-name'; + renderWithZod({ + element: , + schema: z.object({ x: z.string() }), + }); + + expect(screen.getByRole('textbox').closest('div')).toHaveClass( + testClassName, + ); + }); + } } From 5b1ba1c8ab04640b35b819d2296f3952b6809e95 Mon Sep 17 00:00:00 2001 From: Adrian Mucha Date: Fri, 9 Feb 2024 18:42:58 +0100 Subject: [PATCH 06/10] Remove uniforms-bootstrap4 uniforms-bootstrap5 TextField enzyme test --- .../__tests__/TextField.tsx | 189 ----------------- .../__tests__/TextField.tsx | 200 ------------------ .../uniforms-bootstrap5/__tests__/index.ts | 5 +- packages/uniforms/__suites__/TextField.tsx | 18 ++ 4 files changed, 22 insertions(+), 390 deletions(-) delete mode 100644 packages/uniforms-bootstrap4/__tests__/TextField.tsx delete mode 100644 packages/uniforms-bootstrap5/__tests__/TextField.tsx diff --git a/packages/uniforms-bootstrap4/__tests__/TextField.tsx b/packages/uniforms-bootstrap4/__tests__/TextField.tsx deleted file mode 100644 index 666bfc861..000000000 --- a/packages/uniforms-bootstrap4/__tests__/TextField.tsx +++ /dev/null @@ -1,189 +0,0 @@ -import { screen } from '@testing-library/react'; -import React from 'react'; -import { TextField } from 'uniforms-bootstrap4'; -import { render } from 'uniforms/__suites__'; - -import createContext from './_createContext'; -import mount from './_mount'; - -describe('@RTL - TextField tests', () => { - test(' - renders a wrapper with unknown props', () => { - const props = { - 'data-x': 'x', - 'data-y': 'y', - 'data-z': 'z', - }; - render(, { x: String }); - - const wrapper = screen.getByRole('textbox').closest('div'); - Object.entries(props).forEach(([key, value]) => - expect(wrapper).toHaveAttribute(key, value), - ); - }); -}); - -test(' - renders an input', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); -}); - -test(' - renders an input with correct disabled state', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('disabled')).toBe(true); -}); - -test(' - renders an input with correct readOnly state', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('readOnly')).toBe(true); -}); - -test(' - renders an input with correct id (inherited)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('id')).toBeTruthy(); -}); - -test(' - renders an input with correct id (specified)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('id')).toBe('y'); -}); - -test(' - renders an input with correct name', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('name')).toBe('x'); -}); - -test(' - renders an input with correct placeholder', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('placeholder')).toBe('y'); -}); - -test(' - renders an input with correct type', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('type')).toBe('text'); -}); - -test(' - renders an input with correct value (default)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('value')).toBe(''); -}); - -test(' - renders an input with correct value (model)', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { model: { x: 'y' } }), - ); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('value')).toBe('y'); -}); - -test(' - renders an input with correct value (specified)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('value')).toBe('y'); -}); - -test(' - renders an input which correctly reacts on change', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { onChange }), - ); - - expect(wrapper.find('input')).toHaveLength(1); - expect( - wrapper.find('input').simulate('change', { target: { value: 'y' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', 'y'); -}); - -test(' - renders an input which correctly reacts on change (empty)', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { onChange }), - ); - - expect(wrapper.find('input')).toHaveLength(1); - expect( - wrapper.find('input').simulate('change', { target: { value: '' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', ''); -}); - -test(' - renders an input which correctly reacts on change (same value)', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { model: { x: 'y' }, onChange }), - ); - - expect(wrapper.find('input')).toHaveLength(1); - expect( - wrapper.find('input').simulate('change', { target: { value: 'y' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', 'y'); -}); - -test(' - renders a label', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('label')).toHaveLength(1); - expect(wrapper.find('label').text()).toBe('y'); - expect(wrapper.find('label').prop('htmlFor')).toBe( - wrapper.find('input').prop('id'), - ); -}); - -test(' - renders a wrapper with unknown props', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('div').at(0).prop('data-x')).toBe('x'); - expect(wrapper.find('div').at(0).prop('data-y')).toBe('y'); - expect(wrapper.find('div').at(0).prop('data-z')).toBe('z'); -}); - -test(' - renders a input with autocomplete turned off', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('div').at(0).prop('autoComplete')).toBeFalsy(); - expect(wrapper.find('input').prop('autoComplete')).toBe('off'); -}); diff --git a/packages/uniforms-bootstrap5/__tests__/TextField.tsx b/packages/uniforms-bootstrap5/__tests__/TextField.tsx deleted file mode 100644 index aee886918..000000000 --- a/packages/uniforms-bootstrap5/__tests__/TextField.tsx +++ /dev/null @@ -1,200 +0,0 @@ -import { screen } from '@testing-library/react'; -import React from 'react'; -import { TextField } from 'uniforms-bootstrap5'; -import { render } from 'uniforms/__suites__'; - -import createContext from './_createContext'; -import mount from './_mount'; - -describe('@RTL - TextField tests', () => { - test(' - renders a wrapper with unknown props', () => { - const props = { - 'data-x': 'x', - 'data-y': 'y', - 'data-z': 'z', - }; - render(, { x: String }); - - const wrapper = screen.getByRole('textbox').closest('div'); - Object.entries(props).forEach(([key, value]) => - expect(wrapper).toHaveAttribute(key, value), - ); - }); -}); - -test(' - renders an input', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); -}); - -test(' - renders an input with correct disabled state', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('disabled')).toBe(true); -}); - -test(' - renders an input with correct readOnly state', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('readOnly')).toBe(true); -}); - -test(' - renders an input with correct id (inherited)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('id')).toBeTruthy(); -}); - -test(' - renders an input with correct id (specified)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('id')).toBe('y'); -}); - -test(' - renders an input with correct name', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('name')).toBe('x'); -}); - -test(' - renders an input with correct placeholder', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('placeholder')).toBe('y'); -}); - -test(' - renders an input with correct type', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('type')).toBe('text'); -}); - -test(' - renders an input with correct value (default)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('value')).toBe(''); -}); - -test(' - renders an input with correct value (model)', () => { - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { model: { x: 'y' } }), - ); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('value')).toBe('y'); -}); - -test(' - renders an input with correct value (specified)', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('input')).toHaveLength(1); - expect(wrapper.find('input').prop('value')).toBe('y'); -}); - -test(' - renders an input which correctly reacts on change', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { onChange }), - ); - - expect(wrapper.find('input')).toHaveLength(1); - expect( - wrapper.find('input').simulate('change', { target: { value: 'y' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', 'y'); -}); - -test(' - renders an input which correctly reacts on change (empty)', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { onChange }), - ); - - expect(wrapper.find('input')).toHaveLength(1); - expect( - wrapper.find('input').simulate('change', { target: { value: '' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', ''); -}); - -test(' - renders an input which correctly reacts on change (same value)', () => { - const onChange = jest.fn(); - - const element = ; - const wrapper = mount( - element, - createContext({ x: { type: String } }, { model: { x: 'y' }, onChange }), - ); - - expect(wrapper.find('input')).toHaveLength(1); - expect( - wrapper.find('input').simulate('change', { target: { value: 'y' } }), - ).toBeTruthy(); - expect(onChange).toHaveBeenLastCalledWith('x', 'y'); -}); - -test(' - renders a label', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('label')).toHaveLength(1); - expect(wrapper.find('label').text()).toBe('y'); - expect(wrapper.find('label').prop('htmlFor')).toBe( - wrapper.find('input').prop('id'), - ); -}); - -test(' - renders a wrapper with unknown props', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('div').at(0).prop('data-x')).toBe('x'); - expect(wrapper.find('div').at(0).prop('data-y')).toBe('y'); - expect(wrapper.find('div').at(0).prop('data-z')).toBe('z'); -}); - -test(' - renders a input with autocomplete turned off', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('div').at(0).prop('autoComplete')).toBeFalsy(); - expect(wrapper.find('input').prop('autoComplete')).toBe('off'); -}); - -test(' - renders a input with minLength and maxLength', () => { - const element = ; - const wrapper = mount(element, createContext({ x: { type: String } })); - - expect(wrapper.find('div').at(0).prop('minLength')).toBeFalsy(); - expect(wrapper.find('input').prop('minLength')).toBe(1); - - expect(wrapper.find('div').at(0).prop('maxLength')).toBeFalsy(); - expect(wrapper.find('input').prop('maxLength')).toBe(10); -}); diff --git a/packages/uniforms-bootstrap5/__tests__/index.ts b/packages/uniforms-bootstrap5/__tests__/index.ts index 66d5c3e3d..3808ade0b 100644 --- a/packages/uniforms-bootstrap5/__tests__/index.ts +++ b/packages/uniforms-bootstrap5/__tests__/index.ts @@ -56,7 +56,10 @@ describe('@RTL', () => { suites.testQuickForm(theme.QuickForm); suites.testRadioField(theme.RadioField); suites.testSubmitField(theme.SubmitField); - suites.testTextField(theme.TextField, { testWrapClassName: true }); + suites.testTextField(theme.TextField, { + testWrapClassName: true, + testMinMaxLength: true, + }); suites.testValidatedForm(theme.ValidatedForm); suites.testValidatedQuickForm(theme.ValidatedQuickForm); }); diff --git a/packages/uniforms/__suites__/TextField.tsx b/packages/uniforms/__suites__/TextField.tsx index db2905e30..0000df799 100644 --- a/packages/uniforms/__suites__/TextField.tsx +++ b/packages/uniforms/__suites__/TextField.tsx @@ -14,6 +14,7 @@ type TestTextFieldOptions = { }; testWrapClassName?: boolean; testRenderIcon?: boolean; + testMinMaxLength?: boolean; }; export function testTextField( @@ -312,4 +313,21 @@ export function testTextField( ); }); } + + if (options.testMinMaxLength) { + test(' - renders a input with minLength and maxLength', () => { + renderWithZod({ + element: , + schema: z.object({ x: z.string() }), + }); + + const inputElement = screen.getByRole('textbox'); + const wrapperElement = inputElement.parentNode; + + expect(inputElement).toHaveAttribute('minLength', '1'); + expect(inputElement).toHaveAttribute('maxLength', '10'); + expect(wrapperElement).not.toHaveAttribute('minLength'); + expect(wrapperElement).not.toHaveAttribute('maxLength'); + }); + } } From 9cd479a9fa1f0eec42b4d0745ab567991ba55c34 Mon Sep 17 00:00:00 2001 From: Adrian Mucha Date: Fri, 9 Feb 2024 18:54:36 +0100 Subject: [PATCH 07/10] Move uniforms-material LongTextField test to suite --- .../__tests__/LongTextField.tsx | 73 ------------------ .../uniforms-material/__tests__/index.tsx | 15 +++- .../uniforms/__suites__/LongTextField.tsx | 74 ++++++++++++++++++- 3 files changed, 87 insertions(+), 75 deletions(-) delete mode 100644 packages/uniforms-material/__tests__/LongTextField.tsx diff --git a/packages/uniforms-material/__tests__/LongTextField.tsx b/packages/uniforms-material/__tests__/LongTextField.tsx deleted file mode 100644 index 9c2708667..000000000 --- a/packages/uniforms-material/__tests__/LongTextField.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import createMuiTheme from '@material-ui/core/styles/createMuiTheme'; -import ThemeProvider from '@material-ui/styles/ThemeProvider/ThemeProvider'; -import React from 'react'; -import { LongTextField } from 'uniforms-material'; -import { renderWithZod } from 'uniforms/__suites__'; -import z from 'zod'; - -describe('@RTL - LongTextField tests', () => { - test(' - default props are not passed when MUI theme props are specified', () => { - const theme = createMuiTheme({ - props: { MuiTextField: { fullWidth: false, margin: 'normal' } }, - }); - - const { container } = renderWithZod({ - element: ( - - - - ), - schema: z.object({ x: z.string() }), - }); - - const elements = container.getElementsByClassName( - 'MuiFormControl-marginNormal', - ); - expect(elements).toHaveLength(1); - expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); - }); - - test(' - default props are passed when MUI theme props are absent', () => { - const theme = createMuiTheme({}); - - const { container } = renderWithZod({ - element: ( - - - - ), - schema: z.object({ x: z.string() }), - }); - - const elements = container.getElementsByClassName( - 'MuiFormControl-marginDense', - ); - expect(elements).toHaveLength(1); - expect(elements[0]).toHaveClass('MuiFormControl-fullWidth'); - }); - - test(' - explicit props are passed when MUI theme props are specified', () => { - const theme = createMuiTheme({ - props: { MuiTextField: { fullWidth: true, margin: 'dense' } }, - }); - const explicitProps = { - fullWidth: false, - margin: 'normal' as const, - }; - - const { container } = renderWithZod({ - element: ( - - - - ), - schema: z.object({ x: z.string() }), - }); - - const elements = container.getElementsByClassName( - 'MuiFormControl-marginNormal', - ); - expect(elements).toHaveLength(1); - expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); - }); -}); diff --git a/packages/uniforms-material/__tests__/index.tsx b/packages/uniforms-material/__tests__/index.tsx index 1415a3a54..4c3012373 100644 --- a/packages/uniforms-material/__tests__/index.tsx +++ b/packages/uniforms-material/__tests__/index.tsx @@ -55,7 +55,20 @@ describe('@RTL', () => { suites.testListField(theme.ListField, { getListAddField: screen => screen.getByText(/\+/), }); - suites.testLongTextField(theme.LongTextField); + suites.testLongTextField(theme.LongTextField, { + testPassThemeProps: { + ThemeProvider({ + themeOptions, + ...props + }: PropsWithChildren<{ themeOptions: ThemeOptions }>) { + return ( + + {props.children} + + ); + }, + }, + }); suites.testNestField(theme.NestField, { skipInMuiTests: true }); suites.testNumField(theme.NumField); suites.testQuickForm(theme.QuickForm); diff --git a/packages/uniforms/__suites__/LongTextField.tsx b/packages/uniforms/__suites__/LongTextField.tsx index 21cad4259..fced6b2e8 100644 --- a/packages/uniforms/__suites__/LongTextField.tsx +++ b/packages/uniforms/__suites__/LongTextField.tsx @@ -1,6 +1,6 @@ import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import React, { ComponentType } from 'react'; +import React, { ComponentType, PropsWithChildren } from 'react'; import z from 'zod'; import { renderWithZod } from './render-zod'; @@ -10,6 +10,11 @@ export function testLongTextField( options?: { skipShowInlineErrorTests?: boolean; testMinMaxLength?: boolean; + testPassThemeProps?: { + ThemeProvider: ( + props: PropsWithChildren<{ themeOptions: any }>, + ) => JSX.Element; + }; }, ) { test(' - renders a textarea with correct disabled state', () => { @@ -135,6 +140,73 @@ export function testLongTextField( }); } + if (options?.testPassThemeProps) { + const { ThemeProvider } = options.testPassThemeProps; + + test(' - default props are not passed when MUI theme props are specified', () => { + const themeOptions = { + props: { MuiTextField: { fullWidth: false, margin: 'normal' } }, + }; + const { container } = renderWithZod({ + element: ( + + + + ), + schema: z.object({ x: z.string() }), + }); + + const elements = container.getElementsByClassName( + 'MuiFormControl-marginNormal', + ); + expect(elements).toHaveLength(1); + expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); + }); + + test(' - default props are passed when MUI theme props are absent', () => { + const themeOptions = {}; + const { container } = renderWithZod({ + element: ( + + + + ), + schema: z.object({ x: z.string() }), + }); + + const elements = container.getElementsByClassName( + 'MuiFormControl-marginDense', + ); + expect(elements).toHaveLength(1); + expect(elements[0]).toHaveClass('MuiFormControl-fullWidth'); + }); + + test(' - explicit props are passed when MUI theme props are specified', () => { + const themeOptions = { + props: { MuiTextField: { fullWidth: true, margin: 'dense' } }, + }; + const explicitProps = { + fullWidth: false, + margin: 'normal' as const, + }; + + const { container } = renderWithZod({ + element: ( + + + + ), + schema: z.object({ x: z.string() }), + }); + + const elements = container.getElementsByClassName( + 'MuiFormControl-marginNormal', + ); + expect(elements).toHaveLength(1); + expect(elements[0]).not.toHaveClass('MuiFormControl-fullWidth'); + }); + } + if (options?.testMinMaxLength) { test(' - renders a textarea with minLength and maxLength', () => { renderWithZod({ From a1f0cfab62db79d6a7f303e55aa8faeb71888f1e Mon Sep 17 00:00:00 2001 From: Adrian Mucha Date: Tue, 20 Feb 2024 14:40:53 +0100 Subject: [PATCH 08/10] Cover iconLeft test --- packages/uniforms/__suites__/TextField.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/uniforms/__suites__/TextField.tsx b/packages/uniforms/__suites__/TextField.tsx index 0000df799..9040865f4 100644 --- a/packages/uniforms/__suites__/TextField.tsx +++ b/packages/uniforms/__suites__/TextField.tsx @@ -292,7 +292,15 @@ export function testTextField( if (options.testRenderIcon) { test(' - renders an icon', () => { const { container } = renderWithZod({ - element: , + element: , + schema: z.object({ x: z.string() }), + }); + + expect(container.querySelector('i')).toBeInTheDocument(); + }); + test(' - renders an iconLeft', () => { + const { container } = renderWithZod({ + element: , schema: z.object({ x: z.string() }), }); From 2a4f8f1d81e853ce6659a3bb8a3fb9a7d73e9396 Mon Sep 17 00:00:00 2001 From: Adrian Mucha Date: Tue, 20 Feb 2024 14:48:30 +0100 Subject: [PATCH 09/10] Test showInlineError semantic --- packages/uniforms-semantic/__tests__/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/uniforms-semantic/__tests__/index.ts b/packages/uniforms-semantic/__tests__/index.ts index 504702cb3..8d447a64d 100644 --- a/packages/uniforms-semantic/__tests__/index.ts +++ b/packages/uniforms-semantic/__tests__/index.ts @@ -55,6 +55,7 @@ describe('@RTL', () => { suites.testTextField(theme.TextField, { testWrapClassName: true, testRenderIcon: true, + testShowInlineError: true, }); suites.testValidatedForm(theme.ValidatedForm); suites.testValidatedQuickForm(theme.ValidatedQuickForm); From 6e7e92df92a44b9651950329f4bd165385807be9 Mon Sep 17 00:00:00 2001 From: Adrian Mucha Date: Tue, 20 Feb 2024 14:59:12 +0100 Subject: [PATCH 10/10] Test showInlineError material --- packages/uniforms-material/__tests__/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/uniforms-material/__tests__/index.tsx b/packages/uniforms-material/__tests__/index.tsx index 4c3012373..f574b876e 100644 --- a/packages/uniforms-material/__tests__/index.tsx +++ b/packages/uniforms-material/__tests__/index.tsx @@ -75,6 +75,7 @@ describe('@RTL', () => { suites.testRadioField(theme.RadioField); suites.testSubmitField(theme.SubmitField); suites.testTextField(theme.TextField, { + testShowInlineError: true, testPassThemeProps: { ThemeProvider({ themeOptions,