@coxy/react-validator 1.3.4 → 2.0.0

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.
Files changed (56) hide show
  1. package/.eslintignore +1 -1
  2. package/.eslintrc.js +25 -8
  3. package/babel.config.js +3 -0
  4. package/dist/context.d.ts +5 -0
  5. package/dist/context.js +5 -0
  6. package/dist/index.d.ts +5 -0
  7. package/dist/index.js +13 -0
  8. package/dist/rules.d.ts +37 -0
  9. package/dist/rules.js +43 -0
  10. package/dist/use-validator.d.ts +3 -0
  11. package/dist/use-validator.js +22 -0
  12. package/dist/validator-field.d.ts +25 -0
  13. package/dist/validator-field.jsx +34 -0
  14. package/dist/validator-wrapper.d.ts +17 -0
  15. package/dist/validator-wrapper.jsx +43 -0
  16. package/dist/validator.d.ts +28 -0
  17. package/dist/validator.js +72 -0
  18. package/example/example.jsx +29 -26
  19. package/example/index.html +2 -0
  20. package/example/webpack.config.js +15 -7
  21. package/jest.config.ts +10 -0
  22. package/package.json +34 -27
  23. package/src/context.test.ts +7 -0
  24. package/src/context.ts +6 -0
  25. package/src/index.test.ts +7 -0
  26. package/src/index.ts +5 -0
  27. package/src/jest.d.ts +1 -0
  28. package/src/rules.test.ts +127 -0
  29. package/src/{rules.js → rules.ts} +26 -15
  30. package/src/use-validator.test.tsx +58 -0
  31. package/src/use-validator.ts +10 -0
  32. package/src/validator-field.test.tsx +161 -0
  33. package/src/validator-field.tsx +71 -0
  34. package/src/validator-wrapper.test.tsx +138 -0
  35. package/src/validator-wrapper.tsx +58 -0
  36. package/src/validator.test.tsx +30 -0
  37. package/src/validator.ts +105 -0
  38. package/tsconfig.build.json +12 -0
  39. package/tsconfig.json +39 -0
  40. package/.babelrc.js +0 -14
  41. package/build/index.js +0 -1
  42. package/jest.config.js +0 -5
  43. package/src/context.js +0 -3
  44. package/src/context.test.js +0 -13
  45. package/src/index.js +0 -13
  46. package/src/index.test.js +0 -13
  47. package/src/rules.test.js +0 -134
  48. package/src/use-validator.js +0 -8
  49. package/src/use-validator.test.js +0 -56
  50. package/src/validator-field.jsx +0 -72
  51. package/src/validator-field.test.js +0 -190
  52. package/src/validator-wrapper.jsx +0 -63
  53. package/src/validator-wrapper.test.js +0 -177
  54. package/src/validator.js +0 -82
  55. package/src/validator.test.js +0 -40
  56. package/webpack.config.js +0 -32
