11import  type  {  Ref  }  from  'vue' 
22import  {  beforeEach ,  describe ,  expect ,  it ,  vi  }  from  'vitest' 
3- import  {  ref ,   toValue  }  from  'vue' 
3+ import  {  ref  }  from  'vue' 
44import  *  as  z  from  'zod' 
55import  *  as  errorModule  from  '../src/errors' 
66import  {  getErrors  }  from  '../src/errors' 
@@ -31,6 +31,10 @@ describe('useFormValidation', () => {
3131      field2 : '' , 
3232    } ) 
3333    vi . clearAllMocks ( ) 
34+     document . body . innerHTML  =  ` 
35+       <input name="field1" /> 
36+       <input name="field2" /> 
37+     ` 
3438  } ) 
3539
3640  it ( 'should initialize with no errors' ,  ( )  =>  { 
@@ -45,7 +49,7 @@ describe('useFormValidation', () => {
4549    vi . mocked ( getErrors ) . mockResolvedValue ( mockErrors ) 
4650    const  {  validate,  errors,  isValid,  errorCount }  =  useFormValidation ( schema ,  form ) 
4751    await  validate ( ) 
48-     expect ( getErrors ) . toHaveBeenCalledWith ( schema ,  toValue ( form ) ) 
52+     expect ( getErrors ) . toHaveBeenCalledWith ( schema ,  form ,   null ) 
4953    expect ( errors . value ) . toEqual ( mockErrors ) 
5054    expect ( isValid . value ) . toBe ( false ) 
5155    expect ( errorCount . value ) . toBe ( 1 ) 
@@ -62,11 +66,6 @@ describe('useFormValidation', () => {
6266  } ) 
6367
6468  it ( 'should focus the first errored input' ,  async  ( )  =>  { 
65-     document . body . innerHTML  =  ` 
66-       <input name="field1" /> 
67-       <input name="field2" /> 
68-     ` 
69- 
7069    const  mockErrors  =  {  field1 : 'Required'  } 
7170    vi . mocked ( getErrors ) . mockResolvedValue ( mockErrors ) 
7271    const  {  validate,  focusFirstErroredInput }  =  useFormValidation ( schema ,  form ) 
@@ -79,11 +78,6 @@ describe('useFormValidation', () => {
7978  } ) 
8079
8180  it ( 'should focus the input when focusInput is called with inputName' ,  ( )  =>  { 
82-     document . body . innerHTML  =  ` 
83-       <input name="field1" /> 
84-       <input name="field2" /> 
85-     ` 
86- 
8781    const  {  focusInput }  =  useFormValidation ( schema ,  form ) 
8882    const  input : HTMLInputElement  |  null  =  document . querySelector ( 'input[name="field1"]' ) 
8983    expect ( input ) . toBeDefined ( ) 
@@ -101,7 +95,7 @@ describe('useFormValidation', () => {
10195    expect ( errors . value ) . toEqual ( {  field1 : 'Required'  } ) 
10296    expect ( isValid . value ) . toBe ( false ) 
10397    expect ( errorCount . value ) . toBe ( 1 ) 
104-     expect ( getErrors ) . toHaveBeenCalledWith ( schema ,  toValue ( form ) ) 
98+     expect ( getErrors ) . toHaveBeenCalledWith ( schema ,  form ,   null ) 
10599  } ) 
106100
107101  it ( 'should update errors in real-time when form changes in eager mode' ,  async  ( )  =>  { 
@@ -130,7 +124,7 @@ describe('useFormValidation', () => {
130124      } , 
131125    } ) 
132126    await  validate ( ) 
133-     expect ( getErrorsSpy ) . toHaveBeenCalledWith ( schema ,  toValue ( form ) ,  expect . any ( Function ) ) 
127+     expect ( getErrorsSpy ) . toHaveBeenCalledWith ( schema ,  form ,  expect . any ( Function ) ) 
134128    expect ( errors . value ) . toEqual ( {  field1 : 'Transformed error'  } ) 
135129    getErrorsSpy . mockRestore ( ) 
136130  } ) 
@@ -145,4 +139,28 @@ describe('useFormValidation', () => {
145139    // @ts -expect-error field is invalid on purpose 
146140    expect ( getErrorMessage ( 'nonExistentField' ) ) . toBeUndefined ( ) 
147141  } ) 
142+ 
143+   it ( 'should add blur event listeners to inputs in onBlur mode' ,  ( )  =>  { 
144+     const  input1  =  document . querySelector < HTMLInputElement > ( 'input[name="field1"]' ) 
145+     const  input2  =  document . querySelector < HTMLInputElement > ( 'input[name="field2"]' ) 
146+     expect ( input1 ) . toBeDefined ( ) 
147+     expect ( input2 ) . toBeDefined ( ) 
148+     const  blurSpy1  =  vi . spyOn ( input1  as  HTMLInputElement ,  'addEventListener' ) 
149+     const  blurSpy2  =  vi . spyOn ( input2  as  HTMLInputElement ,  'addEventListener' ) 
150+     useFormValidation ( schema ,  form ,  {  mode : 'onBlur'  } ) 
151+     expect ( blurSpy1 ) . toHaveBeenCalledWith ( 'blur' ,  expect . any ( Function ) ) 
152+     expect ( blurSpy2 ) . toHaveBeenCalledWith ( 'blur' ,  expect . any ( Function ) ) 
153+   } ) 
154+ 
155+   it ( 'should update errors only for the blurred field in onBlur mode' ,  async  ( )  =>  { 
156+     const  mockErrors  =  {  field1 : 'field1 is required'  } 
157+     vi . spyOn ( errorModule ,  'getErrors' ) . mockResolvedValue ( mockErrors ) 
158+     const  {  errors }  =  useFormValidation ( schema ,  form ,  {  mode : 'onBlur'  } ) 
159+     const  input1  =  document . querySelector < HTMLInputElement > ( 'input[name="field1"]' ) 
160+     expect ( input1 ) . toBeDefined ( ) 
161+     input1 ?. dispatchEvent ( new  Event ( 'blur' ) ) 
162+     await  flushPromises ( ) 
163+     expect ( errors . value ) . toEqual ( {  field1 : 'field1 is required'  } ) 
164+     expect ( errors . value . field2 ) . toBeUndefined ( ) 
165+   } ) 
148166} ) 
0 commit comments