Skip to content

Commit

Permalink
feat(yup): 添加 validateInOrder, validateInOrderSync 支持按顺序验证对象
Browse files Browse the repository at this point in the history
  • Loading branch information
fjc0k committed Aug 13, 2020
1 parent 1835c3d commit 50a1c42
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 3 deletions.
4 changes: 1 addition & 3 deletions src/react/useValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,7 @@ export function useValidator<T>(
try {
// yup 不能保证验证顺序,但通常顺序又是很重要的,因此对于 object 特殊处理
if (yupSchema.type === 'object') {
for (const key of Object.keys(data)) {
yupSchema.validateSyncAt(key, data, validateOptions)
}
;(yupSchema as _yup.ObjectSchema).validateInOrderSync(data)
} else {
yupSchema.validateSync(data, validateOptions)
}
Expand Down
9 changes: 9 additions & 0 deletions src/validator/__snapshots__/yup.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`yup validateInOrder 正常: 姓名必填 1`] = `[ValidationError: 姓名必填]`;

exports[`yup validateInOrder 正常: 密码有误 1`] = `[ValidationError: 密码必须大于或等于100]`;

exports[`yup validateInOrderSync 正常: 姓名必填 1`] = `[ValidationError: 姓名必填]`;

exports[`yup validateInOrderSync 正常: 密码有误 1`] = `[ValidationError: 密码必须大于或等于100]`;
61 changes: 61 additions & 0 deletions src/validator/yup.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { enUS } from './locale/enUS'
import { run } from '../utils'
import { yup } from './yup'
import { zhCN } from './locale/zhCN'

Expand Down Expand Up @@ -34,4 +35,64 @@ describe('yup', () => {
yup.string().chineseIDCardNumber().validate('11010119881101331X'),
).resolves.toBe('11010119881101331X')
})

test('validateInOrder 正常', async () => {
const rule = yup.object({
name: yup.string().label('姓名').required(),
pass: yup.number().label('密码').required().min(100),
})
const [nameErr] = await run(() =>
rule.validateInOrder({
name: '',
pass: 99,
}),
)
expect(nameErr).toMatchSnapshot('姓名必填')
const [passErr] = await run(() =>
rule.validateInOrder({
pass: 99,
name: '',
}),
)
expect(passErr).toMatchSnapshot('密码有误')
expect(
await rule.validateInOrder({
name: '8',
pass: 101,
}),
).toEqual({
name: '8',
pass: 101,
})
})

test('validateInOrderSync 正常', async () => {
const rule = yup.object({
name: yup.string().label('姓名').required(),
pass: yup.number().label('密码').required().min(100),
})
const [nameErr] = await run(() =>
rule.validateInOrderSync({
name: '',
pass: 99,
}),
)
expect(nameErr).toMatchSnapshot('姓名必填')
const [passErr] = await run(() =>
rule.validateInOrderSync({
pass: 99,
name: '',
}),
)
expect(passErr).toMatchSnapshot('密码有误')
expect(
rule.validateInOrderSync({
name: '8',
pass: 101,
}),
).toEqual({
name: '8',
pass: 101,
})
})
})
23 changes: 23 additions & 0 deletions src/validator/yup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,29 @@ yup.addMethod(yup.string, 'chineseIDCardNumber', function (
return this.test('chineseIDCardNumber', message, isChineseIDCardNumber)
})

// 实现 validateInOrder 方法
yup.addMethod(yup.object, 'validateInOrder', function (
data: any,
options: any,
) {
return Object.keys(data)
.reduce((prev, key) => {
return prev.then(() => this.validateAt(key, data, options))
}, Promise.resolve())
.then(() => this.cast(data)) as any
})

// 实现 validateInOrderSync 方法
yup.addMethod(yup.object, 'validateInOrderSync', function (
data: any,
options: any,
) {
for (const key of Object.keys(data)) {
this.validateSyncAt(key, data, options)
}
return this.cast(data)
})

// 设置中文为默认语言
yup.setLocale(zhCN)

Expand Down
4 changes: 4 additions & 0 deletions src/validator/yupTypes/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ declare module 'yup/es' {
camelCase(): this

constantCase(): this

validateInOrder(value: T, options?: SchemaValidateOptions): Promise<T>

validateInOrderSync(value: T, options?: SchemaValidateOptions): T
}

export function object<T extends {} = {}>(
Expand Down

0 comments on commit 50a1c42

Please sign in to comment.