import React from 'react';
import { fireEvent, render, screen } from '@testing-library/react';
import { NumberInput } from '../NumberInput';
import userEvent from '@testing-library/user-event';
describe('numberInput', () => {
test('renders defaults & extra props', () => {
const { asFragment } = render();
expect(asFragment()).toMatchSnapshot();
});
test('renders success validated', () => {
const { asFragment } = render();
expect(asFragment()).toMatchSnapshot();
});
test('renders error validated', () => {
const { asFragment } = render();
expect(asFragment()).toMatchSnapshot();
});
test('renders warning validated', () => {
const { asFragment } = render();
expect(asFragment()).toMatchSnapshot();
});
test('renders value', () => {
const { asFragment } = render();
expect(asFragment()).toMatchSnapshot();
});
test('renders disabled', () => {
const { asFragment } = render();
expect(asFragment()).toMatchSnapshot();
});
test('disables lower threshold', () => {
const { asFragment } = render();
expect(asFragment()).toMatchSnapshot();
});
test('disables upper threshold', () => {
const { asFragment } = render();
expect(asFragment()).toMatchSnapshot();
});
test('renders unit', () => {
const { asFragment } = render();
expect(asFragment()).toMatchSnapshot();
});
test('renders unit & position', () => {
const { asFragment } = render();
expect(asFragment()).toMatchSnapshot();
});
test('renders custom width', () => {
const { asFragment } = render();
expect(asFragment()).toMatchSnapshot();
});
test('passes input props successfully', () => {
const { asFragment } = render();
expect(asFragment()).toMatchSnapshot();
});
test('passes button props successfully', () => {
const { asFragment } = render(
);
expect(asFragment()).toMatchSnapshot();
});
test('renders negative value', () => {
render();
expect(screen.getByDisplayValue('-999')).toBeInTheDocument();
});
test('renders decimal value', () => {
render();
expect(screen.getByDisplayValue('5.5')).toBeInTheDocument();
});
test('renders negative decimal value', () => {
render();
expect(screen.getByDisplayValue('-5.2')).toBeInTheDocument();
});
test('does not call onChange callback when the input does not change', () => {
const onChangeMock = jest.fn();
render(5);
expect(onChangeMock).not.toHaveBeenCalled();
});
test('calls onChange callback when input changes', async () => {
const onChangeMock = jest.fn();
const user = userEvent.setup();
render(55);
const input = screen.getByRole('spinbutton');
await user.type(input, '55');
expect(onChangeMock).toHaveBeenCalledTimes(2);
});
test('does not call onBlur callback when input does not lose focus', async () => {
const onBlurMock = jest.fn();
const user = userEvent.setup();
render(5);
const input = screen.getByRole('spinbutton');
await user.click(input);
expect(onBlurMock).not.toHaveBeenCalled();
});
test('calls onBlur callback when input loses focus', async () => {
const onBlurMock = jest.fn();
const user = userEvent.setup();
render(5);
const input = screen.getByRole('spinbutton');
await user.click(input);
await user.click(document.body);
expect(onBlurMock).toHaveBeenCalledTimes(1);
});
test('removes leading zeros from a positive whole number', async () => {
const user = userEvent.setup();
render( {}} />);
const input = screen.getByRole('spinbutton');
await user.click(input);
// fireEvent is used here due to an issue with the current version of userEvent where userEvent.type/.keyboard does
// not appear to cause the '0' to be properly added to the input's display value
fireEvent.change(input, { target: { value: '010' } });
expect(input).toHaveDisplayValue('010');
await user.click(document.body);
expect(input).toHaveDisplayValue('10');
});
test('removes leading zeros from a negative whole number', async () => {
const user = userEvent.setup();
render( {}} />);
const input = screen.getByRole('spinbutton');
await user.click(input);
// fireEvent is used here due to an issue with the current version of userEvent where userEvent.type/.keyboard does
// not appear to cause the '0' to be properly added to the input's display value
fireEvent.change(input, { target: { value: '-018' } });
expect(input).toHaveDisplayValue('-018');
await user.click(document.body);
expect(input).toHaveDisplayValue('-18');
});
test('removes leading zeros from a decimal number', async () => {
const user = userEvent.setup();
render( {}} />);
const input = screen.getByRole('spinbutton');
await user.click(input);
// fireEvent is used here due to an issue with the current version of userEvent where userEvent.type/.keyboard does
// not appear to cause the '0' to be properly added to the input's display value
fireEvent.change(input, { target: { value: '047.01' } });
expect(input).toHaveDisplayValue('047.01');
await user.click(document.body);
expect(input).toHaveDisplayValue('47.01');
});
test('renders 0 (default value) if no value passed', () => {
render();
const input = screen.getByRole('spinbutton');
expect(input).toHaveDisplayValue('0');
});
test('renders 0 (default value) if undefined value passed', () => {
render();
const input = screen.getByRole('spinbutton');
expect(input).toHaveDisplayValue('0');
});
test('renders 0 if null value passed', () => {
render();
const input = screen.getByRole('spinbutton');
expect(input).toHaveDisplayValue('');
});
test('does not throw an error if onChange is passed via inputProps as well as the onChange prop', () => {
const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
const NumberInputWrapper = () => {
const [value, setValue] = React.useState(0);
const onChange = event => setValue(event.currentTarget.value);
const inputProps = { onChange: onChange };
return ;
};
render();
const input = screen.getByRole('spinbutton');
userEvent.type(input, '0');
expect(consoleSpy).not.toHaveBeenCalled();
});
test('input is read only if onChange not passed ', () => {
render();
const input = screen.getByLabelText('readonly input');
expect(input).toHaveAttribute('readOnly');
});
test('input is not read only if onChange passed ', () => {
const onChangeMock = jest.fn();
render();
const input = screen.getByLabelText('not readonly input');
expect(input).not.toHaveAttribute('readOnly');
});
});