Codebase list golang-github-go-playground-validator-v10 / 0f02c73
Merge branch 'v1' into v1-development Dean Karn 9 years ago
3 changed file(s) with 94 addition(s) and 104 deletion(s). Raw diff Collapse all Expand all
77
88 // built in
99 errs := validator.ValidateStruct(//your struct)
10 errs := validator.ValidateFieldByTag(field, "omitempty,min=1,max=10")
10 valErr := validator.ValidateFieldByTag(field, "omitempty,min=1,max=10")
1111
1212 // new
1313 newValidator = validator.New("struct tag name", validator.BakedInFunctions)
5656
5757 Why not a better error message? because this library intends for you to handle your own error messages
5858
59 Why should I handle my own errors? Many reasons, for me building and internationalized application
59 Why should I handle my own errors? Many reasons, for me building an internationalized application
6060 I needed to know the field and what validation failed so that I could provide an error in the users specific language.
6161
6262 if fieldErr.Field == "Name" {
2626 type FieldValidationError struct {
2727 Field string
2828 ErrorTag string
29 Kind reflect.Kind
30 Param string
31 Value interface{}
2932 }
3033
3134 // This is intended for use in development + debugging and not intended to be a production error message.
219222
220223 default:
221224
222 if fieldError := v.validateStructFieldByTag(valueField.Interface(), typeField.Name, tag); fieldError != nil {
225 if fieldError := v.validateFieldByNameAndTag(valueField.Interface(), typeField.Name, tag); fieldError != nil {
223226 validationErrors.Errors[fieldError.Field] = fieldError
224227 // free up memory reference
225228 fieldError = nil
234237 return validationErrors
235238 }
236239
237 // ValidateFieldWithTag validates the given field by the given tag arguments
238 func (v *Validator) validateStructFieldByTag(f interface{}, name string, tag string) *FieldValidationError {
239
240 if err := v.validateFieldByNameAndTag(f, name, tag); err != nil {
241 return &FieldValidationError{
242 Field: name,
243 ErrorTag: err.Error(),
244 }
245 }
246
247 return nil
248 }
249
250240 // ValidateFieldByTag allows validation of a single field with the internal validator, still using tag style validation to check multiple errors
251 func ValidateFieldByTag(f interface{}, tag string) error {
241 func ValidateFieldByTag(f interface{}, tag string) *FieldValidationError {
252242
253243 return internalValidator.validateFieldByNameAndTag(f, "", tag)
254244 }
255245
256246 // ValidateFieldByTag allows validation of a single field, still using tag style validation to check multiple errors
257 func (v *Validator) ValidateFieldByTag(f interface{}, tag string) error {
247 func (v *Validator) ValidateFieldByTag(f interface{}, tag string) *FieldValidationError {
258248
259249 return v.validateFieldByNameAndTag(f, "", tag)
260250 }
261251
262 func (v *Validator) validateFieldByNameAndTag(f interface{}, name string, tag string) error {
252 func (v *Validator) validateFieldByNameAndTag(f interface{}, name string, tag string) *FieldValidationError {
263253
264254 // This is a double check if coming from ValidateStruct but need to be here in case function is called directly
265255 if tag == "-" {
282272 panic("Invalid field passed to ValidateFieldWithTag")
283273 }
284274
285 // TODO: validate commas in regex's
275 var valErr *FieldValidationError
276 var err error
286277 valTags := strings.Split(tag, ",")
287278
288279 for _, valTag := range valTags {
295286
296287 for _, val := range orVals {
297288
298 key, err := v.validateFieldByNameAndSingleTag(f, name, val)
289 valErr, err = v.validateFieldByNameAndSingleTag(f, name, val)
299290
300291 if err == nil {
301292 return nil
302293 }
303294
304 errTag += "|" + key
295 errTag += "|" + valErr.ErrorTag
305296
306297 }
307298
308299 errTag = strings.TrimLeft(errTag, "|")
309300
310 return errors.New(errTag)
311 }
312
313 if _, err := v.validateFieldByNameAndSingleTag(f, name, valTag); err != nil {
314 return err
315 }
316
317 // TODO: validate = in regex's
318 // vals := strings.Split(valTag, "=")
319 // key := strings.Trim(vals[0], " ")
320 //
321 // if len(key) == 0 {
322 // panic(fmt.Sprintf("Invalid validation tag on field %s", name))
323 // }
324 //
325 // // OK to continue because we checked it's existance before getting into this loop
326 // if key == omitempty {
327 // continue
328 // }
329 //
330 // valFunc, ok := v.validationFuncs[key]
331 // if !ok {
332 // panic(fmt.Sprintf("Undefined validation function on field %s", name))
333 // }
334 //
335 // param := ""
336 // if len(vals) > 1 {
337 // param = strings.Trim(vals[1], " ")
338 // }
339 //
340 // if err := valFunc(f, param); !err {
341 //
342 // return errors.New(key)
343 // }
344 // if err := v.validateFieldByNameAndSingleTag(f, name, valTag); err != nil {
345 // return err
346 // }
347
301 valErr.ErrorTag = errTag
302 valErr.Kind = valueField.Kind()
303
304 return valErr
305 }
306
307 if valErr, err = v.validateFieldByNameAndSingleTag(f, name, valTag); err != nil {
308 valErr.Kind = valueField.Kind()
309
310 return valErr
311 }
348312 }
349313
350314 return nil
351315 }
352316
353 func (v *Validator) validateFieldByNameAndSingleTag(f interface{}, name string, valTag string) (string, error) {
317 func (v *Validator) validateFieldByNameAndSingleTag(f interface{}, name string, valTag string) (*FieldValidationError, error) {
354318
355319 vals := strings.Split(valTag, "=")
356320 key := strings.Trim(vals[0], " ")
359323 panic(fmt.Sprintf("Invalid validation tag on field %s", name))
360324 }
361325
326 valErr := &FieldValidationError{
327 Field: name,
328 ErrorTag: key,
329 Value: f,
330 Param: "",
331 }
332
362333 // OK to continue because we checked it's existance before getting into this loop
363334 if key == omitempty {
364 return key, nil
335 return valErr, nil
365336 }
366337
367338 valFunc, ok := v.validationFuncs[key]
375346 }
376347
377348 if err := valFunc(f, param); !err {
378 return key, errors.New(key)
379 }
380
381 return key, nil
382 }
349 valErr.Param = param
350 return valErr, errors.New(key)
351 }
352
353 return valErr, nil
354 }
168168 c.Assert(err, IsNil)
169169 } else {
170170 c.Assert(err, NotNil)
171 c.Assert(err.Error(), Equals, "url")
171 c.Assert(err.ErrorTag, Equals, "url")
172172 }
173173 }
174174 }
221221 c.Assert(err, IsNil)
222222 } else {
223223 c.Assert(err, NotNil)
224 c.Assert(err.Error(), Equals, "uri")
224 c.Assert(err.ErrorTag, Equals, "uri")
225225 }
226226 }
227227 }
238238 s = "this ain't right"
239239 err = validator.ValidateFieldByTag(s, "rgb|rgba")
240240 c.Assert(err, NotNil)
241 c.Assert(err.Error(), Equals, "rgb|rgba")
241 c.Assert(err.ErrorTag, Equals, "rgb|rgba")
242242
243243 s = "this ain't right"
244244 err = validator.ValidateFieldByTag(s, "rgb|rgba|len=10")
245245 c.Assert(err, NotNil)
246 c.Assert(err.Error(), Equals, "rgb|rgba|len")
246 c.Assert(err.ErrorTag, Equals, "rgb|rgba|len")
247247
248248 s = "this is right"
249249 err = validator.ValidateFieldByTag(s, "rgb|rgba|len=13")
271271 s = "hsl(361,100%,50%,1)"
272272 err = validator.ValidateFieldByTag(s, "hsla")
273273 c.Assert(err, NotNil)
274 c.Assert(err.Error(), Equals, "hsla")
274 c.Assert(err.ErrorTag, Equals, "hsla")
275275
276276 s = "hsl(361,100%,50%)"
277277 err = validator.ValidateFieldByTag(s, "hsla")
278278 c.Assert(err, NotNil)
279 c.Assert(err.Error(), Equals, "hsla")
279 c.Assert(err.ErrorTag, Equals, "hsla")
280280
281281 s = "hsla(361,100%,50%)"
282282 err = validator.ValidateFieldByTag(s, "hsla")
283283 c.Assert(err, NotNil)
284 c.Assert(err.Error(), Equals, "hsla")
284 c.Assert(err.ErrorTag, Equals, "hsla")
285285
286286 s = "hsla(360,101%,50%)"
287287 err = validator.ValidateFieldByTag(s, "hsla")
288288 c.Assert(err, NotNil)
289 c.Assert(err.Error(), Equals, "hsla")
289 c.Assert(err.ErrorTag, Equals, "hsla")
290290
291291 s = "hsla(360,100%,101%)"
292292 err = validator.ValidateFieldByTag(s, "hsla")
293293 c.Assert(err, NotNil)
294 c.Assert(err.Error(), Equals, "hsla")
294 c.Assert(err.ErrorTag, Equals, "hsla")
295295 }
296296
297297 func (ms *MySuite) TestHsl(c *C) {
307307 s = "hsl(361,100%,50%)"
308308 err = validator.ValidateFieldByTag(s, "hsl")
309309 c.Assert(err, NotNil)
310 c.Assert(err.Error(), Equals, "hsl")
310 c.Assert(err.ErrorTag, Equals, "hsl")
311311
312312 s = "hsl(361,101%,50%)"
313313 err = validator.ValidateFieldByTag(s, "hsl")
314314 c.Assert(err, NotNil)
315 c.Assert(err.Error(), Equals, "hsl")
315 c.Assert(err.ErrorTag, Equals, "hsl")
316316
317317 s = "hsl(361,100%,101%)"
318318 err = validator.ValidateFieldByTag(s, "hsl")
319319 c.Assert(err, NotNil)
320 c.Assert(err.Error(), Equals, "hsl")
320 c.Assert(err.ErrorTag, Equals, "hsl")
321321
322322 s = "hsl(-10,100%,100%)"
323323 err = validator.ValidateFieldByTag(s, "hsl")
324324 c.Assert(err, NotNil)
325 c.Assert(err.Error(), Equals, "hsl")
325 c.Assert(err.ErrorTag, Equals, "hsl")
326326 }
327327
328328 func (ms *MySuite) TestRgba(c *C) {
342342 s = "rgb(0, 31, 255)"
343343 err = validator.ValidateFieldByTag(s, "rgba")
344344 c.Assert(err, NotNil)
345 c.Assert(err.Error(), Equals, "rgba")
345 c.Assert(err.ErrorTag, Equals, "rgba")
346346
347347 s = "rgb(1,349,275,0.5)"
348348 err = validator.ValidateFieldByTag(s, "rgba")
349349 c.Assert(err, NotNil)
350 c.Assert(err.Error(), Equals, "rgba")
350 c.Assert(err.ErrorTag, Equals, "rgba")
351351
352352 s = "rgb(01,31,255,0.5)"
353353 err = validator.ValidateFieldByTag(s, "rgba")
354354 c.Assert(err, NotNil)
355 c.Assert(err.Error(), Equals, "rgba")
355 c.Assert(err.ErrorTag, Equals, "rgba")
356356 }
357357
358358 func (ms *MySuite) TestRgb(c *C) {
368368 s = "rgb(1,349,275)"
369369 err = validator.ValidateFieldByTag(s, "rgb")
370370 c.Assert(err, NotNil)
371 c.Assert(err.Error(), Equals, "rgb")
371 c.Assert(err.ErrorTag, Equals, "rgb")
372372
373373 s = "rgb(01,31,255)"
374374 err = validator.ValidateFieldByTag(s, "rgb")
375375 c.Assert(err, NotNil)
376 c.Assert(err.Error(), Equals, "rgb")
376 c.Assert(err.ErrorTag, Equals, "rgb")
377377
378378 s = "rgba(0,31,255)"
379379 err = validator.ValidateFieldByTag(s, "rgb")
380380 c.Assert(err, NotNil)
381 c.Assert(err.Error(), Equals, "rgb")
381 c.Assert(err.ErrorTag, Equals, "rgb")
382382 }
383383
384384 func (ms *MySuite) TestEmail(c *C) {
389389
390390 s = ""
391391 err = validator.ValidateFieldByTag(s, "email")
392 c.Assert(err.Error(), Equals, "email")
392 c.Assert(err, NotNil)
393 c.Assert(err.ErrorTag, Equals, "email")
393394
394395 s = "test@email"
395396 err = validator.ValidateFieldByTag(s, "email")
396 c.Assert(err.Error(), Equals, "email")
397 c.Assert(err, NotNil)
398 c.Assert(err.ErrorTag, Equals, "email")
397399
398400 s = "test@email."
399401 err = validator.ValidateFieldByTag(s, "email")
400 c.Assert(err.Error(), Equals, "email")
402 c.Assert(err, NotNil)
403 c.Assert(err.ErrorTag, Equals, "email")
401404
402405 s = "@email.com"
403406 err = validator.ValidateFieldByTag(s, "email")
404 c.Assert(err.Error(), Equals, "email")
407 c.Assert(err, NotNil)
408 c.Assert(err.ErrorTag, Equals, "email")
405409 }
406410
407411 func (ms *MySuite) TestHexColor(c *C) {
416420
417421 s = "fff"
418422 err = validator.ValidateFieldByTag(s, "hexcolor")
419 c.Assert(err.Error(), Equals, "hexcolor")
423 c.Assert(err, NotNil)
424 c.Assert(err.ErrorTag, Equals, "hexcolor")
420425
421426 s = "fffFF"
422427 err = validator.ValidateFieldByTag(s, "hexcolor")
423 c.Assert(err.Error(), Equals, "hexcolor")
428 c.Assert(err, NotNil)
429 c.Assert(err.ErrorTag, Equals, "hexcolor")
424430 }
425431
426432 func (ms *MySuite) TestHexadecimal(c *C) {
431437
432438 s = "abcdefg"
433439 err = validator.ValidateFieldByTag(s, "hexadecimal")
434 c.Assert(err.Error(), Equals, "hexadecimal")
440 c.Assert(err, NotNil)
441 c.Assert(err.ErrorTag, Equals, "hexadecimal")
435442 }
436443
437444 func (ms *MySuite) TestNumber(c *C) {
442449
443450 s = "+1"
444451 err = validator.ValidateFieldByTag(s, "number")
445 c.Assert(err.Error(), Equals, "number")
452 c.Assert(err, NotNil)
453 c.Assert(err.ErrorTag, Equals, "number")
446454
447455 s = "-1"
448456 err = validator.ValidateFieldByTag(s, "number")
449 c.Assert(err.Error(), Equals, "number")
457 c.Assert(err, NotNil)
458 c.Assert(err.ErrorTag, Equals, "number")
450459
451460 s = "1.12"
452461 err = validator.ValidateFieldByTag(s, "number")
453 c.Assert(err.Error(), Equals, "number")
462 c.Assert(err, NotNil)
463 c.Assert(err.ErrorTag, Equals, "number")
454464
455465 s = "+1.12"
456466 err = validator.ValidateFieldByTag(s, "number")
457 c.Assert(err.Error(), Equals, "number")
467 c.Assert(err, NotNil)
468 c.Assert(err.ErrorTag, Equals, "number")
458469
459470 s = "-1.12"
460471 err = validator.ValidateFieldByTag(s, "number")
461 c.Assert(err.Error(), Equals, "number")
472 c.Assert(err, NotNil)
473 c.Assert(err.ErrorTag, Equals, "number")
462474
463475 s = "1."
464476 err = validator.ValidateFieldByTag(s, "number")
465 c.Assert(err.Error(), Equals, "number")
477 c.Assert(err, NotNil)
478 c.Assert(err.ErrorTag, Equals, "number")
466479
467480 s = "1.o"
468481 err = validator.ValidateFieldByTag(s, "number")
469 c.Assert(err.Error(), Equals, "number")
482 c.Assert(err, NotNil)
483 c.Assert(err.ErrorTag, Equals, "number")
470484 }
471485
472486 func (ms *MySuite) TestNumeric(c *C) {
497511
498512 s = "1."
499513 err = validator.ValidateFieldByTag(s, "numeric")
500 c.Assert(err.Error(), Equals, "numeric")
514 c.Assert(err, NotNil)
515 c.Assert(err.ErrorTag, Equals, "numeric")
501516
502517 s = "1.o"
503518 err = validator.ValidateFieldByTag(s, "numeric")
504 c.Assert(err.Error(), Equals, "numeric")
519 c.Assert(err, NotNil)
520 c.Assert(err.ErrorTag, Equals, "numeric")
505521 }
506522
507523 func (ms *MySuite) TestAlphaNumeric(c *C) {
512528
513529 s = "abc!23"
514530 err = validator.ValidateFieldByTag(s, "alphanum")
515 c.Assert(err.Error(), Equals, "alphanum")
531 c.Assert(err, NotNil)
532 c.Assert(err.ErrorTag, Equals, "alphanum")
516533
517534 c.Assert(func() { validator.ValidateFieldByTag(1, "alphanum") }, PanicMatches, "Bad field type int")
518535 }
525542
526543 s = "abc1"
527544 err = validator.ValidateFieldByTag(s, "alpha")
528 c.Assert(err.Error(), Equals, "alpha")
545 c.Assert(err, NotNil)
546 c.Assert(err.ErrorTag, Equals, "alpha")
529547
530548 c.Assert(func() { validator.ValidateFieldByTag(1, "alpha") }, PanicMatches, "Bad field type int")
531549 }