Skip to content

Commit

Permalink
feat(validator): oneOf 支持 enum
Browse files Browse the repository at this point in the history
  • Loading branch information
fjc0k committed Jul 14, 2023
1 parent 71f5265 commit ecbd9f6
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 5 deletions.
40 changes: 39 additions & 1 deletion src/validator/__snapshots__/yup.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Object {
"posts": Array [
Object {
"content": "dd",
"createdAt": 2023-07-13T08:53:33.243Z,
"createdAt": 2023-07-14T02:01:17.763Z,
"id": 1,
"isTop": true,
"tags": Array [],
Expand Down Expand Up @@ -366,6 +366,44 @@ Object {
}
`;

exports[`yup oneOf-enum 1`] = `
Object {
"data": Object {
"id": 1,
"status": "pending",
},
}
`;

exports[`yup oneOf-enum 2`] = `
Object {
"data": Object {
"id": 1,
"status": "pending2",
},
"error": [ValidationError: 此项必须是下列值之一: pending, success, failed],
}
`;

exports[`yup oneOf-obj 1`] = `
Object {
"data": Object {
"id": 1,
"status": "pending",
},
}
`;

exports[`yup oneOf-obj 2`] = `
Object {
"data": Object {
"id": 1,
"status": "pending2",
},
"error": [ValidationError: 此项必须是下列值之一: pending, success, failed],
}
`;

exports[`yup ref root 1`] = `
Object {
"data": Object {
Expand Down
69 changes: 69 additions & 0 deletions src/validator/yup.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,4 +417,73 @@ describe('yup', () => {
}),
).toMatchSnapshot()
})

test('oneOf-obj', () => {
const Status = {
pending: 'pending',
success: 'success',
failed: 'failed',
} as const
type Status = typeof Status[keyof typeof Status]

type Message = {
id: number
status: Status
}

const _ = yup
const messageSchema: yup.GetSchema<Message> = _.object($ =>
$.shape({
id: _.number().required(),
status: _.string($ => $.oneOf(Status)),
}),
)
expect(
messageSchema.validatePlusSync({
id: 1,
status: 'pending',
}),
).toMatchSnapshot()
expect(
messageSchema.validatePlusSync({
id: 1,
// @ts-expect-error
status: 'pending2',
}),
).toMatchSnapshot()
})

test('oneOf-enum', () => {
enum Status {
pending = 'pending',
success = 'success',
failed = 'failed',
}

type Message = {
id: number
status: Status
}

const _ = yup
const messageSchema: yup.GetSchema<Message> = _.object($ =>
$.shape({
id: _.number().required(),
status: _.string($ => $.enum(Status)),
}),
)
expect(
messageSchema.validatePlusSync({
id: 1,
status: Status.pending,
}),
).toMatchSnapshot()
expect(
messageSchema.validatePlusSync({
id: 1,
// @ts-expect-error
status: 'pending2',
}),
).toMatchSnapshot()
})
})
8 changes: 6 additions & 2 deletions src/validator/yupSource/mixed.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { cloneDeepWith, has, toArray } from '../../utils'
import { cloneDeepWith, has, toArray, values } from '../../utils'

import Condition from './Condition'
import Ref from './Reference'
Expand Down Expand Up @@ -534,6 +534,10 @@ const proto = (SchemaType.prototype = {
},

oneOf(enums, message = locale.oneOf) {
if (!Array.isArray(enums)) {
enums = values(enums)
}

var next = this.clone()

enums.forEach(val => {
Expand Down Expand Up @@ -643,6 +647,6 @@ for (const method of ['validate', 'validateSync'])
})
}

for (const alias of ['equals', 'is']) proto[alias] = proto.oneOf
for (const alias of ['equals', 'is', 'enum']) proto[alias] = proto.oneOf
for (const alias of ['not', 'nope']) proto[alias] = proto.notOneOf
proto.optional = proto.notRequired
17 changes: 15 additions & 2 deletions src/validator/yupTypes/mixed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,22 @@ export interface MixedSchema<T = any> {

typeError(message: LocaleValue): this

oneOf(arrayOfValues: Refable<T>[], message?: MixedLocale['oneOf']): this
oneOf(
arrayOfValues: Record<any, T> | Refable<T>[],
message?: MixedLocale['oneOf'],
): this

/** oneOf 的别名 */
enum(
arrayOfValues: Record<any, T> | Refable<T>[],
message?: MixedLocale['oneOf'],
): this

equals(arrayOfValues: Refable<T>[], message?: MixedLocale['oneOf']): this
/** oneOf 的别名 */
equals(
arrayOfValues: Record<any, T> | Refable<T>[],
message?: MixedLocale['oneOf'],
): this

notOneOf(arrayOfValues: Refable<T>[], message?: MixedLocale['notOneOf']): this

Expand Down

0 comments on commit ecbd9f6

Please sign in to comment.