Skip to content

Commit

Permalink
feat(cdk:forms): the setMessages supports setting locale for i18n (#1398
Browse files Browse the repository at this point in the history
)
  • Loading branch information
danranVm committed Jan 11, 2023
1 parent 2c58ca2 commit 0a8b116
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 125 deletions.
44 changes: 13 additions & 31 deletions packages/cdk/forms/__tests__/abstractControl.spec.ts
@@ -1,7 +1,6 @@
import { flushPromises } from '@vue/test-utils'
import { Ref, ref, watch } from 'vue'

import { zhCNMessages } from '../src/messages/zh-CN'
import { AbstractControl } from '../src/models/abstractControl'
import { AsyncValidatorFn, ValidateErrors, ValidatorFn, ValidatorOptions } from '../src/types'
import { Validators } from '../src/validators'
Expand Down Expand Up @@ -44,6 +43,8 @@ class Control<T = unknown> extends AbstractControl<T> {
}

describe('abstractControl.ts', () => {
const { getError } = Validators

describe('basic work', () => {
let control: AbstractControl

Expand Down Expand Up @@ -78,39 +79,27 @@ describe('abstractControl.ts', () => {
// setValidators start
control.setValidators(required)

expect(await control.validate()).toEqual({ required: { message: zhCNMessages.required({}, control) } })
expect(await control.validate()).toEqual({ required: getError('required', control) })

control.setValidators([email])
control.setValue('test')

expect(await control.validate()).toEqual({
email: { actual: 'test', message: zhCNMessages.email({ actual: 'test' }, control) },
})
expect(await control.validate()).toEqual({ email: getError('email', control, { actual: 'test' }) })
// setValidators end

// addValidators start
control.addValidators(minLength5)

expect(await control.validate()).toEqual({
email: { actual: 'test', message: zhCNMessages.email({ actual: 'test' }, control) },
minLength: {
actual: 4,
isArray: false,
minLength: 5,
message: zhCNMessages.minLength({ actual: 4, isArray: false, minLength: 5 }, control),
},
email: getError('email', control, { actual: 'test' }),
minLength: getError('minLength', control, { actual: 4, isArray: false, minLength: 5 }),
})

control.addValidators([maxLength10])
control.setValue('test@idux.com')

expect(await control.validate()).toEqual({
maxLength: {
actual: 13,
isArray: false,
maxLength: 10,
message: zhCNMessages.maxLength({ actual: 13, isArray: false, maxLength: 10 }, control),
},
maxLength: getError('maxLength', control, { actual: 13, isArray: false, maxLength: 10 }),
})
// addValidators end

Expand All @@ -122,9 +111,7 @@ describe('abstractControl.ts', () => {
control.removeValidators(minLength5)
control.setValue('test')

expect(await control.validate()).toEqual({
email: { actual: 'test', message: zhCNMessages.email({ actual: 'test' }, control) },
})
expect(await control.validate()).toEqual({ email: getError('email', control, { actual: 'test' }) })
// removeValidators end

// hasValidator start
Expand Down Expand Up @@ -305,7 +292,7 @@ describe('abstractControl.ts', () => {
test('options work', async () => {
control = new Control({ validators: Validators.required })

expect(await control.validate()).toEqual({ required: { message: zhCNMessages.required({}, control) } })
expect(await control.validate()).toEqual({ required: getError('required', control) })

expect(control.trigger).toEqual('change')

Expand All @@ -318,7 +305,7 @@ describe('abstractControl.ts', () => {
const _asyncValidator = (_: unknown) => Promise.resolve({ async: { message: 'async' } } as ValidateErrors)

control = new Control(Validators.required, _asyncValidator)
expect(await control.validate()).toEqual({ required: { message: zhCNMessages.required({}, control) } })
expect(await control.validate()).toEqual({ required: getError('required', control) })

control.setValue('test')
control.validate()
Expand All @@ -338,25 +325,20 @@ describe('abstractControl.ts', () => {

control.enable()

expect(await control.validate()).toEqual({ required: { message: zhCNMessages.required({}, control) } })
expect(await control.validate()).toEqual({ required: getError('required', control) })

control = new Control({
validators: [Validators.required, Validators.maxLength(5)],
disabled: (control, initializing) => (initializing ? false : control.valueRef.value === 'disabled'),
})

expect(await control.validate()).toEqual({ required: { message: zhCNMessages.required({}, control) } })
expect(await control.validate()).toEqual({ required: getError('required', control) })

control.setValue('disable')
await flushPromises()

expect(await control.validate()).toEqual({
maxLength: {
actual: 7,
isArray: false,
maxLength: 5,
message: zhCNMessages.maxLength({ actual: 7, isArray: false, maxLength: 5 }, control),
},
maxLength: getError('maxLength', control, { actual: 7, isArray: false, maxLength: 5 }),
})

control.setValue('disabled')
Expand Down
3 changes: 1 addition & 2 deletions packages/cdk/forms/__tests__/formControl.spec.ts
@@ -1,6 +1,5 @@
import { flushPromises } from '@vue/test-utils'

import { zhCNMessages } from '../src/messages/zh-CN'
import { FormControl } from '../src/models/formControl'
import { ValidateErrors } from '../src/types'
import { Validators } from '../src/validators'
Expand Down Expand Up @@ -73,7 +72,7 @@ describe('formControl.ts', () => {

control.setValidators(Validators.required)

expect(await control.validate()).toEqual({ required: { message: zhCNMessages.required({}, control) } })
expect(await control.validate()).toEqual({ required: Validators.getError('required', control) })
})
})

Expand Down
87 changes: 27 additions & 60 deletions packages/cdk/forms/__tests__/validators.spec.ts
@@ -1,11 +1,11 @@
import { enUSMessages } from '../src/messages/en-US'
import { zhCNMessages } from '../src/messages/zh-CN'
import { FormControl } from '../src/models/formControl'
import { AsyncValidatorFn, ValidateErrors, ValidateMessages, ValidatorFn } from '../src/types'
import { Validators } from '../src/validators'

describe('validators.ts', () => {
const control = new FormControl()
const { getError } = Validators

test('required work', () => {
const required = Validators.required
Expand All @@ -14,9 +14,7 @@ describe('validators.ts', () => {
expect(required('value', control)).toBeUndefined()
expect(required([1, 2], control)).toBeUndefined()

const errorMessage = {
required: { message: zhCNMessages.required({}, control) },
}
const errorMessage = { required: getError('required', control) }
expect(required(undefined, control)).toEqual(errorMessage)
expect(required(undefined, control)).toEqual(errorMessage)
expect(required('', control)).toEqual(errorMessage)
Expand All @@ -28,9 +26,8 @@ describe('validators.ts', () => {

expect(requiredTrue(true, control)).toBeUndefined()

const errorMessage = (actual: unknown) => ({
requiredTrue: { actual, message: zhCNMessages.requiredTrue({ actual }, control) },
})
const errorMessage = (actual: unknown) => ({ requiredTrue: getError('requiredTrue', control, { actual }) })

expect(requiredTrue(undefined, control)).toEqual(errorMessage(undefined))
expect(requiredTrue(undefined, control)).toEqual(errorMessage(undefined))
expect(requiredTrue('', control)).toEqual(errorMessage(''))
Expand All @@ -46,9 +43,8 @@ describe('validators.ts', () => {
expect(email(undefined, control)).toBeUndefined()
expect(email('test@gmail.com', control)).toBeUndefined()

const errorMessage = (actual: unknown) => ({
email: { actual, message: zhCNMessages.email({ actual }, control) },
})
const errorMessage = (actual: unknown) => ({ email: getError('email', control, { actual }) })

expect(email({}, control)).toEqual(errorMessage({}))
expect(email('test', control)).toEqual(errorMessage('test'))
})
Expand All @@ -63,9 +59,8 @@ describe('validators.ts', () => {
expect(minOne(1, control)).toBeUndefined()
expect(minOne(2, control)).toBeUndefined()

const errorMessage = (actual: unknown) => ({
min: { actual, min: 1, message: zhCNMessages.min({ actual, min: 1 }, control) },
})
const errorMessage = (actual: unknown) => ({ min: getError('min', control, { actual, min: 1 }) })

expect(minOne(0, control)).toEqual(errorMessage(0))
expect(minOne('0', control)).toEqual(errorMessage('0'))
})
Expand All @@ -80,9 +75,8 @@ describe('validators.ts', () => {
expect(maxOne(1, control)).toBeUndefined()
expect(maxOne(0, control)).toBeUndefined()

const errorMessage = (actual: unknown) => ({
max: { actual, max: 1, message: zhCNMessages.max({ actual, max: 1 }, control) },
})
const errorMessage = (actual: unknown) => ({ max: getError('max', control, { actual, max: 1 }) })

expect(maxOne(2, control)).toEqual(errorMessage(2))
expect(maxOne('2', control)).toEqual(errorMessage('2'))
})
Expand All @@ -97,9 +91,8 @@ describe('validators.ts', () => {
expect(range3To9(3, control)).toBeUndefined()
expect(range3To9(9, control)).toBeUndefined()

const errorMessage = (actual: unknown) => ({
range: { actual, min: 3, max: 9, message: zhCNMessages.range({ actual, min: 3, max: 9 }, control) },
})
const errorMessage = (actual: unknown) => ({ range: getError('range', control, { actual, min: 3, max: 9 }) })

expect(range3To9(2, control)).toEqual(errorMessage(2))
expect(range3To9('2', control)).toEqual(errorMessage('2'))
expect(range3To9(10, control)).toEqual(errorMessage(10))
Expand All @@ -119,13 +112,9 @@ describe('validators.ts', () => {
expect(minLengthTwo([1, 2, 3], control)).toBeUndefined()

const errorMessage = (actual: unknown, isArray: boolean) => ({
minLength: {
actual,
isArray,
minLength: 2,
message: zhCNMessages.minLength({ actual, isArray, minLength: 2 }, control),
},
minLength: getError('minLength', control, { actual, isArray, minLength: 2 }),
})

expect(minLengthTwo('t', control)).toEqual(errorMessage(1, false))
expect(minLengthTwo([1], control)).toEqual(errorMessage(1, true))
})
Expand All @@ -143,13 +132,9 @@ describe('validators.ts', () => {
expect(maxLengthTwo([1], control)).toBeUndefined()

const errorMessage = (actual: unknown, isArray: boolean) => ({
maxLength: {
actual,
isArray,
maxLength: 2,
message: zhCNMessages.maxLength({ actual, isArray, maxLength: 2 }, control),
},
maxLength: getError('maxLength', control, { actual, isArray, maxLength: 2 }),
})

expect(maxLengthTwo('test', control)).toEqual(errorMessage(4, false))
expect(maxLengthTwo([1, 2, 3], control)).toEqual(errorMessage(3, true))
})
Expand All @@ -167,14 +152,9 @@ describe('validators.ts', () => {
expect(rangeLength2To5([1, 2, 3, 4, 5], control)).toBeUndefined()

const errorMessage = (actual: unknown, isArray: boolean) => ({
rangeLength: {
actual,
isArray,
minLength: 2,
maxLength: 5,
message: zhCNMessages.rangeLength({ actual, isArray, minLength: 2, maxLength: 5 }, control),
},
rangeLength: getError('rangeLength', control, { actual, isArray, minLength: 2, maxLength: 5 }),
})

expect(rangeLength2To5('t', control)).toEqual(errorMessage(1, false))
expect(rangeLength2To5([1, 2, 3, 4, 5, 6], control)).toEqual(errorMessage(6, true))
})
Expand All @@ -189,12 +169,9 @@ describe('validators.ts', () => {
expect(stringPattern('test', control)).toBeUndefined()

let errorMessage = (actual: unknown) => ({
pattern: {
actual,
pattern: '^[a-zA-Z]+$',
message: zhCNMessages.pattern({ actual, pattern: '^[a-zA-Z]+$' }, control),
},
pattern: getError('pattern', control, { actual, pattern: '^[a-zA-Z]+$' }),
})

expect(stringPattern('test1', control)).toEqual(errorMessage('test1'))
expect(stringPattern(1, control)).toEqual(errorMessage(1))

Expand All @@ -209,26 +186,18 @@ describe('validators.ts', () => {
expect(regExpPattern('test', control)).toBeUndefined()
expect(regExpPattern('test1', control)).toBeUndefined()

errorMessage = (actual: unknown) => ({
pattern: {
actual,
pattern: '/[a-zA-Z]+/',
message: zhCNMessages.pattern({ actual, pattern: '/[a-zA-Z]+/' }, control),
},
})
errorMessage = (actual: unknown) => ({ pattern: getError('pattern', control, { actual, pattern: '/[a-zA-Z]+/' }) })

expect(regExpPattern(1, control)).toEqual(errorMessage(1))

const regExpPattern2 = Validators.pattern(new RegExp('^[a-zA-Z]+$'))

expect(regExpPattern2('test', control)).toBeUndefined()

errorMessage = (actual: unknown) => ({
pattern: {
actual,
pattern: '/^[a-zA-Z]+$/',
message: zhCNMessages.pattern({ actual, pattern: '/^[a-zA-Z]+$/' }, control),
},
pattern: getError('pattern', control, { actual, pattern: '/^[a-zA-Z]+$/' }),
})

expect(regExpPattern2('test1', control)).toEqual(errorMessage('test1'))
expect(regExpPattern2(1, control)).toEqual(errorMessage(1))
})
Expand All @@ -253,7 +222,7 @@ describe('validators.ts', () => {
})
expect(compose([_validator('a', message1), _validator('a', message2)])!('test', control)).toEqual({ a: message2 })
expect(compose([undefined, nullValidator, required])!('', control)).toEqual({
required: { message: zhCNMessages.required({}, control) },
required: getError('required', control),
})
})

Expand Down Expand Up @@ -286,10 +255,8 @@ describe('validators.ts', () => {

setMessages(enUSMessages)

expect(required('', control)).toEqual({ required: { message: enUSMessages.required({}, control) } })
expect(requiredTrue(false, control)).toEqual({
requiredTrue: { message: enUSMessages.requiredTrue({ actual: false }, control), actual: false },
})
expect(required('', control)).toEqual({ required: getError('required', control) })
expect(requiredTrue(false, control)).toEqual({ requiredTrue: getError('requiredTrue', control, { actual: false }) })
})

test('setMessages custom messages work', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/cdk/forms/docs/Api.zh.md
Expand Up @@ -104,7 +104,7 @@ export function useFormControl<T>(
| `maxLength()` | 验证表单控件的值的长度小于或等于指定的数字 | `number` | - | 验证失败返回 `{ maxLength: { message: '', maxLength, actual: value.length, isArray } }`|
| `rangeLength()` | 验证表单控件的值的长度范围 | `number, number` | - | 验证失败返回 `{ rangeLength: { message: '', minLength, maxLength, actual: value.length, isArray } }`|
| `pattern()` | 验证表单控件的值匹配一个正则表达式 | `string \| RegExp` | - | 验证失败返回 `{ pattern: { message: '', pattern, actual: value } }`|
| `setMessages()` | 设置验证失败的提示信息 | `ValidateMessages` | - | 每次设置的 `messages` 会跟之前的进行合并, 默认的提示信息为 `zhCNMessages` |
| `setMessages()` | 设置验证失败的提示信息 | `(messages: ValidateMessages, locale?: string)` | - | 每次设置的 `messages` 会跟之前的进行合并, 默认的提示信息为 `zhCNMessages``locale` 是可选的参数, 传入后会将 `messages` 转换成 i18n 的格式。 |

更多默认的提示信息,参见 [messages](https://github.com/IDuxFE/idux/tree/main/packages/cdk/forms/src/messages)

Expand Down
4 changes: 2 additions & 2 deletions packages/cdk/forms/src/messages/en-US.ts
Expand Up @@ -28,10 +28,10 @@ export const enUSMessages = {
},
email: (_: Omit<ValidateError, 'message'>, control: AbstractControl): string => {
const { example } = control
return `Must be a valid email address.${example ? '. Example: ' + example : ''}`
return `Must be a valid email address.${example ? ' Example: ' + example : ''}`
},
min: (err: Omit<ValidateError, 'message'>, __: AbstractControl): string => {
return `Must be a number greater than or equal to ${err.min}`
return `Must be a number greater than or equal to ${err.min}.`
},
max: (err: Omit<ValidateError, 'message'>, __: AbstractControl): string => {
return `Must be a number less than or equal to ${err.max}.`
Expand Down

0 comments on commit 0a8b116

Please sign in to comment.