Skip to content

Commit 295de5c

Browse files
committed
Add test case for validation bug
1 parent f2fa330 commit 295de5c

File tree

5 files changed

+35
-17
lines changed

5 files changed

+35
-17
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-validify",
3-
"version": "5.7.7",
3+
"version": "5.7.8",
44
"description": "Form validation made easy",
55
"main": "dist/index.js",
66
"module": "lib/index.js",

src/form.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type Context = {
1717
hasBlurred: (name: string) => any;
1818
setErrors: Dispatch<SetStateAction<Error[]>>;
1919
updateValue: (name: string, value: string) => any;
20+
setValuesBlurred: Dispatch<SetStateAction<ValuesBlurred>>;
2021
};
2122

2223
const FormContext = React.createContext<Context>({} as Context);
@@ -45,6 +46,7 @@ function Form<Values>({
4546
errors,
4647
setErrors,
4748
valuesBlurred,
49+
setValuesBlurred,
4850
hasBlurred: name => {
4951
if (valuesBlurred[name]) return;
5052
//Store list of values that have been touched, so we can run validation on them now

src/use-submit.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,27 @@ import validate from './validate';
33
import { FormContext } from './form';
44

55
const useSubmit = () => {
6-
const { rules, values, errors, setErrors } = React.useContext(FormContext);
6+
const {
7+
rules,
8+
values,
9+
errors,
10+
setErrors,
11+
setValuesBlurred,
12+
} = React.useContext(FormContext);
713

814
const handleSubmit = (callback: (values: any) => any) => {
915
let errors = validate({
1016
values,
1117
rules,
1218
setErrors,
1319
});
14-
if (!errors.length) callback(values);
20+
if (!errors.length) return callback(values);
21+
22+
// if there are errors, mark all values as blurred,
23+
// so validation runs on change after hitting submit
24+
setValuesBlurred(
25+
Object.keys(rules).reduce((acc, name) => ({ ...acc, [name]: true }), {}),
26+
);
1527
};
1628

1729
return {

src/validate.ts

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,11 @@ type Props = {
77
values: any;
88
rules: { [key: string]: RuleFn[] };
99
setErrors: Dispatch<SetStateAction<Error[]>>;
10-
errors?: Error[];
1110
valuesBlurred?: { [key: string]: boolean };
1211
};
1312

14-
export default ({
15-
values,
16-
rules,
17-
errors = [],
18-
setErrors,
19-
valuesBlurred,
20-
}: Props) => {
13+
export default ({ values, rules, setErrors }: Props) => {
2114
let newErrors = Object.keys(rules)
22-
.filter(rule => {
23-
if (errors.filter(error => error.name === rule).length) return true;
24-
if (valuesBlurred) return valuesBlurred[rule];
25-
26-
return true;
27-
})
2815
.map(field =>
2916
rules[field].map(rule => {
3017
let error = rule(get(values, field) || '', values);

tests/form.test.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,20 @@ test('Empty input value gets passed as empty string to rule fn', async () => {
147147
expect(spy.mock.calls[0][0]).toEqual('');
148148
expect(spy.mock.calls[0][1]).toEqual({ email: 'test' });
149149
});
150+
151+
test('Field validation runs on change, after submitting', async () => {
152+
let { queryByPlaceholderText, getByText } = render(<TestForm />);
153+
const name = queryByPlaceholderText('name');
154+
155+
//trigger submit
156+
getByText('Submit Form').click();
157+
158+
//change name to something valid
159+
fireEvent.change(name, { target: { value: 'testing' } });
160+
161+
// change it back to invalid, and make sure the validation is shown
162+
fireEvent.change(name, { target: { value: '' } });
163+
164+
//ensure the validation shows up
165+
expect(getByText('This field is required')).toBeInTheDocument();
166+
});

0 commit comments

Comments
 (0)