Skip to content

Commit

Permalink
Fix repeated calling of validator function (#95)
Browse files Browse the repository at this point in the history
  • Loading branch information
nighca authored Jan 25, 2024
1 parent fca7ebb commit 9ef719f
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 14 deletions.
15 changes: 10 additions & 5 deletions src/fieldState.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,14 @@ describe('FieldState validation', () => {
})

it('should work well with onChange()', async () => {
const state = new FieldState('xxx').withValidator(val => !val && 'empty')
const validator = jest.fn((val: string) => !val && 'empty')
const state = new FieldState('xxx').withValidator(validator)
state.onChange('')

await delay()
expect(state.validated).toBe(true)
expect(state.hasError).toBe(true)
expect(validator).toBeCalledTimes(1)

state.onChange('123')
state.onChange('123456')
Expand All @@ -134,23 +136,25 @@ describe('FieldState validation', () => {
})

it('should work well with onChange of same value', async () => {
const state = new FieldState(1).withValidator(
() => null
)
const validator = jest.fn(() => null)
const state = new FieldState(1).withValidator(validator)
await state.validate()
expect(state.validated).toBe(true)
expect(state.validating).toBe(false)
expect(state.hasError).toBe(false)
expect(validator).toBeCalledTimes(1)

state.onChange(1)
await delay()
expect(state.validated).toBe(true)
expect(state.validating).toBe(false)
expect(state.hasError).toBe(false)
expect(validator).toBeCalledTimes(1)
})

it('should work well with validate()', async () => {
const state = new FieldState('').withValidator(val => !val && 'empty')
const validator = jest.fn((val: string) => !val && 'empty')
const state = new FieldState('').withValidator(validator)
const validateRet1 = state.validate()

await delay()
Expand All @@ -162,6 +166,7 @@ describe('FieldState validation', () => {
const validateResult1 = await validateRet1
expect(validateResult1.hasError).toBe(true)
expect((validateResult1 as ValidateResultWithError).error).toBe('empty')
expect(validator).toBeCalledTimes(1)

state.onChange('sth')
const validateRet2 = state.validate()
Expand Down
16 changes: 7 additions & 9 deletions src/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,15 +125,13 @@ export abstract class ValidatableState<V> extends BaseState implements IState<V>
return this.validateResult
}

const validation = this.validation

action('activate-when-validate', () => {
this.activated = true
})()

// 若 `validation` 未发生变更,意味着未发生新的校验行为
// 若上边操作未触发自动的校验行为,强制调用之
if (this.validation === validation) {
if (!this.activated) {
// activate 本身会触发自动的校验行为(见 `autorun-check-&-doValidation`)
action('activate-when-validate', () => {
this.activated = true
})()
} else {
// 若未触发自动校验,这里调用之以确保进行了校验
this.doValidation()
}

Expand Down

0 comments on commit 9ef719f

Please sign in to comment.