@@ -13,6 +13,7 @@ import { renderForm } from '../utils/form'
1313import {
1414 UForm ,
1515 UInput ,
16+ URadioGroup ,
1617 UFormField
1718} from '#components'
1819import { flushPromises } from '@vue/test-utils'
@@ -632,4 +633,65 @@ describe('Form', () => {
632633 await flushPromises ( )
633634 expect ( wrapper . html ( ) ) . toContain ( 'Error message' )
634635 } )
636+ it ( 'should not have race condition when clear is called in watchers' , async ( ) => {
637+ const wrapper = await mountSuspended ( {
638+ components : {
639+ UForm,
640+ URadioGroup,
641+ UFormField
642+ } ,
643+ setup ( ) {
644+ const form = ref ( )
645+ const schema = z . object ( {
646+ hello : z . string ( ) . optional ( ) ,
647+ world : z . string ( ) . optional ( ) ,
648+ hi : z . string ( ) . optional ( ) ,
649+ pathForACustomError : z . string ( ) . optional ( )
650+ } )
651+
652+ const state = reactive ( {
653+ hello : 'hello-1' ,
654+ world : 'world-1' ,
655+ hi : 'hi-1' ,
656+ pathForACustomError : ''
657+ } )
658+
659+ return { form, state, schema }
660+ } ,
661+ template : `
662+ <UForm ref="form" :schema="schema" :state="state">
663+ <UFormField name="hello">
664+ <URadioGroup v-model="state.hello" :items="[{ value: 'foo-1', label: 'Foo 1' }, { value: 'foo-2', label: 'Foo 2' }]" />
665+ </UFormField>
666+ </UForm>
667+ `
668+ } )
669+
670+ const form = wrapper . setupState . form
671+
672+ const input = wrapper . findComponent ( {
673+ name : 'RadioGroupRoot'
674+ } )
675+
676+ const state = wrapper . setupState . state
677+
678+ watch ( ( ) => state . hello , ( ) => {
679+ form . value ?. clear ( 'pathForACustomError' )
680+ } )
681+
682+ form . value . setErrors ( [
683+ {
684+ name : 'pathForACustomError' ,
685+ message : 'This is a custom error message.'
686+ }
687+ ] )
688+
689+ expect ( form . value . errors ) . toHaveLength ( 1 )
690+
691+ input . setValue ( 'foo-2' )
692+
693+ await flushPromises ( )
694+
695+ expect ( form . value . errors ) . toHaveLength ( 0 )
696+ } )
635697} )
0 commit comments