@wwog/react 1.3.12 → 1.3.13
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/README.md +78 -0
- package/dist/index.d.mts +101 -10
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/algorithm/date/zellersKongruenz.ts +9 -14
- package/src/algorithm/date.ts +2 -2
- package/src/components/Layout/index.ts +2 -2
- package/src/components/ProcessControl/If.tsx +2 -2
- package/src/components/Sundry/Boundary.tsx +67 -0
- package/src/components/Sundry/Portal.tsx +59 -0
- package/src/components/Sundry/Repeat.tsx +34 -0
- package/src/components/Sundry/index.ts +8 -5
- package/src/hooks/index.ts +1 -1
- package/src/hooks/useScreen.ts +54 -65
- package/src/index.ts +5 -5
- package/src/utils/constants.ts +7 -16
- package/src/utils/createExternalState.ts +71 -84
- package/src/utils/index.ts +7 -7
- package/src/utils/promise.ts +18 -18
- package/src/utils/ruleChecker.test.ts +336 -349
- package/src/utils/ruleChecker.ts +98 -181
- package/src/utils/sundry.ts +66 -67
|
@@ -1,407 +1,403 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import type {
|
|
1
|
+
import {describe, expect, it} from 'vitest'
|
|
2
|
+
import {ruleChecker} from './ruleChecker'
|
|
3
|
+
import type {RuleDescription} from './ruleChecker'
|
|
4
4
|
|
|
5
5
|
describe('ruleChecker', () => {
|
|
6
6
|
// ==== 基础功能测试 ====
|
|
7
7
|
describe('基础功能', () => {
|
|
8
8
|
it('应该通过空规则验证', () => {
|
|
9
|
-
const result = ruleChecker({}, {})
|
|
10
|
-
expect(result.valid).toBe(true)
|
|
9
|
+
const result = ruleChecker({}, {})
|
|
10
|
+
expect(result.valid).toBe(true)
|
|
11
11
|
if (result.valid) {
|
|
12
|
-
expect(result.data).toEqual({})
|
|
12
|
+
expect(result.data).toEqual({})
|
|
13
13
|
}
|
|
14
|
-
})
|
|
14
|
+
})
|
|
15
15
|
|
|
16
16
|
it('应该验证 required 规则 - 成功', () => {
|
|
17
|
-
const data = {
|
|
17
|
+
const data = {name: 'John'}
|
|
18
18
|
const rules: RuleDescription<typeof data> = {
|
|
19
|
-
name: {
|
|
20
|
-
}
|
|
21
|
-
const result = ruleChecker(data, rules)
|
|
22
|
-
expect(result.valid).toBe(true)
|
|
19
|
+
name: {required: true},
|
|
20
|
+
}
|
|
21
|
+
const result = ruleChecker(data, rules)
|
|
22
|
+
expect(result.valid).toBe(true)
|
|
23
23
|
if (result.valid) {
|
|
24
|
-
expect(result.data.name).toBe('John')
|
|
24
|
+
expect(result.data.name).toBe('John')
|
|
25
25
|
}
|
|
26
|
-
})
|
|
26
|
+
})
|
|
27
27
|
|
|
28
28
|
it('应该验证 required 规则 - 失败', () => {
|
|
29
|
-
const data = {
|
|
29
|
+
const data = {name: ''}
|
|
30
30
|
const rules: RuleDescription<typeof data> = {
|
|
31
|
-
name: {
|
|
32
|
-
}
|
|
33
|
-
const result = ruleChecker(data, rules)
|
|
34
|
-
expect(result.valid).toBe(false)
|
|
31
|
+
name: {required: true},
|
|
32
|
+
}
|
|
33
|
+
const result = ruleChecker(data, rules)
|
|
34
|
+
expect(result.valid).toBe(false)
|
|
35
35
|
if (!result.valid) {
|
|
36
|
-
expect(result.errors).toContain('name 为必填项')
|
|
37
|
-
expect(result.fieldErrors.name).toContain('name 为必填项')
|
|
36
|
+
expect(result.errors).toContain('name 为必填项')
|
|
37
|
+
expect(result.fieldErrors.name).toContain('name 为必填项')
|
|
38
38
|
}
|
|
39
|
-
})
|
|
39
|
+
})
|
|
40
40
|
|
|
41
41
|
it('应该使用自定义错误消息', () => {
|
|
42
|
-
const data = {
|
|
42
|
+
const data = {email: ''}
|
|
43
43
|
const rules: RuleDescription<typeof data> = {
|
|
44
|
-
email: {
|
|
45
|
-
}
|
|
46
|
-
const result = ruleChecker(data, rules)
|
|
47
|
-
expect(result.valid).toBe(false)
|
|
44
|
+
email: {required: true, message: '邮箱不能为空'},
|
|
45
|
+
}
|
|
46
|
+
const result = ruleChecker(data, rules)
|
|
47
|
+
expect(result.valid).toBe(false)
|
|
48
48
|
if (!result.valid) {
|
|
49
|
-
expect(result.errors).toContain('邮箱不能为空')
|
|
49
|
+
expect(result.errors).toContain('邮箱不能为空')
|
|
50
50
|
}
|
|
51
|
-
})
|
|
51
|
+
})
|
|
52
52
|
|
|
53
53
|
it('应该处理 null 和 undefined 值', () => {
|
|
54
|
-
type DataType = {
|
|
55
|
-
const data: Partial<DataType> = {
|
|
54
|
+
type DataType = {name: string | null; age?: number}
|
|
55
|
+
const data: Partial<DataType> = {name: null, age: undefined}
|
|
56
56
|
const rules: RuleDescription<DataType> = {
|
|
57
|
-
name: {
|
|
58
|
-
age: {
|
|
59
|
-
}
|
|
60
|
-
const result = ruleChecker(data, rules)
|
|
61
|
-
expect(result.valid).toBe(false)
|
|
57
|
+
name: {required: true},
|
|
58
|
+
age: {required: false},
|
|
59
|
+
}
|
|
60
|
+
const result = ruleChecker(data, rules)
|
|
61
|
+
expect(result.valid).toBe(false)
|
|
62
62
|
if (!result.valid) {
|
|
63
|
-
expect(result.fieldErrors.name).toContain('name 为必填项')
|
|
64
|
-
expect(result.fieldErrors.age).toBeUndefined()
|
|
63
|
+
expect(result.fieldErrors.name).toContain('name 为必填项')
|
|
64
|
+
expect(result.fieldErrors.age).toBeUndefined()
|
|
65
65
|
}
|
|
66
|
-
})
|
|
66
|
+
})
|
|
67
67
|
|
|
68
68
|
it('应该验证自定义 validator - 返回 boolean', () => {
|
|
69
|
-
const data = {
|
|
69
|
+
const data = {password: '123'}
|
|
70
70
|
const rules: RuleDescription<typeof data> = {
|
|
71
71
|
password: {
|
|
72
72
|
validator: (value) => value.length >= 6,
|
|
73
73
|
message: '密码至少6位',
|
|
74
74
|
},
|
|
75
|
-
}
|
|
76
|
-
const result = ruleChecker(data, rules)
|
|
77
|
-
expect(result.valid).toBe(false)
|
|
75
|
+
}
|
|
76
|
+
const result = ruleChecker(data, rules)
|
|
77
|
+
expect(result.valid).toBe(false)
|
|
78
78
|
if (!result.valid) {
|
|
79
|
-
expect(result.errors).toContain('密码至少6位')
|
|
79
|
+
expect(result.errors).toContain('密码至少6位')
|
|
80
80
|
}
|
|
81
|
-
})
|
|
81
|
+
})
|
|
82
82
|
|
|
83
83
|
it('应该验证自定义 validator - 返回 string', () => {
|
|
84
|
-
const data = {
|
|
84
|
+
const data = {username: 'admin'}
|
|
85
85
|
const rules: RuleDescription<typeof data> = {
|
|
86
86
|
username: {
|
|
87
|
-
validator: (value) =>
|
|
88
|
-
value === 'admin' ? '用户名不能是admin' : true,
|
|
87
|
+
validator: (value) => (value === 'admin' ? '用户名不能是admin' : true),
|
|
89
88
|
},
|
|
90
|
-
}
|
|
91
|
-
const result = ruleChecker(data, rules)
|
|
92
|
-
expect(result.valid).toBe(false)
|
|
89
|
+
}
|
|
90
|
+
const result = ruleChecker(data, rules)
|
|
91
|
+
expect(result.valid).toBe(false)
|
|
93
92
|
if (!result.valid) {
|
|
94
|
-
expect(result.errors).toContain('用户名不能是admin')
|
|
93
|
+
expect(result.errors).toContain('用户名不能是admin')
|
|
95
94
|
}
|
|
96
|
-
})
|
|
97
|
-
})
|
|
95
|
+
})
|
|
96
|
+
})
|
|
98
97
|
|
|
99
98
|
// ==== 字符串规则测试 ====
|
|
100
99
|
describe('字符串规则', () => {
|
|
101
100
|
it('应该验证字符串长度 len', () => {
|
|
102
|
-
const data = {
|
|
101
|
+
const data = {code: '123'}
|
|
103
102
|
const rules: RuleDescription<typeof data> = {
|
|
104
|
-
code: {
|
|
105
|
-
}
|
|
106
|
-
const result = ruleChecker(data, rules)
|
|
107
|
-
expect(result.valid).toBe(false)
|
|
103
|
+
code: {len: 4},
|
|
104
|
+
}
|
|
105
|
+
const result = ruleChecker(data, rules)
|
|
106
|
+
expect(result.valid).toBe(false)
|
|
108
107
|
if (!result.valid) {
|
|
109
|
-
expect(result.errors).toContain('code 长度必须为 4')
|
|
108
|
+
expect(result.errors).toContain('code 长度必须为 4')
|
|
110
109
|
}
|
|
111
|
-
})
|
|
110
|
+
})
|
|
112
111
|
|
|
113
112
|
it('应该验证字符串最小长度 min', () => {
|
|
114
|
-
const data = {
|
|
113
|
+
const data = {username: 'ab'}
|
|
115
114
|
const rules: RuleDescription<typeof data> = {
|
|
116
|
-
username: {
|
|
117
|
-
}
|
|
118
|
-
const result = ruleChecker(data, rules)
|
|
119
|
-
expect(result.valid).toBe(false)
|
|
115
|
+
username: {min: 3},
|
|
116
|
+
}
|
|
117
|
+
const result = ruleChecker(data, rules)
|
|
118
|
+
expect(result.valid).toBe(false)
|
|
120
119
|
if (!result.valid) {
|
|
121
|
-
expect(result.errors).toContain('username 长度不能少于 3')
|
|
120
|
+
expect(result.errors).toContain('username 长度不能少于 3')
|
|
122
121
|
}
|
|
123
|
-
})
|
|
122
|
+
})
|
|
124
123
|
|
|
125
124
|
it('应该验证字符串最大长度 max', () => {
|
|
126
|
-
const data = {
|
|
125
|
+
const data = {comment: 'a'.repeat(101)}
|
|
127
126
|
const rules: RuleDescription<typeof data> = {
|
|
128
|
-
comment: {
|
|
129
|
-
}
|
|
130
|
-
const result = ruleChecker(data, rules)
|
|
131
|
-
expect(result.valid).toBe(false)
|
|
127
|
+
comment: {max: 100},
|
|
128
|
+
}
|
|
129
|
+
const result = ruleChecker(data, rules)
|
|
130
|
+
expect(result.valid).toBe(false)
|
|
132
131
|
if (!result.valid) {
|
|
133
|
-
expect(result.errors).toContain('comment 长度不能超过 100')
|
|
132
|
+
expect(result.errors).toContain('comment 长度不能超过 100')
|
|
134
133
|
}
|
|
135
|
-
})
|
|
134
|
+
})
|
|
136
135
|
|
|
137
136
|
it('应该验证正则表达式', () => {
|
|
138
|
-
const data = {
|
|
137
|
+
const data = {phone: '123456'}
|
|
139
138
|
const rules: RuleDescription<typeof data> = {
|
|
140
|
-
phone: {
|
|
141
|
-
}
|
|
142
|
-
const result = ruleChecker(data, rules)
|
|
143
|
-
expect(result.valid).toBe(false)
|
|
139
|
+
phone: {regex: /^\d{11}$/},
|
|
140
|
+
}
|
|
141
|
+
const result = ruleChecker(data, rules)
|
|
142
|
+
expect(result.valid).toBe(false)
|
|
144
143
|
if (!result.valid) {
|
|
145
|
-
expect(result.errors).toContain('phone 格式不正确')
|
|
144
|
+
expect(result.errors).toContain('phone 格式不正确')
|
|
146
145
|
}
|
|
147
|
-
})
|
|
146
|
+
})
|
|
148
147
|
|
|
149
148
|
it('应该验证邮箱格式', () => {
|
|
150
|
-
const data = {
|
|
149
|
+
const data = {email: 'invalid-email'}
|
|
151
150
|
const rules: RuleDescription<typeof data> = {
|
|
152
|
-
email: {
|
|
153
|
-
}
|
|
154
|
-
const result = ruleChecker(data, rules)
|
|
155
|
-
expect(result.valid).toBe(false)
|
|
151
|
+
email: {email: true},
|
|
152
|
+
}
|
|
153
|
+
const result = ruleChecker(data, rules)
|
|
154
|
+
expect(result.valid).toBe(false)
|
|
156
155
|
if (!result.valid) {
|
|
157
|
-
expect(result.errors).toContain('email 不是有效的邮箱')
|
|
156
|
+
expect(result.errors).toContain('email 不是有效的邮箱')
|
|
158
157
|
}
|
|
159
|
-
})
|
|
158
|
+
})
|
|
160
159
|
|
|
161
160
|
it('应该通过有效的邮箱验证', () => {
|
|
162
|
-
const data = {
|
|
161
|
+
const data = {email: 'test@example.com'}
|
|
163
162
|
const rules: RuleDescription<typeof data> = {
|
|
164
|
-
email: {
|
|
165
|
-
}
|
|
166
|
-
const result = ruleChecker(data, rules)
|
|
167
|
-
expect(result.valid).toBe(true)
|
|
168
|
-
})
|
|
163
|
+
email: {email: true},
|
|
164
|
+
}
|
|
165
|
+
const result = ruleChecker(data, rules)
|
|
166
|
+
expect(result.valid).toBe(true)
|
|
167
|
+
})
|
|
169
168
|
|
|
170
169
|
it('应该验证URL格式', () => {
|
|
171
|
-
const data = {
|
|
170
|
+
const data = {website: 'invalid-url'}
|
|
172
171
|
const rules: RuleDescription<typeof data> = {
|
|
173
|
-
website: {
|
|
174
|
-
}
|
|
175
|
-
const result = ruleChecker(data, rules)
|
|
176
|
-
expect(result.valid).toBe(false)
|
|
172
|
+
website: {url: true},
|
|
173
|
+
}
|
|
174
|
+
const result = ruleChecker(data, rules)
|
|
175
|
+
expect(result.valid).toBe(false)
|
|
177
176
|
if (!result.valid) {
|
|
178
|
-
expect(result.errors).toContain('website 不是有效的URL')
|
|
177
|
+
expect(result.errors).toContain('website 不是有效的URL')
|
|
179
178
|
}
|
|
180
|
-
})
|
|
179
|
+
})
|
|
181
180
|
|
|
182
181
|
it('应该通过有效的URL验证', () => {
|
|
183
|
-
const data = {
|
|
182
|
+
const data = {website: 'https://example.com'}
|
|
184
183
|
const rules: RuleDescription<typeof data> = {
|
|
185
|
-
website: {
|
|
186
|
-
}
|
|
187
|
-
const result = ruleChecker(data, rules)
|
|
188
|
-
expect(result.valid).toBe(true)
|
|
189
|
-
})
|
|
184
|
+
website: {url: true},
|
|
185
|
+
}
|
|
186
|
+
const result = ruleChecker(data, rules)
|
|
187
|
+
expect(result.valid).toBe(true)
|
|
188
|
+
})
|
|
190
189
|
|
|
191
190
|
it('应该验证手机号格式', () => {
|
|
192
|
-
const data = {
|
|
191
|
+
const data = {mobile: '123456789'}
|
|
193
192
|
const rules: RuleDescription<typeof data> = {
|
|
194
|
-
mobile: {
|
|
195
|
-
}
|
|
196
|
-
const result = ruleChecker(data, rules)
|
|
197
|
-
expect(result.valid).toBe(false)
|
|
193
|
+
mobile: {phone: true},
|
|
194
|
+
}
|
|
195
|
+
const result = ruleChecker(data, rules)
|
|
196
|
+
expect(result.valid).toBe(false)
|
|
198
197
|
if (!result.valid) {
|
|
199
|
-
expect(result.errors).toContain('mobile 不是有效的手机号')
|
|
198
|
+
expect(result.errors).toContain('mobile 不是有效的手机号')
|
|
200
199
|
}
|
|
201
|
-
})
|
|
200
|
+
})
|
|
202
201
|
|
|
203
202
|
it('应该通过有效的手机号验证', () => {
|
|
204
|
-
const data = {
|
|
203
|
+
const data = {mobile: '13812345678'}
|
|
205
204
|
const rules: RuleDescription<typeof data> = {
|
|
206
|
-
mobile: {
|
|
207
|
-
}
|
|
208
|
-
const result = ruleChecker(data, rules)
|
|
209
|
-
expect(result.valid).toBe(true)
|
|
210
|
-
})
|
|
211
|
-
})
|
|
205
|
+
mobile: {phone: true},
|
|
206
|
+
}
|
|
207
|
+
const result = ruleChecker(data, rules)
|
|
208
|
+
expect(result.valid).toBe(true)
|
|
209
|
+
})
|
|
210
|
+
})
|
|
212
211
|
|
|
213
212
|
// ==== 数字规则测试 ====
|
|
214
213
|
describe('数字规则', () => {
|
|
215
214
|
it('应该验证数字最小值', () => {
|
|
216
|
-
const data = {
|
|
215
|
+
const data = {age: 5}
|
|
217
216
|
const rules: RuleDescription<typeof data> = {
|
|
218
|
-
age: {
|
|
219
|
-
}
|
|
220
|
-
const result = ruleChecker(data, rules)
|
|
221
|
-
expect(result.valid).toBe(false)
|
|
217
|
+
age: {min: 18},
|
|
218
|
+
}
|
|
219
|
+
const result = ruleChecker(data, rules)
|
|
220
|
+
expect(result.valid).toBe(false)
|
|
222
221
|
if (!result.valid) {
|
|
223
|
-
expect(result.errors).toContain('age 不能小于 18')
|
|
222
|
+
expect(result.errors).toContain('age 不能小于 18')
|
|
224
223
|
}
|
|
225
|
-
})
|
|
224
|
+
})
|
|
226
225
|
|
|
227
226
|
it('应该验证数字最大值', () => {
|
|
228
|
-
const data = {
|
|
227
|
+
const data = {score: 105}
|
|
229
228
|
const rules: RuleDescription<typeof data> = {
|
|
230
|
-
score: {
|
|
231
|
-
}
|
|
232
|
-
const result = ruleChecker(data, rules)
|
|
233
|
-
expect(result.valid).toBe(false)
|
|
229
|
+
score: {max: 100},
|
|
230
|
+
}
|
|
231
|
+
const result = ruleChecker(data, rules)
|
|
232
|
+
expect(result.valid).toBe(false)
|
|
234
233
|
if (!result.valid) {
|
|
235
|
-
expect(result.errors).toContain('score 不能大于 100')
|
|
234
|
+
expect(result.errors).toContain('score 不能大于 100')
|
|
236
235
|
}
|
|
237
|
-
})
|
|
236
|
+
})
|
|
238
237
|
|
|
239
238
|
it('应该通过数字范围验证', () => {
|
|
240
|
-
const data = {
|
|
239
|
+
const data = {percentage: 85}
|
|
241
240
|
const rules: RuleDescription<typeof data> = {
|
|
242
|
-
percentage: {
|
|
243
|
-
}
|
|
244
|
-
const result = ruleChecker(data, rules)
|
|
245
|
-
expect(result.valid).toBe(true)
|
|
246
|
-
})
|
|
247
|
-
})
|
|
241
|
+
percentage: {min: 0, max: 100},
|
|
242
|
+
}
|
|
243
|
+
const result = ruleChecker(data, rules)
|
|
244
|
+
expect(result.valid).toBe(true)
|
|
245
|
+
})
|
|
246
|
+
})
|
|
248
247
|
|
|
249
248
|
// ==== 数组规则测试 ====
|
|
250
249
|
describe('数组规则', () => {
|
|
251
250
|
it('应该验证数组长度 len', () => {
|
|
252
|
-
const data = {
|
|
251
|
+
const data = {items: [1, 2, 3]}
|
|
253
252
|
const rules: RuleDescription<typeof data> = {
|
|
254
|
-
items: {
|
|
255
|
-
}
|
|
256
|
-
const result = ruleChecker(data, rules)
|
|
257
|
-
expect(result.valid).toBe(false)
|
|
253
|
+
items: {len: 5},
|
|
254
|
+
}
|
|
255
|
+
const result = ruleChecker(data, rules)
|
|
256
|
+
expect(result.valid).toBe(false)
|
|
258
257
|
if (!result.valid) {
|
|
259
|
-
expect(result.errors).toContain('items 长度必须为 5')
|
|
258
|
+
expect(result.errors).toContain('items 长度必须为 5')
|
|
260
259
|
}
|
|
261
|
-
})
|
|
260
|
+
})
|
|
262
261
|
|
|
263
262
|
it('应该验证数组最小长度', () => {
|
|
264
|
-
const data = {
|
|
263
|
+
const data = {tags: ['one']}
|
|
265
264
|
const rules: RuleDescription<typeof data> = {
|
|
266
|
-
tags: {
|
|
267
|
-
}
|
|
268
|
-
const result = ruleChecker(data, rules)
|
|
269
|
-
expect(result.valid).toBe(false)
|
|
265
|
+
tags: {min: 2},
|
|
266
|
+
}
|
|
267
|
+
const result = ruleChecker(data, rules)
|
|
268
|
+
expect(result.valid).toBe(false)
|
|
270
269
|
if (!result.valid) {
|
|
271
|
-
expect(result.errors).toContain('tags 长度不能小于 2')
|
|
270
|
+
expect(result.errors).toContain('tags 长度不能小于 2')
|
|
272
271
|
}
|
|
273
|
-
})
|
|
272
|
+
})
|
|
274
273
|
|
|
275
274
|
it('应该验证数组最大长度', () => {
|
|
276
|
-
const data = {
|
|
275
|
+
const data = {categories: [1, 2, 3, 4, 5, 6]}
|
|
277
276
|
const rules: RuleDescription<typeof data> = {
|
|
278
|
-
categories: {
|
|
279
|
-
}
|
|
280
|
-
const result = ruleChecker(data, rules)
|
|
281
|
-
expect(result.valid).toBe(false)
|
|
277
|
+
categories: {max: 5},
|
|
278
|
+
}
|
|
279
|
+
const result = ruleChecker(data, rules)
|
|
280
|
+
expect(result.valid).toBe(false)
|
|
282
281
|
if (!result.valid) {
|
|
283
|
-
expect(result.errors).toContain('categories 长度不能大于 5')
|
|
282
|
+
expect(result.errors).toContain('categories 长度不能大于 5')
|
|
284
283
|
}
|
|
285
|
-
})
|
|
284
|
+
})
|
|
286
285
|
|
|
287
286
|
it('应该验证数组元素唯一性', () => {
|
|
288
|
-
const data = {
|
|
287
|
+
const data = {ids: [1, 2, 2, 3]}
|
|
289
288
|
const rules: RuleDescription<typeof data> = {
|
|
290
|
-
ids: {
|
|
291
|
-
}
|
|
292
|
-
const result = ruleChecker(data, rules)
|
|
293
|
-
expect(result.valid).toBe(false)
|
|
289
|
+
ids: {unique: true},
|
|
290
|
+
}
|
|
291
|
+
const result = ruleChecker(data, rules)
|
|
292
|
+
expect(result.valid).toBe(false)
|
|
294
293
|
if (!result.valid) {
|
|
295
|
-
expect(result.errors).toContain('ids 元素必须唯一')
|
|
294
|
+
expect(result.errors).toContain('ids 元素必须唯一')
|
|
296
295
|
}
|
|
297
|
-
})
|
|
296
|
+
})
|
|
298
297
|
|
|
299
298
|
it('应该通过数组元素唯一性验证', () => {
|
|
300
|
-
const data = {
|
|
299
|
+
const data = {ids: [1, 2, 3, 4]}
|
|
301
300
|
const rules: RuleDescription<typeof data> = {
|
|
302
|
-
ids: {
|
|
303
|
-
}
|
|
304
|
-
const result = ruleChecker(data, rules)
|
|
305
|
-
expect(result.valid).toBe(true)
|
|
306
|
-
})
|
|
301
|
+
ids: {unique: true},
|
|
302
|
+
}
|
|
303
|
+
const result = ruleChecker(data, rules)
|
|
304
|
+
expect(result.valid).toBe(true)
|
|
305
|
+
})
|
|
307
306
|
|
|
308
307
|
it('应该验证数组元素规则', () => {
|
|
309
|
-
const data = {
|
|
308
|
+
const data = {emails: ['valid@email.com', 'invalid-email']}
|
|
310
309
|
const rules: RuleDescription<typeof data> = {
|
|
311
310
|
emails: {
|
|
312
|
-
elementRule: {
|
|
311
|
+
elementRule: {email: true},
|
|
313
312
|
},
|
|
314
|
-
}
|
|
315
|
-
const result = ruleChecker(data, rules)
|
|
316
|
-
expect(result.valid).toBe(false)
|
|
313
|
+
}
|
|
314
|
+
const result = ruleChecker(data, rules)
|
|
315
|
+
expect(result.valid).toBe(false)
|
|
317
316
|
if (!result.valid) {
|
|
318
317
|
// 检查错误信息包含了数组元素索引的错误
|
|
319
|
-
expect(result.errors.some((error) => error.includes('emails[1]'))).toBe(
|
|
320
|
-
true
|
|
321
|
-
);
|
|
318
|
+
expect(result.errors.some((error) => error.includes('emails[1]'))).toBe(true)
|
|
322
319
|
}
|
|
323
|
-
})
|
|
324
|
-
})
|
|
320
|
+
})
|
|
321
|
+
})
|
|
325
322
|
|
|
326
323
|
// ==== 依赖验证测试 ====
|
|
327
324
|
describe('依赖验证', () => {
|
|
328
325
|
it('应该验证 dependsOn - 返回 boolean', () => {
|
|
329
|
-
const data = {
|
|
326
|
+
const data = {type: 'premium', discount: 0.9}
|
|
330
327
|
const rules: RuleDescription<typeof data> = {
|
|
331
328
|
discount: {
|
|
332
329
|
dependsOn: (data) => data.type === 'basic', // 当类型不是basic时会失败
|
|
333
330
|
message: '只有基础用户才能设置折扣',
|
|
334
331
|
},
|
|
335
|
-
}
|
|
336
|
-
const result = ruleChecker(data, rules)
|
|
337
|
-
expect(result.valid).toBe(false)
|
|
332
|
+
}
|
|
333
|
+
const result = ruleChecker(data, rules)
|
|
334
|
+
expect(result.valid).toBe(false)
|
|
338
335
|
if (!result.valid) {
|
|
339
|
-
expect(result.errors).toContain('只有基础用户才能设置折扣')
|
|
336
|
+
expect(result.errors).toContain('只有基础用户才能设置折扣')
|
|
340
337
|
}
|
|
341
|
-
})
|
|
338
|
+
})
|
|
342
339
|
|
|
343
340
|
it('应该验证 dependsOn - 返回 string', () => {
|
|
344
|
-
const data = {
|
|
341
|
+
const data = {age: 16, hasLicense: true}
|
|
345
342
|
const rules: RuleDescription<typeof data> = {
|
|
346
343
|
hasLicense: {
|
|
347
|
-
dependsOn: (data) =>
|
|
348
|
-
(data.age || 0) < 18 ? '未成年人不能有驾驶证' : true,
|
|
344
|
+
dependsOn: (data) => ((data.age || 0) < 18 ? '未成年人不能有驾驶证' : true),
|
|
349
345
|
},
|
|
350
|
-
}
|
|
351
|
-
const result = ruleChecker(data, rules)
|
|
352
|
-
expect(result.valid).toBe(false)
|
|
346
|
+
}
|
|
347
|
+
const result = ruleChecker(data, rules)
|
|
348
|
+
expect(result.valid).toBe(false)
|
|
353
349
|
if (!result.valid) {
|
|
354
|
-
expect(result.errors).toContain('未成年人不能有驾驶证')
|
|
350
|
+
expect(result.errors).toContain('未成年人不能有驾驶证')
|
|
355
351
|
}
|
|
356
|
-
})
|
|
352
|
+
})
|
|
357
353
|
|
|
358
354
|
it('应该通过 dependsOn 验证', () => {
|
|
359
|
-
const data = {
|
|
355
|
+
const data = {type: 'basic', discount: undefined}
|
|
360
356
|
const rules: RuleDescription<typeof data> = {
|
|
361
357
|
discount: {
|
|
362
358
|
dependsOn: (data) => data.type === 'premium',
|
|
363
359
|
},
|
|
364
|
-
}
|
|
365
|
-
const result = ruleChecker(data, rules)
|
|
366
|
-
expect(result.valid).toBe(true)
|
|
367
|
-
})
|
|
368
|
-
})
|
|
360
|
+
}
|
|
361
|
+
const result = ruleChecker(data, rules)
|
|
362
|
+
expect(result.valid).toBe(true)
|
|
363
|
+
})
|
|
364
|
+
})
|
|
369
365
|
|
|
370
366
|
// ==== 复杂场景测试 ====
|
|
371
367
|
describe('复杂场景', () => {
|
|
372
368
|
it('应该处理多个规则数组', () => {
|
|
373
|
-
const data = {
|
|
369
|
+
const data = {password: '123'}
|
|
374
370
|
const rules: RuleDescription<typeof data> = {
|
|
375
371
|
password: [
|
|
376
|
-
{
|
|
377
|
-
{
|
|
378
|
-
{
|
|
372
|
+
{required: true},
|
|
373
|
+
{min: 6, message: '密码至少6位'},
|
|
374
|
+
{regex: /[A-Z]/, message: '密码必须包含大写字母'},
|
|
379
375
|
],
|
|
380
|
-
}
|
|
381
|
-
const result = ruleChecker(data, rules)
|
|
382
|
-
expect(result.valid).toBe(false)
|
|
376
|
+
}
|
|
377
|
+
const result = ruleChecker(data, rules)
|
|
378
|
+
expect(result.valid).toBe(false)
|
|
383
379
|
if (!result.valid) {
|
|
384
|
-
expect(result.errors).toContain('密码至少6位')
|
|
385
|
-
expect(result.errors).toContain('密码必须包含大写字母')
|
|
380
|
+
expect(result.errors).toContain('密码至少6位')
|
|
381
|
+
expect(result.errors).toContain('密码必须包含大写字母')
|
|
386
382
|
}
|
|
387
|
-
})
|
|
383
|
+
})
|
|
388
384
|
|
|
389
385
|
it('应该收集多个字段的错误', () => {
|
|
390
|
-
const data = {
|
|
391
|
-
const rules: RuleDescription<typeof data> = {
|
|
392
|
-
name: {
|
|
393
|
-
email: {
|
|
394
|
-
age: {
|
|
395
|
-
}
|
|
396
|
-
const result = ruleChecker(data, rules)
|
|
397
|
-
expect(result.valid).toBe(false)
|
|
386
|
+
const data = {name: '', email: 'invalid', age: 5}
|
|
387
|
+
const rules: RuleDescription<typeof data> = {
|
|
388
|
+
name: {required: true},
|
|
389
|
+
email: {email: true},
|
|
390
|
+
age: {min: 18},
|
|
391
|
+
}
|
|
392
|
+
const result = ruleChecker(data, rules)
|
|
393
|
+
expect(result.valid).toBe(false)
|
|
398
394
|
if (!result.valid) {
|
|
399
|
-
expect(result.errors).toHaveLength(3)
|
|
400
|
-
expect(result.fieldErrors.name).toContain('name 为必填项')
|
|
401
|
-
expect(result.fieldErrors.email).toContain('email 不是有效的邮箱')
|
|
402
|
-
expect(result.fieldErrors.age).toContain('age 不能小于 18')
|
|
395
|
+
expect(result.errors).toHaveLength(3)
|
|
396
|
+
expect(result.fieldErrors.name).toContain('name 为必填项')
|
|
397
|
+
expect(result.fieldErrors.email).toContain('email 不是有效的邮箱')
|
|
398
|
+
expect(result.fieldErrors.age).toContain('age 不能小于 18')
|
|
403
399
|
}
|
|
404
|
-
})
|
|
400
|
+
})
|
|
405
401
|
|
|
406
402
|
it('应该处理复杂的用户注册场景', () => {
|
|
407
403
|
const data = {
|
|
@@ -412,86 +408,77 @@ describe('ruleChecker', () => {
|
|
|
412
408
|
age: 25,
|
|
413
409
|
hobbies: ['reading'],
|
|
414
410
|
terms: false,
|
|
415
|
-
}
|
|
411
|
+
}
|
|
416
412
|
|
|
417
413
|
const rules: RuleDescription<typeof data> = {
|
|
418
|
-
username: {
|
|
419
|
-
email: {
|
|
420
|
-
password: [
|
|
421
|
-
{ required: true },
|
|
422
|
-
{ min: 6 },
|
|
423
|
-
{ regex: /[A-Z]/, message: '密码必须包含大写字母' },
|
|
424
|
-
],
|
|
414
|
+
username: {required: true, min: 3, max: 20},
|
|
415
|
+
email: {required: true, email: true},
|
|
416
|
+
password: [{required: true}, {min: 6}, {regex: /[A-Z]/, message: '密码必须包含大写字母'}],
|
|
425
417
|
confirmPassword: {
|
|
426
418
|
required: true,
|
|
427
|
-
validator: (value, data) =>
|
|
428
|
-
value === data.password || '两次密码不一致',
|
|
419
|
+
validator: (value, data) => value === data.password || '两次密码不一致',
|
|
429
420
|
},
|
|
430
|
-
age: {
|
|
431
|
-
hobbies: {
|
|
421
|
+
age: {required: true, min: 18, max: 120},
|
|
422
|
+
hobbies: {min: 2, max: 5},
|
|
432
423
|
terms: {
|
|
433
424
|
required: true,
|
|
434
425
|
validator: (value) => value === true || '必须同意用户协议',
|
|
435
426
|
},
|
|
436
|
-
}
|
|
427
|
+
}
|
|
437
428
|
|
|
438
|
-
const result = ruleChecker(data, rules)
|
|
439
|
-
expect(result.valid).toBe(false)
|
|
429
|
+
const result = ruleChecker(data, rules)
|
|
430
|
+
expect(result.valid).toBe(false)
|
|
440
431
|
if (!result.valid) {
|
|
441
|
-
expect(result.fieldErrors.username).toContain(
|
|
442
|
-
|
|
443
|
-
)
|
|
444
|
-
expect(result.fieldErrors.
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
expect(result.fieldErrors.hobbies).toContain('hobbies 长度不能小于 2');
|
|
449
|
-
expect(result.fieldErrors.terms).toContain('必须同意用户协议');
|
|
450
|
-
}
|
|
451
|
-
});
|
|
432
|
+
expect(result.fieldErrors.username).toContain('username 长度不能少于 3')
|
|
433
|
+
expect(result.fieldErrors.password).toContain('password 长度不能少于 6')
|
|
434
|
+
expect(result.fieldErrors.confirmPassword).toContain('两次密码不一致')
|
|
435
|
+
expect(result.fieldErrors.hobbies).toContain('hobbies 长度不能小于 2')
|
|
436
|
+
expect(result.fieldErrors.terms).toContain('必须同意用户协议')
|
|
437
|
+
}
|
|
438
|
+
})
|
|
452
439
|
|
|
453
440
|
it('应该在所有验证通过时返回正确的数据', () => {
|
|
454
441
|
const data = {
|
|
455
442
|
name: 'John Doe',
|
|
456
443
|
email: 'john@example.com',
|
|
457
444
|
age: 30,
|
|
458
|
-
}
|
|
445
|
+
}
|
|
459
446
|
|
|
460
447
|
const rules: RuleDescription<typeof data> = {
|
|
461
|
-
name: {
|
|
462
|
-
email: {
|
|
463
|
-
age: {
|
|
464
|
-
}
|
|
448
|
+
name: {required: true, min: 2},
|
|
449
|
+
email: {required: true, email: true},
|
|
450
|
+
age: {required: true, min: 18, max: 120},
|
|
451
|
+
}
|
|
465
452
|
|
|
466
|
-
const result = ruleChecker(data, rules)
|
|
467
|
-
expect(result.valid).toBe(true)
|
|
453
|
+
const result = ruleChecker(data, rules)
|
|
454
|
+
expect(result.valid).toBe(true)
|
|
468
455
|
if (result.valid) {
|
|
469
|
-
expect(result.data).toEqual(data)
|
|
456
|
+
expect(result.data).toEqual(data)
|
|
470
457
|
}
|
|
471
|
-
})
|
|
472
|
-
})
|
|
458
|
+
})
|
|
459
|
+
})
|
|
473
460
|
|
|
474
461
|
// ==== 类型安全测试 ====
|
|
475
462
|
describe('类型安全验证', () => {
|
|
476
463
|
it('数字字段应该只支持数字相关规则', () => {
|
|
477
|
-
const data = {
|
|
464
|
+
const data = {age: 25}
|
|
478
465
|
|
|
479
466
|
// 这些应该是有效的数字规则
|
|
480
467
|
const validRules: RuleDescription<typeof data> = {
|
|
481
|
-
age: {
|
|
482
|
-
}
|
|
468
|
+
age: {min: 0, max: 120, required: true},
|
|
469
|
+
}
|
|
483
470
|
|
|
484
|
-
const result = ruleChecker(data, validRules)
|
|
485
|
-
expect(result.valid).toBe(true)
|
|
471
|
+
const result = ruleChecker(data, validRules)
|
|
472
|
+
expect(result.valid).toBe(true)
|
|
486
473
|
|
|
487
474
|
// 注意:TypeScript 会阻止以下无效的数字规则
|
|
488
475
|
// age: { email: true }, // ❌ 编译错误
|
|
489
476
|
// age: { regex: /test/ }, // ❌ 编译错误
|
|
490
477
|
// age: { len: 10 }, // ❌ 编译错误
|
|
491
|
-
})
|
|
478
|
+
})
|
|
492
479
|
|
|
493
480
|
it('字符串字段应该支持长度和格式规则', () => {
|
|
494
|
-
const data = {
|
|
481
|
+
const data = {email: 'test@example.com', name: 'John'}
|
|
495
482
|
|
|
496
483
|
const rules: RuleDescription<typeof data> = {
|
|
497
484
|
email: {
|
|
@@ -506,35 +493,35 @@ describe('ruleChecker', () => {
|
|
|
506
493
|
max: 50,
|
|
507
494
|
regex: /^[a-zA-Z]+$/,
|
|
508
495
|
},
|
|
509
|
-
}
|
|
496
|
+
}
|
|
510
497
|
|
|
511
|
-
const result = ruleChecker(data, rules)
|
|
512
|
-
expect(result.valid).toBe(true)
|
|
513
|
-
})
|
|
498
|
+
const result = ruleChecker(data, rules)
|
|
499
|
+
expect(result.valid).toBe(true)
|
|
500
|
+
})
|
|
514
501
|
|
|
515
502
|
it('数组字段应该支持长度和唯一性规则', () => {
|
|
516
|
-
const data = {
|
|
503
|
+
const data = {tags: ['react', 'typescript'], ids: [1, 2, 3]}
|
|
517
504
|
|
|
518
505
|
const rules: RuleDescription<typeof data> = {
|
|
519
506
|
tags: {
|
|
520
507
|
min: 1,
|
|
521
508
|
max: 5,
|
|
522
509
|
unique: true,
|
|
523
|
-
elementRule: {
|
|
510
|
+
elementRule: {min: 2, max: 20}, // 元素是字符串
|
|
524
511
|
},
|
|
525
512
|
ids: {
|
|
526
513
|
len: 3,
|
|
527
514
|
unique: true,
|
|
528
|
-
elementRule: {
|
|
515
|
+
elementRule: {min: 1, max: 1000}, // 元素是数字
|
|
529
516
|
},
|
|
530
|
-
}
|
|
517
|
+
}
|
|
531
518
|
|
|
532
|
-
const result = ruleChecker(data, rules)
|
|
533
|
-
expect(result.valid).toBe(true)
|
|
534
|
-
})
|
|
519
|
+
const result = ruleChecker(data, rules)
|
|
520
|
+
expect(result.valid).toBe(true)
|
|
521
|
+
})
|
|
535
522
|
|
|
536
523
|
it('布尔字段应该只支持基础规则', () => {
|
|
537
|
-
const data = {
|
|
524
|
+
const data = {isActive: false, hasPermission: false}
|
|
538
525
|
|
|
539
526
|
const rules: RuleDescription<typeof data> = {
|
|
540
527
|
isActive: {
|
|
@@ -544,14 +531,14 @@ describe('ruleChecker', () => {
|
|
|
544
531
|
hasPermission: {
|
|
545
532
|
required: true,
|
|
546
533
|
},
|
|
547
|
-
}
|
|
534
|
+
}
|
|
548
535
|
|
|
549
|
-
const result = ruleChecker(data, rules)
|
|
550
|
-
expect(result.valid).toBe(false)
|
|
536
|
+
const result = ruleChecker(data, rules)
|
|
537
|
+
expect(result.valid).toBe(false)
|
|
551
538
|
if (!result.valid) {
|
|
552
|
-
expect(result.errors).toContain('必须激活账户')
|
|
539
|
+
expect(result.errors).toContain('必须激活账户')
|
|
553
540
|
}
|
|
554
|
-
})
|
|
541
|
+
})
|
|
555
542
|
|
|
556
543
|
it('应该正确处理混合类型的复杂对象', () => {
|
|
557
544
|
const data = {
|
|
@@ -561,89 +548,89 @@ describe('ruleChecker', () => {
|
|
|
561
548
|
tags: ['electronics', 'mobile'],
|
|
562
549
|
isActive: true,
|
|
563
550
|
description: 'A great product',
|
|
564
|
-
}
|
|
551
|
+
}
|
|
565
552
|
|
|
566
553
|
const rules: RuleDescription<typeof data> = {
|
|
567
|
-
id: {
|
|
568
|
-
name: {
|
|
569
|
-
price: {
|
|
570
|
-
tags: {
|
|
571
|
-
isActive: {
|
|
572
|
-
description: {
|
|
573
|
-
}
|
|
554
|
+
id: {required: true, min: 1}, // 数字规则
|
|
555
|
+
name: {required: true, min: 3, max: 50}, // 字符串长度规则
|
|
556
|
+
price: {required: true, min: 0, max: 10000}, // 数字范围规则
|
|
557
|
+
tags: {min: 1, max: 10, unique: true}, // 数组规则
|
|
558
|
+
isActive: {required: true}, // 布尔基础规则
|
|
559
|
+
description: {min: 10, max: 500, regex: /^[a-zA-Z\s]+$/}, // 字符串格式规则
|
|
560
|
+
}
|
|
574
561
|
|
|
575
|
-
const result = ruleChecker(data, rules)
|
|
576
|
-
expect(result.valid).toBe(true)
|
|
577
|
-
})
|
|
578
|
-
})
|
|
562
|
+
const result = ruleChecker(data, rules)
|
|
563
|
+
expect(result.valid).toBe(true)
|
|
564
|
+
})
|
|
565
|
+
})
|
|
579
566
|
|
|
580
567
|
// ==== 边缘情况测试 ====
|
|
581
568
|
describe('边缘情况', () => {
|
|
582
569
|
it('应该正确处理空字符串的各种验证', () => {
|
|
583
|
-
const data = {
|
|
570
|
+
const data = {text: ''}
|
|
584
571
|
const rules: RuleDescription<typeof data> = {
|
|
585
|
-
text: {
|
|
586
|
-
}
|
|
587
|
-
const result = ruleChecker(data, rules)
|
|
588
|
-
expect(result.valid).toBe(false)
|
|
589
|
-
})
|
|
572
|
+
text: {min: 1}, // 空字符串长度为0,应该失败
|
|
573
|
+
}
|
|
574
|
+
const result = ruleChecker(data, rules)
|
|
575
|
+
expect(result.valid).toBe(false)
|
|
576
|
+
})
|
|
590
577
|
|
|
591
578
|
it('应该正确处理空数组的各种验证', () => {
|
|
592
|
-
const data = {
|
|
579
|
+
const data = {items: [] as string[]}
|
|
593
580
|
const rules: RuleDescription<typeof data> = {
|
|
594
|
-
items: {
|
|
595
|
-
}
|
|
596
|
-
const result = ruleChecker(data, rules)
|
|
597
|
-
expect(result.valid).toBe(false)
|
|
598
|
-
})
|
|
581
|
+
items: {min: 1}, // 空数组长度为0,应该失败
|
|
582
|
+
}
|
|
583
|
+
const result = ruleChecker(data, rules)
|
|
584
|
+
expect(result.valid).toBe(false)
|
|
585
|
+
})
|
|
599
586
|
|
|
600
587
|
it('应该正确处理数字 0 的验证', () => {
|
|
601
|
-
const data = {
|
|
588
|
+
const data = {count: 0}
|
|
602
589
|
const rules: RuleDescription<typeof data> = {
|
|
603
|
-
count: {
|
|
604
|
-
}
|
|
605
|
-
const result = ruleChecker(data, rules)
|
|
606
|
-
expect(result.valid).toBe(true)
|
|
607
|
-
})
|
|
590
|
+
count: {required: true, min: 0}, // 0 是有效值,应该通过
|
|
591
|
+
}
|
|
592
|
+
const result = ruleChecker(data, rules)
|
|
593
|
+
expect(result.valid).toBe(true)
|
|
594
|
+
})
|
|
608
595
|
|
|
609
596
|
it('应该正确处理 false 值的验证', () => {
|
|
610
|
-
const data = {
|
|
597
|
+
const data = {isEnabled: false}
|
|
611
598
|
const rules: RuleDescription<typeof data> = {
|
|
612
|
-
isEnabled: {
|
|
613
|
-
}
|
|
614
|
-
const result = ruleChecker(data, rules)
|
|
615
|
-
expect(result.valid).toBe(true)
|
|
616
|
-
})
|
|
599
|
+
isEnabled: {required: true}, // false 是有效值,应该通过
|
|
600
|
+
}
|
|
601
|
+
const result = ruleChecker(data, rules)
|
|
602
|
+
expect(result.valid).toBe(true)
|
|
603
|
+
})
|
|
617
604
|
|
|
618
605
|
it('应该正确处理只有空格的字符串', () => {
|
|
619
|
-
const data = {
|
|
606
|
+
const data = {text: ' '}
|
|
620
607
|
const rules: RuleDescription<typeof data> = {
|
|
621
|
-
text: {
|
|
622
|
-
}
|
|
623
|
-
const result = ruleChecker(data, rules)
|
|
624
|
-
expect(result.valid).toBe(false)
|
|
625
|
-
})
|
|
608
|
+
text: {required: true}, // 只有空格被视为空值,应该失败
|
|
609
|
+
}
|
|
610
|
+
const result = ruleChecker(data, rules)
|
|
611
|
+
expect(result.valid).toBe(false)
|
|
612
|
+
})
|
|
626
613
|
|
|
627
614
|
it('应该处理非常长的字符串', () => {
|
|
628
|
-
const longText = 'a'.repeat(1000)
|
|
629
|
-
const data = {
|
|
615
|
+
const longText = 'a'.repeat(1000)
|
|
616
|
+
const data = {content: longText}
|
|
630
617
|
const rules: RuleDescription<typeof data> = {
|
|
631
|
-
content: {
|
|
632
|
-
}
|
|
633
|
-
const result = ruleChecker(data, rules)
|
|
634
|
-
expect(result.valid).toBe(false)
|
|
618
|
+
content: {max: 500}, // 超过最大长度,应该失败
|
|
619
|
+
}
|
|
620
|
+
const result = ruleChecker(data, rules)
|
|
621
|
+
expect(result.valid).toBe(false)
|
|
635
622
|
if (!result.valid) {
|
|
636
|
-
expect(result.errors).toContain('content 长度不能超过 500')
|
|
623
|
+
expect(result.errors).toContain('content 长度不能超过 500')
|
|
637
624
|
}
|
|
638
|
-
})
|
|
625
|
+
})
|
|
639
626
|
|
|
640
627
|
it('应该处理复杂的嵌套数组元素验证', () => {
|
|
641
628
|
const data = {
|
|
642
629
|
users: [
|
|
643
|
-
{
|
|
644
|
-
{
|
|
630
|
+
{name: 'Alice', email: 'alice@test.com'},
|
|
631
|
+
{name: 'B', email: 'invalid-email'}, // 名字太短,邮箱无效
|
|
645
632
|
],
|
|
646
|
-
}
|
|
633
|
+
}
|
|
647
634
|
|
|
648
635
|
// 注意:这个例子展示了当前系统的限制
|
|
649
636
|
// 对于复杂嵌套对象,需要扩展 elementRule 支持
|
|
@@ -653,10 +640,10 @@ describe('ruleChecker', () => {
|
|
|
653
640
|
max: 10,
|
|
654
641
|
// elementRule 目前不支持对象验证
|
|
655
642
|
},
|
|
656
|
-
}
|
|
643
|
+
}
|
|
657
644
|
|
|
658
|
-
const result = ruleChecker(data, rules)
|
|
659
|
-
expect(result.valid).toBe(true)
|
|
660
|
-
})
|
|
661
|
-
})
|
|
662
|
-
})
|
|
645
|
+
const result = ruleChecker(data, rules)
|
|
646
|
+
expect(result.valid).toBe(true) // 基本数组规则通过
|
|
647
|
+
})
|
|
648
|
+
})
|
|
649
|
+
})
|