@coxy/react-validator 1.3.3 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +1 -1
- package/.eslintrc.js +25 -8
- package/CHANGELOG.md +6 -0
- package/README.md +15 -15
- package/babel.config.js +3 -0
- package/dist/context.d.ts +5 -0
- package/dist/context.js +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +13 -0
- package/dist/rules.d.ts +37 -0
- package/dist/rules.js +43 -0
- package/dist/use-validator.d.ts +3 -0
- package/dist/use-validator.js +22 -0
- package/dist/validator-field.d.ts +25 -0
- package/dist/validator-field.jsx +34 -0
- package/dist/validator-wrapper.d.ts +17 -0
- package/dist/validator-wrapper.jsx +43 -0
- package/dist/validator.d.ts +28 -0
- package/dist/validator.js +72 -0
- package/example/example.jsx +29 -26
- package/example/index.html +2 -0
- package/example/webpack.config.js +15 -7
- package/jest.config.ts +10 -0
- package/package.json +34 -27
- package/src/context.test.ts +7 -0
- package/src/context.ts +6 -0
- package/src/index.test.ts +7 -0
- package/src/index.ts +5 -0
- package/src/jest.d.ts +1 -0
- package/src/rules.test.ts +127 -0
- package/src/{rules.js → rules.ts} +26 -15
- package/src/use-validator.test.tsx +58 -0
- package/src/use-validator.ts +10 -0
- package/src/validator-field.test.tsx +161 -0
- package/src/validator-field.tsx +71 -0
- package/src/validator-wrapper.test.tsx +138 -0
- package/src/validator-wrapper.tsx +58 -0
- package/src/validator.test.tsx +30 -0
- package/src/validator.ts +105 -0
- package/tsconfig.build.json +12 -0
- package/tsconfig.json +39 -0
- package/.babelrc.js +0 -14
- package/build/index.js +0 -1
- package/jest.config.js +0 -5
- package/src/context.js +0 -3
- package/src/context.test.js +0 -9
- package/src/index.js +0 -13
- package/src/index.test.js +0 -9
- package/src/rules.test.js +0 -130
- package/src/use-validator.js +0 -8
- package/src/use-validator.test.js +0 -52
- package/src/validator-field.jsx +0 -72
- package/src/validator-field.test.js +0 -187
- package/src/validator-wrapper.jsx +0 -63
- package/src/validator-wrapper.test.js +0 -174
- package/src/validator.js +0 -82
- package/src/validator.test.js +0 -36
- package/webpack.config.js +0 -32
package/src/validator-field.jsx
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
/* eslint react/jsx-props-no-spreading: [0], react/sort-comp: [0], camelcase: [0] */
|
|
2
|
-
import React, { Component } from 'react';
|
|
3
|
-
import PropTypes from 'prop-types';
|
|
4
|
-
import Context from './context';
|
|
5
|
-
import { Field } from './validator';
|
|
6
|
-
|
|
7
|
-
class ValidationFieldWrapper extends Component {
|
|
8
|
-
componentWillUnmount() {
|
|
9
|
-
this.props.unregisterField(this);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
componentDidMount() {
|
|
13
|
-
this.props.registerField(this);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
validate() {
|
|
17
|
-
const field = new Field({
|
|
18
|
-
rules: this.props.rules,
|
|
19
|
-
required: this.props.required,
|
|
20
|
-
value: this.props.value,
|
|
21
|
-
id: this.props.id,
|
|
22
|
-
});
|
|
23
|
-
return field.validate();
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
render() {
|
|
27
|
-
const { children, value } = this.props;
|
|
28
|
-
const validity = this.validate();
|
|
29
|
-
return (typeof children === 'function' ? children(validity, value) : children);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export default function ValidationField(props) {
|
|
34
|
-
return (
|
|
35
|
-
<Context.Consumer>
|
|
36
|
-
{(data) => (
|
|
37
|
-
<ValidationFieldWrapper
|
|
38
|
-
{...props}
|
|
39
|
-
registerField={data.registerField}
|
|
40
|
-
unregisterField={data.unregisterField}
|
|
41
|
-
/>
|
|
42
|
-
)}
|
|
43
|
-
</Context.Consumer>
|
|
44
|
-
);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
ValidationFieldWrapper.propTypes = {
|
|
48
|
-
// from context
|
|
49
|
-
registerField: PropTypes.func.isRequired,
|
|
50
|
-
unregisterField: PropTypes.func.isRequired,
|
|
51
|
-
|
|
52
|
-
children: PropTypes.oneOfType([
|
|
53
|
-
PropTypes.node,
|
|
54
|
-
PropTypes.func,
|
|
55
|
-
]),
|
|
56
|
-
rules: PropTypes.arrayOf(PropTypes.shape({
|
|
57
|
-
message: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
|
|
58
|
-
rule: PropTypes.func,
|
|
59
|
-
})),
|
|
60
|
-
|
|
61
|
-
id: PropTypes.string,
|
|
62
|
-
required: PropTypes.bool,
|
|
63
|
-
value: PropTypes.any, // eslint-disable-line
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
ValidationFieldWrapper.defaultProps = {
|
|
67
|
-
rules: [],
|
|
68
|
-
children: null,
|
|
69
|
-
required: true,
|
|
70
|
-
value: undefined,
|
|
71
|
-
id: '',
|
|
72
|
-
};
|
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
/* eslint-env jest */
|
|
2
|
-
/* globals shallow */
|
|
3
|
-
/* eslint react/jsx-filename-extension: [0] */
|
|
4
|
-
|
|
5
|
-
import React from 'react';
|
|
6
|
-
import { render, unmountComponentAtNode } from 'react-dom';
|
|
7
|
-
import { act } from 'react-dom/test-utils';
|
|
8
|
-
|
|
9
|
-
import ValidatorWrapper from './validator-wrapper';
|
|
10
|
-
import ValidatorField from './validator-field';
|
|
11
|
-
import rules from './rules';
|
|
12
|
-
|
|
13
|
-
let container = null;
|
|
14
|
-
beforeEach(() => {
|
|
15
|
-
container = document.createElement('div');
|
|
16
|
-
document.body.appendChild(container);
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
afterEach(() => {
|
|
20
|
-
unmountComponentAtNode(container);
|
|
21
|
-
container.remove();
|
|
22
|
-
container = null;
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it('render without wrapper', () => {
|
|
26
|
-
expect(() => shallow(<ValidatorField />)).toThrowError();
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('normal render', () => {
|
|
30
|
-
act(() => {
|
|
31
|
-
render((
|
|
32
|
-
<ValidatorWrapper>
|
|
33
|
-
<ValidatorField rules={[]} value="" />
|
|
34
|
-
</ValidatorWrapper>
|
|
35
|
-
), container);
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('check context validator', () => {
|
|
40
|
-
const validator = React.createRef();
|
|
41
|
-
act(() => {
|
|
42
|
-
render((
|
|
43
|
-
<ValidatorWrapper ref={validator}>
|
|
44
|
-
<ValidatorField rules={[]} />
|
|
45
|
-
</ValidatorWrapper>
|
|
46
|
-
), container);
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
const validateResult = validator.current.validate();
|
|
50
|
-
|
|
51
|
-
expect(validateResult.isValid).toBe(true);
|
|
52
|
-
expect(validateResult.message).toBe('');
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('check failed validation', () => {
|
|
56
|
-
const validator1 = React.createRef();
|
|
57
|
-
act(() => {
|
|
58
|
-
render((
|
|
59
|
-
<ValidatorWrapper ref={validator1}>
|
|
60
|
-
<ValidatorField rules={rules.email} value="test" />
|
|
61
|
-
</ValidatorWrapper>
|
|
62
|
-
), container);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
const validateResult1 = validator1.current.validate();
|
|
66
|
-
|
|
67
|
-
expect(validateResult1.isValid).toBe(false);
|
|
68
|
-
expect(validateResult1.message).toBe('Email is invalid');
|
|
69
|
-
expect(validateResult1.errors.length).toBe(1);
|
|
70
|
-
|
|
71
|
-
const validator2 = React.createRef();
|
|
72
|
-
act(() => {
|
|
73
|
-
render((
|
|
74
|
-
<ValidatorWrapper ref={validator2}>
|
|
75
|
-
<ValidatorField rules={rules.email} value="" />
|
|
76
|
-
</ValidatorWrapper>
|
|
77
|
-
), container);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
const validateResult2 = validator2.current.validate();
|
|
81
|
-
|
|
82
|
-
expect(validateResult2.isValid).toBe(false);
|
|
83
|
-
expect(validateResult2.message).toBe('Email is required');
|
|
84
|
-
expect(validateResult2.errors.length).toBe(1);
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
jest.useFakeTimers();
|
|
88
|
-
|
|
89
|
-
it('check state change and hide field', () => {
|
|
90
|
-
const validator1 = React.createRef();
|
|
91
|
-
function Comp() {
|
|
92
|
-
const [st, setSt] = React.useState(true);
|
|
93
|
-
|
|
94
|
-
React.useEffect(() => {
|
|
95
|
-
setTimeout(() => {
|
|
96
|
-
act(() => {
|
|
97
|
-
setSt(false);
|
|
98
|
-
});
|
|
99
|
-
}, 100);
|
|
100
|
-
}, []);
|
|
101
|
-
|
|
102
|
-
return (
|
|
103
|
-
<ValidatorWrapper ref={validator1}>
|
|
104
|
-
<ValidatorField rules={rules.email} value="test" />
|
|
105
|
-
{st && (
|
|
106
|
-
<ValidatorField rules={rules.email} value="" />
|
|
107
|
-
)}
|
|
108
|
-
</ValidatorWrapper>
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
act(() => {
|
|
113
|
-
render(<Comp />, container);
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
jest.runAllTimers();
|
|
117
|
-
|
|
118
|
-
const validateResult1 = validator1.current.validate();
|
|
119
|
-
|
|
120
|
-
expect(validateResult1.isValid).toBe(false);
|
|
121
|
-
expect(validateResult1.message).toBe('Email is invalid');
|
|
122
|
-
expect(validateResult1.errors.length).toBe(1);
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
it('check success validation', () => {
|
|
126
|
-
const validator = React.createRef();
|
|
127
|
-
act(() => {
|
|
128
|
-
render((
|
|
129
|
-
<ValidatorWrapper ref={validator}>
|
|
130
|
-
<ValidatorField rules={rules.email} value="email@email.com" />
|
|
131
|
-
</ValidatorWrapper>
|
|
132
|
-
), container);
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
const validateResult = validator.current.validate();
|
|
136
|
-
|
|
137
|
-
expect(validateResult.isValid).toBe(true);
|
|
138
|
-
expect(validateResult.message).toBe('');
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
it('check success validation fot child function', () => {
|
|
142
|
-
const validator = React.createRef();
|
|
143
|
-
act(() => {
|
|
144
|
-
render((
|
|
145
|
-
<ValidatorWrapper ref={validator}>
|
|
146
|
-
<ValidatorField rules={rules.email} value="email@email.com">
|
|
147
|
-
{({ isValid, message }) => (
|
|
148
|
-
<>
|
|
149
|
-
{!isValid && <div>{message}</div>}
|
|
150
|
-
</>
|
|
151
|
-
)}
|
|
152
|
-
</ValidatorField>
|
|
153
|
-
</ValidatorWrapper>
|
|
154
|
-
), container);
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
const validateResult = validator.current.validate();
|
|
158
|
-
|
|
159
|
-
expect(validateResult.isValid).toBe(true);
|
|
160
|
-
expect(validateResult.message).toBe('');
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
it('check custom rule message function', () => {
|
|
164
|
-
const validator = React.createRef();
|
|
165
|
-
const rule = [{
|
|
166
|
-
rule: (value) => value !== 'test',
|
|
167
|
-
message: (value) => `test message ${value}`,
|
|
168
|
-
}];
|
|
169
|
-
act(() => {
|
|
170
|
-
render((
|
|
171
|
-
<ValidatorWrapper ref={validator}>
|
|
172
|
-
<ValidatorField rules={rule} value="test">
|
|
173
|
-
{({ isValid, message }) => (
|
|
174
|
-
<>
|
|
175
|
-
{!isValid && <div>{message}</div>}
|
|
176
|
-
</>
|
|
177
|
-
)}
|
|
178
|
-
</ValidatorField>
|
|
179
|
-
</ValidatorWrapper>
|
|
180
|
-
), container);
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
const validateResult = validator.current.validate();
|
|
184
|
-
|
|
185
|
-
expect(validateResult.isValid).toBe(false);
|
|
186
|
-
expect(validateResult.message).toBe('test message test');
|
|
187
|
-
});
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/* eslint react/sort-comp: [0], camelcase: [0] */
|
|
2
|
-
import React, { Component } from 'react';
|
|
3
|
-
import PropTypes from 'prop-types';
|
|
4
|
-
import Context from './context';
|
|
5
|
-
import Validator from './validator';
|
|
6
|
-
|
|
7
|
-
class ValidatorWrapper extends Component {
|
|
8
|
-
fields = [];
|
|
9
|
-
|
|
10
|
-
constructor(...args) {
|
|
11
|
-
super(...args);
|
|
12
|
-
this.registerField = this.registerField.bind(this);
|
|
13
|
-
this.unregisterField = this.unregisterField.bind(this);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
componentWillUnmount() {
|
|
17
|
-
this.fields = [];
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
registerField(field) {
|
|
21
|
-
if (field && !this.fields.includes(field)) {
|
|
22
|
-
this.fields.push(field);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
unregisterField(field) {
|
|
27
|
-
const index = this.fields.indexOf(field);
|
|
28
|
-
if (index > -1) this.fields.splice(index, 1);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
getField(id) {
|
|
32
|
-
return this.fields.find((field) => field.props.id === id) || null;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
validate() {
|
|
36
|
-
const validator = new Validator({ stopAtFirstError: this.props.stopAtFirstError });
|
|
37
|
-
this.fields.forEach((comp) => {
|
|
38
|
-
validator.addField(comp.props);
|
|
39
|
-
});
|
|
40
|
-
return validator.validate();
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
render() {
|
|
44
|
-
return (
|
|
45
|
-
<Context.Provider
|
|
46
|
-
value={{ registerField: this.registerField, unregisterField: this.unregisterField }}
|
|
47
|
-
>
|
|
48
|
-
{this.props.children}
|
|
49
|
-
</Context.Provider>
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
ValidatorWrapper.propTypes = {
|
|
55
|
-
children: PropTypes.node.isRequired,
|
|
56
|
-
stopAtFirstError: PropTypes.bool,
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
ValidatorWrapper.defaultProps = {
|
|
60
|
-
stopAtFirstError: false,
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
export default ValidatorWrapper;
|
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
/* eslint-env jest */
|
|
2
|
-
/* globals shallow */
|
|
3
|
-
/* eslint react/jsx-filename-extension: [0] */
|
|
4
|
-
import React from 'react';
|
|
5
|
-
import { render, unmountComponentAtNode } from 'react-dom';
|
|
6
|
-
import { act } from 'react-dom/test-utils';
|
|
7
|
-
|
|
8
|
-
import ValidatorWrapper from './validator-wrapper';
|
|
9
|
-
import ValidatorField from './validator-field';
|
|
10
|
-
import rules from './rules';
|
|
11
|
-
|
|
12
|
-
let container = null;
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
container = document.createElement('div');
|
|
15
|
-
document.body.appendChild(container);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
afterEach(() => {
|
|
19
|
-
unmountComponentAtNode(container);
|
|
20
|
-
container.remove();
|
|
21
|
-
container = null;
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('render without child', () => {
|
|
25
|
-
expect(() => shallow(<ValidatorWrapper />)).toThrowError();
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('check wrapper validator', () => {
|
|
29
|
-
const validator = React.createRef();
|
|
30
|
-
act(() => {
|
|
31
|
-
render((
|
|
32
|
-
<ValidatorWrapper ref={validator}>
|
|
33
|
-
<ValidatorField rules={[]} />
|
|
34
|
-
<ValidatorField rules={[]} />
|
|
35
|
-
<ValidatorField rules={[]} />
|
|
36
|
-
<ValidatorField rules={[]} />
|
|
37
|
-
<ValidatorField rules={[]} />
|
|
38
|
-
<ValidatorField rules={[]} />
|
|
39
|
-
</ValidatorWrapper>
|
|
40
|
-
), container);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
expect(typeof validator.current).toBe('object');
|
|
44
|
-
expect(typeof validator.current.validate).toBe('function');
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('check getField validator', () => {
|
|
48
|
-
const validator = React.createRef();
|
|
49
|
-
act(() => {
|
|
50
|
-
render((
|
|
51
|
-
<ValidatorWrapper ref={validator}>
|
|
52
|
-
<ValidatorField rules={[]} id="test" />
|
|
53
|
-
<ValidatorField rules={[]} id="test-fields" />
|
|
54
|
-
</ValidatorWrapper>
|
|
55
|
-
), container);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
expect(typeof validator.current.getField).toBe('function');
|
|
59
|
-
const field = validator.current.getField('test');
|
|
60
|
-
|
|
61
|
-
expect(typeof field.validate).toBe('function');
|
|
62
|
-
const fieldValidate = field.validate();
|
|
63
|
-
|
|
64
|
-
expect(fieldValidate.isValid).toBe(true);
|
|
65
|
-
expect(fieldValidate.message).toBe('');
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it('check getField undefined field', () => {
|
|
69
|
-
const validator = React.createRef();
|
|
70
|
-
act(() => {
|
|
71
|
-
render((
|
|
72
|
-
<ValidatorWrapper ref={validator}>
|
|
73
|
-
<ValidatorField rules={[]} id="test-empty-field" />
|
|
74
|
-
</ValidatorWrapper>
|
|
75
|
-
), container);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
const field = validator.current.getField('8');
|
|
79
|
-
expect(field).toBe(null);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it('check stopAtFirstError validator', () => {
|
|
83
|
-
const validator = React.createRef();
|
|
84
|
-
act(() => {
|
|
85
|
-
render((
|
|
86
|
-
<ValidatorWrapper ref={validator} stopAtFirstError>
|
|
87
|
-
<ValidatorField rules={[]} value="test" />
|
|
88
|
-
<ValidatorField rules={rules.email} value="test" />
|
|
89
|
-
<ValidatorField rules={rules.password} value="" />
|
|
90
|
-
</ValidatorWrapper>
|
|
91
|
-
), container);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
const fieldValidate = validator.current.validate();
|
|
95
|
-
|
|
96
|
-
expect(fieldValidate.isValid).toBe(false);
|
|
97
|
-
expect(fieldValidate.message).toBe('Email is invalid');
|
|
98
|
-
expect(fieldValidate.errors.length).toBe(1);
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it('check unregisterField, registerField', () => {
|
|
102
|
-
const validator = React.createRef();
|
|
103
|
-
act(() => {
|
|
104
|
-
render((
|
|
105
|
-
<ValidatorWrapper ref={validator}>
|
|
106
|
-
<ValidatorField rules={[]} id="test-register-field" />
|
|
107
|
-
</ValidatorWrapper>
|
|
108
|
-
), container);
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
expect(typeof validator.current.registerField).toBe('function');
|
|
112
|
-
expect(typeof validator.current.registerField(1)).toBe('undefined');
|
|
113
|
-
expect(typeof validator.current.registerField()).toBe('undefined');
|
|
114
|
-
|
|
115
|
-
expect(typeof validator.current.unregisterField).toBe('function');
|
|
116
|
-
expect(typeof validator.current.unregisterField(1)).toBe('undefined');
|
|
117
|
-
expect(typeof validator.current.unregisterField()).toBe('undefined');
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
it('check filed in field', () => {
|
|
121
|
-
const validator = React.createRef();
|
|
122
|
-
act(() => {
|
|
123
|
-
render((
|
|
124
|
-
<ValidatorWrapper ref={validator}>
|
|
125
|
-
<ValidatorField rules={[]}>
|
|
126
|
-
<ValidatorField rules={[]} id="check-validate-field-1" />
|
|
127
|
-
<ValidatorField rules={[]} id="check-validate-field-2" />
|
|
128
|
-
</ValidatorField>
|
|
129
|
-
</ValidatorWrapper>
|
|
130
|
-
), container);
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
expect(typeof validator.current).toBe('object');
|
|
134
|
-
expect(typeof validator.current.validate).toBe('function');
|
|
135
|
-
const result = validator.current.validate();
|
|
136
|
-
expect(result.isValid).toBe(true);
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it('check wrapper in wrapper', () => {
|
|
140
|
-
const validatorOut = React.createRef();
|
|
141
|
-
const validatorIn = React.createRef();
|
|
142
|
-
act(() => {
|
|
143
|
-
render((
|
|
144
|
-
<ValidatorWrapper ref={validatorOut}>
|
|
145
|
-
<ValidatorField rules={rules.email} value="" />
|
|
146
|
-
<ValidatorWrapper ref={validatorIn}>
|
|
147
|
-
<ValidatorField rules={rules.password} value="successpasswword" />
|
|
148
|
-
</ValidatorWrapper>
|
|
149
|
-
</ValidatorWrapper>
|
|
150
|
-
), container);
|
|
151
|
-
expect(validatorIn.current.validate().isValid).toBe(true);
|
|
152
|
-
expect(validatorOut.current.validate().isValid).toBe(false);
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it('check two validators', () => {
|
|
157
|
-
const validatorSuccess = React.createRef();
|
|
158
|
-
const validatorFailed = React.createRef();
|
|
159
|
-
act(() => {
|
|
160
|
-
render((
|
|
161
|
-
<>
|
|
162
|
-
<ValidatorWrapper ref={validatorSuccess}>
|
|
163
|
-
<ValidatorField rules={rules.password} value="successpasswword" />
|
|
164
|
-
</ValidatorWrapper>
|
|
165
|
-
<ValidatorWrapper ref={validatorFailed}>
|
|
166
|
-
<ValidatorField rules={rules.email} value="" />
|
|
167
|
-
</ValidatorWrapper>
|
|
168
|
-
</>
|
|
169
|
-
), container);
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
expect(validatorFailed.current.validate().isValid).toBe(false);
|
|
173
|
-
expect(validatorSuccess.current.validate().isValid).toBe(true);
|
|
174
|
-
});
|
package/src/validator.js
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
// eslint-disable-next-line max-classes-per-file
|
|
2
|
-
export class Field {
|
|
3
|
-
constructor({
|
|
4
|
-
rules,
|
|
5
|
-
required,
|
|
6
|
-
value,
|
|
7
|
-
id,
|
|
8
|
-
}) {
|
|
9
|
-
this.rules = rules;
|
|
10
|
-
this.required = required;
|
|
11
|
-
this.value = value;
|
|
12
|
-
this.id = id;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
validate() {
|
|
16
|
-
let isValid = true;
|
|
17
|
-
let message = '';
|
|
18
|
-
const {
|
|
19
|
-
rules,
|
|
20
|
-
value,
|
|
21
|
-
required,
|
|
22
|
-
id,
|
|
23
|
-
} = this;
|
|
24
|
-
|
|
25
|
-
const isEmptyValue = !value && parseFloat(value) !== 0;
|
|
26
|
-
|
|
27
|
-
if (!rules.length || (isEmptyValue && required === false)) {
|
|
28
|
-
return { isValid, message, id };
|
|
29
|
-
}
|
|
30
|
-
rules.forEach((instance) => {
|
|
31
|
-
if (isValid) {
|
|
32
|
-
isValid = instance.rule(value);
|
|
33
|
-
if (!isValid) {
|
|
34
|
-
({ message } = instance);
|
|
35
|
-
if (typeof message === 'function') message = message(value);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
return { isValid, message, id };
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export default class Validator {
|
|
44
|
-
constructor(params) {
|
|
45
|
-
this.params = params || {};
|
|
46
|
-
this.fields = [];
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
addField(params) {
|
|
50
|
-
const field = new Field(params);
|
|
51
|
-
this.fields.push(field);
|
|
52
|
-
return field;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
removeField(field) {
|
|
56
|
-
const index = this.fields.indexOf(field);
|
|
57
|
-
if (index > -1) this.fields.splice(index, 1);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
getField(id) {
|
|
61
|
-
return this.fields.find((field) => field.id === id) || null;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
validate() {
|
|
65
|
-
let prevResult;
|
|
66
|
-
const statuses = this.fields.map((field) => {
|
|
67
|
-
if (this.params.stopAtFirstError && prevResult && prevResult.isValid === false) {
|
|
68
|
-
return null;
|
|
69
|
-
}
|
|
70
|
-
prevResult = field.validate();
|
|
71
|
-
return prevResult;
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
const errors = statuses.filter((inst) => inst && inst.isValid === false);
|
|
75
|
-
|
|
76
|
-
if (errors.length) {
|
|
77
|
-
const { isValid, message } = errors[0];
|
|
78
|
-
return { isValid, message, errors };
|
|
79
|
-
}
|
|
80
|
-
return { isValid: true, message: '' };
|
|
81
|
-
}
|
|
82
|
-
}
|
package/src/validator.test.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/* eslint-env jest */
|
|
2
|
-
|
|
3
|
-
import Validator from './validator';
|
|
4
|
-
import { rules } from './index';
|
|
5
|
-
|
|
6
|
-
it('check normal create validator', () => {
|
|
7
|
-
const validator = new Validator();
|
|
8
|
-
expect(typeof validator).toBe('object');
|
|
9
|
-
expect(typeof validator.validate).toBe('function');
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
it('check normal add and remove fields', () => {
|
|
13
|
-
const validator = new Validator({ stopAtFirstError: true });
|
|
14
|
-
const fieldPassword = validator.addField({
|
|
15
|
-
rules: rules.password,
|
|
16
|
-
value: '',
|
|
17
|
-
id: 'for-remove',
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
expect(typeof fieldPassword).toBe('object');
|
|
21
|
-
|
|
22
|
-
const fieldSearchPassword = validator.getField('for-remove');
|
|
23
|
-
|
|
24
|
-
expect(typeof fieldSearchPassword).toBe('object');
|
|
25
|
-
expect(typeof fieldSearchPassword.validate).toBe('function');
|
|
26
|
-
expect(fieldPassword === fieldSearchPassword).toBe(true);
|
|
27
|
-
|
|
28
|
-
const resultRemove = validator.removeField(fieldPassword);
|
|
29
|
-
expect(resultRemove).toBe(undefined);
|
|
30
|
-
|
|
31
|
-
const resultRemoveUndefined = validator.removeField();
|
|
32
|
-
expect(resultRemoveUndefined).toBe(undefined);
|
|
33
|
-
|
|
34
|
-
const newFieldSearchPassword = validator.getField('for-remove');
|
|
35
|
-
expect(newFieldSearchPassword === null).toBe(true);
|
|
36
|
-
});
|
package/webpack.config.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
const path = require('path');
|
|
2
|
-
|
|
3
|
-
module.exports = {
|
|
4
|
-
entry: './src/index.js',
|
|
5
|
-
output: {
|
|
6
|
-
path: path.resolve(__dirname, 'build'),
|
|
7
|
-
filename: 'index.js',
|
|
8
|
-
libraryTarget: 'commonjs2',
|
|
9
|
-
},
|
|
10
|
-
resolve: {
|
|
11
|
-
extensions: ['.js', '.jsx'],
|
|
12
|
-
},
|
|
13
|
-
module: {
|
|
14
|
-
rules: [
|
|
15
|
-
{
|
|
16
|
-
test: /\.(js|jsx)(\?.*$|$)/,
|
|
17
|
-
exclude: [/node_modules/, /bower_components/],
|
|
18
|
-
include: path.resolve(__dirname, 'src'),
|
|
19
|
-
use: {
|
|
20
|
-
loader: 'babel-loader',
|
|
21
|
-
options: {
|
|
22
|
-
babelrc: true,
|
|
23
|
-
},
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
],
|
|
27
|
-
},
|
|
28
|
-
externals: {
|
|
29
|
-
react: 'commonjs react',
|
|
30
|
-
'prop-types': 'commonjs prop-types',
|
|
31
|
-
},
|
|
32
|
-
};
|