@@ -0,0 +1,7 @@
1
+ import { ValidatorWrapper, ValidatorField, rules } from './index'
2
+
3
+ it('renders with or without a name', () => {
4
+ expect(typeof ValidatorWrapper).toBe('function')
5
+ expect(typeof ValidatorField).toBe('function')
6
+ expect(typeof rules).toBe('object')
7
+ })
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ export { rules } from './rules'
2
+ export { ValidatorField } from './validator-field'
3
+ export { ValidatorWrapper } from './validator-wrapper'
4
+ export { Validator } from './validator'
5
+ export { useValidator } from './use-validator'
package/src/jest.d.ts ADDED
@@ -0,0 +1 @@
1
+ declare let shallow: any
@@ -0,0 +1,127 @@
1
+ import { rules } from './rules'
2
+
3
+ it('check rule email', () => {
4
+ expect(rules.email.length).toBe(2)
5
+
6
+ let result
7
+ // email.length > 0
8
+ result = rules.email[0].rule('test')
9
+ expect(result).toBe(true)
10
+
11
+ // email check regexp
12
+ result = rules.email[1].rule('test')
13
+ expect(result).toBe(false)
14
+
15
+ // email check regexp
16
+ result = rules.email[1].rule('test@gmail.com')
17
+ expect(result).toBe(true)
18
+ })
19
+
20
+ it('check rule password', () => {
21
+ expect(rules.password.length).toBe(2)
22
+
23
+ let result
24
+ // password.length > 0
25
+ result = rules.password[0].rule('test')
26
+ expect(result).toBe(true)
27
+
28
+ // password.length > 5
29
+ result = rules.password[1].rule('test')
30
+ expect(result).toBe(false)
31
+ })
32
+
33
+ it('check rule bool', () => {
34
+ expect(rules.bool.length).toBe(1)
35
+
36
+ const result = rules.bool[0].rule(true)
37
+ expect(result).toBe(true)
38
+ })
39
+
40
+ it('check rule notEmpty', () => {
41
+ expect(rules.notEmpty.length).toBe(1)
42
+
43
+ let result
44
+ result = rules.notEmpty[0].rule('')
45
+ expect(result).toBe(false)
46
+
47
+ result = rules.notEmpty[0].rule('test')
48
+ expect(result).toBe(true)
49
+ })
50
+
51
+ it('check rule min', () => {
52
+ expect(rules.min(1).length).toBe(1)
53
+ expect(typeof rules.min).toBe('function')
54
+
55
+ let result
56
+ result = rules.min(10)[0].rule('')
57
+ expect(result).toBe(false)
58
+
59
+ result = rules.min(9)[0].rule('testtesttest')
60
+ expect(result).toBe(false)
61
+
62
+ result = rules.min(9)[0].rule('11')
63
+ expect(result).toBe(true)
64
+
65
+ result = rules.min(9)[0].rule(10)
66
+ expect(result).toBe(true)
67
+
68
+ result = rules.min(9)[0].rule('8')
69
+ expect(result).toBe(false)
70
+
71
+ result = rules.min(9)[0].rule(7)
72
+ expect(result).toBe(false)
73
+
74
+ result = rules.min(-1)[0].rule('')
75
+ expect(result).toBe(false)
76
+ })
77
+
78
+ it('check rule max', () => {
79
+ let result
80
+ result = rules.max(10)[0].rule('')
81
+ expect(result).toBe(false)
82
+
83
+ result = rules.max(9)[0].rule('testtesttest')
84
+ expect(result).toBe(false)
85
+
86
+ result = rules.max(9)[0].rule('11')
87
+ expect(result).toBe(false)
88
+
89
+ result = rules.max(9)[0].rule(10)
90
+ expect(result).toBe(false)
91
+
92
+ result = rules.max(9)[0].rule('5')
93
+ expect(result).toBe(true)
94
+
95
+ result = rules.max(9)[0].rule(5)
96
+ expect(result).toBe(true)
97
+
98
+ result = rules.max(-1)[0].rule('')
99
+ expect(result).toBe(false)
100
+ })
101
+
102
+ it('check rule length', () => {
103
+ let result
104
+ result = rules.length(1)[0].rule('')
105
+ expect(result).toBe(false)
106
+
107
+ result = rules.length(1)[0].rule('1')
108
+ expect(result).toBe(true)
109
+
110
+ result = rules.length(1, 10)[0].rule('testtesttest')
111
+ expect(result).toBe(true)
112
+
113
+ result = rules.length(1, 10)[1].rule('testtesttest')
114
+ expect(result).toBe(false)
115
+
116
+ result = rules.length(1, 10)[0].rule('lol')
117
+ expect(result).toBe(true)
118
+
119
+ result = rules.length(1, 10)[1].rule('lol')
120
+ expect(result).toBe(true)
121
+
122
+ result = rules.length(1)[1].rule('test undefined 2 param')
123
+ expect(result).toBe(true)
124
+
125
+ result = rules.length(10)[0].rule('tes')
126
+ expect(result).toBe(false)
127
+ })
@@ -1,48 +1,59 @@
1
+ import { Value } from './validator-field'
2
+
1
3
  // eslint-disable-next-line
2
- const emailReg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
4
+ const emailReg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
5
+
6
+ type Fn = (value: Value) => string
7
+
8
+ export interface RuleInstance {
9
+ rule: (value: Value) => boolean
10
+ message: string | Fn
11
+ }
3
12
 
