Fix NumberInput empty values (#57142)

* Fix NumberInput empty values

* tests

* tests
This commit is contained in:
Victor Marin 2022-10-18 16:59:34 +03:00 committed by GitHub
parent 71f79b9de0
commit e91135cf19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 127 additions and 19 deletions

View File

@ -0,0 +1,110 @@
import { render, screen, fireEvent } from '@testing-library/react';
import React from 'react';
import { NumberInput } from './NumberInput';
const setup = (min?: number, max?: number) => {
const onChange = jest.fn();
render(<NumberInput value={15} onChange={onChange} max={max} min={min} />);
return {
input: screen.getByTestId('input-wrapper').firstChild?.firstChild as HTMLInputElement,
onChange,
};
};
describe('NumberInput', () => {
it('updated input correctly', () => {
const data = setup();
const tests = [
{
value: '-10',
expected: -10,
onChangeCalledWith: -10,
},
{
value: '',
expected: null,
onChangeCalledWith: undefined,
},
{
value: '100',
expected: 100,
onChangeCalledWith: 100,
},
{
value: '1asd',
expected: null,
onChangeCalledWith: undefined,
},
{
value: -100,
expected: -100,
onChangeCalledWith: -100,
},
{
value: 20,
expected: 20,
onChangeCalledWith: 20,
},
{
value: 0,
expected: 0,
onChangeCalledWith: 0,
},
{
value: '0',
expected: 0,
onChangeCalledWith: 0,
},
];
tests.forEach((test, i) => {
fireEvent.blur(data.input, { target: { value: test.value } });
expect(data.onChange).toBeCalledWith(test.onChangeCalledWith);
expect(data.onChange).toBeCalledTimes(i + 1);
expect(data.input).toHaveValue(test.expected);
});
});
it('corrects input as per min and max', async () => {
const data = setup(-10, 10);
let input = data.input;
const tests = [
{
value: '-10',
expected: -10,
onChangeCalledWith: -10,
},
{
value: '-100',
expected: -10,
onChangeCalledWith: -10,
},
{
value: '10',
expected: 10,
onChangeCalledWith: 10,
},
{
value: '100',
expected: 10,
onChangeCalledWith: 10,
},
{
value: '5',
expected: 5,
onChangeCalledWith: 5,
},
];
tests.forEach((test, i) => {
input = screen.getByTestId('input-wrapper').firstChild?.firstChild as HTMLInputElement;
fireEvent.blur(input, { target: { value: test.value } });
expect(data.onChange).toBeCalledWith(test.onChangeCalledWith);
expect(data.onChange).toBeCalledTimes(i + 1);
expect(screen.getByTestId('input-wrapper').firstChild?.firstChild).toHaveValue(test.expected);
});
});
});

View File

@ -50,33 +50,31 @@ export class NumberInput extends PureComponent<Props, State> {
let newValue = ''; let newValue = '';
const min = this.props.min; const min = this.props.min;
const max = this.props.max; const max = this.props.max;
const currentValue = txt && +txt; let currentValue = txt !== '' ? Number(txt) : undefined;
if (currentValue) { if (currentValue && !Number.isNaN(currentValue)) {
if (!Number.isNaN(currentValue)) { if (min != null && currentValue < min) {
if (min != null && currentValue < min) { newValue = min.toString();
newValue = min.toString(); corrected = true;
corrected = true; } else if (max != null && currentValue > max) {
} else if (max != null && currentValue > max) { newValue = max.toString();
newValue = max.toString(); corrected = true;
corrected = true; } else {
} else { newValue = txt ?? '';
newValue = txt;
}
} }
this.setState({ this.setState({
text: newValue || '', text: newValue,
inputCorrected: corrected, inputCorrected: corrected,
}); });
}
if (corrected) { if (corrected) {
this.updateValueDebounced(); this.updateValueDebounced();
} }
if (!isNaN(currentValue) && currentValue !== this.props.value) { if (!Number.isNaN(currentValue) && currentValue !== this.props.value) {
this.props.onChange(currentValue); this.props.onChange(currentValue);
}
} }
}; };