@@ -2,16 +2,16 @@ import { useField, useForm } from '@/vee-validate';
2
2
import { toTypedSchema } from '@/zod' ;
3
3
import { mountWithHoc , flushPromises , setValue } from 'vee-validate/tests/helpers' ;
4
4
import { Ref } from 'vue' ;
5
- import * as zod from 'zod' ;
5
+ import { z } from 'zod' ;
6
6
7
7
const REQUIRED_MSG = 'field is required' ;
8
8
const MIN_MSG = 'field is too short' ;
9
9
const EMAIL_MSG = 'field must be a valid email' ;
10
10
11
- test ( 'validates typed field with yup ' , async ( ) => {
11
+ test ( 'validates typed field with zod ' , async ( ) => {
12
12
const wrapper = mountWithHoc ( {
13
13
setup ( ) {
14
- const rules = toTypedSchema ( zod . string ( ) . min ( 1 , REQUIRED_MSG ) . min ( 8 , MIN_MSG ) ) ;
14
+ const rules = toTypedSchema ( z . string ( ) . min ( 1 , REQUIRED_MSG ) . min ( 8 , MIN_MSG ) ) ;
15
15
const { value, errorMessage } = useField ( 'test' , rules ) ;
16
16
17
17
return {
@@ -45,7 +45,7 @@ test('generates multiple errors for any given field', async () => {
45
45
let errors ! : Ref < string [ ] > ;
46
46
const wrapper = mountWithHoc ( {
47
47
setup ( ) {
48
- const rules = toTypedSchema ( zod . string ( ) . min ( 1 , REQUIRED_MSG ) . min ( 8 , MIN_MSG ) ) ;
48
+ const rules = toTypedSchema ( z . string ( ) . min ( 1 , REQUIRED_MSG ) . min ( 8 , MIN_MSG ) ) ;
49
49
const { value, errors : fieldErrors } = useField ( 'test' , rules ) ;
50
50
51
51
errors = fieldErrors ;
@@ -72,9 +72,9 @@ test('shows multiple errors using error bag', async () => {
72
72
const wrapper = mountWithHoc ( {
73
73
setup ( ) {
74
74
const schema = toTypedSchema (
75
- zod . object ( {
76
- email : zod . string ( ) . email ( EMAIL_MSG ) . min ( 7 , MIN_MSG ) ,
77
- password : zod . string ( ) . min ( 8 , MIN_MSG ) ,
75
+ z . object ( {
76
+ email : z . string ( ) . email ( EMAIL_MSG ) . min ( 7 , MIN_MSG ) ,
77
+ password : z . string ( ) . min ( 8 , MIN_MSG ) ,
78
78
} )
79
79
) ;
80
80
@@ -125,13 +125,13 @@ test('shows multiple errors using error bag', async () => {
125
125
expect ( passwordError . textContent ) . toBe ( '' ) ;
126
126
} ) ;
127
127
128
- test ( 'validates typed schema form with yup ' , async ( ) => {
128
+ test ( 'validates typed schema form with zod ' , async ( ) => {
129
129
const wrapper = mountWithHoc ( {
130
130
setup ( ) {
131
131
const schema = toTypedSchema (
132
- zod . object ( {
133
- email : zod . string ( ) . email ( EMAIL_MSG ) . min ( 1 , REQUIRED_MSG ) ,
134
- password : zod . string ( ) . min ( 8 , MIN_MSG ) ,
132
+ z . object ( {
133
+ email : z . string ( ) . email ( EMAIL_MSG ) . min ( 1 , REQUIRED_MSG ) ,
134
+ password : z . string ( ) . min ( 8 , MIN_MSG ) ,
135
135
} )
136
136
) ;
137
137
@@ -182,13 +182,71 @@ test('validates typed schema form with yup', async () => {
182
182
expect ( passwordError . textContent ) . toBe ( '' ) ;
183
183
} ) ;
184
184
185
+ // #4204
186
+ test ( 'handles zod union errors' , async ( ) => {
187
+ const wrapper = mountWithHoc ( {
188
+ setup ( ) {
189
+ const schema = z . object ( {
190
+ email : z . string ( ) . email ( { message : 'valid email' } ) . min ( 1 , 'Email is required' ) ,
191
+ name : z . string ( ) . min ( 1 , 'Name is required' ) ,
192
+ } ) ;
193
+
194
+ const schemaBothUndefined = z . object ( {
195
+ email : z . undefined ( ) ,
196
+ name : z . undefined ( ) ,
197
+ } ) ;
198
+
199
+ const bothOrNeither = schema . or ( schemaBothUndefined ) ;
200
+
201
+ const { useFieldModel, errors } = useForm ( {
202
+ validationSchema : toTypedSchema ( bothOrNeither ) ,
203
+ } ) ;
204
+
205
+ const [ email , name ] = useFieldModel ( [ 'email' , 'name' ] ) ;
206
+
207
+ return {
208
+ schema,
209
+ email,
210
+ name,
211
+ errors,
212
+ } ;
213
+ } ,
214
+ template : `
215
+ <div>
216
+ <input id="email" name="email" v-model="email" />
217
+ <span id="emailErr">{{ errors.email }}</span>
218
+
219
+ <input id="name" name="name" v-model="name" />
220
+ <span id="nameErr">{{ errors.name }}</span>
221
+ </div>
222
+ ` ,
223
+ } ) ;
224
+
225
+ const email = wrapper . $el . querySelector ( '#email' ) ;
226
+ const name = wrapper . $el . querySelector ( '#name' ) ;
227
+ const emailError = wrapper . $el . querySelector ( '#emailErr' ) ;
228
+ const nameError = wrapper . $el . querySelector ( '#nameErr' ) ;
229
+
230
+ await flushPromises ( ) ;
231
+
232
+ setValue ( name , '4' ) ;
233
+ await flushPromises ( ) ;
234
+ expect ( nameError . textContent ) . toBe ( 'Expected undefined, received string' ) ;
235
+
236
+ setValue ( email , 'test@gmail.com' ) ;
237
+ await flushPromises ( ) ;
238
+
239
+ expect ( emailError . textContent ) . toBe ( '' ) ;
240
+ expect ( nameError . textContent ) . toBe ( '' ) ;
241
+ } ) ;
242
+
185
243
test ( 'uses zod for form values transformations and parsing' , async ( ) => {
186
244
const submitSpy = vi . fn ( ) ;
187
245
mountWithHoc ( {
188
246
setup ( ) {
189
247
const schema = toTypedSchema (
190
- zod . object ( {
191
- age : zod . preprocess ( arg => Number ( arg ) , zod . number ( ) ) ,
248
+ z . object ( {
249
+ age : z . preprocess ( arg => Number ( arg ) , z . number ( ) ) ,
192
250
} )
193
251
) ;
194
252
@@ -223,8 +281,8 @@ test('uses zod default values for submission', async () => {
223
281
mountWithHoc ( {
224
282
setup ( ) {
225
283
const schema = toTypedSchema (
226
- zod . object ( {
227
- age : zod . number ( ) . default ( 11 ) ,
284
+ z . object ( {
285
+ age : z . number ( ) . default ( 11 ) ,
228
286
} )
229
287
) ;
230
288
@@ -257,13 +315,13 @@ test('uses zod default values for initial values', async () => {
257
315
mountWithHoc ( {
258
316
setup ( ) {
259
317
const schema = toTypedSchema (
260
- zod . object ( {
261
- name : zod . string ( ) . default ( 'test' ) ,
262
- age : zod . number ( ) . default ( 11 ) ,
263
- unknownKey : zod . string ( ) ,
264
- object : zod . object ( {
265
- nestedKey : zod . string ( ) ,
266
- nestedDefault : zod . string ( ) . default ( 'nested' ) ,
318
+ z . object ( {
319
+ name : z . string ( ) . default ( 'test' ) ,
320
+ age : z . number ( ) . default ( 11 ) ,
321
+ unknownKey : z . string ( ) ,
322
+ object : z . object ( {
323
+ nestedKey : z . string ( ) ,
324
+ nestedDefault : z . string ( ) . default ( 'nested' ) ,
267
325
} ) ,
268
326
} )
269
327
) ;
@@ -301,8 +359,8 @@ test('default values should not be undefined', async () => {
301
359
mountWithHoc ( {
302
360
setup ( ) {
303
361
const schema = toTypedSchema (
304
- zod . object ( {
305
- email : zod . string ( ) . min ( 1 ) ,
362
+ z . object ( {
363
+ email : z . string ( ) . min ( 1 ) ,
306
364
} )
307
365
) ;
308
366
0 commit comments