Skip to content

Commit 160390d

Browse files
committed
feat(withErrorIfNeeded): add new hoc for easier error handling
1 parent ad5066a commit 160390d

2 files changed

Lines changed: 81 additions & 0 deletions

File tree

src/__tests__/withErrorIfNeeded.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import React from "react";
2+
import { compose } from "recompose";
3+
import { TextInput } from "react-native";
4+
import { mount } from "enzyme";
5+
6+
import { withErrorNew as withErrorIfNeeded } from "../..";
7+
import withFormikMock from "../testUtils/withFormikMock";
8+
9+
console.error = jest.fn();
10+
11+
const TOUCHED_INPUT_NAME = "TOUCHED_INPUT_NAME";
12+
const TOUCHED_INPUT_ERROR = "TOUCHED_INPUT_ERROR";
13+
const UNTOUCHED_INPUT_NAME = "UNTOUCHED_INPUT_NAME";
14+
const UNTOUCHED_INPUT_ERROR = "UNTOUCHED_INPUT_ERROR";
15+
16+
const formikContext = {
17+
errors: {
18+
[TOUCHED_INPUT_NAME]: TOUCHED_INPUT_ERROR,
19+
[UNTOUCHED_INPUT_NAME]: UNTOUCHED_INPUT_ERROR
20+
},
21+
touched: {
22+
[TOUCHED_INPUT_NAME]: true
23+
},
24+
submitCount: 0
25+
};
26+
const Input = compose(
27+
withFormikMock(formikContext),
28+
withErrorIfNeeded
29+
)(TextInput);
30+
31+
const testInputError = (inputName, expectedError) => {
32+
const input = mount(<Input name={inputName} />);
33+
expect(input.find(TextInput).props().error).toEqual(expectedError);
34+
};
35+
36+
describe("withError", () => {
37+
it("displays error for all inputs if the form is submitted", () => {
38+
formikContext.submitCount = 1;
39+
testInputError(UNTOUCHED_INPUT_NAME, UNTOUCHED_INPUT_ERROR);
40+
testInputError("valid input", undefined);
41+
});
42+
43+
it("displays error for touched inputs if the form is not submitted", () => {
44+
formikContext.submitCount = 0;
45+
testInputError(UNTOUCHED_INPUT_NAME, undefined);
46+
testInputError(TOUCHED_INPUT_NAME, TOUCHED_INPUT_ERROR);
47+
});
48+
49+
it("keeps other props", () => {
50+
const wrapper = mount(<Input name="inputName" someProp="someValue" />);
51+
expect(wrapper.find(TextInput).props().someProp).toEqual("someValue");
52+
});
53+
54+
it("allows overriding error prop", () => {
55+
const erroredInput = mount(
56+
<Input name={TOUCHED_INPUT_NAME} error="override!!" />
57+
);
58+
expect(erroredInput.find(TextInput).props().error).toEqual("override!!");
59+
});
60+
});

src/withErrorIfNeeded.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { compose, mapProps } from "recompose";
2+
import { connect } from "formik";
3+
import withError from "./withError";
4+
import withTouched from "./withTouched";
5+
6+
const withErrorIfNeeded = compose(
7+
withError,
8+
withTouched,
9+
connect,
10+
mapProps(({ formik: { submitCount }, error, touched, ...props }) => {
11+
const shouldDisplayError = touched || submitCount > 0;
12+
13+
return {
14+
touched,
15+
error: shouldDisplayError ? error : undefined,
16+
...props
17+
};
18+
})
19+
);
20+
21+
export default withErrorIfNeeded;

0 commit comments

Comments
 (0)