1 package validator
2
3 import (
4 "bytes"
5 "context"
6 "database/sql"
7 "database/sql/driver"
8 "encoding/base64"
9 "encoding/json"
10 "fmt"
11 "image"
12 "image/jpeg"
13 "image/png"
14 "os"
15 "path/filepath"
16 "reflect"
17 "strings"
18 "testing"
19 "time"
20
21 . "github.com/go-playground/assert/v2"
22 "github.com/go-playground/locales/en"
23 "github.com/go-playground/locales/fr"
24 "github.com/go-playground/locales/nl"
25 ut "github.com/go-playground/universal-translator"
26 )
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 type I interface {
47 Foo() string
48 }
49
50 type Impl struct {
51 F string `validate:"len=3"`
52 }
53
54 func (i *Impl) Foo() string {
55 return i.F
56 }
57
58 type SubTest struct {
59 Test string `validate:"required"`
60 }
61
62 type TestInterface struct {
63 Iface I
64 }
65
66 type TestString struct {
67 BlankTag string `validate:""`
68 Required string `validate:"required"`
69 Len string `validate:"len=10"`
70 Min string `validate:"min=1"`
71 Max string `validate:"max=10"`
72 MinMax string `validate:"min=1,max=10"`
73 Lt string `validate:"lt=10"`
74 Lte string `validate:"lte=10"`
75 Gt string `validate:"gt=10"`
76 Gte string `validate:"gte=10"`
77 OmitEmpty string `validate:"omitempty,min=1,max=10"`
78 Boolean string `validate:"boolean"`
79 Sub *SubTest
80 SubIgnore *SubTest `validate:"-"`
81 Anonymous struct {
82 A string `validate:"required"`
83 }
84 Iface I
85 }
86
87 type TestUint64 struct {
88 Required uint64 `validate:"required"`
89 Len uint64 `validate:"len=10"`
90 Min uint64 `validate:"min=1"`
91 Max uint64 `validate:"max=10"`
92 MinMax uint64 `validate:"min=1,max=10"`
93 OmitEmpty uint64 `validate:"omitempty,min=1,max=10"`
94 }
95
96 type TestFloat64 struct {
97 Required float64 `validate:"required"`
98 Len float64 `validate:"len=10"`
99 Min float64 `validate:"min=1"`
100 Max float64 `validate:"max=10"`
101 MinMax float64 `validate:"min=1,max=10"`
102 Lte float64 `validate:"lte=10"`
103 OmitEmpty float64 `validate:"omitempty,min=1,max=10"`
104 }
105
106 type TestSlice struct {
107 Required []int `validate:"required"`
108 Len []int `validate:"len=10"`
109 Min []int `validate:"min=1"`
110 Max []int `validate:"max=10"`
111 MinMax []int `validate:"min=1,max=10"`
112 OmitEmpty []int `validate:"omitempty,min=1,max=10"`
113 }
114
115 func AssertError(t *testing.T, err error, nsKey, structNsKey, field, structField, expectedTag string) {
116 errs := err.(ValidationErrors)
117
118 found := false
119 var fe FieldError
120
121 for i := 0; i < len(errs); i++ {
122 if errs[i].Namespace() == nsKey && errs[i].StructNamespace() == structNsKey {
123 found = true
124 fe = errs[i]
125 break
126 }
127 }
128
129 EqualSkip(t, 2, found, true)
130 NotEqualSkip(t, 2, fe, nil)
131 EqualSkip(t, 2, fe.Field(), field)
132 EqualSkip(t, 2, fe.StructField(), structField)
133 EqualSkip(t, 2, fe.Tag(), expectedTag)
134 }
135
136 func AssertDeepError(t *testing.T, err error, nsKey, structNsKey, field, structField, expectedTag, actualTag string) {
137 errs := err.(ValidationErrors)
138
139 found := false
140 var fe FieldError
141
142 for i := 0; i < len(errs); i++ {
143 if errs[i].Namespace() == nsKey && errs[i].StructNamespace() == structNsKey && errs[i].Tag() == expectedTag && errs[i].ActualTag() == actualTag {
144 found = true
145 fe = errs[i]
146 break
147 }
148 }
149
150 EqualSkip(t, 2, found, true)
151 NotEqualSkip(t, 2, fe, nil)
152 EqualSkip(t, 2, fe.Field(), field)
153 EqualSkip(t, 2, fe.StructField(), structField)
154 }
155
156 func getError(err error, nsKey, structNsKey string) FieldError {
157 errs := err.(ValidationErrors)
158
159 var fe FieldError
160
161 for i := 0; i < len(errs); i++ {
162 if errs[i].Namespace() == nsKey && errs[i].StructNamespace() == structNsKey {
163 fe = errs[i]
164 break
165 }
166 }
167
168 return fe
169 }
170
171 type valuer struct {
172 Name string
173 }
174
175 func (v valuer) Value() (driver.Value, error) {
176 if v.Name == "errorme" {
177 panic("SQL Driver Valuer error: some kind of error")
178
179 }
180
181 if len(v.Name) == 0 {
182 return nil, nil
183 }
184
185 return v.Name, nil
186 }
187
188 type MadeUpCustomType struct {
189 FirstName string
190 LastName string
191 }
192
193 func ValidateCustomType(field reflect.Value) interface{} {
194 if cust, ok := field.Interface().(MadeUpCustomType); ok {
195
196 if len(cust.FirstName) == 0 || len(cust.LastName) == 0 {
197 return ""
198 }
199
200 return cust.FirstName + " " + cust.LastName
201 }
202
203 return ""
204 }
205
206 func OverrideIntTypeForSomeReason(field reflect.Value) interface{} {
207 if i, ok := field.Interface().(int); ok {
208 if i == 1 {
209 return "1"
210 }
211
212 if i == 2 {
213 return "12"
214 }
215 }
216
217 return ""
218 }
219
220 type CustomMadeUpStruct struct {
221 MadeUp MadeUpCustomType `validate:"required"`
222 OverriddenInt int `validate:"gt=1"`
223 }
224
225 func ValidateValuerType(field reflect.Value) interface{} {
226 if valuer, ok := field.Interface().(driver.Valuer); ok {
227
228 val, err := valuer.Value()
229 if err != nil {
230
231 return nil
232 }
233
234 return val
235 }
236
237 return nil
238 }
239
240 type TestPartial struct {
241 NoTag string
242 BlankTag string `validate:""`
243 Required string `validate:"required"`
244 SubSlice []*SubTest `validate:"required,dive"`
245 Sub *SubTest
246 SubIgnore *SubTest `validate:"-"`
247 Anonymous struct {
248 A string `validate:"required"`
249 ASubSlice []*SubTest `validate:"required,dive"`
250
251 SubAnonStruct []struct {
252 Test string `validate:"required"`
253 OtherTest string `validate:"required"`
254 } `validate:"required,dive"`
255 }
256 }
257
258 type TestStruct struct {
259 String string `validate:"required" json:"StringVal"`
260 }
261
262 func StructValidationTestStructSuccess(sl StructLevel) {
263 st := sl.Current().Interface().(TestStruct)
264
265 if st.String != "good value" {
266 sl.ReportError(st.String, "StringVal", "String", "badvalueteststruct", "good value")
267 }
268 }
269
270 func StructValidationTestStruct(sl StructLevel) {
271 st := sl.Current().Interface().(TestStruct)
272
273 if st.String != "bad value" {
274 sl.ReportError(st.String, "StringVal", "String", "badvalueteststruct", "bad value")
275 }
276 }
277
278 func StructValidationNoTestStructCustomName(sl StructLevel) {
279 st := sl.Current().Interface().(TestStruct)
280
281 if st.String != "bad value" {
282 sl.ReportError(st.String, "String", "", "badvalueteststruct", "bad value")
283 }
284 }
285
286 func StructValidationTestStructInvalid(sl StructLevel) {
287 st := sl.Current().Interface().(TestStruct)
288
289 if st.String != "bad value" {
290 sl.ReportError(nil, "StringVal", "String", "badvalueteststruct", "bad value")
291 }
292 }
293
294 func StructValidationTestStructReturnValidationErrors(sl StructLevel) {
295 s := sl.Current().Interface().(TestStructReturnValidationErrors)
296
297 errs := sl.Validator().Struct(s.Inner1.Inner2)
298 if errs == nil {
299 return
300 }
301
302 sl.ReportValidationErrors("Inner1.", "Inner1.", errs.(ValidationErrors))
303 }
304
305 func StructValidationTestStructReturnValidationErrors2(sl StructLevel) {
306 s := sl.Current().Interface().(TestStructReturnValidationErrors)
307
308 errs := sl.Validator().Struct(s.Inner1.Inner2)
309 if errs == nil {
310 return
311 }
312
313 sl.ReportValidationErrors("Inner1JSON.", "Inner1.", errs.(ValidationErrors))
314 }
315
316 type TestStructReturnValidationErrorsInner2 struct {
317 String string `validate:"required" json:"JSONString"`
318 }
319
320 type TestStructReturnValidationErrorsInner1 struct {
321 Inner2 *TestStructReturnValidationErrorsInner2
322 }
323
324 type TestStructReturnValidationErrors struct {
325 Inner1 *TestStructReturnValidationErrorsInner1 `json:"Inner1JSON"`
326 }
327
328 type StructLevelInvalidErr struct {
329 Value string
330 }
331
332 func StructLevelInvalidError(sl StructLevel) {
333 top := sl.Top().Interface().(StructLevelInvalidErr)
334 s := sl.Current().Interface().(StructLevelInvalidErr)
335
336 if top.Value == s.Value {
337 sl.ReportError(nil, "Value", "Value", "required", "")
338 }
339 }
340
341 func stringPtr(v string) *string {
342 return &v
343 }
344
345 func intPtr(v int) *int {
346 return &v
347 }
348
349 func float64Ptr(v float64) *float64 {
350 return &v
351 }
352
353 func TestStructLevelInvalidError(t *testing.T) {
354 validate := New()
355 validate.RegisterStructValidation(StructLevelInvalidError, StructLevelInvalidErr{})
356
357 var test StructLevelInvalidErr
358
359 err := validate.Struct(test)
360 NotEqual(t, err, nil)
361
362 errs, ok := err.(ValidationErrors)
363 Equal(t, ok, true)
364
365 fe := errs[0]
366 Equal(t, fe.Field(), "Value")
367 Equal(t, fe.StructField(), "Value")
368 Equal(t, fe.Namespace(), "StructLevelInvalidErr.Value")
369 Equal(t, fe.StructNamespace(), "StructLevelInvalidErr.Value")
370 Equal(t, fe.Tag(), "required")
371 Equal(t, fe.ActualTag(), "required")
372 Equal(t, fe.Kind(), reflect.Invalid)
373 Equal(t, fe.Type(), reflect.TypeOf(nil))
374 }
375
376 func TestNameNamespace(t *testing.T) {
377 type Inner2Namespace struct {
378 String []string `validate:"dive,required" json:"JSONString"`
379 }
380
381 type Inner1Namespace struct {
382 Inner2 *Inner2Namespace `json:"Inner2JSON"`
383 }
384
385 type Namespace struct {
386 Inner1 *Inner1Namespace `json:"Inner1JSON"`
387 }
388
389 validate := New()
390 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
391 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
392
393 if name == "-" {
394 return ""
395 }
396
397 return name
398 })
399
400 i2 := &Inner2Namespace{String: []string{"ok", "ok", "ok"}}
401 i1 := &Inner1Namespace{Inner2: i2}
402 ns := &Namespace{Inner1: i1}
403
404 errs := validate.Struct(ns)
405 Equal(t, errs, nil)
406
407 i2.String[1] = ""
408
409 errs = validate.Struct(ns)
410 NotEqual(t, errs, nil)
411
412 ve := errs.(ValidationErrors)
413 Equal(t, len(ve), 1)
414 AssertError(t, errs, "Namespace.Inner1JSON.Inner2JSON.JSONString[1]", "Namespace.Inner1.Inner2.String[1]", "JSONString[1]", "String[1]", "required")
415
416 fe := getError(ve, "Namespace.Inner1JSON.Inner2JSON.JSONString[1]", "Namespace.Inner1.Inner2.String[1]")
417 NotEqual(t, fe, nil)
418 Equal(t, fe.Field(), "JSONString[1]")
419 Equal(t, fe.StructField(), "String[1]")
420 Equal(t, fe.Namespace(), "Namespace.Inner1JSON.Inner2JSON.JSONString[1]")
421 Equal(t, fe.StructNamespace(), "Namespace.Inner1.Inner2.String[1]")
422 }
423
424 func TestAnonymous(t *testing.T) {
425 validate := New()
426 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
427 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
428
429 if name == "-" {
430 return ""
431 }
432
433 return name
434 })
435
436 type Test struct {
437 Anonymous struct {
438 A string `validate:"required" json:"EH"`
439 }
440 AnonymousB struct {
441 B string `validate:"required" json:"BEE"`
442 }
443 anonymousC struct {
444 c string `validate:"required"`
445 }
446 }
447
448 tst := &Test{
449 Anonymous: struct {
450 A string `validate:"required" json:"EH"`
451 }{
452 A: "1",
453 },
454 AnonymousB: struct {
455 B string `validate:"required" json:"BEE"`
456 }{
457 B: "",
458 },
459 anonymousC: struct {
460 c string `validate:"required"`
461 }{
462 c: "",
463 },
464 }
465
466 Equal(t, tst.anonymousC.c, "")
467
468 err := validate.Struct(tst)
469 NotEqual(t, err, nil)
470
471 errs := err.(ValidationErrors)
472
473 Equal(t, len(errs), 1)
474 AssertError(t, errs, "Test.AnonymousB.BEE", "Test.AnonymousB.B", "BEE", "B", "required")
475
476 fe := getError(errs, "Test.AnonymousB.BEE", "Test.AnonymousB.B")
477 NotEqual(t, fe, nil)
478 Equal(t, fe.Field(), "BEE")
479 Equal(t, fe.StructField(), "B")
480
481 s := struct {
482 c string `validate:"required"`
483 }{
484 c: "",
485 }
486
487 err = validate.Struct(s)
488 Equal(t, err, nil)
489 }
490
491 func TestAnonymousSameStructDifferentTags(t *testing.T) {
492 validate := New()
493 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
494 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
495
496 if name == "-" {
497 return ""
498 }
499
500 return name
501 })
502
503 type Test struct {
504 A interface{}
505 }
506
507 tst := &Test{
508 A: struct {
509 A string `validate:"required"`
510 }{
511 A: "",
512 },
513 }
514
515 err := validate.Struct(tst)
516 NotEqual(t, err, nil)
517
518 errs := err.(ValidationErrors)
519
520 Equal(t, len(errs), 1)
521 AssertError(t, errs, "Test.A.A", "Test.A.A", "A", "A", "required")
522
523 tst = &Test{
524 A: struct {
525 A string `validate:"omitempty,required"`
526 }{
527 A: "",
528 },
529 }
530
531 err = validate.Struct(tst)
532 Equal(t, err, nil)
533 }
534
535 func TestStructLevelReturnValidationErrors(t *testing.T) {
536 validate := New()
537 validate.RegisterStructValidation(StructValidationTestStructReturnValidationErrors, TestStructReturnValidationErrors{})
538
539 inner2 := &TestStructReturnValidationErrorsInner2{
540 String: "I'm HERE",
541 }
542
543 inner1 := &TestStructReturnValidationErrorsInner1{
544 Inner2: inner2,
545 }
546
547 val := &TestStructReturnValidationErrors{
548 Inner1: inner1,
549 }
550
551 errs := validate.Struct(val)
552 Equal(t, errs, nil)
553
554 inner2.String = ""
555
556 errs = validate.Struct(val)
557 NotEqual(t, errs, nil)
558 Equal(t, len(errs.(ValidationErrors)), 2)
559 AssertError(t, errs, "TestStructReturnValidationErrors.Inner1.Inner2.String", "TestStructReturnValidationErrors.Inner1.Inner2.String", "String", "String", "required")
560
561 AssertError(t, errs, "TestStructReturnValidationErrors.Inner1.TestStructReturnValidationErrorsInner2.String", "TestStructReturnValidationErrors.Inner1.TestStructReturnValidationErrorsInner2.String", "String", "String", "required")
562 }
563
564 func TestStructLevelReturnValidationErrorsWithJSON(t *testing.T) {
565 validate := New()
566 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
567 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
568
569 if name == "-" {
570 return ""
571 }
572
573 return name
574 })
575 validate.RegisterStructValidation(StructValidationTestStructReturnValidationErrors2, TestStructReturnValidationErrors{})
576
577 inner2 := &TestStructReturnValidationErrorsInner2{
578 String: "I'm HERE",
579 }
580
581 inner1 := &TestStructReturnValidationErrorsInner1{
582 Inner2: inner2,
583 }
584
585 val := &TestStructReturnValidationErrors{
586 Inner1: inner1,
587 }
588
589 errs := validate.Struct(val)
590 Equal(t, errs, nil)
591
592 inner2.String = ""
593
594 errs = validate.Struct(val)
595 NotEqual(t, errs, nil)
596 Equal(t, len(errs.(ValidationErrors)), 2)
597 AssertError(t, errs, "TestStructReturnValidationErrors.Inner1JSON.Inner2.JSONString", "TestStructReturnValidationErrors.Inner1.Inner2.String", "JSONString", "String", "required")
598
599 AssertError(t, errs, "TestStructReturnValidationErrors.Inner1JSON.TestStructReturnValidationErrorsInner2.JSONString", "TestStructReturnValidationErrors.Inner1.TestStructReturnValidationErrorsInner2.String", "JSONString", "String", "required")
600
601 fe := getError(errs, "TestStructReturnValidationErrors.Inner1JSON.Inner2.JSONString", "TestStructReturnValidationErrors.Inner1.Inner2.String")
602 NotEqual(t, fe, nil)
603
604
605 Equal(t, fe.Field(), "JSONString")
606 Equal(t, fe.StructField(), "String")
607 Equal(t, fe.Namespace(), "TestStructReturnValidationErrors.Inner1JSON.Inner2.JSONString")
608 Equal(t, fe.StructNamespace(), "TestStructReturnValidationErrors.Inner1.Inner2.String")
609
610 fe = getError(errs, "TestStructReturnValidationErrors.Inner1JSON.TestStructReturnValidationErrorsInner2.JSONString", "TestStructReturnValidationErrors.Inner1.TestStructReturnValidationErrorsInner2.String")
611 NotEqual(t, fe, nil)
612
613
614 Equal(t, fe.Field(), "JSONString")
615 Equal(t, fe.StructField(), "String")
616 Equal(t, fe.Namespace(), "TestStructReturnValidationErrors.Inner1JSON.TestStructReturnValidationErrorsInner2.JSONString")
617 Equal(t, fe.StructNamespace(), "TestStructReturnValidationErrors.Inner1.TestStructReturnValidationErrorsInner2.String")
618 }
619
620 func TestStructLevelValidations(t *testing.T) {
621 v1 := New()
622 v1.RegisterStructValidation(StructValidationTestStruct, TestStruct{})
623
624 tst := &TestStruct{
625 String: "good value",
626 }
627
628 errs := v1.Struct(tst)
629 NotEqual(t, errs, nil)
630 AssertError(t, errs, "TestStruct.StringVal", "TestStruct.String", "StringVal", "String", "badvalueteststruct")
631
632 v2 := New()
633 v2.RegisterStructValidation(StructValidationNoTestStructCustomName, TestStruct{})
634
635 errs = v2.Struct(tst)
636 NotEqual(t, errs, nil)
637 AssertError(t, errs, "TestStruct.String", "TestStruct.String", "String", "String", "badvalueteststruct")
638
639 v3 := New()
640 v3.RegisterStructValidation(StructValidationTestStructInvalid, TestStruct{})
641
642 errs = v3.Struct(tst)
643 NotEqual(t, errs, nil)
644 AssertError(t, errs, "TestStruct.StringVal", "TestStruct.String", "StringVal", "String", "badvalueteststruct")
645
646 v4 := New()
647 v4.RegisterStructValidation(StructValidationTestStructSuccess, TestStruct{})
648
649 errs = v4.Struct(tst)
650 Equal(t, errs, nil)
651 }
652
653 func TestAliasTags(t *testing.T) {
654 validate := New()
655 validate.RegisterAlias("iscoloralias", "hexcolor|rgb|rgba|hsl|hsla")
656
657 s := "rgb(255,255,255)"
658 errs := validate.Var(s, "iscoloralias")
659 Equal(t, errs, nil)
660
661 s = ""
662 errs = validate.Var(s, "omitempty,iscoloralias")
663 Equal(t, errs, nil)
664
665 s = "rgb(255,255,0)"
666 errs = validate.Var(s, "iscoloralias,len=5")
667 NotEqual(t, errs, nil)
668 AssertError(t, errs, "", "", "", "", "len")
669
670 type Test struct {
671 Color string `validate:"iscoloralias"`
672 }
673
674 tst := &Test{
675 Color: "#000",
676 }
677
678 errs = validate.Struct(tst)
679 Equal(t, errs, nil)
680
681 tst.Color = "cfvre"
682 errs = validate.Struct(tst)
683 NotEqual(t, errs, nil)
684 AssertError(t, errs, "Test.Color", "Test.Color", "Color", "Color", "iscoloralias")
685
686 fe := getError(errs, "Test.Color", "Test.Color")
687 NotEqual(t, fe, nil)
688 Equal(t, fe.ActualTag(), "hexcolor|rgb|rgba|hsl|hsla")
689
690 validate.RegisterAlias("req", "required,dive,iscoloralias")
691 arr := []string{"val1", "#fff", "#000"}
692
693 errs = validate.Var(arr, "req")
694 NotEqual(t, errs, nil)
695 AssertError(t, errs, "[0]", "[0]", "[0]", "[0]", "iscoloralias")
696
697 PanicMatches(t, func() { validate.RegisterAlias("exists!", "gt=5,lt=10") }, "Alias 'exists!' either contains restricted characters or is the same as a restricted tag needed for normal operation")
698 }
699
700 func TestNilValidator(t *testing.T) {
701 type TestStruct struct {
702 Test string `validate:"required"`
703 }
704
705 ts := TestStruct{}
706
707 var val *Validate
708
709 fn := func(fl FieldLevel) bool {
710 return fl.Parent().String() == fl.Field().String()
711 }
712
713 PanicMatches(t, func() { val.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{}) }, "runtime error: invalid memory address or nil pointer dereference")
714 PanicMatches(t, func() { _ = val.RegisterValidation("something", fn) }, "runtime error: invalid memory address or nil pointer dereference")
715 PanicMatches(t, func() { _ = val.Var(ts.Test, "required") }, "runtime error: invalid memory address or nil pointer dereference")
716 PanicMatches(t, func() { _ = val.VarWithValue("test", ts.Test, "required") }, "runtime error: invalid memory address or nil pointer dereference")
717 PanicMatches(t, func() { _ = val.Struct(ts) }, "runtime error: invalid memory address or nil pointer dereference")
718 PanicMatches(t, func() { _ = val.StructExcept(ts, "Test") }, "runtime error: invalid memory address or nil pointer dereference")
719 PanicMatches(t, func() { _ = val.StructPartial(ts, "Test") }, "runtime error: invalid memory address or nil pointer dereference")
720 }
721
722 func TestStructPartial(t *testing.T) {
723 p1 := []string{
724 "NoTag",
725 "Required",
726 }
727
728 p2 := []string{
729 "SubSlice[0].Test",
730 "Sub",
731 "SubIgnore",
732 "Anonymous.A",
733 }
734
735 p3 := []string{
736 "SubTest.Test",
737 }
738
739 p4 := []string{
740 "A",
741 }
742
743 tPartial := &TestPartial{
744 NoTag: "NoTag",
745 Required: "Required",
746
747 SubSlice: []*SubTest{
748 {
749
750 Test: "Required",
751 },
752 {
753
754 Test: "Required",
755 },
756 },
757
758 Sub: &SubTest{
759 Test: "1",
760 },
761 SubIgnore: &SubTest{
762 Test: "",
763 },
764 Anonymous: struct {
765 A string `validate:"required"`
766 ASubSlice []*SubTest `validate:"required,dive"`
767 SubAnonStruct []struct {
768 Test string `validate:"required"`
769 OtherTest string `validate:"required"`
770 } `validate:"required,dive"`
771 }{
772 A: "1",
773 ASubSlice: []*SubTest{
774 {
775 Test: "Required",
776 },
777 {
778 Test: "Required",
779 },
780 },
781
782 SubAnonStruct: []struct {
783 Test string `validate:"required"`
784 OtherTest string `validate:"required"`
785 }{
786 {"Required", "RequiredOther"},
787 {"Required", "RequiredOther"},
788 },
789 },
790 }
791
792 validate := New()
793
794
795
796 errs := validate.StructPartialCtx(context.Background(), tPartial, p1...)
797 Equal(t, errs, nil)
798
799 errs = validate.StructPartial(tPartial, p2...)
800 Equal(t, errs, nil)
801
802
803 errs = validate.StructPartial(tPartial.SubSlice[0], p3...)
804 Equal(t, errs, nil)
805
806 errs = validate.StructExceptCtx(context.Background(), tPartial, p1...)
807 Equal(t, errs, nil)
808
809 errs = validate.StructExcept(tPartial, p2...)
810 Equal(t, errs, nil)
811
812
813 tPartial.Required = ""
814
815 errs = validate.StructExcept(tPartial, p1...)
816 Equal(t, errs, nil)
817
818 errs = validate.StructPartial(tPartial, p2...)
819 Equal(t, errs, nil)
820
821
822 errs = validate.StructPartial(tPartial, p1...)
823 NotEqual(t, errs, nil)
824 AssertError(t, errs, "TestPartial.Required", "TestPartial.Required", "Required", "Required", "required")
825
826 errs = validate.StructExcept(tPartial, p2...)
827 AssertError(t, errs, "TestPartial.Required", "TestPartial.Required", "Required", "Required", "required")
828
829
830 tPartial.Required = "Required"
831 tPartial.Anonymous.A = ""
832
833
834 errs = validate.StructPartial(tPartial, p1...)
835 Equal(t, errs, nil)
836
837 errs = validate.StructExcept(tPartial, p2...)
838 Equal(t, errs, nil)
839
840
841 errs = validate.StructExcept(tPartial.Anonymous, p4...)
842 Equal(t, errs, nil)
843
844
845 errs = validate.StructPartial(tPartial, p2...)
846 NotEqual(t, errs, nil)
847 AssertError(t, errs, "TestPartial.Anonymous.A", "TestPartial.Anonymous.A", "A", "A", "required")
848
849 errs = validate.StructExcept(tPartial, p1...)
850 NotEqual(t, errs, nil)
851 AssertError(t, errs, "TestPartial.Anonymous.A", "TestPartial.Anonymous.A", "A", "A", "required")
852
853
854 tPartial.Anonymous.A = "Required"
855 tPartial.SubSlice[0].Test = ""
856
857
858 errs = validate.StructPartial(tPartial, p1...)
859 Equal(t, errs, nil)
860
861 errs = validate.StructExcept(tPartial, p2...)
862 Equal(t, errs, nil)
863
864
865 errs = validate.StructExcept(tPartial, p1...)
866 AssertError(t, errs, "TestPartial.SubSlice[0].Test", "TestPartial.SubSlice[0].Test", "Test", "Test", "required")
867 Equal(t, len(errs.(ValidationErrors)), 1)
868
869 errs = validate.StructPartial(tPartial, p2...)
870 NotEqual(t, errs, nil)
871 AssertError(t, errs, "TestPartial.SubSlice[0].Test", "TestPartial.SubSlice[0].Test", "Test", "Test", "required")
872 Equal(t, len(errs.(ValidationErrors)), 1)
873
874
875 tPartial.SubSlice[1].Test = ""
876
877 errs = validate.StructPartial(tPartial, p1...)
878 Equal(t, errs, nil)
879
880
881
882 errs = validate.StructExcept(tPartial, p2...)
883 NotEqual(t, errs, nil)
884 AssertError(t, errs, "TestPartial.SubSlice[1].Test", "TestPartial.SubSlice[1].Test", "Test", "Test", "required")
885
886 errs = validate.StructExcept(tPartial, p1...)
887 Equal(t, len(errs.(ValidationErrors)), 2)
888 AssertError(t, errs, "TestPartial.SubSlice[0].Test", "TestPartial.SubSlice[0].Test", "Test", "Test", "required")
889 AssertError(t, errs, "TestPartial.SubSlice[1].Test", "TestPartial.SubSlice[1].Test", "Test", "Test", "required")
890
891 errs = validate.StructPartial(tPartial, p2...)
892 NotEqual(t, errs, nil)
893 Equal(t, len(errs.(ValidationErrors)), 1)
894 AssertError(t, errs, "TestPartial.SubSlice[0].Test", "TestPartial.SubSlice[0].Test", "Test", "Test", "required")
895
896
897 tPartial.SubSlice[0].Test = "Required"
898
899
900 errs = validate.StructPartial(tPartial, p1...)
901 Equal(t, errs, nil)
902
903 errs = validate.StructPartial(tPartial, p2...)
904 Equal(t, errs, nil)
905
906
907 errs = validate.StructExcept(tPartial, p1...)
908 NotEqual(t, errs, nil)
909 Equal(t, len(errs.(ValidationErrors)), 1)
910 AssertError(t, errs, "TestPartial.SubSlice[1].Test", "TestPartial.SubSlice[1].Test", "Test", "Test", "required")
911
912 errs = validate.StructExcept(tPartial, p2...)
913 NotEqual(t, errs, nil)
914 AssertError(t, errs, "TestPartial.SubSlice[1].Test", "TestPartial.SubSlice[1].Test", "Test", "Test", "required")
915
916 tPartial.SubSlice[1].Test = "Required"
917
918 tPartial.Anonymous.SubAnonStruct[0].Test = ""
919
920 errs = validate.StructPartial(tPartial, p1...)
921 Equal(t, errs, nil)
922
923 errs = validate.StructPartial(tPartial, p2...)
924 Equal(t, errs, nil)
925
926 errs = validate.StructExcept(tPartial, p1...)
927 NotEqual(t, errs, nil)
928 AssertError(t, errs, "TestPartial.Anonymous.SubAnonStruct[0].Test", "TestPartial.Anonymous.SubAnonStruct[0].Test", "Test", "Test", "required")
929
930 errs = validate.StructExcept(tPartial, p2...)
931 NotEqual(t, errs, nil)
932 AssertError(t, errs, "TestPartial.Anonymous.SubAnonStruct[0].Test", "TestPartial.Anonymous.SubAnonStruct[0].Test", "Test", "Test", "required")
933
934
935 testStruct := &TestStruct{
936 String: "test",
937 }
938 unnamedStruct := struct {
939 String string `validate:"required" json:"StringVal"`
940 }{String: "test"}
941 composedUnnamedStruct := struct{ *TestStruct }{&TestStruct{String: "test"}}
942
943 errs = validate.StructPartial(testStruct, "String")
944 Equal(t, errs, nil)
945
946 errs = validate.StructPartial(unnamedStruct, "String")
947 Equal(t, errs, nil)
948
949 errs = validate.StructPartial(composedUnnamedStruct, "TestStruct.String")
950 Equal(t, errs, nil)
951
952 testStruct.String = ""
953 errs = validate.StructPartial(testStruct, "String")
954 NotEqual(t, errs, nil)
955 AssertError(t, errs, "TestStruct.String", "TestStruct.String", "String", "String", "required")
956
957 unnamedStruct.String = ""
958 errs = validate.StructPartial(unnamedStruct, "String")
959 NotEqual(t, errs, nil)
960 AssertError(t, errs, "String", "String", "String", "String", "required")
961
962 composedUnnamedStruct.String = ""
963 errs = validate.StructPartial(composedUnnamedStruct, "TestStruct.String")
964 NotEqual(t, errs, nil)
965 AssertError(t, errs, "TestStruct.String", "TestStruct.String", "String", "String", "required")
966 }
967
968 func TestCrossStructLteFieldValidation(t *testing.T) {
969 var errs error
970 validate := New()
971
972 type Inner struct {
973 CreatedAt *time.Time
974 String string
975 Int int
976 Uint uint
977 Float float64
978 Array []string
979 }
980
981 type Test struct {
982 Inner *Inner
983 CreatedAt *time.Time `validate:"ltecsfield=Inner.CreatedAt"`
984 String string `validate:"ltecsfield=Inner.String"`
985 Int int `validate:"ltecsfield=Inner.Int"`
986 Uint uint `validate:"ltecsfield=Inner.Uint"`
987 Float float64 `validate:"ltecsfield=Inner.Float"`
988 Array []string `validate:"ltecsfield=Inner.Array"`
989 }
990
991 now := time.Now().UTC()
992 then := now.Add(time.Hour * 5)
993
994 inner := &Inner{
995 CreatedAt: &then,
996 String: "abcd",
997 Int: 13,
998 Uint: 13,
999 Float: 1.13,
1000 Array: []string{"val1", "val2"},
1001 }
1002
1003 test := &Test{
1004 Inner: inner,
1005 CreatedAt: &now,
1006 String: "abc",
1007 Int: 12,
1008 Uint: 12,
1009 Float: 1.12,
1010 Array: []string{"val1"},
1011 }
1012
1013 errs = validate.Struct(test)
1014 Equal(t, errs, nil)
1015
1016 test.CreatedAt = &then
1017 test.String = "abcd"
1018 test.Int = 13
1019 test.Uint = 13
1020 test.Float = 1.13
1021 test.Array = []string{"val1", "val2"}
1022
1023 errs = validate.Struct(test)
1024 Equal(t, errs, nil)
1025
1026 after := now.Add(time.Hour * 10)
1027
1028 test.CreatedAt = &after
1029 test.String = "abce"
1030 test.Int = 14
1031 test.Uint = 14
1032 test.Float = 1.14
1033 test.Array = []string{"val1", "val2", "val3"}
1034
1035 errs = validate.Struct(test)
1036 NotEqual(t, errs, nil)
1037 AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "ltecsfield")
1038 AssertError(t, errs, "Test.String", "Test.String", "String", "String", "ltecsfield")
1039 AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "ltecsfield")
1040 AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "ltecsfield")
1041 AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "ltecsfield")
1042 AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "ltecsfield")
1043
1044 errs = validate.VarWithValueCtx(context.Background(), 1, "", "ltecsfield")
1045 NotEqual(t, errs, nil)
1046 AssertError(t, errs, "", "", "", "", "ltecsfield")
1047
1048
1049 errs = validate.VarWithValue(test, now, "ltecsfield")
1050 NotEqual(t, errs, nil)
1051 Equal(t, len(errs.(ValidationErrors)), 6)
1052 AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "ltecsfield")
1053 AssertError(t, errs, "Test.String", "Test.String", "String", "String", "ltecsfield")
1054 AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "ltecsfield")
1055 AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "ltecsfield")
1056 AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "ltecsfield")
1057 AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "ltecsfield")
1058
1059 type Other struct {
1060 Value string
1061 }
1062
1063 type Test2 struct {
1064 Value Other
1065 Time time.Time `validate:"ltecsfield=Value"`
1066 }
1067
1068 tst := Test2{
1069 Value: Other{Value: "StringVal"},
1070 Time: then,
1071 }
1072
1073 errs = validate.Struct(tst)
1074 NotEqual(t, errs, nil)
1075 AssertError(t, errs, "Test2.Time", "Test2.Time", "Time", "Time", "ltecsfield")
1076
1077
1078
1079
1080
1081 errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "ltecsfield")
1082 Equal(t, errs, nil)
1083
1084 errs = validate.VarWithValue(time.Hour, time.Hour, "ltecsfield")
1085 Equal(t, errs, nil)
1086
1087 errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "ltecsfield")
1088 NotEqual(t, errs, nil)
1089 AssertError(t, errs, "", "", "", "", "ltecsfield")
1090
1091 errs = validate.VarWithValue(time.Duration(0), -time.Minute, "omitempty,ltecsfield")
1092 Equal(t, errs, nil)
1093
1094
1095
1096 type TimeDurationInner struct {
1097 Duration time.Duration
1098 }
1099 var timeDurationInner *TimeDurationInner
1100
1101 type TimeDurationTest struct {
1102 Inner *TimeDurationInner
1103 Duration time.Duration `validate:"ltecsfield=Inner.Duration"`
1104 }
1105 var timeDurationTest *TimeDurationTest
1106
1107 timeDurationInner = &TimeDurationInner{time.Hour + time.Minute}
1108 timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
1109 errs = validate.Struct(timeDurationTest)
1110 Equal(t, errs, nil)
1111
1112 timeDurationInner = &TimeDurationInner{time.Hour}
1113 timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
1114 errs = validate.Struct(timeDurationTest)
1115 Equal(t, errs, nil)
1116
1117 timeDurationInner = &TimeDurationInner{time.Hour - time.Minute}
1118 timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
1119 errs = validate.Struct(timeDurationTest)
1120 NotEqual(t, errs, nil)
1121 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "ltecsfield")
1122
1123 type TimeDurationOmitemptyTest struct {
1124 Inner *TimeDurationInner
1125 Duration time.Duration `validate:"omitempty,ltecsfield=Inner.Duration"`
1126 }
1127 var timeDurationOmitemptyTest *TimeDurationOmitemptyTest
1128
1129 timeDurationInner = &TimeDurationInner{-time.Minute}
1130 timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)}
1131 errs = validate.Struct(timeDurationOmitemptyTest)
1132 Equal(t, errs, nil)
1133 }
1134
1135 func TestCrossStructLtFieldValidation(t *testing.T) {
1136 var errs error
1137 validate := New()
1138
1139 type Inner struct {
1140 CreatedAt *time.Time
1141 String string
1142 Int int
1143 Uint uint
1144 Float float64
1145 Array []string
1146 }
1147
1148 type Test struct {
1149 Inner *Inner
1150 CreatedAt *time.Time `validate:"ltcsfield=Inner.CreatedAt"`
1151 String string `validate:"ltcsfield=Inner.String"`
1152 Int int `validate:"ltcsfield=Inner.Int"`
1153 Uint uint `validate:"ltcsfield=Inner.Uint"`
1154 Float float64 `validate:"ltcsfield=Inner.Float"`
1155 Array []string `validate:"ltcsfield=Inner.Array"`
1156 }
1157
1158 now := time.Now().UTC()
1159 then := now.Add(time.Hour * 5)
1160
1161 inner := &Inner{
1162 CreatedAt: &then,
1163 String: "abcd",
1164 Int: 13,
1165 Uint: 13,
1166 Float: 1.13,
1167 Array: []string{"val1", "val2"},
1168 }
1169
1170 test := &Test{
1171 Inner: inner,
1172 CreatedAt: &now,
1173 String: "abc",
1174 Int: 12,
1175 Uint: 12,
1176 Float: 1.12,
1177 Array: []string{"val1"},
1178 }
1179
1180 errs = validate.Struct(test)
1181 Equal(t, errs, nil)
1182
1183 test.CreatedAt = &then
1184 test.String = "abcd"
1185 test.Int = 13
1186 test.Uint = 13
1187 test.Float = 1.13
1188 test.Array = []string{"val1", "val2"}
1189
1190 errs = validate.Struct(test)
1191 NotEqual(t, errs, nil)
1192 AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "ltcsfield")
1193 AssertError(t, errs, "Test.String", "Test.String", "String", "String", "ltcsfield")
1194 AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "ltcsfield")
1195 AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "ltcsfield")
1196 AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "ltcsfield")
1197 AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "ltcsfield")
1198
1199 errs = validate.VarWithValue(1, "", "ltcsfield")
1200 NotEqual(t, errs, nil)
1201 AssertError(t, errs, "", "", "", "", "ltcsfield")
1202
1203
1204 errs = validate.VarWithValue(test, now, "ltcsfield")
1205 NotEqual(t, errs, nil)
1206 AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "ltcsfield")
1207 AssertError(t, errs, "Test.String", "Test.String", "String", "String", "ltcsfield")
1208 AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "ltcsfield")
1209 AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "ltcsfield")
1210 AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "ltcsfield")
1211 AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "ltcsfield")
1212
1213 type Other struct {
1214 Value string
1215 }
1216
1217 type Test2 struct {
1218 Value Other
1219 Time time.Time `validate:"ltcsfield=Value"`
1220 }
1221
1222 tst := Test2{
1223 Value: Other{Value: "StringVal"},
1224 Time: then,
1225 }
1226
1227 errs = validate.Struct(tst)
1228 NotEqual(t, errs, nil)
1229 AssertError(t, errs, "Test2.Time", "Test2.Time", "Time", "Time", "ltcsfield")
1230
1231
1232
1233
1234
1235 errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "ltcsfield")
1236 Equal(t, errs, nil)
1237
1238 errs = validate.VarWithValue(time.Hour, time.Hour, "ltcsfield")
1239 NotEqual(t, errs, nil)
1240 AssertError(t, errs, "", "", "", "", "ltcsfield")
1241
1242 errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "ltcsfield")
1243 NotEqual(t, errs, nil)
1244 AssertError(t, errs, "", "", "", "", "ltcsfield")
1245
1246 errs = validate.VarWithValue(time.Duration(0), -time.Minute, "omitempty,ltcsfield")
1247 Equal(t, errs, nil)
1248
1249
1250
1251 type TimeDurationInner struct {
1252 Duration time.Duration
1253 }
1254 var timeDurationInner *TimeDurationInner
1255
1256 type TimeDurationTest struct {
1257 Inner *TimeDurationInner
1258 Duration time.Duration `validate:"ltcsfield=Inner.Duration"`
1259 }
1260 var timeDurationTest *TimeDurationTest
1261
1262 timeDurationInner = &TimeDurationInner{time.Hour + time.Minute}
1263 timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
1264 errs = validate.Struct(timeDurationTest)
1265 Equal(t, errs, nil)
1266
1267 timeDurationInner = &TimeDurationInner{time.Hour}
1268 timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
1269 errs = validate.Struct(timeDurationTest)
1270 NotEqual(t, errs, nil)
1271 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "ltcsfield")
1272
1273 timeDurationInner = &TimeDurationInner{time.Hour - time.Minute}
1274 timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
1275 errs = validate.Struct(timeDurationTest)
1276 NotEqual(t, errs, nil)
1277 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "ltcsfield")
1278
1279 type TimeDurationOmitemptyTest struct {
1280 Inner *TimeDurationInner
1281 Duration time.Duration `validate:"omitempty,ltcsfield=Inner.Duration"`
1282 }
1283 var timeDurationOmitemptyTest *TimeDurationOmitemptyTest
1284
1285 timeDurationInner = &TimeDurationInner{-time.Minute}
1286 timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)}
1287 errs = validate.Struct(timeDurationOmitemptyTest)
1288 Equal(t, errs, nil)
1289 }
1290
1291 func TestCrossStructGteFieldValidation(t *testing.T) {
1292 var errs error
1293 validate := New()
1294
1295 type Inner struct {
1296 CreatedAt *time.Time
1297 String string
1298 Int int
1299 Uint uint
1300 Float float64
1301 Array []string
1302 }
1303
1304 type Test struct {
1305 Inner *Inner
1306 CreatedAt *time.Time `validate:"gtecsfield=Inner.CreatedAt"`
1307 String string `validate:"gtecsfield=Inner.String"`
1308 Int int `validate:"gtecsfield=Inner.Int"`
1309 Uint uint `validate:"gtecsfield=Inner.Uint"`
1310 Float float64 `validate:"gtecsfield=Inner.Float"`
1311 Array []string `validate:"gtecsfield=Inner.Array"`
1312 }
1313
1314 now := time.Now().UTC()
1315 then := now.Add(time.Hour * -5)
1316
1317 inner := &Inner{
1318 CreatedAt: &then,
1319 String: "abcd",
1320 Int: 13,
1321 Uint: 13,
1322 Float: 1.13,
1323 Array: []string{"val1", "val2"},
1324 }
1325
1326 test := &Test{
1327 Inner: inner,
1328 CreatedAt: &now,
1329 String: "abcde",
1330 Int: 14,
1331 Uint: 14,
1332 Float: 1.14,
1333 Array: []string{"val1", "val2", "val3"},
1334 }
1335
1336 errs = validate.Struct(test)
1337 Equal(t, errs, nil)
1338
1339 test.CreatedAt = &then
1340 test.String = "abcd"
1341 test.Int = 13
1342 test.Uint = 13
1343 test.Float = 1.13
1344 test.Array = []string{"val1", "val2"}
1345
1346 errs = validate.Struct(test)
1347 Equal(t, errs, nil)
1348
1349 before := now.Add(time.Hour * -10)
1350
1351 test.CreatedAt = &before
1352 test.String = "abc"
1353 test.Int = 12
1354 test.Uint = 12
1355 test.Float = 1.12
1356 test.Array = []string{"val1"}
1357
1358 errs = validate.Struct(test)
1359 NotEqual(t, errs, nil)
1360 AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "gtecsfield")
1361 AssertError(t, errs, "Test.String", "Test.String", "String", "String", "gtecsfield")
1362 AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "gtecsfield")
1363 AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "gtecsfield")
1364 AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "gtecsfield")
1365 AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "gtecsfield")
1366
1367 errs = validate.VarWithValue(1, "", "gtecsfield")
1368 NotEqual(t, errs, nil)
1369 AssertError(t, errs, "", "", "", "", "gtecsfield")
1370
1371
1372 errs = validate.VarWithValue(test, now, "gtecsfield")
1373 NotEqual(t, errs, nil)
1374 AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "gtecsfield")
1375 AssertError(t, errs, "Test.String", "Test.String", "String", "String", "gtecsfield")
1376 AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "gtecsfield")
1377 AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "gtecsfield")
1378 AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "gtecsfield")
1379 AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "gtecsfield")
1380
1381 type Other struct {
1382 Value string
1383 }
1384
1385 type Test2 struct {
1386 Value Other
1387 Time time.Time `validate:"gtecsfield=Value"`
1388 }
1389
1390 tst := Test2{
1391 Value: Other{Value: "StringVal"},
1392 Time: then,
1393 }
1394
1395 errs = validate.Struct(tst)
1396 NotEqual(t, errs, nil)
1397 AssertError(t, errs, "Test2.Time", "Test2.Time", "Time", "Time", "gtecsfield")
1398
1399
1400
1401
1402
1403 errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "gtecsfield")
1404 Equal(t, errs, nil)
1405
1406 errs = validate.VarWithValue(time.Hour, time.Hour, "gtecsfield")
1407 Equal(t, errs, nil)
1408
1409 errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "gtecsfield")
1410 NotEqual(t, errs, nil)
1411 AssertError(t, errs, "", "", "", "", "gtecsfield")
1412
1413 errs = validate.VarWithValue(time.Duration(0), time.Hour, "omitempty,gtecsfield")
1414 Equal(t, errs, nil)
1415
1416
1417
1418 type TimeDurationInner struct {
1419 Duration time.Duration
1420 }
1421 var timeDurationInner *TimeDurationInner
1422
1423 type TimeDurationTest struct {
1424 Inner *TimeDurationInner
1425 Duration time.Duration `validate:"gtecsfield=Inner.Duration"`
1426 }
1427 var timeDurationTest *TimeDurationTest
1428
1429 timeDurationInner = &TimeDurationInner{time.Hour - time.Minute}
1430 timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
1431 errs = validate.Struct(timeDurationTest)
1432 Equal(t, errs, nil)
1433
1434 timeDurationInner = &TimeDurationInner{time.Hour}
1435 timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
1436 errs = validate.Struct(timeDurationTest)
1437 Equal(t, errs, nil)
1438
1439 timeDurationInner = &TimeDurationInner{time.Hour + time.Minute}
1440 timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
1441 errs = validate.Struct(timeDurationTest)
1442 NotEqual(t, errs, nil)
1443 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "gtecsfield")
1444
1445 type TimeDurationOmitemptyTest struct {
1446 Inner *TimeDurationInner
1447 Duration time.Duration `validate:"omitempty,gtecsfield=Inner.Duration"`
1448 }
1449 var timeDurationOmitemptyTest *TimeDurationOmitemptyTest
1450
1451 timeDurationInner = &TimeDurationInner{time.Hour}
1452 timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)}
1453 errs = validate.Struct(timeDurationOmitemptyTest)
1454 Equal(t, errs, nil)
1455 }
1456
1457 func TestCrossStructGtFieldValidation(t *testing.T) {
1458 var errs error
1459 validate := New()
1460
1461 type Inner struct {
1462 CreatedAt *time.Time
1463 String string
1464 Int int
1465 Uint uint
1466 Float float64
1467 Array []string
1468 }
1469
1470 type Test struct {
1471 Inner *Inner
1472 CreatedAt *time.Time `validate:"gtcsfield=Inner.CreatedAt"`
1473 String string `validate:"gtcsfield=Inner.String"`
1474 Int int `validate:"gtcsfield=Inner.Int"`
1475 Uint uint `validate:"gtcsfield=Inner.Uint"`
1476 Float float64 `validate:"gtcsfield=Inner.Float"`
1477 Array []string `validate:"gtcsfield=Inner.Array"`
1478 }
1479
1480 now := time.Now().UTC()
1481 then := now.Add(time.Hour * -5)
1482
1483 inner := &Inner{
1484 CreatedAt: &then,
1485 String: "abcd",
1486 Int: 13,
1487 Uint: 13,
1488 Float: 1.13,
1489 Array: []string{"val1", "val2"},
1490 }
1491
1492 test := &Test{
1493 Inner: inner,
1494 CreatedAt: &now,
1495 String: "abcde",
1496 Int: 14,
1497 Uint: 14,
1498 Float: 1.14,
1499 Array: []string{"val1", "val2", "val3"},
1500 }
1501
1502 errs = validate.Struct(test)
1503 Equal(t, errs, nil)
1504
1505 test.CreatedAt = &then
1506 test.String = "abcd"
1507 test.Int = 13
1508 test.Uint = 13
1509 test.Float = 1.13
1510 test.Array = []string{"val1", "val2"}
1511
1512 errs = validate.Struct(test)
1513 NotEqual(t, errs, nil)
1514 AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "gtcsfield")
1515 AssertError(t, errs, "Test.String", "Test.String", "String", "String", "gtcsfield")
1516 AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "gtcsfield")
1517 AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "gtcsfield")
1518 AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "gtcsfield")
1519 AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "gtcsfield")
1520
1521 errs = validate.VarWithValue(1, "", "gtcsfield")
1522 NotEqual(t, errs, nil)
1523 AssertError(t, errs, "", "", "", "", "gtcsfield")
1524
1525
1526 errs = validate.VarWithValue(test, now, "gtcsfield")
1527 NotEqual(t, errs, nil)
1528 AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "gtcsfield")
1529 AssertError(t, errs, "Test.String", "Test.String", "String", "String", "gtcsfield")
1530 AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "gtcsfield")
1531 AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "gtcsfield")
1532 AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "gtcsfield")
1533 AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "gtcsfield")
1534
1535 type Other struct {
1536 Value string
1537 }
1538
1539 type Test2 struct {
1540 Value Other
1541 Time time.Time `validate:"gtcsfield=Value"`
1542 }
1543
1544 tst := Test2{
1545 Value: Other{Value: "StringVal"},
1546 Time: then,
1547 }
1548
1549 errs = validate.Struct(tst)
1550 NotEqual(t, errs, nil)
1551 AssertError(t, errs, "Test2.Time", "Test2.Time", "Time", "Time", "gtcsfield")
1552
1553
1554
1555
1556
1557 errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "gtcsfield")
1558 Equal(t, errs, nil)
1559
1560 errs = validate.VarWithValue(time.Hour, time.Hour, "gtcsfield")
1561 NotEqual(t, errs, nil)
1562 AssertError(t, errs, "", "", "", "", "gtcsfield")
1563
1564 errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "gtcsfield")
1565 NotEqual(t, errs, nil)
1566 AssertError(t, errs, "", "", "", "", "gtcsfield")
1567
1568 errs = validate.VarWithValue(time.Duration(0), time.Hour, "omitempty,gtcsfield")
1569 Equal(t, errs, nil)
1570
1571
1572
1573 type TimeDurationInner struct {
1574 Duration time.Duration
1575 }
1576 var timeDurationInner *TimeDurationInner
1577
1578 type TimeDurationTest struct {
1579 Inner *TimeDurationInner
1580 Duration time.Duration `validate:"gtcsfield=Inner.Duration"`
1581 }
1582 var timeDurationTest *TimeDurationTest
1583
1584 timeDurationInner = &TimeDurationInner{time.Hour - time.Minute}
1585 timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
1586 errs = validate.Struct(timeDurationTest)
1587 Equal(t, errs, nil)
1588
1589 timeDurationInner = &TimeDurationInner{time.Hour}
1590 timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
1591 errs = validate.Struct(timeDurationTest)
1592 NotEqual(t, errs, nil)
1593 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "gtcsfield")
1594
1595 timeDurationInner = &TimeDurationInner{time.Hour + time.Minute}
1596 timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
1597 errs = validate.Struct(timeDurationTest)
1598 NotEqual(t, errs, nil)
1599 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "gtcsfield")
1600
1601 type TimeDurationOmitemptyTest struct {
1602 Inner *TimeDurationInner
1603 Duration time.Duration `validate:"omitempty,gtcsfield=Inner.Duration"`
1604 }
1605 var timeDurationOmitemptyTest *TimeDurationOmitemptyTest
1606
1607 timeDurationInner = &TimeDurationInner{time.Hour}
1608 timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)}
1609 errs = validate.Struct(timeDurationOmitemptyTest)
1610 Equal(t, errs, nil)
1611 }
1612
1613 func TestCrossStructNeFieldValidation(t *testing.T) {
1614 var errs error
1615 validate := New()
1616
1617 type Inner struct {
1618 CreatedAt *time.Time
1619 }
1620
1621 type Test struct {
1622 Inner *Inner
1623 CreatedAt *time.Time `validate:"necsfield=Inner.CreatedAt"`
1624 }
1625
1626 now := time.Now().UTC()
1627 then := now.Add(time.Hour * 5)
1628
1629 inner := &Inner{
1630 CreatedAt: &then,
1631 }
1632
1633 test := &Test{
1634 Inner: inner,
1635 CreatedAt: &now,
1636 }
1637
1638 errs = validate.Struct(test)
1639 Equal(t, errs, nil)
1640
1641 test.CreatedAt = &then
1642
1643 errs = validate.Struct(test)
1644 NotEqual(t, errs, nil)
1645 AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "necsfield")
1646
1647 var j uint64
1648 var k float64
1649 var j2 uint64
1650 var k2 float64
1651 s := "abcd"
1652 i := 1
1653 j = 1
1654 k = 1.543
1655 b := true
1656 arr := []string{"test"}
1657
1658 s2 := "abcd"
1659 i2 := 1
1660 j2 = 1
1661 k2 = 1.543
1662 b2 := true
1663 arr2 := []string{"test"}
1664 arr3 := []string{"test", "test2"}
1665 now2 := now
1666
1667 errs = validate.VarWithValue(s, s2, "necsfield")
1668 NotEqual(t, errs, nil)
1669 AssertError(t, errs, "", "", "", "", "necsfield")
1670
1671 errs = validate.VarWithValue(i2, i, "necsfield")
1672 NotEqual(t, errs, nil)
1673 AssertError(t, errs, "", "", "", "", "necsfield")
1674
1675 errs = validate.VarWithValue(j2, j, "necsfield")
1676 NotEqual(t, errs, nil)
1677 AssertError(t, errs, "", "", "", "", "necsfield")
1678
1679 errs = validate.VarWithValue(k2, k, "necsfield")
1680 NotEqual(t, errs, nil)
1681 AssertError(t, errs, "", "", "", "", "necsfield")
1682
1683 errs = validate.VarWithValue(b2, b, "necsfield")
1684 NotEqual(t, errs, nil)
1685 AssertError(t, errs, "", "", "", "", "necsfield")
1686
1687 errs = validate.VarWithValue(arr2, arr, "necsfield")
1688 NotEqual(t, errs, nil)
1689 AssertError(t, errs, "", "", "", "", "necsfield")
1690
1691 errs = validate.VarWithValue(now2, now, "necsfield")
1692 NotEqual(t, errs, nil)
1693 AssertError(t, errs, "", "", "", "", "necsfield")
1694
1695 errs = validate.VarWithValue(arr3, arr, "necsfield")
1696 Equal(t, errs, nil)
1697
1698 type SInner struct {
1699 Name string
1700 }
1701
1702 type TStruct struct {
1703 Inner *SInner
1704 CreatedAt *time.Time `validate:"necsfield=Inner"`
1705 }
1706
1707 sinner := &SInner{
1708 Name: "NAME",
1709 }
1710
1711 test2 := &TStruct{
1712 Inner: sinner,
1713 CreatedAt: &now,
1714 }
1715
1716 errs = validate.Struct(test2)
1717 Equal(t, errs, nil)
1718
1719 test2.Inner = nil
1720 errs = validate.Struct(test2)
1721 Equal(t, errs, nil)
1722
1723 errs = validate.VarWithValue(nil, 1, "necsfield")
1724 NotEqual(t, errs, nil)
1725 AssertError(t, errs, "", "", "", "", "necsfield")
1726
1727
1728
1729
1730
1731 errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "necsfield")
1732 Equal(t, errs, nil)
1733
1734 errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "necsfield")
1735 Equal(t, errs, nil)
1736
1737 errs = validate.VarWithValue(time.Hour, time.Hour, "necsfield")
1738 NotEqual(t, errs, nil)
1739 AssertError(t, errs, "", "", "", "", "necsfield")
1740
1741 errs = validate.VarWithValue(time.Duration(0), time.Duration(0), "omitempty,necsfield")
1742 Equal(t, errs, nil)
1743
1744
1745
1746 type TimeDurationInner struct {
1747 Duration time.Duration
1748 }
1749 var timeDurationInner *TimeDurationInner
1750
1751 type TimeDurationTest struct {
1752 Inner *TimeDurationInner
1753 Duration time.Duration `validate:"necsfield=Inner.Duration"`
1754 }
1755 var timeDurationTest *TimeDurationTest
1756
1757 timeDurationInner = &TimeDurationInner{time.Hour - time.Minute}
1758 timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
1759 errs = validate.Struct(timeDurationTest)
1760 Equal(t, errs, nil)
1761
1762 timeDurationInner = &TimeDurationInner{time.Hour + time.Minute}
1763 timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
1764 errs = validate.Struct(timeDurationTest)
1765 Equal(t, errs, nil)
1766
1767 timeDurationInner = &TimeDurationInner{time.Hour}
1768 timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
1769 errs = validate.Struct(timeDurationTest)
1770 NotEqual(t, errs, nil)
1771 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "necsfield")
1772
1773 type TimeDurationOmitemptyTest struct {
1774 Inner *TimeDurationInner
1775 Duration time.Duration `validate:"omitempty,necsfield=Inner.Duration"`
1776 }
1777 var timeDurationOmitemptyTest *TimeDurationOmitemptyTest
1778
1779 timeDurationInner = &TimeDurationInner{time.Duration(0)}
1780 timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)}
1781 errs = validate.Struct(timeDurationOmitemptyTest)
1782 Equal(t, errs, nil)
1783 }
1784
1785 func TestCrossStructEqFieldValidation(t *testing.T) {
1786 var errs error
1787 validate := New()
1788
1789 type Inner struct {
1790 CreatedAt *time.Time
1791 }
1792
1793 type Test struct {
1794 Inner *Inner
1795 CreatedAt *time.Time `validate:"eqcsfield=Inner.CreatedAt"`
1796 }
1797
1798 now := time.Now().UTC()
1799
1800 inner := &Inner{
1801 CreatedAt: &now,
1802 }
1803
1804 test := &Test{
1805 Inner: inner,
1806 CreatedAt: &now,
1807 }
1808
1809 errs = validate.Struct(test)
1810 Equal(t, errs, nil)
1811
1812 newTime := time.Now().Add(time.Hour).UTC()
1813 test.CreatedAt = &newTime
1814
1815 errs = validate.Struct(test)
1816 NotEqual(t, errs, nil)
1817 AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "eqcsfield")
1818
1819 var j uint64
1820 var k float64
1821 s := "abcd"
1822 i := 1
1823 j = 1
1824 k = 1.543
1825 b := true
1826 arr := []string{"test"}
1827
1828 var j2 uint64
1829 var k2 float64
1830 s2 := "abcd"
1831 i2 := 1
1832 j2 = 1
1833 k2 = 1.543
1834 b2 := true
1835 arr2 := []string{"test"}
1836 arr3 := []string{"test", "test2"}
1837 now2 := now
1838
1839 errs = validate.VarWithValue(s, s2, "eqcsfield")
1840 Equal(t, errs, nil)
1841
1842 errs = validate.VarWithValue(i2, i, "eqcsfield")
1843 Equal(t, errs, nil)
1844
1845 errs = validate.VarWithValue(j2, j, "eqcsfield")
1846 Equal(t, errs, nil)
1847
1848 errs = validate.VarWithValue(k2, k, "eqcsfield")
1849 Equal(t, errs, nil)
1850
1851 errs = validate.VarWithValue(b2, b, "eqcsfield")
1852 Equal(t, errs, nil)
1853
1854 errs = validate.VarWithValue(arr2, arr, "eqcsfield")
1855 Equal(t, errs, nil)
1856
1857 errs = validate.VarWithValue(now2, now, "eqcsfield")
1858 Equal(t, errs, nil)
1859
1860 errs = validate.VarWithValue(arr3, arr, "eqcsfield")
1861 NotEqual(t, errs, nil)
1862 AssertError(t, errs, "", "", "", "", "eqcsfield")
1863
1864 type SInner struct {
1865 Name string
1866 }
1867
1868 type TStruct struct {
1869 Inner *SInner
1870 CreatedAt *time.Time `validate:"eqcsfield=Inner"`
1871 }
1872
1873 sinner := &SInner{
1874 Name: "NAME",
1875 }
1876
1877 test2 := &TStruct{
1878 Inner: sinner,
1879 CreatedAt: &now,
1880 }
1881
1882 errs = validate.Struct(test2)
1883 NotEqual(t, errs, nil)
1884 AssertError(t, errs, "TStruct.CreatedAt", "TStruct.CreatedAt", "CreatedAt", "CreatedAt", "eqcsfield")
1885
1886 test2.Inner = nil
1887 errs = validate.Struct(test2)
1888 NotEqual(t, errs, nil)
1889 AssertError(t, errs, "TStruct.CreatedAt", "TStruct.CreatedAt", "CreatedAt", "CreatedAt", "eqcsfield")
1890
1891 errs = validate.VarWithValue(nil, 1, "eqcsfield")
1892 NotEqual(t, errs, nil)
1893 AssertError(t, errs, "", "", "", "", "eqcsfield")
1894
1895
1896
1897
1898
1899 errs = validate.VarWithValue(time.Hour, time.Hour, "eqcsfield")
1900 Equal(t, errs, nil)
1901
1902 errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "eqcsfield")
1903 NotEqual(t, errs, nil)
1904 AssertError(t, errs, "", "", "", "", "eqcsfield")
1905
1906 errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "eqcsfield")
1907 NotEqual(t, errs, nil)
1908 AssertError(t, errs, "", "", "", "", "eqcsfield")
1909
1910 errs = validate.VarWithValue(time.Duration(0), time.Hour, "omitempty,eqcsfield")
1911 Equal(t, errs, nil)
1912
1913
1914
1915 type TimeDurationInner struct {
1916 Duration time.Duration
1917 }
1918 var timeDurationInner *TimeDurationInner
1919
1920 type TimeDurationTest struct {
1921 Inner *TimeDurationInner
1922 Duration time.Duration `validate:"eqcsfield=Inner.Duration"`
1923 }
1924 var timeDurationTest *TimeDurationTest
1925
1926 timeDurationInner = &TimeDurationInner{time.Hour}
1927 timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
1928 errs = validate.Struct(timeDurationTest)
1929 Equal(t, errs, nil)
1930
1931 timeDurationInner = &TimeDurationInner{time.Hour - time.Minute}
1932 timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
1933 errs = validate.Struct(timeDurationTest)
1934 NotEqual(t, errs, nil)
1935 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "eqcsfield")
1936
1937 timeDurationInner = &TimeDurationInner{time.Hour + time.Minute}
1938 timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
1939 errs = validate.Struct(timeDurationTest)
1940 NotEqual(t, errs, nil)
1941 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "eqcsfield")
1942
1943 type TimeDurationOmitemptyTest struct {
1944 Inner *TimeDurationInner
1945 Duration time.Duration `validate:"omitempty,eqcsfield=Inner.Duration"`
1946 }
1947 var timeDurationOmitemptyTest *TimeDurationOmitemptyTest
1948
1949 timeDurationInner = &TimeDurationInner{time.Hour}
1950 timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)}
1951 errs = validate.Struct(timeDurationOmitemptyTest)
1952 Equal(t, errs, nil)
1953 }
1954
1955 func TestCrossNamespaceFieldValidation(t *testing.T) {
1956 type SliceStruct struct {
1957 Name string
1958 }
1959
1960 type Inner struct {
1961 CreatedAt *time.Time
1962 Slice []string
1963 SliceStructs []*SliceStruct
1964 SliceSlice [][]string
1965 SliceSliceStruct [][]*SliceStruct
1966 SliceMap []map[string]string
1967 Map map[string]string
1968 MapMap map[string]map[string]string
1969 MapStructs map[string]*SliceStruct
1970 MapMapStruct map[string]map[string]*SliceStruct
1971 MapSlice map[string][]string
1972 MapInt map[int]string
1973 MapInt8 map[int8]string
1974 MapInt16 map[int16]string
1975 MapInt32 map[int32]string
1976 MapInt64 map[int64]string
1977 MapUint map[uint]string
1978 MapUint8 map[uint8]string
1979 MapUint16 map[uint16]string
1980 MapUint32 map[uint32]string
1981 MapUint64 map[uint64]string
1982 MapFloat32 map[float32]string
1983 MapFloat64 map[float64]string
1984 MapBool map[bool]string
1985 }
1986
1987 type Test struct {
1988 Inner *Inner
1989 CreatedAt *time.Time
1990 }
1991
1992 now := time.Now()
1993
1994 inner := &Inner{
1995 CreatedAt: &now,
1996 Slice: []string{"val1", "val2", "val3"},
1997 SliceStructs: []*SliceStruct{{Name: "name1"}, {Name: "name2"}, {Name: "name3"}},
1998 SliceSlice: [][]string{{"1", "2", "3"}, {"4", "5", "6"}, {"7", "8", "9"}},
1999 SliceSliceStruct: [][]*SliceStruct{{{Name: "name1"}, {Name: "name2"}, {Name: "name3"}}, {{Name: "name4"}, {Name: "name5"}, {Name: "name6"}}, {{Name: "name7"}, {Name: "name8"}, {Name: "name9"}}},
2000 SliceMap: []map[string]string{{"key1": "val1", "key2": "val2", "key3": "val3"}, {"key4": "val4", "key5": "val5", "key6": "val6"}},
2001 Map: map[string]string{"key1": "val1", "key2": "val2", "key3": "val3"},
2002 MapStructs: map[string]*SliceStruct{"key1": {Name: "name1"}, "key2": {Name: "name2"}, "key3": {Name: "name3"}},
2003 MapMap: map[string]map[string]string{"key1": {"key1-1": "val1"}, "key2": {"key2-1": "val2"}, "key3": {"key3-1": "val3"}},
2004 MapMapStruct: map[string]map[string]*SliceStruct{"key1": {"key1-1": {Name: "name1"}}, "key2": {"key2-1": {Name: "name2"}}, "key3": {"key3-1": {Name: "name3"}}},
2005 MapSlice: map[string][]string{"key1": {"1", "2", "3"}, "key2": {"4", "5", "6"}, "key3": {"7", "8", "9"}},
2006 MapInt: map[int]string{1: "val1", 2: "val2", 3: "val3"},
2007 MapInt8: map[int8]string{1: "val1", 2: "val2", 3: "val3"},
2008 MapInt16: map[int16]string{1: "val1", 2: "val2", 3: "val3"},
2009 MapInt32: map[int32]string{1: "val1", 2: "val2", 3: "val3"},
2010 MapInt64: map[int64]string{1: "val1", 2: "val2", 3: "val3"},
2011 MapUint: map[uint]string{1: "val1", 2: "val2", 3: "val3"},
2012 MapUint8: map[uint8]string{1: "val1", 2: "val2", 3: "val3"},
2013 MapUint16: map[uint16]string{1: "val1", 2: "val2", 3: "val3"},
2014 MapUint32: map[uint32]string{1: "val1", 2: "val2", 3: "val3"},
2015 MapUint64: map[uint64]string{1: "val1", 2: "val2", 3: "val3"},
2016 MapFloat32: map[float32]string{1.01: "val1", 2.02: "val2", 3.03: "val3"},
2017 MapFloat64: map[float64]string{1.01: "val1", 2.02: "val2", 3.03: "val3"},
2018 MapBool: map[bool]string{true: "val1", false: "val2"},
2019 }
2020
2021 test := &Test{
2022 Inner: inner,
2023 CreatedAt: &now,
2024 }
2025
2026 val := reflect.ValueOf(test)
2027
2028 vd := New()
2029 v := &validate{
2030 v: vd,
2031 }
2032
2033 current, kind, _, ok := v.getStructFieldOKInternal(val, "Inner.CreatedAt")
2034 Equal(t, ok, true)
2035 Equal(t, kind, reflect.Struct)
2036 tm, ok := current.Interface().(time.Time)
2037 Equal(t, ok, true)
2038 Equal(t, tm, now)
2039
2040 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.Slice[1]")
2041 Equal(t, ok, true)
2042 Equal(t, kind, reflect.String)
2043 Equal(t, current.String(), "val2")
2044
2045 _, _, _, ok = v.getStructFieldOKInternal(val, "Inner.CrazyNonExistantField")
2046 Equal(t, ok, false)
2047
2048 _, _, _, ok = v.getStructFieldOKInternal(val, "Inner.Slice[101]")
2049 Equal(t, ok, false)
2050
2051 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.Map[key3]")
2052 Equal(t, ok, true)
2053 Equal(t, kind, reflect.String)
2054 Equal(t, current.String(), "val3")
2055
2056 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapMap[key2][key2-1]")
2057 Equal(t, ok, true)
2058 Equal(t, kind, reflect.String)
2059 Equal(t, current.String(), "val2")
2060
2061 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapStructs[key2].Name")
2062 Equal(t, ok, true)
2063 Equal(t, kind, reflect.String)
2064 Equal(t, current.String(), "name2")
2065
2066 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapMapStruct[key3][key3-1].Name")
2067 Equal(t, ok, true)
2068 Equal(t, kind, reflect.String)
2069 Equal(t, current.String(), "name3")
2070
2071 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.SliceSlice[2][0]")
2072 Equal(t, ok, true)
2073 Equal(t, kind, reflect.String)
2074 Equal(t, current.String(), "7")
2075
2076 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.SliceSliceStruct[2][1].Name")
2077 Equal(t, ok, true)
2078 Equal(t, kind, reflect.String)
2079 Equal(t, current.String(), "name8")
2080
2081 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.SliceMap[1][key5]")
2082 Equal(t, ok, true)
2083 Equal(t, kind, reflect.String)
2084 Equal(t, current.String(), "val5")
2085
2086 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapSlice[key3][2]")
2087 Equal(t, ok, true)
2088 Equal(t, kind, reflect.String)
2089 Equal(t, current.String(), "9")
2090
2091 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapInt[2]")
2092 Equal(t, ok, true)
2093 Equal(t, kind, reflect.String)
2094 Equal(t, current.String(), "val2")
2095
2096 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapInt8[2]")
2097 Equal(t, ok, true)
2098 Equal(t, kind, reflect.String)
2099 Equal(t, current.String(), "val2")
2100
2101 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapInt16[2]")
2102 Equal(t, ok, true)
2103 Equal(t, kind, reflect.String)
2104 Equal(t, current.String(), "val2")
2105
2106 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapInt32[2]")
2107 Equal(t, ok, true)
2108 Equal(t, kind, reflect.String)
2109 Equal(t, current.String(), "val2")
2110
2111 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapInt64[2]")
2112 Equal(t, ok, true)
2113 Equal(t, kind, reflect.String)
2114 Equal(t, current.String(), "val2")
2115
2116 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapUint[2]")
2117 Equal(t, ok, true)
2118 Equal(t, kind, reflect.String)
2119 Equal(t, current.String(), "val2")
2120
2121 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapUint8[2]")
2122 Equal(t, ok, true)
2123 Equal(t, kind, reflect.String)
2124 Equal(t, current.String(), "val2")
2125
2126 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapUint16[2]")
2127 Equal(t, ok, true)
2128 Equal(t, kind, reflect.String)
2129 Equal(t, current.String(), "val2")
2130
2131 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapUint32[2]")
2132 Equal(t, ok, true)
2133 Equal(t, kind, reflect.String)
2134 Equal(t, current.String(), "val2")
2135
2136 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapUint64[2]")
2137 Equal(t, ok, true)
2138 Equal(t, kind, reflect.String)
2139 Equal(t, current.String(), "val2")
2140
2141 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapFloat32[3.03]")
2142 Equal(t, ok, true)
2143 Equal(t, kind, reflect.String)
2144 Equal(t, current.String(), "val3")
2145
2146 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapFloat64[2.02]")
2147 Equal(t, ok, true)
2148 Equal(t, kind, reflect.String)
2149 Equal(t, current.String(), "val2")
2150
2151 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapBool[true]")
2152 Equal(t, ok, true)
2153 Equal(t, kind, reflect.String)
2154 Equal(t, current.String(), "val1")
2155
2156 inner = &Inner{
2157 CreatedAt: &now,
2158 Slice: []string{"val1", "val2", "val3"},
2159 SliceStructs: []*SliceStruct{{Name: "name1"}, {Name: "name2"}, nil},
2160 SliceSlice: [][]string{{"1", "2", "3"}, {"4", "5", "6"}, {"7", "8", "9"}},
2161 SliceSliceStruct: [][]*SliceStruct{{{Name: "name1"}, {Name: "name2"}, {Name: "name3"}}, {{Name: "name4"}, {Name: "name5"}, {Name: "name6"}}, {{Name: "name7"}, {Name: "name8"}, {Name: "name9"}}},
2162 SliceMap: []map[string]string{{"key1": "val1", "key2": "val2", "key3": "val3"}, {"key4": "val4", "key5": "val5", "key6": "val6"}},
2163 Map: map[string]string{"key1": "val1", "key2": "val2", "key3": "val3"},
2164 MapStructs: map[string]*SliceStruct{"key1": {Name: "name1"}, "key2": {Name: "name2"}, "key3": {Name: "name3"}},
2165 MapMap: map[string]map[string]string{"key1": {"key1-1": "val1"}, "key2": {"key2-1": "val2"}, "key3": {"key3-1": "val3"}},
2166 MapMapStruct: map[string]map[string]*SliceStruct{"key1": {"key1-1": {Name: "name1"}}, "key2": {"key2-1": {Name: "name2"}}, "key3": {"key3-1": {Name: "name3"}}},
2167 MapSlice: map[string][]string{"key1": {"1", "2", "3"}, "key2": {"4", "5", "6"}, "key3": {"7", "8", "9"}},
2168 }
2169
2170 test = &Test{
2171 Inner: inner,
2172 CreatedAt: nil,
2173 }
2174
2175 val = reflect.ValueOf(test)
2176
2177 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.SliceStructs[2]")
2178 Equal(t, ok, true)
2179 Equal(t, kind, reflect.Ptr)
2180 Equal(t, current.String(), "<*validator.SliceStruct Value>")
2181 Equal(t, current.IsNil(), true)
2182
2183 current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.SliceStructs[2].Name")
2184 Equal(t, ok, false)
2185 Equal(t, kind, reflect.Ptr)
2186 Equal(t, current.String(), "<*validator.SliceStruct Value>")
2187 Equal(t, current.IsNil(), true)
2188
2189 PanicMatches(t, func() { v.getStructFieldOKInternal(reflect.ValueOf(1), "crazyinput") }, "Invalid field namespace")
2190 }
2191
2192 func TestExistsValidation(t *testing.T) {
2193 jsonText := "{ \"truthiness2\": true }"
2194
2195 type Thing struct {
2196 Truthiness *bool `json:"truthiness" validate:"required"`
2197 }
2198
2199 var ting Thing
2200
2201 err := json.Unmarshal([]byte(jsonText), &ting)
2202 Equal(t, err, nil)
2203 NotEqual(t, ting, nil)
2204 Equal(t, ting.Truthiness, nil)
2205
2206 validate := New()
2207 errs := validate.Struct(ting)
2208 NotEqual(t, errs, nil)
2209 AssertError(t, errs, "Thing.Truthiness", "Thing.Truthiness", "Truthiness", "Truthiness", "required")
2210
2211 jsonText = "{ \"truthiness\": true }"
2212
2213 err = json.Unmarshal([]byte(jsonText), &ting)
2214 Equal(t, err, nil)
2215 NotEqual(t, ting, nil)
2216 Equal(t, ting.Truthiness, true)
2217
2218 errs = validate.Struct(ting)
2219 Equal(t, errs, nil)
2220 }
2221
2222 func TestSQLValue2Validation(t *testing.T) {
2223 validate := New()
2224 validate.RegisterCustomTypeFunc(ValidateValuerType, valuer{}, (*driver.Valuer)(nil), sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{})
2225 validate.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{})
2226 validate.RegisterCustomTypeFunc(OverrideIntTypeForSomeReason, 1)
2227
2228 val := valuer{
2229 Name: "",
2230 }
2231
2232 errs := validate.Var(val, "required")
2233 NotEqual(t, errs, nil)
2234 AssertError(t, errs, "", "", "", "", "required")
2235
2236 val.Name = "Valid Name"
2237 errs = validate.VarCtx(context.Background(), val, "required")
2238 Equal(t, errs, nil)
2239
2240 val.Name = "errorme"
2241
2242 PanicMatches(t, func() { _ = validate.Var(val, "required") }, "SQL Driver Valuer error: some kind of error")
2243
2244 myVal := valuer{
2245 Name: "",
2246 }
2247
2248 errs = validate.Var(myVal, "required")
2249 NotEqual(t, errs, nil)
2250 AssertError(t, errs, "", "", "", "", "required")
2251
2252 cust := MadeUpCustomType{
2253 FirstName: "Joey",
2254 LastName: "Bloggs",
2255 }
2256
2257 c := CustomMadeUpStruct{MadeUp: cust, OverriddenInt: 2}
2258
2259 errs = validate.Struct(c)
2260 Equal(t, errs, nil)
2261
2262 c.MadeUp.FirstName = ""
2263 c.OverriddenInt = 1
2264
2265 errs = validate.Struct(c)
2266 NotEqual(t, errs, nil)
2267 Equal(t, len(errs.(ValidationErrors)), 2)
2268 AssertError(t, errs, "CustomMadeUpStruct.MadeUp", "CustomMadeUpStruct.MadeUp", "MadeUp", "MadeUp", "required")
2269 AssertError(t, errs, "CustomMadeUpStruct.OverriddenInt", "CustomMadeUpStruct.OverriddenInt", "OverriddenInt", "OverriddenInt", "gt")
2270 }
2271
2272 func TestSQLValueValidation(t *testing.T) {
2273 validate := New()
2274 validate.RegisterCustomTypeFunc(ValidateValuerType, (*driver.Valuer)(nil), valuer{})
2275 validate.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{})
2276 validate.RegisterCustomTypeFunc(OverrideIntTypeForSomeReason, 1)
2277
2278 val := valuer{
2279 Name: "",
2280 }
2281
2282 errs := validate.Var(val, "required")
2283 NotEqual(t, errs, nil)
2284 AssertError(t, errs, "", "", "", "", "required")
2285
2286 val.Name = "Valid Name"
2287 errs = validate.Var(val, "required")
2288 Equal(t, errs, nil)
2289
2290 val.Name = "errorme"
2291
2292 PanicMatches(t, func() { errs = validate.Var(val, "required") }, "SQL Driver Valuer error: some kind of error")
2293
2294 myVal := valuer{
2295 Name: "",
2296 }
2297
2298 errs = validate.Var(myVal, "required")
2299 NotEqual(t, errs, nil)
2300 AssertError(t, errs, "", "", "", "", "required")
2301
2302 cust := MadeUpCustomType{
2303 FirstName: "Joey",
2304 LastName: "Bloggs",
2305 }
2306
2307 c := CustomMadeUpStruct{MadeUp: cust, OverriddenInt: 2}
2308
2309 errs = validate.Struct(c)
2310 Equal(t, errs, nil)
2311
2312 c.MadeUp.FirstName = ""
2313 c.OverriddenInt = 1
2314
2315 errs = validate.Struct(c)
2316 NotEqual(t, errs, nil)
2317 Equal(t, len(errs.(ValidationErrors)), 2)
2318 AssertError(t, errs, "CustomMadeUpStruct.MadeUp", "CustomMadeUpStruct.MadeUp", "MadeUp", "MadeUp", "required")
2319 AssertError(t, errs, "CustomMadeUpStruct.OverriddenInt", "CustomMadeUpStruct.OverriddenInt", "OverriddenInt", "OverriddenInt", "gt")
2320
2321
2322 type InvalidValuePanicSafetyTest struct {
2323 V valuer
2324 }
2325 errs = validate.Struct(InvalidValuePanicSafetyTest{})
2326 Equal(t, errs, nil)
2327 }
2328
2329 func TestMACValidation(t *testing.T) {
2330 tests := []struct {
2331 param string
2332 expected bool
2333 }{
2334 {"3D:F2:C9:A6:B3:4F", true},
2335 {"3D-F2-C9-A6-B3:4F", false},
2336 {"123", false},
2337 {"", false},
2338 {"abacaba", false},
2339 {"00:25:96:FF:FE:12:34:56", true},
2340 {"0025:96FF:FE12:3456", false},
2341 }
2342
2343 validate := New()
2344
2345 for i, test := range tests {
2346
2347 errs := validate.Var(test.param, "mac")
2348
2349 if test.expected {
2350 if !IsEqual(errs, nil) {
2351 t.Fatalf("Index: %d mac failed Error: %s", i, errs)
2352 }
2353 } else {
2354 if IsEqual(errs, nil) {
2355 t.Fatalf("Index: %d mac failed Error: %s", i, errs)
2356 } else {
2357 val := getError(errs, "", "")
2358 if val.Tag() != "mac" {
2359 t.Fatalf("Index: %d mac failed Error: %s", i, errs)
2360 }
2361 }
2362 }
2363 }
2364 }
2365
2366 func TestIPValidation(t *testing.T) {
2367 tests := []struct {
2368 param string
2369 expected bool
2370 }{
2371 {"", false},
2372 {"10.0.0.1", true},
2373 {"172.16.0.1", true},
2374 {"192.168.0.1", true},
2375 {"192.168.255.254", true},
2376 {"192.168.255.256", false},
2377 {"172.16.255.254", true},
2378 {"172.16.256.255", false},
2379 {"2001:cdba:0000:0000:0000:0000:3257:9652", true},
2380 {"2001:cdba:0:0:0:0:3257:9652", true},
2381 {"2001:cdba::3257:9652", true},
2382 }
2383
2384 validate := New()
2385
2386 for i, test := range tests {
2387
2388 errs := validate.Var(test.param, "ip")
2389
2390 if test.expected {
2391 if !IsEqual(errs, nil) {
2392 t.Fatalf("Index: %d ip failed Error: %s", i, errs)
2393 }
2394 } else {
2395 if IsEqual(errs, nil) {
2396 t.Fatalf("Index: %d ip failed Error: %s", i, errs)
2397 } else {
2398 val := getError(errs, "", "")
2399 if val.Tag() != "ip" {
2400 t.Fatalf("Index: %d ip failed Error: %s", i, errs)
2401 }
2402 }
2403 }
2404 }
2405 }
2406
2407 func TestIPv6Validation(t *testing.T) {
2408 tests := []struct {
2409 param string
2410 expected bool
2411 }{
2412 {"10.0.0.1", false},
2413 {"172.16.0.1", false},
2414 {"192.168.0.1", false},
2415 {"192.168.255.254", false},
2416 {"192.168.255.256", false},
2417 {"172.16.255.254", false},
2418 {"172.16.256.255", false},
2419 {"2001:cdba:0000:0000:0000:0000:3257:9652", true},
2420 {"2001:cdba:0:0:0:0:3257:9652", true},
2421 {"2001:cdba::3257:9652", true},
2422 }
2423
2424 validate := New()
2425
2426 for i, test := range tests {
2427
2428 errs := validate.Var(test.param, "ipv6")
2429
2430 if test.expected {
2431 if !IsEqual(errs, nil) {
2432 t.Fatalf("Index: %d ipv6 failed Error: %s", i, errs)
2433 }
2434 } else {
2435 if IsEqual(errs, nil) {
2436 t.Fatalf("Index: %d ipv6 failed Error: %s", i, errs)
2437 } else {
2438 val := getError(errs, "", "")
2439 if val.Tag() != "ipv6" {
2440 t.Fatalf("Index: %d ipv6 failed Error: %s", i, errs)
2441 }
2442 }
2443 }
2444 }
2445 }
2446
2447 func TestIPv4Validation(t *testing.T) {
2448 tests := []struct {
2449 param string
2450 expected bool
2451 }{
2452 {"10.0.0.1", true},
2453 {"172.16.0.1", true},
2454 {"192.168.0.1", true},
2455 {"192.168.255.254", true},
2456 {"192.168.255.256", false},
2457 {"172.16.255.254", true},
2458 {"172.16.256.255", false},
2459 {"2001:cdba:0000:0000:0000:0000:3257:9652", false},
2460 {"2001:cdba:0:0:0:0:3257:9652", false},
2461 {"2001:cdba::3257:9652", false},
2462 }
2463
2464 validate := New()
2465
2466 for i, test := range tests {
2467
2468 errs := validate.Var(test.param, "ipv4")
2469
2470 if test.expected {
2471 if !IsEqual(errs, nil) {
2472 t.Fatalf("Index: %d ipv4 failed Error: %s", i, errs)
2473 }
2474 } else {
2475 if IsEqual(errs, nil) {
2476 t.Fatalf("Index: %d ipv4 failed Error: %s", i, errs)
2477 } else {
2478 val := getError(errs, "", "")
2479 if val.Tag() != "ipv4" {
2480 t.Fatalf("Index: %d ipv4 failed Error: %s", i, errs)
2481 }
2482 }
2483 }
2484 }
2485 }
2486
2487 func TestCIDRValidation(t *testing.T) {
2488 tests := []struct {
2489 param string
2490 expected bool
2491 }{
2492 {"10.0.0.0/0", true},
2493 {"10.0.0.1/8", true},
2494 {"172.16.0.1/16", true},
2495 {"192.168.0.1/24", true},
2496 {"192.168.255.254/24", true},
2497 {"192.168.255.254/48", false},
2498 {"192.168.255.256/24", false},
2499 {"172.16.255.254/16", true},
2500 {"172.16.256.255/16", false},
2501 {"2001:cdba:0000:0000:0000:0000:3257:9652/64", true},
2502 {"2001:cdba:0000:0000:0000:0000:3257:9652/256", false},
2503 {"2001:cdba:0:0:0:0:3257:9652/32", true},
2504 {"2001:cdba::3257:9652/16", true},
2505 }
2506
2507 validate := New()
2508
2509 for i, test := range tests {
2510
2511 errs := validate.Var(test.param, "cidr")
2512
2513 if test.expected {
2514 if !IsEqual(errs, nil) {
2515 t.Fatalf("Index: %d cidr failed Error: %s", i, errs)
2516 }
2517 } else {
2518 if IsEqual(errs, nil) {
2519 t.Fatalf("Index: %d cidr failed Error: %s", i, errs)
2520 } else {
2521 val := getError(errs, "", "")
2522 if val.Tag() != "cidr" {
2523 t.Fatalf("Index: %d cidr failed Error: %s", i, errs)
2524 }
2525 }
2526 }
2527 }
2528 }
2529
2530 func TestCIDRv6Validation(t *testing.T) {
2531 tests := []struct {
2532 param string
2533 expected bool
2534 }{
2535 {"10.0.0.0/0", false},
2536 {"10.0.0.1/8", false},
2537 {"172.16.0.1/16", false},
2538 {"192.168.0.1/24", false},
2539 {"192.168.255.254/24", false},
2540 {"192.168.255.254/48", false},
2541 {"192.168.255.256/24", false},
2542 {"172.16.255.254/16", false},
2543 {"172.16.256.255/16", false},
2544 {"2001:cdba:0000:0000:0000:0000:3257:9652/64", true},
2545 {"2001:cdba:0000:0000:0000:0000:3257:9652/256", false},
2546 {"2001:cdba:0:0:0:0:3257:9652/32", true},
2547 {"2001:cdba::3257:9652/16", true},
2548 }
2549
2550 validate := New()
2551
2552 for i, test := range tests {
2553
2554 errs := validate.Var(test.param, "cidrv6")
2555
2556 if test.expected {
2557 if !IsEqual(errs, nil) {
2558 t.Fatalf("Index: %d cidrv6 failed Error: %s", i, errs)
2559 }
2560 } else {
2561 if IsEqual(errs, nil) {
2562 t.Fatalf("Index: %d cidrv6 failed Error: %s", i, errs)
2563 } else {
2564 val := getError(errs, "", "")
2565 if val.Tag() != "cidrv6" {
2566 t.Fatalf("Index: %d cidrv6 failed Error: %s", i, errs)
2567 }
2568 }
2569 }
2570 }
2571 }
2572
2573 func TestCIDRv4Validation(t *testing.T) {
2574 tests := []struct {
2575 param string
2576 expected bool
2577 }{
2578 {"0.0.0.0/0", true},
2579 {"10.0.0.0/0", false},
2580 {"10.0.0.0/8", true},
2581 {"10.0.0.1/8", false},
2582 {"172.16.0.0/16", true},
2583 {"172.16.0.1/16", false},
2584 {"192.168.0.0/24", true},
2585 {"192.168.0.1/24", false},
2586 {"192.168.255.0/24", true},
2587 {"192.168.255.254/24", false},
2588 {"192.168.255.254/48", false},
2589 {"192.168.255.256/24", false},
2590 {"172.16.0.0/16", true},
2591 {"172.16.255.254/16", false},
2592 {"172.16.256.255/16", false},
2593 {"2001:cdba:0000:0000:0000:0000:3257:9652/64", false},
2594 {"2001:cdba:0000:0000:0000:0000:3257:9652/256", false},
2595 {"2001:cdba:0:0:0:0:3257:9652/32", false},
2596 {"2001:cdba::3257:9652/16", false},
2597 {"172.56.1.0/16", false},
2598 }
2599
2600 validate := New()
2601
2602 for i, test := range tests {
2603
2604 errs := validate.Var(test.param, "cidrv4")
2605
2606 if test.expected {
2607 if !IsEqual(errs, nil) {
2608 t.Fatalf("Index: %d cidrv4 failed Error: %s", i, errs)
2609 }
2610 } else {
2611 if IsEqual(errs, nil) {
2612 t.Fatalf("Index: %d cidrv4 failed Error: %s", i, errs)
2613 } else {
2614 val := getError(errs, "", "")
2615 if val.Tag() != "cidrv4" {
2616 t.Fatalf("Index: %d cidrv4 failed Error: %s", i, errs)
2617 }
2618 }
2619 }
2620 }
2621 }
2622
2623 func TestTCPAddrValidation(t *testing.T) {
2624 tests := []struct {
2625 param string
2626 expected bool
2627 }{
2628 {"", false},
2629 {":80", false},
2630 {"127.0.0.1:80", true},
2631 {"[::1]:80", true},
2632 {"256.0.0.0:1", false},
2633 {"[::1]", false},
2634 }
2635
2636 validate := New()
2637
2638 for i, test := range tests {
2639 errs := validate.Var(test.param, "tcp_addr")
2640 if test.expected {
2641 if !IsEqual(errs, nil) {
2642 t.Fatalf("Index: %d tcp_addr failed Error: %s", i, errs)
2643 }
2644 } else {
2645 if IsEqual(errs, nil) {
2646 t.Fatalf("Index: %d tcp_addr failed Error: %s", i, errs)
2647 } else {
2648 val := getError(errs, "", "")
2649 if val.Tag() != "tcp_addr" {
2650 t.Fatalf("Index: %d tcp_addr failed Error: %s", i, errs)
2651 }
2652 }
2653 }
2654 }
2655 }
2656
2657 func TestTCP6AddrValidation(t *testing.T) {
2658 tests := []struct {
2659 param string
2660 expected bool
2661 }{
2662 {"", false},
2663 {":80", false},
2664 {"127.0.0.1:80", false},
2665 {"[::1]:80", true},
2666 {"256.0.0.0:1", false},
2667 {"[::1]", false},
2668 }
2669
2670 validate := New()
2671
2672 for i, test := range tests {
2673 errs := validate.Var(test.param, "tcp6_addr")
2674 if test.expected {
2675 if !IsEqual(errs, nil) {
2676 t.Fatalf("Index: %d tcp6_addr failed Error: %s", i, errs)
2677 }
2678 } else {
2679 if IsEqual(errs, nil) {
2680 t.Fatalf("Index: %d tcp6_addr failed Error: %s", i, errs)
2681 } else {
2682 val := getError(errs, "", "")
2683 if val.Tag() != "tcp6_addr" {
2684 t.Fatalf("Index: %d tcp6_addr failed Error: %s", i, errs)
2685 }
2686 }
2687 }
2688 }
2689 }
2690
2691 func TestTCP4AddrValidation(t *testing.T) {
2692 tests := []struct {
2693 param string
2694 expected bool
2695 }{
2696 {"", false},
2697 {":80", false},
2698 {"127.0.0.1:80", true},
2699 {"[::1]:80", false},
2700 {"256.0.0.0:1", false},
2701 {"[::1]", false},
2702 }
2703
2704 validate := New()
2705
2706 for i, test := range tests {
2707 errs := validate.Var(test.param, "tcp4_addr")
2708 if test.expected {
2709 if !IsEqual(errs, nil) {
2710 t.Fatalf("Index: %d tcp4_addr failed Error: %s", i, errs)
2711 }
2712 } else {
2713 if IsEqual(errs, nil) {
2714 t.Log(test.param, IsEqual(errs, nil))
2715 t.Fatalf("Index: %d tcp4_addr failed Error: %s", i, errs)
2716 } else {
2717 val := getError(errs, "", "")
2718 if val.Tag() != "tcp4_addr" {
2719 t.Fatalf("Index: %d tcp4_addr failed Error: %s", i, errs)
2720 }
2721 }
2722 }
2723 }
2724 }
2725
2726 func TestUDPAddrValidation(t *testing.T) {
2727 tests := []struct {
2728 param string
2729 expected bool
2730 }{
2731 {"", false},
2732 {":80", false},
2733 {"127.0.0.1:80", true},
2734 {"[::1]:80", true},
2735 {"256.0.0.0:1", false},
2736 {"[::1]", false},
2737 }
2738
2739 validate := New()
2740
2741 for i, test := range tests {
2742 errs := validate.Var(test.param, "udp_addr")
2743 if test.expected {
2744 if !IsEqual(errs, nil) {
2745 t.Fatalf("Index: %d udp_addr failed Error: %s", i, errs)
2746 }
2747 } else {
2748 if IsEqual(errs, nil) {
2749 t.Fatalf("Index: %d udp_addr failed Error: %s", i, errs)
2750 } else {
2751 val := getError(errs, "", "")
2752 if val.Tag() != "udp_addr" {
2753 t.Fatalf("Index: %d udp_addr failed Error: %s", i, errs)
2754 }
2755 }
2756 }
2757 }
2758 }
2759
2760 func TestUDP6AddrValidation(t *testing.T) {
2761 tests := []struct {
2762 param string
2763 expected bool
2764 }{
2765 {"", false},
2766 {":80", false},
2767 {"127.0.0.1:80", false},
2768 {"[::1]:80", true},
2769 {"256.0.0.0:1", false},
2770 {"[::1]", false},
2771 }
2772
2773 validate := New()
2774
2775 for i, test := range tests {
2776 errs := validate.Var(test.param, "udp6_addr")
2777 if test.expected {
2778 if !IsEqual(errs, nil) {
2779 t.Fatalf("Index: %d udp6_addr failed Error: %s", i, errs)
2780 }
2781 } else {
2782 if IsEqual(errs, nil) {
2783 t.Fatalf("Index: %d udp6_addr failed Error: %s", i, errs)
2784 } else {
2785 val := getError(errs, "", "")
2786 if val.Tag() != "udp6_addr" {
2787 t.Fatalf("Index: %d udp6_addr failed Error: %s", i, errs)
2788 }
2789 }
2790 }
2791 }
2792 }
2793
2794 func TestUDP4AddrValidation(t *testing.T) {
2795 tests := []struct {
2796 param string
2797 expected bool
2798 }{
2799 {"", false},
2800 {":80", false},
2801 {"127.0.0.1:80", true},
2802 {"[::1]:80", false},
2803 {"256.0.0.0:1", false},
2804 {"[::1]", false},
2805 }
2806
2807 validate := New()
2808
2809 for i, test := range tests {
2810 errs := validate.Var(test.param, "udp4_addr")
2811 if test.expected {
2812 if !IsEqual(errs, nil) {
2813 t.Fatalf("Index: %d udp4_addr failed Error: %s", i, errs)
2814 }
2815 } else {
2816 if IsEqual(errs, nil) {
2817 t.Log(test.param, IsEqual(errs, nil))
2818 t.Fatalf("Index: %d udp4_addr failed Error: %s", i, errs)
2819 } else {
2820 val := getError(errs, "", "")
2821 if val.Tag() != "udp4_addr" {
2822 t.Fatalf("Index: %d udp4_addr failed Error: %s", i, errs)
2823 }
2824 }
2825 }
2826 }
2827 }
2828
2829 func TestIPAddrValidation(t *testing.T) {
2830 tests := []struct {
2831 param string
2832 expected bool
2833 }{
2834 {"", false},
2835 {"127.0.0.1", true},
2836 {"127.0.0.1:80", false},
2837 {"::1", true},
2838 {"256.0.0.0", false},
2839 {"localhost", false},
2840 }
2841
2842 validate := New()
2843
2844 for i, test := range tests {
2845 errs := validate.Var(test.param, "ip_addr")
2846 if test.expected {
2847 if !IsEqual(errs, nil) {
2848 t.Fatalf("Index: %d ip_addr failed Error: %s", i, errs)
2849 }
2850 } else {
2851 if IsEqual(errs, nil) {
2852 t.Fatalf("Index: %d ip_addr failed Error: %s", i, errs)
2853 } else {
2854 val := getError(errs, "", "")
2855 if val.Tag() != "ip_addr" {
2856 t.Fatalf("Index: %d ip_addr failed Error: %s", i, errs)
2857 }
2858 }
2859 }
2860 }
2861 }
2862
2863 func TestIP6AddrValidation(t *testing.T) {
2864 tests := []struct {
2865 param string
2866 expected bool
2867 }{
2868 {"", false},
2869 {"127.0.0.1", false},
2870 {"127.0.0.1:80", false},
2871 {"::1", true},
2872 {"0:0:0:0:0:0:0:1", true},
2873 {"256.0.0.0", false},
2874 }
2875
2876 validate := New()
2877
2878 for i, test := range tests {
2879 errs := validate.Var(test.param, "ip6_addr")
2880 if test.expected {
2881 if !IsEqual(errs, nil) {
2882 t.Fatalf("Index: %d ip6_addr failed Error: %s", i, errs)
2883 }
2884 } else {
2885 if IsEqual(errs, nil) {
2886 t.Fatalf("Index: %d ip6_addr failed Error: %s", i, errs)
2887 } else {
2888 val := getError(errs, "", "")
2889 if val.Tag() != "ip6_addr" {
2890 t.Fatalf("Index: %d ip6_addr failed Error: %s", i, errs)
2891 }
2892 }
2893 }
2894 }
2895 }
2896
2897 func TestIP4AddrValidation(t *testing.T) {
2898 tests := []struct {
2899 param string
2900 expected bool
2901 }{
2902 {"", false},
2903 {"127.0.0.1", true},
2904 {"127.0.0.1:80", false},
2905 {"::1", false},
2906 {"256.0.0.0", false},
2907 {"localhost", false},
2908 }
2909
2910 validate := New()
2911
2912 for i, test := range tests {
2913 errs := validate.Var(test.param, "ip4_addr")
2914 if test.expected {
2915 if !IsEqual(errs, nil) {
2916 t.Fatalf("Index: %d ip4_addr failed Error: %s", i, errs)
2917 }
2918 } else {
2919 if IsEqual(errs, nil) {
2920 t.Log(test.param, IsEqual(errs, nil))
2921 t.Fatalf("Index: %d ip4_addr failed Error: %s", i, errs)
2922 } else {
2923 val := getError(errs, "", "")
2924 if val.Tag() != "ip4_addr" {
2925 t.Fatalf("Index: %d ip4_addr failed Error: %s", i, errs)
2926 }
2927 }
2928 }
2929 }
2930 }
2931
2932 func TestUnixAddrValidation(t *testing.T) {
2933 tests := []struct {
2934 param string
2935 expected bool
2936 }{
2937 {"", true},
2938 {"v.sock", true},
2939 }
2940
2941 validate := New()
2942
2943 for i, test := range tests {
2944 errs := validate.Var(test.param, "unix_addr")
2945 if test.expected {
2946 if !IsEqual(errs, nil) {
2947 t.Fatalf("Index: %d unix_addr failed Error: %s", i, errs)
2948 }
2949 } else {
2950 if IsEqual(errs, nil) {
2951 t.Log(test.param, IsEqual(errs, nil))
2952 t.Fatalf("Index: %d unix_addr failed Error: %s", i, errs)
2953 } else {
2954 val := getError(errs, "", "")
2955 if val.Tag() != "unix_addr" {
2956 t.Fatalf("Index: %d unix_addr failed Error: %s", i, errs)
2957 }
2958 }
2959 }
2960 }
2961 }
2962
2963 func TestSliceMapArrayChanFuncPtrInterfaceRequiredValidation(t *testing.T) {
2964 validate := New()
2965
2966 var m map[string]string
2967
2968 errs := validate.Var(m, "required")
2969 NotEqual(t, errs, nil)
2970 AssertError(t, errs, "", "", "", "", "required")
2971
2972 m = map[string]string{}
2973 errs = validate.Var(m, "required")
2974 Equal(t, errs, nil)
2975
2976 var arr [5]string
2977 errs = validate.Var(arr, "required")
2978 NotEqual(t, errs, nil)
2979 AssertError(t, errs, "", "", "", "", "required")
2980
2981 arr[0] = "ok"
2982 errs = validate.Var(arr, "required")
2983 Equal(t, errs, nil)
2984
2985 var s []string
2986 errs = validate.Var(s, "required")
2987 NotEqual(t, errs, nil)
2988 AssertError(t, errs, "", "", "", "", "required")
2989
2990 s = []string{}
2991 errs = validate.Var(s, "required")
2992 Equal(t, errs, nil)
2993
2994 var c chan string
2995 errs = validate.Var(c, "required")
2996 NotEqual(t, errs, nil)
2997 AssertError(t, errs, "", "", "", "", "required")
2998
2999 c = make(chan string)
3000 errs = validate.Var(c, "required")
3001 Equal(t, errs, nil)
3002
3003 var tst *int
3004 errs = validate.Var(tst, "required")
3005 NotEqual(t, errs, nil)
3006 AssertError(t, errs, "", "", "", "", "required")
3007
3008 one := 1
3009 tst = &one
3010 errs = validate.Var(tst, "required")
3011 Equal(t, errs, nil)
3012
3013 var iface interface{}
3014
3015 errs = validate.Var(iface, "required")
3016 NotEqual(t, errs, nil)
3017 AssertError(t, errs, "", "", "", "", "required")
3018
3019 errs = validate.Var(iface, "omitempty,required")
3020 Equal(t, errs, nil)
3021
3022 errs = validate.Var(iface, "")
3023 Equal(t, errs, nil)
3024
3025 errs = validate.VarWithValue(nil, iface, "")
3026 Equal(t, errs, nil)
3027
3028 var f func(string)
3029
3030 errs = validate.Var(f, "required")
3031 NotEqual(t, errs, nil)
3032 AssertError(t, errs, "", "", "", "", "required")
3033
3034 f = func(name string) {}
3035
3036 errs = validate.Var(f, "required")
3037 Equal(t, errs, nil)
3038 }
3039
3040 func TestDatePtrValidationIssueValidation(t *testing.T) {
3041 type Test struct {
3042 LastViewed *time.Time
3043 Reminder *time.Time
3044 }
3045
3046 test := &Test{}
3047
3048 validate := New()
3049 errs := validate.Struct(test)
3050 Equal(t, errs, nil)
3051 }
3052
3053 func TestCommaAndPipeObfuscationValidation(t *testing.T) {
3054 s := "My Name Is, |joeybloggs|"
3055
3056 validate := New()
3057
3058 errs := validate.Var(s, "excludesall=0x2C")
3059 NotEqual(t, errs, nil)
3060 AssertError(t, errs, "", "", "", "", "excludesall")
3061
3062 errs = validate.Var(s, "excludesall=0x7C")
3063 NotEqual(t, errs, nil)
3064 AssertError(t, errs, "", "", "", "", "excludesall")
3065 }
3066
3067 func TestBadKeyValidation(t *testing.T) {
3068 type Test struct {
3069 Name string `validate:"required, "`
3070 }
3071
3072 tst := &Test{
3073 Name: "test",
3074 }
3075
3076 validate := New()
3077
3078 PanicMatches(t, func() { _ = validate.Struct(tst) }, "Undefined validation function ' ' on field 'Name'")
3079
3080 type Test2 struct {
3081 Name string `validate:"required,,len=2"`
3082 }
3083
3084 tst2 := &Test2{
3085 Name: "test",
3086 }
3087
3088 PanicMatches(t, func() { _ = validate.Struct(tst2) }, "Invalid validation tag on field 'Name'")
3089 }
3090
3091 func TestInterfaceErrValidation(t *testing.T) {
3092 var v2 interface{} = 1
3093 var v1 interface{} = v2
3094
3095 validate := New()
3096 errs := validate.Var(v1, "len=1")
3097 Equal(t, errs, nil)
3098
3099 errs = validate.Var(v2, "len=1")
3100 Equal(t, errs, nil)
3101
3102 type ExternalCMD struct {
3103 Userid string `json:"userid"`
3104 Action uint32 `json:"action"`
3105 Data interface{} `json:"data,omitempty" validate:"required"`
3106 }
3107
3108 s := &ExternalCMD{
3109 Userid: "123456",
3110 Action: 10000,
3111
3112 }
3113
3114 errs = validate.Struct(s)
3115 NotEqual(t, errs, nil)
3116 Equal(t, len(errs.(ValidationErrors)), 1)
3117 AssertError(t, errs, "ExternalCMD.Data", "ExternalCMD.Data", "Data", "Data", "required")
3118
3119 type ExternalCMD2 struct {
3120 Userid string `json:"userid"`
3121 Action uint32 `json:"action"`
3122 Data interface{} `json:"data,omitempty" validate:"len=1"`
3123 }
3124
3125 s2 := &ExternalCMD2{
3126 Userid: "123456",
3127 Action: 10000,
3128
3129 }
3130
3131 errs = validate.Struct(s2)
3132 NotEqual(t, errs, nil)
3133 Equal(t, len(errs.(ValidationErrors)), 1)
3134 AssertError(t, errs, "ExternalCMD2.Data", "ExternalCMD2.Data", "Data", "Data", "len")
3135
3136 s3 := &ExternalCMD2{
3137 Userid: "123456",
3138 Action: 10000,
3139 Data: 2,
3140 }
3141
3142 errs = validate.Struct(s3)
3143 NotEqual(t, errs, nil)
3144 Equal(t, len(errs.(ValidationErrors)), 1)
3145 AssertError(t, errs, "ExternalCMD2.Data", "ExternalCMD2.Data", "Data", "Data", "len")
3146
3147 type Inner struct {
3148 Name string `validate:"required"`
3149 }
3150
3151 inner := &Inner{
3152 Name: "",
3153 }
3154
3155 s4 := &ExternalCMD{
3156 Userid: "123456",
3157 Action: 10000,
3158 Data: inner,
3159 }
3160
3161 errs = validate.Struct(s4)
3162 NotEqual(t, errs, nil)
3163 Equal(t, len(errs.(ValidationErrors)), 1)
3164 AssertError(t, errs, "ExternalCMD.Data.Name", "ExternalCMD.Data.Name", "Name", "Name", "required")
3165
3166 type TestMapStructPtr struct {
3167 Errs map[int]interface{} `validate:"gt=0,dive,required"`
3168 }
3169
3170 mip := map[int]interface{}{0: &Inner{"ok"}, 3: nil, 4: &Inner{"ok"}}
3171
3172 msp := &TestMapStructPtr{
3173 Errs: mip,
3174 }
3175
3176 errs = validate.Struct(msp)
3177 NotEqual(t, errs, nil)
3178 Equal(t, len(errs.(ValidationErrors)), 1)
3179 AssertError(t, errs, "TestMapStructPtr.Errs[3]", "TestMapStructPtr.Errs[3]", "Errs[3]", "Errs[3]", "required")
3180
3181 type TestMultiDimensionalStructs struct {
3182 Errs [][]interface{} `validate:"gt=0,dive,dive"`
3183 }
3184
3185 var errStructArray [][]interface{}
3186
3187 errStructArray = append(errStructArray, []interface{}{&Inner{"ok"}, &Inner{""}, &Inner{""}})
3188 errStructArray = append(errStructArray, []interface{}{&Inner{"ok"}, &Inner{""}, &Inner{""}})
3189
3190 tms := &TestMultiDimensionalStructs{
3191 Errs: errStructArray,
3192 }
3193
3194 errs = validate.Struct(tms)
3195 NotEqual(t, errs, nil)
3196 Equal(t, len(errs.(ValidationErrors)), 4)
3197 AssertError(t, errs, "TestMultiDimensionalStructs.Errs[0][1].Name", "TestMultiDimensionalStructs.Errs[0][1].Name", "Name", "Name", "required")
3198 AssertError(t, errs, "TestMultiDimensionalStructs.Errs[0][2].Name", "TestMultiDimensionalStructs.Errs[0][2].Name", "Name", "Name", "required")
3199 AssertError(t, errs, "TestMultiDimensionalStructs.Errs[1][1].Name", "TestMultiDimensionalStructs.Errs[1][1].Name", "Name", "Name", "required")
3200 AssertError(t, errs, "TestMultiDimensionalStructs.Errs[1][2].Name", "TestMultiDimensionalStructs.Errs[1][2].Name", "Name", "Name", "required")
3201
3202 type TestMultiDimensionalStructsPtr2 struct {
3203 Errs [][]*Inner `validate:"gt=0,dive,dive,required"`
3204 }
3205
3206 var errStructPtr2Array [][]*Inner
3207
3208 errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, {""}})
3209 errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, {""}})
3210 errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, nil})
3211
3212 tmsp2 := &TestMultiDimensionalStructsPtr2{
3213 Errs: errStructPtr2Array,
3214 }
3215
3216 errs = validate.Struct(tmsp2)
3217 NotEqual(t, errs, nil)
3218 Equal(t, len(errs.(ValidationErrors)), 6)
3219 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[0][1].Name", "TestMultiDimensionalStructsPtr2.Errs[0][1].Name", "Name", "Name", "required")
3220 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[0][2].Name", "TestMultiDimensionalStructsPtr2.Errs[0][2].Name", "Name", "Name", "required")
3221 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[1][1].Name", "TestMultiDimensionalStructsPtr2.Errs[1][1].Name", "Name", "Name", "required")
3222 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[1][2].Name", "TestMultiDimensionalStructsPtr2.Errs[1][2].Name", "Name", "Name", "required")
3223 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[2][1].Name", "TestMultiDimensionalStructsPtr2.Errs[2][1].Name", "Name", "Name", "required")
3224 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[2][2]", "TestMultiDimensionalStructsPtr2.Errs[2][2]", "Errs[2][2]", "Errs[2][2]", "required")
3225
3226 m := map[int]interface{}{0: "ok", 3: "", 4: "ok"}
3227
3228 errs = validate.Var(m, "len=3,dive,len=2")
3229 NotEqual(t, errs, nil)
3230 Equal(t, len(errs.(ValidationErrors)), 1)
3231 AssertError(t, errs, "[3]", "[3]", "[3]", "[3]", "len")
3232
3233 errs = validate.Var(m, "len=2,dive,required")
3234 NotEqual(t, errs, nil)
3235 Equal(t, len(errs.(ValidationErrors)), 1)
3236 AssertError(t, errs, "", "", "", "", "len")
3237
3238 arr := []interface{}{"ok", "", "ok"}
3239
3240 errs = validate.Var(arr, "len=3,dive,len=2")
3241 NotEqual(t, errs, nil)
3242 Equal(t, len(errs.(ValidationErrors)), 1)
3243 AssertError(t, errs, "[1]", "[1]", "[1]", "[1]", "len")
3244
3245 errs = validate.Var(arr, "len=2,dive,required")
3246 NotEqual(t, errs, nil)
3247 Equal(t, len(errs.(ValidationErrors)), 1)
3248 AssertError(t, errs, "", "", "", "", "len")
3249
3250 type MyStruct struct {
3251 A, B string
3252 C interface{}
3253 }
3254
3255 var a MyStruct
3256
3257 a.A = "value"
3258 a.C = "nu"
3259
3260 errs = validate.Struct(a)
3261 Equal(t, errs, nil)
3262 }
3263
3264 func TestMapDiveValidation(t *testing.T) {
3265 validate := New()
3266
3267 n := map[int]interface{}{0: nil}
3268 errs := validate.Var(n, "omitempty,required")
3269 Equal(t, errs, nil)
3270
3271 m := map[int]string{0: "ok", 3: "", 4: "ok"}
3272
3273 errs = validate.Var(m, "len=3,dive,required")
3274 NotEqual(t, errs, nil)
3275 Equal(t, len(errs.(ValidationErrors)), 1)
3276 AssertError(t, errs, "[3]", "[3]", "[3]", "[3]", "required")
3277
3278 errs = validate.Var(m, "len=2,dive,required")
3279 NotEqual(t, errs, nil)
3280 Equal(t, len(errs.(ValidationErrors)), 1)
3281 AssertError(t, errs, "", "", "", "", "len")
3282
3283 type Inner struct {
3284 Name string `validate:"required"`
3285 }
3286
3287 type TestMapStruct struct {
3288 Errs map[int]Inner `validate:"gt=0,dive"`
3289 }
3290
3291 mi := map[int]Inner{0: {"ok"}, 3: {""}, 4: {"ok"}}
3292
3293 ms := &TestMapStruct{
3294 Errs: mi,
3295 }
3296
3297 errs = validate.Struct(ms)
3298 NotEqual(t, errs, nil)
3299 Equal(t, len(errs.(ValidationErrors)), 1)
3300 AssertError(t, errs, "TestMapStruct.Errs[3].Name", "TestMapStruct.Errs[3].Name", "Name", "Name", "required")
3301
3302
3303 s := fmt.Sprint(errs.Error())
3304 NotEqual(t, s, "")
3305
3306 type TestMapInterface struct {
3307 Errs map[int]interface{} `validate:"dive"`
3308 }
3309
3310 mit := map[int]interface{}{0: Inner{"ok"}, 1: Inner{""}, 3: nil, 5: "string", 6: 33}
3311
3312 msi := &TestMapInterface{
3313 Errs: mit,
3314 }
3315
3316 errs = validate.Struct(msi)
3317 NotEqual(t, errs, nil)
3318 Equal(t, len(errs.(ValidationErrors)), 1)
3319 AssertError(t, errs, "TestMapInterface.Errs[1].Name", "TestMapInterface.Errs[1].Name", "Name", "Name", "required")
3320
3321 type TestMapTimeStruct struct {
3322 Errs map[int]*time.Time `validate:"gt=0,dive,required"`
3323 }
3324
3325 t1 := time.Now().UTC()
3326
3327 mta := map[int]*time.Time{0: &t1, 3: nil, 4: nil}
3328
3329 mt := &TestMapTimeStruct{
3330 Errs: mta,
3331 }
3332
3333 errs = validate.Struct(mt)
3334 NotEqual(t, errs, nil)
3335 Equal(t, len(errs.(ValidationErrors)), 2)
3336 AssertError(t, errs, "TestMapTimeStruct.Errs[3]", "TestMapTimeStruct.Errs[3]", "Errs[3]", "Errs[3]", "required")
3337 AssertError(t, errs, "TestMapTimeStruct.Errs[4]", "TestMapTimeStruct.Errs[4]", "Errs[4]", "Errs[4]", "required")
3338
3339 type TestMapStructPtr struct {
3340 Errs map[int]*Inner `validate:"gt=0,dive,required"`
3341 }
3342
3343 mip := map[int]*Inner{0: {"ok"}, 3: nil, 4: {"ok"}}
3344
3345 msp := &TestMapStructPtr{
3346 Errs: mip,
3347 }
3348
3349 errs = validate.Struct(msp)
3350 NotEqual(t, errs, nil)
3351 Equal(t, len(errs.(ValidationErrors)), 1)
3352 AssertError(t, errs, "TestMapStructPtr.Errs[3]", "TestMapStructPtr.Errs[3]", "Errs[3]", "Errs[3]", "required")
3353
3354 type TestMapStructPtr2 struct {
3355 Errs map[int]*Inner `validate:"gt=0,dive,omitempty,required"`
3356 }
3357
3358 mip2 := map[int]*Inner{0: {"ok"}, 3: nil, 4: {"ok"}}
3359
3360 msp2 := &TestMapStructPtr2{
3361 Errs: mip2,
3362 }
3363
3364 errs = validate.Struct(msp2)
3365 Equal(t, errs, nil)
3366
3367 v2 := New()
3368 v2.RegisterTagNameFunc(func(fld reflect.StructField) string {
3369 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
3370
3371 if name == "-" {
3372 return ""
3373 }
3374
3375 return name
3376 })
3377
3378 type MapDiveJSONTest struct {
3379 Map map[string]string `validate:"required,gte=1,dive,gte=1" json:"MyName"`
3380 }
3381
3382 mdjt := &MapDiveJSONTest{
3383 Map: map[string]string{
3384 "Key1": "Value1",
3385 "Key2": "",
3386 },
3387 }
3388
3389 err := v2.Struct(mdjt)
3390 NotEqual(t, err, nil)
3391
3392 errs = err.(ValidationErrors)
3393 fe := getError(errs, "MapDiveJSONTest.MyName[Key2]", "MapDiveJSONTest.Map[Key2]")
3394 NotEqual(t, fe, nil)
3395 Equal(t, fe.Tag(), "gte")
3396 Equal(t, fe.ActualTag(), "gte")
3397 Equal(t, fe.Field(), "MyName[Key2]")
3398 Equal(t, fe.StructField(), "Map[Key2]")
3399 }
3400
3401 func TestArrayDiveValidation(t *testing.T) {
3402 validate := New()
3403
3404 arr := []string{"ok", "", "ok"}
3405
3406 errs := validate.Var(arr, "len=3,dive,required")
3407 NotEqual(t, errs, nil)
3408 Equal(t, len(errs.(ValidationErrors)), 1)
3409 AssertError(t, errs, "[1]", "[1]", "[1]", "[1]", "required")
3410
3411 errs = validate.Var(arr, "len=2,dive,required")
3412 NotEqual(t, errs, nil)
3413 Equal(t, len(errs.(ValidationErrors)), 1)
3414 AssertError(t, errs, "", "", "", "", "len")
3415
3416 type BadDive struct {
3417 Name string `validate:"dive"`
3418 }
3419
3420 bd := &BadDive{
3421 Name: "TEST",
3422 }
3423
3424 PanicMatches(t, func() { _ = validate.Struct(bd) }, "dive error! can't dive on a non slice or map")
3425
3426 type Test struct {
3427 Errs []string `validate:"gt=0,dive,required"`
3428 }
3429
3430 test := &Test{
3431 Errs: []string{"ok", "", "ok"},
3432 }
3433
3434 errs = validate.Struct(test)
3435 NotEqual(t, errs, nil)
3436 Equal(t, len(errs.(ValidationErrors)), 1)
3437 AssertError(t, errs, "Test.Errs[1]", "Test.Errs[1]", "Errs[1]", "Errs[1]", "required")
3438
3439 test = &Test{
3440 Errs: []string{"ok", "ok", ""},
3441 }
3442
3443 errs = validate.Struct(test)
3444 NotEqual(t, errs, nil)
3445 Equal(t, len(errs.(ValidationErrors)), 1)
3446 AssertError(t, errs, "Test.Errs[2]", "Test.Errs[2]", "Errs[2]", "Errs[2]", "required")
3447
3448 type TestMultiDimensional struct {
3449 Errs [][]string `validate:"gt=0,dive,dive,required"`
3450 }
3451
3452 var errArray [][]string
3453
3454 errArray = append(errArray, []string{"ok", "", ""})
3455 errArray = append(errArray, []string{"ok", "", ""})
3456
3457 tm := &TestMultiDimensional{
3458 Errs: errArray,
3459 }
3460
3461 errs = validate.Struct(tm)
3462 NotEqual(t, errs, nil)
3463 Equal(t, len(errs.(ValidationErrors)), 4)
3464 AssertError(t, errs, "TestMultiDimensional.Errs[0][1]", "TestMultiDimensional.Errs[0][1]", "Errs[0][1]", "Errs[0][1]", "required")
3465 AssertError(t, errs, "TestMultiDimensional.Errs[0][2]", "TestMultiDimensional.Errs[0][2]", "Errs[0][2]", "Errs[0][2]", "required")
3466 AssertError(t, errs, "TestMultiDimensional.Errs[1][1]", "TestMultiDimensional.Errs[1][1]", "Errs[1][1]", "Errs[1][1]", "required")
3467 AssertError(t, errs, "TestMultiDimensional.Errs[1][2]", "TestMultiDimensional.Errs[1][2]", "Errs[1][2]", "Errs[1][2]", "required")
3468
3469 type Inner struct {
3470 Name string `validate:"required"`
3471 }
3472
3473 type TestMultiDimensionalStructs struct {
3474 Errs [][]Inner `validate:"gt=0,dive,dive"`
3475 }
3476
3477 var errStructArray [][]Inner
3478
3479 errStructArray = append(errStructArray, []Inner{{"ok"}, {""}, {""}})
3480 errStructArray = append(errStructArray, []Inner{{"ok"}, {""}, {""}})
3481
3482 tms := &TestMultiDimensionalStructs{
3483 Errs: errStructArray,
3484 }
3485
3486 errs = validate.Struct(tms)
3487 NotEqual(t, errs, nil)
3488 Equal(t, len(errs.(ValidationErrors)), 4)
3489 AssertError(t, errs, "TestMultiDimensionalStructs.Errs[0][1].Name", "TestMultiDimensionalStructs.Errs[0][1].Name", "Name", "Name", "required")
3490 AssertError(t, errs, "TestMultiDimensionalStructs.Errs[0][2].Name", "TestMultiDimensionalStructs.Errs[0][2].Name", "Name", "Name", "required")
3491 AssertError(t, errs, "TestMultiDimensionalStructs.Errs[1][1].Name", "TestMultiDimensionalStructs.Errs[1][1].Name", "Name", "Name", "required")
3492 AssertError(t, errs, "TestMultiDimensionalStructs.Errs[1][2].Name", "TestMultiDimensionalStructs.Errs[1][2].Name", "Name", "Name", "required")
3493
3494 type TestMultiDimensionalStructsPtr struct {
3495 Errs [][]*Inner `validate:"gt=0,dive,dive"`
3496 }
3497
3498 var errStructPtrArray [][]*Inner
3499
3500 errStructPtrArray = append(errStructPtrArray, []*Inner{{"ok"}, {""}, {""}})
3501 errStructPtrArray = append(errStructPtrArray, []*Inner{{"ok"}, {""}, {""}})
3502 errStructPtrArray = append(errStructPtrArray, []*Inner{{"ok"}, {""}, nil})
3503
3504 tmsp := &TestMultiDimensionalStructsPtr{
3505 Errs: errStructPtrArray,
3506 }
3507
3508 errs = validate.Struct(tmsp)
3509 NotEqual(t, errs, nil)
3510 Equal(t, len(errs.(ValidationErrors)), 5)
3511 AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[0][1].Name", "TestMultiDimensionalStructsPtr.Errs[0][1].Name", "Name", "Name", "required")
3512 AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[0][2].Name", "TestMultiDimensionalStructsPtr.Errs[0][2].Name", "Name", "Name", "required")
3513 AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[1][1].Name", "TestMultiDimensionalStructsPtr.Errs[1][1].Name", "Name", "Name", "required")
3514 AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[1][2].Name", "TestMultiDimensionalStructsPtr.Errs[1][2].Name", "Name", "Name", "required")
3515 AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[2][1].Name", "TestMultiDimensionalStructsPtr.Errs[2][1].Name", "Name", "Name", "required")
3516
3517
3518 s := fmt.Sprint(errs.Error())
3519 NotEqual(t, s, "")
3520
3521 type TestMultiDimensionalStructsPtr2 struct {
3522 Errs [][]*Inner `validate:"gt=0,dive,dive,required"`
3523 }
3524
3525 var errStructPtr2Array [][]*Inner
3526
3527 errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, {""}})
3528 errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, {""}})
3529 errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, nil})
3530
3531 tmsp2 := &TestMultiDimensionalStructsPtr2{
3532 Errs: errStructPtr2Array,
3533 }
3534
3535 errs = validate.Struct(tmsp2)
3536 NotEqual(t, errs, nil)
3537 Equal(t, len(errs.(ValidationErrors)), 6)
3538 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[0][1].Name", "TestMultiDimensionalStructsPtr2.Errs[0][1].Name", "Name", "Name", "required")
3539 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[0][2].Name", "TestMultiDimensionalStructsPtr2.Errs[0][2].Name", "Name", "Name", "required")
3540 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[1][1].Name", "TestMultiDimensionalStructsPtr2.Errs[1][1].Name", "Name", "Name", "required")
3541 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[1][2].Name", "TestMultiDimensionalStructsPtr2.Errs[1][2].Name", "Name", "Name", "required")
3542 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[2][1].Name", "TestMultiDimensionalStructsPtr2.Errs[2][1].Name", "Name", "Name", "required")
3543 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[2][2]", "TestMultiDimensionalStructsPtr2.Errs[2][2]", "Errs[2][2]", "Errs[2][2]", "required")
3544
3545 type TestMultiDimensionalStructsPtr3 struct {
3546 Errs [][]*Inner `validate:"gt=0,dive,dive,omitempty"`
3547 }
3548
3549 var errStructPtr3Array [][]*Inner
3550
3551 errStructPtr3Array = append(errStructPtr3Array, []*Inner{{"ok"}, {""}, {""}})
3552 errStructPtr3Array = append(errStructPtr3Array, []*Inner{{"ok"}, {""}, {""}})
3553 errStructPtr3Array = append(errStructPtr3Array, []*Inner{{"ok"}, {""}, nil})
3554
3555 tmsp3 := &TestMultiDimensionalStructsPtr3{
3556 Errs: errStructPtr3Array,
3557 }
3558
3559 errs = validate.Struct(tmsp3)
3560 NotEqual(t, errs, nil)
3561 Equal(t, len(errs.(ValidationErrors)), 5)
3562 AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[0][1].Name", "TestMultiDimensionalStructsPtr3.Errs[0][1].Name", "Name", "Name", "required")
3563 AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[0][2].Name", "TestMultiDimensionalStructsPtr3.Errs[0][2].Name", "Name", "Name", "required")
3564 AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[1][1].Name", "TestMultiDimensionalStructsPtr3.Errs[1][1].Name", "Name", "Name", "required")
3565 AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[1][2].Name", "TestMultiDimensionalStructsPtr3.Errs[1][2].Name", "Name", "Name", "required")
3566 AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[2][1].Name", "TestMultiDimensionalStructsPtr3.Errs[2][1].Name", "Name", "Name", "required")
3567
3568 type TestMultiDimensionalTimeTime struct {
3569 Errs [][]*time.Time `validate:"gt=0,dive,dive,required"`
3570 }
3571
3572 var errTimePtr3Array [][]*time.Time
3573
3574 t1 := time.Now().UTC()
3575 t2 := time.Now().UTC()
3576 t3 := time.Now().UTC().Add(time.Hour * 24)
3577
3578 errTimePtr3Array = append(errTimePtr3Array, []*time.Time{&t1, &t2, &t3})
3579 errTimePtr3Array = append(errTimePtr3Array, []*time.Time{&t1, &t2, nil})
3580 errTimePtr3Array = append(errTimePtr3Array, []*time.Time{&t1, nil, nil})
3581
3582 tmtp3 := &TestMultiDimensionalTimeTime{
3583 Errs: errTimePtr3Array,
3584 }
3585
3586 errs = validate.Struct(tmtp3)
3587 NotEqual(t, errs, nil)
3588 Equal(t, len(errs.(ValidationErrors)), 3)
3589 AssertError(t, errs, "TestMultiDimensionalTimeTime.Errs[1][2]", "TestMultiDimensionalTimeTime.Errs[1][2]", "Errs[1][2]", "Errs[1][2]", "required")
3590 AssertError(t, errs, "TestMultiDimensionalTimeTime.Errs[2][1]", "TestMultiDimensionalTimeTime.Errs[2][1]", "Errs[2][1]", "Errs[2][1]", "required")
3591 AssertError(t, errs, "TestMultiDimensionalTimeTime.Errs[2][2]", "TestMultiDimensionalTimeTime.Errs[2][2]", "Errs[2][2]", "Errs[2][2]", "required")
3592
3593 type TestMultiDimensionalTimeTime2 struct {
3594 Errs [][]*time.Time `validate:"gt=0,dive,dive,required"`
3595 }
3596
3597 var errTimeArray [][]*time.Time
3598
3599 t1 = time.Now().UTC()
3600 t2 = time.Now().UTC()
3601 t3 = time.Now().UTC().Add(time.Hour * 24)
3602
3603 errTimeArray = append(errTimeArray, []*time.Time{&t1, &t2, &t3})
3604 errTimeArray = append(errTimeArray, []*time.Time{&t1, &t2, nil})
3605 errTimeArray = append(errTimeArray, []*time.Time{&t1, nil, nil})
3606
3607 tmtp := &TestMultiDimensionalTimeTime2{
3608 Errs: errTimeArray,
3609 }
3610
3611 errs = validate.Struct(tmtp)
3612 NotEqual(t, errs, nil)
3613 Equal(t, len(errs.(ValidationErrors)), 3)
3614 AssertError(t, errs, "TestMultiDimensionalTimeTime2.Errs[1][2]", "TestMultiDimensionalTimeTime2.Errs[1][2]", "Errs[1][2]", "Errs[1][2]", "required")
3615 AssertError(t, errs, "TestMultiDimensionalTimeTime2.Errs[2][1]", "TestMultiDimensionalTimeTime2.Errs[2][1]", "Errs[2][1]", "Errs[2][1]", "required")
3616 AssertError(t, errs, "TestMultiDimensionalTimeTime2.Errs[2][2]", "TestMultiDimensionalTimeTime2.Errs[2][2]", "Errs[2][2]", "Errs[2][2]", "required")
3617 }
3618
3619 func TestNilStructPointerValidation(t *testing.T) {
3620 type Inner struct {
3621 Data string
3622 }
3623
3624 type Outer struct {
3625 Inner *Inner `validate:"omitempty"`
3626 }
3627
3628 inner := &Inner{
3629 Data: "test",
3630 }
3631
3632 outer := &Outer{
3633 Inner: inner,
3634 }
3635
3636 validate := New()
3637 errs := validate.Struct(outer)
3638 Equal(t, errs, nil)
3639
3640 outer = &Outer{
3641 Inner: nil,
3642 }
3643
3644 errs = validate.Struct(outer)
3645 Equal(t, errs, nil)
3646
3647 type Inner2 struct {
3648 Data string
3649 }
3650
3651 type Outer2 struct {
3652 Inner2 *Inner2 `validate:"required"`
3653 }
3654
3655 inner2 := &Inner2{
3656 Data: "test",
3657 }
3658
3659 outer2 := &Outer2{
3660 Inner2: inner2,
3661 }
3662
3663 errs = validate.Struct(outer2)
3664 Equal(t, errs, nil)
3665
3666 outer2 = &Outer2{
3667 Inner2: nil,
3668 }
3669
3670 errs = validate.Struct(outer2)
3671 NotEqual(t, errs, nil)
3672 AssertError(t, errs, "Outer2.Inner2", "Outer2.Inner2", "Inner2", "Inner2", "required")
3673
3674 type Inner3 struct {
3675 Data string
3676 }
3677
3678 type Outer3 struct {
3679 Inner3 *Inner3
3680 }
3681
3682 inner3 := &Inner3{
3683 Data: "test",
3684 }
3685
3686 outer3 := &Outer3{
3687 Inner3: inner3,
3688 }
3689
3690 errs = validate.Struct(outer3)
3691 Equal(t, errs, nil)
3692
3693 type Inner4 struct {
3694 Data string
3695 }
3696
3697 type Outer4 struct {
3698 Inner4 *Inner4 `validate:"-"`
3699 }
3700
3701 inner4 := &Inner4{
3702 Data: "test",
3703 }
3704
3705 outer4 := &Outer4{
3706 Inner4: inner4,
3707 }
3708
3709 errs = validate.Struct(outer4)
3710 Equal(t, errs, nil)
3711 }
3712
3713 func TestSSNValidation(t *testing.T) {
3714 tests := []struct {
3715 param string
3716 expected bool
3717 }{
3718 {"", false},
3719 {"00-90-8787", false},
3720 {"66690-76", false},
3721 {"191 60 2869", true},
3722 {"191-60-2869", true},
3723 }
3724
3725 validate := New()
3726
3727 for i, test := range tests {
3728
3729 errs := validate.Var(test.param, "ssn")
3730
3731 if test.expected {
3732 if !IsEqual(errs, nil) {
3733 t.Fatalf("Index: %d SSN failed Error: %s", i, errs)
3734 }
3735 } else {
3736 if IsEqual(errs, nil) {
3737 t.Fatalf("Index: %d SSN failed Error: %s", i, errs)
3738 } else {
3739 val := getError(errs, "", "")
3740 if val.Tag() != "ssn" {
3741 t.Fatalf("Index: %d Latitude failed Error: %s", i, errs)
3742 }
3743 }
3744 }
3745 }
3746 }
3747
3748 func TestLongitudeValidation(t *testing.T) {
3749 tests := []struct {
3750 param interface{}
3751 expected bool
3752 }{
3753 {"", false},
3754 {"-180.000", true},
3755 {"180.1", false},
3756 {"+73.234", true},
3757 {"+382.3811", false},
3758 {"23.11111111", true},
3759 {uint(180), true},
3760 {float32(-180.0), true},
3761 {-180, true},
3762 {180.1, false},
3763 }
3764
3765 validate := New()
3766
3767 for i, test := range tests {
3768
3769 errs := validate.Var(test.param, "longitude")
3770
3771 if test.expected {
3772 if !IsEqual(errs, nil) {
3773 t.Fatalf("Index: %d Longitude failed Error: %s", i, errs)
3774 }
3775 } else {
3776 if IsEqual(errs, nil) {
3777 t.Fatalf("Index: %d Longitude failed Error: %s", i, errs)
3778 } else {
3779 val := getError(errs, "", "")
3780 if val.Tag() != "longitude" {
3781 t.Fatalf("Index: %d Longitude failed Error: %s", i, errs)
3782 }
3783 }
3784 }
3785 }
3786
3787 PanicMatches(t, func() { _ = validate.Var(true, "longitude") }, "Bad field type bool")
3788 }
3789
3790 func TestLatitudeValidation(t *testing.T) {
3791 tests := []struct {
3792 param interface{}
3793 expected bool
3794 }{
3795 {"", false},
3796 {"-90.000", true},
3797 {"+90", true},
3798 {"47.1231231", true},
3799 {"+99.9", false},
3800 {"108", false},
3801 {uint(90), true},
3802 {float32(-90.0), true},
3803 {-90, true},
3804 {90.1, false},
3805 }
3806
3807 validate := New()
3808
3809 for i, test := range tests {
3810
3811 errs := validate.Var(test.param, "latitude")
3812
3813 if test.expected {
3814 if !IsEqual(errs, nil) {
3815 t.Fatalf("Index: %d Latitude failed Error: %s", i, errs)
3816 }
3817 } else {
3818 if IsEqual(errs, nil) {
3819 t.Fatalf("Index: %d Latitude failed Error: %s", i, errs)
3820 } else {
3821 val := getError(errs, "", "")
3822 if val.Tag() != "latitude" {
3823 t.Fatalf("Index: %d Latitude failed Error: %s", i, errs)
3824 }
3825 }
3826 }
3827 }
3828
3829 PanicMatches(t, func() { _ = validate.Var(true, "latitude") }, "Bad field type bool")
3830 }
3831
3832 func TestDataURIValidation(t *testing.T) {
3833 tests := []struct {
3834 param string
3835 expected bool
3836 }{
3837 {"data:image/png;base64,TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4=", true},
3838 {"data:text/plain;base64,Vml2YW11cyBmZXJtZW50dW0gc2VtcGVyIHBvcnRhLg==", true},
3839 {"image/gif;base64,U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", false},
3840 {
3841 "data:image/gif;base64,MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuMPNS1Ufof9EW/M98FNw" +
3842 "UAKrwflsqVxaxQjBQnHQmiI7Vac40t8x7pIb8gLGV6wL7sBTJiPovJ0V7y7oc0Ye" +
3843 "rhKh0Rm4skP2z/jHwwZICgGzBvA0rH8xlhUiTvcwDCJ0kc+fh35hNt8srZQM4619" +
3844 "FTgB66Xmp4EtVyhpQV+t02g6NzK72oZI0vnAvqhpkxLeLiMCyrI416wHm5Tkukhx" +
3845 "QmcL2a6hNOyu0ixX/x2kSFXApEnVrJ+/IxGyfyw8kf4N2IZpW5nEP847lpfj0SZZ" +
3846 "Fwrd1mnfnDbYohX2zRptLy2ZUn06Qo9pkG5ntvFEPo9bfZeULtjYzIl6K8gJ2uGZ" + "HQIDAQAB", true,
3847 },
3848 {"data:image/png;base64,12345", false},
3849 {"", false},
3850 {"data:text,:;base85,U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", false},
3851 {"data:image/jpeg;key=value;base64,UEsDBBQAAAAI", true},
3852 {"data:image/jpeg;key=value,UEsDBBQAAAAI", true},
3853 {"data:;base64;sdfgsdfgsdfasdfa=s,UEsDBBQAAAAI", true},
3854 {"data:,UEsDBBQAAAAI", true},
3855 }
3856
3857 validate := New()
3858
3859 for i, test := range tests {
3860 errs := validate.Var(test.param, "datauri")
3861
3862 if test.expected {
3863 if !IsEqual(errs, nil) {
3864 t.Fatalf("Index: %d DataURI failed Error: %s", i, errs)
3865 }
3866 } else {
3867 if IsEqual(errs, nil) {
3868 t.Fatalf("Index: %d DataURI failed Error: %s", i, errs)
3869 } else {
3870 val := getError(errs, "", "")
3871 if val.Tag() != "datauri" {
3872 t.Fatalf("Index: %d DataURI failed Error: %s", i, errs)
3873 }
3874 }
3875 }
3876 }
3877 }
3878
3879 func TestMultibyteValidation(t *testing.T) {
3880 tests := []struct {
3881 param string
3882 expected bool
3883 }{
3884 {"", true},
3885 {"abc", false},
3886 {"123", false},
3887 {"<>@;.-=", false},
3888 {"ひらがな・カタカナ、.漢字", true},
3889 {"あいうえお foobar", true},
3890 {"test@example.com", true},
3891 {"test@example.com", true},
3892 {"1234abcDExyz", true},
3893 {"カタカナ", true},
3894 }
3895
3896 validate := New()
3897
3898 for i, test := range tests {
3899
3900 errs := validate.Var(test.param, "multibyte")
3901
3902 if test.expected {
3903 if !IsEqual(errs, nil) {
3904 t.Fatalf("Index: %d Multibyte failed Error: %s", i, errs)
3905 }
3906 } else {
3907 if IsEqual(errs, nil) {
3908 t.Fatalf("Index: %d Multibyte failed Error: %s", i, errs)
3909 } else {
3910 val := getError(errs, "", "")
3911 if val.Tag() != "multibyte" {
3912 t.Fatalf("Index: %d Multibyte failed Error: %s", i, errs)
3913 }
3914 }
3915 }
3916 }
3917 }
3918
3919 func TestPrintableASCIIValidation(t *testing.T) {
3920 tests := []struct {
3921 param string
3922 expected bool
3923 }{
3924 {"", true},
3925 {"foobar", false},
3926 {"xyz098", false},
3927 {"123456", false},
3928 {"カタカナ", false},
3929 {"foobar", true},
3930 {"0987654321", true},
3931 {"test@example.com", true},
3932 {"1234abcDEF", true},
3933 {"newline\n", false},
3934 {"\x19test\x7F", false},
3935 }
3936
3937 validate := New()
3938
3939 for i, test := range tests {
3940
3941 errs := validate.Var(test.param, "printascii")
3942
3943 if test.expected {
3944 if !IsEqual(errs, nil) {
3945 t.Fatalf("Index: %d Printable ASCII failed Error: %s", i, errs)
3946 }
3947 } else {
3948 if IsEqual(errs, nil) {
3949 t.Fatalf("Index: %d Printable ASCII failed Error: %s", i, errs)
3950 } else {
3951 val := getError(errs, "", "")
3952 if val.Tag() != "printascii" {
3953 t.Fatalf("Index: %d Printable ASCII failed Error: %s", i, errs)
3954 }
3955 }
3956 }
3957 }
3958 }
3959
3960 func TestASCIIValidation(t *testing.T) {
3961 tests := []struct {
3962 param string
3963 expected bool
3964 }{
3965 {"", true},
3966 {"foobar", false},
3967 {"xyz098", false},
3968 {"123456", false},
3969 {"カタカナ", false},
3970 {"foobar", true},
3971 {"0987654321", true},
3972 {"test@example.com", true},
3973 {"1234abcDEF", true},
3974 {"", true},
3975 }
3976
3977 validate := New()
3978
3979 for i, test := range tests {
3980
3981 errs := validate.Var(test.param, "ascii")
3982
3983 if test.expected {
3984 if !IsEqual(errs, nil) {
3985 t.Fatalf("Index: %d ASCII failed Error: %s", i, errs)
3986 }
3987 } else {
3988 if IsEqual(errs, nil) {
3989 t.Fatalf("Index: %d ASCII failed Error: %s", i, errs)
3990 } else {
3991 val := getError(errs, "", "")
3992 if val.Tag() != "ascii" {
3993 t.Fatalf("Index: %d ASCII failed Error: %s", i, errs)
3994 }
3995 }
3996 }
3997 }
3998 }
3999
4000 func TestUUID5Validation(t *testing.T) {
4001 tests := []struct {
4002 param string
4003 expected bool
4004 }{
4005
4006 {"", false},
4007 {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
4008 {"9c858901-8a57-4791-81fe-4c455b099bc9", false},
4009 {"a987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
4010 {"987fbc97-4bed-5078-af07-9141ba07c9f3", true},
4011 {"987fbc97-4bed-5078-9f07-9141ba07c9f3", true},
4012 }
4013
4014 validate := New()
4015
4016 for i, test := range tests {
4017
4018 errs := validate.Var(test.param, "uuid5")
4019
4020 if test.expected {
4021 if !IsEqual(errs, nil) {
4022 t.Fatalf("Index: %d UUID5 failed Error: %s", i, errs)
4023 }
4024 } else {
4025 if IsEqual(errs, nil) {
4026 t.Fatalf("Index: %d UUID5 failed Error: %s", i, errs)
4027 } else {
4028 val := getError(errs, "", "")
4029 if val.Tag() != "uuid5" {
4030 t.Fatalf("Index: %d UUID5 failed Error: %s", i, errs)
4031 }
4032 }
4033 }
4034 }
4035 }
4036
4037 func TestUUID4Validation(t *testing.T) {
4038 tests := []struct {
4039 param string
4040 expected bool
4041 }{
4042 {"", false},
4043 {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
4044 {"a987fbc9-4bed-5078-af07-9141ba07c9f3", false},
4045 {"934859", false},
4046 {"57b73598-8764-4ad0-a76a-679bb6640eb1", true},
4047 {"625e63f3-58f5-40b7-83a1-a72ad31acffb", true},
4048 }
4049
4050 validate := New()
4051
4052 for i, test := range tests {
4053
4054 errs := validate.Var(test.param, "uuid4")
4055
4056 if test.expected {
4057 if !IsEqual(errs, nil) {
4058 t.Fatalf("Index: %d UUID4 failed Error: %s", i, errs)
4059 }
4060 } else {
4061 if IsEqual(errs, nil) {
4062 t.Fatalf("Index: %d UUID4 failed Error: %s", i, errs)
4063 } else {
4064 val := getError(errs, "", "")
4065 if val.Tag() != "uuid4" {
4066 t.Fatalf("Index: %d UUID4 failed Error: %s", i, errs)
4067 }
4068 }
4069 }
4070 }
4071 }
4072
4073 func TestUUID3Validation(t *testing.T) {
4074 tests := []struct {
4075 param string
4076 expected bool
4077 }{
4078 {"", false},
4079 {"412452646", false},
4080 {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
4081 {"a987fbc9-4bed-4078-8f07-9141ba07c9f3", false},
4082 {"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true},
4083 }
4084
4085 validate := New()
4086
4087 for i, test := range tests {
4088
4089 errs := validate.Var(test.param, "uuid3")
4090
4091 if test.expected {
4092 if !IsEqual(errs, nil) {
4093 t.Fatalf("Index: %d UUID3 failed Error: %s", i, errs)
4094 }
4095 } else {
4096 if IsEqual(errs, nil) {
4097 t.Fatalf("Index: %d UUID3 failed Error: %s", i, errs)
4098 } else {
4099 val := getError(errs, "", "")
4100 if val.Tag() != "uuid3" {
4101 t.Fatalf("Index: %d UUID3 failed Error: %s", i, errs)
4102 }
4103 }
4104 }
4105 }
4106 }
4107
4108 type uuidTestType struct {
4109 val string
4110 }
4111
4112 func (u uuidTestType) String() string {
4113 return u.val
4114 }
4115
4116 type uuidAlias string
4117
4118 func (u uuidAlias) String() string {
4119 return "This is a UUID " + string(u)
4120 }
4121
4122 var _ fmt.Stringer = uuidTestType{}
4123 var _ fmt.Stringer = uuidAlias("")
4124
4125 func TestUUIDValidation(t *testing.T) {
4126 tests := []struct {
4127 param string
4128 expected bool
4129 }{
4130 {"", false},
4131 {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
4132 {"a987fbc9-4bed-3078-cf07-9141ba07c9f3xxx", false},
4133 {"a987fbc94bed3078cf079141ba07c9f3", false},
4134 {"934859", false},
4135 {"987fbc9-4bed-3078-cf07a-9141ba07c9f3", false},
4136 {"aaaaaaaa-1111-1111-aaag-111111111111", false},
4137 {"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true},
4138 }
4139
4140 validate := New()
4141
4142 for i, test := range tests {
4143
4144 errs := validate.Var(test.param, "uuid")
4145
4146 if test.expected {
4147 if !IsEqual(errs, nil) {
4148 t.Fatalf("Index: %d UUID failed Error: %s", i, errs)
4149 }
4150 } else {
4151 if IsEqual(errs, nil) {
4152 t.Fatalf("Index: %d UUID failed Error: %s", i, errs)
4153 } else {
4154 val := getError(errs, "", "")
4155 if val.Tag() != "uuid" {
4156 t.Fatalf("Index: %d UUID failed Error: %s", i, errs)
4157 }
4158 }
4159 }
4160 }
4161
4162
4163 structWithValidUUID := struct {
4164 UUID uuidTestType `validate:"uuid"`
4165 }{
4166 UUID: uuidTestType{val: "a987fbc9-4bed-3078-cf07-9141ba07c9f3"},
4167 }
4168 structWithInvalidUUID := struct {
4169 UUID uuidTestType `validate:"uuid"`
4170 }{
4171 UUID: uuidTestType{val: "934859"},
4172 }
4173
4174 if err := validate.Struct(structWithValidUUID); err != nil {
4175 t.Fatalf("UUID failed Error: %s", err)
4176 }
4177 if err := validate.Struct(structWithInvalidUUID); err == nil {
4178 t.Fatal("UUID failed Error expected but received nil")
4179 }
4180
4181
4182 alias := uuidAlias("a987fbc9-4bed-3078-cf07-9141ba07c9f3")
4183 if err := validate.Var(alias, "uuid"); err != nil {
4184 t.Fatalf("UUID failed Error: %s", err)
4185 }
4186 }
4187
4188 func TestUUID5RFC4122Validation(t *testing.T) {
4189 tests := []struct {
4190 param string
4191 expected bool
4192 }{
4193
4194 {"", false},
4195 {"xxxa987Fbc9-4bed-3078-cf07-9141ba07c9f3", false},
4196 {"9c858901-8a57-4791-81Fe-4c455b099bc9", false},
4197 {"a987Fbc9-4bed-3078-cf07-9141ba07c9f3", false},
4198 {"987Fbc97-4bed-5078-af07-9141ba07c9f3", true},
4199 {"987Fbc97-4bed-5078-9f07-9141ba07c9f3", true},
4200 }
4201
4202 validate := New()
4203
4204 for i, test := range tests {
4205
4206 errs := validate.Var(test.param, "uuid5_rfc4122")
4207
4208 if test.expected {
4209 if !IsEqual(errs, nil) {
4210 t.Fatalf("Index: %d UUID5RFC4122 failed Error: %s", i, errs)
4211 }
4212 } else {
4213 if IsEqual(errs, nil) {
4214 t.Fatalf("Index: %d UUID5RFC4122 failed Error: %s", i, errs)
4215 } else {
4216 val := getError(errs, "", "")
4217 if val.Tag() != "uuid5_rfc4122" {
4218 t.Fatalf("Index: %d UUID5RFC4122 failed Error: %s", i, errs)
4219 }
4220 }
4221 }
4222 }
4223 }
4224
4225 func TestUUID4RFC4122Validation(t *testing.T) {
4226 tests := []struct {
4227 param string
4228 expected bool
4229 }{
4230 {"", false},
4231 {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9F3", false},
4232 {"a987fbc9-4bed-5078-af07-9141ba07c9F3", false},
4233 {"934859", false},
4234 {"57b73598-8764-4ad0-a76A-679bb6640eb1", true},
4235 {"625e63f3-58f5-40b7-83a1-a72ad31acFfb", true},
4236 }
4237
4238 validate := New()
4239
4240 for i, test := range tests {
4241
4242 errs := validate.Var(test.param, "uuid4_rfc4122")
4243
4244 if test.expected {
4245 if !IsEqual(errs, nil) {
4246 t.Fatalf("Index: %d UUID4RFC4122 failed Error: %s", i, errs)
4247 }
4248 } else {
4249 if IsEqual(errs, nil) {
4250 t.Fatalf("Index: %d UUID4RFC4122 failed Error: %s", i, errs)
4251 } else {
4252 val := getError(errs, "", "")
4253 if val.Tag() != "uuid4_rfc4122" {
4254 t.Fatalf("Index: %d UUID4RFC4122 failed Error: %s", i, errs)
4255 }
4256 }
4257 }
4258 }
4259 }
4260
4261 func TestUUID3RFC4122Validation(t *testing.T) {
4262 tests := []struct {
4263 param string
4264 expected bool
4265 }{
4266 {"", false},
4267 {"412452646", false},
4268 {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9F3", false},
4269 {"a987fbc9-4bed-4078-8f07-9141ba07c9F3", false},
4270 {"a987fbc9-4bed-3078-cf07-9141ba07c9F3", true},
4271 }
4272
4273 validate := New()
4274
4275 for i, test := range tests {
4276
4277 errs := validate.Var(test.param, "uuid3_rfc4122")
4278
4279 if test.expected {
4280 if !IsEqual(errs, nil) {
4281 t.Fatalf("Index: %d UUID3RFC4122 failed Error: %s", i, errs)
4282 }
4283 } else {
4284 if IsEqual(errs, nil) {
4285 t.Fatalf("Index: %d UUID3RFC4122 failed Error: %s", i, errs)
4286 } else {
4287 val := getError(errs, "", "")
4288 if val.Tag() != "uuid3_rfc4122" {
4289 t.Fatalf("Index: %d UUID3RFC4122 failed Error: %s", i, errs)
4290 }
4291 }
4292 }
4293 }
4294 }
4295
4296 func TestUUIDRFC4122Validation(t *testing.T) {
4297 tests := []struct {
4298 param string
4299 expected bool
4300 }{
4301 {"", false},
4302 {"xxxa987Fbc9-4bed-3078-cf07-9141ba07c9f3", false},
4303 {"a987Fbc9-4bed-3078-cf07-9141ba07c9f3xxx", false},
4304 {"a987Fbc94bed3078cf079141ba07c9f3", false},
4305 {"934859", false},
4306 {"987fbc9-4bed-3078-cf07a-9141ba07c9F3", false},
4307 {"aaaaaaaa-1111-1111-aaaG-111111111111", false},
4308 {"a987Fbc9-4bed-3078-cf07-9141ba07c9f3", true},
4309 }
4310
4311 validate := New()
4312
4313 for i, test := range tests {
4314
4315 errs := validate.Var(test.param, "uuid_rfc4122")
4316
4317 if test.expected {
4318 if !IsEqual(errs, nil) {
4319 t.Fatalf("Index: %d UUIDRFC4122 failed Error: %s", i, errs)
4320 }
4321 } else {
4322 if IsEqual(errs, nil) {
4323 t.Fatalf("Index: %d UUIDRFC4122 failed Error: %s", i, errs)
4324 } else {
4325 val := getError(errs, "", "")
4326 if val.Tag() != "uuid_rfc4122" {
4327 t.Fatalf("Index: %d UUIDRFC4122 failed Error: %s", i, errs)
4328 }
4329 }
4330 }
4331 }
4332 }
4333
4334 func TestULIDValidation(t *testing.T) {
4335 tests := []struct {
4336 param string
4337 expected bool
4338 }{
4339 {"", false},
4340 {"01BX5ZZKBKACT-V9WEVGEMMVRZ", false},
4341 {"01bx5zzkbkactav9wevgemmvrz", true},
4342 {"a987Fbc9-4bed-3078-cf07-9141ba07c9f3xxx", false},
4343 {"01BX5ZZKBKACTAV9WEVGEMMVRZABC", false},
4344 {"01BX5ZZKBKACTAV9WEVGEMMVRZABC", false},
4345 {"0IBX5ZZKBKACTAV9WEVGEMMVRZ", false},
4346 {"O1BX5ZZKBKACTAV9WEVGEMMVRZ", false},
4347 {"01BX5ZZKBKACTAVLWEVGEMMVRZ", false},
4348 {"01BX5ZZKBKACTAV9WEVGEMMVRZ", true},
4349 }
4350
4351 validate := New()
4352
4353 for i, test := range tests {
4354
4355 errs := validate.Var(test.param, "ulid")
4356
4357 if test.expected {
4358 if !IsEqual(errs, nil) {
4359 t.Fatalf("Index: %d ULID failed Error: %s", i, errs)
4360 }
4361 } else {
4362 if IsEqual(errs, nil) {
4363 t.Fatalf("Index: %d ULID failed Error: %s", i, errs)
4364 } else {
4365 val := getError(errs, "", "")
4366 if val.Tag() != "ulid" {
4367 t.Fatalf("Index: %d ULID failed Error: %s", i, errs)
4368 }
4369 }
4370 }
4371 }
4372 }
4373
4374 func TestMD4Validation(t *testing.T) {
4375 tests := []struct {
4376 param string
4377 expected bool
4378 }{
4379 {"", false},
4380 {"6f5902ac237024bdd0c176cb93063dc4", true},
4381 {"6f5902ac237024bdd0c176cb93063dc-", false},
4382 {"6f5902ac237024bdd0c176cb93063dc41", false},
4383 {"6f5902ac237024bdd0c176cb93063dcC", false},
4384 {"6f5902ac237024bdd0c176cb93063dc", false},
4385 }
4386
4387 validate := New()
4388
4389 for i, test := range tests {
4390
4391 errs := validate.Var(test.param, "md4")
4392
4393 if test.expected {
4394 if !IsEqual(errs, nil) {
4395 t.Fatalf("Index: %d MD4 failed Error: %s", i, errs)
4396 }
4397 } else {
4398 if IsEqual(errs, nil) {
4399 t.Fatalf("Index: %d MD4 failed Error: %s", i, errs)
4400 } else {
4401 val := getError(errs, "", "")
4402 if val.Tag() != "md4" {
4403 t.Fatalf("Index: %d MD4 failed Error: %s", i, errs)
4404 }
4405 }
4406 }
4407 }
4408 }
4409
4410 func TestMD5Validation(t *testing.T) {
4411 tests := []struct {
4412 param string
4413 expected bool
4414 }{
4415 {"", false},
4416 {"6f5902ac237024bdd0c176cb93063dc4", true},
4417 {"6f5902ac237024bdd0c176cb93063dc-", false},
4418 {"6f5902ac237024bdd0c176cb93063dc41", false},
4419 {"6f5902ac237024bdd0c176cb93063dcC", false},
4420 {"6f5902ac237024bdd0c176cb93063dc", false},
4421 }
4422
4423 validate := New()
4424
4425 for i, test := range tests {
4426
4427 errs := validate.Var(test.param, "md5")
4428
4429 if test.expected {
4430 if !IsEqual(errs, nil) {
4431 t.Fatalf("Index: %d MD5 failed Error: %s", i, errs)
4432 }
4433 } else {
4434 if IsEqual(errs, nil) {
4435 t.Fatalf("Index: %d MD5 failed Error: %s", i, errs)
4436 } else {
4437 val := getError(errs, "", "")
4438 if val.Tag() != "md5" {
4439 t.Fatalf("Index: %d MD5 failed Error: %s", i, errs)
4440 }
4441 }
4442 }
4443 }
4444 }
4445
4446 func TestSHA256Validation(t *testing.T) {
4447 tests := []struct {
4448 param string
4449 expected bool
4450 }{
4451 {"", false},
4452 {"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc4", true},
4453 {"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc-", false},
4454 {"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc41", false},
4455 {"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dcC", false},
4456 {"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc", false},
4457 }
4458
4459 validate := New()
4460
4461 for i, test := range tests {
4462
4463 errs := validate.Var(test.param, "sha256")
4464 if test.expected {
4465 if !IsEqual(errs, nil) {
4466 t.Fatalf("Index: %d SHA256 failed Error: %s", i, errs)
4467 }
4468 } else {
4469 if IsEqual(errs, nil) {
4470 t.Fatalf("Index: %d SHA256 failed Error: %s", i, errs)
4471 } else {
4472 val := getError(errs, "", "")
4473 if val.Tag() != "sha256" {
4474 t.Fatalf("Index: %d SHA256 failed Error: %s", i, errs)
4475 }
4476 }
4477 }
4478 }
4479 }
4480
4481 func TestSHA384Validation(t *testing.T) {
4482 tests := []struct {
4483 param string
4484 expected bool
4485 }{
4486 {"", false},
4487 {"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc4", true},
4488 {"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc-", false},
4489 {"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc41", false},
4490 {"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dcC", false},
4491 {"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc", false},
4492 }
4493
4494 validate := New()
4495
4496 for i, test := range tests {
4497
4498 errs := validate.Var(test.param, "sha384")
4499
4500 if test.expected {
4501 if !IsEqual(errs, nil) {
4502 t.Fatalf("Index: %d SHA384 failed Error: %s", i, errs)
4503 }
4504 } else {
4505 if IsEqual(errs, nil) {
4506 t.Fatalf("Index: %d SHA384 failed Error: %s", i, errs)
4507 } else {
4508 val := getError(errs, "", "")
4509 if val.Tag() != "sha384" {
4510 t.Fatalf("Index: %d SHA384 failed Error: %s", i, errs)
4511 }
4512 }
4513 }
4514 }
4515 }
4516
4517 func TestSHA512Validation(t *testing.T) {
4518 tests := []struct {
4519 param string
4520 expected bool
4521 }{
4522 {"", false},
4523 {"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc4", true},
4524 {"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc-", false},
4525 {"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc41", false},
4526 {"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dcC", false},
4527 {"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc", false},
4528 }
4529
4530 validate := New()
4531
4532 for i, test := range tests {
4533
4534 errs := validate.Var(test.param, "sha512")
4535
4536 if test.expected {
4537 if !IsEqual(errs, nil) {
4538 t.Fatalf("Index: %d SHA512 failed Error: %s", i, errs)
4539 }
4540 } else {
4541 if IsEqual(errs, nil) {
4542 t.Fatalf("Index: %d SHA512 failed Error: %s", i, errs)
4543 } else {
4544 val := getError(errs, "", "")
4545 if val.Tag() != "sha512" {
4546 t.Fatalf("Index: %d SHA512 failed Error: %s", i, errs)
4547 }
4548 }
4549 }
4550 }
4551 }
4552
4553 func TestRIPEMD128Validation(t *testing.T) {
4554 tests := []struct {
4555 param string
4556 expected bool
4557 }{
4558 {"", false},
4559 {"6f5902ac237024bdd0c176cb93063dc4", true},
4560 {"6f5902ac237024bdd0c176cb93063dc-", false},
4561 {"6f5902ac237024bdd0c176cb93063dc41", false},
4562 {"6f5902ac237024bdd0c176cb93063dcC", false},
4563 {"6f5902ac237024bdd0c176cb93063dc", false},
4564 }
4565
4566 validate := New()
4567
4568 for i, test := range tests {
4569
4570 errs := validate.Var(test.param, "ripemd128")
4571
4572 if test.expected {
4573 if !IsEqual(errs, nil) {
4574 t.Fatalf("Index: %d RIPEMD128 failed Error: %s", i, errs)
4575 }
4576 } else {
4577 if IsEqual(errs, nil) {
4578 t.Fatalf("Index: %d RIPEMD128 failed Error: %s", i, errs)
4579 } else {
4580 val := getError(errs, "", "")
4581 if val.Tag() != "ripemd128" {
4582 t.Fatalf("Index: %d RIPEMD128 failed Error: %s", i, errs)
4583 }
4584 }
4585 }
4586 }
4587 }
4588
4589 func TestRIPEMD160Validation(t *testing.T) {
4590 tests := []struct {
4591 param string
4592 expected bool
4593 }{
4594 {"", false},
4595 {"6f5902ac6f5902ac237024bdd0c176cb93063dc4", true},
4596 {"6f5902ac6f5902ac237024bdd0c176cb93063dc-", false},
4597 {"6f5902ac6f5902ac237024bdd0c176cb93063dc41", false},
4598 {"6f5902ac6f5902ac237024bdd0c176cb93063dcC", false},
4599 {"6f5902ac6f5902ac237024bdd0c176cb93063dc", false},
4600 }
4601
4602 validate := New()
4603
4604 for i, test := range tests {
4605
4606 errs := validate.Var(test.param, "ripemd160")
4607
4608 if test.expected {
4609 if !IsEqual(errs, nil) {
4610 t.Fatalf("Index: %d RIPEMD160 failed Error: %s", i, errs)
4611 }
4612 } else {
4613 if IsEqual(errs, nil) {
4614 t.Fatalf("Index: %d RIPEMD160 failed Error: %s", i, errs)
4615 } else {
4616 val := getError(errs, "", "")
4617 if val.Tag() != "ripemd160" {
4618 t.Fatalf("Index: %d RIPEMD160 failed Error: %s", i, errs)
4619 }
4620 }
4621 }
4622 }
4623 }
4624
4625 func TestTIGER128Validation(t *testing.T) {
4626 tests := []struct {
4627 param string
4628 expected bool
4629 }{
4630 {"", false},
4631 {"6f5902ac237024bdd0c176cb93063dc4", true},
4632 {"6f5902ac237024bdd0c176cb93063dc-", false},
4633 {"6f5902ac237024bdd0c176cb93063dc41", false},
4634 {"6f5902ac237024bdd0c176cb93063dcC", false},
4635 {"6f5902ac237024bdd0c176cb93063dc", false},
4636 }
4637
4638 validate := New()
4639
4640 for i, test := range tests {
4641
4642 errs := validate.Var(test.param, "tiger128")
4643
4644 if test.expected {
4645 if !IsEqual(errs, nil) {
4646 t.Fatalf("Index: %d TIGER128 failed Error: %s", i, errs)
4647 }
4648 } else {
4649 if IsEqual(errs, nil) {
4650 t.Fatalf("Index: %d TIGER128 failed Error: %s", i, errs)
4651 } else {
4652 val := getError(errs, "", "")
4653 if val.Tag() != "tiger128" {
4654 t.Fatalf("Index: %d TIGER128 failed Error: %s", i, errs)
4655 }
4656 }
4657 }
4658 }
4659 }
4660
4661 func TestTIGER160Validation(t *testing.T) {
4662 tests := []struct {
4663 param string
4664 expected bool
4665 }{
4666 {"", false},
4667 {"6f5902ac6f5902ac237024bdd0c176cb93063dc4", true},
4668 {"6f5902ac6f5902ac237024bdd0c176cb93063dc-", false},
4669 {"6f5902ac6f5902ac237024bdd0c176cb93063dc41", false},
4670 {"6f5902ac6f5902ac237024bdd0c176cb93063dcC", false},
4671 {"6f5902ac6f5902ac237024bdd0c176cb93063dc", false},
4672 }
4673
4674 validate := New()
4675
4676 for i, test := range tests {
4677
4678 errs := validate.Var(test.param, "tiger160")
4679
4680 if test.expected {
4681 if !IsEqual(errs, nil) {
4682 t.Fatalf("Index: %d TIGER160 failed Error: %s", i, errs)
4683 }
4684 } else {
4685 if IsEqual(errs, nil) {
4686 t.Fatalf("Index: %d TIGER160 failed Error: %s", i, errs)
4687 } else {
4688 val := getError(errs, "", "")
4689 if val.Tag() != "tiger160" {
4690 t.Fatalf("Index: %d TIGER160 failed Error: %s", i, errs)
4691 }
4692 }
4693 }
4694 }
4695 }
4696
4697 func TestTIGER192Validation(t *testing.T) {
4698 tests := []struct {
4699 param string
4700 expected bool
4701 }{
4702 {"", false},
4703 {"6f5902ac237024bd6f5902ac237024bdd0c176cb93063dc4", true},
4704 {"6f5902ac237024bd6f5902ac237024bdd0c176cb93063dc-", false},
4705 {"6f5902ac237024bd6f5902ac237024bdd0c176cb93063dc41", false},
4706 {"6f5902ac237024bd6f5902ac237024bdd0c176cb93063dcC", false},
4707 {"6f5902ac237024bd6f5902ac237024bdd0c176cb93063dc", false},
4708 }
4709
4710 validate := New()
4711
4712 for i, test := range tests {
4713
4714 errs := validate.Var(test.param, "tiger192")
4715
4716 if test.expected {
4717 if !IsEqual(errs, nil) {
4718 t.Fatalf("Index: %d TIGER192 failed Error: %s", i, errs)
4719 }
4720 } else {
4721 if IsEqual(errs, nil) {
4722 t.Fatalf("Index: %d TIGER192 failed Error: %s", i, errs)
4723 } else {
4724 val := getError(errs, "", "")
4725 if val.Tag() != "tiger192" {
4726 t.Fatalf("Index: %d TIGER192 failed Error: %s", i, errs)
4727 }
4728 }
4729 }
4730 }
4731 }
4732
4733 func TestISBNValidation(t *testing.T) {
4734 tests := []struct {
4735 param string
4736 expected bool
4737 }{
4738 {"", false},
4739 {"foo", false},
4740 {"3836221195", true},
4741 {"1-61729-085-8", true},
4742 {"3 423 21412 0", true},
4743 {"3 401 01319 X", true},
4744 {"9784873113685", true},
4745 {"978-4-87311-368-5", true},
4746 {"978 3401013190", true},
4747 {"978-3-8362-2119-1", true},
4748 }
4749
4750 validate := New()
4751
4752 for i, test := range tests {
4753
4754 errs := validate.Var(test.param, "isbn")
4755
4756 if test.expected {
4757 if !IsEqual(errs, nil) {
4758 t.Fatalf("Index: %d ISBN failed Error: %s", i, errs)
4759 }
4760 } else {
4761 if IsEqual(errs, nil) {
4762 t.Fatalf("Index: %d ISBN failed Error: %s", i, errs)
4763 } else {
4764 val := getError(errs, "", "")
4765 if val.Tag() != "isbn" {
4766 t.Fatalf("Index: %d ISBN failed Error: %s", i, errs)
4767 }
4768 }
4769 }
4770 }
4771 }
4772
4773 func TestISBN13Validation(t *testing.T) {
4774 tests := []struct {
4775 param string
4776 expected bool
4777 }{
4778 {"", false},
4779 {"foo", false},
4780 {"3-8362-2119-5", false},
4781 {"01234567890ab", false},
4782 {"978 3 8362 2119 0", false},
4783 {"9784873113685", true},
4784 {"978-4-87311-368-5", true},
4785 {"978 3401013190", true},
4786 {"978-3-8362-2119-1", true},
4787 }
4788
4789 validate := New()
4790
4791 for i, test := range tests {
4792
4793 errs := validate.Var(test.param, "isbn13")
4794
4795 if test.expected {
4796 if !IsEqual(errs, nil) {
4797 t.Fatalf("Index: %d ISBN13 failed Error: %s", i, errs)
4798 }
4799 } else {
4800 if IsEqual(errs, nil) {
4801 t.Fatalf("Index: %d ISBN13 failed Error: %s", i, errs)
4802 } else {
4803 val := getError(errs, "", "")
4804 if val.Tag() != "isbn13" {
4805 t.Fatalf("Index: %d ISBN13 failed Error: %s", i, errs)
4806 }
4807 }
4808 }
4809 }
4810 }
4811
4812 func TestISBN10Validation(t *testing.T) {
4813 tests := []struct {
4814 param string
4815 expected bool
4816 }{
4817 {"", false},
4818 {"foo", false},
4819 {"3423214121", false},
4820 {"978-3836221191", false},
4821 {"3-423-21412-1", false},
4822 {"3 423 21412 1", false},
4823 {"3836221195", true},
4824 {"1-61729-085-8", true},
4825 {"3 423 21412 0", true},
4826 {"3 401 01319 X", true},
4827 }
4828
4829 validate := New()
4830
4831 for i, test := range tests {
4832
4833 errs := validate.Var(test.param, "isbn10")
4834
4835 if test.expected {
4836 if !IsEqual(errs, nil) {
4837 t.Fatalf("Index: %d ISBN10 failed Error: %s", i, errs)
4838 }
4839 } else {
4840 if IsEqual(errs, nil) {
4841 t.Fatalf("Index: %d ISBN10 failed Error: %s", i, errs)
4842 } else {
4843 val := getError(errs, "", "")
4844 if val.Tag() != "isbn10" {
4845 t.Fatalf("Index: %d ISBN10 failed Error: %s", i, errs)
4846 }
4847 }
4848 }
4849 }
4850 }
4851
4852 func TestISSNValidation(t *testing.T) {
4853 tests := []struct {
4854 param string
4855 expected bool
4856 }{
4857 {"", false},
4858 {"foo", false},
4859 {"20519990", false},
4860 {"2051-9991", false},
4861 {"2051-999X", false},
4862 {"1050-124X", true},
4863 {"0317-8471", true},
4864 }
4865
4866 validate := New()
4867
4868 for i, test := range tests {
4869 errs := validate.Var(test.param, "issn")
4870
4871 if test.expected {
4872 if !IsEqual(errs, nil) {
4873 t.Fatalf("Index: %d ISSN failed Error: %s", i, errs)
4874 }
4875 } else {
4876 if IsEqual(errs, nil) {
4877 t.Fatalf("Index: %d ISSN failed Error: %s", i, errs)
4878 } else {
4879 val := getError(errs, "", "")
4880 if val.Tag() != "issn" {
4881 t.Fatalf("Index: %d ISSN failed Error: %s", i, errs)
4882 }
4883 }
4884 }
4885 }
4886 }
4887
4888 func TestExcludesRuneValidation(t *testing.T) {
4889 tests := []struct {
4890 Value string `validate:"excludesrune=☻"`
4891 Tag string
4892 ExpectedNil bool
4893 }{
4894 {Value: "a☺b☻c☹d", Tag: "excludesrune=☻", ExpectedNil: false},
4895 {Value: "abcd", Tag: "excludesrune=☻", ExpectedNil: true},
4896 }
4897
4898 validate := New()
4899
4900 for i, s := range tests {
4901 errs := validate.Var(s.Value, s.Tag)
4902
4903 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
4904 t.Fatalf("Index: %d failed Error: %s", i, errs)
4905 }
4906
4907 errs = validate.Struct(s)
4908
4909 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
4910 t.Fatalf("Index: %d failed Error: %s", i, errs)
4911 }
4912 }
4913 }
4914
4915 func TestExcludesAllValidation(t *testing.T) {
4916 tests := []struct {
4917 Value string `validate:"excludesall=@!{}[]"`
4918 Tag string
4919 ExpectedNil bool
4920 }{
4921 {Value: "abcd@!jfk", Tag: "excludesall=@!{}[]", ExpectedNil: false},
4922 {Value: "abcdefg", Tag: "excludesall=@!{}[]", ExpectedNil: true},
4923 }
4924
4925 validate := New()
4926
4927 for i, s := range tests {
4928 errs := validate.Var(s.Value, s.Tag)
4929
4930 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
4931 t.Fatalf("Index: %d failed Error: %s", i, errs)
4932 }
4933
4934 errs = validate.Struct(s)
4935
4936 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
4937 t.Fatalf("Index: %d failed Error: %s", i, errs)
4938 }
4939 }
4940
4941 username := "joeybloggs "
4942
4943 errs := validate.Var(username, "excludesall=@ ")
4944 NotEqual(t, errs, nil)
4945 AssertError(t, errs, "", "", "", "", "excludesall")
4946
4947 excluded := ","
4948
4949 errs = validate.Var(excluded, "excludesall=!@#$%^&*()_+.0x2C?")
4950 NotEqual(t, errs, nil)
4951 AssertError(t, errs, "", "", "", "", "excludesall")
4952
4953 excluded = "="
4954
4955 errs = validate.Var(excluded, "excludesall=!@#$%^&*()_+.0x2C=?")
4956 NotEqual(t, errs, nil)
4957 AssertError(t, errs, "", "", "", "", "excludesall")
4958 }
4959
4960 func TestExcludesValidation(t *testing.T) {
4961 tests := []struct {
4962 Value string `validate:"excludes=@"`
4963 Tag string
4964 ExpectedNil bool
4965 }{
4966 {Value: "abcd@!jfk", Tag: "excludes=@", ExpectedNil: false},
4967 {Value: "abcdq!jfk", Tag: "excludes=@", ExpectedNil: true},
4968 }
4969
4970 validate := New()
4971
4972 for i, s := range tests {
4973 errs := validate.Var(s.Value, s.Tag)
4974
4975 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
4976 t.Fatalf("Index: %d failed Error: %s", i, errs)
4977 }
4978
4979 errs = validate.Struct(s)
4980
4981 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
4982 t.Fatalf("Index: %d failed Error: %s", i, errs)
4983 }
4984 }
4985 }
4986
4987 func TestContainsRuneValidation(t *testing.T) {
4988 tests := []struct {
4989 Value string `validate:"containsrune=☻"`
4990 Tag string
4991 ExpectedNil bool
4992 }{
4993 {Value: "a☺b☻c☹d", Tag: "containsrune=☻", ExpectedNil: true},
4994 {Value: "abcd", Tag: "containsrune=☻", ExpectedNil: false},
4995 }
4996
4997 validate := New()
4998
4999 for i, s := range tests {
5000 errs := validate.Var(s.Value, s.Tag)
5001
5002 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
5003 t.Fatalf("Index: %d failed Error: %s", i, errs)
5004 }
5005
5006 errs = validate.Struct(s)
5007
5008 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
5009 t.Fatalf("Index: %d failed Error: %s", i, errs)
5010 }
5011 }
5012 }
5013
5014 func TestContainsAnyValidation(t *testing.T) {
5015 tests := []struct {
5016 Value string `validate:"containsany=@!{}[]"`
5017 Tag string
5018 ExpectedNil bool
5019 }{
5020 {Value: "abcd@!jfk", Tag: "containsany=@!{}[]", ExpectedNil: true},
5021 {Value: "abcdefg", Tag: "containsany=@!{}[]", ExpectedNil: false},
5022 }
5023
5024 validate := New()
5025
5026 for i, s := range tests {
5027 errs := validate.Var(s.Value, s.Tag)
5028
5029 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
5030 t.Fatalf("Index: %d failed Error: %s", i, errs)
5031 }
5032
5033 errs = validate.Struct(s)
5034
5035 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
5036 t.Fatalf("Index: %d failed Error: %s", i, errs)
5037 }
5038 }
5039 }
5040
5041 func TestContainsValidation(t *testing.T) {
5042 tests := []struct {
5043 Value string `validate:"contains=@"`
5044 Tag string
5045 ExpectedNil bool
5046 }{
5047 {Value: "abcd@!jfk", Tag: "contains=@", ExpectedNil: true},
5048 {Value: "abcdq!jfk", Tag: "contains=@", ExpectedNil: false},
5049 }
5050
5051 validate := New()
5052
5053 for i, s := range tests {
5054 errs := validate.Var(s.Value, s.Tag)
5055
5056 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
5057 t.Fatalf("Index: %d failed Error: %s", i, errs)
5058 }
5059
5060 errs = validate.Struct(s)
5061
5062 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
5063 t.Fatalf("Index: %d failed Error: %s", i, errs)
5064 }
5065 }
5066 }
5067
5068 func TestIsNeFieldValidation(t *testing.T) {
5069 var errs error
5070 validate := New()
5071
5072 var j uint64
5073 var k float64
5074 s := "abcd"
5075 i := 1
5076 j = 1
5077 k = 1.543
5078 b := true
5079 arr := []string{"test"}
5080 now := time.Now().UTC()
5081
5082 var j2 uint64
5083 var k2 float64
5084 s2 := "abcdef"
5085 i2 := 3
5086 j2 = 2
5087 k2 = 1.5434456
5088 b2 := false
5089 arr2 := []string{"test", "test2"}
5090 arr3 := []string{"test"}
5091 now2 := now
5092
5093 errs = validate.VarWithValue(s, s2, "nefield")
5094 Equal(t, errs, nil)
5095
5096 errs = validate.VarWithValue(i2, i, "nefield")
5097 Equal(t, errs, nil)
5098
5099 errs = validate.VarWithValue(j2, j, "nefield")
5100 Equal(t, errs, nil)
5101
5102 errs = validate.VarWithValue(k2, k, "nefield")
5103 Equal(t, errs, nil)
5104
5105 errs = validate.VarWithValue(b2, b, "nefield")
5106 Equal(t, errs, nil)
5107
5108 errs = validate.VarWithValue(arr2, arr, "nefield")
5109 Equal(t, errs, nil)
5110
5111 errs = validate.VarWithValue(now2, now, "nefield")
5112 NotEqual(t, errs, nil)
5113 AssertError(t, errs, "", "", "", "", "nefield")
5114
5115 errs = validate.VarWithValue(arr3, arr, "nefield")
5116 NotEqual(t, errs, nil)
5117 AssertError(t, errs, "", "", "", "", "nefield")
5118
5119 type Test struct {
5120 Start *time.Time `validate:"nefield=End"`
5121 End *time.Time
5122 }
5123
5124 sv := &Test{
5125 Start: &now,
5126 End: &now,
5127 }
5128
5129 errs = validate.Struct(sv)
5130 NotEqual(t, errs, nil)
5131 AssertError(t, errs, "Test.Start", "Test.Start", "Start", "Start", "nefield")
5132
5133 now3 := time.Now().Add(time.Hour).UTC()
5134
5135 sv = &Test{
5136 Start: &now,
5137 End: &now3,
5138 }
5139
5140 errs = validate.Struct(sv)
5141 Equal(t, errs, nil)
5142
5143 errs = validate.VarWithValue(nil, 1, "nefield")
5144 NotEqual(t, errs, nil)
5145 AssertError(t, errs, "", "", "", "", "nefield")
5146
5147 errs = validate.VarWithValue(sv, now, "nefield")
5148 Equal(t, errs, nil)
5149
5150 type Test2 struct {
5151 Start *time.Time `validate:"nefield=NonExistantField"`
5152 End *time.Time
5153 }
5154
5155 sv2 := &Test2{
5156 Start: &now,
5157 End: &now,
5158 }
5159
5160 errs = validate.Struct(sv2)
5161 Equal(t, errs, nil)
5162
5163 type Other struct {
5164 Value string
5165 }
5166
5167 type Test3 struct {
5168 Value Other
5169 Time time.Time `validate:"nefield=Value"`
5170 }
5171
5172 tst := Test3{
5173 Value: Other{Value: "StringVal"},
5174 Time: now,
5175 }
5176
5177 errs = validate.Struct(tst)
5178 Equal(t, errs, nil)
5179
5180
5181
5182
5183
5184 errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "nefield")
5185 Equal(t, errs, nil)
5186
5187 errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "nefield")
5188 Equal(t, errs, nil)
5189
5190 errs = validate.VarWithValue(time.Hour, time.Hour, "nefield")
5191 NotEqual(t, errs, nil)
5192 AssertError(t, errs, "", "", "", "", "nefield")
5193
5194 errs = validate.VarWithValue(time.Duration(0), time.Duration(0), "omitempty,nefield")
5195 Equal(t, errs, nil)
5196
5197
5198
5199 type TimeDurationTest struct {
5200 First time.Duration `validate:"nefield=Second"`
5201 Second time.Duration
5202 }
5203 var timeDurationTest *TimeDurationTest
5204
5205 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour - time.Minute}
5206 errs = validate.Struct(timeDurationTest)
5207 Equal(t, errs, nil)
5208
5209 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour + time.Minute}
5210 errs = validate.Struct(timeDurationTest)
5211 Equal(t, errs, nil)
5212
5213 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour}
5214 errs = validate.Struct(timeDurationTest)
5215 NotEqual(t, errs, nil)
5216 AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "nefield")
5217
5218 type TimeDurationOmitemptyTest struct {
5219 First time.Duration `validate:"omitempty,nefield=Second"`
5220 Second time.Duration
5221 }
5222
5223 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0), time.Duration(0)}
5224 errs = validate.Struct(timeDurationOmitemptyTest)
5225 Equal(t, errs, nil)
5226 }
5227
5228 func TestIsNeValidation(t *testing.T) {
5229 var errs error
5230 validate := New()
5231
5232 var j uint64
5233 var k float64
5234 s := "abcdef"
5235 i := 3
5236 j = 2
5237 k = 1.5434
5238 arr := []string{"test"}
5239 now := time.Now().UTC()
5240
5241 errs = validate.Var(s, "ne=abcd")
5242 Equal(t, errs, nil)
5243
5244 errs = validate.Var(i, "ne=1")
5245 Equal(t, errs, nil)
5246
5247 errs = validate.Var(j, "ne=1")
5248 Equal(t, errs, nil)
5249
5250 errs = validate.Var(k, "ne=1.543")
5251 Equal(t, errs, nil)
5252
5253 errs = validate.Var(arr, "ne=2")
5254 Equal(t, errs, nil)
5255
5256 errs = validate.Var(arr, "ne=1")
5257 NotEqual(t, errs, nil)
5258 AssertError(t, errs, "", "", "", "", "ne")
5259
5260 PanicMatches(t, func() { _ = validate.Var(now, "ne=now") }, "Bad field type time.Time")
5261
5262
5263
5264
5265
5266 errs = validate.Var(time.Hour-time.Minute, "ne=1h")
5267 Equal(t, errs, nil)
5268
5269 errs = validate.Var(time.Hour+time.Minute, "ne=1h")
5270 Equal(t, errs, nil)
5271
5272 errs = validate.Var(time.Hour, "ne=1h")
5273 NotEqual(t, errs, nil)
5274 AssertError(t, errs, "", "", "", "", "ne")
5275
5276 errs = validate.Var(time.Duration(0), "omitempty,ne=0")
5277 Equal(t, errs, nil)
5278
5279
5280
5281 type TimeDurationTest struct {
5282 Duration time.Duration `validate:"ne=1h"`
5283 }
5284 var timeDurationTest *TimeDurationTest
5285
5286 timeDurationTest = &TimeDurationTest{time.Hour - time.Minute}
5287 errs = validate.Struct(timeDurationTest)
5288 Equal(t, errs, nil)
5289
5290 timeDurationTest = &TimeDurationTest{time.Hour + time.Minute}
5291 errs = validate.Struct(timeDurationTest)
5292 Equal(t, errs, nil)
5293
5294 timeDurationTest = &TimeDurationTest{time.Hour}
5295 errs = validate.Struct(timeDurationTest)
5296 NotEqual(t, errs, nil)
5297 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "ne")
5298
5299 type TimeDurationOmitemptyTest struct {
5300 Duration time.Duration `validate:"omitempty,ne=0"`
5301 }
5302
5303 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
5304 errs = validate.Struct(timeDurationOmitemptyTest)
5305 Equal(t, errs, nil)
5306 }
5307
5308 func TestIsNeIgnoreCaseValidation(t *testing.T) {
5309 var errs error
5310 validate := New()
5311 s := "abcd"
5312 now := time.Now()
5313
5314 errs = validate.Var(s, "ne_ignore_case=efgh")
5315 Equal(t, errs, nil)
5316
5317 errs = validate.Var(s, "ne_ignore_case=AbCd")
5318 NotEqual(t, errs, nil)
5319 AssertError(t, errs, "", "", "", "", "ne_ignore_case")
5320
5321 PanicMatches(
5322 t, func() { _ = validate.Var(now, "ne_ignore_case=abcd") }, "Bad field type time.Time",
5323 )
5324 }
5325
5326 func TestIsEqFieldValidation(t *testing.T) {
5327 var errs error
5328 validate := New()
5329
5330 var j uint64
5331 var k float64
5332 s := "abcd"
5333 i := 1
5334 j = 1
5335 k = 1.543
5336 b := true
5337 arr := []string{"test"}
5338 now := time.Now().UTC()
5339
5340 var j2 uint64
5341 var k2 float64
5342 s2 := "abcd"
5343 i2 := 1
5344 j2 = 1
5345 k2 = 1.543
5346 b2 := true
5347 arr2 := []string{"test"}
5348 arr3 := []string{"test", "test2"}
5349 now2 := now
5350
5351 errs = validate.VarWithValue(s, s2, "eqfield")
5352 Equal(t, errs, nil)
5353
5354 errs = validate.VarWithValue(i2, i, "eqfield")
5355 Equal(t, errs, nil)
5356
5357 errs = validate.VarWithValue(j2, j, "eqfield")
5358 Equal(t, errs, nil)
5359
5360 errs = validate.VarWithValue(k2, k, "eqfield")
5361 Equal(t, errs, nil)
5362
5363 errs = validate.VarWithValue(b2, b, "eqfield")
5364 Equal(t, errs, nil)
5365
5366 errs = validate.VarWithValue(arr2, arr, "eqfield")
5367 Equal(t, errs, nil)
5368
5369 errs = validate.VarWithValue(now2, now, "eqfield")
5370 Equal(t, errs, nil)
5371
5372 errs = validate.VarWithValue(arr3, arr, "eqfield")
5373 NotEqual(t, errs, nil)
5374 AssertError(t, errs, "", "", "", "", "eqfield")
5375
5376 type Test struct {
5377 Start *time.Time `validate:"eqfield=End"`
5378 End *time.Time
5379 }
5380
5381 sv := &Test{
5382 Start: &now,
5383 End: &now,
5384 }
5385
5386 errs = validate.Struct(sv)
5387 Equal(t, errs, nil)
5388
5389 now3 := time.Now().Add(time.Hour).UTC()
5390
5391 sv = &Test{
5392 Start: &now,
5393 End: &now3,
5394 }
5395
5396 errs = validate.Struct(sv)
5397 NotEqual(t, errs, nil)
5398 AssertError(t, errs, "Test.Start", "Test.Start", "Start", "Start", "eqfield")
5399
5400 errs = validate.VarWithValue(nil, 1, "eqfield")
5401 NotEqual(t, errs, nil)
5402 AssertError(t, errs, "", "", "", "", "eqfield")
5403
5404 channel := make(chan string)
5405 errs = validate.VarWithValue(5, channel, "eqfield")
5406 NotEqual(t, errs, nil)
5407 AssertError(t, errs, "", "", "", "", "eqfield")
5408
5409 errs = validate.VarWithValue(5, now, "eqfield")
5410 NotEqual(t, errs, nil)
5411 AssertError(t, errs, "", "", "", "", "eqfield")
5412
5413 type Test2 struct {
5414 Start *time.Time `validate:"eqfield=NonExistantField"`
5415 End *time.Time
5416 }
5417
5418 sv2 := &Test2{
5419 Start: &now,
5420 End: &now,
5421 }
5422
5423 errs = validate.Struct(sv2)
5424 NotEqual(t, errs, nil)
5425 AssertError(t, errs, "Test2.Start", "Test2.Start", "Start", "Start", "eqfield")
5426
5427 type Inner struct {
5428 Name string
5429 }
5430
5431 type TStruct struct {
5432 Inner *Inner
5433 CreatedAt *time.Time `validate:"eqfield=Inner"`
5434 }
5435
5436 inner := &Inner{
5437 Name: "NAME",
5438 }
5439
5440 test := &TStruct{
5441 Inner: inner,
5442 CreatedAt: &now,
5443 }
5444
5445 errs = validate.Struct(test)
5446 NotEqual(t, errs, nil)
5447 AssertError(t, errs, "TStruct.CreatedAt", "TStruct.CreatedAt", "CreatedAt", "CreatedAt", "eqfield")
5448
5449
5450
5451
5452
5453 errs = validate.VarWithValue(time.Hour, time.Hour, "eqfield")
5454 Equal(t, errs, nil)
5455
5456 errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "eqfield")
5457 NotEqual(t, errs, nil)
5458 AssertError(t, errs, "", "", "", "", "eqfield")
5459
5460 errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "eqfield")
5461 NotEqual(t, errs, nil)
5462 AssertError(t, errs, "", "", "", "", "eqfield")
5463
5464 errs = validate.VarWithValue(time.Duration(0), time.Hour, "omitempty,eqfield")
5465 Equal(t, errs, nil)
5466
5467
5468
5469 type TimeDurationTest struct {
5470 First time.Duration `validate:"eqfield=Second"`
5471 Second time.Duration
5472 }
5473 var timeDurationTest *TimeDurationTest
5474
5475 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour}
5476 errs = validate.Struct(timeDurationTest)
5477 Equal(t, errs, nil)
5478
5479 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour - time.Minute}
5480 errs = validate.Struct(timeDurationTest)
5481 NotEqual(t, errs, nil)
5482 AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "eqfield")
5483
5484 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour + time.Minute}
5485 errs = validate.Struct(timeDurationTest)
5486 NotEqual(t, errs, nil)
5487 AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "eqfield")
5488
5489 type TimeDurationOmitemptyTest struct {
5490 First time.Duration `validate:"omitempty,eqfield=Second"`
5491 Second time.Duration
5492 }
5493
5494 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0), time.Hour}
5495 errs = validate.Struct(timeDurationOmitemptyTest)
5496 Equal(t, errs, nil)
5497 }
5498
5499 func TestIsEqFieldValidationWithAliasTime(t *testing.T) {
5500 var errs error
5501 validate := New()
5502
5503 type CustomTime time.Time
5504
5505 type Test struct {
5506 Start CustomTime `validate:"eqfield=End"`
5507 End *time.Time
5508 }
5509
5510 now := time.Now().UTC()
5511
5512 sv := &Test{
5513 Start: CustomTime(now),
5514 End: &now,
5515 }
5516
5517 errs = validate.Struct(sv)
5518 Equal(t, errs, nil)
5519 }
5520
5521 func TestIsEqValidation(t *testing.T) {
5522 var errs error
5523 validate := New()
5524
5525 var j uint64
5526 var k float64
5527 s := "abcd"
5528 i := 1
5529 j = 1
5530 k = 1.543
5531 arr := []string{"test"}
5532 now := time.Now().UTC()
5533
5534 errs = validate.Var(s, "eq=abcd")
5535 Equal(t, errs, nil)
5536
5537 errs = validate.Var(i, "eq=1")
5538 Equal(t, errs, nil)
5539
5540 errs = validate.Var(j, "eq=1")
5541 Equal(t, errs, nil)
5542
5543 errs = validate.Var(k, "eq=1.543")
5544 Equal(t, errs, nil)
5545
5546 errs = validate.Var(arr, "eq=1")
5547 Equal(t, errs, nil)
5548
5549 errs = validate.Var(arr, "eq=2")
5550 NotEqual(t, errs, nil)
5551 AssertError(t, errs, "", "", "", "", "eq")
5552
5553 PanicMatches(t, func() { _ = validate.Var(now, "eq=now") }, "Bad field type time.Time")
5554
5555
5556
5557
5558
5559 errs = validate.Var(time.Hour, "eq=1h")
5560 Equal(t, errs, nil)
5561
5562 errs = validate.Var(time.Hour-time.Minute, "eq=1h")
5563 NotEqual(t, errs, nil)
5564 AssertError(t, errs, "", "", "", "", "eq")
5565
5566 errs = validate.Var(time.Hour+time.Minute, "eq=1h")
5567 NotEqual(t, errs, nil)
5568 AssertError(t, errs, "", "", "", "", "eq")
5569
5570 errs = validate.Var(time.Duration(0), "omitempty,eq=1h")
5571 Equal(t, errs, nil)
5572
5573
5574
5575 type TimeDurationTest struct {
5576 Duration time.Duration `validate:"eq=1h"`
5577 }
5578 var timeDurationTest *TimeDurationTest
5579
5580 timeDurationTest = &TimeDurationTest{time.Hour}
5581 errs = validate.Struct(timeDurationTest)
5582 Equal(t, errs, nil)
5583
5584 timeDurationTest = &TimeDurationTest{time.Hour - time.Minute}
5585 errs = validate.Struct(timeDurationTest)
5586 NotEqual(t, errs, nil)
5587 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "eq")
5588
5589 timeDurationTest = &TimeDurationTest{time.Hour + time.Minute}
5590 errs = validate.Struct(timeDurationTest)
5591 NotEqual(t, errs, nil)
5592 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "eq")
5593
5594 type TimeDurationOmitemptyTest struct {
5595 Duration time.Duration `validate:"omitempty,eq=1h"`
5596 }
5597
5598 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
5599 errs = validate.Struct(timeDurationOmitemptyTest)
5600 Equal(t, errs, nil)
5601 }
5602
5603 func TestIsEqIgnoreCaseValidation(t *testing.T) {
5604 var errs error
5605 validate := New()
5606 s := "abcd"
5607 now := time.Now()
5608
5609 errs = validate.Var(s, "eq_ignore_case=abcd")
5610 Equal(t, errs, nil)
5611
5612 errs = validate.Var(s, "eq_ignore_case=AbCd")
5613 Equal(t, errs, nil)
5614
5615 PanicMatches(
5616 t, func() { _ = validate.Var(now, "eq_ignore_case=abcd") }, "Bad field type time.Time",
5617 )
5618 }
5619
5620 func TestOneOfValidation(t *testing.T) {
5621 validate := New()
5622
5623 passSpecs := []struct {
5624 f interface{}
5625 t string
5626 }{
5627 {f: "red", t: "oneof=red green"},
5628 {f: "green", t: "oneof=red green"},
5629 {f: "red green", t: "oneof='red green' blue"},
5630 {f: "blue", t: "oneof='red green' blue"},
5631 {f: 5, t: "oneof=5 6"},
5632 {f: 6, t: "oneof=5 6"},
5633 {f: int8(6), t: "oneof=5 6"},
5634 {f: int16(6), t: "oneof=5 6"},
5635 {f: int32(6), t: "oneof=5 6"},
5636 {f: int64(6), t: "oneof=5 6"},
5637 {f: uint(6), t: "oneof=5 6"},
5638 {f: uint8(6), t: "oneof=5 6"},
5639 {f: uint16(6), t: "oneof=5 6"},
5640 {f: uint32(6), t: "oneof=5 6"},
5641 {f: uint64(6), t: "oneof=5 6"},
5642 }
5643
5644 for _, spec := range passSpecs {
5645 t.Logf("%#v", spec)
5646 errs := validate.Var(spec.f, spec.t)
5647 Equal(t, errs, nil)
5648 }
5649
5650 failSpecs := []struct {
5651 f interface{}
5652 t string
5653 }{
5654 {f: "", t: "oneof=red green"},
5655 {f: "yellow", t: "oneof=red green"},
5656 {f: "green", t: "oneof='red green' blue"},
5657 {f: 5, t: "oneof=red green"},
5658 {f: 6, t: "oneof=red green"},
5659 {f: 6, t: "oneof=7"},
5660 {f: uint(6), t: "oneof=7"},
5661 {f: int8(5), t: "oneof=red green"},
5662 {f: int16(5), t: "oneof=red green"},
5663 {f: int32(5), t: "oneof=red green"},
5664 {f: int64(5), t: "oneof=red green"},
5665 {f: uint(5), t: "oneof=red green"},
5666 {f: uint8(5), t: "oneof=red green"},
5667 {f: uint16(5), t: "oneof=red green"},
5668 {f: uint32(5), t: "oneof=red green"},
5669 {f: uint64(5), t: "oneof=red green"},
5670 }
5671
5672 for _, spec := range failSpecs {
5673 t.Logf("%#v", spec)
5674 errs := validate.Var(spec.f, spec.t)
5675 AssertError(t, errs, "", "", "", "", "oneof")
5676 }
5677
5678 PanicMatches(t, func() {
5679 _ = validate.Var(3.14, "oneof=red green")
5680 }, "Bad field type float64")
5681 }
5682
5683 func TestBase32Validation(t *testing.T) {
5684 validate := New()
5685
5686 s := "ABCD2345"
5687 errs := validate.Var(s, "base32")
5688 Equal(t, errs, nil)
5689
5690 s = "AB======"
5691 errs = validate.Var(s, "base32")
5692 Equal(t, errs, nil)
5693
5694 s = "ABCD2==="
5695 errs = validate.Var(s, "base32")
5696 Equal(t, errs, nil)
5697
5698 s = "ABCD===="
5699 errs = validate.Var(s, "base32")
5700 Equal(t, errs, nil)
5701
5702 s = "ABCD234="
5703 errs = validate.Var(s, "base32")
5704 Equal(t, errs, nil)
5705
5706 s = ""
5707 errs = validate.Var(s, "base32")
5708 NotEqual(t, errs, nil)
5709 AssertError(t, errs, "", "", "", "", "base32")
5710
5711 s = "ABCabc1890== foo bar"
5712 errs = validate.Var(s, "base32")
5713 NotEqual(t, errs, nil)
5714 AssertError(t, errs, "", "", "", "", "base32")
5715 }
5716
5717 func TestBase64Validation(t *testing.T) {
5718 validate := New()
5719
5720 s := "dW5pY29ybg=="
5721
5722 errs := validate.Var(s, "base64")
5723 Equal(t, errs, nil)
5724
5725 s = "dGhpIGlzIGEgdGVzdCBiYXNlNjQ="
5726 errs = validate.Var(s, "base64")
5727 Equal(t, errs, nil)
5728
5729 s = ""
5730 errs = validate.Var(s, "base64")
5731 NotEqual(t, errs, nil)
5732 AssertError(t, errs, "", "", "", "", "base64")
5733
5734 s = "dW5pY29ybg== foo bar"
5735 errs = validate.Var(s, "base64")
5736 NotEqual(t, errs, nil)
5737 AssertError(t, errs, "", "", "", "", "base64")
5738 }
5739
5740 func TestBase64URLValidation(t *testing.T) {
5741 validate := New()
5742
5743 testCases := []struct {
5744 decoded, encoded string
5745 success bool
5746 }{
5747
5748 {"", "", false},
5749
5750 {"", "a", false},
5751
5752 {"f", "Zg==", true},
5753 {"fo", "Zm8=", true},
5754
5755 {"foo", "Zm9v", true},
5756 {"", "Zg", false},
5757 {"", "Zm8", false},
5758
5759 {"\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l+", false},
5760 {"\x14\xfb\x9c\x03\xf9\x73", "FPucA/lz", false},
5761
5762 {"\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l-", true},
5763 {"\x14\xfb\x9c\x03\xf9\x73", "FPucA_lz", true},
5764
5765 {"", "@mc=", false},
5766 {"", "Zm 9", false},
5767 }
5768 for _, tc := range testCases {
5769 err := validate.Var(tc.encoded, "base64url")
5770 if tc.success {
5771 Equal(t, err, nil)
5772
5773 d, innerErr := base64.URLEncoding.DecodeString(tc.encoded)
5774 Equal(t, innerErr, nil)
5775 Equal(t, tc.decoded, string(d))
5776 } else {
5777 NotEqual(t, err, nil)
5778 if len(tc.encoded) > 0 {
5779
5780 _, err := base64.URLEncoding.DecodeString(tc.encoded)
5781 NotEqual(t, err, nil)
5782 }
5783 }
5784 }
5785 }
5786
5787 func TestBase64RawURLValidation(t *testing.T) {
5788 validate := New()
5789
5790 testCases := []struct {
5791 decoded, encoded string
5792 success bool
5793 }{
5794
5795 {"", "", false},
5796
5797 {"", "a", false},
5798
5799 {"f", "Zg==", false},
5800 {"fo", "Zm8=", false},
5801
5802 {"foo", "Zm9v", true},
5803 {"hello", "aGVsbG8", true},
5804 {"", "aGVsb", false},
5805
5806 {"\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l+", false},
5807 {"\x14\xfb\x9c\x03\xf9\x73", "FPucA/lz", false},
5808
5809 {"\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l-", true},
5810 {"\x14\xfb\x9c\x03\xf9\x73", "FPucA_lz", true},
5811
5812 {"", "@mc=", false},
5813 {"", "Zm 9", false},
5814 }
5815 for _, tc := range testCases {
5816 err := validate.Var(tc.encoded, "base64rawurl")
5817 if tc.success {
5818 Equal(t, err, nil)
5819
5820 d, innerErr := base64.RawURLEncoding.DecodeString(tc.encoded)
5821 Equal(t, innerErr, nil)
5822 Equal(t, tc.decoded, string(d))
5823 } else {
5824 NotEqual(t, err, nil)
5825 if len(tc.encoded) > 0 {
5826
5827 _, err := base64.RawURLEncoding.DecodeString(tc.encoded)
5828 NotEqual(t, err, nil)
5829 }
5830 }
5831 }
5832 }
5833
5834 func TestFileValidation(t *testing.T) {
5835 validate := New()
5836
5837 tests := []struct {
5838 title string
5839 param string
5840 expected bool
5841 }{
5842 {"empty path", "", false},
5843 {"regular file", filepath.Join("testdata", "a.go"), true},
5844 {"missing file", filepath.Join("testdata", "no.go"), false},
5845 {"directory, not a file", "testdata", false},
5846 }
5847
5848 for _, test := range tests {
5849 errs := validate.Var(test.param, "file")
5850
5851 if test.expected {
5852 if !IsEqual(errs, nil) {
5853 t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
5854 }
5855 } else {
5856 if IsEqual(errs, nil) {
5857 t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
5858 }
5859 }
5860 }
5861
5862 PanicMatches(t, func() {
5863 _ = validate.Var(6, "file")
5864 }, "Bad field type int")
5865 }
5866
5867 func TestImageValidation(t *testing.T) {
5868 validate := New()
5869
5870 paths := map[string]string{
5871 "empty": "",
5872 "directory": "testdata",
5873 "missing": filepath.Join("testdata", "none.png"),
5874 "png": filepath.Join("testdata", "image.png"),
5875 "jpeg": filepath.Join("testdata", "image.jpg"),
5876 "mp3": filepath.Join("testdata", "music.mp3"),
5877 }
5878
5879 tests := []struct {
5880 title string
5881 param string
5882 expected bool
5883 createImage func()
5884 destroyImage func()
5885 }{
5886 {
5887 "empty path",
5888 paths["empty"], false,
5889 func() {},
5890 func() {},
5891 },
5892 {
5893 "directory, not a file",
5894 paths["directory"],
5895 false,
5896 func() {},
5897 func() {},
5898 },
5899 {
5900 "missing file",
5901 paths["missing"],
5902 false,
5903 func() {},
5904 func() {},
5905 },
5906 {
5907 "valid png",
5908 paths["png"],
5909 true,
5910 func() {
5911 img := image.NewRGBA(image.Rectangle{image.Point{0, 0}, image.Point{10, 10}})
5912 f, _ := os.Create(paths["png"])
5913 err := png.Encode(f, img)
5914 if err != nil {
5915 panic(fmt.Sprintf("Could not encode file in PNG. Error: %s", err))
5916 }
5917 },
5918 func() {
5919 os.Remove(paths["png"])
5920 },
5921 },
5922 {
5923 "valid jpeg",
5924 paths["jpeg"],
5925 true,
5926 func() {
5927 var opt jpeg.Options
5928 img := image.NewGray(image.Rect(0, 0, 10, 10))
5929 f, _ := os.Create(paths["jpeg"])
5930 err := jpeg.Encode(f, img, &opt)
5931 if err != nil {
5932 panic(fmt.Sprintf("Could not encode file in JPEG. Error: %s", err))
5933 }
5934 },
5935 func() {
5936 os.Remove(paths["jpeg"])
5937 },
5938 },
5939 {
5940 "valid mp3",
5941 paths["mp3"],
5942 false,
5943 func() {},
5944 func() {},
5945 },
5946 }
5947
5948 for _, test := range tests {
5949 test.createImage()
5950 errs := validate.Var(test.param, "image")
5951
5952 if test.expected {
5953 if !IsEqual(errs, nil) {
5954 t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
5955 }
5956 } else {
5957 if IsEqual(errs, nil) {
5958 t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
5959 }
5960 }
5961 test.destroyImage()
5962 }
5963
5964 PanicMatches(t, func() {
5965 _ = validate.Var(6, "file")
5966 }, "Bad field type int")
5967 }
5968
5969 func TestFilePathValidation(t *testing.T) {
5970 validate := New()
5971
5972 tests := []struct {
5973 title string
5974 param string
5975 expected bool
5976 }{
5977 {"empty filepath", "", false},
5978 {"valid filepath", filepath.Join("testdata", "a.go"), true},
5979 {"invalid filepath", filepath.Join("testdata", "no\000.go"), false},
5980 {"directory, not a filepath", "testdata" + string(os.PathSeparator), false},
5981 {"directory", "testdata", false},
5982 }
5983
5984 for _, test := range tests {
5985 errs := validate.Var(test.param, "filepath")
5986
5987 if test.expected {
5988 if !IsEqual(errs, nil) {
5989 t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
5990 }
5991 } else {
5992 if IsEqual(errs, nil) {
5993 t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
5994 }
5995 }
5996
5997 }
5998
5999 PanicMatches(t, func() {
6000 _ = validate.Var(6, "filepath")
6001 }, "Bad field type int")
6002 }
6003
6004 func TestEthereumAddressValidation(t *testing.T) {
6005 validate := New()
6006
6007 tests := []struct {
6008 param string
6009 expected bool
6010 }{
6011
6012 {"0x52908400098527886E0F7030069857D2E4169EE7", true},
6013 {"0x8617E340B3D01FA5F11F306F4090FD50E238070D", true},
6014
6015
6016 {"0xde709f2102306220921060314715629080e2fb77", true},
6017 {"0x27b1fdb04752bbc536007a920d24acb045561c26", true},
6018 {"0x123f681646d4a755815f9cb19e1acc8565a0c2ac", true},
6019
6020
6021 {"0x02F9AE5f22EA3fA88F05780B30385bECFacbf130", true},
6022 {"0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed", true},
6023 {"0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359", true},
6024 {"0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB", true},
6025 {"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb", true},
6026 {"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDB", true},
6027
6028
6029 {"", false},
6030 {"D1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb", false},
6031 {"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDbc", false},
6032 {"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aD", false},
6033 {"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDw", false},
6034 }
6035
6036 for i, test := range tests {
6037
6038 errs := validate.Var(test.param, "eth_addr")
6039
6040 if test.expected {
6041 if !IsEqual(errs, nil) {
6042 t.Fatalf("Index: %d eth_addr failed Error: %s", i, errs)
6043 }
6044 } else {
6045 if IsEqual(errs, nil) {
6046 t.Fatalf("Index: %d eth_addr failed Error: %s", i, errs)
6047 } else {
6048 val := getError(errs, "", "")
6049 if val.Tag() != "eth_addr" {
6050 t.Fatalf("Index: %d Latitude failed Error: %s", i, errs)
6051 }
6052 }
6053 }
6054 }
6055 }
6056
6057 func TestEthereumAddressChecksumValidation(t *testing.T) {
6058 validate := New()
6059
6060 tests := []struct {
6061 param string
6062 expected bool
6063 }{
6064
6065 {"0x52908400098527886E0F7030069857D2E4169EE7", true},
6066 {"0x8617E340B3D01FA5F11F306F4090FD50E238070D", true},
6067
6068
6069 {"0x27b1fdb04752bbc536007a920d24acb045561c26", true},
6070 {"0x123f681646d4a755815f9cb19e1acc8565a0c2ac", false},
6071
6072
6073 {"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb", true},
6074 {"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDB", false},
6075 {"0x000000000000000000000000000000000000dead", false},
6076 {"0x000000000000000000000000000000000000dEaD", true},
6077
6078
6079 {"", false},
6080 {"D1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb", false},
6081 {"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDbc", false},
6082 {"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aD", false},
6083 {"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDw", false},
6084 }
6085
6086 for i, test := range tests {
6087
6088 errs := validate.Var(test.param, "eth_addr_checksum")
6089
6090 if test.expected {
6091 if !IsEqual(errs, nil) {
6092 t.Fatalf("Index: %d eth_addr_checksum failed Error: %s", i, errs)
6093 }
6094 } else {
6095 if IsEqual(errs, nil) {
6096 t.Fatalf("Index: %d eth_addr_checksum failed Error: %s", i, errs)
6097 } else {
6098 val := getError(errs, "", "")
6099 if val.Tag() != "eth_addr_checksum" {
6100 t.Fatalf("Index: %d Latitude failed Error: %s", i, errs)
6101 }
6102 }
6103 }
6104 }
6105 }
6106
6107 func TestBitcoinAddressValidation(t *testing.T) {
6108 validate := New()
6109
6110 tests := []struct {
6111 param string
6112 expected bool
6113 }{
6114 {"", false},
6115 {"x", false},
6116 {"0x02F9AE5f22EA3fA88F05780B30385bEC", false},
6117 {"1A1zP1ePQGefi2DMPTifTL5SLmv7DivfNa", false},
6118 {"1P9RQEr2XeE3PEb44ZE35sfZRRW1JH8Uqx", false},
6119 {"3P14159I73E4gFr7JterCCQh9QjiTjiZrG", false},
6120 {"3P141597f3E4gFr7JterCCQh9QjiTjiZrG", false},
6121 {"37qgekLpCCHrQuSjvX3fs496FWTGsHFHizjJAs6NPcR47aefnnCWECAhHV6E3g4YN7u7Yuwod5Y", false},
6122 {"dzb7VV1Ui55BARxv7ATxAtCUeJsANKovDGWFVgpTbhq9gvPqP3yv", false},
6123 {"MuNu7ZAEDFiHthiunm7dPjwKqrVNCM3mAz6rP9zFveQu14YA8CxExSJTHcVP9DErn6u84E6Ej7S", false},
6124 {"rPpQpYknyNQ5AEHuY6H8ijJJrYc2nDKKk9jjmKEXsWzyAQcFGpDLU2Zvsmoi8JLR7hAwoy3RQWf", false},
6125 {"4Uc3FmN6NQ6zLBK5QQBXRBUREaaHwCZYsGCueHauuDmJpZKn6jkEskMB2Zi2CNgtb5r6epWEFfUJq", false},
6126 {"7aQgR5DFQ25vyXmqZAWmnVCjL3PkBcdVkBUpjrjMTcghHx3E8wb", false},
6127 {"17QpPprjeg69fW1DV8DcYYCKvWjYhXvWkov6MJ1iTTvMFj6weAqW7wybZeH57WTNxXVCRH4veVs", false},
6128 {"KxuACDviz8Xvpn1xAh9MfopySZNuyajYMZWz16Dv2mHHryznWUp3", false},
6129 {"7nK3GSmqdXJQtdohvGfJ7KsSmn3TmGqExug49583bDAL91pVSGq5xS9SHoAYL3Wv3ijKTit65th", false},
6130 {"cTivdBmq7bay3RFGEBBuNfMh2P1pDCgRYN2Wbxmgwr4ki3jNUL2va", false},
6131 {"gjMV4vjNjyMrna4fsAr8bWxAbwtmMUBXJS3zL4NJt5qjozpbQLmAfK1uA3CquSqsZQMpoD1g2nk", false},
6132 {"emXm1naBMoVzPjbk7xpeTVMFy4oDEe25UmoyGgKEB1gGWsK8kRGs", false},
6133 {"7VThQnNRj1o3Zyvc7XHPRrjDf8j2oivPTeDXnRPYWeYGE4pXeRJDZgf28ppti5hsHWXS2GSobdqyo", false},
6134 {"1G9u6oCVCPh2o8m3t55ACiYvG1y5BHewUkDSdiQarDcYXXhFHYdzMdYfUAhfxn5vNZBwpgUNpso", false},
6135 {"31QQ7ZMLkScDiB4VyZjuptr7AEc9j1SjstF7pRoLhHTGkW4Q2y9XELobQmhhWxeRvqcukGd1XCq", false},
6136 {"DHqKSnpxa8ZdQyH8keAhvLTrfkyBMQxqngcQA5N8LQ9KVt25kmGN", false},
6137 {"2LUHcJPbwLCy9GLH1qXmfmAwvadWw4bp4PCpDfduLqV17s6iDcy1imUwhQJhAoNoN1XNmweiJP4i", false},
6138 {"7USRzBXAnmck8fX9HmW7RAb4qt92VFX6soCnts9s74wxm4gguVhtG5of8fZGbNPJA83irHVY6bCos", false},
6139 {"1DGezo7BfVebZxAbNT3XGujdeHyNNBF3vnficYoTSp4PfK2QaML9bHzAMxke3wdKdHYWmsMTJVu", false},
6140 {"2D12DqDZKwCxxkzs1ZATJWvgJGhQ4cFi3WrizQ5zLAyhN5HxuAJ1yMYaJp8GuYsTLLxTAz6otCfb", false},
6141 {"8AFJzuTujXjw1Z6M3fWhQ1ujDW7zsV4ePeVjVo7D1egERqSW9nZ", false},
6142 {"163Q17qLbTCue8YY3AvjpUhotuaodLm2uqMhpYirsKjVqnxJRWTEoywMVY3NbBAHuhAJ2cF9GAZ", false},
6143 {"2MnmgiRH4eGLyLc9eAqStzk7dFgBjFtUCtu", false},
6144 {"461QQ2sYWxU7H2PV4oBwJGNch8XVTYYbZxU", false},
6145 {"2UCtv53VttmQYkVU4VMtXB31REvQg4ABzs41AEKZ8UcB7DAfVzdkV9JDErwGwyj5AUHLkmgZeobs", false},
6146 {"cSNjAsnhgtiFMi6MtfvgscMB2Cbhn2v1FUYfviJ1CdjfidvmeW6mn", false},
6147 {"gmsow2Y6EWAFDFE1CE4Hd3Tpu2BvfmBfG1SXsuRARbnt1WjkZnFh1qGTiptWWbjsq2Q6qvpgJVj", false},
6148 {"nksUKSkzS76v8EsSgozXGMoQFiCoCHzCVajFKAXqzK5on9ZJYVHMD5CKwgmX3S3c7M1U3xabUny", false},
6149 {"L3favK1UzFGgdzYBF2oBT5tbayCo4vtVBLJhg2iYuMeePxWG8SQc", false},
6150 {"7VxLxGGtYT6N99GdEfi6xz56xdQ8nP2dG1CavuXx7Rf2PrvNMTBNevjkfgs9JmkcGm6EXpj8ipyPZ ", false},
6151 {"2mbZwFXF6cxShaCo2czTRB62WTx9LxhTtpP", false},
6152 {"dB7cwYdcPSgiyAwKWL3JwCVwSk6epU2txw", false},
6153 {"HPhFUhUAh8ZQQisH8QQWafAxtQYju3SFTX", false},
6154 {"4ctAH6AkHzq5ioiM1m9T3E2hiYEev5mTsB", false},
6155 {"31uEbMgunupShBVTewXjtqbBv5MndwfXhb", false},
6156 {"175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W", false},
6157 {"Hn1uFi4dNexWrqARpjMqgT6cX1UsNPuV3cHdGg9ExyXw8HTKadbktRDtdeVmY3M1BxJStiL4vjJ", false},
6158 {"Sq3fDbvutABmnAHHExJDgPLQn44KnNC7UsXuT7KZecpaYDMU9Txs", false},
6159 {"6TqWyrqdgUEYDQU1aChMuFMMEimHX44qHFzCUgGfqxGgZNMUVWJ", false},
6160 {"giqJo7oWqFxNKWyrgcBxAVHXnjJ1t6cGoEffce5Y1y7u649Noj5wJ4mmiUAKEVVrYAGg2KPB3Y4", false},
6161 {"cNzHY5e8vcmM3QVJUcjCyiKMYfeYvyueq5qCMV3kqcySoLyGLYUK", false},
6162 {"37uTe568EYc9WLoHEd9jXEvUiWbq5LFLscNyqvAzLU5vBArUJA6eydkLmnMwJDjkL5kXc2VK7ig", false},
6163 {"EsYbG4tWWWY45G31nox838qNdzksbPySWc", false},
6164 {"nbuzhfwMoNzA3PaFnyLcRxE9bTJPDkjZ6Rf6Y6o2ckXZfzZzXBT", false},
6165 {"cQN9PoxZeCWK1x56xnz6QYAsvR11XAce3Ehp3gMUdfSQ53Y2mPzx", false},
6166 {"1Gm3N3rkef6iMbx4voBzaxtXcmmiMTqZPhcuAepRzYUJQW4qRpEnHvMojzof42hjFRf8PE2jPde", false},
6167 {"2TAq2tuN6x6m233bpT7yqdYQPELdTDJn1eU", false},
6168 {"ntEtnnGhqPii4joABvBtSEJG6BxjT2tUZqE8PcVYgk3RHpgxgHDCQxNbLJf7ardf1dDk2oCQ7Cf", false},
6169 {"Ky1YjoZNgQ196HJV3HpdkecfhRBmRZdMJk89Hi5KGfpfPwS2bUbfd", false},
6170 {"2A1q1YsMZowabbvta7kTy2Fd6qN4r5ZCeG3qLpvZBMzCixMUdkN2Y4dHB1wPsZAeVXUGD83MfRED", false},
6171 {"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", true},
6172 {"1Ax4gZtb7gAit2TivwejZHYtNNLT18PUXJ", true},
6173 {"1C5bSj1iEGUgSTbziymG7Cn18ENQuT36vv", true},
6174 {"1Gqk4Tv79P91Cc1STQtU3s1W6277M2CVWu", true},
6175 {"1JwMWBVLtiqtscbaRHai4pqHokhFCbtoB4", true},
6176 {"19dcawoKcZdQz365WpXWMhX6QCUpR9SY4r", true},
6177 {"13p1ijLwsnrcuyqcTvJXkq2ASdXqcnEBLE", true},
6178 {"1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2", true},
6179 {"3P14159f73E4gFr7JterCCQh9QjiTjiZrG", true},
6180 {"3CMNFxN1oHBc4R1EpboAL5yzHGgE611Xou", true},
6181 {"3QjYXhTkvuj8qPaXHTTWb5wjXhdsLAAWVy", true},
6182 {"3AnNxabYGoTxYiTEZwFEnerUoeFXK2Zoks", true},
6183 {"33vt8ViH5jsr115AGkW6cEmEz9MpvJSwDk", true},
6184 {"3QCzvfL4ZRvmJFiWWBVwxfdaNBT8EtxB5y", true},
6185 {"37Sp6Rv3y4kVd1nQ1JV5pfqXccHNyZm1x3", true},
6186 {"3ALJH9Y951VCGcVZYAdpA3KchoP9McEj1G", true},
6187 {"12KYrjTdVGjFMtaxERSk3gphreJ5US8aUP", true},
6188 {"12QeMLzSrB8XH8FvEzPMVoRxVAzTr5XM2y", true},
6189 {"1oNLrsHnBcR6dpaBpwz3LSwutbUNkNSjs", true},
6190 {"1SQHtwR5oJRKLfiWQ2APsAd9miUc4k2ez", true},
6191 {"116CGDLddrZhMrTwhCVJXtXQpxygTT1kHd", true},
6192 {"3NJZLcZEEYBpxYEUGewU4knsQRn1WM5Fkt", true},
6193 }
6194
6195 for i, test := range tests {
6196
6197 errs := validate.Var(test.param, "btc_addr")
6198
6199 if test.expected {
6200 if !IsEqual(errs, nil) {
6201 t.Fatalf("Index: %d btc_addr failed with Error: %s", i, errs)
6202 }
6203 } else {
6204 if IsEqual(errs, nil) {
6205 t.Fatalf("Index: %d btc_addr failed with Error: %s", i, errs)
6206 } else {
6207 val := getError(errs, "", "")
6208 if val.Tag() != "btc_addr" {
6209 t.Fatalf("Index: %d Latitude failed with Error: %s", i, errs)
6210 }
6211 }
6212 }
6213 }
6214 }
6215
6216 func TestBitcoinBech32AddressValidation(t *testing.T) {
6217 validate := New()
6218
6219 tests := []struct {
6220 param string
6221 expected bool
6222 }{
6223 {"", false},
6224 {"bc1rw5uspcuh", false},
6225 {"bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5", false},
6226 {"BC13W508D6QEJXTDG4Y5R3ZARVARY0C5XW7KN40WF2", false},
6227 {"qw508d6qejxtdg4y5r3zarvary0c5xw7kg3g4ty", false},
6228 {"bc1rw5uspcuh", false},
6229 {"bc10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90", false},
6230 {"BC1QW508d6QEJxTDG4y5R3ZArVARY0C5XW7KV8F3T4", false},
6231 {"BC1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P", false},
6232 {"bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5", false},
6233 {"bc10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90", false},
6234 {"bc1pw508d6qejxtdg4y5r3zarqfsj6c3", false},
6235 {"bc1zw508d6qejxtdg4y5r3zarvaryvqyzf3du", false},
6236 {"bc1gmk9yu", false},
6237 {"bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv", false},
6238 {"BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4", true},
6239 {"bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx", true},
6240 {"bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3", true},
6241 {"BC1SW50QA3JX3S", true},
6242 {"bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj", true},
6243 }
6244
6245 for i, test := range tests {
6246
6247 errs := validate.Var(test.param, "btc_addr_bech32")
6248
6249 if test.expected {
6250 if !IsEqual(errs, nil) {
6251 t.Fatalf("Index: %d btc_addr_bech32 failed with Error: %s", i, errs)
6252 }
6253 } else {
6254 if IsEqual(errs, nil) {
6255 t.Fatalf("Index: %d btc_addr_bech32 failed with Error: %s", i, errs)
6256 } else {
6257 val := getError(errs, "", "")
6258 if val.Tag() != "btc_addr_bech32" {
6259 t.Fatalf("Index: %d Latitude failed with Error: %s", i, errs)
6260 }
6261 }
6262 }
6263 }
6264 }
6265
6266 func TestNoStructLevelValidation(t *testing.T) {
6267 type Inner struct {
6268 Test string `validate:"len=5"`
6269 }
6270
6271 type Outer struct {
6272 InnerStruct Inner `validate:"required,nostructlevel"`
6273 InnerStructPtr *Inner `validate:"required,nostructlevel"`
6274 }
6275
6276 outer := &Outer{
6277 InnerStructPtr: nil,
6278 InnerStruct: Inner{},
6279 }
6280
6281
6282 validate := New(WithRequiredStructEnabled())
6283
6284 errs := validate.Struct(outer)
6285 NotEqual(t, errs, nil)
6286 AssertError(t, errs, "Outer.InnerStruct", "Outer.InnerStruct", "InnerStruct", "InnerStruct", "required")
6287 AssertError(t, errs, "Outer.InnerStructPtr", "Outer.InnerStructPtr", "InnerStructPtr", "InnerStructPtr", "required")
6288
6289 inner := Inner{
6290 Test: "1234",
6291 }
6292
6293 outer = &Outer{
6294 InnerStruct: inner,
6295 InnerStructPtr: &inner,
6296 }
6297
6298 errs = validate.Struct(outer)
6299 Equal(t, errs, nil)
6300
6301
6302
6303 outer = &Outer{
6304 InnerStructPtr: nil,
6305 InnerStruct: Inner{},
6306 }
6307 validate = New()
6308
6309 errs = validate.Struct(outer)
6310 NotEqual(t, errs, nil)
6311 AssertError(t, errs, "Outer.InnerStructPtr", "Outer.InnerStructPtr", "InnerStructPtr", "InnerStructPtr", "required")
6312
6313 inner = Inner{
6314 Test: "1234",
6315 }
6316
6317 outer = &Outer{
6318 InnerStruct: inner,
6319 InnerStructPtr: &inner,
6320 }
6321
6322 errs = validate.Struct(outer)
6323 Equal(t, errs, nil)
6324 }
6325
6326 func TestStructOnlyValidation(t *testing.T) {
6327 type Inner struct {
6328 Test string `validate:"len=5"`
6329 }
6330
6331 type Outer struct {
6332 InnerStruct Inner `validate:"required,structonly"`
6333 InnerStructPtr *Inner `validate:"required,structonly"`
6334 }
6335
6336 outer := &Outer{
6337 InnerStruct: Inner{},
6338 InnerStructPtr: nil,
6339 }
6340
6341
6342 validate := New()
6343
6344 errs := validate.Struct(outer)
6345 NotEqual(t, errs, nil)
6346 AssertError(t, errs, "Outer.InnerStructPtr", "Outer.InnerStructPtr", "InnerStructPtr", "InnerStructPtr", "required")
6347
6348
6349 validate.requiredStructEnabled = true
6350
6351 errs = validate.Struct(outer)
6352 NotEqual(t, errs, nil)
6353 AssertError(t, errs, "Outer.InnerStruct", "Outer.InnerStruct", "InnerStruct", "InnerStruct", "required")
6354 AssertError(t, errs, "Outer.InnerStructPtr", "Outer.InnerStructPtr", "InnerStructPtr", "InnerStructPtr", "required")
6355
6356 inner := Inner{
6357 Test: "1234",
6358 }
6359
6360 outer = &Outer{
6361 InnerStruct: inner,
6362 InnerStructPtr: &inner,
6363 }
6364
6365 errs = validate.Struct(outer)
6366 Equal(t, errs, nil)
6367
6368
6369 type Address struct {
6370 Street string `validate:"required"`
6371 City string `validate:"required"`
6372 Planet string `validate:"required"`
6373 Phone string `validate:"required"`
6374 }
6375
6376 type User struct {
6377 FirstName string `json:"fname"`
6378 LastName string `json:"lname"`
6379 Age uint8 `validate:"gte=0,lte=130"`
6380 Number string `validate:"required,e164"`
6381 Email string `validate:"required,email"`
6382 FavouriteColor string `validate:"hexcolor|rgb|rgba"`
6383 Addresses []*Address `validate:"required"`
6384 Address Address `validate:"structonly"`
6385 }
6386
6387 address := &Address{
6388 Street: "Eavesdown Docks",
6389 Planet: "Persphone",
6390 Phone: "none",
6391 City: "Unknown",
6392 }
6393
6394 user := &User{
6395 FirstName: "",
6396 LastName: "",
6397 Age: 45,
6398 Number: "+1123456789",
6399 Email: "Badger.Smith@gmail.com",
6400 FavouriteColor: "#000",
6401 Addresses: []*Address{address},
6402 Address: Address{
6403
6404 Planet: "Persphone",
6405 Phone: "none",
6406 City: "Unknown",
6407 },
6408 }
6409
6410 errs = validate.Struct(user)
6411 Equal(t, errs, nil)
6412 }
6413
6414 func TestGtField(t *testing.T) {
6415 var errs error
6416 validate := New()
6417
6418 type TimeTest struct {
6419 Start *time.Time `validate:"required,gt"`
6420 End *time.Time `validate:"required,gt,gtfield=Start"`
6421 }
6422
6423 now := time.Now()
6424 start := now.Add(time.Hour * 24)
6425 end := start.Add(time.Hour * 24)
6426
6427 timeTest := &TimeTest{
6428 Start: &start,
6429 End: &end,
6430 }
6431
6432 errs = validate.Struct(timeTest)
6433 Equal(t, errs, nil)
6434
6435 timeTest = &TimeTest{
6436 Start: &end,
6437 End: &start,
6438 }
6439
6440 errs = validate.Struct(timeTest)
6441 NotEqual(t, errs, nil)
6442 AssertError(t, errs, "TimeTest.End", "TimeTest.End", "End", "End", "gtfield")
6443
6444 errs = validate.VarWithValue(&end, &start, "gtfield")
6445 Equal(t, errs, nil)
6446
6447 errs = validate.VarWithValue(&start, &end, "gtfield")
6448 NotEqual(t, errs, nil)
6449 AssertError(t, errs, "", "", "", "", "gtfield")
6450
6451 errs = validate.VarWithValue(&end, &start, "gtfield")
6452 Equal(t, errs, nil)
6453
6454 errs = validate.VarWithValue(&timeTest, &end, "gtfield")
6455 NotEqual(t, errs, nil)
6456
6457 errs = validate.VarWithValue("test bigger", "test", "gtfield")
6458 Equal(t, errs, nil)
6459
6460
6461
6462
6463
6464 errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "gtfield")
6465 Equal(t, errs, nil)
6466
6467 errs = validate.VarWithValue(time.Hour, time.Hour, "gtfield")
6468 NotEqual(t, errs, nil)
6469 AssertError(t, errs, "", "", "", "", "gtfield")
6470
6471 errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "gtfield")
6472 NotEqual(t, errs, nil)
6473 AssertError(t, errs, "", "", "", "", "gtfield")
6474
6475 errs = validate.VarWithValue(time.Duration(0), time.Hour, "omitempty,gtfield")
6476 Equal(t, errs, nil)
6477
6478
6479
6480 type TimeDurationTest struct {
6481 First time.Duration `validate:"gtfield=Second"`
6482 Second time.Duration
6483 }
6484 var timeDurationTest *TimeDurationTest
6485
6486 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour - time.Minute}
6487 errs = validate.Struct(timeDurationTest)
6488 Equal(t, errs, nil)
6489
6490 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour}
6491 errs = validate.Struct(timeDurationTest)
6492 NotEqual(t, errs, nil)
6493 AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "gtfield")
6494
6495 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour + time.Minute}
6496 errs = validate.Struct(timeDurationTest)
6497 NotEqual(t, errs, nil)
6498 AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "gtfield")
6499
6500 type TimeDurationOmitemptyTest struct {
6501 First time.Duration `validate:"omitempty,gtfield=Second"`
6502 Second time.Duration
6503 }
6504
6505 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0), time.Hour}
6506 errs = validate.Struct(timeDurationOmitemptyTest)
6507 Equal(t, errs, nil)
6508
6509
6510
6511 type IntTest struct {
6512 Val1 int `validate:"required"`
6513 Val2 int `validate:"required,gtfield=Val1"`
6514 }
6515
6516 intTest := &IntTest{
6517 Val1: 1,
6518 Val2: 5,
6519 }
6520
6521 errs = validate.Struct(intTest)
6522 Equal(t, errs, nil)
6523
6524 intTest = &IntTest{
6525 Val1: 5,
6526 Val2: 1,
6527 }
6528
6529 errs = validate.Struct(intTest)
6530 NotEqual(t, errs, nil)
6531 AssertError(t, errs, "IntTest.Val2", "IntTest.Val2", "Val2", "Val2", "gtfield")
6532
6533 errs = validate.VarWithValue(int(5), int(1), "gtfield")
6534 Equal(t, errs, nil)
6535
6536 errs = validate.VarWithValue(int(1), int(5), "gtfield")
6537 NotEqual(t, errs, nil)
6538 AssertError(t, errs, "", "", "", "", "gtfield")
6539
6540 type UIntTest struct {
6541 Val1 uint `validate:"required"`
6542 Val2 uint `validate:"required,gtfield=Val1"`
6543 }
6544
6545 uIntTest := &UIntTest{
6546 Val1: 1,
6547 Val2: 5,
6548 }
6549
6550 errs = validate.Struct(uIntTest)
6551 Equal(t, errs, nil)
6552
6553 uIntTest = &UIntTest{
6554 Val1: 5,
6555 Val2: 1,
6556 }
6557
6558 errs = validate.Struct(uIntTest)
6559 NotEqual(t, errs, nil)
6560 AssertError(t, errs, "UIntTest.Val2", "UIntTest.Val2", "Val2", "Val2", "gtfield")
6561
6562 errs = validate.VarWithValue(uint(5), uint(1), "gtfield")
6563 Equal(t, errs, nil)
6564
6565 errs = validate.VarWithValue(uint(1), uint(5), "gtfield")
6566 NotEqual(t, errs, nil)
6567 AssertError(t, errs, "", "", "", "", "gtfield")
6568
6569 type FloatTest struct {
6570 Val1 float64 `validate:"required"`
6571 Val2 float64 `validate:"required,gtfield=Val1"`
6572 }
6573
6574 floatTest := &FloatTest{
6575 Val1: 1,
6576 Val2: 5,
6577 }
6578
6579 errs = validate.Struct(floatTest)
6580 Equal(t, errs, nil)
6581
6582 floatTest = &FloatTest{
6583 Val1: 5,
6584 Val2: 1,
6585 }
6586
6587 errs = validate.Struct(floatTest)
6588 NotEqual(t, errs, nil)
6589 AssertError(t, errs, "FloatTest.Val2", "FloatTest.Val2", "Val2", "Val2", "gtfield")
6590
6591 errs = validate.VarWithValue(float32(5), float32(1), "gtfield")
6592 Equal(t, errs, nil)
6593
6594 errs = validate.VarWithValue(float32(1), float32(5), "gtfield")
6595 NotEqual(t, errs, nil)
6596 AssertError(t, errs, "", "", "", "", "gtfield")
6597
6598 errs = validate.VarWithValue(nil, 1, "gtfield")
6599 NotEqual(t, errs, nil)
6600 AssertError(t, errs, "", "", "", "", "gtfield")
6601
6602 errs = validate.VarWithValue(5, "T", "gtfield")
6603 NotEqual(t, errs, nil)
6604 AssertError(t, errs, "", "", "", "", "gtfield")
6605
6606 errs = validate.VarWithValue(5, start, "gtfield")
6607 NotEqual(t, errs, nil)
6608 AssertError(t, errs, "", "", "", "", "gtfield")
6609
6610 type TimeTest2 struct {
6611 Start *time.Time `validate:"required"`
6612 End *time.Time `validate:"required,gtfield=NonExistantField"`
6613 }
6614
6615 timeTest2 := &TimeTest2{
6616 Start: &start,
6617 End: &end,
6618 }
6619
6620 errs = validate.Struct(timeTest2)
6621 NotEqual(t, errs, nil)
6622 AssertError(t, errs, "TimeTest2.End", "TimeTest2.End", "End", "End", "gtfield")
6623
6624 type Other struct {
6625 Value string
6626 }
6627
6628 type Test struct {
6629 Value Other
6630 Time time.Time `validate:"gtfield=Value"`
6631 }
6632
6633 tst := Test{
6634 Value: Other{Value: "StringVal"},
6635 Time: end,
6636 }
6637
6638 errs = validate.Struct(tst)
6639 NotEqual(t, errs, nil)
6640 AssertError(t, errs, "Test.Time", "Test.Time", "Time", "Time", "gtfield")
6641 }
6642
6643 func TestLtField(t *testing.T) {
6644 var errs error
6645 validate := New()
6646
6647 type TimeTest struct {
6648 Start *time.Time `validate:"required,lt,ltfield=End"`
6649 End *time.Time `validate:"required,lt"`
6650 }
6651
6652 now := time.Now()
6653 start := now.Add(time.Hour * 24 * -1 * 2)
6654 end := start.Add(time.Hour * 24)
6655
6656 timeTest := &TimeTest{
6657 Start: &start,
6658 End: &end,
6659 }
6660
6661 errs = validate.Struct(timeTest)
6662 Equal(t, errs, nil)
6663
6664 timeTest = &TimeTest{
6665 Start: &end,
6666 End: &start,
6667 }
6668
6669 errs = validate.Struct(timeTest)
6670 NotEqual(t, errs, nil)
6671 AssertError(t, errs, "TimeTest.Start", "TimeTest.Start", "Start", "Start", "ltfield")
6672
6673 errs = validate.VarWithValue(&start, &end, "ltfield")
6674 Equal(t, errs, nil)
6675
6676 errs = validate.VarWithValue(&end, &start, "ltfield")
6677 NotEqual(t, errs, nil)
6678 AssertError(t, errs, "", "", "", "", "ltfield")
6679
6680 errs = validate.VarWithValue(&end, timeTest, "ltfield")
6681 NotEqual(t, errs, nil)
6682 AssertError(t, errs, "", "", "", "", "ltfield")
6683
6684 errs = validate.VarWithValue("tes", "test", "ltfield")
6685 Equal(t, errs, nil)
6686
6687
6688
6689
6690
6691 errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "ltfield")
6692 Equal(t, errs, nil)
6693
6694 errs = validate.VarWithValue(time.Hour, time.Hour, "ltfield")
6695 NotEqual(t, errs, nil)
6696 AssertError(t, errs, "", "", "", "", "ltfield")
6697
6698 errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "ltfield")
6699 NotEqual(t, errs, nil)
6700 AssertError(t, errs, "", "", "", "", "ltfield")
6701
6702 errs = validate.VarWithValue(time.Duration(0), -time.Minute, "omitempty,ltfield")
6703 Equal(t, errs, nil)
6704
6705
6706
6707 type TimeDurationTest struct {
6708 First time.Duration `validate:"ltfield=Second"`
6709 Second time.Duration
6710 }
6711 var timeDurationTest *TimeDurationTest
6712
6713 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour + time.Minute}
6714 errs = validate.Struct(timeDurationTest)
6715 Equal(t, errs, nil)
6716
6717 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour}
6718 errs = validate.Struct(timeDurationTest)
6719 NotEqual(t, errs, nil)
6720 AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "ltfield")
6721
6722 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour - time.Minute}
6723 errs = validate.Struct(timeDurationTest)
6724 NotEqual(t, errs, nil)
6725 AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "ltfield")
6726
6727 type TimeDurationOmitemptyTest struct {
6728 First time.Duration `validate:"omitempty,ltfield=Second"`
6729 Second time.Duration
6730 }
6731
6732 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0), -time.Minute}
6733 errs = validate.Struct(timeDurationOmitemptyTest)
6734 Equal(t, errs, nil)
6735
6736
6737
6738 type IntTest struct {
6739 Val1 int `validate:"required"`
6740 Val2 int `validate:"required,ltfield=Val1"`
6741 }
6742
6743 intTest := &IntTest{
6744 Val1: 5,
6745 Val2: 1,
6746 }
6747
6748 errs = validate.Struct(intTest)
6749 Equal(t, errs, nil)
6750
6751 intTest = &IntTest{
6752 Val1: 1,
6753 Val2: 5,
6754 }
6755
6756 errs = validate.Struct(intTest)
6757 NotEqual(t, errs, nil)
6758 AssertError(t, errs, "IntTest.Val2", "IntTest.Val2", "Val2", "Val2", "ltfield")
6759
6760 errs = validate.VarWithValue(int(1), int(5), "ltfield")
6761 Equal(t, errs, nil)
6762
6763 errs = validate.VarWithValue(int(5), int(1), "ltfield")
6764 NotEqual(t, errs, nil)
6765 AssertError(t, errs, "", "", "", "", "ltfield")
6766
6767 type UIntTest struct {
6768 Val1 uint `validate:"required"`
6769 Val2 uint `validate:"required,ltfield=Val1"`
6770 }
6771
6772 uIntTest := &UIntTest{
6773 Val1: 5,
6774 Val2: 1,
6775 }
6776
6777 errs = validate.Struct(uIntTest)
6778 Equal(t, errs, nil)
6779
6780 uIntTest = &UIntTest{
6781 Val1: 1,
6782 Val2: 5,
6783 }
6784
6785 errs = validate.Struct(uIntTest)
6786 NotEqual(t, errs, nil)
6787 AssertError(t, errs, "UIntTest.Val2", "UIntTest.Val2", "Val2", "Val2", "ltfield")
6788
6789 errs = validate.VarWithValue(uint(1), uint(5), "ltfield")
6790 Equal(t, errs, nil)
6791
6792 errs = validate.VarWithValue(uint(5), uint(1), "ltfield")
6793 NotEqual(t, errs, nil)
6794 AssertError(t, errs, "", "", "", "", "ltfield")
6795
6796 type FloatTest struct {
6797 Val1 float64 `validate:"required"`
6798 Val2 float64 `validate:"required,ltfield=Val1"`
6799 }
6800
6801 floatTest := &FloatTest{
6802 Val1: 5,
6803 Val2: 1,
6804 }
6805
6806 errs = validate.Struct(floatTest)
6807 Equal(t, errs, nil)
6808
6809 floatTest = &FloatTest{
6810 Val1: 1,
6811 Val2: 5,
6812 }
6813
6814 errs = validate.Struct(floatTest)
6815 NotEqual(t, errs, nil)
6816 AssertError(t, errs, "FloatTest.Val2", "FloatTest.Val2", "Val2", "Val2", "ltfield")
6817
6818 errs = validate.VarWithValue(float32(1), float32(5), "ltfield")
6819 Equal(t, errs, nil)
6820
6821 errs = validate.VarWithValue(float32(5), float32(1), "ltfield")
6822 NotEqual(t, errs, nil)
6823 AssertError(t, errs, "", "", "", "", "ltfield")
6824
6825 errs = validate.VarWithValue(nil, 5, "ltfield")
6826 NotEqual(t, errs, nil)
6827 AssertError(t, errs, "", "", "", "", "ltfield")
6828
6829 errs = validate.VarWithValue(1, "T", "ltfield")
6830 NotEqual(t, errs, nil)
6831 AssertError(t, errs, "", "", "", "", "ltfield")
6832
6833 errs = validate.VarWithValue(1, end, "ltfield")
6834 NotEqual(t, errs, nil)
6835 AssertError(t, errs, "", "", "", "", "ltfield")
6836
6837 type TimeTest2 struct {
6838 Start *time.Time `validate:"required"`
6839 End *time.Time `validate:"required,ltfield=NonExistantField"`
6840 }
6841
6842 timeTest2 := &TimeTest2{
6843 Start: &end,
6844 End: &start,
6845 }
6846
6847 errs = validate.Struct(timeTest2)
6848 NotEqual(t, errs, nil)
6849 AssertError(t, errs, "TimeTest2.End", "TimeTest2.End", "End", "End", "ltfield")
6850 }
6851
6852 func TestFieldContains(t *testing.T) {
6853 validate := New()
6854
6855 type StringTest struct {
6856 Foo string `validate:"fieldcontains=Bar"`
6857 Bar string
6858 }
6859
6860 stringTest := &StringTest{
6861 Foo: "foobar",
6862 Bar: "bar",
6863 }
6864
6865 errs := validate.Struct(stringTest)
6866 Equal(t, errs, nil)
6867
6868 stringTest = &StringTest{
6869 Foo: "foo",
6870 Bar: "bar",
6871 }
6872
6873 errs = validate.Struct(stringTest)
6874 NotEqual(t, errs, nil)
6875 AssertError(t, errs, "StringTest.Foo", "StringTest.Foo", "Foo", "Foo", "fieldcontains")
6876
6877 errs = validate.VarWithValue("foo", "bar", "fieldcontains")
6878 NotEqual(t, errs, nil)
6879 AssertError(t, errs, "", "", "", "", "fieldcontains")
6880
6881 errs = validate.VarWithValue("bar", "foobarfoo", "fieldcontains")
6882 NotEqual(t, errs, nil)
6883 AssertError(t, errs, "", "", "", "", "fieldcontains")
6884
6885 errs = validate.VarWithValue("foobarfoo", "bar", "fieldcontains")
6886 Equal(t, errs, nil)
6887
6888 type StringTestMissingField struct {
6889 Foo string `validate:"fieldcontains=Bar"`
6890 }
6891
6892 stringTestMissingField := &StringTestMissingField{
6893 Foo: "foo",
6894 }
6895
6896 errs = validate.Struct(stringTestMissingField)
6897 NotEqual(t, errs, nil)
6898 AssertError(t, errs, "StringTestMissingField.Foo", "StringTestMissingField.Foo", "Foo", "Foo", "fieldcontains")
6899 }
6900
6901 func TestFieldExcludes(t *testing.T) {
6902 validate := New()
6903
6904 type StringTest struct {
6905 Foo string `validate:"fieldexcludes=Bar"`
6906 Bar string
6907 }
6908
6909 stringTest := &StringTest{
6910 Foo: "foobar",
6911 Bar: "bar",
6912 }
6913
6914 errs := validate.Struct(stringTest)
6915 NotEqual(t, errs, nil)
6916 AssertError(t, errs, "StringTest.Foo", "StringTest.Foo", "Foo", "Foo", "fieldexcludes")
6917
6918 stringTest = &StringTest{
6919 Foo: "foo",
6920 Bar: "bar",
6921 }
6922
6923 errs = validate.Struct(stringTest)
6924 Equal(t, errs, nil)
6925
6926 errs = validate.VarWithValue("foo", "bar", "fieldexcludes")
6927 Equal(t, errs, nil)
6928
6929 errs = validate.VarWithValue("bar", "foobarfoo", "fieldexcludes")
6930 Equal(t, errs, nil)
6931
6932 errs = validate.VarWithValue("foobarfoo", "bar", "fieldexcludes")
6933 NotEqual(t, errs, nil)
6934 AssertError(t, errs, "", "", "", "", "fieldexcludes")
6935
6936 type StringTestMissingField struct {
6937 Foo string `validate:"fieldexcludes=Bar"`
6938 }
6939
6940 stringTestMissingField := &StringTestMissingField{
6941 Foo: "foo",
6942 }
6943
6944 errs = validate.Struct(stringTestMissingField)
6945 Equal(t, errs, nil)
6946 }
6947
6948 func TestContainsAndExcludes(t *testing.T) {
6949 validate := New()
6950
6951 type ImpossibleStringTest struct {
6952 Foo string `validate:"fieldcontains=Bar"`
6953 Bar string `validate:"fieldexcludes=Foo"`
6954 }
6955
6956 impossibleStringTest := &ImpossibleStringTest{
6957 Foo: "foo",
6958 Bar: "bar",
6959 }
6960
6961 errs := validate.Struct(impossibleStringTest)
6962 NotEqual(t, errs, nil)
6963 AssertError(t, errs, "ImpossibleStringTest.Foo", "ImpossibleStringTest.Foo", "Foo", "Foo", "fieldcontains")
6964
6965 impossibleStringTest = &ImpossibleStringTest{
6966 Foo: "bar",
6967 Bar: "foo",
6968 }
6969
6970 errs = validate.Struct(impossibleStringTest)
6971 NotEqual(t, errs, nil)
6972 AssertError(t, errs, "ImpossibleStringTest.Foo", "ImpossibleStringTest.Foo", "Foo", "Foo", "fieldcontains")
6973 }
6974
6975 func TestLteField(t *testing.T) {
6976 var errs error
6977 validate := New()
6978
6979 type TimeTest struct {
6980 Start *time.Time `validate:"required,lte,ltefield=End"`
6981 End *time.Time `validate:"required,lte"`
6982 }
6983
6984 now := time.Now()
6985 start := now.Add(time.Hour * 24 * -1 * 2)
6986 end := start.Add(time.Hour * 24)
6987
6988 timeTest := &TimeTest{
6989 Start: &start,
6990 End: &end,
6991 }
6992
6993 errs = validate.Struct(timeTest)
6994 Equal(t, errs, nil)
6995
6996 timeTest = &TimeTest{
6997 Start: &end,
6998 End: &start,
6999 }
7000
7001 errs = validate.Struct(timeTest)
7002 NotEqual(t, errs, nil)
7003 AssertError(t, errs, "TimeTest.Start", "TimeTest.Start", "Start", "Start", "ltefield")
7004
7005 errs = validate.VarWithValue(&start, &end, "ltefield")
7006 Equal(t, errs, nil)
7007
7008 errs = validate.VarWithValue(&end, &start, "ltefield")
7009 NotEqual(t, errs, nil)
7010 AssertError(t, errs, "", "", "", "", "ltefield")
7011
7012 errs = validate.VarWithValue(&end, timeTest, "ltefield")
7013 NotEqual(t, errs, nil)
7014 AssertError(t, errs, "", "", "", "", "ltefield")
7015
7016 errs = validate.VarWithValue("tes", "test", "ltefield")
7017 Equal(t, errs, nil)
7018
7019 errs = validate.VarWithValue("test", "test", "ltefield")
7020 Equal(t, errs, nil)
7021
7022
7023
7024
7025
7026 errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "ltefield")
7027 Equal(t, errs, nil)
7028
7029 errs = validate.VarWithValue(time.Hour, time.Hour, "ltefield")
7030 Equal(t, errs, nil)
7031
7032 errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "ltefield")
7033 NotEqual(t, errs, nil)
7034 AssertError(t, errs, "", "", "", "", "ltefield")
7035
7036 errs = validate.VarWithValue(time.Duration(0), -time.Minute, "omitempty,ltefield")
7037 Equal(t, errs, nil)
7038
7039
7040
7041 type TimeDurationTest struct {
7042 First time.Duration `validate:"ltefield=Second"`
7043 Second time.Duration
7044 }
7045 var timeDurationTest *TimeDurationTest
7046
7047 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour + time.Minute}
7048 errs = validate.Struct(timeDurationTest)
7049 Equal(t, errs, nil)
7050
7051 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour}
7052 errs = validate.Struct(timeDurationTest)
7053 Equal(t, errs, nil)
7054
7055 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour - time.Minute}
7056 errs = validate.Struct(timeDurationTest)
7057 NotEqual(t, errs, nil)
7058 AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "ltefield")
7059
7060 type TimeDurationOmitemptyTest struct {
7061 First time.Duration `validate:"omitempty,ltefield=Second"`
7062 Second time.Duration
7063 }
7064
7065 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0), -time.Minute}
7066 errs = validate.Struct(timeDurationOmitemptyTest)
7067 Equal(t, errs, nil)
7068
7069
7070
7071 type IntTest struct {
7072 Val1 int `validate:"required"`
7073 Val2 int `validate:"required,ltefield=Val1"`
7074 }
7075
7076 intTest := &IntTest{
7077 Val1: 5,
7078 Val2: 1,
7079 }
7080
7081 errs = validate.Struct(intTest)
7082 Equal(t, errs, nil)
7083
7084 intTest = &IntTest{
7085 Val1: 1,
7086 Val2: 5,
7087 }
7088
7089 errs = validate.Struct(intTest)
7090 NotEqual(t, errs, nil)
7091 AssertError(t, errs, "IntTest.Val2", "IntTest.Val2", "Val2", "Val2", "ltefield")
7092
7093 errs = validate.VarWithValue(int(1), int(5), "ltefield")
7094 Equal(t, errs, nil)
7095
7096 errs = validate.VarWithValue(int(5), int(1), "ltefield")
7097 NotEqual(t, errs, nil)
7098 AssertError(t, errs, "", "", "", "", "ltefield")
7099
7100 type UIntTest struct {
7101 Val1 uint `validate:"required"`
7102 Val2 uint `validate:"required,ltefield=Val1"`
7103 }
7104
7105 uIntTest := &UIntTest{
7106 Val1: 5,
7107 Val2: 1,
7108 }
7109
7110 errs = validate.Struct(uIntTest)
7111 Equal(t, errs, nil)
7112
7113 uIntTest = &UIntTest{
7114 Val1: 1,
7115 Val2: 5,
7116 }
7117
7118 errs = validate.Struct(uIntTest)
7119 NotEqual(t, errs, nil)
7120 AssertError(t, errs, "UIntTest.Val2", "UIntTest.Val2", "Val2", "Val2", "ltefield")
7121
7122 errs = validate.VarWithValue(uint(1), uint(5), "ltefield")
7123 Equal(t, errs, nil)
7124
7125 errs = validate.VarWithValue(uint(5), uint(1), "ltefield")
7126 NotEqual(t, errs, nil)
7127 AssertError(t, errs, "", "", "", "", "ltefield")
7128
7129 type FloatTest struct {
7130 Val1 float64 `validate:"required"`
7131 Val2 float64 `validate:"required,ltefield=Val1"`
7132 }
7133
7134 floatTest := &FloatTest{
7135 Val1: 5,
7136 Val2: 1,
7137 }
7138
7139 errs = validate.Struct(floatTest)
7140 Equal(t, errs, nil)
7141
7142 floatTest = &FloatTest{
7143 Val1: 1,
7144 Val2: 5,
7145 }
7146
7147 errs = validate.Struct(floatTest)
7148 NotEqual(t, errs, nil)
7149 AssertError(t, errs, "FloatTest.Val2", "FloatTest.Val2", "Val2", "Val2", "ltefield")
7150
7151 errs = validate.VarWithValue(float32(1), float32(5), "ltefield")
7152 Equal(t, errs, nil)
7153
7154 errs = validate.VarWithValue(float32(5), float32(1), "ltefield")
7155 NotEqual(t, errs, nil)
7156 AssertError(t, errs, "", "", "", "", "ltefield")
7157
7158 errs = validate.VarWithValue(nil, 5, "ltefield")
7159 NotEqual(t, errs, nil)
7160 AssertError(t, errs, "", "", "", "", "ltefield")
7161
7162 errs = validate.VarWithValue(1, "T", "ltefield")
7163 NotEqual(t, errs, nil)
7164 AssertError(t, errs, "", "", "", "", "ltefield")
7165
7166 errs = validate.VarWithValue(1, end, "ltefield")
7167 NotEqual(t, errs, nil)
7168 AssertError(t, errs, "", "", "", "", "ltefield")
7169
7170 type TimeTest2 struct {
7171 Start *time.Time `validate:"required"`
7172 End *time.Time `validate:"required,ltefield=NonExistantField"`
7173 }
7174
7175 timeTest2 := &TimeTest2{
7176 Start: &end,
7177 End: &start,
7178 }
7179
7180 errs = validate.Struct(timeTest2)
7181 NotEqual(t, errs, nil)
7182 AssertError(t, errs, "TimeTest2.End", "TimeTest2.End", "End", "End", "ltefield")
7183 }
7184
7185 func TestGteField(t *testing.T) {
7186 var errs error
7187 validate := New()
7188
7189 type TimeTest struct {
7190 Start *time.Time `validate:"required,gte"`
7191 End *time.Time `validate:"required,gte,gtefield=Start"`
7192 }
7193
7194 now := time.Now()
7195 start := now.Add(time.Hour * 24)
7196 end := start.Add(time.Hour * 24)
7197
7198 timeTest := &TimeTest{
7199 Start: &start,
7200 End: &end,
7201 }
7202
7203 errs = validate.Struct(timeTest)
7204 Equal(t, errs, nil)
7205
7206 timeTest = &TimeTest{
7207 Start: &end,
7208 End: &start,
7209 }
7210
7211 errs = validate.Struct(timeTest)
7212 NotEqual(t, errs, nil)
7213 AssertError(t, errs, "TimeTest.End", "TimeTest.End", "End", "End", "gtefield")
7214
7215 errs = validate.VarWithValue(&end, &start, "gtefield")
7216 Equal(t, errs, nil)
7217
7218 errs = validate.VarWithValue(&start, &end, "gtefield")
7219 NotEqual(t, errs, nil)
7220 AssertError(t, errs, "", "", "", "", "gtefield")
7221
7222 errs = validate.VarWithValue(&start, timeTest, "gtefield")
7223 NotEqual(t, errs, nil)
7224 AssertError(t, errs, "", "", "", "", "gtefield")
7225
7226 errs = validate.VarWithValue("test", "test", "gtefield")
7227 Equal(t, errs, nil)
7228
7229 errs = validate.VarWithValue("test bigger", "test", "gtefield")
7230 Equal(t, errs, nil)
7231
7232
7233
7234
7235
7236 errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "gtefield")
7237 Equal(t, errs, nil)
7238
7239 errs = validate.VarWithValue(time.Hour, time.Hour, "gtefield")
7240 Equal(t, errs, nil)
7241
7242 errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "gtefield")
7243 NotEqual(t, errs, nil)
7244 AssertError(t, errs, "", "", "", "", "gtefield")
7245
7246 errs = validate.VarWithValue(time.Duration(0), time.Hour, "omitempty,gtefield")
7247 Equal(t, errs, nil)
7248
7249
7250
7251 type TimeDurationTest struct {
7252 First time.Duration `validate:"gtefield=Second"`
7253 Second time.Duration
7254 }
7255 var timeDurationTest *TimeDurationTest
7256
7257 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour - time.Minute}
7258 errs = validate.Struct(timeDurationTest)
7259 Equal(t, errs, nil)
7260
7261 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour}
7262 errs = validate.Struct(timeDurationTest)
7263 Equal(t, errs, nil)
7264
7265 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour + time.Minute}
7266 errs = validate.Struct(timeDurationTest)
7267 NotEqual(t, errs, nil)
7268 AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "gtefield")
7269
7270 type TimeDurationOmitemptyTest struct {
7271 First time.Duration `validate:"omitempty,gtefield=Second"`
7272 Second time.Duration
7273 }
7274
7275 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0), time.Hour}
7276 errs = validate.Struct(timeDurationOmitemptyTest)
7277 Equal(t, errs, nil)
7278
7279
7280
7281 type IntTest struct {
7282 Val1 int `validate:"required"`
7283 Val2 int `validate:"required,gtefield=Val1"`
7284 }
7285
7286 intTest := &IntTest{
7287 Val1: 1,
7288 Val2: 5,
7289 }
7290
7291 errs = validate.Struct(intTest)
7292 Equal(t, errs, nil)
7293
7294 intTest = &IntTest{
7295 Val1: 5,
7296 Val2: 1,
7297 }
7298
7299 errs = validate.Struct(intTest)
7300 NotEqual(t, errs, nil)
7301 AssertError(t, errs, "IntTest.Val2", "IntTest.Val2", "Val2", "Val2", "gtefield")
7302
7303 errs = validate.VarWithValue(int(5), int(1), "gtefield")
7304 Equal(t, errs, nil)
7305
7306 errs = validate.VarWithValue(int(1), int(5), "gtefield")
7307 NotEqual(t, errs, nil)
7308 AssertError(t, errs, "", "", "", "", "gtefield")
7309
7310 type UIntTest struct {
7311 Val1 uint `validate:"required"`
7312 Val2 uint `validate:"required,gtefield=Val1"`
7313 }
7314
7315 uIntTest := &UIntTest{
7316 Val1: 1,
7317 Val2: 5,
7318 }
7319
7320 errs = validate.Struct(uIntTest)
7321 Equal(t, errs, nil)
7322
7323 uIntTest = &UIntTest{
7324 Val1: 5,
7325 Val2: 1,
7326 }
7327
7328 errs = validate.Struct(uIntTest)
7329 NotEqual(t, errs, nil)
7330 AssertError(t, errs, "UIntTest.Val2", "UIntTest.Val2", "Val2", "Val2", "gtefield")
7331
7332 errs = validate.VarWithValue(uint(5), uint(1), "gtefield")
7333 Equal(t, errs, nil)
7334
7335 errs = validate.VarWithValue(uint(1), uint(5), "gtefield")
7336 NotEqual(t, errs, nil)
7337 AssertError(t, errs, "", "", "", "", "gtefield")
7338
7339 type FloatTest struct {
7340 Val1 float64 `validate:"required"`
7341 Val2 float64 `validate:"required,gtefield=Val1"`
7342 }
7343
7344 floatTest := &FloatTest{
7345 Val1: 1,
7346 Val2: 5,
7347 }
7348
7349 errs = validate.Struct(floatTest)
7350 Equal(t, errs, nil)
7351
7352 floatTest = &FloatTest{
7353 Val1: 5,
7354 Val2: 1,
7355 }
7356
7357 errs = validate.Struct(floatTest)
7358 NotEqual(t, errs, nil)
7359 AssertError(t, errs, "FloatTest.Val2", "FloatTest.Val2", "Val2", "Val2", "gtefield")
7360
7361 errs = validate.VarWithValue(float32(5), float32(1), "gtefield")
7362 Equal(t, errs, nil)
7363
7364 errs = validate.VarWithValue(float32(1), float32(5), "gtefield")
7365 NotEqual(t, errs, nil)
7366 AssertError(t, errs, "", "", "", "", "gtefield")
7367
7368 errs = validate.VarWithValue(nil, 1, "gtefield")
7369 NotEqual(t, errs, nil)
7370 AssertError(t, errs, "", "", "", "", "gtefield")
7371
7372 errs = validate.VarWithValue(5, "T", "gtefield")
7373 NotEqual(t, errs, nil)
7374 AssertError(t, errs, "", "", "", "", "gtefield")
7375
7376 errs = validate.VarWithValue(5, start, "gtefield")
7377 NotEqual(t, errs, nil)
7378 AssertError(t, errs, "", "", "", "", "gtefield")
7379
7380 type TimeTest2 struct {
7381 Start *time.Time `validate:"required"`
7382 End *time.Time `validate:"required,gtefield=NonExistantField"`
7383 }
7384
7385 timeTest2 := &TimeTest2{
7386 Start: &start,
7387 End: &end,
7388 }
7389
7390 errs = validate.Struct(timeTest2)
7391 NotEqual(t, errs, nil)
7392 AssertError(t, errs, "TimeTest2.End", "TimeTest2.End", "End", "End", "gtefield")
7393 }
7394
7395 func TestValidateByTagAndValue(t *testing.T) {
7396 validate := New()
7397
7398 val := "test"
7399 field := "test"
7400 errs := validate.VarWithValue(val, field, "required")
7401 Equal(t, errs, nil)
7402
7403 fn := func(fl FieldLevel) bool {
7404 return fl.Parent().String() == fl.Field().String()
7405 }
7406
7407 errs = validate.RegisterValidation("isequaltestfunc", fn)
7408 Equal(t, errs, nil)
7409
7410 errs = validate.VarWithValue(val, field, "isequaltestfunc")
7411 Equal(t, errs, nil)
7412
7413 val = "unequal"
7414
7415 errs = validate.VarWithValue(val, field, "isequaltestfunc")
7416 NotEqual(t, errs, nil)
7417 AssertError(t, errs, "", "", "", "", "isequaltestfunc")
7418 }
7419
7420 func TestAddFunctions(t *testing.T) {
7421 fn := func(fl FieldLevel) bool {
7422 return true
7423 }
7424
7425 fnCtx := func(ctx context.Context, fl FieldLevel) bool {
7426 return true
7427 }
7428
7429 validate := New()
7430
7431 errs := validate.RegisterValidation("new", fn)
7432 Equal(t, errs, nil)
7433
7434 errs = validate.RegisterValidation("", fn)
7435 NotEqual(t, errs, nil)
7436
7437 errs = validate.RegisterValidation("new", nil)
7438 NotEqual(t, errs, nil)
7439
7440 errs = validate.RegisterValidation("new", fn)
7441 Equal(t, errs, nil)
7442
7443 errs = validate.RegisterValidationCtx("new", fnCtx)
7444 Equal(t, errs, nil)
7445
7446 PanicMatches(t, func() { _ = validate.RegisterValidation("dive", fn) }, "Tag 'dive' either contains restricted characters or is the same as a restricted tag needed for normal operation")
7447 }
7448
7449 func TestChangeTag(t *testing.T) {
7450 validate := New()
7451 validate.SetTagName("val")
7452
7453 type Test struct {
7454 Name string `val:"len=4"`
7455 }
7456 s := &Test{
7457 Name: "TEST",
7458 }
7459
7460 errs := validate.Struct(s)
7461 Equal(t, errs, nil)
7462
7463 s.Name = ""
7464
7465 errs = validate.Struct(s)
7466 NotEqual(t, errs, nil)
7467 AssertError(t, errs, "Test.Name", "Test.Name", "Name", "Name", "len")
7468 }
7469
7470 func TestUnexposedStruct(t *testing.T) {
7471 validate := New()
7472
7473 type Test struct {
7474 Name string
7475 unexposed struct {
7476 A string `validate:"required"`
7477 }
7478 }
7479
7480 s := &Test{
7481 Name: "TEST",
7482 }
7483 Equal(t, s.unexposed.A, "")
7484
7485 errs := validate.Struct(s)
7486 Equal(t, errs, nil)
7487 }
7488
7489 func TestBadParams(t *testing.T) {
7490 validate := New()
7491 i := 1
7492 errs := validate.Var(i, "-")
7493 Equal(t, errs, nil)
7494
7495 PanicMatches(t, func() { _ = validate.Var(i, "len=a") }, "strconv.ParseInt: parsing \"a\": invalid syntax")
7496 PanicMatches(t, func() { _ = validate.Var(i, "len=a") }, "strconv.ParseInt: parsing \"a\": invalid syntax")
7497
7498 var ui uint = 1
7499 PanicMatches(t, func() { _ = validate.Var(ui, "len=a") }, "strconv.ParseUint: parsing \"a\": invalid syntax")
7500
7501 f := 1.23
7502 PanicMatches(t, func() { _ = validate.Var(f, "len=a") }, "strconv.ParseFloat: parsing \"a\": invalid syntax")
7503 }
7504
7505 func TestLength(t *testing.T) {
7506 validate := New()
7507 i := true
7508 PanicMatches(t, func() { _ = validate.Var(i, "len") }, "Bad field type bool")
7509 }
7510
7511 func TestIsGt(t *testing.T) {
7512 var errs error
7513 validate := New()
7514
7515 myMap := map[string]string{}
7516 errs = validate.Var(myMap, "gt=0")
7517 NotEqual(t, errs, nil)
7518
7519 f := 1.23
7520 errs = validate.Var(f, "gt=5")
7521 NotEqual(t, errs, nil)
7522 AssertError(t, errs, "", "", "", "", "gt")
7523
7524 var ui uint = 5
7525 errs = validate.Var(ui, "gt=10")
7526 NotEqual(t, errs, nil)
7527 AssertError(t, errs, "", "", "", "", "gt")
7528
7529 i := true
7530 PanicMatches(t, func() { _ = validate.Var(i, "gt") }, "Bad field type bool")
7531
7532 tm := time.Now().UTC()
7533 tm = tm.Add(time.Hour * 24)
7534
7535 errs = validate.Var(tm, "gt")
7536 Equal(t, errs, nil)
7537
7538 t2 := time.Now().UTC().Add(-time.Hour)
7539
7540 errs = validate.Var(t2, "gt")
7541 NotEqual(t, errs, nil)
7542 AssertError(t, errs, "", "", "", "", "gt")
7543
7544 type Test struct {
7545 Now *time.Time `validate:"gt"`
7546 }
7547 s := &Test{
7548 Now: &tm,
7549 }
7550
7551 errs = validate.Struct(s)
7552 Equal(t, errs, nil)
7553
7554 s = &Test{
7555 Now: &t2,
7556 }
7557
7558 errs = validate.Struct(s)
7559 NotEqual(t, errs, nil)
7560 AssertError(t, errs, "Test.Now", "Test.Now", "Now", "Now", "gt")
7561
7562
7563
7564
7565
7566 errs = validate.Var(time.Hour, "gt=59m")
7567 Equal(t, errs, nil)
7568
7569 errs = validate.Var(time.Hour-time.Minute, "gt=59m")
7570 NotEqual(t, errs, nil)
7571 AssertError(t, errs, "", "", "", "", "gt")
7572
7573 errs = validate.Var(time.Hour-2*time.Minute, "gt=59m")
7574 NotEqual(t, errs, nil)
7575 AssertError(t, errs, "", "", "", "", "gt")
7576
7577 errs = validate.Var(time.Duration(0), "omitempty,gt=59m")
7578 Equal(t, errs, nil)
7579
7580
7581
7582 type TimeDurationTest struct {
7583 Duration time.Duration `validate:"gt=59m"`
7584 }
7585 var timeDurationTest *TimeDurationTest
7586
7587 timeDurationTest = &TimeDurationTest{time.Hour}
7588 errs = validate.Struct(timeDurationTest)
7589 Equal(t, errs, nil)
7590
7591 timeDurationTest = &TimeDurationTest{time.Hour - time.Minute}
7592 errs = validate.Struct(timeDurationTest)
7593 NotEqual(t, errs, nil)
7594 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "gt")
7595
7596 timeDurationTest = &TimeDurationTest{time.Hour - 2*time.Minute}
7597 errs = validate.Struct(timeDurationTest)
7598 NotEqual(t, errs, nil)
7599 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "gt")
7600
7601 type TimeDurationOmitemptyTest struct {
7602 Duration time.Duration `validate:"omitempty,gt=59m"`
7603 }
7604
7605 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
7606 errs = validate.Struct(timeDurationOmitemptyTest)
7607 Equal(t, errs, nil)
7608 }
7609
7610 func TestIsGte(t *testing.T) {
7611 var errs error
7612 validate := New()
7613
7614 i := true
7615 PanicMatches(t, func() { _ = validate.Var(i, "gte") }, "Bad field type bool")
7616
7617 t1 := time.Now().UTC()
7618 t1 = t1.Add(time.Hour * 24)
7619
7620 errs = validate.Var(t1, "gte")
7621 Equal(t, errs, nil)
7622
7623 t2 := time.Now().UTC().Add(-time.Hour)
7624
7625 errs = validate.Var(t2, "gte")
7626 NotEqual(t, errs, nil)
7627 AssertError(t, errs, "", "", "", "", "gte")
7628
7629 type Test struct {
7630 Now *time.Time `validate:"gte"`
7631 }
7632 s := &Test{
7633 Now: &t1,
7634 }
7635
7636 errs = validate.Struct(s)
7637 Equal(t, errs, nil)
7638
7639 s = &Test{
7640 Now: &t2,
7641 }
7642
7643 errs = validate.Struct(s)
7644 NotEqual(t, errs, nil)
7645 AssertError(t, errs, "Test.Now", "Test.Now", "Now", "Now", "gte")
7646
7647
7648
7649
7650
7651 errs = validate.Var(time.Hour, "gte=59m")
7652 Equal(t, errs, nil)
7653
7654 errs = validate.Var(time.Hour-time.Minute, "gte=59m")
7655 Equal(t, errs, nil)
7656
7657 errs = validate.Var(time.Hour-2*time.Minute, "gte=59m")
7658 NotEqual(t, errs, nil)
7659 AssertError(t, errs, "", "", "", "", "gte")
7660
7661 errs = validate.Var(time.Duration(0), "omitempty,gte=59m")
7662 Equal(t, errs, nil)
7663
7664
7665
7666 type TimeDurationTest struct {
7667 Duration time.Duration `validate:"gte=59m"`
7668 }
7669 var timeDurationTest *TimeDurationTest
7670
7671 timeDurationTest = &TimeDurationTest{time.Hour}
7672 errs = validate.Struct(timeDurationTest)
7673 Equal(t, errs, nil)
7674
7675 timeDurationTest = &TimeDurationTest{time.Hour - time.Minute}
7676 errs = validate.Struct(timeDurationTest)
7677 Equal(t, errs, nil)
7678
7679 timeDurationTest = &TimeDurationTest{time.Hour - 2*time.Minute}
7680 errs = validate.Struct(timeDurationTest)
7681 NotEqual(t, errs, nil)
7682 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "gte")
7683
7684 type TimeDurationOmitemptyTest struct {
7685 Duration time.Duration `validate:"omitempty,gte=59m"`
7686 }
7687
7688 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
7689 errs = validate.Struct(timeDurationOmitemptyTest)
7690 Equal(t, errs, nil)
7691 }
7692
7693 func TestMinValidation(t *testing.T) {
7694 var errs error
7695 validate := New()
7696
7697
7698
7699
7700
7701 errs = validate.Var(time.Hour, "min=59m")
7702 Equal(t, errs, nil)
7703
7704 errs = validate.Var(time.Hour-time.Minute, "min=59m")
7705 Equal(t, errs, nil)
7706
7707 errs = validate.Var(time.Hour-2*time.Minute, "min=59m")
7708 NotEqual(t, errs, nil)
7709 AssertError(t, errs, "", "", "", "", "min")
7710
7711 errs = validate.Var(time.Duration(0), "omitempty,min=59m")
7712 Equal(t, errs, nil)
7713
7714
7715
7716 type TimeDurationTest struct {
7717 Duration time.Duration `validate:"min=59m"`
7718 }
7719 var timeDurationTest *TimeDurationTest
7720
7721 timeDurationTest = &TimeDurationTest{time.Hour}
7722 errs = validate.Struct(timeDurationTest)
7723 Equal(t, errs, nil)
7724
7725 timeDurationTest = &TimeDurationTest{time.Hour - time.Minute}
7726 errs = validate.Struct(timeDurationTest)
7727 Equal(t, errs, nil)
7728
7729 timeDurationTest = &TimeDurationTest{time.Hour - 2*time.Minute}
7730 errs = validate.Struct(timeDurationTest)
7731 NotEqual(t, errs, nil)
7732 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "min")
7733
7734 type TimeDurationOmitemptyTest struct {
7735 Duration time.Duration `validate:"omitempty,min=59m"`
7736 }
7737
7738 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
7739 errs = validate.Struct(timeDurationOmitemptyTest)
7740 Equal(t, errs, nil)
7741 }
7742
7743 func TestMaxValidation(t *testing.T) {
7744 var errs error
7745 validate := New()
7746
7747
7748
7749
7750
7751 errs = validate.Var(time.Hour, "max=1h1m")
7752 Equal(t, errs, nil)
7753
7754 errs = validate.Var(time.Hour+time.Minute, "max=1h1m")
7755 Equal(t, errs, nil)
7756
7757 errs = validate.Var(time.Hour+2*time.Minute, "max=1h1m")
7758 NotEqual(t, errs, nil)
7759 AssertError(t, errs, "", "", "", "", "max")
7760
7761 errs = validate.Var(time.Duration(0), "omitempty,max=-1s")
7762 Equal(t, errs, nil)
7763
7764
7765
7766 type TimeDurationTest struct {
7767 Duration time.Duration `validate:"max=1h1m"`
7768 }
7769 var timeDurationTest *TimeDurationTest
7770
7771 timeDurationTest = &TimeDurationTest{time.Hour}
7772 errs = validate.Struct(timeDurationTest)
7773 Equal(t, errs, nil)
7774
7775 timeDurationTest = &TimeDurationTest{time.Hour + time.Minute}
7776 errs = validate.Struct(timeDurationTest)
7777 Equal(t, errs, nil)
7778
7779 timeDurationTest = &TimeDurationTest{time.Hour + 2*time.Minute}
7780 errs = validate.Struct(timeDurationTest)
7781 NotEqual(t, errs, nil)
7782 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "max")
7783
7784 type TimeDurationOmitemptyTest struct {
7785 Duration time.Duration `validate:"omitempty,max=-1s"`
7786 }
7787
7788 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
7789 errs = validate.Struct(timeDurationOmitemptyTest)
7790 Equal(t, errs, nil)
7791 }
7792
7793 func TestMinMaxValidation(t *testing.T) {
7794 var errs error
7795 validate := New()
7796
7797
7798
7799
7800
7801 errs = validate.Var(time.Hour, "min=59m,max=1h1m")
7802 Equal(t, errs, nil)
7803
7804 errs = validate.Var(time.Hour-time.Minute, "min=59m,max=1h1m")
7805 Equal(t, errs, nil)
7806
7807 errs = validate.Var(time.Hour+time.Minute, "min=59m,max=1h1m")
7808 Equal(t, errs, nil)
7809
7810 errs = validate.Var(time.Hour-2*time.Minute, "min=59m,max=1h1m")
7811 NotEqual(t, errs, nil)
7812 AssertError(t, errs, "", "", "", "", "min")
7813
7814 errs = validate.Var(time.Hour+2*time.Minute, "min=59m,max=1h1m")
7815 NotEqual(t, errs, nil)
7816 AssertError(t, errs, "", "", "", "", "max")
7817
7818 errs = validate.Var(time.Duration(0), "omitempty,min=59m,max=1h1m")
7819 Equal(t, errs, nil)
7820
7821
7822
7823 type TimeDurationTest struct {
7824 Duration time.Duration `validate:"min=59m,max=1h1m"`
7825 }
7826 var timeDurationTest *TimeDurationTest
7827
7828 timeDurationTest = &TimeDurationTest{time.Hour}
7829 errs = validate.Struct(timeDurationTest)
7830 Equal(t, errs, nil)
7831
7832 timeDurationTest = &TimeDurationTest{time.Hour - time.Minute}
7833 errs = validate.Struct(timeDurationTest)
7834 Equal(t, errs, nil)
7835
7836 timeDurationTest = &TimeDurationTest{time.Hour + time.Minute}
7837 errs = validate.Struct(timeDurationTest)
7838 Equal(t, errs, nil)
7839
7840 timeDurationTest = &TimeDurationTest{time.Hour - 2*time.Minute}
7841 errs = validate.Struct(timeDurationTest)
7842 NotEqual(t, errs, nil)
7843 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "min")
7844
7845 timeDurationTest = &TimeDurationTest{time.Hour + 2*time.Minute}
7846 errs = validate.Struct(timeDurationTest)
7847 NotEqual(t, errs, nil)
7848 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "max")
7849
7850 type TimeDurationOmitemptyTest struct {
7851 Duration time.Duration `validate:"omitempty,min=59m,max=1h1m"`
7852 }
7853
7854 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
7855 errs = validate.Struct(timeDurationOmitemptyTest)
7856 Equal(t, errs, nil)
7857 }
7858
7859 func TestLenValidation(t *testing.T) {
7860 var errs error
7861 validate := New()
7862
7863
7864
7865
7866
7867 errs = validate.Var(time.Hour, "len=1h")
7868 Equal(t, errs, nil)
7869
7870 errs = validate.Var(time.Hour-time.Minute, "len=1h")
7871 NotEqual(t, errs, nil)
7872 AssertError(t, errs, "", "", "", "", "len")
7873
7874 errs = validate.Var(time.Hour+time.Minute, "len=1h")
7875 NotEqual(t, errs, nil)
7876 AssertError(t, errs, "", "", "", "", "len")
7877
7878 errs = validate.Var(time.Duration(0), "omitempty,len=1h")
7879 Equal(t, errs, nil)
7880
7881
7882
7883 type TimeDurationTest struct {
7884 Duration time.Duration `validate:"len=1h"`
7885 }
7886 var timeDurationTest *TimeDurationTest
7887
7888 timeDurationTest = &TimeDurationTest{time.Hour}
7889 errs = validate.Struct(timeDurationTest)
7890 Equal(t, errs, nil)
7891
7892 timeDurationTest = &TimeDurationTest{time.Hour - time.Minute}
7893 errs = validate.Struct(timeDurationTest)
7894 NotEqual(t, errs, nil)
7895 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "len")
7896
7897 timeDurationTest = &TimeDurationTest{time.Hour + time.Minute}
7898 errs = validate.Struct(timeDurationTest)
7899 NotEqual(t, errs, nil)
7900 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "len")
7901
7902 type TimeDurationOmitemptyTest struct {
7903 Duration time.Duration `validate:"omitempty,len=1h"`
7904 }
7905
7906 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
7907 errs = validate.Struct(timeDurationOmitemptyTest)
7908 Equal(t, errs, nil)
7909 }
7910
7911 func TestIsLt(t *testing.T) {
7912 var errs error
7913 validate := New()
7914
7915 myMap := map[string]string{}
7916 errs = validate.Var(myMap, "lt=0")
7917 NotEqual(t, errs, nil)
7918 AssertError(t, errs, "", "", "", "", "lt")
7919
7920 f := 1.23
7921 errs = validate.Var(f, "lt=0")
7922 NotEqual(t, errs, nil)
7923 AssertError(t, errs, "", "", "", "", "lt")
7924
7925 var ui uint = 5
7926 errs = validate.Var(ui, "lt=0")
7927 NotEqual(t, errs, nil)
7928 AssertError(t, errs, "", "", "", "", "lt")
7929
7930 i := true
7931 PanicMatches(t, func() { _ = validate.Var(i, "lt") }, "Bad field type bool")
7932
7933 t1 := time.Now().UTC().Add(-time.Hour)
7934
7935 errs = validate.Var(t1, "lt")
7936 Equal(t, errs, nil)
7937
7938 t2 := time.Now().UTC()
7939 t2 = t2.Add(time.Hour * 24)
7940
7941 errs = validate.Var(t2, "lt")
7942 NotEqual(t, errs, nil)
7943 AssertError(t, errs, "", "", "", "", "lt")
7944
7945 type Test struct {
7946 Now *time.Time `validate:"lt"`
7947 }
7948
7949 s := &Test{
7950 Now: &t1,
7951 }
7952
7953 errs = validate.Struct(s)
7954 Equal(t, errs, nil)
7955
7956 s = &Test{
7957 Now: &t2,
7958 }
7959
7960 errs = validate.Struct(s)
7961 NotEqual(t, errs, nil)
7962 AssertError(t, errs, "Test.Now", "Test.Now", "Now", "Now", "lt")
7963
7964
7965
7966
7967
7968 errs = validate.Var(time.Hour, "lt=1h1m")
7969 Equal(t, errs, nil)
7970
7971 errs = validate.Var(time.Hour+time.Minute, "lt=1h1m")
7972 NotEqual(t, errs, nil)
7973 AssertError(t, errs, "", "", "", "", "lt")
7974
7975 errs = validate.Var(time.Hour+2*time.Minute, "lt=1h1m")
7976 NotEqual(t, errs, nil)
7977 AssertError(t, errs, "", "", "", "", "lt")
7978
7979 errs = validate.Var(time.Duration(0), "omitempty,lt=0")
7980 Equal(t, errs, nil)
7981
7982
7983
7984 type TimeDurationTest struct {
7985 Duration time.Duration `validate:"lt=1h1m"`
7986 }
7987 var timeDurationTest *TimeDurationTest
7988
7989 timeDurationTest = &TimeDurationTest{time.Hour}
7990 errs = validate.Struct(timeDurationTest)
7991 Equal(t, errs, nil)
7992
7993 timeDurationTest = &TimeDurationTest{time.Hour + time.Minute}
7994 errs = validate.Struct(timeDurationTest)
7995 NotEqual(t, errs, nil)
7996 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "lt")
7997
7998 timeDurationTest = &TimeDurationTest{time.Hour + 2*time.Minute}
7999 errs = validate.Struct(timeDurationTest)
8000 NotEqual(t, errs, nil)
8001 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "lt")
8002
8003 type TimeDurationOmitemptyTest struct {
8004 Duration time.Duration `validate:"omitempty,lt=0"`
8005 }
8006
8007 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
8008 errs = validate.Struct(timeDurationOmitemptyTest)
8009 Equal(t, errs, nil)
8010 }
8011
8012 func TestIsLte(t *testing.T) {
8013 var errs error
8014 validate := New()
8015
8016 i := true
8017 PanicMatches(t, func() { _ = validate.Var(i, "lte") }, "Bad field type bool")
8018
8019 t1 := time.Now().UTC().Add(-time.Hour)
8020
8021 errs = validate.Var(t1, "lte")
8022 Equal(t, errs, nil)
8023
8024 t2 := time.Now().UTC()
8025 t2 = t2.Add(time.Hour * 24)
8026
8027 errs = validate.Var(t2, "lte")
8028 NotEqual(t, errs, nil)
8029 AssertError(t, errs, "", "", "", "", "lte")
8030
8031 type Test struct {
8032 Now *time.Time `validate:"lte"`
8033 }
8034
8035 s := &Test{
8036 Now: &t1,
8037 }
8038
8039 errs = validate.Struct(s)
8040 Equal(t, errs, nil)
8041
8042 s = &Test{
8043 Now: &t2,
8044 }
8045
8046 errs = validate.Struct(s)
8047 NotEqual(t, errs, nil)
8048
8049
8050
8051
8052
8053 errs = validate.Var(time.Hour, "lte=1h1m")
8054 Equal(t, errs, nil)
8055
8056 errs = validate.Var(time.Hour+time.Minute, "lte=1h1m")
8057 Equal(t, errs, nil)
8058
8059 errs = validate.Var(time.Hour+2*time.Minute, "lte=1h1m")
8060 NotEqual(t, errs, nil)
8061 AssertError(t, errs, "", "", "", "", "lte")
8062
8063 errs = validate.Var(time.Duration(0), "omitempty,lte=-1s")
8064 Equal(t, errs, nil)
8065
8066
8067
8068 type TimeDurationTest struct {
8069 Duration time.Duration `validate:"lte=1h1m"`
8070 }
8071 var timeDurationTest *TimeDurationTest
8072
8073 timeDurationTest = &TimeDurationTest{time.Hour}
8074 errs = validate.Struct(timeDurationTest)
8075 Equal(t, errs, nil)
8076
8077 timeDurationTest = &TimeDurationTest{time.Hour + time.Minute}
8078 errs = validate.Struct(timeDurationTest)
8079 Equal(t, errs, nil)
8080
8081 timeDurationTest = &TimeDurationTest{time.Hour + 2*time.Minute}
8082 errs = validate.Struct(timeDurationTest)
8083 NotEqual(t, errs, nil)
8084 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "lte")
8085
8086 type TimeDurationOmitemptyTest struct {
8087 Duration time.Duration `validate:"omitempty,lte=-1s"`
8088 }
8089
8090 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
8091 errs = validate.Struct(timeDurationOmitemptyTest)
8092 Equal(t, errs, nil)
8093 }
8094
8095 func TestUrnRFC2141(t *testing.T) {
8096 tests := []struct {
8097 param string
8098 expected bool
8099 }{
8100 {"urn:a:b", true},
8101 {"urn:a::", true},
8102 {"urn:a:-", true},
8103 {"URN:simple:simple", true},
8104 {"urn:urna:simple", true},
8105 {"urn:burnout:nss", true},
8106 {"urn:burn:nss", true},
8107 {"urn:urnurnurn:x", true},
8108 {"urn:abcdefghilmnopqrstuvzabcdefghilm:x", true},
8109 {"URN:123:x", true},
8110 {"URN:abcd-:x", true},
8111 {"URN:abcd-abcd:x", true},
8112 {"urn:urnx:urn", true},
8113 {"urn:ciao:a:b:c", true},
8114 {"urn:aaa:x:y:", true},
8115 {"urn:ciao:-", true},
8116 {"urn:colon:::::nss", true},
8117 {"urn:ciao:@!=%2C(xyz)+a,b.*@g=$_'", true},
8118 {"URN:hexes:%25", true},
8119 {"URN:x:abc%1Dz%2F%3az", true},
8120 {"URN:foo:a123,456", true},
8121 {"urn:foo:a123,456", true},
8122 {"urn:FOO:a123,456", true},
8123 {"urn:foo:A123,456", true},
8124 {"urn:foo:a123%2C456", true},
8125 {"URN:FOO:a123%2c456", true},
8126 {"URN:FOO:ABC%FFabc123%2c456", true},
8127 {"URN:FOO:ABC%FFabc123%2C456%9A", true},
8128 {"urn:ietf:params:scim:schemas:core:2.0:User", true},
8129 {"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:meta.lastModified", true},
8130 {"URN:-xxx:x", false},
8131 {"urn::colon:nss", false},
8132 {"urn:abcdefghilmnopqrstuvzabcdefghilmn:specificstring", false},
8133 {"URN:a!?:x", false},
8134 {"URN:#,:x", false},
8135 {"urn:urn:NSS", false},
8136 {"urn:URN:NSS", false},
8137 {"urn:white space:NSS", false},
8138 {"urn:concat:no spaces", false},
8139 {"urn:a:%", false},
8140 {"urn:", false},
8141 }
8142
8143 tag := "urn_rfc2141"
8144
8145 validate := New()
8146
8147 for i, test := range tests {
8148
8149 errs := validate.Var(test.param, tag)
8150
8151 if test.expected {
8152 if !IsEqual(errs, nil) {
8153 t.Fatalf("Index: %d URN failed Error: %s", i, errs)
8154 }
8155 } else {
8156 if IsEqual(errs, nil) {
8157 t.Fatalf("Index: %d URN failed Error: %s", i, errs)
8158 } else {
8159 val := getError(errs, "", "")
8160 if val.Tag() != tag {
8161 t.Fatalf("Index: %d URN failed Error: %s", i, errs)
8162 }
8163 }
8164 }
8165 }
8166
8167 i := 1
8168 PanicMatches(t, func() { _ = validate.Var(i, tag) }, "Bad field type int")
8169 }
8170
8171 func TestUrl(t *testing.T) {
8172 tests := []struct {
8173 param string
8174 expected bool
8175 }{
8176 {"http://foo.bar#com", true},
8177 {"http://foobar.com", true},
8178 {"https://foobar.com", true},
8179 {"foobar.com", false},
8180 {"http://foobar.coffee/", true},
8181 {"http://foobar.中文网/", true},
8182 {"http://foobar.org/", true},
8183 {"http://foobar.org:8080/", true},
8184 {"ftp://foobar.ru/", true},
8185 {"http://user:pass@www.foobar.com/", true},
8186 {"http://127.0.0.1/", true},
8187 {"http://duckduckgo.com/?q=%2F", true},
8188 {"http://localhost:3000/", true},
8189 {"http://foobar.com/?foo=bar#baz=qux", true},
8190 {"http://foobar.com?foo=bar", true},
8191 {"http://www.xn--froschgrn-x9a.net/", true},
8192 {"", false},
8193 {"xyz://foobar.com", true},
8194 {"invalid.", false},
8195 {".com", false},
8196 {"rtmp://foobar.com", true},
8197 {"http://www.foo_bar.com/", true},
8198 {"http://localhost:3000/", true},
8199 {"http://foobar.com/#baz", true},
8200 {"http://foobar.com#baz=qux", true},
8201 {"http://foobar.com/t$-_.+!*\\'(),", true},
8202 {"http://www.foobar.com/~foobar", true},
8203 {"http://www.-foobar.com/", true},
8204 {"http://www.foo---bar.com/", true},
8205 {"mailto:someone@example.com", true},
8206 {"irc://irc.server.org/channel", true},
8207 {"irc://#channel@network", true},
8208 {"/abs/test/dir", false},
8209 {"./rel/test/dir", false},
8210 {"irc:", false},
8211 {"http://", false},
8212 {"file://path/to/file.txt", true},
8213 {"file:///c:/Windows/file.txt", true},
8214 {"file://localhost/path/to/file.txt", true},
8215 {"file://localhost/c:/WINDOWS/file.txt", true},
8216 {"file://", true},
8217 {"file:////remotehost/path/file.txt", true},
8218 }
8219
8220 validate := New()
8221
8222 for i, test := range tests {
8223
8224 errs := validate.Var(test.param, "url")
8225
8226 if test.expected {
8227 if !IsEqual(errs, nil) {
8228 t.Fatalf("Index: %d URL failed Error: %s", i, errs)
8229 }
8230 } else {
8231 if IsEqual(errs, nil) {
8232 t.Fatalf("Index: %d URL failed Error: %s", i, errs)
8233 } else {
8234 val := getError(errs, "", "")
8235 if val.Tag() != "url" {
8236 t.Fatalf("Index: %d URL failed Error: %s", i, errs)
8237 }
8238 }
8239 }
8240 }
8241
8242 i := 1
8243 PanicMatches(t, func() { _ = validate.Var(i, "url") }, "Bad field type int")
8244 }
8245
8246 func TestHttpUrl(t *testing.T) {
8247 tests := []struct {
8248 param string
8249 expected bool
8250 }{
8251 {"http://foo.bar#com", true},
8252 {"http://foobar.com", true},
8253 {"HTTP://foobar.com", true},
8254 {"https://foobar.com", true},
8255 {"foobar.com", false},
8256 {"http://foobar.coffee/", true},
8257 {"http://foobar.中文网/", true},
8258 {"http://foobar.org/", true},
8259 {"http://foobar.org:8080/", true},
8260 {"ftp://foobar.ru/", false},
8261 {"file:///etc/passwd", false},
8262 {"file://C:/windows/win.ini", false},
8263 {"http://user:pass@www.foobar.com/", true},
8264 {"http://127.0.0.1/", true},
8265 {"http://duckduckgo.com/?q=%2F", true},
8266 {"http://localhost:3000/", true},
8267 {"http://foobar.com/?foo=bar#baz=qux", true},
8268 {"http://foobar.com?foo=bar", true},
8269 {"http://www.xn--froschgrn-x9a.net/", true},
8270 {"", false},
8271 {"a://b", false},
8272 {"xyz://foobar.com", false},
8273 {"invalid.", false},
8274 {".com", false},
8275 {"rtmp://foobar.com", false},
8276 {"http://www.foo_bar.com/", true},
8277 {"http://localhost:3000/", true},
8278 {"http://foobar.com/#baz", true},
8279 {"http://foobar.com#baz=qux", true},
8280 {"http://foobar.com/t$-_.+!*\\'(),", true},
8281 {"http://www.foobar.com/~foobar", true},
8282 {"http://www.-foobar.com/", true},
8283 {"http://www.foo---bar.com/", true},
8284 {"mailto:someone@example.com", false},
8285 {"irc://irc.server.org/channel", false},
8286 {"irc://#channel@network", false},
8287 {"/abs/test/dir", false},
8288 {"./rel/test/dir", false},
8289 {"http:", false},
8290 {"http://", false},
8291 {"http://#invalid", false},
8292 {"https://1.1.1.1", true},
8293 }
8294
8295 validate := New()
8296
8297 for i, test := range tests {
8298
8299 errs := validate.Var(test.param, "http_url")
8300
8301 if test.expected {
8302 if !IsEqual(errs, nil) {
8303 t.Fatalf("Index: %d HTTP URL failed Error: %s", i, errs)
8304 }
8305 } else {
8306 if IsEqual(errs, nil) {
8307 t.Fatalf("Index: %d HTTP URL failed Error: %s", i, errs)
8308 } else {
8309 val := getError(errs, "", "")
8310 if val.Tag() != "http_url" {
8311 t.Fatalf("Index: %d HTTP URL failed Error: %s", i, errs)
8312 }
8313 }
8314 }
8315 }
8316
8317 i := 1
8318 PanicMatches(t, func() { _ = validate.Var(i, "http_url") }, "Bad field type int")
8319 }
8320
8321 func TestUri(t *testing.T) {
8322 tests := []struct {
8323 param string
8324 expected bool
8325 }{
8326 {"http://foo.bar#com", true},
8327 {"http://foobar.com", true},
8328 {"https://foobar.com", true},
8329 {"foobar.com", false},
8330 {"http://foobar.coffee/", true},
8331 {"http://foobar.中文网/", true},
8332 {"http://foobar.org/", true},
8333 {"http://foobar.org:8080/", true},
8334 {"ftp://foobar.ru/", true},
8335 {"http://user:pass@www.foobar.com/", true},
8336 {"http://127.0.0.1/", true},
8337 {"http://duckduckgo.com/?q=%2F", true},
8338 {"http://localhost:3000/", true},
8339 {"http://foobar.com/?foo=bar#baz=qux", true},
8340 {"http://foobar.com?foo=bar", true},
8341 {"http://www.xn--froschgrn-x9a.net/", true},
8342 {"", false},
8343 {"xyz://foobar.com", true},
8344 {"invalid.", false},
8345 {".com", false},
8346 {"rtmp://foobar.com", true},
8347 {"http://www.foo_bar.com/", true},
8348 {"http://localhost:3000/", true},
8349 {"http://foobar.com#baz=qux", true},
8350 {"http://foobar.com/t$-_.+!*\\'(),", true},
8351 {"http://www.foobar.com/~foobar", true},
8352 {"http://www.-foobar.com/", true},
8353 {"http://www.foo---bar.com/", true},
8354 {"mailto:someone@example.com", true},
8355 {"irc://irc.server.org/channel", true},
8356 {"irc://#channel@network", true},
8357 {"/abs/test/dir", true},
8358 {"./rel/test/dir", false},
8359 }
8360
8361 validate := New()
8362
8363 for i, test := range tests {
8364
8365 errs := validate.Var(test.param, "uri")
8366
8367 if test.expected {
8368 if !IsEqual(errs, nil) {
8369 t.Fatalf("Index: %d URI failed Error: %s", i, errs)
8370 }
8371 } else {
8372 if IsEqual(errs, nil) {
8373 t.Fatalf("Index: %d URI failed Error: %s", i, errs)
8374 } else {
8375 val := getError(errs, "", "")
8376 if val.Tag() != "uri" {
8377 t.Fatalf("Index: %d URI failed Error: %s", i, errs)
8378 }
8379 }
8380 }
8381 }
8382
8383 i := 1
8384 PanicMatches(t, func() { _ = validate.Var(i, "uri") }, "Bad field type int")
8385 }
8386
8387 func TestOrTag(t *testing.T) {
8388 validate := New()
8389
8390 s := "rgba(0,31,255,0.5)"
8391 errs := validate.Var(s, "rgb|rgba")
8392 Equal(t, errs, nil)
8393
8394 s = "rgba(0,31,255,0.5)"
8395 errs = validate.Var(s, "rgb|rgba|len=18")
8396 Equal(t, errs, nil)
8397
8398 s = "this ain't right"
8399 errs = validate.Var(s, "rgb|rgba")
8400 NotEqual(t, errs, nil)
8401 AssertError(t, errs, "", "", "", "", "rgb|rgba")
8402
8403 s = "this ain't right"
8404 errs = validate.Var(s, "rgb|rgba|len=10")
8405 NotEqual(t, errs, nil)
8406 AssertError(t, errs, "", "", "", "", "rgb|rgba|len=10")
8407
8408 s = "this is right"
8409 errs = validate.Var(s, "rgb|rgba|len=13")
8410 Equal(t, errs, nil)
8411
8412 s = ""
8413 errs = validate.Var(s, "omitempty,rgb|rgba")
8414 Equal(t, errs, nil)
8415
8416 s = "green"
8417 errs = validate.Var(s, "eq=|eq=blue,rgb|rgba")
8418 NotEqual(t, errs, nil)
8419 ve := errs.(ValidationErrors)
8420 Equal(t, len(ve), 1)
8421 Equal(t, ve[0].Tag(), "eq=|eq=blue")
8422
8423 s = "this is right, but a blank or isn't"
8424
8425 PanicMatches(t, func() { _ = validate.Var(s, "rgb||len=13") }, "Invalid validation tag on field ''")
8426 PanicMatches(t, func() { _ = validate.Var(s, "rgb|rgbaa|len=13") }, "Undefined validation function 'rgbaa' on field ''")
8427
8428 v2 := New()
8429 v2.RegisterTagNameFunc(func(fld reflect.StructField) string {
8430 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
8431
8432 if name == "-" {
8433 return ""
8434 }
8435
8436 return name
8437 })
8438
8439 type Colors struct {
8440 Fav string `validate:"rgb|rgba" json:"fc"`
8441 }
8442
8443 c := Colors{Fav: "this ain't right"}
8444
8445 err := v2.Struct(c)
8446 NotEqual(t, err, nil)
8447
8448 errs = err.(ValidationErrors)
8449 fe := getError(errs, "Colors.fc", "Colors.Fav")
8450 NotEqual(t, fe, nil)
8451 }
8452
8453 func TestHsla(t *testing.T) {
8454 validate := New()
8455
8456 s := "hsla(360,100%,100%,1)"
8457 errs := validate.Var(s, "hsla")
8458 Equal(t, errs, nil)
8459
8460 s = "hsla(360,100%,100%,0.5)"
8461 errs = validate.Var(s, "hsla")
8462 Equal(t, errs, nil)
8463
8464 s = "hsla(0,0%,0%, 0)"
8465 errs = validate.Var(s, "hsla")
8466 Equal(t, errs, nil)
8467
8468 s = "hsl(361,100%,50%,1)"
8469 errs = validate.Var(s, "hsla")
8470 NotEqual(t, errs, nil)
8471 AssertError(t, errs, "", "", "", "", "hsla")
8472
8473 s = "hsl(361,100%,50%)"
8474 errs = validate.Var(s, "hsla")
8475 NotEqual(t, errs, nil)
8476 AssertError(t, errs, "", "", "", "", "hsla")
8477
8478 s = "hsla(361,100%,50%)"
8479 errs = validate.Var(s, "hsla")
8480 NotEqual(t, errs, nil)
8481 AssertError(t, errs, "", "", "", "", "hsla")
8482
8483 s = "hsla(360,101%,50%)"
8484 errs = validate.Var(s, "hsla")
8485 NotEqual(t, errs, nil)
8486 AssertError(t, errs, "", "", "", "", "hsla")
8487
8488 s = "hsla(360,100%,101%)"
8489 errs = validate.Var(s, "hsla")
8490 NotEqual(t, errs, nil)
8491 AssertError(t, errs, "", "", "", "", "hsla")
8492
8493 i := 1
8494 errs = validate.Var(i, "hsla")
8495 NotEqual(t, errs, nil)
8496 AssertError(t, errs, "", "", "", "", "hsla")
8497 }
8498
8499 func TestHsl(t *testing.T) {
8500 validate := New()
8501
8502 s := "hsl(360,100%,50%)"
8503 errs := validate.Var(s, "hsl")
8504 Equal(t, errs, nil)
8505
8506 s = "hsl(0,0%,0%)"
8507 errs = validate.Var(s, "hsl")
8508 Equal(t, errs, nil)
8509
8510 s = "hsl(361,100%,50%)"
8511 errs = validate.Var(s, "hsl")
8512 NotEqual(t, errs, nil)
8513 AssertError(t, errs, "", "", "", "", "hsl")
8514
8515 s = "hsl(361,101%,50%)"
8516 errs = validate.Var(s, "hsl")
8517 NotEqual(t, errs, nil)
8518 AssertError(t, errs, "", "", "", "", "hsl")
8519
8520 s = "hsl(361,100%,101%)"
8521 errs = validate.Var(s, "hsl")
8522 NotEqual(t, errs, nil)
8523 AssertError(t, errs, "", "", "", "", "hsl")
8524
8525 s = "hsl(-10,100%,100%)"
8526 errs = validate.Var(s, "hsl")
8527 NotEqual(t, errs, nil)
8528 AssertError(t, errs, "", "", "", "", "hsl")
8529
8530 i := 1
8531 errs = validate.Var(i, "hsl")
8532 NotEqual(t, errs, nil)
8533 AssertError(t, errs, "", "", "", "", "hsl")
8534 }
8535
8536 func TestRgba(t *testing.T) {
8537 validate := New()
8538
8539 s := "rgba(0,31,255,0.5)"
8540 errs := validate.Var(s, "rgba")
8541 Equal(t, errs, nil)
8542
8543 s = "rgba(0,31,255,0.12)"
8544 errs = validate.Var(s, "rgba")
8545 Equal(t, errs, nil)
8546
8547 s = "rgba(12%,55%,100%,0.12)"
8548 errs = validate.Var(s, "rgba")
8549 Equal(t, errs, nil)
8550
8551 s = "rgba( 0, 31, 255, 0.5)"
8552 errs = validate.Var(s, "rgba")
8553 Equal(t, errs, nil)
8554
8555 s = "rgba(12%,55,100%,0.12)"
8556 errs = validate.Var(s, "rgba")
8557 NotEqual(t, errs, nil)
8558 AssertError(t, errs, "", "", "", "", "rgba")
8559
8560 s = "rgb(0, 31, 255)"
8561 errs = validate.Var(s, "rgba")
8562 NotEqual(t, errs, nil)
8563 AssertError(t, errs, "", "", "", "", "rgba")
8564
8565 s = "rgb(1,349,275,0.5)"
8566 errs = validate.Var(s, "rgba")
8567 NotEqual(t, errs, nil)
8568 AssertError(t, errs, "", "", "", "", "rgba")
8569
8570 s = "rgb(01,31,255,0.5)"
8571 errs = validate.Var(s, "rgba")
8572 NotEqual(t, errs, nil)
8573 AssertError(t, errs, "", "", "", "", "rgba")
8574
8575 i := 1
8576 errs = validate.Var(i, "rgba")
8577 NotEqual(t, errs, nil)
8578 AssertError(t, errs, "", "", "", "", "rgba")
8579 }
8580
8581 func TestRgb(t *testing.T) {
8582 validate := New()
8583
8584 s := "rgb(0,31,255)"
8585 errs := validate.Var(s, "rgb")
8586 Equal(t, errs, nil)
8587
8588 s = "rgb(0, 31, 255)"
8589 errs = validate.Var(s, "rgb")
8590 Equal(t, errs, nil)
8591
8592 s = "rgb(10%, 50%, 100%)"
8593 errs = validate.Var(s, "rgb")
8594 Equal(t, errs, nil)
8595
8596 s = "rgb(10%, 50%, 55)"
8597 errs = validate.Var(s, "rgb")
8598 NotEqual(t, errs, nil)
8599 AssertError(t, errs, "", "", "", "", "rgb")
8600
8601 s = "rgb(1,349,275)"
8602 errs = validate.Var(s, "rgb")
8603 NotEqual(t, errs, nil)
8604 AssertError(t, errs, "", "", "", "", "rgb")
8605
8606 s = "rgb(01,31,255)"
8607 errs = validate.Var(s, "rgb")
8608 NotEqual(t, errs, nil)
8609 AssertError(t, errs, "", "", "", "", "rgb")
8610
8611 s = "rgba(0,31,255)"
8612 errs = validate.Var(s, "rgb")
8613 NotEqual(t, errs, nil)
8614 AssertError(t, errs, "", "", "", "", "rgb")
8615
8616 i := 1
8617 errs = validate.Var(i, "rgb")
8618 NotEqual(t, errs, nil)
8619 AssertError(t, errs, "", "", "", "", "rgb")
8620 }
8621
8622 func TestEmail(t *testing.T) {
8623 validate := New()
8624
8625 s := "test@mail.com"
8626 errs := validate.Var(s, "email")
8627 Equal(t, errs, nil)
8628
8629 s = "Dörte@Sörensen.example.com"
8630 errs = validate.Var(s, "email")
8631 Equal(t, errs, nil)
8632
8633 s = "θσερ@εχαμπλε.ψομ"
8634 errs = validate.Var(s, "email")
8635 Equal(t, errs, nil)
8636
8637 s = "юзер@екзампл.ком"
8638 errs = validate.Var(s, "email")
8639 Equal(t, errs, nil)
8640
8641 s = "उपयोगकर्ता@उदाहरण.कॉम"
8642 errs = validate.Var(s, "email")
8643 Equal(t, errs, nil)
8644
8645 s = "用户@例子.广告"
8646 errs = validate.Var(s, "email")
8647 Equal(t, errs, nil)
8648
8649 s = "mail@domain_with_underscores.org"
8650 errs = validate.Var(s, "email")
8651 NotEqual(t, errs, nil)
8652 AssertError(t, errs, "", "", "", "", "email")
8653
8654 s = ""
8655 errs = validate.Var(s, "email")
8656 NotEqual(t, errs, nil)
8657 AssertError(t, errs, "", "", "", "", "email")
8658
8659 s = "test@email"
8660 errs = validate.Var(s, "email")
8661 NotEqual(t, errs, nil)
8662 AssertError(t, errs, "", "", "", "", "email")
8663
8664 s = "test@email."
8665 errs = validate.Var(s, "email")
8666 NotEqual(t, errs, nil)
8667 AssertError(t, errs, "", "", "", "", "email")
8668
8669 s = "@email.com"
8670 errs = validate.Var(s, "email")
8671 NotEqual(t, errs, nil)
8672 AssertError(t, errs, "", "", "", "", "email")
8673
8674 s = `"test test"@email.com`
8675 errs = validate.Var(s, "email")
8676 Equal(t, errs, nil)
8677
8678 s = `"@email.com`
8679 errs = validate.Var(s, "email")
8680 NotEqual(t, errs, nil)
8681 AssertError(t, errs, "", "", "", "", "email")
8682
8683 i := true
8684 errs = validate.Var(i, "email")
8685 NotEqual(t, errs, nil)
8686 AssertError(t, errs, "", "", "", "", "email")
8687 }
8688
8689 func TestHexColor(t *testing.T) {
8690 validate := New()
8691
8692 s := "#fff"
8693 errs := validate.Var(s, "hexcolor")
8694 Equal(t, errs, nil)
8695
8696 s = "#c2c2c2"
8697 errs = validate.Var(s, "hexcolor")
8698 Equal(t, errs, nil)
8699
8700 s = "fff"
8701 errs = validate.Var(s, "hexcolor")
8702 NotEqual(t, errs, nil)
8703 AssertError(t, errs, "", "", "", "", "hexcolor")
8704
8705 s = "fffFF"
8706 errs = validate.Var(s, "hexcolor")
8707 NotEqual(t, errs, nil)
8708 AssertError(t, errs, "", "", "", "", "hexcolor")
8709
8710 i := true
8711 errs = validate.Var(i, "hexcolor")
8712 NotEqual(t, errs, nil)
8713 AssertError(t, errs, "", "", "", "", "hexcolor")
8714 }
8715
8716 func TestHexadecimal(t *testing.T) {
8717 validate := New()
8718
8719 s := "ff0044"
8720 errs := validate.Var(s, "hexadecimal")
8721 Equal(t, errs, nil)
8722
8723 s = "0xff0044"
8724 errs = validate.Var(s, "hexadecimal")
8725 Equal(t, errs, nil)
8726
8727 s = "0Xff0044"
8728 errs = validate.Var(s, "hexadecimal")
8729 Equal(t, errs, nil)
8730
8731 s = "abcdefg"
8732 errs = validate.Var(s, "hexadecimal")
8733 NotEqual(t, errs, nil)
8734 AssertError(t, errs, "", "", "", "", "hexadecimal")
8735
8736 i := true
8737 errs = validate.Var(i, "hexadecimal")
8738 NotEqual(t, errs, nil)
8739 AssertError(t, errs, "", "", "", "", "hexadecimal")
8740 }
8741
8742 func TestNumber(t *testing.T) {
8743 validate := New()
8744
8745 s := "1"
8746 errs := validate.Var(s, "number")
8747 Equal(t, errs, nil)
8748
8749 s = "+1"
8750 errs = validate.Var(s, "number")
8751 NotEqual(t, errs, nil)
8752 AssertError(t, errs, "", "", "", "", "number")
8753
8754 s = "-1"
8755 errs = validate.Var(s, "number")
8756 NotEqual(t, errs, nil)
8757 AssertError(t, errs, "", "", "", "", "number")
8758
8759 s = "1.12"
8760 errs = validate.Var(s, "number")
8761 NotEqual(t, errs, nil)
8762 AssertError(t, errs, "", "", "", "", "number")
8763
8764 s = "+1.12"
8765 errs = validate.Var(s, "number")
8766 NotEqual(t, errs, nil)
8767 AssertError(t, errs, "", "", "", "", "number")
8768
8769 s = "-1.12"
8770 errs = validate.Var(s, "number")
8771 NotEqual(t, errs, nil)
8772 AssertError(t, errs, "", "", "", "", "number")
8773
8774 s = "1."
8775 errs = validate.Var(s, "number")
8776 NotEqual(t, errs, nil)
8777 AssertError(t, errs, "", "", "", "", "number")
8778
8779 s = "1.o"
8780 errs = validate.Var(s, "number")
8781 NotEqual(t, errs, nil)
8782 AssertError(t, errs, "", "", "", "", "number")
8783
8784 i := 1
8785 errs = validate.Var(i, "number")
8786 Equal(t, errs, nil)
8787 }
8788
8789 func TestNumeric(t *testing.T) {
8790 validate := New()
8791
8792 s := "1"
8793 errs := validate.Var(s, "numeric")
8794 Equal(t, errs, nil)
8795
8796 s = "+1"
8797 errs = validate.Var(s, "numeric")
8798 Equal(t, errs, nil)
8799
8800 s = "-1"
8801 errs = validate.Var(s, "numeric")
8802 Equal(t, errs, nil)
8803
8804 s = "1.12"
8805 errs = validate.Var(s, "numeric")
8806 Equal(t, errs, nil)
8807
8808 s = "+1.12"
8809 errs = validate.Var(s, "numeric")
8810 Equal(t, errs, nil)
8811
8812 s = "-1.12"
8813 errs = validate.Var(s, "numeric")
8814 Equal(t, errs, nil)
8815
8816 s = "1."
8817 errs = validate.Var(s, "numeric")
8818 NotEqual(t, errs, nil)
8819 AssertError(t, errs, "", "", "", "", "numeric")
8820
8821 s = "1.o"
8822 errs = validate.Var(s, "numeric")
8823 NotEqual(t, errs, nil)
8824 AssertError(t, errs, "", "", "", "", "numeric")
8825
8826 i := 1
8827 errs = validate.Var(i, "numeric")
8828 Equal(t, errs, nil)
8829 }
8830 func TestBoolean(t *testing.T) {
8831 validate := New()
8832
8833 b := true
8834 errs := validate.Var(b, "boolean")
8835 Equal(t, errs, nil)
8836
8837 b = false
8838 errs = validate.Var(b, "boolean")
8839 Equal(t, errs, nil)
8840
8841 s := "true"
8842 errs = validate.Var(s, "boolean")
8843 Equal(t, errs, nil)
8844
8845 s = "false"
8846 errs = validate.Var(s, "boolean")
8847 Equal(t, errs, nil)
8848
8849 s = "0"
8850 errs = validate.Var(s, "boolean")
8851 Equal(t, errs, nil)
8852
8853 s = "1"
8854 errs = validate.Var(s, "boolean")
8855 Equal(t, errs, nil)
8856
8857 s = "xyz"
8858 errs = validate.Var(s, "boolean")
8859 NotEqual(t, errs, nil)
8860 AssertError(t, errs, "", "", "", "", "boolean")
8861
8862 s = "1."
8863 errs = validate.Var(s, "boolean")
8864 NotEqual(t, errs, nil)
8865 AssertError(t, errs, "", "", "", "", "boolean")
8866 }
8867
8868 func TestAlphaNumeric(t *testing.T) {
8869 validate := New()
8870
8871 s := "abcd123"
8872 errs := validate.Var(s, "alphanum")
8873 Equal(t, errs, nil)
8874
8875 s = "abc!23"
8876 errs = validate.Var(s, "alphanum")
8877 NotEqual(t, errs, nil)
8878 AssertError(t, errs, "", "", "", "", "alphanum")
8879
8880 errs = validate.Var(1, "alphanum")
8881 NotEqual(t, errs, nil)
8882 AssertError(t, errs, "", "", "", "", "alphanum")
8883 }
8884
8885 func TestAlpha(t *testing.T) {
8886 validate := New()
8887
8888 s := "abcd"
8889 errs := validate.Var(s, "alpha")
8890 Equal(t, errs, nil)
8891
8892 s = "abc®"
8893 errs = validate.Var(s, "alpha")
8894 NotEqual(t, errs, nil)
8895 AssertError(t, errs, "", "", "", "", "alpha")
8896
8897 s = "abc÷"
8898 errs = validate.Var(s, "alpha")
8899 NotEqual(t, errs, nil)
8900 AssertError(t, errs, "", "", "", "", "alpha")
8901
8902 s = "abc1"
8903 errs = validate.Var(s, "alpha")
8904 NotEqual(t, errs, nil)
8905 AssertError(t, errs, "", "", "", "", "alpha")
8906
8907 s = "this is a test string"
8908 errs = validate.Var(s, "alpha")
8909 NotEqual(t, errs, nil)
8910 AssertError(t, errs, "", "", "", "", "alpha")
8911
8912 errs = validate.Var(1, "alpha")
8913 NotEqual(t, errs, nil)
8914 AssertError(t, errs, "", "", "", "", "alpha")
8915 }
8916
8917 func TestStructStringValidation(t *testing.T) {
8918 validate := New()
8919
8920 tSuccess := &TestString{
8921 Required: "Required",
8922 Len: "length==10",
8923 Min: "min=1",
8924 Max: "1234567890",
8925 MinMax: "12345",
8926 Lt: "012345678",
8927 Lte: "0123456789",
8928 Gt: "01234567890",
8929 Gte: "0123456789",
8930 Boolean: "true",
8931 OmitEmpty: "",
8932 Sub: &SubTest{
8933 Test: "1",
8934 },
8935 SubIgnore: &SubTest{
8936 Test: "",
8937 },
8938 Anonymous: struct {
8939 A string `validate:"required"`
8940 }{
8941 A: "1",
8942 },
8943 Iface: &Impl{
8944 F: "123",
8945 },
8946 }
8947
8948 errs := validate.Struct(tSuccess)
8949 Equal(t, errs, nil)
8950
8951 tFail := &TestString{
8952 Required: "",
8953 Len: "",
8954 Min: "",
8955 Max: "12345678901",
8956 MinMax: "",
8957 Lt: "0123456789",
8958 Lte: "01234567890",
8959 Gt: "1",
8960 Gte: "1",
8961 OmitEmpty: "12345678901",
8962 Boolean: "nope",
8963 Sub: &SubTest{
8964 Test: "",
8965 },
8966 Anonymous: struct {
8967 A string `validate:"required"`
8968 }{
8969 A: "",
8970 },
8971 Iface: &Impl{
8972 F: "12",
8973 },
8974 }
8975
8976 errs = validate.Struct(tFail)
8977
8978
8979 NotEqual(t, errs, nil)
8980 Equal(t, len(errs.(ValidationErrors)), 14)
8981
8982
8983 AssertError(t, errs, "TestString.Required", "TestString.Required", "Required", "Required", "required")
8984 AssertError(t, errs, "TestString.Len", "TestString.Len", "Len", "Len", "len")
8985 AssertError(t, errs, "TestString.Min", "TestString.Min", "Min", "Min", "min")
8986 AssertError(t, errs, "TestString.Max", "TestString.Max", "Max", "Max", "max")
8987 AssertError(t, errs, "TestString.MinMax", "TestString.MinMax", "MinMax", "MinMax", "min")
8988 AssertError(t, errs, "TestString.Lt", "TestString.Lt", "Lt", "Lt", "lt")
8989 AssertError(t, errs, "TestString.Lte", "TestString.Lte", "Lte", "Lte", "lte")
8990 AssertError(t, errs, "TestString.Gt", "TestString.Gt", "Gt", "Gt", "gt")
8991 AssertError(t, errs, "TestString.Gte", "TestString.Gte", "Gte", "Gte", "gte")
8992 AssertError(t, errs, "TestString.OmitEmpty", "TestString.OmitEmpty", "OmitEmpty", "OmitEmpty", "max")
8993 AssertError(t, errs, "TestString.Boolean", "TestString.Boolean", "Boolean", "Boolean", "boolean")
8994
8995
8996 AssertError(t, errs, "TestString.Anonymous.A", "TestString.Anonymous.A", "A", "A", "required")
8997 AssertError(t, errs, "TestString.Sub.Test", "TestString.Sub.Test", "Test", "Test", "required")
8998 AssertError(t, errs, "TestString.Iface.F", "TestString.Iface.F", "F", "F", "len")
8999 }
9000
9001 func TestStructInt32Validation(t *testing.T) {
9002 type TestInt32 struct {
9003 Required int `validate:"required"`
9004 Len int `validate:"len=10"`
9005 Min int `validate:"min=1"`
9006 Max int `validate:"max=10"`
9007 MinMax int `validate:"min=1,max=10"`
9008 Lt int `validate:"lt=10"`
9009 Lte int `validate:"lte=10"`
9010 Gt int `validate:"gt=10"`
9011 Gte int `validate:"gte=10"`
9012 OmitEmpty int `validate:"omitempty,min=1,max=10"`
9013 }
9014
9015 tSuccess := &TestInt32{
9016 Required: 1,
9017 Len: 10,
9018 Min: 1,
9019 Max: 10,
9020 MinMax: 5,
9021 Lt: 9,
9022 Lte: 10,
9023 Gt: 11,
9024 Gte: 10,
9025 OmitEmpty: 0,
9026 }
9027
9028 validate := New()
9029 errs := validate.Struct(tSuccess)
9030 Equal(t, errs, nil)
9031
9032 tFail := &TestInt32{
9033 Required: 0,
9034 Len: 11,
9035 Min: -1,
9036 Max: 11,
9037 MinMax: -1,
9038 Lt: 10,
9039 Lte: 11,
9040 Gt: 10,
9041 Gte: 9,
9042 OmitEmpty: 11,
9043 }
9044
9045 errs = validate.Struct(tFail)
9046
9047
9048 NotEqual(t, errs, nil)
9049 Equal(t, len(errs.(ValidationErrors)), 10)
9050
9051
9052 AssertError(t, errs, "TestInt32.Required", "TestInt32.Required", "Required", "Required", "required")
9053 AssertError(t, errs, "TestInt32.Len", "TestInt32.Len", "Len", "Len", "len")
9054 AssertError(t, errs, "TestInt32.Min", "TestInt32.Min", "Min", "Min", "min")
9055 AssertError(t, errs, "TestInt32.Max", "TestInt32.Max", "Max", "Max", "max")
9056 AssertError(t, errs, "TestInt32.MinMax", "TestInt32.MinMax", "MinMax", "MinMax", "min")
9057 AssertError(t, errs, "TestInt32.Lt", "TestInt32.Lt", "Lt", "Lt", "lt")
9058 AssertError(t, errs, "TestInt32.Lte", "TestInt32.Lte", "Lte", "Lte", "lte")
9059 AssertError(t, errs, "TestInt32.Gt", "TestInt32.Gt", "Gt", "Gt", "gt")
9060 AssertError(t, errs, "TestInt32.Gte", "TestInt32.Gte", "Gte", "Gte", "gte")
9061 AssertError(t, errs, "TestInt32.OmitEmpty", "TestInt32.OmitEmpty", "OmitEmpty", "OmitEmpty", "max")
9062 }
9063
9064 func TestStructUint64Validation(t *testing.T) {
9065 validate := New()
9066
9067 tSuccess := &TestUint64{
9068 Required: 1,
9069 Len: 10,
9070 Min: 1,
9071 Max: 10,
9072 MinMax: 5,
9073 OmitEmpty: 0,
9074 }
9075
9076 errs := validate.Struct(tSuccess)
9077 Equal(t, errs, nil)
9078
9079 tFail := &TestUint64{
9080 Required: 0,
9081 Len: 11,
9082 Min: 0,
9083 Max: 11,
9084 MinMax: 0,
9085 OmitEmpty: 11,
9086 }
9087
9088 errs = validate.Struct(tFail)
9089
9090
9091 NotEqual(t, errs, nil)
9092 Equal(t, len(errs.(ValidationErrors)), 6)
9093
9094
9095 AssertError(t, errs, "TestUint64.Required", "TestUint64.Required", "Required", "Required", "required")
9096 AssertError(t, errs, "TestUint64.Len", "TestUint64.Len", "Len", "Len", "len")
9097 AssertError(t, errs, "TestUint64.Min", "TestUint64.Min", "Min", "Min", "min")
9098 AssertError(t, errs, "TestUint64.Max", "TestUint64.Max", "Max", "Max", "max")
9099 AssertError(t, errs, "TestUint64.MinMax", "TestUint64.MinMax", "MinMax", "MinMax", "min")
9100 AssertError(t, errs, "TestUint64.OmitEmpty", "TestUint64.OmitEmpty", "OmitEmpty", "OmitEmpty", "max")
9101 }
9102
9103 func TestStructFloat64Validation(t *testing.T) {
9104 validate := New()
9105
9106 tSuccess := &TestFloat64{
9107 Required: 1,
9108 Len: 10,
9109 Min: 1,
9110 Max: 10,
9111 MinMax: 5,
9112 OmitEmpty: 0,
9113 }
9114
9115 errs := validate.Struct(tSuccess)
9116 Equal(t, errs, nil)
9117
9118 tFail := &TestFloat64{
9119 Required: 0,
9120 Len: 11,
9121 Min: 0,
9122 Max: 11,
9123 MinMax: 0,
9124 OmitEmpty: 11,
9125 }
9126
9127 errs = validate.Struct(tFail)
9128
9129
9130 NotEqual(t, errs, nil)
9131 Equal(t, len(errs.(ValidationErrors)), 6)
9132
9133
9134 AssertError(t, errs, "TestFloat64.Required", "TestFloat64.Required", "Required", "Required", "required")
9135 AssertError(t, errs, "TestFloat64.Len", "TestFloat64.Len", "Len", "Len", "len")
9136 AssertError(t, errs, "TestFloat64.Min", "TestFloat64.Min", "Min", "Min", "min")
9137 AssertError(t, errs, "TestFloat64.Max", "TestFloat64.Max", "Max", "Max", "max")
9138 AssertError(t, errs, "TestFloat64.MinMax", "TestFloat64.MinMax", "MinMax", "MinMax", "min")
9139 AssertError(t, errs, "TestFloat64.OmitEmpty", "TestFloat64.OmitEmpty", "OmitEmpty", "OmitEmpty", "max")
9140 }
9141
9142 func TestStructSliceValidation(t *testing.T) {
9143 validate := New()
9144
9145 tSuccess := &TestSlice{
9146 Required: []int{1},
9147 Len: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0},
9148 Min: []int{1, 2},
9149 Max: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0},
9150 MinMax: []int{1, 2, 3, 4, 5},
9151 OmitEmpty: nil,
9152 }
9153
9154 errs := validate.Struct(tSuccess)
9155 Equal(t, errs, nil)
9156
9157 tFail := &TestSlice{
9158 Required: nil,
9159 Len: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1},
9160 Min: []int{},
9161 Max: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1},
9162 MinMax: []int{},
9163 OmitEmpty: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1},
9164 }
9165
9166 errs = validate.Struct(tFail)
9167 NotEqual(t, errs, nil)
9168 Equal(t, len(errs.(ValidationErrors)), 6)
9169
9170
9171 AssertError(t, errs, "TestSlice.Required", "TestSlice.Required", "Required", "Required", "required")
9172 AssertError(t, errs, "TestSlice.Len", "TestSlice.Len", "Len", "Len", "len")
9173 AssertError(t, errs, "TestSlice.Min", "TestSlice.Min", "Min", "Min", "min")
9174 AssertError(t, errs, "TestSlice.Max", "TestSlice.Max", "Max", "Max", "max")
9175 AssertError(t, errs, "TestSlice.MinMax", "TestSlice.MinMax", "MinMax", "MinMax", "min")
9176 AssertError(t, errs, "TestSlice.OmitEmpty", "TestSlice.OmitEmpty", "OmitEmpty", "OmitEmpty", "max")
9177
9178 fe := getError(errs, "TestSlice.Len", "TestSlice.Len")
9179 NotEqual(t, fe, nil)
9180 Equal(t, fe.Field(), "Len")
9181 Equal(t, fe.StructField(), "Len")
9182 Equal(t, fe.Namespace(), "TestSlice.Len")
9183 Equal(t, fe.StructNamespace(), "TestSlice.Len")
9184 Equal(t, fe.Tag(), "len")
9185 Equal(t, fe.ActualTag(), "len")
9186 Equal(t, fe.Param(), "10")
9187 Equal(t, fe.Kind(), reflect.Slice)
9188 Equal(t, fe.Type(), reflect.TypeOf([]int{}))
9189
9190 _, ok := fe.Value().([]int)
9191 Equal(t, ok, true)
9192 }
9193
9194 func TestInvalidStruct(t *testing.T) {
9195 validate := New()
9196
9197 s := &SubTest{
9198 Test: "1",
9199 }
9200
9201 err := validate.Struct(s.Test)
9202 NotEqual(t, err, nil)
9203 Equal(t, err.Error(), "validator: (nil string)")
9204
9205 err = validate.Struct(nil)
9206 NotEqual(t, err, nil)
9207 Equal(t, err.Error(), "validator: (nil)")
9208
9209 err = validate.StructPartial(nil, "SubTest.Test")
9210 NotEqual(t, err, nil)
9211 Equal(t, err.Error(), "validator: (nil)")
9212
9213 err = validate.StructExcept(nil, "SubTest.Test")
9214 NotEqual(t, err, nil)
9215 Equal(t, err.Error(), "validator: (nil)")
9216 }
9217
9218 func TestInvalidValidatorFunction(t *testing.T) {
9219 validate := New()
9220
9221 s := &SubTest{
9222 Test: "1",
9223 }
9224
9225 PanicMatches(t, func() { _ = validate.Var(s.Test, "zzxxBadFunction") }, "Undefined validation function 'zzxxBadFunction' on field ''")
9226 }
9227
9228 func TestCustomFieldName(t *testing.T) {
9229 validate := New()
9230 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
9231 name := strings.SplitN(fld.Tag.Get("schema"), ",", 2)[0]
9232
9233 if name == "-" {
9234 return ""
9235 }
9236
9237 return name
9238 })
9239
9240 type A struct {
9241 B string `schema:"b" validate:"required"`
9242 C string `schema:"c" validate:"required"`
9243 D []bool `schema:"d" validate:"required"`
9244 E string `schema:"-" validate:"required"`
9245 }
9246
9247 a := &A{}
9248
9249 err := validate.Struct(a)
9250 NotEqual(t, err, nil)
9251
9252 errs := err.(ValidationErrors)
9253 Equal(t, len(errs), 4)
9254 Equal(t, getError(errs, "A.b", "A.B").Field(), "b")
9255 Equal(t, getError(errs, "A.c", "A.C").Field(), "c")
9256 Equal(t, getError(errs, "A.d", "A.D").Field(), "d")
9257 Equal(t, getError(errs, "A.E", "A.E").Field(), "E")
9258
9259 v2 := New()
9260 err = v2.Struct(a)
9261 NotEqual(t, err, nil)
9262
9263 errs = err.(ValidationErrors)
9264 Equal(t, len(errs), 4)
9265 Equal(t, getError(errs, "A.B", "A.B").Field(), "B")
9266 Equal(t, getError(errs, "A.C", "A.C").Field(), "C")
9267 Equal(t, getError(errs, "A.D", "A.D").Field(), "D")
9268 Equal(t, getError(errs, "A.E", "A.E").Field(), "E")
9269 }
9270
9271 func TestMutipleRecursiveExtractStructCache(t *testing.T) {
9272 validate := New()
9273
9274 type Recursive struct {
9275 Field *string `validate:"required,len=5,ne=string"`
9276 }
9277
9278 var test Recursive
9279
9280 current := reflect.ValueOf(test)
9281 name := "Recursive"
9282 proceed := make(chan struct{})
9283
9284 sc := validate.extractStructCache(current, name)
9285 ptr := fmt.Sprintf("%p", sc)
9286
9287 for i := 0; i < 100; i++ {
9288 go func() {
9289 <-proceed
9290 sc := validate.extractStructCache(current, name)
9291 Equal(t, ptr, fmt.Sprintf("%p", sc))
9292 }()
9293 }
9294
9295 close(proceed)
9296 }
9297
9298
9299 func TestPointerAndOmitEmpty(t *testing.T) {
9300 validate := New()
9301
9302 type Test struct {
9303 MyInt *int `validate:"omitempty,gte=2,lte=255"`
9304 }
9305
9306 val1 := 0
9307 val2 := 256
9308
9309 t1 := Test{MyInt: &val1}
9310 t2 := Test{MyInt: &val2}
9311 t3 := Test{MyInt: nil}
9312
9313 errs := validate.Struct(t1)
9314 NotEqual(t, errs, nil)
9315 AssertError(t, errs, "Test.MyInt", "Test.MyInt", "MyInt", "MyInt", "gte")
9316
9317 errs = validate.Struct(t2)
9318 NotEqual(t, errs, nil)
9319 AssertError(t, errs, "Test.MyInt", "Test.MyInt", "MyInt", "MyInt", "lte")
9320
9321 errs = validate.Struct(t3)
9322 Equal(t, errs, nil)
9323
9324 type TestIface struct {
9325 MyInt interface{} `validate:"omitempty,gte=2,lte=255"`
9326 }
9327
9328 ti1 := TestIface{MyInt: &val1}
9329 ti2 := TestIface{MyInt: &val2}
9330 ti3 := TestIface{MyInt: nil}
9331
9332 errs = validate.Struct(ti1)
9333 NotEqual(t, errs, nil)
9334 AssertError(t, errs, "TestIface.MyInt", "TestIface.MyInt", "MyInt", "MyInt", "gte")
9335
9336 errs = validate.Struct(ti2)
9337 NotEqual(t, errs, nil)
9338 AssertError(t, errs, "TestIface.MyInt", "TestIface.MyInt", "MyInt", "MyInt", "lte")
9339
9340 errs = validate.Struct(ti3)
9341 Equal(t, errs, nil)
9342 }
9343
9344 func TestRequired(t *testing.T) {
9345 validate := New()
9346 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
9347 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
9348
9349 if name == "-" {
9350 return ""
9351 }
9352
9353 return name
9354 })
9355
9356 type Test struct {
9357 Value interface{} `validate:"required"`
9358 }
9359
9360 var test Test
9361
9362 err := validate.Struct(test)
9363 NotEqual(t, err, nil)
9364 AssertError(t, err.(ValidationErrors), "Test.Value", "Test.Value", "Value", "Value", "required")
9365 }
9366
9367 func TestBoolEqual(t *testing.T) {
9368 validate := New()
9369
9370 type Test struct {
9371 Value bool `validate:"eq=true"`
9372 }
9373
9374 var test Test
9375
9376 err := validate.Struct(test)
9377 NotEqual(t, err, nil)
9378 AssertError(t, err.(ValidationErrors), "Test.Value", "Test.Value", "Value", "Value", "eq")
9379
9380 test.Value = true
9381 err = validate.Struct(test)
9382 Equal(t, err, nil)
9383 }
9384
9385 func TestTranslations(t *testing.T) {
9386 en := en.New()
9387 uni := ut.New(en, en, fr.New())
9388
9389 trans, _ := uni.GetTranslator("en")
9390 fr, _ := uni.GetTranslator("fr")
9391
9392 validate := New()
9393 err := validate.RegisterTranslation("required", trans,
9394 func(ut ut.Translator) (err error) {
9395
9396 if err = ut.Add("required", "{0} is a required field", false); err != nil {
9397 return
9398 }
9399
9400 return
9401 }, func(ut ut.Translator, fe FieldError) string {
9402 t, err := ut.T(fe.Tag(), fe.Field())
9403 if err != nil {
9404 fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError))
9405 return fe.(*fieldError).Error()
9406 }
9407
9408 return t
9409 })
9410 Equal(t, err, nil)
9411
9412 err = validate.RegisterTranslation("required", fr,
9413 func(ut ut.Translator) (err error) {
9414
9415 if err = ut.Add("required", "{0} est un champ obligatoire", false); err != nil {
9416 return
9417 }
9418
9419 return
9420 }, func(ut ut.Translator, fe FieldError) string {
9421 t, transErr := ut.T(fe.Tag(), fe.Field())
9422 if transErr != nil {
9423 fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError))
9424 return fe.(*fieldError).Error()
9425 }
9426
9427 return t
9428 })
9429
9430 Equal(t, err, nil)
9431
9432 type Test struct {
9433 Value interface{} `validate:"required"`
9434 }
9435
9436 var test Test
9437
9438 err = validate.Struct(test)
9439 NotEqual(t, err, nil)
9440
9441 errs := err.(ValidationErrors)
9442 Equal(t, len(errs), 1)
9443
9444 fe := errs[0]
9445 Equal(t, fe.Tag(), "required")
9446 Equal(t, fe.Namespace(), "Test.Value")
9447 Equal(t, fe.Translate(trans), fmt.Sprintf("%s is a required field", fe.Field()))
9448 Equal(t, fe.Translate(fr), fmt.Sprintf("%s est un champ obligatoire", fe.Field()))
9449
9450 nl := nl.New()
9451 uni2 := ut.New(nl, nl)
9452 trans2, _ := uni2.GetTranslator("nl")
9453 Equal(t, fe.Translate(trans2), "Key: 'Test.Value' Error:Field validation for 'Value' failed on the 'required' tag")
9454
9455 terrs := errs.Translate(trans)
9456 Equal(t, len(terrs), 1)
9457
9458 v, ok := terrs["Test.Value"]
9459 Equal(t, ok, true)
9460 Equal(t, v, fmt.Sprintf("%s is a required field", fe.Field()))
9461
9462 terrs = errs.Translate(fr)
9463 Equal(t, len(terrs), 1)
9464
9465 v, ok = terrs["Test.Value"]
9466 Equal(t, ok, true)
9467 Equal(t, v, fmt.Sprintf("%s est un champ obligatoire", fe.Field()))
9468
9469 type Test2 struct {
9470 Value string `validate:"gt=1"`
9471 }
9472
9473 var t2 Test2
9474
9475 err = validate.Struct(t2)
9476 NotEqual(t, err, nil)
9477
9478 errs = err.(ValidationErrors)
9479 Equal(t, len(errs), 1)
9480
9481 fe = errs[0]
9482 Equal(t, fe.Tag(), "gt")
9483 Equal(t, fe.Namespace(), "Test2.Value")
9484 Equal(t, fe.Translate(trans), "Key: 'Test2.Value' Error:Field validation for 'Value' failed on the 'gt' tag")
9485 }
9486
9487 func TestTranslationErrors(t *testing.T) {
9488 en := en.New()
9489 uni := ut.New(en, en, fr.New())
9490
9491 trans, _ := uni.GetTranslator("en")
9492 err := trans.Add("required", "{0} is a required field", false)
9493 Equal(t, err, nil)
9494
9495 validate := New()
9496 err = validate.RegisterTranslation("required", trans,
9497 func(ut ut.Translator) (err error) {
9498
9499 if err = ut.Add("required", "{0} is a required field", false); err != nil {
9500 return
9501 }
9502
9503 return
9504 }, func(ut ut.Translator, fe FieldError) string {
9505 t, err := ut.T(fe.Tag(), fe.Field())
9506 if err != nil {
9507 fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError))
9508 return fe.(*fieldError).Error()
9509 }
9510
9511 return t
9512 })
9513
9514 NotEqual(t, err, nil)
9515 Equal(t, err.Error(), "error: conflicting key 'required' rule 'Unknown' with text '{0} is a required field' for locale 'en', value being ignored")
9516 }
9517
9518 func TestStructFiltered(t *testing.T) {
9519 p1 := func(ns []byte) bool {
9520 if bytes.HasSuffix(ns, []byte("NoTag")) || bytes.HasSuffix(ns, []byte("Required")) {
9521 return false
9522 }
9523
9524 return true
9525 }
9526
9527 p2 := func(ns []byte) bool {
9528 if bytes.HasSuffix(ns, []byte("SubSlice[0].Test")) ||
9529 bytes.HasSuffix(ns, []byte("SubSlice[0]")) ||
9530 bytes.HasSuffix(ns, []byte("SubSlice")) ||
9531 bytes.HasSuffix(ns, []byte("Sub")) ||
9532 bytes.HasSuffix(ns, []byte("SubIgnore")) ||
9533 bytes.HasSuffix(ns, []byte("Anonymous")) ||
9534 bytes.HasSuffix(ns, []byte("Anonymous.A")) {
9535 return false
9536 }
9537
9538 return true
9539 }
9540
9541 p3 := func(ns []byte) bool {
9542 return !bytes.HasSuffix(ns, []byte("SubTest.Test"))
9543 }
9544
9545
9546
9547
9548
9549 tPartial := &TestPartial{
9550 NoTag: "NoTag",
9551 Required: "Required",
9552
9553 SubSlice: []*SubTest{
9554 {
9555
9556 Test: "Required",
9557 },
9558 {
9559
9560 Test: "Required",
9561 },
9562 },
9563
9564 Sub: &SubTest{
9565 Test: "1",
9566 },
9567 SubIgnore: &SubTest{
9568 Test: "",
9569 },
9570 Anonymous: struct {
9571 A string `validate:"required"`
9572 ASubSlice []*SubTest `validate:"required,dive"`
9573 SubAnonStruct []struct {
9574 Test string `validate:"required"`
9575 OtherTest string `validate:"required"`
9576 } `validate:"required,dive"`
9577 }{
9578 A: "1",
9579 ASubSlice: []*SubTest{
9580 {
9581 Test: "Required",
9582 },
9583 {
9584 Test: "Required",
9585 },
9586 },
9587
9588 SubAnonStruct: []struct {
9589 Test string `validate:"required"`
9590 OtherTest string `validate:"required"`
9591 }{
9592 {"Required", "RequiredOther"},
9593 {"Required", "RequiredOther"},
9594 },
9595 },
9596 }
9597
9598 validate := New()
9599
9600
9601
9602 errs := validate.StructFilteredCtx(context.Background(), tPartial, p1)
9603 Equal(t, errs, nil)
9604
9605 errs = validate.StructFiltered(tPartial, p2)
9606 Equal(t, errs, nil)
9607
9608
9609 errs = validate.StructFiltered(tPartial.SubSlice[0], p3)
9610 Equal(t, errs, nil)
9611
9612
9613 tPartial.Required = ""
9614
9615
9616 errs = validate.StructFiltered(tPartial, p1)
9617 NotEqual(t, errs, nil)
9618 AssertError(t, errs, "TestPartial.Required", "TestPartial.Required", "Required", "Required", "required")
9619
9620
9621 tPartial.Required = "Required"
9622 tPartial.Anonymous.A = ""
9623
9624
9625 errs = validate.StructFiltered(tPartial, p1)
9626 Equal(t, errs, nil)
9627
9628
9629 errs = validate.StructFiltered(tPartial, p2)
9630 NotEqual(t, errs, nil)
9631 AssertError(t, errs, "TestPartial.Anonymous.A", "TestPartial.Anonymous.A", "A", "A", "required")
9632
9633
9634 tPartial.Anonymous.A = "Required"
9635 tPartial.SubSlice[0].Test = ""
9636
9637
9638 errs = validate.StructFiltered(tPartial, p1)
9639 Equal(t, errs, nil)
9640
9641 errs = validate.StructFiltered(tPartial, p2)
9642 NotEqual(t, errs, nil)
9643 AssertError(t, errs, "TestPartial.SubSlice[0].Test", "TestPartial.SubSlice[0].Test", "Test", "Test", "required")
9644 Equal(t, len(errs.(ValidationErrors)), 1)
9645
9646
9647 tPartial.SubSlice[1].Test = ""
9648
9649 errs = validate.StructFiltered(tPartial, p1)
9650 Equal(t, errs, nil)
9651
9652 errs = validate.StructFiltered(tPartial, p2)
9653 NotEqual(t, errs, nil)
9654 Equal(t, len(errs.(ValidationErrors)), 1)
9655 AssertError(t, errs, "TestPartial.SubSlice[0].Test", "TestPartial.SubSlice[0].Test", "Test", "Test", "required")
9656
9657
9658 tPartial.SubSlice[0].Test = "Required"
9659
9660
9661 errs = validate.StructFiltered(tPartial, p1)
9662 Equal(t, errs, nil)
9663
9664 errs = validate.StructFiltered(tPartial, p2)
9665 Equal(t, errs, nil)
9666
9667 tPartial.SubSlice[1].Test = "Required"
9668 tPartial.Anonymous.SubAnonStruct[0].Test = ""
9669
9670
9671 errs = validate.StructFiltered(tPartial, p1)
9672 Equal(t, errs, nil)
9673
9674 errs = validate.StructFiltered(tPartial, p2)
9675 Equal(t, errs, nil)
9676
9677 dt := time.Now()
9678 err := validate.StructFiltered(&dt, func(ns []byte) bool { return true })
9679 NotEqual(t, err, nil)
9680 Equal(t, err.Error(), "validator: (nil *time.Time)")
9681 }
9682
9683 func TestRequiredPtr(t *testing.T) {
9684 type Test struct {
9685 Bool *bool `validate:"required"`
9686 }
9687
9688 validate := New()
9689
9690 f := false
9691
9692 test := Test{
9693 Bool: &f,
9694 }
9695
9696 err := validate.Struct(test)
9697 Equal(t, err, nil)
9698
9699 tr := true
9700
9701 test.Bool = &tr
9702
9703 err = validate.Struct(test)
9704 Equal(t, err, nil)
9705
9706 test.Bool = nil
9707
9708 err = validate.Struct(test)
9709 NotEqual(t, err, nil)
9710
9711 errs, ok := err.(ValidationErrors)
9712 Equal(t, ok, true)
9713 Equal(t, len(errs), 1)
9714 AssertError(t, errs, "Test.Bool", "Test.Bool", "Bool", "Bool", "required")
9715
9716 type Test2 struct {
9717 Bool bool `validate:"required"`
9718 }
9719
9720 var test2 Test2
9721
9722 err = validate.Struct(test2)
9723 NotEqual(t, err, nil)
9724
9725 errs, ok = err.(ValidationErrors)
9726 Equal(t, ok, true)
9727 Equal(t, len(errs), 1)
9728 AssertError(t, errs, "Test2.Bool", "Test2.Bool", "Bool", "Bool", "required")
9729
9730 test2.Bool = true
9731
9732 err = validate.Struct(test2)
9733 Equal(t, err, nil)
9734
9735 type Test3 struct {
9736 Arr []string `validate:"required"`
9737 }
9738
9739 var test3 Test3
9740
9741 err = validate.Struct(test3)
9742 NotEqual(t, err, nil)
9743
9744 errs, ok = err.(ValidationErrors)
9745 Equal(t, ok, true)
9746 Equal(t, len(errs), 1)
9747 AssertError(t, errs, "Test3.Arr", "Test3.Arr", "Arr", "Arr", "required")
9748
9749 test3.Arr = make([]string, 0)
9750
9751 err = validate.Struct(test3)
9752 Equal(t, err, nil)
9753
9754 type Test4 struct {
9755 Arr *[]string `validate:"required"`
9756 }
9757
9758 var test4 Test4
9759
9760 err = validate.Struct(test4)
9761 NotEqual(t, err, nil)
9762
9763 errs, ok = err.(ValidationErrors)
9764 Equal(t, ok, true)
9765 Equal(t, len(errs), 1)
9766 AssertError(t, errs, "Test4.Arr", "Test4.Arr", "Arr", "Arr", "required")
9767
9768 arr := make([]string, 0)
9769 test4.Arr = &arr
9770
9771 err = validate.Struct(test4)
9772 Equal(t, err, nil)
9773 }
9774
9775 func TestAlphaUnicodeValidation(t *testing.T) {
9776 tests := []struct {
9777 param string
9778 expected bool
9779 }{
9780 {"", false},
9781 {"abc", true},
9782 {"this is a test string", false},
9783 {"这是一个测试字符串", true},
9784 {"123", false},
9785 {"<>@;.-=", false},
9786 {"ひらがな・カタカナ、.漢字", false},
9787 {"あいうえおfoobar", true},
9788 {"test@example.com", false},
9789 {"1234abcDE", false},
9790 {"カタカナ", true},
9791 }
9792
9793 validate := New()
9794
9795 for i, test := range tests {
9796
9797 errs := validate.Var(test.param, "alphaunicode")
9798
9799 if test.expected {
9800 if !IsEqual(errs, nil) {
9801 t.Fatalf("Index: %d Alpha Unicode failed Error: %s", i, errs)
9802 }
9803 } else {
9804 if IsEqual(errs, nil) {
9805 t.Fatalf("Index: %d Alpha Unicode failed Error: %s", i, errs)
9806 } else {
9807 val := getError(errs, "", "")
9808 if val.Tag() != "alphaunicode" {
9809 t.Fatalf("Index: %d Alpha Unicode failed Error: %s", i, errs)
9810 }
9811 }
9812 }
9813 }
9814 }
9815
9816 func TestAlphanumericUnicodeValidation(t *testing.T) {
9817 tests := []struct {
9818 param string
9819 expected bool
9820 }{
9821 {"", false},
9822 {"abc", true},
9823 {"this is a test string", false},
9824 {"这是一个测试字符串", true},
9825 {"\u0031\u0032\u0033", true},
9826 {"123", true},
9827 {"<>@;.-=", false},
9828 {"ひらがな・カタカナ、.漢字", false},
9829 {"あいうえおfoobar", true},
9830 {"test@example.com", false},
9831 {"1234abcDE", true},
9832 {"カタカナ", true},
9833 }
9834
9835 validate := New()
9836
9837 for i, test := range tests {
9838
9839 errs := validate.Var(test.param, "alphanumunicode")
9840
9841 if test.expected {
9842 if !IsEqual(errs, nil) {
9843 t.Fatalf("Index: %d Alphanum Unicode failed Error: %s", i, errs)
9844 }
9845 } else {
9846 if IsEqual(errs, nil) {
9847 t.Fatalf("Index: %d Alphanum Unicode failed Error: %s", i, errs)
9848 } else {
9849 val := getError(errs, "", "")
9850 if val.Tag() != "alphanumunicode" {
9851 t.Fatalf("Index: %d Alphanum Unicode failed Error: %s", i, errs)
9852 }
9853 }
9854 }
9855 }
9856 }
9857
9858 func TestArrayStructNamespace(t *testing.T) {
9859 validate := New()
9860 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
9861 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
9862
9863 if name == "-" {
9864 return ""
9865 }
9866
9867 return name
9868 })
9869
9870 type child struct {
9871 Name string `json:"name" validate:"required"`
9872 }
9873 var input struct {
9874 Children []child `json:"children" validate:"required,gt=0,dive"`
9875 }
9876 input.Children = []child{{"ok"}, {""}}
9877
9878 errs := validate.Struct(input)
9879 NotEqual(t, errs, nil)
9880
9881 ve := errs.(ValidationErrors)
9882 Equal(t, len(ve), 1)
9883 AssertError(t, errs, "children[1].name", "Children[1].Name", "name", "Name", "required")
9884 }
9885
9886 func TestMapStructNamespace(t *testing.T) {
9887 validate := New()
9888 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
9889 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
9890
9891 if name == "-" {
9892 return ""
9893 }
9894
9895 return name
9896 })
9897
9898 type child struct {
9899 Name string `json:"name" validate:"required"`
9900 }
9901 var input struct {
9902 Children map[int]child `json:"children" validate:"required,gt=0,dive"`
9903 }
9904 input.Children = map[int]child{
9905 0: {Name: "ok"},
9906 1: {Name: ""},
9907 }
9908
9909 errs := validate.Struct(input)
9910 NotEqual(t, errs, nil)
9911
9912 ve := errs.(ValidationErrors)
9913 Equal(t, len(ve), 1)
9914 AssertError(t, errs, "children[1].name", "Children[1].Name", "name", "Name", "required")
9915 }
9916
9917 func TestFieldLevelName(t *testing.T) {
9918 type Test struct {
9919 String string `validate:"custom1" json:"json1"`
9920 Array []string `validate:"dive,custom2" json:"json2"`
9921 Map map[string]string `validate:"dive,custom3" json:"json3"`
9922 Array2 []string `validate:"custom4" json:"json4"`
9923 Map2 map[string]string `validate:"custom5" json:"json5"`
9924 }
9925
9926 var res1, res2, res3, res4, res5, alt1, alt2, alt3, alt4, alt5 string
9927 validate := New()
9928 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
9929 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
9930
9931 if name == "-" {
9932 return ""
9933 }
9934
9935 return name
9936 })
9937 err := validate.RegisterValidation("custom1", func(fl FieldLevel) bool {
9938 res1 = fl.FieldName()
9939 alt1 = fl.StructFieldName()
9940 return true
9941 })
9942 Equal(t, err, nil)
9943
9944 err = validate.RegisterValidation("custom2", func(fl FieldLevel) bool {
9945 res2 = fl.FieldName()
9946 alt2 = fl.StructFieldName()
9947 return true
9948 })
9949 Equal(t, err, nil)
9950
9951 err = validate.RegisterValidation("custom3", func(fl FieldLevel) bool {
9952 res3 = fl.FieldName()
9953 alt3 = fl.StructFieldName()
9954 return true
9955 })
9956 Equal(t, err, nil)
9957
9958 err = validate.RegisterValidation("custom4", func(fl FieldLevel) bool {
9959 res4 = fl.FieldName()
9960 alt4 = fl.StructFieldName()
9961 return true
9962 })
9963 Equal(t, err, nil)
9964
9965 err = validate.RegisterValidation("custom5", func(fl FieldLevel) bool {
9966 res5 = fl.FieldName()
9967 alt5 = fl.StructFieldName()
9968 return true
9969 })
9970 Equal(t, err, nil)
9971
9972 test := Test{
9973 String: "test",
9974 Array: []string{"1"},
9975 Map: map[string]string{"test": "test"},
9976 }
9977
9978 errs := validate.Struct(test)
9979 Equal(t, errs, nil)
9980 Equal(t, res1, "json1")
9981 Equal(t, alt1, "String")
9982 Equal(t, res2, "json2[0]")
9983 Equal(t, alt2, "Array[0]")
9984 Equal(t, res3, "json3[test]")
9985 Equal(t, alt3, "Map[test]")
9986 Equal(t, res4, "json4")
9987 Equal(t, alt4, "Array2")
9988 Equal(t, res5, "json5")
9989 Equal(t, alt5, "Map2")
9990 }
9991
9992 func TestValidateStructRegisterCtx(t *testing.T) {
9993 var ctxVal string
9994
9995 fnCtx := func(ctx context.Context, fl FieldLevel) bool {
9996 ctxVal = ctx.Value(&ctxVal).(string)
9997 return true
9998 }
9999
10000 var ctxSlVal string
10001 slFn := func(ctx context.Context, sl StructLevel) {
10002 ctxSlVal = ctx.Value(&ctxSlVal).(string)
10003 }
10004
10005 type Test struct {
10006 Field string `validate:"val"`
10007 }
10008
10009 var tst Test
10010
10011 validate := New()
10012 err := validate.RegisterValidationCtx("val", fnCtx)
10013 Equal(t, err, nil)
10014
10015 validate.RegisterStructValidationCtx(slFn, Test{})
10016
10017 ctx := context.WithValue(context.Background(), &ctxVal, "testval")
10018 ctx = context.WithValue(ctx, &ctxSlVal, "slVal")
10019 errs := validate.StructCtx(ctx, tst)
10020 Equal(t, errs, nil)
10021 Equal(t, ctxVal, "testval")
10022 Equal(t, ctxSlVal, "slVal")
10023 }
10024
10025 func TestHostnameRFC952Validation(t *testing.T) {
10026 tests := []struct {
10027 param string
10028 expected bool
10029 }{
10030 {"test.example.com", true},
10031 {"example.com", true},
10032 {"example24.com", true},
10033 {"test.example24.com", true},
10034 {"test24.example24.com", true},
10035 {"example", true},
10036 {"EXAMPLE", true},
10037 {"1.foo.com", false},
10038 {"test.example.com.", false},
10039 {"example.com.", false},
10040 {"example24.com.", false},
10041 {"test.example24.com.", false},
10042 {"test24.example24.com.", false},
10043 {"example.", false},
10044 {"192.168.0.1", false},
10045 {"email@example.com", false},
10046 {"2001:cdba:0000:0000:0000:0000:3257:9652", false},
10047 {"2001:cdba:0:0:0:0:3257:9652", false},
10048 {"2001:cdba::3257:9652", false},
10049 {"example..........com", false},
10050 {"1234", false},
10051 {"abc1234", true},
10052 {"example. com", false},
10053 {"ex ample.com", false},
10054 }
10055
10056 validate := New()
10057
10058 for i, test := range tests {
10059
10060 errs := validate.Var(test.param, "hostname")
10061
10062 if test.expected {
10063 if !IsEqual(errs, nil) {
10064 t.Fatalf("Index: %d hostname failed Error: %v", i, errs)
10065 }
10066 } else {
10067 if IsEqual(errs, nil) {
10068 t.Fatalf("Index: %d hostname failed Error: %v", i, errs)
10069 } else {
10070 val := getError(errs, "", "")
10071 if val.Tag() != "hostname" {
10072 t.Fatalf("Index: %d hostname failed Error: %v", i, errs)
10073 }
10074 }
10075 }
10076 }
10077 }
10078
10079 func TestHostnameRFC1123Validation(t *testing.T) {
10080 tests := []struct {
10081 param string
10082 expected bool
10083 }{
10084 {"test.example.com", true},
10085 {"example.com", true},
10086 {"example24.com", true},
10087 {"test.example24.com", true},
10088 {"test24.example24.com", true},
10089 {"example", true},
10090 {"1.foo.com", true},
10091 {"test.example.com.", false},
10092 {"example.com.", false},
10093 {"example24.com.", false},
10094 {"test.example24.com.", false},
10095 {"test24.example24.com.", false},
10096 {"example.", false},
10097 {"test_example", false},
10098 {"192.168.0.1", true},
10099 {"email@example.com", false},
10100 {"2001:cdba:0000:0000:0000:0000:3257:9652", false},
10101 {"2001:cdba:0:0:0:0:3257:9652", false},
10102 {"2001:cdba::3257:9652", false},
10103 }
10104
10105 validate := New()
10106
10107 for i, test := range tests {
10108
10109 errs := validate.Var(test.param, "hostname_rfc1123")
10110
10111 if test.expected {
10112 if !IsEqual(errs, nil) {
10113 t.Fatalf("Hostname: %v failed Error: %v", test, errs)
10114 }
10115 } else {
10116 if IsEqual(errs, nil) {
10117 t.Fatalf("Hostname: %v failed Error: %v", test, errs)
10118 } else {
10119 val := getError(errs, "", "")
10120 if val.Tag() != "hostname_rfc1123" {
10121 t.Fatalf("Hostname: %v failed Error: %v", i, errs)
10122 }
10123 }
10124 }
10125 }
10126 }
10127
10128 func TestHostnameRFC1123AliasValidation(t *testing.T) {
10129 tests := []struct {
10130 param string
10131 expected bool
10132 }{
10133 {"test.example.com", true},
10134 {"example.com", true},
10135 {"example24.com", true},
10136 {"test.example24.com", true},
10137 {"test24.example24.com", true},
10138 {"example", true},
10139 {"1.foo.com", true},
10140 {"test.example.com.", false},
10141 {"example.com.", false},
10142 {"example24.com.", false},
10143 {"test.example24.com.", false},
10144 {"test24.example24.com.", false},
10145 {"example.", false},
10146 {"test_example", false},
10147 {"192.168.0.1", true},
10148 {"email@example.com", false},
10149 {"2001:cdba:0000:0000:0000:0000:3257:9652", false},
10150 {"2001:cdba:0:0:0:0:3257:9652", false},
10151 {"2001:cdba::3257:9652", false},
10152 }
10153
10154 validate := New()
10155 validate.RegisterAlias("hostname", "hostname_rfc1123")
10156
10157 for i, test := range tests {
10158
10159 errs := validate.Var(test.param, "hostname")
10160
10161 if test.expected {
10162 if !IsEqual(errs, nil) {
10163 t.Fatalf("Index: %d hostname failed Error: %v", i, errs)
10164 }
10165 } else {
10166 if IsEqual(errs, nil) {
10167 t.Fatalf("Index: %d hostname failed Error: %v", i, errs)
10168 } else {
10169 val := getError(errs, "", "")
10170 if val.Tag() != "hostname" {
10171 t.Fatalf("Index: %d hostname failed Error: %v", i, errs)
10172 }
10173 }
10174 }
10175 }
10176 }
10177
10178 func TestFQDNValidation(t *testing.T) {
10179 tests := []struct {
10180 param string
10181 expected bool
10182 }{
10183 {"test.example.com", true},
10184 {"example.com", true},
10185 {"example24.com", true},
10186 {"test.example24.com", true},
10187 {"test24.example24.com", true},
10188 {"test.example.com.", true},
10189 {"example.com.", true},
10190 {"example24.com.", true},
10191 {"test.example24.com.", true},
10192 {"test24.example24.com.", true},
10193 {"24.example24.com", true},
10194 {"test.24.example.com", true},
10195 {"test24.example24.com..", false},
10196 {"example", false},
10197 {"192.168.0.1", false},
10198 {"email@example.com", false},
10199 {"2001:cdba:0000:0000:0000:0000:3257:9652", false},
10200 {"2001:cdba:0:0:0:0:3257:9652", false},
10201 {"2001:cdba::3257:9652", false},
10202 {"", false},
10203 }
10204
10205 validate := New()
10206
10207 for i, test := range tests {
10208
10209 errs := validate.Var(test.param, "fqdn")
10210
10211 if test.expected {
10212 if !IsEqual(errs, nil) {
10213 t.Fatalf("Index: %d fqdn failed Error: %v", i, errs)
10214 }
10215 } else {
10216 if IsEqual(errs, nil) {
10217 t.Fatalf("Index: %d fqdn failed Error: %v", i, errs)
10218 } else {
10219 val := getError(errs, "", "")
10220 if val.Tag() != "fqdn" {
10221 t.Fatalf("Index: %d fqdn failed Error: %v", i, errs)
10222 }
10223 }
10224 }
10225 }
10226 }
10227
10228 func TestIsDefault(t *testing.T) {
10229 validate := New()
10230
10231 type Inner struct {
10232 String string `validate:"isdefault"`
10233 }
10234 type Test struct {
10235 String string `validate:"isdefault"`
10236 Inner *Inner `validate:"isdefault"`
10237 }
10238
10239 var tt Test
10240
10241 errs := validate.Struct(tt)
10242 Equal(t, errs, nil)
10243
10244 tt.Inner = &Inner{String: ""}
10245 errs = validate.Struct(tt)
10246 NotEqual(t, errs, nil)
10247
10248 fe := errs.(ValidationErrors)[0]
10249 Equal(t, fe.Field(), "Inner")
10250 Equal(t, fe.Namespace(), "Test.Inner")
10251 Equal(t, fe.Tag(), "isdefault")
10252
10253 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
10254 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
10255 if name == "-" {
10256 return ""
10257 }
10258 return name
10259 })
10260
10261 type Inner2 struct {
10262 String string `validate:"isdefault"`
10263 }
10264
10265 type Test2 struct {
10266 Inner Inner2 `validate:"isdefault" json:"inner"`
10267 }
10268
10269 var t2 Test2
10270 errs = validate.Struct(t2)
10271 Equal(t, errs, nil)
10272
10273 t2.Inner.String = "Changed"
10274 errs = validate.Struct(t2)
10275 NotEqual(t, errs, nil)
10276
10277 fe = errs.(ValidationErrors)[0]
10278 Equal(t, fe.Field(), "inner")
10279 Equal(t, fe.Namespace(), "Test2.inner")
10280 Equal(t, fe.Tag(), "isdefault")
10281 }
10282
10283 func TestUniqueValidation(t *testing.T) {
10284 tests := []struct {
10285 param interface{}
10286 expected bool
10287 }{
10288
10289 {[2]string{"a", "b"}, true},
10290 {[2]int{1, 2}, true},
10291 {[2]float64{1, 2}, true},
10292 {[2]interface{}{"a", "b"}, true},
10293 {[2]interface{}{"a", 1}, true},
10294 {[2]float64{1, 1}, false},
10295 {[2]int{1, 1}, false},
10296 {[2]string{"a", "a"}, false},
10297 {[2]interface{}{"a", "a"}, false},
10298 {[4]interface{}{"a", 1, "b", 1}, false},
10299 {[2]*string{stringPtr("a"), stringPtr("b")}, true},
10300 {[2]*int{intPtr(1), intPtr(2)}, true},
10301 {[2]*float64{float64Ptr(1), float64Ptr(2)}, true},
10302 {[2]*string{stringPtr("a"), stringPtr("a")}, false},
10303 {[2]*float64{float64Ptr(1), float64Ptr(1)}, false},
10304 {[2]*int{intPtr(1), intPtr(1)}, false},
10305
10306 {[]string{"a", "b"}, true},
10307 {[]int{1, 2}, true},
10308 {[]float64{1, 2}, true},
10309 {[]interface{}{"a", "b"}, true},
10310 {[]interface{}{"a", 1}, true},
10311 {[]float64{1, 1}, false},
10312 {[]int{1, 1}, false},
10313 {[]string{"a", "a"}, false},
10314 {[]interface{}{"a", "a"}, false},
10315 {[]interface{}{"a", 1, "b", 1}, false},
10316 {[]*string{stringPtr("a"), stringPtr("b")}, true},
10317 {[]*int{intPtr(1), intPtr(2)}, true},
10318 {[]*float64{float64Ptr(1), float64Ptr(2)}, true},
10319 {[]*string{stringPtr("a"), stringPtr("a")}, false},
10320 {[]*float64{float64Ptr(1), float64Ptr(1)}, false},
10321 {[]*int{intPtr(1), intPtr(1)}, false},
10322
10323 {map[string]string{"one": "a", "two": "b"}, true},
10324 {map[string]int{"one": 1, "two": 2}, true},
10325 {map[string]float64{"one": 1, "two": 2}, true},
10326 {map[string]interface{}{"one": "a", "two": "b"}, true},
10327 {map[string]interface{}{"one": "a", "two": 1}, true},
10328 {map[string]float64{"one": 1, "two": 1}, false},
10329 {map[string]int{"one": 1, "two": 1}, false},
10330 {map[string]string{"one": "a", "two": "a"}, false},
10331 {map[string]interface{}{"one": "a", "two": "a"}, false},
10332 {map[string]interface{}{"one": "a", "two": 1, "three": "b", "four": 1}, false},
10333 {map[string]*string{"one": stringPtr("a"), "two": stringPtr("a")}, false},
10334 {map[string]*string{"one": stringPtr("a"), "two": stringPtr("b")}, true},
10335 {map[string]*int{"one": intPtr(1), "two": intPtr(1)}, false},
10336 {map[string]*int{"one": intPtr(1), "two": intPtr(2)}, true},
10337 {map[string]*float64{"one": float64Ptr(1.1), "two": float64Ptr(1.1)}, false},
10338 {map[string]*float64{"one": float64Ptr(1.1), "two": float64Ptr(1.2)}, true},
10339 }
10340
10341 validate := New()
10342
10343 for i, test := range tests {
10344
10345 errs := validate.Var(test.param, "unique")
10346
10347 if test.expected {
10348 if !IsEqual(errs, nil) {
10349 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10350 }
10351 } else {
10352 if IsEqual(errs, nil) {
10353 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10354 } else {
10355 val := getError(errs, "", "")
10356 if val.Tag() != "unique" {
10357 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10358 }
10359 }
10360 }
10361 }
10362 PanicMatches(t, func() { _ = validate.Var(1.0, "unique") }, "Bad field type float64")
10363
10364 t.Run("struct", func(t *testing.T) {
10365 tests := []struct {
10366 param interface{}
10367 expected bool
10368 }{
10369 {struct {
10370 A string `validate:"unique=B"`
10371 B string
10372 }{A: "abc", B: "bcd"}, true},
10373 {struct {
10374 A string `validate:"unique=B"`
10375 B string
10376 }{A: "abc", B: "abc"}, false},
10377 }
10378 validate := New()
10379
10380 for i, test := range tests {
10381 errs := validate.Struct(test.param)
10382 if test.expected {
10383 if !IsEqual(errs, nil) {
10384 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10385 }
10386 } else {
10387 if IsEqual(errs, nil) {
10388 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10389 } else {
10390 val := getError(errs, "A", "A")
10391 if val.Tag() != "unique" {
10392 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10393 }
10394 }
10395 }
10396 }
10397 })
10398 }
10399
10400 func TestUniqueValidationStructSlice(t *testing.T) {
10401 testStructs := []struct {
10402 A string
10403 B string
10404 }{
10405 {A: "one", B: "two"},
10406 {A: "one", B: "three"},
10407 }
10408
10409 tests := []struct {
10410 target interface{}
10411 param string
10412 expected bool
10413 }{
10414 {testStructs, "unique", true},
10415 {testStructs, "unique=A", false},
10416 {testStructs, "unique=B", true},
10417 }
10418
10419 validate := New()
10420
10421 for i, test := range tests {
10422
10423 errs := validate.Var(test.target, test.param)
10424
10425 if test.expected {
10426 if !IsEqual(errs, nil) {
10427 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10428 }
10429 } else {
10430 if IsEqual(errs, nil) {
10431 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10432 } else {
10433 val := getError(errs, "", "")
10434 if val.Tag() != "unique" {
10435 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10436 }
10437 }
10438 }
10439 }
10440 PanicMatches(t, func() { _ = validate.Var(testStructs, "unique=C") }, "Bad field name C")
10441 }
10442
10443 func TestUniqueValidationStructPtrSlice(t *testing.T) {
10444 testStructs := []*struct {
10445 A *string
10446 B *string
10447 }{
10448 {A: stringPtr("one"), B: stringPtr("two")},
10449 {A: stringPtr("one"), B: stringPtr("three")},
10450 {},
10451 }
10452
10453 tests := []struct {
10454 target interface{}
10455 param string
10456 expected bool
10457 }{
10458 {testStructs, "unique", true},
10459 {testStructs, "unique=A", false},
10460 {testStructs, "unique=B", true},
10461 }
10462
10463 validate := New()
10464
10465 for i, test := range tests {
10466
10467 errs := validate.Var(test.target, test.param)
10468
10469 if test.expected {
10470 if !IsEqual(errs, nil) {
10471 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10472 }
10473 } else {
10474 if IsEqual(errs, nil) {
10475 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10476 } else {
10477 val := getError(errs, "", "")
10478 if val.Tag() != "unique" {
10479 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10480 }
10481 }
10482 }
10483 }
10484 PanicMatches(t, func() { _ = validate.Var(testStructs, "unique=C") }, "Bad field name C")
10485 }
10486
10487 func TestHTMLValidation(t *testing.T) {
10488 tests := []struct {
10489 param string
10490 expected bool
10491 }{
10492 {"<html>", true},
10493 {"<script>", true},
10494 {"<stillworks>", true},
10495 {"</html", false},
10496 {"</script>", true},
10497 {"<//script>", false},
10498 {"<123nonsense>", false},
10499 {"test", false},
10500 {"&example", false},
10501 }
10502
10503 validate := New()
10504
10505 for i, test := range tests {
10506
10507 errs := validate.Var(test.param, "html")
10508
10509 if test.expected {
10510 if !IsEqual(errs, nil) {
10511 t.Fatalf("Index: %d html failed Error: %v", i, errs)
10512 }
10513 } else {
10514 if IsEqual(errs, nil) {
10515 t.Fatalf("Index: %d html failed Error: %v", i, errs)
10516 } else {
10517 val := getError(errs, "", "")
10518 if val.Tag() != "html" {
10519 t.Fatalf("Index: %d html failed Error: %v", i, errs)
10520 }
10521 }
10522 }
10523 }
10524 }
10525
10526 func TestHTMLEncodedValidation(t *testing.T) {
10527 tests := []struct {
10528 param string
10529 expected bool
10530 }{
10531 {"<", true},
10532 {"¯", true},
10533 {"�", true},
10534 {"ð", true},
10535 {"<", true},
10536 {"¯", true},
10537 {"�", true},
10538 {"ð", true},
10539 {"&#ab", true},
10540 {"<", true},
10541 {">", true},
10542 {""", true},
10543 {"&", true},
10544 {"#x0a", false},
10545 {"&x00", false},
10546 {"z", false},
10547 }
10548
10549 validate := New()
10550
10551 for i, test := range tests {
10552
10553 errs := validate.Var(test.param, "html_encoded")
10554
10555 if test.expected {
10556 if !IsEqual(errs, nil) {
10557 t.Fatalf("Index: %d html_encoded failed Error: %v", i, errs)
10558 }
10559 } else {
10560 if IsEqual(errs, nil) {
10561 t.Fatalf("Index: %d html_enocded failed Error: %v", i, errs)
10562 } else {
10563 val := getError(errs, "", "")
10564 if val.Tag() != "html_encoded" {
10565 t.Fatalf("Index: %d html_encoded failed Error: %v", i, errs)
10566 }
10567 }
10568 }
10569 }
10570 }
10571
10572 func TestURLEncodedValidation(t *testing.T) {
10573 tests := []struct {
10574 param string
10575 expected bool
10576 }{
10577 {"%20", true},
10578 {"%af", true},
10579 {"%ff", true},
10580 {"<%az", false},
10581 {"%test%", false},
10582 {"a%b", false},
10583 {"1%2", false},
10584 {"%%a%%", false},
10585 {"hello", true},
10586 {"", true},
10587 {"+", true},
10588 }
10589
10590 validate := New()
10591
10592 for i, test := range tests {
10593
10594 errs := validate.Var(test.param, "url_encoded")
10595
10596 if test.expected {
10597 if !IsEqual(errs, nil) {
10598 t.Fatalf("Index: %d url_encoded failed Error: %v", i, errs)
10599 }
10600 } else {
10601 if IsEqual(errs, nil) {
10602 t.Fatalf("Index: %d url_enocded failed Error: %v", i, errs)
10603 } else {
10604 val := getError(errs, "", "")
10605 if val.Tag() != "url_encoded" {
10606 t.Fatalf("Index: %d url_encoded failed Error: %v", i, errs)
10607 }
10608 }
10609 }
10610 }
10611 }
10612
10613 func TestKeys(t *testing.T) {
10614 type Test struct {
10615 Test1 map[string]string `validate:"gt=0,dive,keys,eq=testkey,endkeys,eq=testval" json:"test1"`
10616 Test2 map[int]int `validate:"gt=0,dive,keys,eq=3,endkeys,eq=4" json:"test2"`
10617 Test3 map[int]int `validate:"gt=0,dive,keys,eq=3,endkeys" json:"test3"`
10618 }
10619
10620 var tst Test
10621
10622 validate := New()
10623 err := validate.Struct(tst)
10624 NotEqual(t, err, nil)
10625 Equal(t, len(err.(ValidationErrors)), 3)
10626 AssertError(t, err.(ValidationErrors), "Test.Test1", "Test.Test1", "Test1", "Test1", "gt")
10627 AssertError(t, err.(ValidationErrors), "Test.Test2", "Test.Test2", "Test2", "Test2", "gt")
10628 AssertError(t, err.(ValidationErrors), "Test.Test3", "Test.Test3", "Test3", "Test3", "gt")
10629
10630 tst.Test1 = map[string]string{
10631 "testkey": "testval",
10632 }
10633
10634 tst.Test2 = map[int]int{
10635 3: 4,
10636 }
10637
10638 tst.Test3 = map[int]int{
10639 3: 4,
10640 }
10641
10642 err = validate.Struct(tst)
10643 Equal(t, err, nil)
10644
10645 tst.Test1["badtestkey"] = "badtestvalue"
10646 tst.Test2[10] = 11
10647
10648 err = validate.Struct(tst)
10649 NotEqual(t, err, nil)
10650
10651 errs := err.(ValidationErrors)
10652
10653 Equal(t, len(errs), 4)
10654
10655 AssertDeepError(t, errs, "Test.Test1[badtestkey]", "Test.Test1[badtestkey]", "Test1[badtestkey]", "Test1[badtestkey]", "eq", "eq")
10656 AssertDeepError(t, errs, "Test.Test1[badtestkey]", "Test.Test1[badtestkey]", "Test1[badtestkey]", "Test1[badtestkey]", "eq", "eq")
10657 AssertDeepError(t, errs, "Test.Test2[10]", "Test.Test2[10]", "Test2[10]", "Test2[10]", "eq", "eq")
10658 AssertDeepError(t, errs, "Test.Test2[10]", "Test.Test2[10]", "Test2[10]", "Test2[10]", "eq", "eq")
10659
10660 type Test2 struct {
10661 NestedKeys map[[1]string]string `validate:"gt=0,dive,keys,dive,eq=innertestkey,endkeys,eq=outertestval"`
10662 }
10663
10664 var tst2 Test2
10665
10666 err = validate.Struct(tst2)
10667 NotEqual(t, err, nil)
10668 Equal(t, len(err.(ValidationErrors)), 1)
10669 AssertError(t, err.(ValidationErrors), "Test2.NestedKeys", "Test2.NestedKeys", "NestedKeys", "NestedKeys", "gt")
10670
10671 tst2.NestedKeys = map[[1]string]string{
10672 {"innertestkey"}: "outertestval",
10673 }
10674
10675 err = validate.Struct(tst2)
10676 Equal(t, err, nil)
10677
10678 tst2.NestedKeys[[1]string{"badtestkey"}] = "badtestvalue"
10679
10680 err = validate.Struct(tst2)
10681 NotEqual(t, err, nil)
10682
10683 errs = err.(ValidationErrors)
10684
10685 Equal(t, len(errs), 2)
10686 AssertDeepError(t, errs, "Test2.NestedKeys[[badtestkey]][0]", "Test2.NestedKeys[[badtestkey]][0]", "NestedKeys[[badtestkey]][0]", "NestedKeys[[badtestkey]][0]", "eq", "eq")
10687 AssertDeepError(t, errs, "Test2.NestedKeys[[badtestkey]]", "Test2.NestedKeys[[badtestkey]]", "NestedKeys[[badtestkey]]", "NestedKeys[[badtestkey]]", "eq", "eq")
10688
10689
10690
10691 PanicMatches(t, func() { _ = validate.Var(map[string]string{"key": "val"}, "endkeys,dive,eq=val") }, "'endkeys' tag encountered without a corresponding 'keys' tag")
10692 PanicMatches(t, func() { _ = validate.Var(1, "keys,eq=1,endkeys") }, "'keys' tag must be immediately preceded by the 'dive' tag")
10693
10694
10695 validate = New()
10696 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
10697 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
10698
10699 if name == "-" {
10700 return ""
10701 }
10702 return name
10703 })
10704
10705 err = validate.Struct(tst)
10706 NotEqual(t, err, nil)
10707
10708 errs = err.(ValidationErrors)
10709
10710 Equal(t, len(errs), 4)
10711
10712 AssertDeepError(t, errs, "Test.test1[badtestkey]", "Test.Test1[badtestkey]", "test1[badtestkey]", "Test1[badtestkey]", "eq", "eq")
10713 AssertDeepError(t, errs, "Test.test1[badtestkey]", "Test.Test1[badtestkey]", "test1[badtestkey]", "Test1[badtestkey]", "eq", "eq")
10714 AssertDeepError(t, errs, "Test.test2[10]", "Test.Test2[10]", "test2[10]", "Test2[10]", "eq", "eq")
10715 AssertDeepError(t, errs, "Test.test2[10]", "Test.Test2[10]", "test2[10]", "Test2[10]", "eq", "eq")
10716 }
10717
10718
10719 func TestKeysCustomValidation(t *testing.T) {
10720 type LangCode string
10721 type Label map[LangCode]string
10722
10723 type TestMapStructPtr struct {
10724 Label Label `validate:"dive,keys,lang_code,endkeys,required"`
10725 }
10726
10727 validate := New()
10728 err := validate.RegisterValidation("lang_code", func(fl FieldLevel) bool {
10729 validLangCodes := map[LangCode]struct{}{
10730 "en": {},
10731 "es": {},
10732 "pt": {},
10733 }
10734
10735 _, ok := validLangCodes[fl.Field().Interface().(LangCode)]
10736 return ok
10737 })
10738 Equal(t, err, nil)
10739
10740 label := Label{
10741 "en": "Good morning!",
10742 "pt": "",
10743 "es": "¡Buenos días!",
10744 "xx": "Bad key",
10745 "xxx": "",
10746 }
10747
10748 err = validate.Struct(TestMapStructPtr{label})
10749 NotEqual(t, err, nil)
10750
10751 errs := err.(ValidationErrors)
10752 Equal(t, len(errs), 4)
10753
10754 AssertDeepError(t, errs, "TestMapStructPtr.Label[xx]", "TestMapStructPtr.Label[xx]", "Label[xx]", "Label[xx]", "lang_code", "lang_code")
10755 AssertDeepError(t, errs, "TestMapStructPtr.Label[pt]", "TestMapStructPtr.Label[pt]", "Label[pt]", "Label[pt]", "required", "required")
10756 AssertDeepError(t, errs, "TestMapStructPtr.Label[xxx]", "TestMapStructPtr.Label[xxx]", "Label[xxx]", "Label[xxx]", "lang_code", "lang_code")
10757 AssertDeepError(t, errs, "TestMapStructPtr.Label[xxx]", "TestMapStructPtr.Label[xxx]", "Label[xxx]", "Label[xxx]", "required", "required")
10758
10759
10760
10761 var e FieldError
10762 for _, e = range errs {
10763 if e.Namespace() == "TestMapStructPtr.Label[xxx]" {
10764 break
10765 }
10766 }
10767
10768 Equal(t, e.Param(), "")
10769 Equal(t, e.Value().(LangCode), LangCode("xxx"))
10770
10771 for _, e = range errs {
10772 if e.Namespace() == "TestMapStructPtr.Label[xxx]" && e.Tag() == "required" {
10773 break
10774 }
10775 }
10776
10777 Equal(t, e.Param(), "")
10778 Equal(t, e.Value().(string), "")
10779 }
10780
10781 func TestKeyOrs(t *testing.T) {
10782 type Test struct {
10783 Test1 map[string]string `validate:"gt=0,dive,keys,eq=testkey|eq=testkeyok,endkeys,eq=testval" json:"test1"`
10784 }
10785
10786 var tst Test
10787
10788 validate := New()
10789 err := validate.Struct(tst)
10790 NotEqual(t, err, nil)
10791 Equal(t, len(err.(ValidationErrors)), 1)
10792 AssertError(t, err.(ValidationErrors), "Test.Test1", "Test.Test1", "Test1", "Test1", "gt")
10793
10794 tst.Test1 = map[string]string{
10795 "testkey": "testval",
10796 }
10797
10798 err = validate.Struct(tst)
10799 Equal(t, err, nil)
10800
10801 tst.Test1["badtestkey"] = "badtestval"
10802
10803 err = validate.Struct(tst)
10804 NotEqual(t, err, nil)
10805
10806 errs := err.(ValidationErrors)
10807
10808 Equal(t, len(errs), 2)
10809
10810 AssertDeepError(t, errs, "Test.Test1[badtestkey]", "Test.Test1[badtestkey]", "Test1[badtestkey]", "Test1[badtestkey]", "eq=testkey|eq=testkeyok", "eq=testkey|eq=testkeyok")
10811 AssertDeepError(t, errs, "Test.Test1[badtestkey]", "Test.Test1[badtestkey]", "Test1[badtestkey]", "Test1[badtestkey]", "eq", "eq")
10812
10813 validate.RegisterAlias("okkey", "eq=testkey|eq=testkeyok")
10814
10815 type Test2 struct {
10816 Test1 map[string]string `validate:"gt=0,dive,keys,okkey,endkeys,eq=testval" json:"test1"`
10817 }
10818
10819 var tst2 Test2
10820
10821 err = validate.Struct(tst2)
10822 NotEqual(t, err, nil)
10823 Equal(t, len(err.(ValidationErrors)), 1)
10824 AssertError(t, err.(ValidationErrors), "Test2.Test1", "Test2.Test1", "Test1", "Test1", "gt")
10825
10826 tst2.Test1 = map[string]string{
10827 "testkey": "testval",
10828 }
10829
10830 err = validate.Struct(tst2)
10831 Equal(t, err, nil)
10832
10833 tst2.Test1["badtestkey"] = "badtestval"
10834
10835 err = validate.Struct(tst2)
10836 NotEqual(t, err, nil)
10837
10838 errs = err.(ValidationErrors)
10839
10840 Equal(t, len(errs), 2)
10841
10842 AssertDeepError(t, errs, "Test2.Test1[badtestkey]", "Test2.Test1[badtestkey]", "Test1[badtestkey]", "Test1[badtestkey]", "okkey", "eq=testkey|eq=testkeyok")
10843 AssertDeepError(t, errs, "Test2.Test1[badtestkey]", "Test2.Test1[badtestkey]", "Test1[badtestkey]", "Test1[badtestkey]", "eq", "eq")
10844 }
10845
10846 func TestStructLevelValidationsPointerPassing(t *testing.T) {
10847 v1 := New()
10848 v1.RegisterStructValidation(StructValidationTestStruct, &TestStruct{})
10849
10850 tst := &TestStruct{
10851 String: "good value",
10852 }
10853
10854 errs := v1.Struct(tst)
10855 NotEqual(t, errs, nil)
10856 AssertError(t, errs, "TestStruct.StringVal", "TestStruct.String", "StringVal", "String", "badvalueteststruct")
10857 }
10858
10859 func TestDirValidation(t *testing.T) {
10860 validate := New()
10861
10862 tests := []struct {
10863 title string
10864 param string
10865 expected bool
10866 }{
10867 {"existing dir", "testdata", true},
10868 {"existing self dir", ".", true},
10869 {"existing parent dir", "..", true},
10870 {"empty dir", "", false},
10871 {"missing dir", "non_existing_testdata", false},
10872 {"a file not a directory", filepath.Join("testdata", "a.go"), false},
10873 }
10874
10875 for _, test := range tests {
10876 errs := validate.Var(test.param, "dir")
10877
10878 if test.expected {
10879 if !IsEqual(errs, nil) {
10880 t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
10881 }
10882 } else {
10883 if IsEqual(errs, nil) {
10884 t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
10885 }
10886 }
10887 }
10888
10889 PanicMatches(t, func() {
10890 _ = validate.Var(2, "dir")
10891 }, "Bad field type int")
10892 }
10893
10894 func TestDirPathValidation(t *testing.T) {
10895 validate := New()
10896
10897 tests := []struct {
10898 title string
10899 param string
10900 expected bool
10901 }{
10902 {"empty dirpath", "", false},
10903 {"valid dirpath - exists", "testdata", true},
10904 {"valid dirpath - explicit", "testdatanoexist" + string(os.PathSeparator), true},
10905 {"invalid dirpath", "testdata\000" + string(os.PathSeparator), false},
10906 {"file, not a dirpath", filepath.Join("testdata", "a.go"), false},
10907 }
10908
10909 for _, test := range tests {
10910 errs := validate.Var(test.param, "dirpath")
10911
10912 if test.expected {
10913 if !IsEqual(errs, nil) {
10914 t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
10915 }
10916 } else {
10917 if IsEqual(errs, nil) {
10918 t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
10919 }
10920 }
10921 }
10922
10923 PanicMatches(t, func() {
10924 _ = validate.Var(6, "filepath")
10925 }, "Bad field type int")
10926 }
10927
10928 func TestStartsWithValidation(t *testing.T) {
10929 tests := []struct {
10930 Value string `validate:"startswith=(/^ヮ^)/*:・゚✧"`
10931 Tag string
10932 ExpectedNil bool
10933 }{
10934 {Value: "(/^ヮ^)/*:・゚✧ glitter", Tag: "startswith=(/^ヮ^)/*:・゚✧", ExpectedNil: true},
10935 {Value: "abcd", Tag: "startswith=(/^ヮ^)/*:・゚✧", ExpectedNil: false},
10936 }
10937
10938 validate := New()
10939
10940 for i, s := range tests {
10941 errs := validate.Var(s.Value, s.Tag)
10942
10943 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
10944 t.Fatalf("Index: %d failed Error: %s", i, errs)
10945 }
10946
10947 errs = validate.Struct(s)
10948
10949 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
10950 t.Fatalf("Index: %d failed Error: %s", i, errs)
10951 }
10952 }
10953 }
10954
10955 func TestEndsWithValidation(t *testing.T) {
10956 tests := []struct {
10957 Value string `validate:"endswith=(/^ヮ^)/*:・゚✧"`
10958 Tag string
10959 ExpectedNil bool
10960 }{
10961 {Value: "glitter (/^ヮ^)/*:・゚✧", Tag: "endswith=(/^ヮ^)/*:・゚✧", ExpectedNil: true},
10962 {Value: "(/^ヮ^)/*:・゚✧ glitter", Tag: "endswith=(/^ヮ^)/*:・゚✧", ExpectedNil: false},
10963 }
10964
10965 validate := New()
10966
10967 for i, s := range tests {
10968 errs := validate.Var(s.Value, s.Tag)
10969
10970 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
10971 t.Fatalf("Index: %d failed Error: %s", i, errs)
10972 }
10973
10974 errs = validate.Struct(s)
10975
10976 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
10977 t.Fatalf("Index: %d failed Error: %s", i, errs)
10978 }
10979 }
10980 }
10981
10982 func TestRequiredIf(t *testing.T) {
10983 type Inner struct {
10984 Field *string
10985 }
10986
10987 fieldVal := "test"
10988 test := struct {
10989 Inner *Inner
10990 FieldE string `validate:"omitempty" json:"field_e"`
10991 FieldER string `validate:"required_if=FieldE test" json:"field_er"`
10992 Field1 string `validate:"omitempty" json:"field_1"`
10993 Field2 *string `validate:"required_if=Field1 test" json:"field_2"`
10994 Field3 map[string]string `validate:"required_if=Field2 test" json:"field_3"`
10995 Field4 interface{} `validate:"required_if=Field3 1" json:"field_4"`
10996 Field5 int `validate:"required_if=Inner.Field test" json:"field_5"`
10997 Field6 uint `validate:"required_if=Field5 1" json:"field_6"`
10998 Field7 float32 `validate:"required_if=Field6 1" json:"field_7"`
10999 Field8 float64 `validate:"required_if=Field7 1.0" json:"field_8"`
11000 Field9 Inner `validate:"required_if=Field1 test" json:"field_9"`
11001 Field10 *Inner `validate:"required_if=Field1 test" json:"field_10"`
11002 }{
11003 Inner: &Inner{Field: &fieldVal},
11004 Field2: &fieldVal,
11005 Field3: map[string]string{"key": "val"},
11006 Field4: "test",
11007 Field5: 2,
11008 }
11009
11010 validate := New()
11011
11012 errs := validate.Struct(test)
11013 Equal(t, errs, nil)
11014
11015 test2 := struct {
11016 Inner *Inner
11017 Inner2 *Inner
11018 FieldE string `validate:"omitempty" json:"field_e"`
11019 FieldER string `validate:"required_if=FieldE test" json:"field_er"`
11020 Field1 string `validate:"omitempty" json:"field_1"`
11021 Field2 *string `validate:"required_if=Field1 test" json:"field_2"`
11022 Field3 map[string]string `validate:"required_if=Field2 test" json:"field_3"`
11023 Field4 interface{} `validate:"required_if=Field2 test" json:"field_4"`
11024 Field5 string `validate:"required_if=Field3 1" json:"field_5"`
11025 Field6 string `validate:"required_if=Inner.Field test" json:"field_6"`
11026 Field7 string `validate:"required_if=Inner2.Field test" json:"field_7"`
11027 Field8 Inner `validate:"required_if=Field2 test" json:"field_8"`
11028 Field9 *Inner `validate:"required_if=Field2 test" json:"field_9"`
11029 }{
11030 Inner: &Inner{Field: &fieldVal},
11031 Field2: &fieldVal,
11032 }
11033
11034 errs = validate.Struct(test2)
11035 NotEqual(t, errs, nil)
11036
11037 ve := errs.(ValidationErrors)
11038 Equal(t, len(ve), 5)
11039 AssertError(t, errs, "Field3", "Field3", "Field3", "Field3", "required_if")
11040 AssertError(t, errs, "Field4", "Field4", "Field4", "Field4", "required_if")
11041 AssertError(t, errs, "Field6", "Field6", "Field6", "Field6", "required_if")
11042 AssertError(t, errs, "Field8", "Field8", "Field8", "Field8", "required_if")
11043 AssertError(t, errs, "Field9", "Field9", "Field9", "Field9", "required_if")
11044
11045 defer func() {
11046 if r := recover(); r == nil {
11047 t.Errorf("test3 should have panicked!")
11048 }
11049 }()
11050
11051 test3 := struct {
11052 Inner *Inner
11053 Field1 string `validate:"required_if=Inner.Field" json:"field_1"`
11054 }{
11055 Inner: &Inner{Field: &fieldVal},
11056 }
11057 _ = validate.Struct(test3)
11058 }
11059
11060 func TestRequiredUnless(t *testing.T) {
11061 type Inner struct {
11062 Field *string
11063 }
11064
11065 fieldVal := "test"
11066 test := struct {
11067 Inner *Inner
11068 FieldE string `validate:"omitempty" json:"field_e"`
11069 FieldER string `validate:"required_unless=FieldE test" json:"field_er"`
11070 Field1 string `validate:"omitempty" json:"field_1"`
11071 Field2 *string `validate:"required_unless=Field1 test" json:"field_2"`
11072 Field3 map[string]string `validate:"required_unless=Field2 test" json:"field_3"`
11073 Field4 interface{} `validate:"required_unless=Field3 1" json:"field_4"`
11074 Field5 int `validate:"required_unless=Inner.Field test" json:"field_5"`
11075 Field6 uint `validate:"required_unless=Field5 2" json:"field_6"`
11076 Field7 float32 `validate:"required_unless=Field6 0" json:"field_7"`
11077 Field8 float64 `validate:"required_unless=Field7 0.0" json:"field_8"`
11078 Field9 bool `validate:"omitempty" json:"field_9"`
11079 Field10 string `validate:"required_unless=Field9 true" json:"field_10"`
11080 Field11 Inner `validate:"required_unless=Field9 true" json:"field_11"`
11081 Field12 *Inner `validate:"required_unless=Field9 true" json:"field_12"`
11082 }{
11083 FieldE: "test",
11084 Field2: &fieldVal,
11085 Field3: map[string]string{"key": "val"},
11086 Field4: "test",
11087 Field5: 2,
11088 Field9: true,
11089 }
11090
11091 validate := New()
11092
11093 errs := validate.Struct(test)
11094 Equal(t, errs, nil)
11095
11096 test2 := struct {
11097 Inner *Inner
11098 Inner2 *Inner
11099 FieldE string `validate:"omitempty" json:"field_e"`
11100 FieldER string `validate:"required_unless=FieldE test" json:"field_er"`
11101 Field1 string `validate:"omitempty" json:"field_1"`
11102 Field2 *string `validate:"required_unless=Field1 test" json:"field_2"`
11103 Field3 map[string]string `validate:"required_unless=Field2 test" json:"field_3"`
11104 Field4 interface{} `validate:"required_unless=Field2 test" json:"field_4"`
11105 Field5 string `validate:"required_unless=Field3 0" json:"field_5"`
11106 Field6 string `validate:"required_unless=Inner.Field test" json:"field_6"`
11107 Field7 string `validate:"required_unless=Inner2.Field test" json:"field_7"`
11108 Field8 bool `validate:"omitempty" json:"field_8"`
11109 Field9 string `validate:"required_unless=Field8 true" json:"field_9"`
11110 Field10 Inner `validate:"required_unless=Field9 true" json:"field_10"`
11111 Field11 *Inner `validate:"required_unless=Field9 true" json:"field_11"`
11112 }{
11113 Inner: &Inner{Field: &fieldVal},
11114 FieldE: "test",
11115 Field1: "test",
11116 }
11117
11118 errs = validate.Struct(test2)
11119 NotEqual(t, errs, nil)
11120
11121 ve := errs.(ValidationErrors)
11122 Equal(t, len(ve), 6)
11123 AssertError(t, errs, "Field3", "Field3", "Field3", "Field3", "required_unless")
11124 AssertError(t, errs, "Field4", "Field4", "Field4", "Field4", "required_unless")
11125 AssertError(t, errs, "Field7", "Field7", "Field7", "Field7", "required_unless")
11126 AssertError(t, errs, "Field9", "Field9", "Field9", "Field9", "required_unless")
11127 AssertError(t, errs, "Field10", "Field10", "Field10", "Field10", "required_unless")
11128 AssertError(t, errs, "Field11", "Field11", "Field11", "Field11", "required_unless")
11129
11130 defer func() {
11131 if r := recover(); r == nil {
11132 t.Errorf("test3 should have panicked!")
11133 }
11134 }()
11135
11136 test3 := struct {
11137 Inner *Inner
11138 Field1 string `validate:"required_unless=Inner.Field" json:"field_1"`
11139 }{
11140 Inner: &Inner{Field: &fieldVal},
11141 }
11142 _ = validate.Struct(test3)
11143 }
11144
11145 func TestSkipUnless(t *testing.T) {
11146 type Inner struct {
11147 Field *string
11148 }
11149
11150 fieldVal := "test1"
11151 test := struct {
11152 Inner *Inner
11153 FieldE string `validate:"omitempty" json:"field_e"`
11154 FieldER string `validate:"skip_unless=FieldE test" json:"field_er"`
11155 Field1 string `validate:"omitempty" json:"field_1"`
11156 Field2 *string `validate:"skip_unless=Field1 test" json:"field_2"`
11157 Field3 map[string]string `validate:"skip_unless=Field2 test" json:"field_3"`
11158 Field4 interface{} `validate:"skip_unless=Field3 1" json:"field_4"`
11159 Field5 int `validate:"skip_unless=Inner.Field test" json:"field_5"`
11160 Field6 uint `validate:"skip_unless=Field5 2" json:"field_6"`
11161 Field7 float32 `validate:"skip_unless=Field6 1" json:"field_7"`
11162 Field8 float64 `validate:"skip_unless=Field7 1.0" json:"field_8"`
11163 Field9 bool `validate:"omitempty" json:"field_9"`
11164 Field10 string `validate:"skip_unless=Field9 false" json:"field_10"`
11165 Field11 Inner `validate:"skip_unless=Field9 false" json:"field_11"`
11166 Field12 *Inner `validate:"skip_unless=Field9 false" json:"field_12"`
11167 }{
11168 FieldE: "test1",
11169 Field2: &fieldVal,
11170 Field3: map[string]string{"key": "val"},
11171 Field4: "test",
11172 Field5: 3,
11173 Field9: true,
11174 }
11175
11176 validate := New()
11177
11178 errs := validate.Struct(test)
11179 Equal(t, errs, nil)
11180
11181 test2 := struct {
11182 Inner *Inner
11183 Inner2 *Inner
11184 FieldE string `validate:"omitempty" json:"field_e"`
11185 FieldER string `validate:"skip_unless=FieldE test" json:"field_er"`
11186 Field1 string `validate:"omitempty" json:"field_1"`
11187 Field2 *string `validate:"skip_unless=Field1 test" json:"field_2"`
11188 Field3 map[string]string `validate:"skip_unless=Field2 test" json:"field_3"`
11189 Field4 interface{} `validate:"skip_unless=Field2 test" json:"field_4"`
11190 Field5 string `validate:"skip_unless=Field3 0" json:"field_5"`
11191 Field6 string `validate:"skip_unless=Inner.Field test" json:"field_6"`
11192 Field7 string `validate:"skip_unless=Inner2.Field test" json:"field_7"`
11193 Field8 bool `validate:"omitempty" json:"field_8"`
11194 Field9 string `validate:"skip_unless=Field8 true" json:"field_9"`
11195 Field10 Inner `validate:"skip_unless=Field8 false" json:"field_10"`
11196 Field11 *Inner `validate:"skip_unless=Field8 false" json:"field_11"`
11197 }{
11198 Inner: &Inner{Field: &fieldVal},
11199 FieldE: "test1",
11200 Field1: "test1",
11201 }
11202
11203 errs = validate.Struct(test2)
11204 NotEqual(t, errs, nil)
11205
11206 ve := errs.(ValidationErrors)
11207 Equal(t, len(ve), 3)
11208 AssertError(t, errs, "Field5", "Field5", "Field5", "Field5", "skip_unless")
11209 AssertError(t, errs, "Field10", "Field10", "Field10", "Field10", "skip_unless")
11210 AssertError(t, errs, "Field11", "Field11", "Field11", "Field11", "skip_unless")
11211
11212 test3 := struct {
11213 Inner *Inner
11214 Field1 string `validate:"skip_unless=Inner.Field" json:"field_1"`
11215 }{
11216 Inner: &Inner{Field: &fieldVal},
11217 }
11218 PanicMatches(t, func() {
11219 _ = validate.Struct(test3)
11220 }, "Bad param number for skip_unless Field1")
11221
11222 test4 := struct {
11223 Inner *Inner
11224 Field1 string `validate:"skip_unless=Inner.Field test1" json:"field_1"`
11225 }{
11226 Inner: &Inner{Field: &fieldVal},
11227 }
11228 errs = validate.Struct(test4)
11229 NotEqual(t, errs, nil)
11230
11231 ve = errs.(ValidationErrors)
11232 Equal(t, len(ve), 1)
11233 AssertError(t, errs, "Field1", "Field1", "Field1", "Field1", "skip_unless")
11234 }
11235
11236 func TestRequiredWith(t *testing.T) {
11237 type Inner struct {
11238 Field *string
11239 }
11240
11241 fieldVal := "test"
11242 test := struct {
11243 Inner *Inner
11244 FieldE string `validate:"omitempty" json:"field_e"`
11245 FieldER string `validate:"required_with=FieldE" json:"field_er"`
11246 Field1 string `validate:"omitempty" json:"field_1"`
11247 Field2 *string `validate:"required_with=Field1" json:"field_2"`
11248 Field3 map[string]string `validate:"required_with=Field2" json:"field_3"`
11249 Field4 interface{} `validate:"required_with=Field3" json:"field_4"`
11250 Field5 string `validate:"required_with=Field" json:"field_5"`
11251 Field6 Inner `validate:"required_with=Field2" json:"field_6"`
11252 Field7 *Inner `validate:"required_with=Field2" json:"field_7"`
11253 }{
11254 Inner: &Inner{Field: &fieldVal},
11255 Field2: &fieldVal,
11256 Field3: map[string]string{"key": "val"},
11257 Field4: "test",
11258 Field5: "test",
11259 Field6: Inner{Field: &fieldVal},
11260 Field7: &Inner{Field: &fieldVal},
11261 }
11262
11263 validate := New()
11264
11265 errs := validate.Struct(test)
11266 Equal(t, errs, nil)
11267
11268 test2 := struct {
11269 Inner *Inner
11270 Inner2 *Inner
11271 FieldE string `validate:"omitempty" json:"field_e"`
11272 FieldER string `validate:"required_with=FieldE" json:"field_er"`
11273 Field1 string `validate:"omitempty" json:"field_1"`
11274 Field2 *string `validate:"required_with=Field1" json:"field_2"`
11275 Field3 map[string]string `validate:"required_with=Field2" json:"field_3"`
11276 Field4 interface{} `validate:"required_with=Field2" json:"field_4"`
11277 Field5 string `validate:"required_with=Field3" json:"field_5"`
11278 Field6 string `validate:"required_with=Inner.Field" json:"field_6"`
11279 Field7 string `validate:"required_with=Inner2.Field" json:"field_7"`
11280 Field8 Inner `validate:"required_with=Field2" json:"field_8"`
11281 Field9 *Inner `validate:"required_with=Field2" json:"field_9"`
11282 }{
11283 Inner: &Inner{Field: &fieldVal},
11284 Field2: &fieldVal,
11285 }
11286
11287 errs = validate.Struct(test2)
11288 NotEqual(t, errs, nil)
11289
11290 ve := errs.(ValidationErrors)
11291 Equal(t, len(ve), 5)
11292 AssertError(t, errs, "Field3", "Field3", "Field3", "Field3", "required_with")
11293 AssertError(t, errs, "Field4", "Field4", "Field4", "Field4", "required_with")
11294 AssertError(t, errs, "Field6", "Field6", "Field6", "Field6", "required_with")
11295 AssertError(t, errs, "Field8", "Field8", "Field8", "Field8", "required_with")
11296 AssertError(t, errs, "Field9", "Field9", "Field9", "Field9", "required_with")
11297 }
11298
11299 func TestExcludedWith(t *testing.T) {
11300 type Inner struct {
11301 FieldE string
11302 Field *string
11303 }
11304
11305 fieldVal := "test"
11306 test := struct {
11307 Inner *Inner
11308 Inner2 *Inner
11309 Field string `validate:"omitempty" json:"field"`
11310 FieldE string `validate:"omitempty" json:"field_e"`
11311 Field1 string `validate:"excluded_with=FieldE" json:"field_1"`
11312 Field2 *string `validate:"excluded_with=FieldE" json:"field_2"`
11313 Field3 map[string]string `validate:"excluded_with=FieldE" json:"field_3"`
11314 Field4 interface{} `validate:"excluded_with=FieldE" json:"field_4"`
11315 Field5 string `validate:"excluded_with=Inner.FieldE" json:"field_5"`
11316 Field6 string `validate:"excluded_with=Inner2.FieldE" json:"field_6"`
11317 Field7 Inner `validate:"excluded_with=FieldE" json:"field_7"`
11318 Field8 *Inner `validate:"excluded_with=FieldE" json:"field_8"`
11319 }{
11320 Inner: &Inner{Field: &fieldVal},
11321 Field1: fieldVal,
11322 Field2: &fieldVal,
11323 Field3: map[string]string{"key": "val"},
11324 Field4: "test",
11325 Field5: "test",
11326 Field6: "test",
11327 }
11328
11329 validate := New()
11330
11331 errs := validate.Struct(test)
11332 Equal(t, errs, nil)
11333
11334 test2 := struct {
11335 Inner *Inner
11336 Inner2 *Inner
11337 Field string `validate:"omitempty" json:"field"`
11338 FieldE string `validate:"omitempty" json:"field_e"`
11339 Field1 string `validate:"excluded_with=Field" json:"field_1"`
11340 Field2 *string `validate:"excluded_with=Field" json:"field_2"`
11341 Field3 map[string]string `validate:"excluded_with=Field" json:"field_3"`
11342 Field4 interface{} `validate:"excluded_with=Field" json:"field_4"`
11343 Field5 string `validate:"excluded_with=Inner.Field" json:"field_5"`
11344 Field6 string `validate:"excluded_with=Inner2.Field" json:"field_6"`
11345 Field7 Inner `validate:"excluded_with=Field" json:"field_7"`
11346 Field8 *Inner `validate:"excluded_with=Field" json:"field_8"`
11347 }{
11348 Inner: &Inner{Field: &fieldVal},
11349 Field: "populated",
11350 Field1: fieldVal,
11351 Field2: &fieldVal,
11352 Field3: map[string]string{"key": "val"},
11353 Field4: "test",
11354 Field5: "test",
11355 Field6: "test",
11356 Field7: Inner{FieldE: "potato"},
11357 Field8: &Inner{FieldE: "potato"},
11358 }
11359
11360 errs = validate.Struct(test2)
11361 NotEqual(t, errs, nil)
11362
11363 ve := errs.(ValidationErrors)
11364 Equal(t, len(ve), 7)
11365 for i := 1; i <= 7; i++ {
11366
11367 if i > 5 {
11368 i++
11369 }
11370 name := fmt.Sprintf("Field%d", i)
11371 AssertError(t, errs, name, name, name, name, "excluded_with")
11372 }
11373
11374 test3 := struct {
11375 Inner *Inner
11376 Inner2 *Inner
11377 Field string `validate:"omitempty" json:"field"`
11378 FieldE string `validate:"omitempty" json:"field_e"`
11379 Field1 string `validate:"excluded_with=FieldE" json:"field_1"`
11380 Field2 *string `validate:"excluded_with=FieldE" json:"field_2"`
11381 Field3 map[string]string `validate:"excluded_with=FieldE" json:"field_3"`
11382 Field4 interface{} `validate:"excluded_with=FieldE" json:"field_4"`
11383 Field5 string `validate:"excluded_with=Inner.FieldE" json:"field_5"`
11384 Field6 string `validate:"excluded_with=Inner2.FieldE" json:"field_6"`
11385 Field7 Inner `validate:"excluded_with=FieldE" json:"field_7"`
11386 Field8 *Inner `validate:"excluded_with=FieldE" json:"field_8"`
11387 }{
11388 Inner: &Inner{FieldE: "populated"},
11389 Inner2: &Inner{FieldE: "populated"},
11390 FieldE: "populated",
11391 }
11392
11393 validate = New()
11394
11395 errs = validate.Struct(test3)
11396 Equal(t, errs, nil)
11397 }
11398
11399 func TestExcludedWithout(t *testing.T) {
11400 type Inner struct {
11401 FieldE string
11402 Field *string
11403 }
11404
11405 fieldVal := "test"
11406 test := struct {
11407 Inner *Inner
11408 Inner2 *Inner
11409 Field string `validate:"omitempty" json:"field"`
11410 FieldE string `validate:"omitempty" json:"field_e"`
11411 Field1 string `validate:"excluded_without=Field" json:"field_1"`
11412 Field2 *string `validate:"excluded_without=Field" json:"field_2"`
11413 Field3 map[string]string `validate:"excluded_without=Field" json:"field_3"`
11414 Field4 interface{} `validate:"excluded_without=Field" json:"field_4"`
11415 Field5 string `validate:"excluded_without=Inner.Field" json:"field_5"`
11416 Field6 Inner `validate:"excluded_without=Field" json:"field_6"`
11417 Field7 *Inner `validate:"excluded_without=Field" json:"field_7"`
11418 }{
11419 Inner: &Inner{Field: &fieldVal},
11420 Field: "populated",
11421 Field1: fieldVal,
11422 Field2: &fieldVal,
11423 Field3: map[string]string{"key": "val"},
11424 Field4: "test",
11425 Field5: "test",
11426 Field6: Inner{FieldE: "potato"},
11427 Field7: &Inner{FieldE: "potato"},
11428 }
11429
11430 validate := New()
11431
11432 errs := validate.Struct(test)
11433 Equal(t, errs, nil)
11434
11435 test2 := struct {
11436 Inner *Inner
11437 Inner2 *Inner
11438 Field string `validate:"omitempty" json:"field"`
11439 FieldE string `validate:"omitempty" json:"field_e"`
11440 Field1 string `validate:"excluded_without=FieldE" json:"field_1"`
11441 Field2 *string `validate:"excluded_without=FieldE" json:"field_2"`
11442 Field3 map[string]string `validate:"excluded_without=FieldE" json:"field_3"`
11443 Field4 interface{} `validate:"excluded_without=FieldE" json:"field_4"`
11444 Field5 string `validate:"excluded_without=Inner.FieldE" json:"field_5"`
11445 Field6 string `validate:"excluded_without=Inner2.FieldE" json:"field_6"`
11446 Field7 Inner `validate:"excluded_without=FieldE" json:"field_7"`
11447 Field8 *Inner `validate:"excluded_without=FieldE" json:"field_8"`
11448 }{
11449 Inner: &Inner{Field: &fieldVal},
11450 Field1: fieldVal,
11451 Field2: &fieldVal,
11452 Field3: map[string]string{"key": "val"},
11453 Field4: "test",
11454 Field5: "test",
11455 Field6: "test",
11456 Field7: Inner{FieldE: "potato"},
11457 Field8: &Inner{FieldE: "potato"},
11458 }
11459
11460 errs = validate.Struct(test2)
11461 NotEqual(t, errs, nil)
11462
11463 ve := errs.(ValidationErrors)
11464 Equal(t, len(ve), 8)
11465 for i := 1; i <= 8; i++ {
11466 name := fmt.Sprintf("Field%d", i)
11467 AssertError(t, errs, name, name, name, name, "excluded_without")
11468 }
11469
11470 test3 := struct {
11471 Inner *Inner
11472 Inner2 *Inner
11473 Field string `validate:"omitempty" json:"field"`
11474 FieldE string `validate:"omitempty" json:"field_e"`
11475 Field1 string `validate:"excluded_without=Field" json:"field_1"`
11476 Field2 *string `validate:"excluded_without=Field" json:"field_2"`
11477 Field3 map[string]string `validate:"excluded_without=Field" json:"field_3"`
11478 Field4 interface{} `validate:"excluded_without=Field" json:"field_4"`
11479 Field5 string `validate:"excluded_without=Inner.Field" json:"field_5"`
11480 Field6 Inner `validate:"excluded_without=Field" json:"field_6"`
11481 Field7 *Inner `validate:"excluded_without=Field" json:"field_7"`
11482 }{
11483 Inner: &Inner{Field: &fieldVal},
11484 Field: "populated",
11485 }
11486
11487 validate = New()
11488
11489 errs = validate.Struct(test3)
11490 Equal(t, errs, nil)
11491 }
11492
11493 func TestExcludedWithAll(t *testing.T) {
11494 type Inner struct {
11495 FieldE string
11496 Field *string
11497 }
11498
11499 fieldVal := "test"
11500 test := struct {
11501 Inner *Inner
11502 Inner2 *Inner
11503 Field string `validate:"omitempty" json:"field"`
11504 FieldE string `validate:"omitempty" json:"field_e"`
11505 Field1 string `validate:"excluded_with_all=FieldE Field" json:"field_1"`
11506 Field2 *string `validate:"excluded_with_all=FieldE Field" json:"field_2"`
11507 Field3 map[string]string `validate:"excluded_with_all=FieldE Field" json:"field_3"`
11508 Field4 interface{} `validate:"excluded_with_all=FieldE Field" json:"field_4"`
11509 Field5 string `validate:"excluded_with_all=Inner.FieldE" json:"field_5"`
11510 Field6 string `validate:"excluded_with_all=Inner2.FieldE" json:"field_6"`
11511 Field7 Inner `validate:"excluded_with_all=FieldE Field" json:"field_7"`
11512 Field8 *Inner `validate:"excluded_with_all=FieldE Field" json:"field_8"`
11513 }{
11514 Inner: &Inner{Field: &fieldVal},
11515 Field: fieldVal,
11516 Field1: fieldVal,
11517 Field2: &fieldVal,
11518 Field3: map[string]string{"key": "val"},
11519 Field4: "test",
11520 Field5: "test",
11521 Field6: "test",
11522 Field7: Inner{FieldE: "potato"},
11523 Field8: &Inner{FieldE: "potato"},
11524 }
11525
11526 validate := New()
11527
11528 errs := validate.Struct(test)
11529 Equal(t, errs, nil)
11530
11531 test2 := struct {
11532 Inner *Inner
11533 Inner2 *Inner
11534 Field string `validate:"omitempty" json:"field"`
11535 FieldE string `validate:"omitempty" json:"field_e"`
11536 Field1 string `validate:"excluded_with_all=Field FieldE" json:"field_1"`
11537 Field2 *string `validate:"excluded_with_all=Field FieldE" json:"field_2"`
11538 Field3 map[string]string `validate:"excluded_with_all=Field FieldE" json:"field_3"`
11539 Field4 interface{} `validate:"excluded_with_all=Field FieldE" json:"field_4"`
11540 Field5 string `validate:"excluded_with_all=Inner.Field" json:"field_5"`
11541 Field6 string `validate:"excluded_with_all=Inner2.Field" json:"field_6"`
11542 Field7 Inner `validate:"excluded_with_all=Field FieldE" json:"field_7"`
11543 Field8 *Inner `validate:"excluded_with_all=Field FieldE" json:"field_8"`
11544 }{
11545 Inner: &Inner{Field: &fieldVal},
11546 Field: "populated",
11547 FieldE: "populated",
11548 Field1: fieldVal,
11549 Field2: &fieldVal,
11550 Field3: map[string]string{"key": "val"},
11551 Field4: "test",
11552 Field5: "test",
11553 Field6: "test",
11554 Field7: Inner{FieldE: "potato"},
11555 Field8: &Inner{FieldE: "potato"},
11556 }
11557
11558 errs = validate.Struct(test2)
11559 NotEqual(t, errs, nil)
11560
11561 ve := errs.(ValidationErrors)
11562 Equal(t, len(ve), 7)
11563 for i := 1; i <= 7; i++ {
11564
11565 if i > 5 {
11566 i++
11567 }
11568 name := fmt.Sprintf("Field%d", i)
11569 AssertError(t, errs, name, name, name, name, "excluded_with_all")
11570 }
11571
11572 test3 := struct {
11573 Inner *Inner
11574 Inner2 *Inner
11575 Field string `validate:"omitempty" json:"field"`
11576 FieldE string `validate:"omitempty" json:"field_e"`
11577 Field1 string `validate:"excluded_with_all=FieldE Field" json:"field_1"`
11578 Field2 *string `validate:"excluded_with_all=FieldE Field" json:"field_2"`
11579 Field3 map[string]string `validate:"excluded_with_all=FieldE Field" json:"field_3"`
11580 Field4 interface{} `validate:"excluded_with_all=FieldE Field" json:"field_4"`
11581 Field5 string `validate:"excluded_with_all=Inner.FieldE" json:"field_5"`
11582 Field6 string `validate:"excluded_with_all=Inner2.FieldE" json:"field_6"`
11583 Field7 Inner `validate:"excluded_with_all=Field FieldE" json:"field_7"`
11584 Field8 *Inner `validate:"excluded_with_all=Field FieldE" json:"field_8"`
11585 }{
11586 Inner: &Inner{FieldE: "populated"},
11587 Inner2: &Inner{FieldE: "populated"},
11588 Field: "populated",
11589 FieldE: "populated",
11590 }
11591
11592 validate = New()
11593
11594 errs = validate.Struct(test3)
11595 Equal(t, errs, nil)
11596 }
11597
11598 func TestExcludedWithoutAll(t *testing.T) {
11599 type Inner struct {
11600 FieldE string
11601 Field *string
11602 }
11603
11604 fieldVal := "test"
11605 test := struct {
11606 Inner *Inner
11607 Inner2 *Inner
11608 Field string `validate:"omitempty" json:"field"`
11609 FieldE string `validate:"omitempty" json:"field_e"`
11610 Field1 string `validate:"excluded_without_all=Field FieldE" json:"field_1"`
11611 Field2 *string `validate:"excluded_without_all=Field FieldE" json:"field_2"`
11612 Field3 map[string]string `validate:"excluded_without_all=Field FieldE" json:"field_3"`
11613 Field4 interface{} `validate:"excluded_without_all=Field FieldE" json:"field_4"`
11614 Field5 string `validate:"excluded_without_all=Inner.Field Inner2.Field" json:"field_5"`
11615 Field6 Inner `validate:"excluded_without_all=Field FieldE" json:"field_6"`
11616 Field7 *Inner `validate:"excluded_without_all=Field FieldE" json:"field_7"`
11617 }{
11618 Inner: &Inner{Field: &fieldVal},
11619 Inner2: &Inner{Field: &fieldVal},
11620 Field: "populated",
11621 Field1: fieldVal,
11622 Field2: &fieldVal,
11623 Field3: map[string]string{"key": "val"},
11624 Field4: "test",
11625 Field5: "test",
11626 Field6: Inner{FieldE: "potato"},
11627 Field7: &Inner{FieldE: "potato"},
11628 }
11629
11630 validate := New()
11631
11632 errs := validate.Struct(test)
11633 Equal(t, errs, nil)
11634
11635 test2 := struct {
11636 Inner *Inner
11637 Inner2 *Inner
11638 Field string `validate:"omitempty" json:"field"`
11639 FieldE string `validate:"omitempty" json:"field_e"`
11640 Field1 string `validate:"excluded_without_all=FieldE Field" json:"field_1"`
11641 Field2 *string `validate:"excluded_without_all=FieldE Field" json:"field_2"`
11642 Field3 map[string]string `validate:"excluded_without_all=FieldE Field" json:"field_3"`
11643 Field4 interface{} `validate:"excluded_without_all=FieldE Field" json:"field_4"`
11644 Field5 string `validate:"excluded_without_all=Inner.FieldE" json:"field_5"`
11645 Field6 string `validate:"excluded_without_all=Inner2.FieldE" json:"field_6"`
11646 Field7 Inner `validate:"excluded_without_all=Field FieldE" json:"field_7"`
11647 Field8 *Inner `validate:"excluded_without_all=Field FieldE" json:"field_8"`
11648 }{
11649 Inner: &Inner{Field: &fieldVal},
11650 Field1: fieldVal,
11651 Field2: &fieldVal,
11652 Field3: map[string]string{"key": "val"},
11653 Field4: "test",
11654 Field5: "test",
11655 Field6: "test",
11656 Field7: Inner{FieldE: "potato"},
11657 Field8: &Inner{FieldE: "potato"},
11658 }
11659
11660 errs = validate.Struct(test2)
11661 NotEqual(t, errs, nil)
11662
11663 ve := errs.(ValidationErrors)
11664 Equal(t, len(ve), 8)
11665 for i := 1; i <= 8; i++ {
11666 name := fmt.Sprintf("Field%d", i)
11667 AssertError(t, errs, name, name, name, name, "excluded_without_all")
11668 }
11669
11670 test3 := struct {
11671 Inner *Inner
11672 Inner2 *Inner
11673 Field string `validate:"omitempty" json:"field"`
11674 FieldE string `validate:"omitempty" json:"field_e"`
11675 Field1 string `validate:"excluded_without_all=Field FieldE" json:"field_1"`
11676 Field2 *string `validate:"excluded_without_all=Field FieldE" json:"field_2"`
11677 Field3 map[string]string `validate:"excluded_without_all=Field FieldE" json:"field_3"`
11678 Field4 interface{} `validate:"excluded_without_all=Field FieldE" json:"field_4"`
11679 Field5 string `validate:"excluded_without_all=Inner.Field Inner2.Field" json:"field_5"`
11680 Field6 Inner `validate:"excluded_without_all=Field FieldE" json:"field_6"`
11681 Field7 *Inner `validate:"excluded_without_all=Field FieldE" json:"field_7"`
11682 }{
11683 Inner: &Inner{Field: &fieldVal},
11684 Inner2: &Inner{Field: &fieldVal},
11685 Field: "populated",
11686 FieldE: "populated",
11687 }
11688
11689 validate = New()
11690
11691 errs = validate.Struct(test3)
11692 Equal(t, errs, nil)
11693 }
11694
11695 func TestRequiredWithAll(t *testing.T) {
11696 type Inner struct {
11697 Field *string
11698 }
11699
11700 fieldVal := "test"
11701 test := struct {
11702 Inner *Inner
11703 FieldE string `validate:"omitempty" json:"field_e"`
11704 FieldER string `validate:"required_with_all=FieldE" json:"field_er"`
11705 Field1 string `validate:"omitempty" json:"field_1"`
11706 Field2 *string `validate:"required_with_all=Field1" json:"field_2"`
11707 Field3 map[string]string `validate:"required_with_all=Field2" json:"field_3"`
11708 Field4 interface{} `validate:"required_with_all=Field3" json:"field_4"`
11709 Field5 string `validate:"required_with_all=Inner.Field" json:"field_5"`
11710 Field6 Inner `validate:"required_with_all=Field1 Field2" json:"field_6"`
11711 Field7 *Inner `validate:"required_with_all=Field1 Field2" json:"field_7"`
11712 }{
11713 Inner: &Inner{Field: &fieldVal},
11714 Field1: "test_field1",
11715 Field2: &fieldVal,
11716 Field3: map[string]string{"key": "val"},
11717 Field4: "test",
11718 Field5: "test",
11719 Field6: Inner{Field: &fieldVal},
11720 Field7: &Inner{Field: &fieldVal},
11721 }
11722
11723 validate := New()
11724
11725 errs := validate.Struct(test)
11726 Equal(t, errs, nil)
11727
11728 test2 := struct {
11729 Inner *Inner
11730 Inner2 *Inner
11731 FieldE string `validate:"omitempty" json:"field_e"`
11732 FieldER string `validate:"required_with_all=FieldE" json:"field_er"`
11733 Field1 string `validate:"omitempty" json:"field_1"`
11734 Field2 *string `validate:"required_with_all=Field1" json:"field_2"`
11735 Field3 map[string]string `validate:"required_with_all=Field2" json:"field_3"`
11736 Field4 interface{} `validate:"required_with_all=Field1 FieldE" json:"field_4"`
11737 Field5 string `validate:"required_with_all=Inner.Field Field2" json:"field_5"`
11738 Field6 string `validate:"required_with_all=Inner2.Field Field2" json:"field_6"`
11739 Field7 Inner `validate:"required_with_all=Inner.Field Field2" json:"field_7"`
11740 Field8 *Inner `validate:"required_with_all=Inner.Field Field2" json:"field_8"`
11741 }{
11742 Inner: &Inner{Field: &fieldVal},
11743 Field2: &fieldVal,
11744 }
11745
11746 errs = validate.Struct(test2)
11747 NotEqual(t, errs, nil)
11748
11749 ve := errs.(ValidationErrors)
11750 Equal(t, len(ve), 4)
11751 AssertError(t, errs, "Field3", "Field3", "Field3", "Field3", "required_with_all")
11752 AssertError(t, errs, "Field5", "Field5", "Field5", "Field5", "required_with_all")
11753 AssertError(t, errs, "Field7", "Field7", "Field7", "Field7", "required_with_all")
11754 AssertError(t, errs, "Field8", "Field8", "Field8", "Field8", "required_with_all")
11755 }
11756
11757 func TestRequiredWithout(t *testing.T) {
11758 type Inner struct {
11759 Field *string
11760 }
11761
11762 fieldVal := "test"
11763 test := struct {
11764 Inner *Inner
11765 Field1 string `validate:"omitempty" json:"field_1"`
11766 Field2 *string `validate:"required_without=Field1" json:"field_2"`
11767 Field3 map[string]string `validate:"required_without=Field2" json:"field_3"`
11768 Field4 interface{} `validate:"required_without=Field3" json:"field_4"`
11769 Field5 string `validate:"required_without=Field3" json:"field_5"`
11770 Field6 Inner `validate:"required_without=Field1" json:"field_6"`
11771 Field7 *Inner `validate:"required_without=Field1" json:"field_7"`
11772 }{
11773 Inner: &Inner{Field: &fieldVal},
11774 Field2: &fieldVal,
11775 Field3: map[string]string{"key": "val"},
11776 Field4: "test",
11777 Field5: "test",
11778 Field6: Inner{Field: &fieldVal},
11779 Field7: &Inner{Field: &fieldVal},
11780 }
11781
11782 validate := New()
11783
11784 errs := validate.Struct(test)
11785 Equal(t, errs, nil)
11786
11787 test2 := struct {
11788 Inner *Inner
11789 Inner2 *Inner
11790 Field1 string `json:"field_1"`
11791 Field2 *string `validate:"required_without=Field1" json:"field_2"`
11792 Field3 map[string]string `validate:"required_without=Field2" json:"field_3"`
11793 Field4 interface{} `validate:"required_without=Field3" json:"field_4"`
11794 Field5 string `validate:"required_without=Field3" json:"field_5"`
11795 Field6 string `validate:"required_without=Field1" json:"field_6"`
11796 Field7 string `validate:"required_without=Inner.Field" json:"field_7"`
11797 Field8 string `validate:"required_without=Inner.Field" json:"field_8"`
11798 Field9 Inner `validate:"required_without=Field1" json:"field_9"`
11799 Field10 *Inner `validate:"required_without=Field1" json:"field_10"`
11800 }{
11801 Inner: &Inner{},
11802 Field3: map[string]string{"key": "val"},
11803 Field4: "test",
11804 Field5: "test",
11805 }
11806
11807 errs = validate.Struct(&test2)
11808 NotEqual(t, errs, nil)
11809
11810 ve := errs.(ValidationErrors)
11811 Equal(t, len(ve), 6)
11812 AssertError(t, errs, "Field2", "Field2", "Field2", "Field2", "required_without")
11813 AssertError(t, errs, "Field6", "Field6", "Field6", "Field6", "required_without")
11814 AssertError(t, errs, "Field7", "Field7", "Field7", "Field7", "required_without")
11815 AssertError(t, errs, "Field8", "Field8", "Field8", "Field8", "required_without")
11816 AssertError(t, errs, "Field9", "Field9", "Field9", "Field9", "required_without")
11817 AssertError(t, errs, "Field10", "Field10", "Field10", "Field10", "required_without")
11818
11819 test3 := struct {
11820 Field1 *string `validate:"required_without=Field2,omitempty,min=1" json:"field_1"`
11821 Field2 *string `validate:"required_without=Field1,omitempty,min=1" json:"field_2"`
11822 }{
11823 Field1: &fieldVal,
11824 }
11825
11826 errs = validate.Struct(&test3)
11827 Equal(t, errs, nil)
11828 }
11829
11830 func TestRequiredWithoutAll(t *testing.T) {
11831 type nested struct {
11832 value string
11833 }
11834 fieldVal := "test"
11835 test := struct {
11836 Field1 string `validate:"omitempty" json:"field_1"`
11837 Field2 *string `validate:"required_without_all=Field1" json:"field_2"`
11838 Field3 map[string]string `validate:"required_without_all=Field2" json:"field_3"`
11839 Field4 interface{} `validate:"required_without_all=Field3" json:"field_4"`
11840 Field5 string `validate:"required_without_all=Field3" json:"field_5"`
11841 Field6 nested `validate:"required_without_all=Field1" json:"field_6"`
11842 Field7 *nested `validate:"required_without_all=Field1" json:"field_7"`
11843 }{
11844 Field1: "",
11845 Field2: &fieldVal,
11846 Field3: map[string]string{"key": "val"},
11847 Field4: "test",
11848 Field5: "test",
11849 Field6: nested{"potato"},
11850 Field7: &nested{"potato"},
11851 }
11852
11853 validate := New()
11854
11855 errs := validate.Struct(test)
11856 Equal(t, errs, nil)
11857
11858 test2 := struct {
11859 Field1 string `validate:"omitempty" json:"field_1"`
11860 Field2 *string `validate:"required_without_all=Field1" json:"field_2"`
11861 Field3 map[string]string `validate:"required_without_all=Field2" json:"field_3"`
11862 Field4 interface{} `validate:"required_without_all=Field3" json:"field_4"`
11863 Field5 string `validate:"required_without_all=Field3" json:"field_5"`
11864 Field6 string `validate:"required_without_all=Field1 Field3" json:"field_6"`
11865 Field7 nested `validate:"required_without_all=Field1" json:"field_7"`
11866 Field8 *nested `validate:"required_without_all=Field1" json:"field_8"`
11867 }{
11868 Field3: map[string]string{"key": "val"},
11869 Field4: "test",
11870 Field5: "test",
11871 }
11872
11873 errs = validate.Struct(test2)
11874 NotEqual(t, errs, nil)
11875
11876 ve := errs.(ValidationErrors)
11877 Equal(t, len(ve), 3)
11878 AssertError(t, errs, "Field2", "Field2", "Field2", "Field2", "required_without_all")
11879 AssertError(t, errs, "Field7", "Field7", "Field7", "Field7", "required_without_all")
11880 AssertError(t, errs, "Field8", "Field8", "Field8", "Field8", "required_without_all")
11881 }
11882
11883 func TestExcludedIf(t *testing.T) {
11884 validate := New()
11885 type Inner struct {
11886 Field *string
11887 }
11888
11889 shouldExclude := "exclude"
11890 shouldNotExclude := "dontExclude"
11891
11892 test1 := struct {
11893 FieldE string `validate:"omitempty" json:"field_e"`
11894 FieldER *string `validate:"excluded_if=FieldE exclude" json:"field_er"`
11895 }{
11896 FieldE: shouldExclude,
11897 }
11898 errs := validate.Struct(test1)
11899 Equal(t, errs, nil)
11900
11901 test2 := struct {
11902 FieldE string `validate:"omitempty" json:"field_e"`
11903 FieldER string `validate:"excluded_if=FieldE exclude" json:"field_er"`
11904 }{
11905 FieldE: shouldExclude,
11906 FieldER: "set",
11907 }
11908 errs = validate.Struct(test2)
11909 NotEqual(t, errs, nil)
11910 ve := errs.(ValidationErrors)
11911 Equal(t, len(ve), 1)
11912 AssertError(t, errs, "FieldER", "FieldER", "FieldER", "FieldER", "excluded_if")
11913
11914 test3 := struct {
11915 FieldE string `validate:"omitempty" json:"field_e"`
11916 FieldF string `validate:"omitempty" json:"field_f"`
11917 FieldER string `validate:"excluded_if=FieldE exclude FieldF exclude" json:"field_er"`
11918 }{
11919 FieldE: shouldExclude,
11920 FieldF: shouldExclude,
11921 FieldER: "set",
11922 }
11923 errs = validate.Struct(test3)
11924 NotEqual(t, errs, nil)
11925 ve = errs.(ValidationErrors)
11926 Equal(t, len(ve), 1)
11927 AssertError(t, errs, "FieldER", "FieldER", "FieldER", "FieldER", "excluded_if")
11928
11929 test4 := struct {
11930 FieldE string `validate:"omitempty" json:"field_e"`
11931 FieldF string `validate:"omitempty" json:"field_f"`
11932 FieldER string `validate:"excluded_if=FieldE exclude FieldF exclude" json:"field_er"`
11933 }{
11934 FieldE: shouldExclude,
11935 FieldF: shouldNotExclude,
11936 FieldER: "set",
11937 }
11938 errs = validate.Struct(test4)
11939 Equal(t, errs, nil)
11940
11941 test5 := struct {
11942 FieldE string `validate:"omitempty" json:"field_e"`
11943 FieldER string `validate:"excluded_if=FieldE exclude" json:"field_er"`
11944 }{
11945 FieldE: shouldNotExclude,
11946 }
11947 errs = validate.Struct(test5)
11948 Equal(t, errs, nil)
11949
11950 test6 := struct {
11951 FieldE string `validate:"omitempty" json:"field_e"`
11952 FieldER string `validate:"excluded_if=FieldE exclude" json:"field_er"`
11953 }{
11954 FieldE: shouldNotExclude,
11955 FieldER: "set",
11956 }
11957 errs = validate.Struct(test6)
11958 Equal(t, errs, nil)
11959
11960 test7 := struct {
11961 Inner *Inner
11962 FieldE string `validate:"omitempty" json:"field_e"`
11963 Field1 int `validate:"excluded_if=Inner.Field exclude" json:"field_1"`
11964 }{
11965 Inner: &Inner{Field: &shouldExclude},
11966 }
11967 errs = validate.Struct(test7)
11968 Equal(t, errs, nil)
11969
11970 test8 := struct {
11971 Inner *Inner
11972 FieldE string `validate:"omitempty" json:"field_e"`
11973 Field1 int `validate:"excluded_if=Inner.Field exclude" json:"field_1"`
11974 }{
11975 Inner: &Inner{Field: &shouldExclude},
11976 Field1: 1,
11977 }
11978 errs = validate.Struct(test8)
11979 NotEqual(t, errs, nil)
11980 ve = errs.(ValidationErrors)
11981 Equal(t, len(ve), 1)
11982 AssertError(t, errs, "Field1", "Field1", "Field1", "Field1", "excluded_if")
11983
11984 test9 := struct {
11985 Inner *Inner
11986 FieldE string `validate:"omitempty" json:"field_e"`
11987 Field1 int `validate:"excluded_if=Inner.Field exclude" json:"field_1"`
11988 }{
11989 Inner: &Inner{Field: &shouldNotExclude},
11990 }
11991 errs = validate.Struct(test9)
11992 Equal(t, errs, nil)
11993
11994 test10 := struct {
11995 Inner *Inner
11996 FieldE string `validate:"omitempty" json:"field_e"`
11997 Field1 int `validate:"excluded_if=Inner.Field exclude" json:"field_1"`
11998 }{
11999 Inner: &Inner{Field: &shouldNotExclude},
12000 Field1: 1,
12001 }
12002 errs = validate.Struct(test10)
12003 Equal(t, errs, nil)
12004
12005
12006 defer func() {
12007 if r := recover(); r == nil {
12008 t.Errorf("panicTest should have panicked!")
12009 }
12010 }()
12011 fieldVal := "panicTest"
12012 panicTest := struct {
12013 Inner *Inner
12014 Field1 string `validate:"excluded_if=Inner.Field" json:"field_1"`
12015 }{
12016 Inner: &Inner{Field: &fieldVal},
12017 }
12018 _ = validate.Struct(panicTest)
12019 }
12020
12021 func TestExcludedUnless(t *testing.T) {
12022 validate := New()
12023 type Inner struct {
12024 Field *string
12025 }
12026
12027 fieldVal := "test"
12028 test := struct {
12029 FieldE string `validate:"omitempty" json:"field_e"`
12030 FieldER string `validate:"excluded_unless=FieldE test" json:"field_er"`
12031 }{
12032 FieldE: "test",
12033 FieldER: "filled",
12034 }
12035 errs := validate.Struct(test)
12036 Equal(t, errs, nil)
12037
12038 test2 := struct {
12039 FieldE string `validate:"omitempty" json:"field_e"`
12040 FieldER string `validate:"excluded_unless=FieldE test" json:"field_er"`
12041 }{
12042 FieldE: "notest",
12043 FieldER: "filled",
12044 }
12045 errs = validate.Struct(test2)
12046 NotEqual(t, errs, nil)
12047 ve := errs.(ValidationErrors)
12048 Equal(t, len(ve), 1)
12049 AssertError(t, errs, "FieldER", "FieldER", "FieldER", "FieldER", "excluded_unless")
12050
12051
12052 test5 := struct {
12053 FieldE string `validate:"omitempty" json:"field_e"`
12054 FieldER string `validate:"excluded_unless=FieldE test" json:"field_er"`
12055 }{
12056 FieldE: "test",
12057 }
12058 errs = validate.Struct(test5)
12059 Equal(t, errs, nil)
12060
12061 test6 := struct {
12062 FieldE string `validate:"omitempty" json:"field_e"`
12063 FieldER string `validate:"excluded_unless=FieldE test" json:"field_er"`
12064 }{
12065 FieldE: "notest",
12066 }
12067 errs = validate.Struct(test6)
12068 Equal(t, errs, nil)
12069
12070 shouldError := "notest"
12071 test3 := struct {
12072 Inner *Inner
12073 Field1 string `validate:"excluded_unless=Inner.Field test" json:"field_1"`
12074 }{
12075 Inner: &Inner{Field: &shouldError},
12076 Field1: "filled",
12077 }
12078 errs = validate.Struct(test3)
12079 NotEqual(t, errs, nil)
12080 ve = errs.(ValidationErrors)
12081 Equal(t, len(ve), 1)
12082 AssertError(t, errs, "Field1", "Field1", "Field1", "Field1", "excluded_unless")
12083
12084 shouldPass := "test"
12085 test4 := struct {
12086 Inner *Inner
12087 FieldE string `validate:"omitempty" json:"field_e"`
12088 Field1 string `validate:"excluded_unless=Inner.Field test" json:"field_1"`
12089 }{
12090 Inner: &Inner{Field: &shouldPass},
12091 Field1: "filled",
12092 }
12093 errs = validate.Struct(test4)
12094 Equal(t, errs, nil)
12095
12096
12097 test7 := struct {
12098 Inner *Inner
12099 FieldE string `validate:"omitempty" json:"field_e"`
12100 FieldER string `validate:"excluded_unless=Inner.Field test" json:"field_er"`
12101 }{
12102 FieldE: "test",
12103 }
12104 errs = validate.Struct(test7)
12105 Equal(t, errs, nil)
12106
12107 test8 := struct {
12108 FieldE string `validate:"omitempty" json:"field_e"`
12109 FieldER string `validate:"excluded_unless=Inner.Field test" json:"field_er"`
12110 }{
12111 FieldE: "test",
12112 }
12113 errs = validate.Struct(test8)
12114 Equal(t, errs, nil)
12115
12116
12117 defer func() {
12118 if r := recover(); r == nil {
12119 t.Errorf("panicTest should have panicked!")
12120 }
12121 }()
12122 panicTest := struct {
12123 Inner *Inner
12124 Field1 string `validate:"excluded_unless=Inner.Field" json:"field_1"`
12125 }{
12126 Inner: &Inner{Field: &fieldVal},
12127 }
12128 _ = validate.Struct(panicTest)
12129 }
12130
12131 func TestLookup(t *testing.T) {
12132 type Lookup struct {
12133 FieldA *string `json:"fieldA,omitempty" validate:"required_without=FieldB"`
12134 FieldB *string `json:"fieldB,omitempty" validate:"required_without=FieldA"`
12135 }
12136
12137 fieldAValue := "1232"
12138 lookup := Lookup{
12139 FieldA: &fieldAValue,
12140 FieldB: nil,
12141 }
12142 Equal(t, New().Struct(lookup), nil)
12143 }
12144
12145 func TestAbilityToValidateNils(t *testing.T) {
12146 type TestStruct struct {
12147 Test *string `validate:"nil"`
12148 }
12149
12150 ts := TestStruct{}
12151 val := New()
12152 fn := func(fl FieldLevel) bool {
12153 return fl.Field().Kind() == reflect.Ptr && fl.Field().IsNil()
12154 }
12155
12156 err := val.RegisterValidation("nil", fn, true)
12157 Equal(t, err, nil)
12158
12159 errs := val.Struct(ts)
12160 Equal(t, errs, nil)
12161
12162 str := "string"
12163 ts.Test = &str
12164
12165 errs = val.Struct(ts)
12166 NotEqual(t, errs, nil)
12167 }
12168
12169 func TestRequiredWithoutPointers(t *testing.T) {
12170 type Lookup struct {
12171 FieldA *bool `json:"fieldA,omitempty" validate:"required_without=FieldB"`
12172 FieldB *bool `json:"fieldB,omitempty" validate:"required_without=FieldA"`
12173 }
12174
12175 b := true
12176 lookup := Lookup{
12177 FieldA: &b,
12178 FieldB: nil,
12179 }
12180
12181 val := New()
12182 errs := val.Struct(lookup)
12183 Equal(t, errs, nil)
12184
12185 b = false
12186 lookup = Lookup{
12187 FieldA: &b,
12188 FieldB: nil,
12189 }
12190 errs = val.Struct(lookup)
12191 Equal(t, errs, nil)
12192 }
12193
12194 func TestRequiredWithoutAllPointers(t *testing.T) {
12195 type Lookup struct {
12196 FieldA *bool `json:"fieldA,omitempty" validate:"required_without_all=FieldB"`
12197 FieldB *bool `json:"fieldB,omitempty" validate:"required_without_all=FieldA"`
12198 }
12199
12200 b := true
12201 lookup := Lookup{
12202 FieldA: &b,
12203 FieldB: nil,
12204 }
12205
12206 val := New()
12207 errs := val.Struct(lookup)
12208 Equal(t, errs, nil)
12209
12210 b = false
12211 lookup = Lookup{
12212 FieldA: &b,
12213 FieldB: nil,
12214 }
12215 errs = val.Struct(lookup)
12216 Equal(t, errs, nil)
12217 }
12218
12219 func TestGetTag(t *testing.T) {
12220 var tag string
12221
12222 type Test struct {
12223 String string `validate:"mytag"`
12224 }
12225
12226 val := New()
12227 _ = val.RegisterValidation("mytag", func(fl FieldLevel) bool {
12228 tag = fl.GetTag()
12229 return true
12230 })
12231
12232 var test Test
12233 errs := val.Struct(test)
12234 Equal(t, errs, nil)
12235 Equal(t, tag, "mytag")
12236 }
12237
12238 func TestJSONValidation(t *testing.T) {
12239 tests := []struct {
12240 param interface{}
12241 expected bool
12242 }{
12243 {`foo`, false},
12244 {`}{`, false},
12245 {`{]`, false},
12246 {`{}`, true},
12247 {`{"foo":"bar"}`, true},
12248 {`{"foo":"bar","bar":{"baz":["qux"]}}`, true},
12249 {`{"foo": 3 "bar": 4}`, false},
12250 {`{"foo": 3 ,"bar": 4`, false},
12251 {`{foo": 3, "bar": 4}`, false},
12252 {`foo`, false},
12253 {`1`, true},
12254 {`true`, true},
12255 {`null`, true},
12256 {`"null"`, true},
12257 {json.RawMessage(`foo`), false},
12258 {json.RawMessage(`}{`), false},
12259 {json.RawMessage(`{]`), false},
12260 {json.RawMessage(`{}`), true},
12261 {json.RawMessage(`{"foo":"bar"}`), true},
12262 {json.RawMessage(`{"foo":"bar","bar":{"baz":["qux"]}}`), true},
12263 {json.RawMessage(`{"foo": 3 "bar": 4}`), false},
12264 {json.RawMessage(`{"foo": 3 ,"bar": 4`), false},
12265 {json.RawMessage(`{foo": 3, "bar": 4}`), false},
12266 {json.RawMessage(`foo`), false},
12267 {json.RawMessage(`1`), true},
12268 {json.RawMessage(`true`), true},
12269 {json.RawMessage(`null`), true},
12270 {json.RawMessage(`"null"`), true},
12271 {[]byte(`foo`), false},
12272 {[]byte(`}{`), false},
12273 {[]byte(`{]`), false},
12274 {[]byte(`{}`), true},
12275 {[]byte(`{"foo":"bar"}`), true},
12276 {[]byte(`{"foo":"bar","bar":{"baz":["qux"]}}`), true},
12277 {[]byte(`{"foo": 3 "bar": 4}`), false},
12278 {[]byte(`{"foo": 3 ,"bar": 4`), false},
12279 {[]byte(`{foo": 3, "bar": 4}`), false},
12280 {[]byte(`foo`), false},
12281 {[]byte(`1`), true},
12282 {[]byte(`true`), true},
12283 {[]byte(`null`), true},
12284 {[]byte(`"null"`), true},
12285 }
12286
12287 validate := New()
12288
12289 for i, test := range tests {
12290
12291 errs := validate.Var(test.param, "json")
12292
12293 if test.expected {
12294 if !IsEqual(errs, nil) {
12295 t.Fatalf("Index: %d json failed Error: %s", i, errs)
12296 }
12297 } else {
12298 if IsEqual(errs, nil) {
12299 t.Fatalf("Index: %d json failed Error: %s", i, errs)
12300 } else {
12301 val := getError(errs, "", "")
12302 if val.Tag() != "json" {
12303 t.Fatalf("Index: %d json failed Error: %s", i, errs)
12304 }
12305 }
12306 }
12307 }
12308
12309 PanicMatches(t, func() {
12310 _ = validate.Var(2, "json")
12311 }, "Bad field type int")
12312 }
12313
12314 func TestJWTValidation(t *testing.T) {
12315 tests := []struct {
12316 param string
12317 expected bool
12318 }{
12319 {"eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiZ29waGVyIn0.O_bROM_szPq9qBql-XDHMranHwP48ODdoLICWzqBr_U", true},
12320 {"acb123-_.def456-_.ghi789-_", true},
12321 {"eyJhbGciOiJOT05FIn0.e30.", true},
12322 {"eyJhbGciOiJOT05FIn0.e30.\n", false},
12323 {"\x00.\x00.\x00", false},
12324 {"", false},
12325 }
12326
12327 validate := New()
12328
12329 for i, test := range tests {
12330
12331 errs := validate.Var(test.param, "jwt")
12332
12333 if test.expected {
12334 if !IsEqual(errs, nil) {
12335 t.Fatalf("Index: %d jwt failed Error: %s", i, errs)
12336 }
12337 } else {
12338 if IsEqual(errs, nil) {
12339 t.Fatalf("Index: %d jwt failed Error: %s", i, errs)
12340 } else {
12341 val := getError(errs, "", "")
12342 if val.Tag() != "jwt" {
12343 t.Fatalf("Index: %d jwt failed Error: %s", i, errs)
12344 }
12345 }
12346 }
12347 }
12348 }
12349
12350 func Test_hostnameport_validator(t *testing.T) {
12351 type Host struct {
12352 Addr string `validate:"hostname_port"`
12353 }
12354
12355 type testInput struct {
12356 data string
12357 expected bool
12358 }
12359 testData := []testInput{
12360 {"bad..domain.name:234", false},
12361 {"extra.dot.com.", false},
12362 {"localhost:1234", true},
12363 {"192.168.1.1:1234", true},
12364 {":1234", true},
12365 {"domain.com:1334", true},
12366 {"this.domain.com:234", true},
12367 {"domain:75000", false},
12368 {"missing.port", false},
12369 }
12370 for _, td := range testData {
12371 h := Host{Addr: td.data}
12372 v := New()
12373 err := v.Struct(h)
12374 if td.expected != (err == nil) {
12375 t.Fatalf("Test failed for data: %v Error: %v", td.data, err)
12376 }
12377 }
12378 }
12379
12380 func TestLowercaseValidation(t *testing.T) {
12381 tests := []struct {
12382 param string
12383 expected bool
12384 }{
12385 {`abcdefg`, true},
12386 {`Abcdefg`, false},
12387 {"", false},
12388 }
12389
12390 validate := New()
12391
12392 for i, test := range tests {
12393
12394 errs := validate.Var(test.param, "lowercase")
12395
12396 if test.expected {
12397 if !IsEqual(errs, nil) {
12398 t.Fatalf("Index: %d lowercase failed Error: %s", i, errs)
12399 }
12400 } else {
12401 if IsEqual(errs, nil) {
12402 t.Fatalf("Index: %d lowercase failed Error: %s", i, errs)
12403 } else {
12404 val := getError(errs, "", "")
12405 if val.Tag() != "lowercase" {
12406 t.Fatalf("Index: %d lowercase failed Error: %s", i, errs)
12407 }
12408 }
12409 }
12410 }
12411
12412 PanicMatches(t, func() {
12413 _ = validate.Var(2, "lowercase")
12414 }, "Bad field type int")
12415 }
12416
12417 func TestUppercaseValidation(t *testing.T) {
12418 tests := []struct {
12419 param string
12420 expected bool
12421 }{
12422 {`ABCDEFG`, true},
12423 {`aBCDEFG`, false},
12424 {"", false},
12425 }
12426
12427 validate := New()
12428
12429 for i, test := range tests {
12430
12431 errs := validate.Var(test.param, "uppercase")
12432
12433 if test.expected {
12434 if !IsEqual(errs, nil) {
12435 t.Fatalf("Index: %d uppercase failed Error: %s", i, errs)
12436 }
12437 } else {
12438 if IsEqual(errs, nil) {
12439 t.Fatalf("Index: %d uppercase failed Error: %s", i, errs)
12440 } else {
12441 val := getError(errs, "", "")
12442 if val.Tag() != "uppercase" {
12443 t.Fatalf("Index: %d uppercase failed Error: %s", i, errs)
12444 }
12445 }
12446 }
12447 }
12448
12449 PanicMatches(t, func() {
12450 _ = validate.Var(2, "uppercase")
12451 }, "Bad field type int")
12452 }
12453
12454 func TestDatetimeValidation(t *testing.T) {
12455 tests := []struct {
12456 value string `validate:"datetime=2006-01-02"`
12457 tag string
12458 expected bool
12459 }{
12460 {"2008-02-01", `datetime=2006-01-02`, true},
12461 {"2008-Feb-01", `datetime=2006-01-02`, false},
12462 }
12463
12464 validate := New()
12465
12466 for i, test := range tests {
12467
12468 errs := validate.Var(test.value, test.tag)
12469
12470 if test.expected {
12471 if !IsEqual(errs, nil) {
12472 t.Fatalf("Index: %d datetime failed Error: %s", i, errs)
12473 }
12474 } else {
12475 if IsEqual(errs, nil) {
12476 t.Fatalf("Index: %d datetime failed Error: %s", i, errs)
12477 } else {
12478 val := getError(errs, "", "")
12479 if val.Tag() != "datetime" {
12480 t.Fatalf("Index: %d datetime failed Error: %s", i, errs)
12481 }
12482 }
12483 }
12484 }
12485
12486 PanicMatches(t, func() {
12487 _ = validate.Var(2, "datetime")
12488 }, "Bad field type int")
12489 }
12490
12491 func TestIsIso3166Alpha2Validation(t *testing.T) {
12492 tests := []struct {
12493 value string `validate:"iso3166_1_alpha2"`
12494 expected bool
12495 }{
12496 {"PL", true},
12497 {"POL", false},
12498 {"AA", false},
12499 }
12500
12501 validate := New()
12502
12503 for i, test := range tests {
12504
12505 errs := validate.Var(test.value, "iso3166_1_alpha2")
12506
12507 if test.expected {
12508 if !IsEqual(errs, nil) {
12509 t.Fatalf("Index: %d iso3166_1_alpha2 failed Error: %s", i, errs)
12510 }
12511 } else {
12512 if IsEqual(errs, nil) {
12513 t.Fatalf("Index: %d iso3166_1_alpha2 failed Error: %s", i, errs)
12514 }
12515 }
12516 }
12517 }
12518
12519 func TestIsIso3166Alpha2EUValidation(t *testing.T) {
12520 tests := []struct {
12521 value string `validate:"iso3166_1_alpha2_eu"`
12522 expected bool
12523 }{
12524 {"SE", true},
12525 {"UK", false},
12526 }
12527
12528 validate := New()
12529
12530 for i, test := range tests {
12531
12532 errs := validate.Var(test.value, "iso3166_1_alpha2_eu")
12533
12534 if test.expected {
12535 if !IsEqual(errs, nil) {
12536 t.Fatalf("Index: %d iso3166_1_alpha2_eu failed Error: %s", i, errs)
12537 }
12538 } else {
12539 if IsEqual(errs, nil) {
12540 t.Fatalf("Index: %d iso3166_1_alpha2_eu failed Error: %s", i, errs)
12541 }
12542 }
12543 }
12544 }
12545
12546 func TestIsIso31662Validation(t *testing.T) {
12547 tests := []struct {
12548 value string `validate:"iso3166_2"`
12549 expected bool
12550 }{
12551 {"US-FL", true},
12552 {"US-F", false},
12553 {"US", false},
12554 }
12555
12556 validate := New()
12557
12558 for i, test := range tests {
12559
12560 errs := validate.Var(test.value, "iso3166_2")
12561
12562 if test.expected {
12563 if !IsEqual(errs, nil) {
12564 t.Fatalf("Index: %d iso3166_2 failed Error: %s", i, errs)
12565 }
12566 } else {
12567 if IsEqual(errs, nil) {
12568 t.Fatalf("Index: %d iso3166_2 failed Error: %s", i, errs)
12569 }
12570 }
12571 }
12572 }
12573
12574 func TestIsIso3166Alpha3Validation(t *testing.T) {
12575 tests := []struct {
12576 value string `validate:"iso3166_1_alpha3"`
12577 expected bool
12578 }{
12579 {"POL", true},
12580 {"PL", false},
12581 {"AAA", false},
12582 }
12583
12584 validate := New()
12585
12586 for i, test := range tests {
12587
12588 errs := validate.Var(test.value, "iso3166_1_alpha3")
12589
12590 if test.expected {
12591 if !IsEqual(errs, nil) {
12592 t.Fatalf("Index: %d iso3166_1_alpha3 failed Error: %s", i, errs)
12593 }
12594 } else {
12595 if IsEqual(errs, nil) {
12596 t.Fatalf("Index: %d iso3166_1_alpha3 failed Error: %s", i, errs)
12597 }
12598 }
12599 }
12600 }
12601
12602 func TestIsIso3166Alpha3EUValidation(t *testing.T) {
12603 tests := []struct {
12604 value string `validate:"iso3166_1_alpha3_eu"`
12605 expected bool
12606 }{
12607 {"POL", true},
12608 {"SWE", true},
12609 {"UNK", false},
12610 }
12611
12612 validate := New()
12613
12614 for i, test := range tests {
12615
12616 errs := validate.Var(test.value, "iso3166_1_alpha3_eu")
12617
12618 if test.expected {
12619 if !IsEqual(errs, nil) {
12620 t.Fatalf("Index: %d iso3166_1_alpha3_eu failed Error: %s", i, errs)
12621 }
12622 } else {
12623 if IsEqual(errs, nil) {
12624 t.Fatalf("Index: %d iso3166_1_alpha3_eu failed Error: %s", i, errs)
12625 }
12626 }
12627 }
12628 }
12629
12630 func TestIsIso3166AlphaNumericValidation(t *testing.T) {
12631 tests := []struct {
12632 value interface{}
12633 expected bool
12634 }{
12635 {248, true},
12636 {"248", true},
12637 {0, false},
12638 {1, false},
12639 {"1", false},
12640 {"invalid_int", false},
12641 }
12642
12643 validate := New()
12644
12645 for i, test := range tests {
12646
12647 errs := validate.Var(test.value, "iso3166_1_alpha_numeric")
12648
12649 if test.expected {
12650 if !IsEqual(errs, nil) {
12651 t.Fatalf("Index: %d iso3166_1_alpha_numeric failed Error: %s", i, errs)
12652 }
12653 } else {
12654 if IsEqual(errs, nil) {
12655 t.Fatalf("Index: %d iso3166_1_alpha_numeric failed Error: %s", i, errs)
12656 }
12657 }
12658 }
12659
12660 PanicMatches(t, func() {
12661 _ = validate.Var([]string{"1"}, "iso3166_1_alpha_numeric")
12662 }, "Bad field type []string")
12663 }
12664
12665 func TestIsIso3166AlphaNumericEUValidation(t *testing.T) {
12666 tests := []struct {
12667 value interface{}
12668 expected bool
12669 }{
12670 {752, true},
12671 {"752", true},
12672 {826, false},
12673 {"826", false},
12674 }
12675
12676 validate := New()
12677
12678 for i, test := range tests {
12679
12680 errs := validate.Var(test.value, "iso3166_1_alpha_numeric_eu")
12681
12682 if test.expected {
12683 if !IsEqual(errs, nil) {
12684 t.Fatalf("Index: %d iso3166_1_alpha_numeric_eu failed Error: %s", i, errs)
12685 }
12686 } else {
12687 if IsEqual(errs, nil) {
12688 t.Fatalf("Index: %d iso3166_1_alpha_numeric_eu failed Error: %s", i, errs)
12689 }
12690 }
12691 }
12692
12693 PanicMatches(t, func() {
12694 _ = validate.Var([]string{"1"}, "iso3166_1_alpha_numeric_eu")
12695 }, "Bad field type []string")
12696 }
12697
12698 func TestCountryCodeValidation(t *testing.T) {
12699 tests := []struct {
12700 value interface{}
12701 expected bool
12702 }{
12703 {248, true},
12704 {0, false},
12705 {1, false},
12706 {"POL", true},
12707 {"NO", true},
12708 {"248", true},
12709 {"1", false},
12710 {"0", false},
12711 }
12712
12713 validate := New()
12714
12715 for i, test := range tests {
12716
12717 errs := validate.Var(test.value, "country_code")
12718
12719 if test.expected {
12720 if !IsEqual(errs, nil) {
12721 t.Fatalf("Index: %d country_code failed Error: %s", i, errs)
12722 }
12723 } else {
12724 if IsEqual(errs, nil) {
12725 t.Fatalf("Index: %d country_code failed Error: %s", i, errs)
12726 }
12727 }
12728 }
12729 }
12730
12731 func TestEUCountryCodeValidation(t *testing.T) {
12732 tests := []struct {
12733 value interface{}
12734 expected bool
12735 }{
12736 {724, true},
12737 {0, false},
12738 {1, false},
12739 {"POL", true},
12740 {"NO", false},
12741 {"724", true},
12742 {"1", false},
12743 {"0", false},
12744 }
12745
12746 validate := New()
12747
12748 for i, test := range tests {
12749
12750 errs := validate.Var(test.value, "eu_country_code")
12751
12752 if test.expected {
12753 if !IsEqual(errs, nil) {
12754 t.Fatalf("Index: %d eu_country_code failed Error: %s", i, errs)
12755 }
12756 } else {
12757 if IsEqual(errs, nil) {
12758 t.Fatalf("Index: %d eu_country_code failed Error: %s", i, errs)
12759 }
12760 }
12761 }
12762 }
12763
12764 func TestIsIso4217Validation(t *testing.T) {
12765 tests := []struct {
12766 value string `validate:"iso4217"`
12767 expected bool
12768 }{
12769 {"TRY", true},
12770 {"EUR", true},
12771 {"USA", false},
12772 }
12773
12774 validate := New()
12775
12776 for i, test := range tests {
12777
12778 errs := validate.Var(test.value, "iso4217")
12779
12780 if test.expected {
12781 if !IsEqual(errs, nil) {
12782 t.Fatalf("Index: %d iso4217 failed Error: %s", i, errs)
12783 }
12784 } else {
12785 if IsEqual(errs, nil) {
12786 t.Fatalf("Index: %d iso4217 failed Error: %s", i, errs)
12787 }
12788 }
12789 }
12790 }
12791
12792 func TestIsIso4217NumericValidation(t *testing.T) {
12793 tests := []struct {
12794 value int `validate:"iso4217_numeric"`
12795 expected bool
12796 }{
12797 {8, true},
12798 {12, true},
12799 {13, false},
12800 }
12801
12802 validate := New()
12803
12804 for i, test := range tests {
12805
12806 errs := validate.Var(test.value, "iso4217_numeric")
12807
12808 if test.expected {
12809 if !IsEqual(errs, nil) {
12810 t.Fatalf("Index: %d iso4217 failed Error: %s", i, errs)
12811 }
12812 } else {
12813 if IsEqual(errs, nil) {
12814 t.Fatalf("Index: %d iso4217 failed Error: %s", i, errs)
12815 }
12816 }
12817 }
12818 }
12819
12820 func TestTimeZoneValidation(t *testing.T) {
12821 tests := []struct {
12822 value string `validate:"timezone"`
12823 tag string
12824 expected bool
12825 }{
12826
12827 {"America/New_York", `timezone`, true},
12828 {"UTC", `timezone`, true},
12829 {"", `timezone`, false},
12830 {"Local", `timezone`, false},
12831 {"Unknown", `timezone`, false},
12832 }
12833
12834 validate := New()
12835
12836 for i, test := range tests {
12837
12838 errs := validate.Var(test.value, test.tag)
12839
12840 if test.expected {
12841 if !IsEqual(errs, nil) {
12842 t.Fatalf("Index: %d time zone failed Error: %s", i, errs)
12843 }
12844 } else {
12845 if IsEqual(errs, nil) {
12846 t.Fatalf("Index: %d time zone failed Error: %s", i, errs)
12847 } else {
12848 val := getError(errs, "", "")
12849 if val.Tag() != "timezone" {
12850 t.Fatalf("Index: %d time zone failed Error: %s", i, errs)
12851 }
12852 }
12853 }
12854 }
12855
12856 PanicMatches(t, func() {
12857 _ = validate.Var(2, "timezone")
12858 }, "Bad field type int")
12859 }
12860
12861 func TestDurationType(t *testing.T) {
12862 tests := []struct {
12863 name string
12864 s interface{}
12865 success bool
12866 }{
12867 {
12868 name: "valid duration string pass",
12869 s: struct {
12870 Value time.Duration `validate:"gte=500ns"`
12871 }{
12872 Value: time.Second,
12873 },
12874 success: true,
12875 },
12876 {
12877 name: "valid duration int pass",
12878 s: struct {
12879 Value time.Duration `validate:"gte=500"`
12880 }{
12881 Value: time.Second,
12882 },
12883 success: true,
12884 },
12885 }
12886
12887 validate := New()
12888
12889 for _, tc := range tests {
12890 tc := tc
12891 t.Run(tc.name, func(t *testing.T) {
12892 t.Parallel()
12893
12894 errs := validate.Struct(tc.s)
12895 if tc.success {
12896 Equal(t, errs, nil)
12897 return
12898 }
12899 NotEqual(t, errs, nil)
12900 })
12901 }
12902 }
12903
12904 func TestBCP47LanguageTagValidation(t *testing.T) {
12905 tests := []struct {
12906 value string `validate:"bcp47_language_tag"`
12907 tag string
12908 expected bool
12909 }{
12910 {"en-US", "bcp47_language_tag", true},
12911 {"en_GB", "bcp47_language_tag", true},
12912 {"es", "bcp47_language_tag", true},
12913 {"English", "bcp47_language_tag", false},
12914 {"ESES", "bcp47_language_tag", false},
12915 {"az-Cyrl-AZ", "bcp47_language_tag", true},
12916 {"en-029", "bcp47_language_tag", true},
12917 {"xog", "bcp47_language_tag", true},
12918 }
12919
12920 validate := New()
12921
12922 for i, test := range tests {
12923
12924 errs := validate.Var(test.value, test.tag)
12925
12926 if test.expected {
12927 if !IsEqual(errs, nil) {
12928 t.Fatalf("Index: %d locale failed Error: %s", i, errs)
12929 }
12930 } else {
12931 if IsEqual(errs, nil) {
12932 t.Fatalf("Index: %d locale failed Error: %s", i, errs)
12933 } else {
12934 val := getError(errs, "", "")
12935 if val.Tag() != "bcp47_language_tag" {
12936 t.Fatalf("Index: %d locale failed Error: %s", i, errs)
12937 }
12938 }
12939 }
12940 }
12941
12942 PanicMatches(t, func() {
12943 _ = validate.Var(2, "bcp47_language_tag")
12944 }, "Bad field type int")
12945 }
12946
12947 func TestBicIsoFormatValidation(t *testing.T) {
12948 tests := []struct {
12949 value string `validate:"bic"`
12950 tag string
12951 expected bool
12952 }{
12953 {"SBICKEN1345", "bic", true},
12954 {"SBICKEN1", "bic", true},
12955 {"SBICKENY", "bic", true},
12956 {"SBICKEN1YYP", "bic", true},
12957 {"SBIC23NXXX", "bic", false},
12958 {"S23CKENXXXX", "bic", false},
12959 {"SBICKENXX", "bic", false},
12960 {"SBICKENXX9", "bic", false},
12961 {"SBICKEN13458", "bic", false},
12962 {"SBICKEN", "bic", false},
12963 }
12964
12965 validate := New()
12966
12967 for i, test := range tests {
12968
12969 errs := validate.Var(test.value, test.tag)
12970
12971 if test.expected {
12972 if !IsEqual(errs, nil) {
12973 t.Fatalf("Index: %d bic failed Error: %s", i, errs)
12974 }
12975 } else {
12976 if IsEqual(errs, nil) {
12977 t.Fatalf("Index: %d bic failed Error: %s", i, errs)
12978 } else {
12979 val := getError(errs, "", "")
12980 if val.Tag() != "bic" {
12981 t.Fatalf("Index: %d bic failed Error: %s", i, errs)
12982 }
12983 }
12984 }
12985 }
12986 }
12987
12988 func TestSemverFormatValidation(t *testing.T) {
12989 tests := []struct {
12990 value string `validate:"semver"`
12991 tag string
12992 expected bool
12993 }{
12994 {"1.2.3", "semver", true},
12995 {"10.20.30", "semver", true},
12996 {"1.1.2-prerelease+meta", "semver", true},
12997 {"1.1.2+meta", "semver", true},
12998 {"1.1.2+meta-valid", "semver", true},
12999 {"1.0.0-alpha", "semver", true},
13000 {"1.0.0-alpha.1", "semver", true},
13001 {"1.0.0-alpha.beta", "semver", true},
13002 {"1.0.0-alpha.beta.1", "semver", true},
13003 {"1.0.0-alpha0.valid", "semver", true},
13004 {"1.0.0-alpha.0valid", "semver", true},
13005 {"1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay", "semver", true},
13006 {"1.0.0-rc.1+build.1", "semver", true},
13007 {"1.0.0-rc.1+build.123", "semver", true},
13008 {"1.2.3-beta", "semver", true},
13009 {"1.2.3-DEV-SNAPSHOT", "semver", true},
13010 {"1.2.3-SNAPSHOT-123", "semver", true},
13011 {"2.0.0+build.1848", "semver", true},
13012 {"2.0.1-alpha.1227", "semver", true},
13013 {"1.0.0-alpha+beta", "semver", true},
13014 {"1.2.3----RC-SNAPSHOT.12.9.1--.12+788", "semver", true},
13015 {"1.2.3----R-S.12.9.1--.12+meta", "semver", true},
13016 {"1.2.3----RC-SNAPSHOT.12.9.1--.12", "semver", true},
13017 {"1.0.0+0.build.1-rc.10000aaa-kk-0.1", "semver", true},
13018 {"99999999999999999999999.999999999999999999.99999999999999999", "semver", true},
13019 {"1.0.0-0A.is.legal", "semver", true},
13020 {"1", "semver", false},
13021 {"1.2", "semver", false},
13022 {"1.2.3-0123", "semver", false},
13023 {"1.2.3-0123.0123", "semver", false},
13024 {"1.1.2+.123", "semver", false},
13025 {"+invalid", "semver", false},
13026 {"-invalid", "semver", false},
13027 {"-invalid+invalid", "semver", false},
13028 {"alpha", "semver", false},
13029 {"alpha.beta.1", "semver", false},
13030 {"alpha.1", "semver", false},
13031 {"1.0.0-alpha_beta", "semver", false},
13032 {"1.0.0-alpha_beta", "semver", false},
13033 {"1.0.0-alpha...1", "semver", false},
13034 {"01.1.1", "semver", false},
13035 {"1.01.1", "semver", false},
13036 {"1.1.01", "semver", false},
13037 {"1.2", "semver", false},
13038 {"1.2.Dev", "semver", false},
13039 {"1.2.3.Dev", "semver", false},
13040 {"1.2-SNAPSHOT", "semver", false},
13041 }
13042
13043 validate := New()
13044
13045 for i, test := range tests {
13046
13047 errs := validate.Var(test.value, test.tag)
13048
13049 if test.expected {
13050 if !IsEqual(errs, nil) {
13051 t.Fatalf("Index: %d semver failed Error: %s", i, errs)
13052 }
13053 } else {
13054 if IsEqual(errs, nil) {
13055 t.Fatalf("Index: %d semver failed Error: %s", i, errs)
13056 } else {
13057 val := getError(errs, "", "")
13058 if val.Tag() != "semver" {
13059 t.Fatalf("Index: %d semver failed Error: %s", i, errs)
13060 }
13061 }
13062 }
13063 }
13064 }
13065
13066 func TestCveFormatValidation(t *testing.T) {
13067
13068 tests := []struct {
13069 value string `validate:"cve"`
13070 tag string
13071 expected bool
13072 }{
13073 {"CVE-1999-0001", "cve", true},
13074 {"CVE-1998-0001", "cve", false},
13075 {"CVE-2000-0001", "cve", true},
13076 {"CVE-2222-0001", "cve", true},
13077 {"2222-0001", "cve", false},
13078 {"-2222-0001", "cve", false},
13079 {"CVE22220001", "cve", false},
13080 {"CVE-2222-000001", "cve", false},
13081 {"CVE-2222-100001", "cve", true},
13082 {"CVE-2222-99999999999", "cve", true},
13083 {"CVE-3000-0001", "cve", false},
13084 {"CVE-1999-0000", "cve", false},
13085 {"CVE-2099-0000", "cve", false},
13086 }
13087
13088 validate := New()
13089
13090 for i, test := range tests {
13091 errs := validate.Var(test.value, test.tag)
13092
13093 if test.expected {
13094 if !IsEqual(errs, nil) {
13095 t.Fatalf("Index: %d cve failed Error: %s", i, errs)
13096 }
13097 } else {
13098 if IsEqual(errs, nil) {
13099 t.Fatalf("Index: %d cve failed Error: %s", i, errs)
13100 } else {
13101 val := getError(errs, "", "")
13102 if val.Tag() != "cve" {
13103 t.Fatalf("Index: %d cve failed Error: %s", i, errs)
13104 }
13105 }
13106 }
13107 }
13108 }
13109
13110 func TestRFC1035LabelFormatValidation(t *testing.T) {
13111 tests := []struct {
13112 value string `validate:"dns_rfc1035_label"`
13113 tag string
13114 expected bool
13115 }{
13116 {"abc", "dns_rfc1035_label", true},
13117 {"abc-", "dns_rfc1035_label", false},
13118 {"abc-123", "dns_rfc1035_label", true},
13119 {"ABC", "dns_rfc1035_label", false},
13120 {"ABC-123", "dns_rfc1035_label", false},
13121 {"abc-abc", "dns_rfc1035_label", true},
13122 {"ABC-ABC", "dns_rfc1035_label", false},
13123 {"123-abc", "dns_rfc1035_label", false},
13124 {"", "dns_rfc1035_label", false},
13125 }
13126
13127 validate := New()
13128
13129 for i, test := range tests {
13130 errs := validate.Var(test.value, test.tag)
13131
13132 if test.expected {
13133 if !IsEqual(errs, nil) {
13134 t.Fatalf("Index: %d dns_rfc1035_label failed Error: %s", i, errs)
13135 }
13136 } else {
13137 if IsEqual(errs, nil) {
13138 t.Fatalf("Index: %d dns_rfc1035_label failed Error: %s", i, errs)
13139 } else {
13140 val := getError(errs, "", "")
13141 if val.Tag() != "dns_rfc1035_label" {
13142 t.Fatalf("Index: %d dns_rfc1035_label failed Error: %s", i, errs)
13143 }
13144 }
13145 }
13146 }
13147 }
13148
13149 func TestPostCodeByIso3166Alpha2(t *testing.T) {
13150 tests := map[string][]struct {
13151 value string
13152 expected bool
13153 }{
13154 "VN": {
13155 {"ABC", false},
13156 {"700000", true},
13157 {"A1", false},
13158 },
13159 "GB": {
13160 {"EC1A 1BB", true},
13161 {"CF10 1B1H", false},
13162 },
13163 "VI": {
13164 {"00803", true},
13165 {"1234567", false},
13166 },
13167 "LC": {
13168
13169 {"123456", false},
13170 },
13171 "XX": {
13172
13173 {"123456", false},
13174 },
13175 }
13176
13177 validate := New()
13178
13179 for cc, ccTests := range tests {
13180 for i, test := range ccTests {
13181 errs := validate.Var(test.value, fmt.Sprintf("postcode_iso3166_alpha2=%s", cc))
13182
13183 if test.expected {
13184 if !IsEqual(errs, nil) {
13185 t.Fatalf("Index: %d postcode_iso3166_alpha2=%s failed Error: %s", i, cc, errs)
13186 }
13187 } else {
13188 if IsEqual(errs, nil) {
13189 t.Fatalf("Index: %d postcode_iso3166_alpha2=%s failed Error: %s", i, cc, errs)
13190 }
13191 }
13192 }
13193 }
13194 }
13195
13196 func TestPostCodeByIso3166Alpha2Field(t *testing.T) {
13197 tests := []struct {
13198 Value string `validate:"postcode_iso3166_alpha2_field=CountryCode"`
13199 CountryCode interface{}
13200 expected bool
13201 }{
13202 {"ABC", "VN", false},
13203 {"700000", "VN", true},
13204 {"A1", "VN", false},
13205 {"EC1A 1BB", "GB", true},
13206 {"CF10 1B1H", "GB", false},
13207 {"00803", "VI", true},
13208 {"1234567", "VI", false},
13209 {"123456", "LC", false},
13210 {"123456", "XX", false},
13211 }
13212
13213 validate := New()
13214
13215 for i, test := range tests {
13216 errs := validate.Struct(test)
13217 if test.expected {
13218 if !IsEqual(errs, nil) {
13219 t.Fatalf("Index: %d postcode_iso3166_alpha2_field=CountryCode failed Error: %s", i, errs)
13220 }
13221 } else {
13222 if IsEqual(errs, nil) {
13223 t.Fatalf("Index: %d postcode_iso3166_alpha2_field=CountryCode failed Error: %s", i, errs)
13224 }
13225 }
13226 }
13227 }
13228
13229 func TestPostCodeByIso3166Alpha2Field_WrongField(t *testing.T) {
13230 type test struct {
13231 Value string `validate:"postcode_iso3166_alpha2_field=CountryCode"`
13232 CountryCode1 interface{}
13233 expected bool
13234 }
13235
13236 errs := New().Struct(test{"ABC", "VN", false})
13237 NotEqual(t, nil, errs)
13238 }
13239
13240 func TestPostCodeByIso3166Alpha2Field_MissingParam(t *testing.T) {
13241 type test struct {
13242 Value string `validate:"postcode_iso3166_alpha2_field="`
13243 CountryCode1 interface{}
13244 expected bool
13245 }
13246
13247 errs := New().Struct(test{"ABC", "VN", false})
13248 NotEqual(t, nil, errs)
13249 }
13250
13251 func TestPostCodeByIso3166Alpha2Field_InvalidKind(t *testing.T) {
13252 type test struct {
13253 Value string `validate:"postcode_iso3166_alpha2_field=CountryCode"`
13254 CountryCode interface{}
13255 expected bool
13256 }
13257 defer func() { _ = recover() }()
13258
13259 _ = New().Struct(test{"ABC", 123, false})
13260 t.Errorf("Didn't panic as expected")
13261 }
13262
13263 func TestValidate_ValidateMapCtx(t *testing.T) {
13264
13265 type args struct {
13266 data map[string]interface{}
13267 rules map[string]interface{}
13268 }
13269 tests := []struct {
13270 name string
13271 args args
13272 want int
13273 }{
13274 {
13275 name: "test nested map in slice",
13276 args: args{
13277 data: map[string]interface{}{
13278 "Test_A": map[string]interface{}{
13279 "Test_B": "Test_B",
13280 "Test_C": []map[string]interface{}{
13281 {
13282 "Test_D": "Test_D",
13283 },
13284 },
13285 "Test_E": map[string]interface{}{
13286 "Test_F": "Test_F",
13287 },
13288 },
13289 },
13290 rules: map[string]interface{}{
13291 "Test_A": map[string]interface{}{
13292 "Test_B": "min=2",
13293 "Test_C": map[string]interface{}{
13294 "Test_D": "min=2",
13295 },
13296 "Test_E": map[string]interface{}{
13297 "Test_F": "min=2",
13298 },
13299 },
13300 },
13301 },
13302 want: 0,
13303 },
13304
13305 {
13306 name: "test nested map error",
13307 args: args{
13308 data: map[string]interface{}{
13309 "Test_A": map[string]interface{}{
13310 "Test_B": "Test_B",
13311 "Test_C": []interface{}{"Test_D"},
13312 "Test_E": map[string]interface{}{
13313 "Test_F": "Test_F",
13314 },
13315 "Test_G": "Test_G",
13316 "Test_I": []map[string]interface{}{
13317 {
13318 "Test_J": "Test_J",
13319 },
13320 },
13321 },
13322 },
13323 rules: map[string]interface{}{
13324 "Test_A": map[string]interface{}{
13325 "Test_B": "min=2",
13326 "Test_C": map[string]interface{}{
13327 "Test_D": "min=2",
13328 },
13329 "Test_E": map[string]interface{}{
13330 "Test_F": "min=100",
13331 },
13332 "Test_G": map[string]interface{}{
13333 "Test_H": "min=2",
13334 },
13335 "Test_I": map[string]interface{}{
13336 "Test_J": "min=100",
13337 },
13338 },
13339 },
13340 },
13341 want: 1,
13342 },
13343 }
13344 for _, tt := range tests {
13345 t.Run(tt.name, func(t *testing.T) {
13346 validate := New()
13347 if got := validate.ValidateMapCtx(context.Background(), tt.args.data, tt.args.rules); len(got) != tt.want {
13348 t.Errorf("ValidateMapCtx() = %v, want %v", got, tt.want)
13349 }
13350 })
13351 }
13352 }
13353
13354 func TestMongoDBObjectIDFormatValidation(t *testing.T) {
13355 tests := []struct {
13356 value string `validate:"mongodb"`
13357 tag string
13358 expected bool
13359 }{
13360 {"507f191e810c19729de860ea", "mongodb", true},
13361 {"507f191e810c19729de860eG", "mongodb", false},
13362 {"M07f191e810c19729de860eG", "mongodb", false},
13363 {"07f191e810c19729de860ea", "mongodb", false},
13364 {"507f191e810c19729de860e", "mongodb", false},
13365 {"507f191e810c19729de860ea4", "mongodb", false},
13366 }
13367
13368 validate := New()
13369
13370 for i, test := range tests {
13371 errs := validate.Var(test.value, test.tag)
13372
13373 if test.expected {
13374 if !IsEqual(errs, nil) {
13375 t.Fatalf("Index: %d mongodb failed Error: %s", i, errs)
13376 }
13377 } else {
13378 if IsEqual(errs, nil) {
13379 t.Fatalf("Index: %d mongodb failed Error: %s", i, errs)
13380 } else {
13381 val := getError(errs, "", "")
13382 if val.Tag() != "mongodb" {
13383 t.Fatalf("Index: %d mongodb failed Error: %s", i, errs)
13384 }
13385 }
13386 }
13387 }
13388 }
13389
13390 func TestSpiceDBValueFormatValidation(t *testing.T) {
13391 tests := []struct {
13392 value string
13393 tag string
13394 expected bool
13395 }{
13396
13397 {"*", "spicedb=id", true},
13398 {`azAZ09_|/-=+`, "spicedb=id", true},
13399 {`a*`, "spicedb=id", false},
13400 {`/`, "spicedb=id", true},
13401 {"*", "spicedb", true},
13402
13403
13404 {"a", "spicedb=permission", false},
13405 {"1", "spicedb=permission", false},
13406 {"a1", "spicedb=permission", false},
13407 {"a_b", "spicedb=permission", true},
13408 {"A_b", "spicedb=permission", false},
13409 {"a_B", "spicedb=permission", false},
13410 {"abcdefghijklmnopqrstuvwxyz_0123456789_abcdefghijklmnopqrstuvwxyz", "spicedb=permission", true},
13411 {"abcdefghijklmnopqrstuvwxyz_01234_56789_abcdefghijklmnopqrstuvwxyz", "spicedb=permission", false},
13412
13413
13414 {"a", "spicedb=type", false},
13415 {"1", "spicedb=type", false},
13416 {"a1", "spicedb=type", false},
13417 {"a_b", "spicedb=type", true},
13418 {"A_b", "spicedb=type", false},
13419 {"a_B", "spicedb=type", false},
13420 {"abcdefghijklmnopqrstuvwxyz_0123456789_abcdefghijklmnopqrstuvwxyz", "spicedb=type", true},
13421 {"abcdefghijklmnopqrstuvwxyz_01234_56789_abcdefghijklmnopqrstuvwxyz", "spicedb=type", false},
13422
13423 {`a_b/a`, "spicedb=type", false},
13424 {`a_b/1`, "spicedb=type", false},
13425 {`a_b/a1`, "spicedb=type", false},
13426 {`a_b/a_b`, "spicedb=type", true},
13427 {`a_b/A_b`, "spicedb=type", false},
13428 {`a_b/a_B`, "spicedb=type", false},
13429 {`a_b/abcdefghijklmnopqrstuvwxyz_0123456789_abcdefghijklmnopqrstuvwxyz`, "spicedb=type", true},
13430 {`a_b/abcdefghijklmnopqrstuvwxyz_01234_56789_abcdefghijklmnopqrstuvwxyz`, "spicedb=type", false},
13431
13432 {`a/a_b`, "spicedb=type", false},
13433 {`1/a_b`, "spicedb=type", false},
13434 {`a1/a_b`, "spicedb=type", false},
13435 {`a_b/a_b`, "spicedb=type", true},
13436 {`A_b/a_b`, "spicedb=type", false},
13437 {`a_B/a_b`, "spicedb=type", false},
13438 {`abcdefghijklmnopqrstuvwxyz_0123456789_abcdefghijklmnopqrstuvwxy/a_b`, "spicedb=type", true},
13439 {`abcdefghijklmnopqrstuvwxyz_0123456789_abcdefghijklmnopqrstuvwxyz/a_b`, "spicedb=type", false},
13440 }
13441
13442 validate := New()
13443
13444 for i, test := range tests {
13445 errs := validate.Var(test.value, test.tag)
13446
13447 if test.expected {
13448 if !IsEqual(errs, nil) {
13449 t.Fatalf("Index: %d spicedb failed Error: %s", i, errs)
13450 }
13451 } else {
13452 if IsEqual(errs, nil) {
13453 t.Fatalf("Index: %d spicedb - expected error but there was none.", i)
13454 } else {
13455 val := getError(errs, "", "")
13456 if val.Tag() != "spicedb" {
13457 t.Fatalf("Index: %d spicedb failed Error: %s", i, errs)
13458 }
13459 }
13460 }
13461 }
13462 }
13463
13464 func TestCreditCardFormatValidation(t *testing.T) {
13465 tests := []struct {
13466 value string `validate:"credit_card"`
13467 tag string
13468 expected bool
13469 }{
13470 {"586824160825533338", "credit_card", true},
13471 {"586824160825533328", "credit_card", false},
13472 {"4624748233249780", "credit_card", true},
13473 {"4624748233349780", "credit_card", false},
13474 {"378282246310005", "credit_card", true},
13475 {"378282146310005", "credit_card", false},
13476 {"4624 7482 3324 9780", "credit_card", true},
13477 {"4624 7482 3324 9780", "credit_card", false},
13478 {"4624 7482 3324 978A", "credit_card", false},
13479 {"4624 7482 332", "credit_card", false},
13480 }
13481
13482 validate := New()
13483
13484 for i, test := range tests {
13485 errs := validate.Var(test.value, test.tag)
13486
13487 if test.expected {
13488 if !IsEqual(errs, nil) {
13489 t.Fatalf("Index: %d credit_card failed Error: %s", i, errs)
13490 }
13491 } else {
13492 if IsEqual(errs, nil) {
13493 t.Fatalf("Index: %d credit_card failed Error: %s", i, errs)
13494 } else {
13495 val := getError(errs, "", "")
13496 if val.Tag() != "credit_card" {
13497 t.Fatalf("Index: %d credit_card failed Error: %s", i, errs)
13498 }
13499 }
13500 }
13501 }
13502 }
13503
13504 func TestLuhnChecksumValidation(t *testing.T) {
13505 testsUint := []struct {
13506 value interface{} `validate:"luhn_checksum"`
13507 tag string
13508 expected bool
13509 }{
13510 {uint64(586824160825533338), "luhn_checksum", true},
13511 {586824160825533338, "luhn_checksum", true},
13512 {"586824160825533338", "luhn_checksum", true},
13513 {uint64(586824160825533328), "luhn_checksum", false},
13514 {586824160825533328, "luhn_checksum", false},
13515 {"586824160825533328", "luhn_checksum", false},
13516 {10000000116, "luhn_checksum", true},
13517 {"10000000116", "luhn_checksum", true},
13518 {10000000117, "luhn_checksum", false},
13519 {"10000000117", "luhn_checksum", false},
13520 {uint64(12345678123456789011), "luhn_checksum", true},
13521 {"12345678123456789011", "luhn_checksum", true},
13522 {1, "luhn_checksum", false},
13523 {"1", "luhn_checksum", false},
13524 {-10, "luhn_checksum", false},
13525 {"abcdefghijklmnop", "luhn_checksum", false},
13526 }
13527
13528 validate := New()
13529
13530 for i, test := range testsUint {
13531 errs := validate.Var(test.value, test.tag)
13532 if test.expected {
13533 if !IsEqual(errs, nil) {
13534 t.Fatalf("Index: %d luhn_checksum failed Error: %s", i, errs)
13535 }
13536 } else {
13537 if IsEqual(errs, nil) {
13538 t.Fatalf("Index: %d luhn_checksum failed Error: %s", i, errs)
13539 } else {
13540 val := getError(errs, "", "")
13541 if val.Tag() != "luhn_checksum" {
13542 t.Fatalf("Index: %d luhn_checksum failed Error: %s", i, errs)
13543 }
13544 }
13545 }
13546 }
13547 }
13548
13549 func TestMultiOrOperatorGroup(t *testing.T) {
13550 tests := []struct {
13551 Value int `validate:"eq=1|gte=5,eq=1|lt=7"`
13552 expected bool
13553 }{
13554 {1, true}, {2, false}, {5, true}, {6, true}, {8, false},
13555 }
13556
13557 validate := New()
13558
13559 for i, test := range tests {
13560 errs := validate.Struct(test)
13561 if test.expected {
13562 if !IsEqual(errs, nil) {
13563 t.Fatalf("Index: %d multi_group_of_OR_operators failed Error: %s", i, errs)
13564 }
13565 } else {
13566 if IsEqual(errs, nil) {
13567 t.Fatalf("Index: %d multi_group_of_OR_operators should have errs", i)
13568 }
13569 }
13570 }
13571 }
13572
13573 func TestCronExpressionValidation(t *testing.T) {
13574 tests := []struct {
13575 value string `validate:"cron"`
13576 tag string
13577 expected bool
13578 }{
13579 {"0 0 12 * * ?", "cron", true},
13580 {"0 15 10 ? * *", "cron", true},
13581 {"0 15 10 * * ?", "cron", true},
13582 {"0 15 10 * * ? 2005", "cron", true},
13583 {"0 15 10 ? * 6L", "cron", true},
13584 {"0 15 10 ? * 6L 2002-2005", "cron", true},
13585 {"*/20 * * * *", "cron", true},
13586 {"0 15 10 ? * MON-FRI", "cron", true},
13587 {"0 15 10 ? * 6#3", "cron", true},
13588 {"wrong", "cron", false},
13589 }
13590
13591 validate := New()
13592
13593 for i, test := range tests {
13594 errs := validate.Var(test.value, test.tag)
13595 if test.expected {
13596 if !IsEqual(errs, nil) {
13597 t.Fatalf(`Index: %d cron "%s" failed Error: %s`, i, test.value, errs)
13598 }
13599 } else {
13600 if IsEqual(errs, nil) {
13601 t.Fatalf(`Index: %d cron "%s" should have errs`, i, test.value)
13602 }
13603 }
13604 }
13605 }
13606
13607 func TestNestedStructValidation(t *testing.T) {
13608 validator := New(WithRequiredStructEnabled())
13609
13610 t.Run("required", func(t *testing.T) {
13611 type (
13612 value struct {
13613 Field string
13614 }
13615 topLevel struct {
13616 Nested value `validate:"required"`
13617 }
13618 )
13619
13620 var validationErrs ValidationErrors
13621 if errs := validator.Struct(topLevel{}); errs != nil {
13622 validationErrs = errs.(ValidationErrors)
13623 }
13624
13625 Equal(t, 1, len(validationErrs))
13626 AssertError(t, validationErrs, "topLevel.Nested", "topLevel.Nested", "Nested", "Nested", "required")
13627
13628 Equal(t, validator.Struct(topLevel{value{"potato"}}), nil)
13629 })
13630
13631 t.Run("omitempty", func(t *testing.T) {
13632 type (
13633 value struct {
13634 Field string
13635 }
13636 topLevel struct {
13637 Nested value `validate:"omitempty,required"`
13638 }
13639 )
13640
13641 errs := validator.Struct(topLevel{})
13642 Equal(t, errs, nil)
13643 })
13644
13645 t.Run("excluded_if", func(t *testing.T) {
13646 type (
13647 value struct {
13648 Field string
13649 }
13650 topLevel struct {
13651 Field string
13652 Nested value `validate:"excluded_if=Field potato"`
13653 }
13654 )
13655
13656 errs := validator.Struct(topLevel{Field: "test", Nested: value{"potato"}})
13657 Equal(t, errs, nil)
13658
13659 errs = validator.Struct(topLevel{Field: "potato"})
13660 Equal(t, errs, nil)
13661
13662 errs = validator.Struct(topLevel{Field: "potato", Nested: value{"potato"}})
13663 AssertError(t, errs, "topLevel.Nested", "topLevel.Nested", "Nested", "Nested", "excluded_if")
13664 })
13665
13666 t.Run("excluded_unless", func(t *testing.T) {
13667 type (
13668 value struct {
13669 Field string
13670 }
13671 topLevel struct {
13672 Field string
13673 Nested value `validate:"excluded_unless=Field potato"`
13674 }
13675 )
13676
13677 errs := validator.Struct(topLevel{Field: "test"})
13678 Equal(t, errs, nil)
13679
13680 errs = validator.Struct(topLevel{Field: "potato", Nested: value{"potato"}})
13681 Equal(t, errs, nil)
13682
13683 errs = validator.Struct(topLevel{Field: "test", Nested: value{"potato"}})
13684 AssertError(t, errs, "topLevel.Nested", "topLevel.Nested", "Nested", "Nested", "excluded_unless")
13685 })
13686
13687 t.Run("nonComparableField", func(t *testing.T) {
13688 type (
13689 value struct {
13690 Field []string
13691 }
13692 topLevel struct {
13693 Nested value `validate:"required"`
13694 }
13695 )
13696
13697 errs := validator.Struct(topLevel{value{[]string{}}})
13698 Equal(t, errs, nil)
13699 })
13700
13701 type (
13702 veggyBasket struct {
13703 Root string
13704 Squash string `validate:"required"`
13705 }
13706 testErr struct {
13707 path string
13708 tag string
13709 }
13710 test struct {
13711 name string
13712 err testErr
13713 value veggyBasket
13714 }
13715 )
13716
13717 if err := validator.RegisterValidation("veggy", func(f FieldLevel) bool {
13718 v, ok := f.Field().Interface().(veggyBasket)
13719 if !ok || v.Root != "potato" {
13720 return false
13721 }
13722 return true
13723 }); err != nil {
13724 t.Fatal(fmt.Errorf("failed to register potato tag: %w", err))
13725 }
13726
13727 tests := []test{
13728 {
13729 name: "valid",
13730 value: veggyBasket{"potato", "zucchini"},
13731 }, {
13732 name: "failedCustomTag",
13733 value: veggyBasket{"zucchini", "potato"},
13734 err: testErr{"topLevel.VeggyBasket", "veggy"},
13735 }, {
13736 name: "failedInnerField",
13737 value: veggyBasket{"potato", ""},
13738 err: testErr{"topLevel.VeggyBasket.Squash", "required"},
13739 }, {
13740 name: "customTagFailurePriorityCheck",
13741 value: veggyBasket{"zucchini", ""},
13742 err: testErr{"topLevel.VeggyBasket", "veggy"},
13743 },
13744 }
13745
13746 var evaluateTest = func(tt test, errs error) {
13747 if tt.err != (testErr{}) && errs != nil {
13748 Equal(t, len(errs.(ValidationErrors)), 1)
13749
13750 segments := strings.Split(tt.err.path, ".")
13751 fieldName := segments[len(segments)-1]
13752 AssertError(t, errs, tt.err.path, tt.err.path, fieldName, fieldName, tt.err.tag)
13753 }
13754
13755 shouldFail := tt.err != (testErr{})
13756 hasFailed := errs != nil
13757 if shouldFail != hasFailed {
13758 t.Fatalf("expected failure %v, got: %v with errs: %v", shouldFail, hasFailed, errs)
13759 }
13760 }
13761
13762 for _, tt := range tests {
13763 type topLevel struct {
13764 VeggyBasket veggyBasket `validate:"veggy"`
13765 }
13766
13767 t.Run(tt.name, func(t *testing.T) {
13768 evaluateTest(tt, validator.Struct(topLevel{tt.value}))
13769 })
13770 }
13771
13772
13773 for _, tt := range tests {
13774 type topLevel struct {
13775 VeggyBasket *veggyBasket `validate:"veggy"`
13776 }
13777
13778 t.Run(tt.name+"Ptr", func(t *testing.T) {
13779 evaluateTest(tt, validator.Struct(topLevel{&tt.value}))
13780 })
13781 }
13782 }
13783
13784 func TestTimeRequired(t *testing.T) {
13785 validate := New()
13786 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
13787 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
13788
13789 if name == "-" {
13790 return ""
13791 }
13792
13793 return name
13794 })
13795
13796 type TestTime struct {
13797 Time time.Time `validate:"required"`
13798 }
13799
13800 var testTime TestTime
13801
13802 err := validate.Struct(&testTime)
13803 NotEqual(t, err, nil)
13804 AssertError(t, err.(ValidationErrors), "TestTime.Time", "TestTime.Time", "Time", "Time", "required")
13805 }
13806
13807 func TestOmitNilAndRequired(t *testing.T) {
13808 type (
13809 OmitEmpty struct {
13810 Str string `validate:"omitempty,required,min=10"`
13811 StrPtr *string `validate:"omitempty,required,min=10"`
13812 Inner *OmitEmpty
13813 }
13814 OmitNil struct {
13815 Str string `validate:"omitnil,required,min=10"`
13816 StrPtr *string `validate:"omitnil,required,min=10"`
13817 Inner *OmitNil
13818 }
13819 )
13820
13821 var (
13822 validate = New(WithRequiredStructEnabled())
13823 valid = "this is the long string to pass the validation rule"
13824 )
13825
13826 t.Run("compare using valid data", func(t *testing.T) {
13827 err1 := validate.Struct(OmitEmpty{Str: valid, StrPtr: &valid, Inner: &OmitEmpty{Str: valid, StrPtr: &valid}})
13828 err2 := validate.Struct(OmitNil{Str: valid, StrPtr: &valid, Inner: &OmitNil{Str: valid, StrPtr: &valid}})
13829
13830 Equal(t, err1, nil)
13831 Equal(t, err2, nil)
13832 })
13833
13834 t.Run("compare fully empty omitempty and omitnil", func(t *testing.T) {
13835 err1 := validate.Struct(OmitEmpty{})
13836 err2 := validate.Struct(OmitNil{})
13837
13838 Equal(t, err1, nil)
13839 AssertError(t, err2, "OmitNil.Str", "OmitNil.Str", "Str", "Str", "required")
13840 })
13841
13842 t.Run("validate in deep", func(t *testing.T) {
13843 err1 := validate.Struct(OmitEmpty{Str: valid, Inner: &OmitEmpty{}})
13844 err2 := validate.Struct(OmitNil{Str: valid, Inner: &OmitNil{}})
13845
13846 Equal(t, err1, nil)
13847 AssertError(t, err2, "OmitNil.Inner.Str", "OmitNil.Inner.Str", "Str", "Str", "required")
13848 })
13849 }
13850
13851 func TestPrivateFieldsStruct(t *testing.T) {
13852 type tc struct {
13853 stct interface{}
13854 errorNum int
13855 }
13856
13857 tcs := []tc{
13858 {
13859 stct: &struct {
13860 f1 int8 `validate:"required"`
13861 f2 int16 `validate:"required"`
13862 f3 int32 `validate:"required"`
13863 f4 int64 `validate:"required"`
13864 }{},
13865 errorNum: 4,
13866 },
13867 {
13868 stct: &struct {
13869 f1 uint8 `validate:"required"`
13870 f2 uint16 `validate:"required"`
13871 f3 uint32 `validate:"required"`
13872 f4 uint64 `validate:"required"`
13873 }{},
13874 errorNum: 4,
13875 },
13876 {
13877 stct: &struct {
13878 f1 complex64 `validate:"required"`
13879 f2 complex128 `validate:"required"`
13880 }{},
13881 errorNum: 2,
13882 },
13883 {
13884 stct: &struct {
13885 f1 float32 `validate:"required"`
13886 f2 float64 `validate:"required"`
13887 }{},
13888 errorNum: 2,
13889 },
13890 {
13891 stct: struct {
13892 f1 int8 `validate:"required"`
13893 f2 int16 `validate:"required"`
13894 f3 int32 `validate:"required"`
13895 f4 int64 `validate:"required"`
13896 }{},
13897 errorNum: 4,
13898 },
13899 {
13900 stct: struct {
13901 f1 uint8 `validate:"required"`
13902 f2 uint16 `validate:"required"`
13903 f3 uint32 `validate:"required"`
13904 f4 uint64 `validate:"required"`
13905 }{},
13906 errorNum: 4,
13907 },
13908 {
13909 stct: struct {
13910 f1 complex64 `validate:"required"`
13911 f2 complex128 `validate:"required"`
13912 }{},
13913 errorNum: 2,
13914 },
13915 {
13916 stct: struct {
13917 f1 float32 `validate:"required"`
13918 f2 float64 `validate:"required"`
13919 }{},
13920 errorNum: 2,
13921 },
13922 {
13923 stct: struct {
13924 f1 *int `validate:"required"`
13925 f2 struct {
13926 f3 int `validate:"required"`
13927 }
13928 }{},
13929 errorNum: 2,
13930 },
13931 {
13932 stct: &struct {
13933 f1 *int `validate:"required"`
13934 f2 struct {
13935 f3 int `validate:"required"`
13936 }
13937 }{},
13938 errorNum: 2,
13939 },
13940 }
13941
13942 validate := New(WithPrivateFieldValidation())
13943
13944 for _, tc := range tcs {
13945 err := validate.Struct(tc.stct)
13946 NotEqual(t, err, nil)
13947
13948 errs := err.(ValidationErrors)
13949 Equal(t, len(errs), tc.errorNum)
13950 }
13951 }
13952
View as plain text