4
- export default {
13
+ export type ValidatorRules = RuleInstance[]
14
+
15
+ export const rules = {
5
16
  notEmpty: [{
6
17
  rule: (value) => value !== '' && value.length > 0,
7
- message: 'Value is required',
18
+ message: 'Value is required'
8
19
  }],
9
20
 
10
21
  bool: [{
11
22
  rule: (value) => !!value,
12
- message: 'Value is required',
23
+ message: 'Value is required'
13
24
  }],
14
25
 
15
26
  password: [{
16
27
  rule: (value) => value.length > 0,
17
- message: 'Password field cannot be empty',
28
+ message: 'Password field cannot be empty'
18
29
  }, {
19
30
  rule: (value) => value.length > 5,
20
- message: 'Password field can not be less than 6 characters',
31
+ message: 'Password field can not be less than 6 characters'
21
32
  }],
22
33
 
23
34
  email: [{
24
35
  rule: (value) => !!value && value !== '' && value.length !== 0,
25
- message: 'Email is required',
36
+ message: 'Email is required'
26
37
  }, {
27
38
  rule: (value) => emailReg.test(String(value).toLowerCase()),
28
- message: 'Email is invalid',
39
+ message: 'Email is invalid'
29
40
  }],
30
41
 
31
42
  min: (min) => [{
32
43
  rule: (value) => parseFloat(value) > min,
33
- message: `The value must be greater than ${min}`,
44
+ message: `The value must be greater than ${min}`
34
45
  }],
35
46
 
36
47
  max: (max) => [{
37
48
  rule: (value) => parseFloat(value) < max,
38
- message: `The value must be smaller ${max}`,
49
+ message: `The value must be smaller ${max}`
39
50
  }],
40
51
 
41
- length: (min, max) => [{
52
+ length: (min, max?) => [{
42
53
  rule: (value) => String(value).length >= min,
43
- message: `No less than ${min} symbols`,
54
+ message: `No less than ${min} symbols`
44
55
  }, {
45
56
  rule: (value) => (max !== undefined ? String(value).length <= max : true),
46
- message: `No more than ${max} symbols`,
47
- }],
48
- };
57
+ message: `No more than ${max} symbols`
58
+ }]
59
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @jest-environment jsdom
3
+ */
4
+
5
+ import { unmountComponentAtNode } from 'react-dom'
6
+ import { render, screen } from '@testing-library/react'
7
+ import { act } from 'react-dom/test-utils'
8
+ import { useEffect, useState } from 'react'
9
+
10
+ import { rules } from './rules'
11
+ import { useValidator } from './use-validator'
12
+
13
+ let container
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
+ jest.useFakeTimers()
26
+
27
+ it('check state change and hide field', () => {
28
+ function Comp () {
29
+ const [value, setValue] = useState(false)
30
+ const [isValid, validateObject] = useValidator(value, rules.bool)
31
+
32
+ useEffect(() => {
33
+ setTimeout(() => {
34
+ act(() => {
35
+ setValue(true)
36
+ })
37
+ }, 100)
38
+ }, [])
39
+
40
+ return (
41
+ <>
42
+ <span data-testid="test1">{isValid ? 'true' : 'false'}</span>
43
+ <span data-testid="test2">{validateObject.message || 'true'}</span>
44
+ </>
45
+ )
46
+ }
47
+ act(() => {
48
+ render(<Comp />)
49
+ })
50
+
51
+ expect(screen.getByTestId('test1').textContent).toContain('false')
52
+ expect(screen.getByTestId('test2').textContent).toContain('Value is required')
53
+
54
+ jest.runAllTimers()
55
+
56
+ expect(screen.getByTestId('test1').textContent).toContain('true')
57
+ expect(screen.getByTestId('test2').textContent).toContain('true')
58
+ })
@@ -0,0 +1,10 @@
1
+ import { Validator } from './validator'
2
+ import { ValidatorRules } from './rules'
3
+ import { Validity, Value } from './validator-field'
4
+
5
+ export function useValidator (value: Value, rules: ValidatorRules): [boolean, Pick<Validity, 'message' | 'errors'>] {
6
+ const validator = new Validator()
7
+ validator.addField({ value, rules })
8
+ const { isValid, ...validateObject } = validator.validate()
9
+ return [isValid, validateObject]
10
+ }
@@ -0,0 +1,161 @@
1
+ /**
2
+ * @jest-environment jsdom
3
+ */
4
+
5
+ import { createRef, useEffect, useState } from 'react'
6
+ import { render, act } from '@testing-library/react'
7
+
8
+ import { ValidatorWrapper } from './validator-wrapper'
9
+ import { ValidatorField } from './validator-field'
10
+ import { rules } from './rules'
11
+
12
+ it('render without wrapper', () => {
13
+ expect(() => shallow(<ValidatorField />)).toThrowError()
14
+ })
15
+
16
+ it('normal render', () => {
17
+ render((
18
+ <ValidatorWrapper>
19
+ <ValidatorField rules={[]} value="" />
20
+ </ValidatorWrapper>
21
+ ))
22
+ })
23
+
24
+ it('check context validator', () => {
25
+ const validator = createRef<ValidatorWrapper>()
26
+ render((
27
+ <ValidatorWrapper ref={validator}>
28
+ <ValidatorField rules={[]} />
29
+ </ValidatorWrapper>
30
+ ))
31
+
32
+ const validateResult = validator.current.validate()
33
+
34
+ expect(validateResult.isValid).toBe(true)
35
+ expect(validateResult.message).toBe('')
36
+ })
37
+
38
+ it('check failed validation', () => {
39
+ const validator1 = createRef<ValidatorWrapper>()
40
+ const validator2 = createRef<ValidatorWrapper>()
41
+
42
+ render((
43
+ <>
44
+ <ValidatorWrapper ref={validator1}>
45
+ <ValidatorField rules={rules.email} value="test" />
46
+ </ValidatorWrapper>
47
+ <ValidatorWrapper ref={validator2}>
48
+ <ValidatorField rules={rules.email} value="" />
49
+ </ValidatorWrapper>
50
+ </>
51
+ ))
52
+
53
+ act(() => {
54
+ const validateResult1 = validator1.current.validate()
55
+
56
+ expect(validateResult1.isValid).toBe(false)
57
+ expect(validateResult1.message).toBe('Email is invalid')
58
+ expect(validateResult1.errors.length).toBe(1)
59
+
60
+ const validateResult2 = validator2.current.validate()
61
+
62
+ expect(validateResult2.isValid).toBe(false)
63
+ expect(validateResult2.message).toBe('Email is required')
64
+ expect(validateResult2.errors.length).toBe(1)
65
+ })
66
+ })
67
+
68
+ jest.useFakeTimers()
69
+
70
+ it('check state change and hide field', () => {
71
+ const validator1 = createRef<ValidatorWrapper>()
72
+
73
+ function Comp () {
74
+ const [st, setSt] = useState(true)
75
+
76
+ useEffect(() => {
77
+ setTimeout(() => {
78
+ act(() => {
79
+ setSt(false)
80
+ })
81
+ }, 100)
82
+ }, [])
83
+
84
+ return (
85
+ <ValidatorWrapper ref={validator1}>
86
+ <ValidatorField rules={rules.email} value="test" />
87
+ {st && (
88
+ <ValidatorField rules={rules.email} value="" />
89
+ )}
90
+ </ValidatorWrapper>
91
+ )
92
+ }
93
+
94
+ render(<Comp />)
95
+
96
+ jest.runAllTimers()
97
+
98
+ const validateResult1 = validator1.current.validate()
99
+
100
+ expect(validateResult1.isValid).toBe(false)
101
+ expect(validateResult1.message).toBe('Email is invalid')
102
+ expect(validateResult1.errors.length).toBe(1)
103
+ })
104
+
105
+ it('check success validation', () => {
106
+ const validator = createRef<ValidatorWrapper>()
107
+ render((
108
+ <ValidatorWrapper ref={validator}>
109
+ <ValidatorField rules={rules.email} value="email@email.com" />
110
+ </ValidatorWrapper>
111
+ ))
112
+
113
+ const validateResult = validator.current.validate()
114
+
115
+ expect(validateResult.isValid).toBe(true)
116
+ expect(validateResult.message).toBe('')
117
+ })
118
+
119
+ it('check success validation fot child function', () => {
120
+ const validator = createRef<ValidatorWrapper>()
121
+ render((
122
+ <ValidatorWrapper ref={validator}>
123
+ <ValidatorField rules={rules.email} value="email@email.com">
124
+ {({ isValid, message }) => (
125
+ <>
126
+ {!isValid && <div>{message}</div>}
127
+ </>
128
+ )}
129
+ </ValidatorField>
130
+ </ValidatorWrapper>
131
+ ))
132
+
133
+ const validateResult = validator.current.validate()
134
+
135
+ expect(validateResult.isValid).toBe(true)
136
+ expect(validateResult.message).toBe('')
137
+ })
138
+
139
+ it('check custom rule message function', () => {
140
+ const validator = createRef<ValidatorWrapper>()
141
+ const rule = [{
142
+ rule: (value) => value !== 'test',
143
+ message: (value) => `test message ${value}`
144
+ }]
145
+ render((
146
+ <ValidatorWrapper ref={validator}>
147
+ <ValidatorField rules={rule} value="test">
148
+ {({ isValid, message }) => (
149
+ <>
150
+ {!isValid && <div>{message}</div>}
151
+ </>
152
+ )}
153
+ </ValidatorField>
154
+ </ValidatorWrapper>
155
+ ))
156
+
157
+ const validateResult = validator.current.validate()
158
+
159
+ expect(validateResult.isValid).toBe(false)
160
+ expect(validateResult.message).toBe('test message test')
161
+ })
@@ -0,0 +1,71 @@
1
+ import { Component, ReactNode } from 'react'
2
+
3
+ import { Context } from './context'
4
+ import { Field } from './validator'
5
+ import { ValidatorRules } from './rules'
6
+
7
+ export type Value = any
8
+
9
+ export interface ErrorMessage {
10
+ message: string
11
+ isValid: boolean
12
+ }
13
+
14
+ export interface Validity {
15
+ message: string
16
+ isValid: boolean
17
+ errors?: ErrorMessage[]
18
+ id?: string | number
19
+ }
20
+
21
+ type Fn = (validity: Validity, value: Value) => ReactNode
22
+
23
+ interface Props {
24
+ rules?: ValidatorRules,
25
+ required?: boolean,
26
+ value?: Value
27
+ id?: string | number
28
+ children?: ReactNode | Fn
29
+ unregisterField: (val: any) => void
30
+ registerField: (val: any) => void
31
+ }
32
+
33
+ class ValidationFieldWrapper extends Component<Props> {
34
+ componentWillUnmount () {
35
+ this.props.unregisterField(this)
36
+ }
37
+
38
+ componentDidMount () {
39
+ this.props.registerField(this)
40
+ }
41
+
42
+ validate (): Validity {
43
+ const field = new Field({
44
+ rules: this.props.rules,
45
+ required: this.props.required,
46
+ value: this.props.value,
47
+ id: this.props.id
48
+ })
49
+ return field.validate()
50
+ }
51
+
52
+ render () {
53
+ const { children, value } = this.props
54
+ const validity = this.validate()
55
+ return (typeof children === 'function' ? children(validity, value) : children)
56
+ }
57
+ }
58
+
59
+ export function ValidatorField (props: Omit<Props, 'registerField' | 'unregisterField'>) {
60
+ return (
61
+ <Context.Consumer>
62
+ {(data) => (
63
+ <ValidationFieldWrapper
64
+ {...props}
65
+ registerField={data.registerField}
66
+ unregisterField={data.unregisterField}
67
+ />
68
+ )}
69
+ </Context.Consumer>
70
+ )
71
+ }
@@ -0,0 +1,138 @@
1
+ /**
2
+ * @jest-environment jsdom
3
+ */
4
+
5
+ import { createRef } from 'react'
6
+ import { render } from '@testing-library/react'
7
+
8
+ import { ValidatorWrapper } from './validator-wrapper'
9
+ import { ValidatorField } from './validator-field'
10
+ import { rules } from './rules'
11
+
12
+ it('render without child', () => {
13
+ expect(() => shallow(<ValidatorWrapper />)).toThrowError()
14
+ })
15
+
16
+ it('check wrapper validator', () => {
17
+ const validator = createRef<ValidatorWrapper>()
18
+ render((
19
+ <ValidatorWrapper ref={validator}>
20
+ <ValidatorField rules={[]} />
21
+ <ValidatorField rules={[]} />
22
+ <ValidatorField rules={[]} />
23
+ <ValidatorField rules={[]} />
24
+ <ValidatorField rules={[]} />
25
+ <ValidatorField rules={[]} />
26
+ </ValidatorWrapper>
27
+ ))
28
+
29
+ expect(typeof validator.current).toBe('object')
30
+ expect(typeof validator.current.validate).toBe('function')
31
+ })
32
+
33
+ it('check getField validator', () => {
34
+ const validator = createRef<ValidatorWrapper>()
35
+ render((
36
+ <ValidatorWrapper ref={validator}>
37
+ <ValidatorField rules={[]} id="test" />
38
+ <ValidatorField rules={[]} id="test-fields" />
39
+ </ValidatorWrapper>
40
+ ))
41
+ expect(typeof validator.current.getField).toBe('function')
42
+ const field = validator.current.getField('test')
43
+
44
+ expect(typeof field.validate).toBe('function')
45
+ const fieldValidate = field.validate()
46
+
47
+ expect(fieldValidate.isValid).toBe(true)
48
+ expect(fieldValidate.message).toBe('')
49
+ })
50
+
51
+ it('check getField undefined field', () => {
52
+ const validator = createRef<ValidatorWrapper>()
53
+ render((
54
+ <ValidatorWrapper ref={validator}>
55
+ <ValidatorField rules={[]} id="test-empty-field" />
56
+ </ValidatorWrapper>
57
+ ))
58
+
59
+ const field = validator.current.getField('8')
60
+ expect(field).toBe(null)
61
+ })
62
+
63
+ it('check stopAtFirstError validator', () => {
64
+ const validator = createRef<ValidatorWrapper>()
65
+ render((
66
+ <ValidatorWrapper ref={validator} stopAtFirstError>
67
+ <ValidatorField rules={[]} value="test" />
68
+ <ValidatorField rules={rules.email} value="test" />
69
+ <ValidatorField rules={rules.password} value="" />
70
+ </ValidatorWrapper>
71
+ ))
72
+ const fieldValidate = validator.current.validate()
73
+ expect(fieldValidate.isValid).toBe(false)
74
+ expect(fieldValidate.message).toBe('Email is invalid')
75
+ expect(fieldValidate.errors.length).toBe(1)
76
+ })
77
+
78
+ it('check unregisterField, registerField', () => {
79
+ const validator = createRef<ValidatorWrapper>()
80
+ render((
81
+ <ValidatorWrapper ref={validator}>
82
+ <ValidatorField rules={[]} id="test-register-field" />
83
+ </ValidatorWrapper>
84
+ ))
85
+
86
+ expect(typeof validator.current.registerField).toBe('function')
87
+ expect(typeof validator.current.unregisterField).toBe('function')
88
+ })
89
+
90
+ it('check filed in field', () => {
91
+ const validator = createRef<ValidatorWrapper>()
92
+ render(
93
+ <ValidatorWrapper ref={validator}>
94
+ <ValidatorField rules={[]}>
95
+ <ValidatorField rules={[]} id="check-validate-field-1" />
96
+ <ValidatorField rules={[]} id="check-validate-field-2" />
97
+ </ValidatorField>
98
+ </ValidatorWrapper>
99
+ )
100
+
101
+ expect(typeof validator.current).toBe('object')
102
+ expect(typeof validator.current.validate).toBe('function')
103
+ const result = validator.current.validate()
104
+ expect(result.isValid).toBe(true)
105
+ })
106
+
107
+ it('check wrapper in wrapper', () => {
108
+ const validatorOut = createRef<ValidatorWrapper>()
109
+ const validatorIn = createRef<ValidatorWrapper>()
110
+ render((
111
+ <ValidatorWrapper ref={validatorOut}>
112
+ <ValidatorField rules={rules.email} value="" />
113
+ <ValidatorWrapper ref={validatorIn}>
114
+ <ValidatorField rules={rules.password} value="successpasswword" />
115
+ </ValidatorWrapper>
116
+ </ValidatorWrapper>
117
+ ))
118
+ expect(validatorIn.current.validate().isValid).toBe(true)
119
+ expect(validatorOut.current.validate().isValid).toBe(false)
120
+ })
121
+
122
+ it('check two validators', () => {
123
+ const validatorSuccess = createRef<ValidatorWrapper>()
124
+ const validatorFailed = createRef<ValidatorWrapper>()
125
+ render((
126
+ <>
127
+ <ValidatorWrapper ref={validatorSuccess}>
128
+ <ValidatorField rules={rules.password} value="successpasswword" />
129
+ </ValidatorWrapper>
130
+ <ValidatorWrapper ref={validatorFailed}>
131
+ <ValidatorField rules={rules.email} value="" />
132
+ </ValidatorWrapper>
133
+ </>
134
+ ))
135
+
136
+ expect(validatorFailed.current.validate().isValid).toBe(false)
137
+ expect(validatorSuccess.current.validate().isValid).toBe(true)
138
+ })