Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
update check error condition
  • Loading branch information
Luncher committed May 16, 2022
commit b2f88ba42b26a1919a88ca18e0854936a2cf7c3a
41 changes: 29 additions & 12 deletions src/fieldState.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,35 @@ describe('FieldState', () => {
expect(state.value).toBe(initialValue)
expect(state.touched).toBe(false)
})

it('should setError well', async () => {
const initialValue = ''
const state = new FieldState(initialValue)

state.setError('')
expect(state.hasError).toBe(false)
expect(state.error).toBe(undefined)
expect(state.ownError).toBe(undefined)
expect(state.rawError).toBe(undefined)

state.setError('123')
expect(state.hasError).toBe(true)
expect(state.error).toBe('123')
expect(state.ownError).toBe('123')
expect(state.rawError).toBe('123')

state.setError({ message: 'mewo3' })
expect(state.hasError).toBe(true)
expect(state.error).toBe('mewo3')
expect(state.ownError).toBe('mewo3')
expect(state.rawError).toEqual({ message: 'mewo3' })

state.reset()
expect(state.hasError).toBe(false)
expect(state.error).toBe(undefined)
expect(state.ownError).toBe(undefined)
expect(state.rawError).toBe(undefined)
})
})

describe('FieldState validation', () => {
Expand Down Expand Up @@ -386,18 +415,6 @@ describe('FieldState validation', () => {
expect(state.rawError).toEqual({ message: 'error-object-msg' })
expect(res).toEqual({ hasError: true, error: 'error-object-msg' })
})

it('should work well with sync resolved empty message', async () => {
const state = new FieldState('').withValidator(
_ => ({ message: '' })
)

const res = await state.validate()
expect(state.hasError).toBe(true)
expect(state.error).toBe('')
expect(state.rawError).toEqual({ message: '' })
expect(res).toEqual({ hasError: true, error: '' })
})

it('should work well with async resolved', async () => {
const state = new FieldState('').withValidator(
Expand Down
76 changes: 76 additions & 0 deletions src/formState.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,45 @@ describe('FormState (mode: object)', () => {
expect(state.value).toEqual(initialValue)
expect(state.touched).toBe(false)
})

it('should setError well', async () => {
const initialValue = { foo: 123 }
const state = new FormState({
foo: new FieldState(initialValue.foo)
})

state.setError('')
expect(state.hasError).toBe(false)
expect(state.error).toBe(undefined)
expect(state.ownError).toBe(undefined)
expect(state.rawError).toBe(undefined)

state.setError('123')
expect(state.hasError).toBe(true)
expect(state.error).toBe('123')
expect(state.ownError).toBe('123')
expect(state.rawError).toBe('123')

state.setError({ message: 'mewo3' })
expect(state.hasError).toBe(true)
expect(state.error).toBe('mewo3')
expect(state.ownError).toBe('mewo3')
expect(state.rawError).toEqual({ message: 'mewo3' })

state.reset()

state.$.foo.setError({ message: 'mewo4' })
expect(state.hasError).toBe(true)
expect(state.error).toBe('mewo4')
expect(state.ownError).toBe(undefined)
expect(state.rawError).toEqual(undefined)

state.reset()
expect(state.hasError).toBe(false)
expect(state.error).toBe(undefined)
expect(state.ownError).toBe(undefined)
expect(state.rawError).toBe(undefined)
})
})

describe('FormState (mode: object) validation', () => {
Expand Down Expand Up @@ -1015,6 +1054,43 @@ describe('FormState (mode: array)', () => {
expect(state.touched).toBe(false)
})

it('should setError well', async () => {
const initialValue = ['123']
const state = new ArrayFormState(initialValue, v => new FieldState(v))

state.setError('')
expect(state.hasError).toBe(false)
expect(state.error).toBe(undefined)
expect(state.ownError).toBe(undefined)
expect(state.rawError).toBe(undefined)

state.setError('123')
expect(state.hasError).toBe(true)
expect(state.error).toBe('123')
expect(state.ownError).toBe('123')
expect(state.rawError).toBe('123')

state.setError({ message: 'mewo3' })
expect(state.hasError).toBe(true)
expect(state.error).toBe('mewo3')
expect(state.ownError).toBe('mewo3')
expect(state.rawError).toEqual({ message: 'mewo3' })

state.reset()

state.$[0].setError({ message: 'mewo4' })
expect(state.hasError).toBe(true)
expect(state.error).toBe('mewo4')
expect(state.ownError).toBe(undefined)
expect(state.rawError).toEqual(undefined)

state.reset()
expect(state.hasError).toBe(false)
expect(state.error).toBe(undefined)
expect(state.ownError).toBe(undefined)
expect(state.rawError).toBe(undefined)
})

it('should reset well with fields changed', async () => {
const initialValue = ['123', '456']
const state = new ArrayFormState(initialValue, v => new FieldState(v))
Expand Down
4 changes: 2 additions & 2 deletions src/state.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { action, autorun, computed, makeObservable, observable, when } from 'mobx'
import { ValidationRawError, ValidationError, IState, Validation, ValidateResult, ValidateStatus, Validator } from './types'
import Disposable from './disposable'
import { applyValidators, isPromiseLike, normalizeRawError, normalizeError } from './utils'
import { applyValidators, isPromiseLike, normalizeRawError, normalizeError, convertEmptyStringWithWarning } from './utils'

/** Extraction for some basic features of State */
export abstract class BaseState extends Disposable implements Pick<
Expand Down Expand Up @@ -74,7 +74,7 @@ export abstract class ValidatableState<V> extends BaseState implements IState<V>
* Set error info.
*/
@action setError(error: ValidationRawError) {
this._error = error
this._error = convertEmptyStringWithWarning(error)
}

/** List of validator functions. */
Expand Down
3 changes: 2 additions & 1 deletion src/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,10 @@ describe('normalizeValidationResult', () => {

it('normalizeError should work well', () => {
expect(normalizeError(undefined)).toBe(undefined)
expect(normalizeError('')).toBe('')
expect(normalizeError('')).toBe(undefined)
expect(normalizeError('foo')).toBe('foo')
expect(normalizeError({ message: 'mewo' })).toBe('mewo')
expect(normalizeError(Error('mewo2'))).toBe('mewo2')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

需要 normalizeError({ message: '' }) 的 case


class Foo implements ValidationErrorObject { message = 'mewo' }
const foo = new Foo()
Expand Down
21 changes: 18 additions & 3 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export function normalizeRawError(err: ValidationResult): ValidationRawError {
}

if (err === false || err === '' || err === null) {
// TODO: print an alert?
return undefined
}

Expand All @@ -18,11 +17,27 @@ export function normalizeError(rawError: ValidationRawError): ValidationError {
if (isErrorObject(rawError)) {
return rawError.message
}
return rawError

return convertEmptyStringWithWarning(rawError)
}

export function isErrorObject(err: any): err is ValidationErrorObject {
return err != null && typeof err === 'object' && 'message' in err
if (err != null && typeof err === 'object' && 'message' in err) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里是不是最好再加个 typeof err.message === 'string'

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P.S. 如果加了 typeof err.message === 'string',好像 'message' in err 也可以省了

if (!err.message) {
console.log(err)
throw new Error('ValidationErrorObject message property cannot be empty')
Copy link
Collaborator

@nighca nighca May 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

在这(isErrorObject)抛错不合理吧..放到 setError 去抛可能会好一点,甚至 normalizeError 也比这里好

}
return true
}
return false
Comment on lines +24 to +26
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIP: 特地改成这样有啥说法么 = =

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

没懂..

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

一开始 pr 里是 return a && b && c 差不多这样的
后面特地改成

if (a && b && c) {
  return true
}
return false

后面有比前面更好吗…

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你不说我都忘记之前的 isErrorObject 的实现是

return a && b && c 

了。。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果是:a && b && c、返回值可能就不是 true/false 了。

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

一开始我也是这么想的
但是看了一下你的实现,也不是这情况…
另外如果是为了防止出现那种状况
我会选择标记一下返回类型为 boolean

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我试了下,: err is ValidationErrorObject 这种,只能返回 boolean

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

对喔,那就更没问题了

}

export function convertEmptyStringWithWarning<T>(err: T) {
if (typeof err === 'string' && err === '') {
console.warn('An empty string errs should be replaced with undefined.')
return undefined
}
return err
}

export function isPromiseLike(arg: any): arg is Promise<any> {
Expand Down