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", false},
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 TestBase64Validation(t *testing.T) {
5684 validate := New()
5685
5686 s := "dW5pY29ybg=="
5687
5688 errs := validate.Var(s, "base64")
5689 Equal(t, errs, nil)
5690
5691 s = "dGhpIGlzIGEgdGVzdCBiYXNlNjQ="
5692 errs = validate.Var(s, "base64")
5693 Equal(t, errs, nil)
5694
5695 s = ""
5696 errs = validate.Var(s, "base64")
5697 NotEqual(t, errs, nil)
5698 AssertError(t, errs, "", "", "", "", "base64")
5699
5700 s = "dW5pY29ybg== foo bar"
5701 errs = validate.Var(s, "base64")
5702 NotEqual(t, errs, nil)
5703 AssertError(t, errs, "", "", "", "", "base64")
5704 }
5705
5706 func TestBase64URLValidation(t *testing.T) {
5707 validate := New()
5708
5709 testCases := []struct {
5710 decoded, encoded string
5711 success bool
5712 }{
5713
5714 {"", "", false},
5715
5716 {"", "a", false},
5717
5718 {"f", "Zg==", true},
5719 {"fo", "Zm8=", true},
5720
5721 {"foo", "Zm9v", true},
5722 {"", "Zg", false},
5723 {"", "Zm8", false},
5724
5725 {"\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l+", false},
5726 {"\x14\xfb\x9c\x03\xf9\x73", "FPucA/lz", false},
5727
5728 {"\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l-", true},
5729 {"\x14\xfb\x9c\x03\xf9\x73", "FPucA_lz", true},
5730
5731 {"", "@mc=", false},
5732 {"", "Zm 9", false},
5733 }
5734 for _, tc := range testCases {
5735 err := validate.Var(tc.encoded, "base64url")
5736 if tc.success {
5737 Equal(t, err, nil)
5738
5739 d, innerErr := base64.URLEncoding.DecodeString(tc.encoded)
5740 Equal(t, innerErr, nil)
5741 Equal(t, tc.decoded, string(d))
5742 } else {
5743 NotEqual(t, err, nil)
5744 if len(tc.encoded) > 0 {
5745
5746 _, err := base64.URLEncoding.DecodeString(tc.encoded)
5747 NotEqual(t, err, nil)
5748 }
5749 }
5750 }
5751 }
5752
5753 func TestBase64RawURLValidation(t *testing.T) {
5754 validate := New()
5755
5756 testCases := []struct {
5757 decoded, encoded string
5758 success bool
5759 }{
5760
5761 {"", "", false},
5762
5763 {"", "a", false},
5764
5765 {"f", "Zg==", false},
5766 {"fo", "Zm8=", false},
5767
5768 {"foo", "Zm9v", true},
5769 {"hello", "aGVsbG8", true},
5770 {"", "aGVsb", false},
5771
5772 {"\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l+", false},
5773 {"\x14\xfb\x9c\x03\xf9\x73", "FPucA/lz", false},
5774
5775 {"\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l-", true},
5776 {"\x14\xfb\x9c\x03\xf9\x73", "FPucA_lz", true},
5777
5778 {"", "@mc=", false},
5779 {"", "Zm 9", false},
5780 }
5781 for _, tc := range testCases {
5782 err := validate.Var(tc.encoded, "base64rawurl")
5783 if tc.success {
5784 Equal(t, err, nil)
5785
5786 d, innerErr := base64.RawURLEncoding.DecodeString(tc.encoded)
5787 Equal(t, innerErr, nil)
5788 Equal(t, tc.decoded, string(d))
5789 } else {
5790 NotEqual(t, err, nil)
5791 if len(tc.encoded) > 0 {
5792
5793 _, err := base64.RawURLEncoding.DecodeString(tc.encoded)
5794 NotEqual(t, err, nil)
5795 }
5796 }
5797 }
5798 }
5799
5800 func TestFileValidation(t *testing.T) {
5801 validate := New()
5802
5803 tests := []struct {
5804 title string
5805 param string
5806 expected bool
5807 }{
5808 {"empty path", "", false},
5809 {"regular file", filepath.Join("testdata", "a.go"), true},
5810 {"missing file", filepath.Join("testdata", "no.go"), false},
5811 {"directory, not a file", "testdata", false},
5812 }
5813
5814 for _, test := range tests {
5815 errs := validate.Var(test.param, "file")
5816
5817 if test.expected {
5818 if !IsEqual(errs, nil) {
5819 t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
5820 }
5821 } else {
5822 if IsEqual(errs, nil) {
5823 t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
5824 }
5825 }
5826 }
5827
5828 PanicMatches(t, func() {
5829 _ = validate.Var(6, "file")
5830 }, "Bad field type int")
5831 }
5832
5833 func TestImageValidation(t *testing.T) {
5834 validate := New()
5835
5836 paths := map[string]string{
5837 "empty": "",
5838 "directory": "testdata",
5839 "missing": filepath.Join("testdata", "none.png"),
5840 "png": filepath.Join("testdata", "image.png"),
5841 "jpeg": filepath.Join("testdata", "image.jpg"),
5842 "mp3": filepath.Join("testdata", "music.mp3"),
5843 }
5844
5845 tests := []struct {
5846 title string
5847 param string
5848 expected bool
5849 createImage func()
5850 destroyImage func()
5851 }{
5852 {
5853 "empty path",
5854 paths["empty"], false,
5855 func() {},
5856 func() {},
5857 },
5858 {
5859 "directory, not a file",
5860 paths["directory"],
5861 false,
5862 func() {},
5863 func() {},
5864 },
5865 {
5866 "missing file",
5867 paths["missing"],
5868 false,
5869 func() {},
5870 func() {},
5871 },
5872 {
5873 "valid png",
5874 paths["png"],
5875 true,
5876 func() {
5877 img := image.NewRGBA(image.Rectangle{image.Point{0, 0}, image.Point{10, 10}})
5878 f, _ := os.Create(paths["png"])
5879 err := png.Encode(f, img)
5880 if err != nil {
5881 panic(fmt.Sprintf("Could not encode file in PNG. Error: %s", err))
5882 }
5883 },
5884 func() {
5885 os.Remove(paths["png"])
5886 },
5887 },
5888 {
5889 "valid jpeg",
5890 paths["jpeg"],
5891 true,
5892 func() {
5893 var opt jpeg.Options
5894 img := image.NewGray(image.Rect(0, 0, 10, 10))
5895 f, _ := os.Create(paths["jpeg"])
5896 err := jpeg.Encode(f, img, &opt)
5897 if err != nil {
5898 panic(fmt.Sprintf("Could not encode file in JPEG. Error: %s", err))
5899 }
5900 },
5901 func() {
5902 os.Remove(paths["jpeg"])
5903 },
5904 },
5905 {
5906 "valid mp3",
5907 paths["mp3"],
5908 false,
5909 func() {},
5910 func() {},
5911 },
5912 }
5913
5914 for _, test := range tests {
5915 test.createImage()
5916 errs := validate.Var(test.param, "image")
5917
5918 if test.expected {
5919 if !IsEqual(errs, nil) {
5920 t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
5921 }
5922 } else {
5923 if IsEqual(errs, nil) {
5924 t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
5925 }
5926 }
5927 test.destroyImage()
5928 }
5929
5930 PanicMatches(t, func() {
5931 _ = validate.Var(6, "file")
5932 }, "Bad field type int")
5933 }
5934
5935 func TestFilePathValidation(t *testing.T) {
5936 validate := New()
5937
5938 tests := []struct {
5939 title string
5940 param string
5941 expected bool
5942 }{
5943 {"empty filepath", "", false},
5944 {"valid filepath", filepath.Join("testdata", "a.go"), true},
5945 {"invalid filepath", filepath.Join("testdata", "no\000.go"), false},
5946 {"directory, not a filepath", "testdata" + string(os.PathSeparator), false},
5947 {"directory", "testdata", false},
5948 }
5949
5950 for _, test := range tests {
5951 errs := validate.Var(test.param, "filepath")
5952
5953 if test.expected {
5954 if !IsEqual(errs, nil) {
5955 t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
5956 }
5957 } else {
5958 if IsEqual(errs, nil) {
5959 t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
5960 }
5961 }
5962
5963 }
5964
5965 PanicMatches(t, func() {
5966 _ = validate.Var(6, "filepath")
5967 }, "Bad field type int")
5968 }
5969
5970 func TestEthereumAddressValidation(t *testing.T) {
5971 validate := New()
5972
5973 tests := []struct {
5974 param string
5975 expected bool
5976 }{
5977
5978 {"0x52908400098527886E0F7030069857D2E4169EE7", true},
5979 {"0x8617E340B3D01FA5F11F306F4090FD50E238070D", true},
5980
5981
5982 {"0xde709f2102306220921060314715629080e2fb77", true},
5983 {"0x27b1fdb04752bbc536007a920d24acb045561c26", true},
5984 {"0x123f681646d4a755815f9cb19e1acc8565a0c2ac", true},
5985
5986
5987 {"0x02F9AE5f22EA3fA88F05780B30385bECFacbf130", true},
5988 {"0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed", true},
5989 {"0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359", true},
5990 {"0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB", true},
5991 {"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb", true},
5992 {"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDB", true},
5993
5994
5995 {"", false},
5996 {"D1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb", false},
5997 {"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDbc", false},
5998 {"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aD", false},
5999 {"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDw", false},
6000 }
6001
6002 for i, test := range tests {
6003
6004 errs := validate.Var(test.param, "eth_addr")
6005
6006 if test.expected {
6007 if !IsEqual(errs, nil) {
6008 t.Fatalf("Index: %d eth_addr failed Error: %s", i, errs)
6009 }
6010 } else {
6011 if IsEqual(errs, nil) {
6012 t.Fatalf("Index: %d eth_addr failed Error: %s", i, errs)
6013 } else {
6014 val := getError(errs, "", "")
6015 if val.Tag() != "eth_addr" {
6016 t.Fatalf("Index: %d Latitude failed Error: %s", i, errs)
6017 }
6018 }
6019 }
6020 }
6021 }
6022
6023 func TestEthereumAddressChecksumValidation(t *testing.T) {
6024 validate := New()
6025
6026 tests := []struct {
6027 param string
6028 expected bool
6029 }{
6030
6031 {"0x52908400098527886E0F7030069857D2E4169EE7", true},
6032 {"0x8617E340B3D01FA5F11F306F4090FD50E238070D", true},
6033
6034
6035 {"0x27b1fdb04752bbc536007a920d24acb045561c26", true},
6036 {"0x123f681646d4a755815f9cb19e1acc8565a0c2ac", false},
6037
6038
6039 {"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb", true},
6040 {"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDB", false},
6041 {"0x000000000000000000000000000000000000dead", false},
6042 {"0x000000000000000000000000000000000000dEaD", true},
6043
6044
6045 {"", false},
6046 {"D1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb", false},
6047 {"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDbc", false},
6048 {"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aD", false},
6049 {"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDw", false},
6050 }
6051
6052 for i, test := range tests {
6053
6054 errs := validate.Var(test.param, "eth_addr_checksum")
6055
6056 if test.expected {
6057 if !IsEqual(errs, nil) {
6058 t.Fatalf("Index: %d eth_addr_checksum failed Error: %s", i, errs)
6059 }
6060 } else {
6061 if IsEqual(errs, nil) {
6062 t.Fatalf("Index: %d eth_addr_checksum failed Error: %s", i, errs)
6063 } else {
6064 val := getError(errs, "", "")
6065 if val.Tag() != "eth_addr_checksum" {
6066 t.Fatalf("Index: %d Latitude failed Error: %s", i, errs)
6067 }
6068 }
6069 }
6070 }
6071 }
6072
6073 func TestBitcoinAddressValidation(t *testing.T) {
6074 validate := New()
6075
6076 tests := []struct {
6077 param string
6078 expected bool
6079 }{
6080 {"", false},
6081 {"x", false},
6082 {"0x02F9AE5f22EA3fA88F05780B30385bEC", false},
6083 {"1A1zP1ePQGefi2DMPTifTL5SLmv7DivfNa", false},
6084 {"1P9RQEr2XeE3PEb44ZE35sfZRRW1JH8Uqx", false},
6085 {"3P14159I73E4gFr7JterCCQh9QjiTjiZrG", false},
6086 {"3P141597f3E4gFr7JterCCQh9QjiTjiZrG", false},
6087 {"37qgekLpCCHrQuSjvX3fs496FWTGsHFHizjJAs6NPcR47aefnnCWECAhHV6E3g4YN7u7Yuwod5Y", false},
6088 {"dzb7VV1Ui55BARxv7ATxAtCUeJsANKovDGWFVgpTbhq9gvPqP3yv", false},
6089 {"MuNu7ZAEDFiHthiunm7dPjwKqrVNCM3mAz6rP9zFveQu14YA8CxExSJTHcVP9DErn6u84E6Ej7S", false},
6090 {"rPpQpYknyNQ5AEHuY6H8ijJJrYc2nDKKk9jjmKEXsWzyAQcFGpDLU2Zvsmoi8JLR7hAwoy3RQWf", false},
6091 {"4Uc3FmN6NQ6zLBK5QQBXRBUREaaHwCZYsGCueHauuDmJpZKn6jkEskMB2Zi2CNgtb5r6epWEFfUJq", false},
6092 {"7aQgR5DFQ25vyXmqZAWmnVCjL3PkBcdVkBUpjrjMTcghHx3E8wb", false},
6093 {"17QpPprjeg69fW1DV8DcYYCKvWjYhXvWkov6MJ1iTTvMFj6weAqW7wybZeH57WTNxXVCRH4veVs", false},
6094 {"KxuACDviz8Xvpn1xAh9MfopySZNuyajYMZWz16Dv2mHHryznWUp3", false},
6095 {"7nK3GSmqdXJQtdohvGfJ7KsSmn3TmGqExug49583bDAL91pVSGq5xS9SHoAYL3Wv3ijKTit65th", false},
6096 {"cTivdBmq7bay3RFGEBBuNfMh2P1pDCgRYN2Wbxmgwr4ki3jNUL2va", false},
6097 {"gjMV4vjNjyMrna4fsAr8bWxAbwtmMUBXJS3zL4NJt5qjozpbQLmAfK1uA3CquSqsZQMpoD1g2nk", false},
6098 {"emXm1naBMoVzPjbk7xpeTVMFy4oDEe25UmoyGgKEB1gGWsK8kRGs", false},
6099 {"7VThQnNRj1o3Zyvc7XHPRrjDf8j2oivPTeDXnRPYWeYGE4pXeRJDZgf28ppti5hsHWXS2GSobdqyo", false},
6100 {"1G9u6oCVCPh2o8m3t55ACiYvG1y5BHewUkDSdiQarDcYXXhFHYdzMdYfUAhfxn5vNZBwpgUNpso", false},
6101 {"31QQ7ZMLkScDiB4VyZjuptr7AEc9j1SjstF7pRoLhHTGkW4Q2y9XELobQmhhWxeRvqcukGd1XCq", false},
6102 {"DHqKSnpxa8ZdQyH8keAhvLTrfkyBMQxqngcQA5N8LQ9KVt25kmGN", false},
6103 {"2LUHcJPbwLCy9GLH1qXmfmAwvadWw4bp4PCpDfduLqV17s6iDcy1imUwhQJhAoNoN1XNmweiJP4i", false},
6104 {"7USRzBXAnmck8fX9HmW7RAb4qt92VFX6soCnts9s74wxm4gguVhtG5of8fZGbNPJA83irHVY6bCos", false},
6105 {"1DGezo7BfVebZxAbNT3XGujdeHyNNBF3vnficYoTSp4PfK2QaML9bHzAMxke3wdKdHYWmsMTJVu", false},
6106 {"2D12DqDZKwCxxkzs1ZATJWvgJGhQ4cFi3WrizQ5zLAyhN5HxuAJ1yMYaJp8GuYsTLLxTAz6otCfb", false},
6107 {"8AFJzuTujXjw1Z6M3fWhQ1ujDW7zsV4ePeVjVo7D1egERqSW9nZ", false},
6108 {"163Q17qLbTCue8YY3AvjpUhotuaodLm2uqMhpYirsKjVqnxJRWTEoywMVY3NbBAHuhAJ2cF9GAZ", false},
6109 {"2MnmgiRH4eGLyLc9eAqStzk7dFgBjFtUCtu", false},
6110 {"461QQ2sYWxU7H2PV4oBwJGNch8XVTYYbZxU", false},
6111 {"2UCtv53VttmQYkVU4VMtXB31REvQg4ABzs41AEKZ8UcB7DAfVzdkV9JDErwGwyj5AUHLkmgZeobs", false},
6112 {"cSNjAsnhgtiFMi6MtfvgscMB2Cbhn2v1FUYfviJ1CdjfidvmeW6mn", false},
6113 {"gmsow2Y6EWAFDFE1CE4Hd3Tpu2BvfmBfG1SXsuRARbnt1WjkZnFh1qGTiptWWbjsq2Q6qvpgJVj", false},
6114 {"nksUKSkzS76v8EsSgozXGMoQFiCoCHzCVajFKAXqzK5on9ZJYVHMD5CKwgmX3S3c7M1U3xabUny", false},
6115 {"L3favK1UzFGgdzYBF2oBT5tbayCo4vtVBLJhg2iYuMeePxWG8SQc", false},
6116 {"7VxLxGGtYT6N99GdEfi6xz56xdQ8nP2dG1CavuXx7Rf2PrvNMTBNevjkfgs9JmkcGm6EXpj8ipyPZ ", false},
6117 {"2mbZwFXF6cxShaCo2czTRB62WTx9LxhTtpP", false},
6118 {"dB7cwYdcPSgiyAwKWL3JwCVwSk6epU2txw", false},
6119 {"HPhFUhUAh8ZQQisH8QQWafAxtQYju3SFTX", false},
6120 {"4ctAH6AkHzq5ioiM1m9T3E2hiYEev5mTsB", false},
6121 {"31uEbMgunupShBVTewXjtqbBv5MndwfXhb", false},
6122 {"175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W", false},
6123 {"Hn1uFi4dNexWrqARpjMqgT6cX1UsNPuV3cHdGg9ExyXw8HTKadbktRDtdeVmY3M1BxJStiL4vjJ", false},
6124 {"Sq3fDbvutABmnAHHExJDgPLQn44KnNC7UsXuT7KZecpaYDMU9Txs", false},
6125 {"6TqWyrqdgUEYDQU1aChMuFMMEimHX44qHFzCUgGfqxGgZNMUVWJ", false},
6126 {"giqJo7oWqFxNKWyrgcBxAVHXnjJ1t6cGoEffce5Y1y7u649Noj5wJ4mmiUAKEVVrYAGg2KPB3Y4", false},
6127 {"cNzHY5e8vcmM3QVJUcjCyiKMYfeYvyueq5qCMV3kqcySoLyGLYUK", false},
6128 {"37uTe568EYc9WLoHEd9jXEvUiWbq5LFLscNyqvAzLU5vBArUJA6eydkLmnMwJDjkL5kXc2VK7ig", false},
6129 {"EsYbG4tWWWY45G31nox838qNdzksbPySWc", false},
6130 {"nbuzhfwMoNzA3PaFnyLcRxE9bTJPDkjZ6Rf6Y6o2ckXZfzZzXBT", false},
6131 {"cQN9PoxZeCWK1x56xnz6QYAsvR11XAce3Ehp3gMUdfSQ53Y2mPzx", false},
6132 {"1Gm3N3rkef6iMbx4voBzaxtXcmmiMTqZPhcuAepRzYUJQW4qRpEnHvMojzof42hjFRf8PE2jPde", false},
6133 {"2TAq2tuN6x6m233bpT7yqdYQPELdTDJn1eU", false},
6134 {"ntEtnnGhqPii4joABvBtSEJG6BxjT2tUZqE8PcVYgk3RHpgxgHDCQxNbLJf7ardf1dDk2oCQ7Cf", false},
6135 {"Ky1YjoZNgQ196HJV3HpdkecfhRBmRZdMJk89Hi5KGfpfPwS2bUbfd", false},
6136 {"2A1q1YsMZowabbvta7kTy2Fd6qN4r5ZCeG3qLpvZBMzCixMUdkN2Y4dHB1wPsZAeVXUGD83MfRED", false},
6137 {"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", true},
6138 {"1Ax4gZtb7gAit2TivwejZHYtNNLT18PUXJ", true},
6139 {"1C5bSj1iEGUgSTbziymG7Cn18ENQuT36vv", true},
6140 {"1Gqk4Tv79P91Cc1STQtU3s1W6277M2CVWu", true},
6141 {"1JwMWBVLtiqtscbaRHai4pqHokhFCbtoB4", true},
6142 {"19dcawoKcZdQz365WpXWMhX6QCUpR9SY4r", true},
6143 {"13p1ijLwsnrcuyqcTvJXkq2ASdXqcnEBLE", true},
6144 {"1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2", true},
6145 {"3P14159f73E4gFr7JterCCQh9QjiTjiZrG", true},
6146 {"3CMNFxN1oHBc4R1EpboAL5yzHGgE611Xou", true},
6147 {"3QjYXhTkvuj8qPaXHTTWb5wjXhdsLAAWVy", true},
6148 {"3AnNxabYGoTxYiTEZwFEnerUoeFXK2Zoks", true},
6149 {"33vt8ViH5jsr115AGkW6cEmEz9MpvJSwDk", true},
6150 {"3QCzvfL4ZRvmJFiWWBVwxfdaNBT8EtxB5y", true},
6151 {"37Sp6Rv3y4kVd1nQ1JV5pfqXccHNyZm1x3", true},
6152 {"3ALJH9Y951VCGcVZYAdpA3KchoP9McEj1G", true},
6153 {"12KYrjTdVGjFMtaxERSk3gphreJ5US8aUP", true},
6154 {"12QeMLzSrB8XH8FvEzPMVoRxVAzTr5XM2y", true},
6155 {"1oNLrsHnBcR6dpaBpwz3LSwutbUNkNSjs", true},
6156 {"1SQHtwR5oJRKLfiWQ2APsAd9miUc4k2ez", true},
6157 {"116CGDLddrZhMrTwhCVJXtXQpxygTT1kHd", true},
6158 {"3NJZLcZEEYBpxYEUGewU4knsQRn1WM5Fkt", true},
6159 }
6160
6161 for i, test := range tests {
6162
6163 errs := validate.Var(test.param, "btc_addr")
6164
6165 if test.expected {
6166 if !IsEqual(errs, nil) {
6167 t.Fatalf("Index: %d btc_addr failed with Error: %s", i, errs)
6168 }
6169 } else {
6170 if IsEqual(errs, nil) {
6171 t.Fatalf("Index: %d btc_addr failed with Error: %s", i, errs)
6172 } else {
6173 val := getError(errs, "", "")
6174 if val.Tag() != "btc_addr" {
6175 t.Fatalf("Index: %d Latitude failed with Error: %s", i, errs)
6176 }
6177 }
6178 }
6179 }
6180 }
6181
6182 func TestBitcoinBech32AddressValidation(t *testing.T) {
6183 validate := New()
6184
6185 tests := []struct {
6186 param string
6187 expected bool
6188 }{
6189 {"", false},
6190 {"bc1rw5uspcuh", false},
6191 {"bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5", false},
6192 {"BC13W508D6QEJXTDG4Y5R3ZARVARY0C5XW7KN40WF2", false},
6193 {"qw508d6qejxtdg4y5r3zarvary0c5xw7kg3g4ty", false},
6194 {"bc1rw5uspcuh", false},
6195 {"bc10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90", false},
6196 {"BC1QW508d6QEJxTDG4y5R3ZArVARY0C5XW7KV8F3T4", false},
6197 {"BC1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P", false},
6198 {"bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5", false},
6199 {"bc10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90", false},
6200 {"bc1pw508d6qejxtdg4y5r3zarqfsj6c3", false},
6201 {"bc1zw508d6qejxtdg4y5r3zarvaryvqyzf3du", false},
6202 {"bc1gmk9yu", false},
6203 {"bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv", false},
6204 {"BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4", true},
6205 {"bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx", true},
6206 {"bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3", true},
6207 {"BC1SW50QA3JX3S", true},
6208 {"bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj", true},
6209 }
6210
6211 for i, test := range tests {
6212
6213 errs := validate.Var(test.param, "btc_addr_bech32")
6214
6215 if test.expected {
6216 if !IsEqual(errs, nil) {
6217 t.Fatalf("Index: %d btc_addr_bech32 failed with Error: %s", i, errs)
6218 }
6219 } else {
6220 if IsEqual(errs, nil) {
6221 t.Fatalf("Index: %d btc_addr_bech32 failed with Error: %s", i, errs)
6222 } else {
6223 val := getError(errs, "", "")
6224 if val.Tag() != "btc_addr_bech32" {
6225 t.Fatalf("Index: %d Latitude failed with Error: %s", i, errs)
6226 }
6227 }
6228 }
6229 }
6230 }
6231
6232 func TestNoStructLevelValidation(t *testing.T) {
6233 type Inner struct {
6234 Test string `validate:"len=5"`
6235 }
6236
6237 type Outer struct {
6238 InnerStruct Inner `validate:"required,nostructlevel"`
6239 InnerStructPtr *Inner `validate:"required,nostructlevel"`
6240 }
6241
6242 outer := &Outer{
6243 InnerStructPtr: nil,
6244 InnerStruct: Inner{},
6245 }
6246
6247
6248 validate := New(WithRequiredStructEnabled())
6249
6250 errs := validate.Struct(outer)
6251 NotEqual(t, errs, nil)
6252 AssertError(t, errs, "Outer.InnerStruct", "Outer.InnerStruct", "InnerStruct", "InnerStruct", "required")
6253 AssertError(t, errs, "Outer.InnerStructPtr", "Outer.InnerStructPtr", "InnerStructPtr", "InnerStructPtr", "required")
6254
6255 inner := Inner{
6256 Test: "1234",
6257 }
6258
6259 outer = &Outer{
6260 InnerStruct: inner,
6261 InnerStructPtr: &inner,
6262 }
6263
6264 errs = validate.Struct(outer)
6265 Equal(t, errs, nil)
6266
6267
6268
6269 outer = &Outer{
6270 InnerStructPtr: nil,
6271 InnerStruct: Inner{},
6272 }
6273 validate = New()
6274
6275 errs = validate.Struct(outer)
6276 NotEqual(t, errs, nil)
6277 AssertError(t, errs, "Outer.InnerStructPtr", "Outer.InnerStructPtr", "InnerStructPtr", "InnerStructPtr", "required")
6278
6279 inner = Inner{
6280 Test: "1234",
6281 }
6282
6283 outer = &Outer{
6284 InnerStruct: inner,
6285 InnerStructPtr: &inner,
6286 }
6287
6288 errs = validate.Struct(outer)
6289 Equal(t, errs, nil)
6290 }
6291
6292 func TestStructOnlyValidation(t *testing.T) {
6293 type Inner struct {
6294 Test string `validate:"len=5"`
6295 }
6296
6297 type Outer struct {
6298 InnerStruct Inner `validate:"required,structonly"`
6299 InnerStructPtr *Inner `validate:"required,structonly"`
6300 }
6301
6302 outer := &Outer{
6303 InnerStruct: Inner{},
6304 InnerStructPtr: nil,
6305 }
6306
6307
6308 validate := New()
6309
6310 errs := validate.Struct(outer)
6311 NotEqual(t, errs, nil)
6312 AssertError(t, errs, "Outer.InnerStructPtr", "Outer.InnerStructPtr", "InnerStructPtr", "InnerStructPtr", "required")
6313
6314
6315 validate.requiredStructEnabled = true
6316
6317 errs = validate.Struct(outer)
6318 NotEqual(t, errs, nil)
6319 AssertError(t, errs, "Outer.InnerStruct", "Outer.InnerStruct", "InnerStruct", "InnerStruct", "required")
6320 AssertError(t, errs, "Outer.InnerStructPtr", "Outer.InnerStructPtr", "InnerStructPtr", "InnerStructPtr", "required")
6321
6322 inner := Inner{
6323 Test: "1234",
6324 }
6325
6326 outer = &Outer{
6327 InnerStruct: inner,
6328 InnerStructPtr: &inner,
6329 }
6330
6331 errs = validate.Struct(outer)
6332 Equal(t, errs, nil)
6333
6334
6335 type Address struct {
6336 Street string `validate:"required"`
6337 City string `validate:"required"`
6338 Planet string `validate:"required"`
6339 Phone string `validate:"required"`
6340 }
6341
6342 type User struct {
6343 FirstName string `json:"fname"`
6344 LastName string `json:"lname"`
6345 Age uint8 `validate:"gte=0,lte=130"`
6346 Number string `validate:"required,e164"`
6347 Email string `validate:"required,email"`
6348 FavouriteColor string `validate:"hexcolor|rgb|rgba"`
6349 Addresses []*Address `validate:"required"`
6350 Address Address `validate:"structonly"`
6351 }
6352
6353 address := &Address{
6354 Street: "Eavesdown Docks",
6355 Planet: "Persphone",
6356 Phone: "none",
6357 City: "Unknown",
6358 }
6359
6360 user := &User{
6361 FirstName: "",
6362 LastName: "",
6363 Age: 45,
6364 Number: "+1123456789",
6365 Email: "Badger.Smith@gmail.com",
6366 FavouriteColor: "#000",
6367 Addresses: []*Address{address},
6368 Address: Address{
6369
6370 Planet: "Persphone",
6371 Phone: "none",
6372 City: "Unknown",
6373 },
6374 }
6375
6376 errs = validate.Struct(user)
6377 Equal(t, errs, nil)
6378 }
6379
6380 func TestGtField(t *testing.T) {
6381 var errs error
6382 validate := New()
6383
6384 type TimeTest struct {
6385 Start *time.Time `validate:"required,gt"`
6386 End *time.Time `validate:"required,gt,gtfield=Start"`
6387 }
6388
6389 now := time.Now()
6390 start := now.Add(time.Hour * 24)
6391 end := start.Add(time.Hour * 24)
6392
6393 timeTest := &TimeTest{
6394 Start: &start,
6395 End: &end,
6396 }
6397
6398 errs = validate.Struct(timeTest)
6399 Equal(t, errs, nil)
6400
6401 timeTest = &TimeTest{
6402 Start: &end,
6403 End: &start,
6404 }
6405
6406 errs = validate.Struct(timeTest)
6407 NotEqual(t, errs, nil)
6408 AssertError(t, errs, "TimeTest.End", "TimeTest.End", "End", "End", "gtfield")
6409
6410 errs = validate.VarWithValue(&end, &start, "gtfield")
6411 Equal(t, errs, nil)
6412
6413 errs = validate.VarWithValue(&start, &end, "gtfield")
6414 NotEqual(t, errs, nil)
6415 AssertError(t, errs, "", "", "", "", "gtfield")
6416
6417 errs = validate.VarWithValue(&end, &start, "gtfield")
6418 Equal(t, errs, nil)
6419
6420 errs = validate.VarWithValue(&timeTest, &end, "gtfield")
6421 NotEqual(t, errs, nil)
6422
6423 errs = validate.VarWithValue("test bigger", "test", "gtfield")
6424 Equal(t, errs, nil)
6425
6426
6427
6428
6429
6430 errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "gtfield")
6431 Equal(t, errs, nil)
6432
6433 errs = validate.VarWithValue(time.Hour, time.Hour, "gtfield")
6434 NotEqual(t, errs, nil)
6435 AssertError(t, errs, "", "", "", "", "gtfield")
6436
6437 errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "gtfield")
6438 NotEqual(t, errs, nil)
6439 AssertError(t, errs, "", "", "", "", "gtfield")
6440
6441 errs = validate.VarWithValue(time.Duration(0), time.Hour, "omitempty,gtfield")
6442 Equal(t, errs, nil)
6443
6444
6445
6446 type TimeDurationTest struct {
6447 First time.Duration `validate:"gtfield=Second"`
6448 Second time.Duration
6449 }
6450 var timeDurationTest *TimeDurationTest
6451
6452 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour - time.Minute}
6453 errs = validate.Struct(timeDurationTest)
6454 Equal(t, errs, nil)
6455
6456 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour}
6457 errs = validate.Struct(timeDurationTest)
6458 NotEqual(t, errs, nil)
6459 AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "gtfield")
6460
6461 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour + time.Minute}
6462 errs = validate.Struct(timeDurationTest)
6463 NotEqual(t, errs, nil)
6464 AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "gtfield")
6465
6466 type TimeDurationOmitemptyTest struct {
6467 First time.Duration `validate:"omitempty,gtfield=Second"`
6468 Second time.Duration
6469 }
6470
6471 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0), time.Hour}
6472 errs = validate.Struct(timeDurationOmitemptyTest)
6473 Equal(t, errs, nil)
6474
6475
6476
6477 type IntTest struct {
6478 Val1 int `validate:"required"`
6479 Val2 int `validate:"required,gtfield=Val1"`
6480 }
6481
6482 intTest := &IntTest{
6483 Val1: 1,
6484 Val2: 5,
6485 }
6486
6487 errs = validate.Struct(intTest)
6488 Equal(t, errs, nil)
6489
6490 intTest = &IntTest{
6491 Val1: 5,
6492 Val2: 1,
6493 }
6494
6495 errs = validate.Struct(intTest)
6496 NotEqual(t, errs, nil)
6497 AssertError(t, errs, "IntTest.Val2", "IntTest.Val2", "Val2", "Val2", "gtfield")
6498
6499 errs = validate.VarWithValue(int(5), int(1), "gtfield")
6500 Equal(t, errs, nil)
6501
6502 errs = validate.VarWithValue(int(1), int(5), "gtfield")
6503 NotEqual(t, errs, nil)
6504 AssertError(t, errs, "", "", "", "", "gtfield")
6505
6506 type UIntTest struct {
6507 Val1 uint `validate:"required"`
6508 Val2 uint `validate:"required,gtfield=Val1"`
6509 }
6510
6511 uIntTest := &UIntTest{
6512 Val1: 1,
6513 Val2: 5,
6514 }
6515
6516 errs = validate.Struct(uIntTest)
6517 Equal(t, errs, nil)
6518
6519 uIntTest = &UIntTest{
6520 Val1: 5,
6521 Val2: 1,
6522 }
6523
6524 errs = validate.Struct(uIntTest)
6525 NotEqual(t, errs, nil)
6526 AssertError(t, errs, "UIntTest.Val2", "UIntTest.Val2", "Val2", "Val2", "gtfield")
6527
6528 errs = validate.VarWithValue(uint(5), uint(1), "gtfield")
6529 Equal(t, errs, nil)
6530
6531 errs = validate.VarWithValue(uint(1), uint(5), "gtfield")
6532 NotEqual(t, errs, nil)
6533 AssertError(t, errs, "", "", "", "", "gtfield")
6534
6535 type FloatTest struct {
6536 Val1 float64 `validate:"required"`
6537 Val2 float64 `validate:"required,gtfield=Val1"`
6538 }
6539
6540 floatTest := &FloatTest{
6541 Val1: 1,
6542 Val2: 5,
6543 }
6544
6545 errs = validate.Struct(floatTest)
6546 Equal(t, errs, nil)
6547
6548 floatTest = &FloatTest{
6549 Val1: 5,
6550 Val2: 1,
6551 }
6552
6553 errs = validate.Struct(floatTest)
6554 NotEqual(t, errs, nil)
6555 AssertError(t, errs, "FloatTest.Val2", "FloatTest.Val2", "Val2", "Val2", "gtfield")
6556
6557 errs = validate.VarWithValue(float32(5), float32(1), "gtfield")
6558 Equal(t, errs, nil)
6559
6560 errs = validate.VarWithValue(float32(1), float32(5), "gtfield")
6561 NotEqual(t, errs, nil)
6562 AssertError(t, errs, "", "", "", "", "gtfield")
6563
6564 errs = validate.VarWithValue(nil, 1, "gtfield")
6565 NotEqual(t, errs, nil)
6566 AssertError(t, errs, "", "", "", "", "gtfield")
6567
6568 errs = validate.VarWithValue(5, "T", "gtfield")
6569 NotEqual(t, errs, nil)
6570 AssertError(t, errs, "", "", "", "", "gtfield")
6571
6572 errs = validate.VarWithValue(5, start, "gtfield")
6573 NotEqual(t, errs, nil)
6574 AssertError(t, errs, "", "", "", "", "gtfield")
6575
6576 type TimeTest2 struct {
6577 Start *time.Time `validate:"required"`
6578 End *time.Time `validate:"required,gtfield=NonExistantField"`
6579 }
6580
6581 timeTest2 := &TimeTest2{
6582 Start: &start,
6583 End: &end,
6584 }
6585
6586 errs = validate.Struct(timeTest2)
6587 NotEqual(t, errs, nil)
6588 AssertError(t, errs, "TimeTest2.End", "TimeTest2.End", "End", "End", "gtfield")
6589
6590 type Other struct {
6591 Value string
6592 }
6593
6594 type Test struct {
6595 Value Other
6596 Time time.Time `validate:"gtfield=Value"`
6597 }
6598
6599 tst := Test{
6600 Value: Other{Value: "StringVal"},
6601 Time: end,
6602 }
6603
6604 errs = validate.Struct(tst)
6605 NotEqual(t, errs, nil)
6606 AssertError(t, errs, "Test.Time", "Test.Time", "Time", "Time", "gtfield")
6607 }
6608
6609 func TestLtField(t *testing.T) {
6610 var errs error
6611 validate := New()
6612
6613 type TimeTest struct {
6614 Start *time.Time `validate:"required,lt,ltfield=End"`
6615 End *time.Time `validate:"required,lt"`
6616 }
6617
6618 now := time.Now()
6619 start := now.Add(time.Hour * 24 * -1 * 2)
6620 end := start.Add(time.Hour * 24)
6621
6622 timeTest := &TimeTest{
6623 Start: &start,
6624 End: &end,
6625 }
6626
6627 errs = validate.Struct(timeTest)
6628 Equal(t, errs, nil)
6629
6630 timeTest = &TimeTest{
6631 Start: &end,
6632 End: &start,
6633 }
6634
6635 errs = validate.Struct(timeTest)
6636 NotEqual(t, errs, nil)
6637 AssertError(t, errs, "TimeTest.Start", "TimeTest.Start", "Start", "Start", "ltfield")
6638
6639 errs = validate.VarWithValue(&start, &end, "ltfield")
6640 Equal(t, errs, nil)
6641
6642 errs = validate.VarWithValue(&end, &start, "ltfield")
6643 NotEqual(t, errs, nil)
6644 AssertError(t, errs, "", "", "", "", "ltfield")
6645
6646 errs = validate.VarWithValue(&end, timeTest, "ltfield")
6647 NotEqual(t, errs, nil)
6648 AssertError(t, errs, "", "", "", "", "ltfield")
6649
6650 errs = validate.VarWithValue("tes", "test", "ltfield")
6651 Equal(t, errs, nil)
6652
6653
6654
6655
6656
6657 errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "ltfield")
6658 Equal(t, errs, nil)
6659
6660 errs = validate.VarWithValue(time.Hour, time.Hour, "ltfield")
6661 NotEqual(t, errs, nil)
6662 AssertError(t, errs, "", "", "", "", "ltfield")
6663
6664 errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "ltfield")
6665 NotEqual(t, errs, nil)
6666 AssertError(t, errs, "", "", "", "", "ltfield")
6667
6668 errs = validate.VarWithValue(time.Duration(0), -time.Minute, "omitempty,ltfield")
6669 Equal(t, errs, nil)
6670
6671
6672
6673 type TimeDurationTest struct {
6674 First time.Duration `validate:"ltfield=Second"`
6675 Second time.Duration
6676 }
6677 var timeDurationTest *TimeDurationTest
6678
6679 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour + time.Minute}
6680 errs = validate.Struct(timeDurationTest)
6681 Equal(t, errs, nil)
6682
6683 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour}
6684 errs = validate.Struct(timeDurationTest)
6685 NotEqual(t, errs, nil)
6686 AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "ltfield")
6687
6688 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour - time.Minute}
6689 errs = validate.Struct(timeDurationTest)
6690 NotEqual(t, errs, nil)
6691 AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "ltfield")
6692
6693 type TimeDurationOmitemptyTest struct {
6694 First time.Duration `validate:"omitempty,ltfield=Second"`
6695 Second time.Duration
6696 }
6697
6698 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0), -time.Minute}
6699 errs = validate.Struct(timeDurationOmitemptyTest)
6700 Equal(t, errs, nil)
6701
6702
6703
6704 type IntTest struct {
6705 Val1 int `validate:"required"`
6706 Val2 int `validate:"required,ltfield=Val1"`
6707 }
6708
6709 intTest := &IntTest{
6710 Val1: 5,
6711 Val2: 1,
6712 }
6713
6714 errs = validate.Struct(intTest)
6715 Equal(t, errs, nil)
6716
6717 intTest = &IntTest{
6718 Val1: 1,
6719 Val2: 5,
6720 }
6721
6722 errs = validate.Struct(intTest)
6723 NotEqual(t, errs, nil)
6724 AssertError(t, errs, "IntTest.Val2", "IntTest.Val2", "Val2", "Val2", "ltfield")
6725
6726 errs = validate.VarWithValue(int(1), int(5), "ltfield")
6727 Equal(t, errs, nil)
6728
6729 errs = validate.VarWithValue(int(5), int(1), "ltfield")
6730 NotEqual(t, errs, nil)
6731 AssertError(t, errs, "", "", "", "", "ltfield")
6732
6733 type UIntTest struct {
6734 Val1 uint `validate:"required"`
6735 Val2 uint `validate:"required,ltfield=Val1"`
6736 }
6737
6738 uIntTest := &UIntTest{
6739 Val1: 5,
6740 Val2: 1,
6741 }
6742
6743 errs = validate.Struct(uIntTest)
6744 Equal(t, errs, nil)
6745
6746 uIntTest = &UIntTest{
6747 Val1: 1,
6748 Val2: 5,
6749 }
6750
6751 errs = validate.Struct(uIntTest)
6752 NotEqual(t, errs, nil)
6753 AssertError(t, errs, "UIntTest.Val2", "UIntTest.Val2", "Val2", "Val2", "ltfield")
6754
6755 errs = validate.VarWithValue(uint(1), uint(5), "ltfield")
6756 Equal(t, errs, nil)
6757
6758 errs = validate.VarWithValue(uint(5), uint(1), "ltfield")
6759 NotEqual(t, errs, nil)
6760 AssertError(t, errs, "", "", "", "", "ltfield")
6761
6762 type FloatTest struct {
6763 Val1 float64 `validate:"required"`
6764 Val2 float64 `validate:"required,ltfield=Val1"`
6765 }
6766
6767 floatTest := &FloatTest{
6768 Val1: 5,
6769 Val2: 1,
6770 }
6771
6772 errs = validate.Struct(floatTest)
6773 Equal(t, errs, nil)
6774
6775 floatTest = &FloatTest{
6776 Val1: 1,
6777 Val2: 5,
6778 }
6779
6780 errs = validate.Struct(floatTest)
6781 NotEqual(t, errs, nil)
6782 AssertError(t, errs, "FloatTest.Val2", "FloatTest.Val2", "Val2", "Val2", "ltfield")
6783
6784 errs = validate.VarWithValue(float32(1), float32(5), "ltfield")
6785 Equal(t, errs, nil)
6786
6787 errs = validate.VarWithValue(float32(5), float32(1), "ltfield")
6788 NotEqual(t, errs, nil)
6789 AssertError(t, errs, "", "", "", "", "ltfield")
6790
6791 errs = validate.VarWithValue(nil, 5, "ltfield")
6792 NotEqual(t, errs, nil)
6793 AssertError(t, errs, "", "", "", "", "ltfield")
6794
6795 errs = validate.VarWithValue(1, "T", "ltfield")
6796 NotEqual(t, errs, nil)
6797 AssertError(t, errs, "", "", "", "", "ltfield")
6798
6799 errs = validate.VarWithValue(1, end, "ltfield")
6800 NotEqual(t, errs, nil)
6801 AssertError(t, errs, "", "", "", "", "ltfield")
6802
6803 type TimeTest2 struct {
6804 Start *time.Time `validate:"required"`
6805 End *time.Time `validate:"required,ltfield=NonExistantField"`
6806 }
6807
6808 timeTest2 := &TimeTest2{
6809 Start: &end,
6810 End: &start,
6811 }
6812
6813 errs = validate.Struct(timeTest2)
6814 NotEqual(t, errs, nil)
6815 AssertError(t, errs, "TimeTest2.End", "TimeTest2.End", "End", "End", "ltfield")
6816 }
6817
6818 func TestFieldContains(t *testing.T) {
6819 validate := New()
6820
6821 type StringTest struct {
6822 Foo string `validate:"fieldcontains=Bar"`
6823 Bar string
6824 }
6825
6826 stringTest := &StringTest{
6827 Foo: "foobar",
6828 Bar: "bar",
6829 }
6830
6831 errs := validate.Struct(stringTest)
6832 Equal(t, errs, nil)
6833
6834 stringTest = &StringTest{
6835 Foo: "foo",
6836 Bar: "bar",
6837 }
6838
6839 errs = validate.Struct(stringTest)
6840 NotEqual(t, errs, nil)
6841 AssertError(t, errs, "StringTest.Foo", "StringTest.Foo", "Foo", "Foo", "fieldcontains")
6842
6843 errs = validate.VarWithValue("foo", "bar", "fieldcontains")
6844 NotEqual(t, errs, nil)
6845 AssertError(t, errs, "", "", "", "", "fieldcontains")
6846
6847 errs = validate.VarWithValue("bar", "foobarfoo", "fieldcontains")
6848 NotEqual(t, errs, nil)
6849 AssertError(t, errs, "", "", "", "", "fieldcontains")
6850
6851 errs = validate.VarWithValue("foobarfoo", "bar", "fieldcontains")
6852 Equal(t, errs, nil)
6853
6854 type StringTestMissingField struct {
6855 Foo string `validate:"fieldcontains=Bar"`
6856 }
6857
6858 stringTestMissingField := &StringTestMissingField{
6859 Foo: "foo",
6860 }
6861
6862 errs = validate.Struct(stringTestMissingField)
6863 NotEqual(t, errs, nil)
6864 AssertError(t, errs, "StringTestMissingField.Foo", "StringTestMissingField.Foo", "Foo", "Foo", "fieldcontains")
6865 }
6866
6867 func TestFieldExcludes(t *testing.T) {
6868 validate := New()
6869
6870 type StringTest struct {
6871 Foo string `validate:"fieldexcludes=Bar"`
6872 Bar string
6873 }
6874
6875 stringTest := &StringTest{
6876 Foo: "foobar",
6877 Bar: "bar",
6878 }
6879
6880 errs := validate.Struct(stringTest)
6881 NotEqual(t, errs, nil)
6882 AssertError(t, errs, "StringTest.Foo", "StringTest.Foo", "Foo", "Foo", "fieldexcludes")
6883
6884 stringTest = &StringTest{
6885 Foo: "foo",
6886 Bar: "bar",
6887 }
6888
6889 errs = validate.Struct(stringTest)
6890 Equal(t, errs, nil)
6891
6892 errs = validate.VarWithValue("foo", "bar", "fieldexcludes")
6893 Equal(t, errs, nil)
6894
6895 errs = validate.VarWithValue("bar", "foobarfoo", "fieldexcludes")
6896 Equal(t, errs, nil)
6897
6898 errs = validate.VarWithValue("foobarfoo", "bar", "fieldexcludes")
6899 NotEqual(t, errs, nil)
6900 AssertError(t, errs, "", "", "", "", "fieldexcludes")
6901
6902 type StringTestMissingField struct {
6903 Foo string `validate:"fieldexcludes=Bar"`
6904 }
6905
6906 stringTestMissingField := &StringTestMissingField{
6907 Foo: "foo",
6908 }
6909
6910 errs = validate.Struct(stringTestMissingField)
6911 Equal(t, errs, nil)
6912 }
6913
6914 func TestContainsAndExcludes(t *testing.T) {
6915 validate := New()
6916
6917 type ImpossibleStringTest struct {
6918 Foo string `validate:"fieldcontains=Bar"`
6919 Bar string `validate:"fieldexcludes=Foo"`
6920 }
6921
6922 impossibleStringTest := &ImpossibleStringTest{
6923 Foo: "foo",
6924 Bar: "bar",
6925 }
6926
6927 errs := validate.Struct(impossibleStringTest)
6928 NotEqual(t, errs, nil)
6929 AssertError(t, errs, "ImpossibleStringTest.Foo", "ImpossibleStringTest.Foo", "Foo", "Foo", "fieldcontains")
6930
6931 impossibleStringTest = &ImpossibleStringTest{
6932 Foo: "bar",
6933 Bar: "foo",
6934 }
6935
6936 errs = validate.Struct(impossibleStringTest)
6937 NotEqual(t, errs, nil)
6938 AssertError(t, errs, "ImpossibleStringTest.Foo", "ImpossibleStringTest.Foo", "Foo", "Foo", "fieldcontains")
6939 }
6940
6941 func TestLteField(t *testing.T) {
6942 var errs error
6943 validate := New()
6944
6945 type TimeTest struct {
6946 Start *time.Time `validate:"required,lte,ltefield=End"`
6947 End *time.Time `validate:"required,lte"`
6948 }
6949
6950 now := time.Now()
6951 start := now.Add(time.Hour * 24 * -1 * 2)
6952 end := start.Add(time.Hour * 24)
6953
6954 timeTest := &TimeTest{
6955 Start: &start,
6956 End: &end,
6957 }
6958
6959 errs = validate.Struct(timeTest)
6960 Equal(t, errs, nil)
6961
6962 timeTest = &TimeTest{
6963 Start: &end,
6964 End: &start,
6965 }
6966
6967 errs = validate.Struct(timeTest)
6968 NotEqual(t, errs, nil)
6969 AssertError(t, errs, "TimeTest.Start", "TimeTest.Start", "Start", "Start", "ltefield")
6970
6971 errs = validate.VarWithValue(&start, &end, "ltefield")
6972 Equal(t, errs, nil)
6973
6974 errs = validate.VarWithValue(&end, &start, "ltefield")
6975 NotEqual(t, errs, nil)
6976 AssertError(t, errs, "", "", "", "", "ltefield")
6977
6978 errs = validate.VarWithValue(&end, timeTest, "ltefield")
6979 NotEqual(t, errs, nil)
6980 AssertError(t, errs, "", "", "", "", "ltefield")
6981
6982 errs = validate.VarWithValue("tes", "test", "ltefield")
6983 Equal(t, errs, nil)
6984
6985 errs = validate.VarWithValue("test", "test", "ltefield")
6986 Equal(t, errs, nil)
6987
6988
6989
6990
6991
6992 errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "ltefield")
6993 Equal(t, errs, nil)
6994
6995 errs = validate.VarWithValue(time.Hour, time.Hour, "ltefield")
6996 Equal(t, errs, nil)
6997
6998 errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "ltefield")
6999 NotEqual(t, errs, nil)
7000 AssertError(t, errs, "", "", "", "", "ltefield")
7001
7002 errs = validate.VarWithValue(time.Duration(0), -time.Minute, "omitempty,ltefield")
7003 Equal(t, errs, nil)
7004
7005
7006
7007 type TimeDurationTest struct {
7008 First time.Duration `validate:"ltefield=Second"`
7009 Second time.Duration
7010 }
7011 var timeDurationTest *TimeDurationTest
7012
7013 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour + time.Minute}
7014 errs = validate.Struct(timeDurationTest)
7015 Equal(t, errs, nil)
7016
7017 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour}
7018 errs = validate.Struct(timeDurationTest)
7019 Equal(t, errs, nil)
7020
7021 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour - time.Minute}
7022 errs = validate.Struct(timeDurationTest)
7023 NotEqual(t, errs, nil)
7024 AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "ltefield")
7025
7026 type TimeDurationOmitemptyTest struct {
7027 First time.Duration `validate:"omitempty,ltefield=Second"`
7028 Second time.Duration
7029 }
7030
7031 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0), -time.Minute}
7032 errs = validate.Struct(timeDurationOmitemptyTest)
7033 Equal(t, errs, nil)
7034
7035
7036
7037 type IntTest struct {
7038 Val1 int `validate:"required"`
7039 Val2 int `validate:"required,ltefield=Val1"`
7040 }
7041
7042 intTest := &IntTest{
7043 Val1: 5,
7044 Val2: 1,
7045 }
7046
7047 errs = validate.Struct(intTest)
7048 Equal(t, errs, nil)
7049
7050 intTest = &IntTest{
7051 Val1: 1,
7052 Val2: 5,
7053 }
7054
7055 errs = validate.Struct(intTest)
7056 NotEqual(t, errs, nil)
7057 AssertError(t, errs, "IntTest.Val2", "IntTest.Val2", "Val2", "Val2", "ltefield")
7058
7059 errs = validate.VarWithValue(int(1), int(5), "ltefield")
7060 Equal(t, errs, nil)
7061
7062 errs = validate.VarWithValue(int(5), int(1), "ltefield")
7063 NotEqual(t, errs, nil)
7064 AssertError(t, errs, "", "", "", "", "ltefield")
7065
7066 type UIntTest struct {
7067 Val1 uint `validate:"required"`
7068 Val2 uint `validate:"required,ltefield=Val1"`
7069 }
7070
7071 uIntTest := &UIntTest{
7072 Val1: 5,
7073 Val2: 1,
7074 }
7075
7076 errs = validate.Struct(uIntTest)
7077 Equal(t, errs, nil)
7078
7079 uIntTest = &UIntTest{
7080 Val1: 1,
7081 Val2: 5,
7082 }
7083
7084 errs = validate.Struct(uIntTest)
7085 NotEqual(t, errs, nil)
7086 AssertError(t, errs, "UIntTest.Val2", "UIntTest.Val2", "Val2", "Val2", "ltefield")
7087
7088 errs = validate.VarWithValue(uint(1), uint(5), "ltefield")
7089 Equal(t, errs, nil)
7090
7091 errs = validate.VarWithValue(uint(5), uint(1), "ltefield")
7092 NotEqual(t, errs, nil)
7093 AssertError(t, errs, "", "", "", "", "ltefield")
7094
7095 type FloatTest struct {
7096 Val1 float64 `validate:"required"`
7097 Val2 float64 `validate:"required,ltefield=Val1"`
7098 }
7099
7100 floatTest := &FloatTest{
7101 Val1: 5,
7102 Val2: 1,
7103 }
7104
7105 errs = validate.Struct(floatTest)
7106 Equal(t, errs, nil)
7107
7108 floatTest = &FloatTest{
7109 Val1: 1,
7110 Val2: 5,
7111 }
7112
7113 errs = validate.Struct(floatTest)
7114 NotEqual(t, errs, nil)
7115 AssertError(t, errs, "FloatTest.Val2", "FloatTest.Val2", "Val2", "Val2", "ltefield")
7116
7117 errs = validate.VarWithValue(float32(1), float32(5), "ltefield")
7118 Equal(t, errs, nil)
7119
7120 errs = validate.VarWithValue(float32(5), float32(1), "ltefield")
7121 NotEqual(t, errs, nil)
7122 AssertError(t, errs, "", "", "", "", "ltefield")
7123
7124 errs = validate.VarWithValue(nil, 5, "ltefield")
7125 NotEqual(t, errs, nil)
7126 AssertError(t, errs, "", "", "", "", "ltefield")
7127
7128 errs = validate.VarWithValue(1, "T", "ltefield")
7129 NotEqual(t, errs, nil)
7130 AssertError(t, errs, "", "", "", "", "ltefield")
7131
7132 errs = validate.VarWithValue(1, end, "ltefield")
7133 NotEqual(t, errs, nil)
7134 AssertError(t, errs, "", "", "", "", "ltefield")
7135
7136 type TimeTest2 struct {
7137 Start *time.Time `validate:"required"`
7138 End *time.Time `validate:"required,ltefield=NonExistantField"`
7139 }
7140
7141 timeTest2 := &TimeTest2{
7142 Start: &end,
7143 End: &start,
7144 }
7145
7146 errs = validate.Struct(timeTest2)
7147 NotEqual(t, errs, nil)
7148 AssertError(t, errs, "TimeTest2.End", "TimeTest2.End", "End", "End", "ltefield")
7149 }
7150
7151 func TestGteField(t *testing.T) {
7152 var errs error
7153 validate := New()
7154
7155 type TimeTest struct {
7156 Start *time.Time `validate:"required,gte"`
7157 End *time.Time `validate:"required,gte,gtefield=Start"`
7158 }
7159
7160 now := time.Now()
7161 start := now.Add(time.Hour * 24)
7162 end := start.Add(time.Hour * 24)
7163
7164 timeTest := &TimeTest{
7165 Start: &start,
7166 End: &end,
7167 }
7168
7169 errs = validate.Struct(timeTest)
7170 Equal(t, errs, nil)
7171
7172 timeTest = &TimeTest{
7173 Start: &end,
7174 End: &start,
7175 }
7176
7177 errs = validate.Struct(timeTest)
7178 NotEqual(t, errs, nil)
7179 AssertError(t, errs, "TimeTest.End", "TimeTest.End", "End", "End", "gtefield")
7180
7181 errs = validate.VarWithValue(&end, &start, "gtefield")
7182 Equal(t, errs, nil)
7183
7184 errs = validate.VarWithValue(&start, &end, "gtefield")
7185 NotEqual(t, errs, nil)
7186 AssertError(t, errs, "", "", "", "", "gtefield")
7187
7188 errs = validate.VarWithValue(&start, timeTest, "gtefield")
7189 NotEqual(t, errs, nil)
7190 AssertError(t, errs, "", "", "", "", "gtefield")
7191
7192 errs = validate.VarWithValue("test", "test", "gtefield")
7193 Equal(t, errs, nil)
7194
7195 errs = validate.VarWithValue("test bigger", "test", "gtefield")
7196 Equal(t, errs, nil)
7197
7198
7199
7200
7201
7202 errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "gtefield")
7203 Equal(t, errs, nil)
7204
7205 errs = validate.VarWithValue(time.Hour, time.Hour, "gtefield")
7206 Equal(t, errs, nil)
7207
7208 errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "gtefield")
7209 NotEqual(t, errs, nil)
7210 AssertError(t, errs, "", "", "", "", "gtefield")
7211
7212 errs = validate.VarWithValue(time.Duration(0), time.Hour, "omitempty,gtefield")
7213 Equal(t, errs, nil)
7214
7215
7216
7217 type TimeDurationTest struct {
7218 First time.Duration `validate:"gtefield=Second"`
7219 Second time.Duration
7220 }
7221 var timeDurationTest *TimeDurationTest
7222
7223 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour - time.Minute}
7224 errs = validate.Struct(timeDurationTest)
7225 Equal(t, errs, nil)
7226
7227 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour}
7228 errs = validate.Struct(timeDurationTest)
7229 Equal(t, errs, nil)
7230
7231 timeDurationTest = &TimeDurationTest{time.Hour, time.Hour + time.Minute}
7232 errs = validate.Struct(timeDurationTest)
7233 NotEqual(t, errs, nil)
7234 AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "gtefield")
7235
7236 type TimeDurationOmitemptyTest struct {
7237 First time.Duration `validate:"omitempty,gtefield=Second"`
7238 Second time.Duration
7239 }
7240
7241 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0), time.Hour}
7242 errs = validate.Struct(timeDurationOmitemptyTest)
7243 Equal(t, errs, nil)
7244
7245
7246
7247 type IntTest struct {
7248 Val1 int `validate:"required"`
7249 Val2 int `validate:"required,gtefield=Val1"`
7250 }
7251
7252 intTest := &IntTest{
7253 Val1: 1,
7254 Val2: 5,
7255 }
7256
7257 errs = validate.Struct(intTest)
7258 Equal(t, errs, nil)
7259
7260 intTest = &IntTest{
7261 Val1: 5,
7262 Val2: 1,
7263 }
7264
7265 errs = validate.Struct(intTest)
7266 NotEqual(t, errs, nil)
7267 AssertError(t, errs, "IntTest.Val2", "IntTest.Val2", "Val2", "Val2", "gtefield")
7268
7269 errs = validate.VarWithValue(int(5), int(1), "gtefield")
7270 Equal(t, errs, nil)
7271
7272 errs = validate.VarWithValue(int(1), int(5), "gtefield")
7273 NotEqual(t, errs, nil)
7274 AssertError(t, errs, "", "", "", "", "gtefield")
7275
7276 type UIntTest struct {
7277 Val1 uint `validate:"required"`
7278 Val2 uint `validate:"required,gtefield=Val1"`
7279 }
7280
7281 uIntTest := &UIntTest{
7282 Val1: 1,
7283 Val2: 5,
7284 }
7285
7286 errs = validate.Struct(uIntTest)
7287 Equal(t, errs, nil)
7288
7289 uIntTest = &UIntTest{
7290 Val1: 5,
7291 Val2: 1,
7292 }
7293
7294 errs = validate.Struct(uIntTest)
7295 NotEqual(t, errs, nil)
7296 AssertError(t, errs, "UIntTest.Val2", "UIntTest.Val2", "Val2", "Val2", "gtefield")
7297
7298 errs = validate.VarWithValue(uint(5), uint(1), "gtefield")
7299 Equal(t, errs, nil)
7300
7301 errs = validate.VarWithValue(uint(1), uint(5), "gtefield")
7302 NotEqual(t, errs, nil)
7303 AssertError(t, errs, "", "", "", "", "gtefield")
7304
7305 type FloatTest struct {
7306 Val1 float64 `validate:"required"`
7307 Val2 float64 `validate:"required,gtefield=Val1"`
7308 }
7309
7310 floatTest := &FloatTest{
7311 Val1: 1,
7312 Val2: 5,
7313 }
7314
7315 errs = validate.Struct(floatTest)
7316 Equal(t, errs, nil)
7317
7318 floatTest = &FloatTest{
7319 Val1: 5,
7320 Val2: 1,
7321 }
7322
7323 errs = validate.Struct(floatTest)
7324 NotEqual(t, errs, nil)
7325 AssertError(t, errs, "FloatTest.Val2", "FloatTest.Val2", "Val2", "Val2", "gtefield")
7326
7327 errs = validate.VarWithValue(float32(5), float32(1), "gtefield")
7328 Equal(t, errs, nil)
7329
7330 errs = validate.VarWithValue(float32(1), float32(5), "gtefield")
7331 NotEqual(t, errs, nil)
7332 AssertError(t, errs, "", "", "", "", "gtefield")
7333
7334 errs = validate.VarWithValue(nil, 1, "gtefield")
7335 NotEqual(t, errs, nil)
7336 AssertError(t, errs, "", "", "", "", "gtefield")
7337
7338 errs = validate.VarWithValue(5, "T", "gtefield")
7339 NotEqual(t, errs, nil)
7340 AssertError(t, errs, "", "", "", "", "gtefield")
7341
7342 errs = validate.VarWithValue(5, start, "gtefield")
7343 NotEqual(t, errs, nil)
7344 AssertError(t, errs, "", "", "", "", "gtefield")
7345
7346 type TimeTest2 struct {
7347 Start *time.Time `validate:"required"`
7348 End *time.Time `validate:"required,gtefield=NonExistantField"`
7349 }
7350
7351 timeTest2 := &TimeTest2{
7352 Start: &start,
7353 End: &end,
7354 }
7355
7356 errs = validate.Struct(timeTest2)
7357 NotEqual(t, errs, nil)
7358 AssertError(t, errs, "TimeTest2.End", "TimeTest2.End", "End", "End", "gtefield")
7359 }
7360
7361 func TestValidateByTagAndValue(t *testing.T) {
7362 validate := New()
7363
7364 val := "test"
7365 field := "test"
7366 errs := validate.VarWithValue(val, field, "required")
7367 Equal(t, errs, nil)
7368
7369 fn := func(fl FieldLevel) bool {
7370 return fl.Parent().String() == fl.Field().String()
7371 }
7372
7373 errs = validate.RegisterValidation("isequaltestfunc", fn)
7374 Equal(t, errs, nil)
7375
7376 errs = validate.VarWithValue(val, field, "isequaltestfunc")
7377 Equal(t, errs, nil)
7378
7379 val = "unequal"
7380
7381 errs = validate.VarWithValue(val, field, "isequaltestfunc")
7382 NotEqual(t, errs, nil)
7383 AssertError(t, errs, "", "", "", "", "isequaltestfunc")
7384 }
7385
7386 func TestAddFunctions(t *testing.T) {
7387 fn := func(fl FieldLevel) bool {
7388 return true
7389 }
7390
7391 fnCtx := func(ctx context.Context, fl FieldLevel) bool {
7392 return true
7393 }
7394
7395 validate := New()
7396
7397 errs := validate.RegisterValidation("new", fn)
7398 Equal(t, errs, nil)
7399
7400 errs = validate.RegisterValidation("", fn)
7401 NotEqual(t, errs, nil)
7402
7403 errs = validate.RegisterValidation("new", nil)
7404 NotEqual(t, errs, nil)
7405
7406 errs = validate.RegisterValidation("new", fn)
7407 Equal(t, errs, nil)
7408
7409 errs = validate.RegisterValidationCtx("new", fnCtx)
7410 Equal(t, errs, nil)
7411
7412 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")
7413 }
7414
7415 func TestChangeTag(t *testing.T) {
7416 validate := New()
7417 validate.SetTagName("val")
7418
7419 type Test struct {
7420 Name string `val:"len=4"`
7421 }
7422 s := &Test{
7423 Name: "TEST",
7424 }
7425
7426 errs := validate.Struct(s)
7427 Equal(t, errs, nil)
7428
7429 s.Name = ""
7430
7431 errs = validate.Struct(s)
7432 NotEqual(t, errs, nil)
7433 AssertError(t, errs, "Test.Name", "Test.Name", "Name", "Name", "len")
7434 }
7435
7436 func TestUnexposedStruct(t *testing.T) {
7437 validate := New()
7438
7439 type Test struct {
7440 Name string
7441 unexposed struct {
7442 A string `validate:"required"`
7443 }
7444 }
7445
7446 s := &Test{
7447 Name: "TEST",
7448 }
7449 Equal(t, s.unexposed.A, "")
7450
7451 errs := validate.Struct(s)
7452 Equal(t, errs, nil)
7453 }
7454
7455 func TestBadParams(t *testing.T) {
7456 validate := New()
7457 i := 1
7458 errs := validate.Var(i, "-")
7459 Equal(t, errs, nil)
7460
7461 PanicMatches(t, func() { _ = validate.Var(i, "len=a") }, "strconv.ParseInt: parsing \"a\": invalid syntax")
7462 PanicMatches(t, func() { _ = validate.Var(i, "len=a") }, "strconv.ParseInt: parsing \"a\": invalid syntax")
7463
7464 var ui uint = 1
7465 PanicMatches(t, func() { _ = validate.Var(ui, "len=a") }, "strconv.ParseUint: parsing \"a\": invalid syntax")
7466
7467 f := 1.23
7468 PanicMatches(t, func() { _ = validate.Var(f, "len=a") }, "strconv.ParseFloat: parsing \"a\": invalid syntax")
7469 }
7470
7471 func TestLength(t *testing.T) {
7472 validate := New()
7473 i := true
7474 PanicMatches(t, func() { _ = validate.Var(i, "len") }, "Bad field type bool")
7475 }
7476
7477 func TestIsGt(t *testing.T) {
7478 var errs error
7479 validate := New()
7480
7481 myMap := map[string]string{}
7482 errs = validate.Var(myMap, "gt=0")
7483 NotEqual(t, errs, nil)
7484
7485 f := 1.23
7486 errs = validate.Var(f, "gt=5")
7487 NotEqual(t, errs, nil)
7488 AssertError(t, errs, "", "", "", "", "gt")
7489
7490 var ui uint = 5
7491 errs = validate.Var(ui, "gt=10")
7492 NotEqual(t, errs, nil)
7493 AssertError(t, errs, "", "", "", "", "gt")
7494
7495 i := true
7496 PanicMatches(t, func() { _ = validate.Var(i, "gt") }, "Bad field type bool")
7497
7498 tm := time.Now().UTC()
7499 tm = tm.Add(time.Hour * 24)
7500
7501 errs = validate.Var(tm, "gt")
7502 Equal(t, errs, nil)
7503
7504 t2 := time.Now().UTC().Add(-time.Hour)
7505
7506 errs = validate.Var(t2, "gt")
7507 NotEqual(t, errs, nil)
7508 AssertError(t, errs, "", "", "", "", "gt")
7509
7510 type Test struct {
7511 Now *time.Time `validate:"gt"`
7512 }
7513 s := &Test{
7514 Now: &tm,
7515 }
7516
7517 errs = validate.Struct(s)
7518 Equal(t, errs, nil)
7519
7520 s = &Test{
7521 Now: &t2,
7522 }
7523
7524 errs = validate.Struct(s)
7525 NotEqual(t, errs, nil)
7526 AssertError(t, errs, "Test.Now", "Test.Now", "Now", "Now", "gt")
7527
7528
7529
7530
7531
7532 errs = validate.Var(time.Hour, "gt=59m")
7533 Equal(t, errs, nil)
7534
7535 errs = validate.Var(time.Hour-time.Minute, "gt=59m")
7536 NotEqual(t, errs, nil)
7537 AssertError(t, errs, "", "", "", "", "gt")
7538
7539 errs = validate.Var(time.Hour-2*time.Minute, "gt=59m")
7540 NotEqual(t, errs, nil)
7541 AssertError(t, errs, "", "", "", "", "gt")
7542
7543 errs = validate.Var(time.Duration(0), "omitempty,gt=59m")
7544 Equal(t, errs, nil)
7545
7546
7547
7548 type TimeDurationTest struct {
7549 Duration time.Duration `validate:"gt=59m"`
7550 }
7551 var timeDurationTest *TimeDurationTest
7552
7553 timeDurationTest = &TimeDurationTest{time.Hour}
7554 errs = validate.Struct(timeDurationTest)
7555 Equal(t, errs, nil)
7556
7557 timeDurationTest = &TimeDurationTest{time.Hour - time.Minute}
7558 errs = validate.Struct(timeDurationTest)
7559 NotEqual(t, errs, nil)
7560 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "gt")
7561
7562 timeDurationTest = &TimeDurationTest{time.Hour - 2*time.Minute}
7563 errs = validate.Struct(timeDurationTest)
7564 NotEqual(t, errs, nil)
7565 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "gt")
7566
7567 type TimeDurationOmitemptyTest struct {
7568 Duration time.Duration `validate:"omitempty,gt=59m"`
7569 }
7570
7571 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
7572 errs = validate.Struct(timeDurationOmitemptyTest)
7573 Equal(t, errs, nil)
7574 }
7575
7576 func TestIsGte(t *testing.T) {
7577 var errs error
7578 validate := New()
7579
7580 i := true
7581 PanicMatches(t, func() { _ = validate.Var(i, "gte") }, "Bad field type bool")
7582
7583 t1 := time.Now().UTC()
7584 t1 = t1.Add(time.Hour * 24)
7585
7586 errs = validate.Var(t1, "gte")
7587 Equal(t, errs, nil)
7588
7589 t2 := time.Now().UTC().Add(-time.Hour)
7590
7591 errs = validate.Var(t2, "gte")
7592 NotEqual(t, errs, nil)
7593 AssertError(t, errs, "", "", "", "", "gte")
7594
7595 type Test struct {
7596 Now *time.Time `validate:"gte"`
7597 }
7598 s := &Test{
7599 Now: &t1,
7600 }
7601
7602 errs = validate.Struct(s)
7603 Equal(t, errs, nil)
7604
7605 s = &Test{
7606 Now: &t2,
7607 }
7608
7609 errs = validate.Struct(s)
7610 NotEqual(t, errs, nil)
7611 AssertError(t, errs, "Test.Now", "Test.Now", "Now", "Now", "gte")
7612
7613
7614
7615
7616
7617 errs = validate.Var(time.Hour, "gte=59m")
7618 Equal(t, errs, nil)
7619
7620 errs = validate.Var(time.Hour-time.Minute, "gte=59m")
7621 Equal(t, errs, nil)
7622
7623 errs = validate.Var(time.Hour-2*time.Minute, "gte=59m")
7624 NotEqual(t, errs, nil)
7625 AssertError(t, errs, "", "", "", "", "gte")
7626
7627 errs = validate.Var(time.Duration(0), "omitempty,gte=59m")
7628 Equal(t, errs, nil)
7629
7630
7631
7632 type TimeDurationTest struct {
7633 Duration time.Duration `validate:"gte=59m"`
7634 }
7635 var timeDurationTest *TimeDurationTest
7636
7637 timeDurationTest = &TimeDurationTest{time.Hour}
7638 errs = validate.Struct(timeDurationTest)
7639 Equal(t, errs, nil)
7640
7641 timeDurationTest = &TimeDurationTest{time.Hour - time.Minute}
7642 errs = validate.Struct(timeDurationTest)
7643 Equal(t, errs, nil)
7644
7645 timeDurationTest = &TimeDurationTest{time.Hour - 2*time.Minute}
7646 errs = validate.Struct(timeDurationTest)
7647 NotEqual(t, errs, nil)
7648 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "gte")
7649
7650 type TimeDurationOmitemptyTest struct {
7651 Duration time.Duration `validate:"omitempty,gte=59m"`
7652 }
7653
7654 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
7655 errs = validate.Struct(timeDurationOmitemptyTest)
7656 Equal(t, errs, nil)
7657 }
7658
7659 func TestMinValidation(t *testing.T) {
7660 var errs error
7661 validate := New()
7662
7663
7664
7665
7666
7667 errs = validate.Var(time.Hour, "min=59m")
7668 Equal(t, errs, nil)
7669
7670 errs = validate.Var(time.Hour-time.Minute, "min=59m")
7671 Equal(t, errs, nil)
7672
7673 errs = validate.Var(time.Hour-2*time.Minute, "min=59m")
7674 NotEqual(t, errs, nil)
7675 AssertError(t, errs, "", "", "", "", "min")
7676
7677 errs = validate.Var(time.Duration(0), "omitempty,min=59m")
7678 Equal(t, errs, nil)
7679
7680
7681
7682 type TimeDurationTest struct {
7683 Duration time.Duration `validate:"min=59m"`
7684 }
7685 var timeDurationTest *TimeDurationTest
7686
7687 timeDurationTest = &TimeDurationTest{time.Hour}
7688 errs = validate.Struct(timeDurationTest)
7689 Equal(t, errs, nil)
7690
7691 timeDurationTest = &TimeDurationTest{time.Hour - time.Minute}
7692 errs = validate.Struct(timeDurationTest)
7693 Equal(t, errs, nil)
7694
7695 timeDurationTest = &TimeDurationTest{time.Hour - 2*time.Minute}
7696 errs = validate.Struct(timeDurationTest)
7697 NotEqual(t, errs, nil)
7698 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "min")
7699
7700 type TimeDurationOmitemptyTest struct {
7701 Duration time.Duration `validate:"omitempty,min=59m"`
7702 }
7703
7704 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
7705 errs = validate.Struct(timeDurationOmitemptyTest)
7706 Equal(t, errs, nil)
7707 }
7708
7709 func TestMaxValidation(t *testing.T) {
7710 var errs error
7711 validate := New()
7712
7713
7714
7715
7716
7717 errs = validate.Var(time.Hour, "max=1h1m")
7718 Equal(t, errs, nil)
7719
7720 errs = validate.Var(time.Hour+time.Minute, "max=1h1m")
7721 Equal(t, errs, nil)
7722
7723 errs = validate.Var(time.Hour+2*time.Minute, "max=1h1m")
7724 NotEqual(t, errs, nil)
7725 AssertError(t, errs, "", "", "", "", "max")
7726
7727 errs = validate.Var(time.Duration(0), "omitempty,max=-1s")
7728 Equal(t, errs, nil)
7729
7730
7731
7732 type TimeDurationTest struct {
7733 Duration time.Duration `validate:"max=1h1m"`
7734 }
7735 var timeDurationTest *TimeDurationTest
7736
7737 timeDurationTest = &TimeDurationTest{time.Hour}
7738 errs = validate.Struct(timeDurationTest)
7739 Equal(t, errs, nil)
7740
7741 timeDurationTest = &TimeDurationTest{time.Hour + time.Minute}
7742 errs = validate.Struct(timeDurationTest)
7743 Equal(t, errs, nil)
7744
7745 timeDurationTest = &TimeDurationTest{time.Hour + 2*time.Minute}
7746 errs = validate.Struct(timeDurationTest)
7747 NotEqual(t, errs, nil)
7748 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "max")
7749
7750 type TimeDurationOmitemptyTest struct {
7751 Duration time.Duration `validate:"omitempty,max=-1s"`
7752 }
7753
7754 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
7755 errs = validate.Struct(timeDurationOmitemptyTest)
7756 Equal(t, errs, nil)
7757 }
7758
7759 func TestMinMaxValidation(t *testing.T) {
7760 var errs error
7761 validate := New()
7762
7763
7764
7765
7766
7767 errs = validate.Var(time.Hour, "min=59m,max=1h1m")
7768 Equal(t, errs, nil)
7769
7770 errs = validate.Var(time.Hour-time.Minute, "min=59m,max=1h1m")
7771 Equal(t, errs, nil)
7772
7773 errs = validate.Var(time.Hour+time.Minute, "min=59m,max=1h1m")
7774 Equal(t, errs, nil)
7775
7776 errs = validate.Var(time.Hour-2*time.Minute, "min=59m,max=1h1m")
7777 NotEqual(t, errs, nil)
7778 AssertError(t, errs, "", "", "", "", "min")
7779
7780 errs = validate.Var(time.Hour+2*time.Minute, "min=59m,max=1h1m")
7781 NotEqual(t, errs, nil)
7782 AssertError(t, errs, "", "", "", "", "max")
7783
7784 errs = validate.Var(time.Duration(0), "omitempty,min=59m,max=1h1m")
7785 Equal(t, errs, nil)
7786
7787
7788
7789 type TimeDurationTest struct {
7790 Duration time.Duration `validate:"min=59m,max=1h1m"`
7791 }
7792 var timeDurationTest *TimeDurationTest
7793
7794 timeDurationTest = &TimeDurationTest{time.Hour}
7795 errs = validate.Struct(timeDurationTest)
7796 Equal(t, errs, nil)
7797
7798 timeDurationTest = &TimeDurationTest{time.Hour - time.Minute}
7799 errs = validate.Struct(timeDurationTest)
7800 Equal(t, errs, nil)
7801
7802 timeDurationTest = &TimeDurationTest{time.Hour + time.Minute}
7803 errs = validate.Struct(timeDurationTest)
7804 Equal(t, errs, nil)
7805
7806 timeDurationTest = &TimeDurationTest{time.Hour - 2*time.Minute}
7807 errs = validate.Struct(timeDurationTest)
7808 NotEqual(t, errs, nil)
7809 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "min")
7810
7811 timeDurationTest = &TimeDurationTest{time.Hour + 2*time.Minute}
7812 errs = validate.Struct(timeDurationTest)
7813 NotEqual(t, errs, nil)
7814 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "max")
7815
7816 type TimeDurationOmitemptyTest struct {
7817 Duration time.Duration `validate:"omitempty,min=59m,max=1h1m"`
7818 }
7819
7820 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
7821 errs = validate.Struct(timeDurationOmitemptyTest)
7822 Equal(t, errs, nil)
7823 }
7824
7825 func TestLenValidation(t *testing.T) {
7826 var errs error
7827 validate := New()
7828
7829
7830
7831
7832
7833 errs = validate.Var(time.Hour, "len=1h")
7834 Equal(t, errs, nil)
7835
7836 errs = validate.Var(time.Hour-time.Minute, "len=1h")
7837 NotEqual(t, errs, nil)
7838 AssertError(t, errs, "", "", "", "", "len")
7839
7840 errs = validate.Var(time.Hour+time.Minute, "len=1h")
7841 NotEqual(t, errs, nil)
7842 AssertError(t, errs, "", "", "", "", "len")
7843
7844 errs = validate.Var(time.Duration(0), "omitempty,len=1h")
7845 Equal(t, errs, nil)
7846
7847
7848
7849 type TimeDurationTest struct {
7850 Duration time.Duration `validate:"len=1h"`
7851 }
7852 var timeDurationTest *TimeDurationTest
7853
7854 timeDurationTest = &TimeDurationTest{time.Hour}
7855 errs = validate.Struct(timeDurationTest)
7856 Equal(t, errs, nil)
7857
7858 timeDurationTest = &TimeDurationTest{time.Hour - time.Minute}
7859 errs = validate.Struct(timeDurationTest)
7860 NotEqual(t, errs, nil)
7861 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "len")
7862
7863 timeDurationTest = &TimeDurationTest{time.Hour + time.Minute}
7864 errs = validate.Struct(timeDurationTest)
7865 NotEqual(t, errs, nil)
7866 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "len")
7867
7868 type TimeDurationOmitemptyTest struct {
7869 Duration time.Duration `validate:"omitempty,len=1h"`
7870 }
7871
7872 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
7873 errs = validate.Struct(timeDurationOmitemptyTest)
7874 Equal(t, errs, nil)
7875 }
7876
7877 func TestIsLt(t *testing.T) {
7878 var errs error
7879 validate := New()
7880
7881 myMap := map[string]string{}
7882 errs = validate.Var(myMap, "lt=0")
7883 NotEqual(t, errs, nil)
7884 AssertError(t, errs, "", "", "", "", "lt")
7885
7886 f := 1.23
7887 errs = validate.Var(f, "lt=0")
7888 NotEqual(t, errs, nil)
7889 AssertError(t, errs, "", "", "", "", "lt")
7890
7891 var ui uint = 5
7892 errs = validate.Var(ui, "lt=0")
7893 NotEqual(t, errs, nil)
7894 AssertError(t, errs, "", "", "", "", "lt")
7895
7896 i := true
7897 PanicMatches(t, func() { _ = validate.Var(i, "lt") }, "Bad field type bool")
7898
7899 t1 := time.Now().UTC().Add(-time.Hour)
7900
7901 errs = validate.Var(t1, "lt")
7902 Equal(t, errs, nil)
7903
7904 t2 := time.Now().UTC()
7905 t2 = t2.Add(time.Hour * 24)
7906
7907 errs = validate.Var(t2, "lt")
7908 NotEqual(t, errs, nil)
7909 AssertError(t, errs, "", "", "", "", "lt")
7910
7911 type Test struct {
7912 Now *time.Time `validate:"lt"`
7913 }
7914
7915 s := &Test{
7916 Now: &t1,
7917 }
7918
7919 errs = validate.Struct(s)
7920 Equal(t, errs, nil)
7921
7922 s = &Test{
7923 Now: &t2,
7924 }
7925
7926 errs = validate.Struct(s)
7927 NotEqual(t, errs, nil)
7928 AssertError(t, errs, "Test.Now", "Test.Now", "Now", "Now", "lt")
7929
7930
7931
7932
7933
7934 errs = validate.Var(time.Hour, "lt=1h1m")
7935 Equal(t, errs, nil)
7936
7937 errs = validate.Var(time.Hour+time.Minute, "lt=1h1m")
7938 NotEqual(t, errs, nil)
7939 AssertError(t, errs, "", "", "", "", "lt")
7940
7941 errs = validate.Var(time.Hour+2*time.Minute, "lt=1h1m")
7942 NotEqual(t, errs, nil)
7943 AssertError(t, errs, "", "", "", "", "lt")
7944
7945 errs = validate.Var(time.Duration(0), "omitempty,lt=0")
7946 Equal(t, errs, nil)
7947
7948
7949
7950 type TimeDurationTest struct {
7951 Duration time.Duration `validate:"lt=1h1m"`
7952 }
7953 var timeDurationTest *TimeDurationTest
7954
7955 timeDurationTest = &TimeDurationTest{time.Hour}
7956 errs = validate.Struct(timeDurationTest)
7957 Equal(t, errs, nil)
7958
7959 timeDurationTest = &TimeDurationTest{time.Hour + time.Minute}
7960 errs = validate.Struct(timeDurationTest)
7961 NotEqual(t, errs, nil)
7962 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "lt")
7963
7964 timeDurationTest = &TimeDurationTest{time.Hour + 2*time.Minute}
7965 errs = validate.Struct(timeDurationTest)
7966 NotEqual(t, errs, nil)
7967 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "lt")
7968
7969 type TimeDurationOmitemptyTest struct {
7970 Duration time.Duration `validate:"omitempty,lt=0"`
7971 }
7972
7973 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
7974 errs = validate.Struct(timeDurationOmitemptyTest)
7975 Equal(t, errs, nil)
7976 }
7977
7978 func TestIsLte(t *testing.T) {
7979 var errs error
7980 validate := New()
7981
7982 i := true
7983 PanicMatches(t, func() { _ = validate.Var(i, "lte") }, "Bad field type bool")
7984
7985 t1 := time.Now().UTC().Add(-time.Hour)
7986
7987 errs = validate.Var(t1, "lte")
7988 Equal(t, errs, nil)
7989
7990 t2 := time.Now().UTC()
7991 t2 = t2.Add(time.Hour * 24)
7992
7993 errs = validate.Var(t2, "lte")
7994 NotEqual(t, errs, nil)
7995 AssertError(t, errs, "", "", "", "", "lte")
7996
7997 type Test struct {
7998 Now *time.Time `validate:"lte"`
7999 }
8000
8001 s := &Test{
8002 Now: &t1,
8003 }
8004
8005 errs = validate.Struct(s)
8006 Equal(t, errs, nil)
8007
8008 s = &Test{
8009 Now: &t2,
8010 }
8011
8012 errs = validate.Struct(s)
8013 NotEqual(t, errs, nil)
8014
8015
8016
8017
8018
8019 errs = validate.Var(time.Hour, "lte=1h1m")
8020 Equal(t, errs, nil)
8021
8022 errs = validate.Var(time.Hour+time.Minute, "lte=1h1m")
8023 Equal(t, errs, nil)
8024
8025 errs = validate.Var(time.Hour+2*time.Minute, "lte=1h1m")
8026 NotEqual(t, errs, nil)
8027 AssertError(t, errs, "", "", "", "", "lte")
8028
8029 errs = validate.Var(time.Duration(0), "omitempty,lte=-1s")
8030 Equal(t, errs, nil)
8031
8032
8033
8034 type TimeDurationTest struct {
8035 Duration time.Duration `validate:"lte=1h1m"`
8036 }
8037 var timeDurationTest *TimeDurationTest
8038
8039 timeDurationTest = &TimeDurationTest{time.Hour}
8040 errs = validate.Struct(timeDurationTest)
8041 Equal(t, errs, nil)
8042
8043 timeDurationTest = &TimeDurationTest{time.Hour + time.Minute}
8044 errs = validate.Struct(timeDurationTest)
8045 Equal(t, errs, nil)
8046
8047 timeDurationTest = &TimeDurationTest{time.Hour + 2*time.Minute}
8048 errs = validate.Struct(timeDurationTest)
8049 NotEqual(t, errs, nil)
8050 AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "lte")
8051
8052 type TimeDurationOmitemptyTest struct {
8053 Duration time.Duration `validate:"omitempty,lte=-1s"`
8054 }
8055
8056 timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
8057 errs = validate.Struct(timeDurationOmitemptyTest)
8058 Equal(t, errs, nil)
8059 }
8060
8061 func TestUrnRFC2141(t *testing.T) {
8062 tests := []struct {
8063 param string
8064 expected bool
8065 }{
8066 {"urn:a:b", true},
8067 {"urn:a::", true},
8068 {"urn:a:-", true},
8069 {"URN:simple:simple", true},
8070 {"urn:urna:simple", true},
8071 {"urn:burnout:nss", true},
8072 {"urn:burn:nss", true},
8073 {"urn:urnurnurn:x", true},
8074 {"urn:abcdefghilmnopqrstuvzabcdefghilm:x", true},
8075 {"URN:123:x", true},
8076 {"URN:abcd-:x", true},
8077 {"URN:abcd-abcd:x", true},
8078 {"urn:urnx:urn", true},
8079 {"urn:ciao:a:b:c", true},
8080 {"urn:aaa:x:y:", true},
8081 {"urn:ciao:-", true},
8082 {"urn:colon:::::nss", true},
8083 {"urn:ciao:@!=%2C(xyz)+a,b.*@g=$_'", true},
8084 {"URN:hexes:%25", true},
8085 {"URN:x:abc%1Dz%2F%3az", true},
8086 {"URN:foo:a123,456", true},
8087 {"urn:foo:a123,456", true},
8088 {"urn:FOO:a123,456", true},
8089 {"urn:foo:A123,456", true},
8090 {"urn:foo:a123%2C456", true},
8091 {"URN:FOO:a123%2c456", true},
8092 {"URN:FOO:ABC%FFabc123%2c456", true},
8093 {"URN:FOO:ABC%FFabc123%2C456%9A", true},
8094 {"urn:ietf:params:scim:schemas:core:2.0:User", true},
8095 {"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:meta.lastModified", true},
8096 {"URN:-xxx:x", false},
8097 {"urn::colon:nss", false},
8098 {"urn:abcdefghilmnopqrstuvzabcdefghilmn:specificstring", false},
8099 {"URN:a!?:x", false},
8100 {"URN:#,:x", false},
8101 {"urn:urn:NSS", false},
8102 {"urn:URN:NSS", false},
8103 {"urn:white space:NSS", false},
8104 {"urn:concat:no spaces", false},
8105 {"urn:a:%", false},
8106 {"urn:", false},
8107 }
8108
8109 tag := "urn_rfc2141"
8110
8111 validate := New()
8112
8113 for i, test := range tests {
8114
8115 errs := validate.Var(test.param, tag)
8116
8117 if test.expected {
8118 if !IsEqual(errs, nil) {
8119 t.Fatalf("Index: %d URN failed Error: %s", i, errs)
8120 }
8121 } else {
8122 if IsEqual(errs, nil) {
8123 t.Fatalf("Index: %d URN failed Error: %s", i, errs)
8124 } else {
8125 val := getError(errs, "", "")
8126 if val.Tag() != tag {
8127 t.Fatalf("Index: %d URN failed Error: %s", i, errs)
8128 }
8129 }
8130 }
8131 }
8132
8133 i := 1
8134 PanicMatches(t, func() { _ = validate.Var(i, tag) }, "Bad field type int")
8135 }
8136
8137 func TestUrl(t *testing.T) {
8138 tests := []struct {
8139 param string
8140 expected bool
8141 }{
8142 {"http://foo.bar#com", true},
8143 {"http://foobar.com", true},
8144 {"https://foobar.com", true},
8145 {"foobar.com", false},
8146 {"http://foobar.coffee/", true},
8147 {"http://foobar.中文网/", true},
8148 {"http://foobar.org/", true},
8149 {"http://foobar.org:8080/", true},
8150 {"ftp://foobar.ru/", true},
8151 {"http://user:pass@www.foobar.com/", true},
8152 {"http://127.0.0.1/", true},
8153 {"http://duckduckgo.com/?q=%2F", true},
8154 {"http://localhost:3000/", true},
8155 {"http://foobar.com/?foo=bar#baz=qux", true},
8156 {"http://foobar.com?foo=bar", true},
8157 {"http://www.xn--froschgrn-x9a.net/", true},
8158 {"", false},
8159 {"xyz://foobar.com", true},
8160 {"invalid.", false},
8161 {".com", false},
8162 {"rtmp://foobar.com", true},
8163 {"http://www.foo_bar.com/", true},
8164 {"http://localhost:3000/", true},
8165 {"http://foobar.com/#baz", true},
8166 {"http://foobar.com#baz=qux", true},
8167 {"http://foobar.com/t$-_.+!*\\'(),", true},
8168 {"http://www.foobar.com/~foobar", true},
8169 {"http://www.-foobar.com/", true},
8170 {"http://www.foo---bar.com/", true},
8171 {"mailto:someone@example.com", true},
8172 {"irc://irc.server.org/channel", true},
8173 {"irc://#channel@network", true},
8174 {"/abs/test/dir", false},
8175 {"./rel/test/dir", false},
8176 {"irc:", false},
8177 {"http://", false},
8178 {"file://path/to/file.txt", true},
8179 {"file:///c:/Windows/file.txt", true},
8180 {"file://localhost/path/to/file.txt", true},
8181 {"file://localhost/c:/WINDOWS/file.txt", true},
8182 {"file://", true},
8183 {"file:////remotehost/path/file.txt", true},
8184 }
8185
8186 validate := New()
8187
8188 for i, test := range tests {
8189
8190 errs := validate.Var(test.param, "url")
8191
8192 if test.expected {
8193 if !IsEqual(errs, nil) {
8194 t.Fatalf("Index: %d URL failed Error: %s", i, errs)
8195 }
8196 } else {
8197 if IsEqual(errs, nil) {
8198 t.Fatalf("Index: %d URL failed Error: %s", i, errs)
8199 } else {
8200 val := getError(errs, "", "")
8201 if val.Tag() != "url" {
8202 t.Fatalf("Index: %d URL failed Error: %s", i, errs)
8203 }
8204 }
8205 }
8206 }
8207
8208 i := 1
8209 PanicMatches(t, func() { _ = validate.Var(i, "url") }, "Bad field type int")
8210 }
8211
8212 func TestHttpUrl(t *testing.T) {
8213 tests := []struct {
8214 param string
8215 expected bool
8216 }{
8217 {"http://foo.bar#com", true},
8218 {"http://foobar.com", true},
8219 {"HTTP://foobar.com", true},
8220 {"https://foobar.com", true},
8221 {"foobar.com", false},
8222 {"http://foobar.coffee/", true},
8223 {"http://foobar.中文网/", true},
8224 {"http://foobar.org/", true},
8225 {"http://foobar.org:8080/", true},
8226 {"ftp://foobar.ru/", false},
8227 {"file:///etc/passwd", false},
8228 {"file://C:/windows/win.ini", false},
8229 {"http://user:pass@www.foobar.com/", true},
8230 {"http://127.0.0.1/", true},
8231 {"http://duckduckgo.com/?q=%2F", true},
8232 {"http://localhost:3000/", true},
8233 {"http://foobar.com/?foo=bar#baz=qux", true},
8234 {"http://foobar.com?foo=bar", true},
8235 {"http://www.xn--froschgrn-x9a.net/", true},
8236 {"", false},
8237 {"a://b", false},
8238 {"xyz://foobar.com", false},
8239 {"invalid.", false},
8240 {".com", false},
8241 {"rtmp://foobar.com", false},
8242 {"http://www.foo_bar.com/", true},
8243 {"http://localhost:3000/", true},
8244 {"http://foobar.com/#baz", true},
8245 {"http://foobar.com#baz=qux", true},
8246 {"http://foobar.com/t$-_.+!*\\'(),", true},
8247 {"http://www.foobar.com/~foobar", true},
8248 {"http://www.-foobar.com/", true},
8249 {"http://www.foo---bar.com/", true},
8250 {"mailto:someone@example.com", false},
8251 {"irc://irc.server.org/channel", false},
8252 {"irc://#channel@network", false},
8253 {"/abs/test/dir", false},
8254 {"./rel/test/dir", false},
8255 {"http:", false},
8256 {"http://", false},
8257 {"http://#invalid", false},
8258 {"https://1.1.1.1", true},
8259 }
8260
8261 validate := New()
8262
8263 for i, test := range tests {
8264
8265 errs := validate.Var(test.param, "http_url")
8266
8267 if test.expected {
8268 if !IsEqual(errs, nil) {
8269 t.Fatalf("Index: %d HTTP URL failed Error: %s", i, errs)
8270 }
8271 } else {
8272 if IsEqual(errs, nil) {
8273 t.Fatalf("Index: %d HTTP URL failed Error: %s", i, errs)
8274 } else {
8275 val := getError(errs, "", "")
8276 if val.Tag() != "http_url" {
8277 t.Fatalf("Index: %d HTTP URL failed Error: %s", i, errs)
8278 }
8279 }
8280 }
8281 }
8282
8283 i := 1
8284 PanicMatches(t, func() { _ = validate.Var(i, "http_url") }, "Bad field type int")
8285 }
8286
8287 func TestUri(t *testing.T) {
8288 tests := []struct {
8289 param string
8290 expected bool
8291 }{
8292 {"http://foo.bar#com", true},
8293 {"http://foobar.com", true},
8294 {"https://foobar.com", true},
8295 {"foobar.com", false},
8296 {"http://foobar.coffee/", true},
8297 {"http://foobar.中文网/", true},
8298 {"http://foobar.org/", true},
8299 {"http://foobar.org:8080/", true},
8300 {"ftp://foobar.ru/", true},
8301 {"http://user:pass@www.foobar.com/", true},
8302 {"http://127.0.0.1/", true},
8303 {"http://duckduckgo.com/?q=%2F", true},
8304 {"http://localhost:3000/", true},
8305 {"http://foobar.com/?foo=bar#baz=qux", true},
8306 {"http://foobar.com?foo=bar", true},
8307 {"http://www.xn--froschgrn-x9a.net/", true},
8308 {"", false},
8309 {"xyz://foobar.com", true},
8310 {"invalid.", false},
8311 {".com", false},
8312 {"rtmp://foobar.com", true},
8313 {"http://www.foo_bar.com/", true},
8314 {"http://localhost:3000/", true},
8315 {"http://foobar.com#baz=qux", true},
8316 {"http://foobar.com/t$-_.+!*\\'(),", true},
8317 {"http://www.foobar.com/~foobar", true},
8318 {"http://www.-foobar.com/", true},
8319 {"http://www.foo---bar.com/", true},
8320 {"mailto:someone@example.com", true},
8321 {"irc://irc.server.org/channel", true},
8322 {"irc://#channel@network", true},
8323 {"/abs/test/dir", true},
8324 {"./rel/test/dir", false},
8325 }
8326
8327 validate := New()
8328
8329 for i, test := range tests {
8330
8331 errs := validate.Var(test.param, "uri")
8332
8333 if test.expected {
8334 if !IsEqual(errs, nil) {
8335 t.Fatalf("Index: %d URI failed Error: %s", i, errs)
8336 }
8337 } else {
8338 if IsEqual(errs, nil) {
8339 t.Fatalf("Index: %d URI failed Error: %s", i, errs)
8340 } else {
8341 val := getError(errs, "", "")
8342 if val.Tag() != "uri" {
8343 t.Fatalf("Index: %d URI failed Error: %s", i, errs)
8344 }
8345 }
8346 }
8347 }
8348
8349 i := 1
8350 PanicMatches(t, func() { _ = validate.Var(i, "uri") }, "Bad field type int")
8351 }
8352
8353 func TestOrTag(t *testing.T) {
8354 validate := New()
8355
8356 s := "rgba(0,31,255,0.5)"
8357 errs := validate.Var(s, "rgb|rgba")
8358 Equal(t, errs, nil)
8359
8360 s = "rgba(0,31,255,0.5)"
8361 errs = validate.Var(s, "rgb|rgba|len=18")
8362 Equal(t, errs, nil)
8363
8364 s = "this ain't right"
8365 errs = validate.Var(s, "rgb|rgba")
8366 NotEqual(t, errs, nil)
8367 AssertError(t, errs, "", "", "", "", "rgb|rgba")
8368
8369 s = "this ain't right"
8370 errs = validate.Var(s, "rgb|rgba|len=10")
8371 NotEqual(t, errs, nil)
8372 AssertError(t, errs, "", "", "", "", "rgb|rgba|len=10")
8373
8374 s = "this is right"
8375 errs = validate.Var(s, "rgb|rgba|len=13")
8376 Equal(t, errs, nil)
8377
8378 s = ""
8379 errs = validate.Var(s, "omitempty,rgb|rgba")
8380 Equal(t, errs, nil)
8381
8382 s = "green"
8383 errs = validate.Var(s, "eq=|eq=blue,rgb|rgba")
8384 NotEqual(t, errs, nil)
8385 ve := errs.(ValidationErrors)
8386 Equal(t, len(ve), 1)
8387 Equal(t, ve[0].Tag(), "eq=|eq=blue")
8388
8389 s = "this is right, but a blank or isn't"
8390
8391 PanicMatches(t, func() { _ = validate.Var(s, "rgb||len=13") }, "Invalid validation tag on field ''")
8392 PanicMatches(t, func() { _ = validate.Var(s, "rgb|rgbaa|len=13") }, "Undefined validation function 'rgbaa' on field ''")
8393
8394 v2 := New()
8395 v2.RegisterTagNameFunc(func(fld reflect.StructField) string {
8396 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
8397
8398 if name == "-" {
8399 return ""
8400 }
8401
8402 return name
8403 })
8404
8405 type Colors struct {
8406 Fav string `validate:"rgb|rgba" json:"fc"`
8407 }
8408
8409 c := Colors{Fav: "this ain't right"}
8410
8411 err := v2.Struct(c)
8412 NotEqual(t, err, nil)
8413
8414 errs = err.(ValidationErrors)
8415 fe := getError(errs, "Colors.fc", "Colors.Fav")
8416 NotEqual(t, fe, nil)
8417 }
8418
8419 func TestHsla(t *testing.T) {
8420 validate := New()
8421
8422 s := "hsla(360,100%,100%,1)"
8423 errs := validate.Var(s, "hsla")
8424 Equal(t, errs, nil)
8425
8426 s = "hsla(360,100%,100%,0.5)"
8427 errs = validate.Var(s, "hsla")
8428 Equal(t, errs, nil)
8429
8430 s = "hsla(0,0%,0%, 0)"
8431 errs = validate.Var(s, "hsla")
8432 Equal(t, errs, nil)
8433
8434 s = "hsl(361,100%,50%,1)"
8435 errs = validate.Var(s, "hsla")
8436 NotEqual(t, errs, nil)
8437 AssertError(t, errs, "", "", "", "", "hsla")
8438
8439 s = "hsl(361,100%,50%)"
8440 errs = validate.Var(s, "hsla")
8441 NotEqual(t, errs, nil)
8442 AssertError(t, errs, "", "", "", "", "hsla")
8443
8444 s = "hsla(361,100%,50%)"
8445 errs = validate.Var(s, "hsla")
8446 NotEqual(t, errs, nil)
8447 AssertError(t, errs, "", "", "", "", "hsla")
8448
8449 s = "hsla(360,101%,50%)"
8450 errs = validate.Var(s, "hsla")
8451 NotEqual(t, errs, nil)
8452 AssertError(t, errs, "", "", "", "", "hsla")
8453
8454 s = "hsla(360,100%,101%)"
8455 errs = validate.Var(s, "hsla")
8456 NotEqual(t, errs, nil)
8457 AssertError(t, errs, "", "", "", "", "hsla")
8458
8459 i := 1
8460 errs = validate.Var(i, "hsla")
8461 NotEqual(t, errs, nil)
8462 AssertError(t, errs, "", "", "", "", "hsla")
8463 }
8464
8465 func TestHsl(t *testing.T) {
8466 validate := New()
8467
8468 s := "hsl(360,100%,50%)"
8469 errs := validate.Var(s, "hsl")
8470 Equal(t, errs, nil)
8471
8472 s = "hsl(0,0%,0%)"
8473 errs = validate.Var(s, "hsl")
8474 Equal(t, errs, nil)
8475
8476 s = "hsl(361,100%,50%)"
8477 errs = validate.Var(s, "hsl")
8478 NotEqual(t, errs, nil)
8479 AssertError(t, errs, "", "", "", "", "hsl")
8480
8481 s = "hsl(361,101%,50%)"
8482 errs = validate.Var(s, "hsl")
8483 NotEqual(t, errs, nil)
8484 AssertError(t, errs, "", "", "", "", "hsl")
8485
8486 s = "hsl(361,100%,101%)"
8487 errs = validate.Var(s, "hsl")
8488 NotEqual(t, errs, nil)
8489 AssertError(t, errs, "", "", "", "", "hsl")
8490
8491 s = "hsl(-10,100%,100%)"
8492 errs = validate.Var(s, "hsl")
8493 NotEqual(t, errs, nil)
8494 AssertError(t, errs, "", "", "", "", "hsl")
8495
8496 i := 1
8497 errs = validate.Var(i, "hsl")
8498 NotEqual(t, errs, nil)
8499 AssertError(t, errs, "", "", "", "", "hsl")
8500 }
8501
8502 func TestRgba(t *testing.T) {
8503 validate := New()
8504
8505 s := "rgba(0,31,255,0.5)"
8506 errs := validate.Var(s, "rgba")
8507 Equal(t, errs, nil)
8508
8509 s = "rgba(0,31,255,0.12)"
8510 errs = validate.Var(s, "rgba")
8511 Equal(t, errs, nil)
8512
8513 s = "rgba(12%,55%,100%,0.12)"
8514 errs = validate.Var(s, "rgba")
8515 Equal(t, errs, nil)
8516
8517 s = "rgba( 0, 31, 255, 0.5)"
8518 errs = validate.Var(s, "rgba")
8519 Equal(t, errs, nil)
8520
8521 s = "rgba(12%,55,100%,0.12)"
8522 errs = validate.Var(s, "rgba")
8523 NotEqual(t, errs, nil)
8524 AssertError(t, errs, "", "", "", "", "rgba")
8525
8526 s = "rgb(0, 31, 255)"
8527 errs = validate.Var(s, "rgba")
8528 NotEqual(t, errs, nil)
8529 AssertError(t, errs, "", "", "", "", "rgba")
8530
8531 s = "rgb(1,349,275,0.5)"
8532 errs = validate.Var(s, "rgba")
8533 NotEqual(t, errs, nil)
8534 AssertError(t, errs, "", "", "", "", "rgba")
8535
8536 s = "rgb(01,31,255,0.5)"
8537 errs = validate.Var(s, "rgba")
8538 NotEqual(t, errs, nil)
8539 AssertError(t, errs, "", "", "", "", "rgba")
8540
8541 i := 1
8542 errs = validate.Var(i, "rgba")
8543 NotEqual(t, errs, nil)
8544 AssertError(t, errs, "", "", "", "", "rgba")
8545 }
8546
8547 func TestRgb(t *testing.T) {
8548 validate := New()
8549
8550 s := "rgb(0,31,255)"
8551 errs := validate.Var(s, "rgb")
8552 Equal(t, errs, nil)
8553
8554 s = "rgb(0, 31, 255)"
8555 errs = validate.Var(s, "rgb")
8556 Equal(t, errs, nil)
8557
8558 s = "rgb(10%, 50%, 100%)"
8559 errs = validate.Var(s, "rgb")
8560 Equal(t, errs, nil)
8561
8562 s = "rgb(10%, 50%, 55)"
8563 errs = validate.Var(s, "rgb")
8564 NotEqual(t, errs, nil)
8565 AssertError(t, errs, "", "", "", "", "rgb")
8566
8567 s = "rgb(1,349,275)"
8568 errs = validate.Var(s, "rgb")
8569 NotEqual(t, errs, nil)
8570 AssertError(t, errs, "", "", "", "", "rgb")
8571
8572 s = "rgb(01,31,255)"
8573 errs = validate.Var(s, "rgb")
8574 NotEqual(t, errs, nil)
8575 AssertError(t, errs, "", "", "", "", "rgb")
8576
8577 s = "rgba(0,31,255)"
8578 errs = validate.Var(s, "rgb")
8579 NotEqual(t, errs, nil)
8580 AssertError(t, errs, "", "", "", "", "rgb")
8581
8582 i := 1
8583 errs = validate.Var(i, "rgb")
8584 NotEqual(t, errs, nil)
8585 AssertError(t, errs, "", "", "", "", "rgb")
8586 }
8587
8588 func TestEmail(t *testing.T) {
8589 validate := New()
8590
8591 s := "test@mail.com"
8592 errs := validate.Var(s, "email")
8593 Equal(t, errs, nil)
8594
8595 s = "Dörte@Sörensen.example.com"
8596 errs = validate.Var(s, "email")
8597 Equal(t, errs, nil)
8598
8599 s = "θσερ@εχαμπλε.ψομ"
8600 errs = validate.Var(s, "email")
8601 Equal(t, errs, nil)
8602
8603 s = "юзер@екзампл.ком"
8604 errs = validate.Var(s, "email")
8605 Equal(t, errs, nil)
8606
8607 s = "उपयोगकर्ता@उदाहरण.कॉम"
8608 errs = validate.Var(s, "email")
8609 Equal(t, errs, nil)
8610
8611 s = "用户@例子.广告"
8612 errs = validate.Var(s, "email")
8613 Equal(t, errs, nil)
8614
8615 s = "mail@domain_with_underscores.org"
8616 errs = validate.Var(s, "email")
8617 NotEqual(t, errs, nil)
8618 AssertError(t, errs, "", "", "", "", "email")
8619
8620 s = ""
8621 errs = validate.Var(s, "email")
8622 NotEqual(t, errs, nil)
8623 AssertError(t, errs, "", "", "", "", "email")
8624
8625 s = "test@email"
8626 errs = validate.Var(s, "email")
8627 NotEqual(t, errs, nil)
8628 AssertError(t, errs, "", "", "", "", "email")
8629
8630 s = "test@email."
8631 errs = validate.Var(s, "email")
8632 NotEqual(t, errs, nil)
8633 AssertError(t, errs, "", "", "", "", "email")
8634
8635 s = "@email.com"
8636 errs = validate.Var(s, "email")
8637 NotEqual(t, errs, nil)
8638 AssertError(t, errs, "", "", "", "", "email")
8639
8640 s = `"test test"@email.com`
8641 errs = validate.Var(s, "email")
8642 Equal(t, errs, nil)
8643
8644 s = `"@email.com`
8645 errs = validate.Var(s, "email")
8646 NotEqual(t, errs, nil)
8647 AssertError(t, errs, "", "", "", "", "email")
8648
8649 i := true
8650 errs = validate.Var(i, "email")
8651 NotEqual(t, errs, nil)
8652 AssertError(t, errs, "", "", "", "", "email")
8653 }
8654
8655 func TestHexColor(t *testing.T) {
8656 validate := New()
8657
8658 s := "#fff"
8659 errs := validate.Var(s, "hexcolor")
8660 Equal(t, errs, nil)
8661
8662 s = "#c2c2c2"
8663 errs = validate.Var(s, "hexcolor")
8664 Equal(t, errs, nil)
8665
8666 s = "fff"
8667 errs = validate.Var(s, "hexcolor")
8668 NotEqual(t, errs, nil)
8669 AssertError(t, errs, "", "", "", "", "hexcolor")
8670
8671 s = "fffFF"
8672 errs = validate.Var(s, "hexcolor")
8673 NotEqual(t, errs, nil)
8674 AssertError(t, errs, "", "", "", "", "hexcolor")
8675
8676 i := true
8677 errs = validate.Var(i, "hexcolor")
8678 NotEqual(t, errs, nil)
8679 AssertError(t, errs, "", "", "", "", "hexcolor")
8680 }
8681
8682 func TestHexadecimal(t *testing.T) {
8683 validate := New()
8684
8685 s := "ff0044"
8686 errs := validate.Var(s, "hexadecimal")
8687 Equal(t, errs, nil)
8688
8689 s = "0xff0044"
8690 errs = validate.Var(s, "hexadecimal")
8691 Equal(t, errs, nil)
8692
8693 s = "0Xff0044"
8694 errs = validate.Var(s, "hexadecimal")
8695 Equal(t, errs, nil)
8696
8697 s = "abcdefg"
8698 errs = validate.Var(s, "hexadecimal")
8699 NotEqual(t, errs, nil)
8700 AssertError(t, errs, "", "", "", "", "hexadecimal")
8701
8702 i := true
8703 errs = validate.Var(i, "hexadecimal")
8704 NotEqual(t, errs, nil)
8705 AssertError(t, errs, "", "", "", "", "hexadecimal")
8706 }
8707
8708 func TestNumber(t *testing.T) {
8709 validate := New()
8710
8711 s := "1"
8712 errs := validate.Var(s, "number")
8713 Equal(t, errs, nil)
8714
8715 s = "+1"
8716 errs = validate.Var(s, "number")
8717 NotEqual(t, errs, nil)
8718 AssertError(t, errs, "", "", "", "", "number")
8719
8720 s = "-1"
8721 errs = validate.Var(s, "number")
8722 NotEqual(t, errs, nil)
8723 AssertError(t, errs, "", "", "", "", "number")
8724
8725 s = "1.12"
8726 errs = validate.Var(s, "number")
8727 NotEqual(t, errs, nil)
8728 AssertError(t, errs, "", "", "", "", "number")
8729
8730 s = "+1.12"
8731 errs = validate.Var(s, "number")
8732 NotEqual(t, errs, nil)
8733 AssertError(t, errs, "", "", "", "", "number")
8734
8735 s = "-1.12"
8736 errs = validate.Var(s, "number")
8737 NotEqual(t, errs, nil)
8738 AssertError(t, errs, "", "", "", "", "number")
8739
8740 s = "1."
8741 errs = validate.Var(s, "number")
8742 NotEqual(t, errs, nil)
8743 AssertError(t, errs, "", "", "", "", "number")
8744
8745 s = "1.o"
8746 errs = validate.Var(s, "number")
8747 NotEqual(t, errs, nil)
8748 AssertError(t, errs, "", "", "", "", "number")
8749
8750 i := 1
8751 errs = validate.Var(i, "number")
8752 Equal(t, errs, nil)
8753 }
8754
8755 func TestNumeric(t *testing.T) {
8756 validate := New()
8757
8758 s := "1"
8759 errs := validate.Var(s, "numeric")
8760 Equal(t, errs, nil)
8761
8762 s = "+1"
8763 errs = validate.Var(s, "numeric")
8764 Equal(t, errs, nil)
8765
8766 s = "-1"
8767 errs = validate.Var(s, "numeric")
8768 Equal(t, errs, nil)
8769
8770 s = "1.12"
8771 errs = validate.Var(s, "numeric")
8772 Equal(t, errs, nil)
8773
8774 s = "+1.12"
8775 errs = validate.Var(s, "numeric")
8776 Equal(t, errs, nil)
8777
8778 s = "-1.12"
8779 errs = validate.Var(s, "numeric")
8780 Equal(t, errs, nil)
8781
8782 s = "1."
8783 errs = validate.Var(s, "numeric")
8784 NotEqual(t, errs, nil)
8785 AssertError(t, errs, "", "", "", "", "numeric")
8786
8787 s = "1.o"
8788 errs = validate.Var(s, "numeric")
8789 NotEqual(t, errs, nil)
8790 AssertError(t, errs, "", "", "", "", "numeric")
8791
8792 i := 1
8793 errs = validate.Var(i, "numeric")
8794 Equal(t, errs, nil)
8795 }
8796 func TestBoolean(t *testing.T) {
8797 validate := New()
8798
8799 b := true
8800 errs := validate.Var(b, "boolean")
8801 Equal(t, errs, nil)
8802
8803 b = false
8804 errs = validate.Var(b, "boolean")
8805 Equal(t, errs, nil)
8806
8807 s := "true"
8808 errs = validate.Var(s, "boolean")
8809 Equal(t, errs, nil)
8810
8811 s = "false"
8812 errs = validate.Var(s, "boolean")
8813 Equal(t, errs, nil)
8814
8815 s = "0"
8816 errs = validate.Var(s, "boolean")
8817 Equal(t, errs, nil)
8818
8819 s = "1"
8820 errs = validate.Var(s, "boolean")
8821 Equal(t, errs, nil)
8822
8823 s = "xyz"
8824 errs = validate.Var(s, "boolean")
8825 NotEqual(t, errs, nil)
8826 AssertError(t, errs, "", "", "", "", "boolean")
8827
8828 s = "1."
8829 errs = validate.Var(s, "boolean")
8830 NotEqual(t, errs, nil)
8831 AssertError(t, errs, "", "", "", "", "boolean")
8832 }
8833
8834 func TestAlphaNumeric(t *testing.T) {
8835 validate := New()
8836
8837 s := "abcd123"
8838 errs := validate.Var(s, "alphanum")
8839 Equal(t, errs, nil)
8840
8841 s = "abc!23"
8842 errs = validate.Var(s, "alphanum")
8843 NotEqual(t, errs, nil)
8844 AssertError(t, errs, "", "", "", "", "alphanum")
8845
8846 errs = validate.Var(1, "alphanum")
8847 NotEqual(t, errs, nil)
8848 AssertError(t, errs, "", "", "", "", "alphanum")
8849 }
8850
8851 func TestAlpha(t *testing.T) {
8852 validate := New()
8853
8854 s := "abcd"
8855 errs := validate.Var(s, "alpha")
8856 Equal(t, errs, nil)
8857
8858 s = "abc®"
8859 errs = validate.Var(s, "alpha")
8860 NotEqual(t, errs, nil)
8861 AssertError(t, errs, "", "", "", "", "alpha")
8862
8863 s = "abc÷"
8864 errs = validate.Var(s, "alpha")
8865 NotEqual(t, errs, nil)
8866 AssertError(t, errs, "", "", "", "", "alpha")
8867
8868 s = "abc1"
8869 errs = validate.Var(s, "alpha")
8870 NotEqual(t, errs, nil)
8871 AssertError(t, errs, "", "", "", "", "alpha")
8872
8873 s = "this is a test string"
8874 errs = validate.Var(s, "alpha")
8875 NotEqual(t, errs, nil)
8876 AssertError(t, errs, "", "", "", "", "alpha")
8877
8878 errs = validate.Var(1, "alpha")
8879 NotEqual(t, errs, nil)
8880 AssertError(t, errs, "", "", "", "", "alpha")
8881 }
8882
8883 func TestStructStringValidation(t *testing.T) {
8884 validate := New()
8885
8886 tSuccess := &TestString{
8887 Required: "Required",
8888 Len: "length==10",
8889 Min: "min=1",
8890 Max: "1234567890",
8891 MinMax: "12345",
8892 Lt: "012345678",
8893 Lte: "0123456789",
8894 Gt: "01234567890",
8895 Gte: "0123456789",
8896 Boolean: "true",
8897 OmitEmpty: "",
8898 Sub: &SubTest{
8899 Test: "1",
8900 },
8901 SubIgnore: &SubTest{
8902 Test: "",
8903 },
8904 Anonymous: struct {
8905 A string `validate:"required"`
8906 }{
8907 A: "1",
8908 },
8909 Iface: &Impl{
8910 F: "123",
8911 },
8912 }
8913
8914 errs := validate.Struct(tSuccess)
8915 Equal(t, errs, nil)
8916
8917 tFail := &TestString{
8918 Required: "",
8919 Len: "",
8920 Min: "",
8921 Max: "12345678901",
8922 MinMax: "",
8923 Lt: "0123456789",
8924 Lte: "01234567890",
8925 Gt: "1",
8926 Gte: "1",
8927 OmitEmpty: "12345678901",
8928 Boolean: "nope",
8929 Sub: &SubTest{
8930 Test: "",
8931 },
8932 Anonymous: struct {
8933 A string `validate:"required"`
8934 }{
8935 A: "",
8936 },
8937 Iface: &Impl{
8938 F: "12",
8939 },
8940 }
8941
8942 errs = validate.Struct(tFail)
8943
8944
8945 NotEqual(t, errs, nil)
8946 Equal(t, len(errs.(ValidationErrors)), 14)
8947
8948
8949 AssertError(t, errs, "TestString.Required", "TestString.Required", "Required", "Required", "required")
8950 AssertError(t, errs, "TestString.Len", "TestString.Len", "Len", "Len", "len")
8951 AssertError(t, errs, "TestString.Min", "TestString.Min", "Min", "Min", "min")
8952 AssertError(t, errs, "TestString.Max", "TestString.Max", "Max", "Max", "max")
8953 AssertError(t, errs, "TestString.MinMax", "TestString.MinMax", "MinMax", "MinMax", "min")
8954 AssertError(t, errs, "TestString.Lt", "TestString.Lt", "Lt", "Lt", "lt")
8955 AssertError(t, errs, "TestString.Lte", "TestString.Lte", "Lte", "Lte", "lte")
8956 AssertError(t, errs, "TestString.Gt", "TestString.Gt", "Gt", "Gt", "gt")
8957 AssertError(t, errs, "TestString.Gte", "TestString.Gte", "Gte", "Gte", "gte")
8958 AssertError(t, errs, "TestString.OmitEmpty", "TestString.OmitEmpty", "OmitEmpty", "OmitEmpty", "max")
8959 AssertError(t, errs, "TestString.Boolean", "TestString.Boolean", "Boolean", "Boolean", "boolean")
8960
8961
8962 AssertError(t, errs, "TestString.Anonymous.A", "TestString.Anonymous.A", "A", "A", "required")
8963 AssertError(t, errs, "TestString.Sub.Test", "TestString.Sub.Test", "Test", "Test", "required")
8964 AssertError(t, errs, "TestString.Iface.F", "TestString.Iface.F", "F", "F", "len")
8965 }
8966
8967 func TestStructInt32Validation(t *testing.T) {
8968 type TestInt32 struct {
8969 Required int `validate:"required"`
8970 Len int `validate:"len=10"`
8971 Min int `validate:"min=1"`
8972 Max int `validate:"max=10"`
8973 MinMax int `validate:"min=1,max=10"`
8974 Lt int `validate:"lt=10"`
8975 Lte int `validate:"lte=10"`
8976 Gt int `validate:"gt=10"`
8977 Gte int `validate:"gte=10"`
8978 OmitEmpty int `validate:"omitempty,min=1,max=10"`
8979 }
8980
8981 tSuccess := &TestInt32{
8982 Required: 1,
8983 Len: 10,
8984 Min: 1,
8985 Max: 10,
8986 MinMax: 5,
8987 Lt: 9,
8988 Lte: 10,
8989 Gt: 11,
8990 Gte: 10,
8991 OmitEmpty: 0,
8992 }
8993
8994 validate := New()
8995 errs := validate.Struct(tSuccess)
8996 Equal(t, errs, nil)
8997
8998 tFail := &TestInt32{
8999 Required: 0,
9000 Len: 11,
9001 Min: -1,
9002 Max: 11,
9003 MinMax: -1,
9004 Lt: 10,
9005 Lte: 11,
9006 Gt: 10,
9007 Gte: 9,
9008 OmitEmpty: 11,
9009 }
9010
9011 errs = validate.Struct(tFail)
9012
9013
9014 NotEqual(t, errs, nil)
9015 Equal(t, len(errs.(ValidationErrors)), 10)
9016
9017
9018 AssertError(t, errs, "TestInt32.Required", "TestInt32.Required", "Required", "Required", "required")
9019 AssertError(t, errs, "TestInt32.Len", "TestInt32.Len", "Len", "Len", "len")
9020 AssertError(t, errs, "TestInt32.Min", "TestInt32.Min", "Min", "Min", "min")
9021 AssertError(t, errs, "TestInt32.Max", "TestInt32.Max", "Max", "Max", "max")
9022 AssertError(t, errs, "TestInt32.MinMax", "TestInt32.MinMax", "MinMax", "MinMax", "min")
9023 AssertError(t, errs, "TestInt32.Lt", "TestInt32.Lt", "Lt", "Lt", "lt")
9024 AssertError(t, errs, "TestInt32.Lte", "TestInt32.Lte", "Lte", "Lte", "lte")
9025 AssertError(t, errs, "TestInt32.Gt", "TestInt32.Gt", "Gt", "Gt", "gt")
9026 AssertError(t, errs, "TestInt32.Gte", "TestInt32.Gte", "Gte", "Gte", "gte")
9027 AssertError(t, errs, "TestInt32.OmitEmpty", "TestInt32.OmitEmpty", "OmitEmpty", "OmitEmpty", "max")
9028 }
9029
9030 func TestStructUint64Validation(t *testing.T) {
9031 validate := New()
9032
9033 tSuccess := &TestUint64{
9034 Required: 1,
9035 Len: 10,
9036 Min: 1,
9037 Max: 10,
9038 MinMax: 5,
9039 OmitEmpty: 0,
9040 }
9041
9042 errs := validate.Struct(tSuccess)
9043 Equal(t, errs, nil)
9044
9045 tFail := &TestUint64{
9046 Required: 0,
9047 Len: 11,
9048 Min: 0,
9049 Max: 11,
9050 MinMax: 0,
9051 OmitEmpty: 11,
9052 }
9053
9054 errs = validate.Struct(tFail)
9055
9056
9057 NotEqual(t, errs, nil)
9058 Equal(t, len(errs.(ValidationErrors)), 6)
9059
9060
9061 AssertError(t, errs, "TestUint64.Required", "TestUint64.Required", "Required", "Required", "required")
9062 AssertError(t, errs, "TestUint64.Len", "TestUint64.Len", "Len", "Len", "len")
9063 AssertError(t, errs, "TestUint64.Min", "TestUint64.Min", "Min", "Min", "min")
9064 AssertError(t, errs, "TestUint64.Max", "TestUint64.Max", "Max", "Max", "max")
9065 AssertError(t, errs, "TestUint64.MinMax", "TestUint64.MinMax", "MinMax", "MinMax", "min")
9066 AssertError(t, errs, "TestUint64.OmitEmpty", "TestUint64.OmitEmpty", "OmitEmpty", "OmitEmpty", "max")
9067 }
9068
9069 func TestStructFloat64Validation(t *testing.T) {
9070 validate := New()
9071
9072 tSuccess := &TestFloat64{
9073 Required: 1,
9074 Len: 10,
9075 Min: 1,
9076 Max: 10,
9077 MinMax: 5,
9078 OmitEmpty: 0,
9079 }
9080
9081 errs := validate.Struct(tSuccess)
9082 Equal(t, errs, nil)
9083
9084 tFail := &TestFloat64{
9085 Required: 0,
9086 Len: 11,
9087 Min: 0,
9088 Max: 11,
9089 MinMax: 0,
9090 OmitEmpty: 11,
9091 }
9092
9093 errs = validate.Struct(tFail)
9094
9095
9096 NotEqual(t, errs, nil)
9097 Equal(t, len(errs.(ValidationErrors)), 6)
9098
9099
9100 AssertError(t, errs, "TestFloat64.Required", "TestFloat64.Required", "Required", "Required", "required")
9101 AssertError(t, errs, "TestFloat64.Len", "TestFloat64.Len", "Len", "Len", "len")
9102 AssertError(t, errs, "TestFloat64.Min", "TestFloat64.Min", "Min", "Min", "min")
9103 AssertError(t, errs, "TestFloat64.Max", "TestFloat64.Max", "Max", "Max", "max")
9104 AssertError(t, errs, "TestFloat64.MinMax", "TestFloat64.MinMax", "MinMax", "MinMax", "min")
9105 AssertError(t, errs, "TestFloat64.OmitEmpty", "TestFloat64.OmitEmpty", "OmitEmpty", "OmitEmpty", "max")
9106 }
9107
9108 func TestStructSliceValidation(t *testing.T) {
9109 validate := New()
9110
9111 tSuccess := &TestSlice{
9112 Required: []int{1},
9113 Len: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0},
9114 Min: []int{1, 2},
9115 Max: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0},
9116 MinMax: []int{1, 2, 3, 4, 5},
9117 OmitEmpty: nil,
9118 }
9119
9120 errs := validate.Struct(tSuccess)
9121 Equal(t, errs, nil)
9122
9123 tFail := &TestSlice{
9124 Required: nil,
9125 Len: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1},
9126 Min: []int{},
9127 Max: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1},
9128 MinMax: []int{},
9129 OmitEmpty: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1},
9130 }
9131
9132 errs = validate.Struct(tFail)
9133 NotEqual(t, errs, nil)
9134 Equal(t, len(errs.(ValidationErrors)), 6)
9135
9136
9137 AssertError(t, errs, "TestSlice.Required", "TestSlice.Required", "Required", "Required", "required")
9138 AssertError(t, errs, "TestSlice.Len", "TestSlice.Len", "Len", "Len", "len")
9139 AssertError(t, errs, "TestSlice.Min", "TestSlice.Min", "Min", "Min", "min")
9140 AssertError(t, errs, "TestSlice.Max", "TestSlice.Max", "Max", "Max", "max")
9141 AssertError(t, errs, "TestSlice.MinMax", "TestSlice.MinMax", "MinMax", "MinMax", "min")
9142 AssertError(t, errs, "TestSlice.OmitEmpty", "TestSlice.OmitEmpty", "OmitEmpty", "OmitEmpty", "max")
9143
9144 fe := getError(errs, "TestSlice.Len", "TestSlice.Len")
9145 NotEqual(t, fe, nil)
9146 Equal(t, fe.Field(), "Len")
9147 Equal(t, fe.StructField(), "Len")
9148 Equal(t, fe.Namespace(), "TestSlice.Len")
9149 Equal(t, fe.StructNamespace(), "TestSlice.Len")
9150 Equal(t, fe.Tag(), "len")
9151 Equal(t, fe.ActualTag(), "len")
9152 Equal(t, fe.Param(), "10")
9153 Equal(t, fe.Kind(), reflect.Slice)
9154 Equal(t, fe.Type(), reflect.TypeOf([]int{}))
9155
9156 _, ok := fe.Value().([]int)
9157 Equal(t, ok, true)
9158 }
9159
9160 func TestInvalidStruct(t *testing.T) {
9161 validate := New()
9162
9163 s := &SubTest{
9164 Test: "1",
9165 }
9166
9167 err := validate.Struct(s.Test)
9168 NotEqual(t, err, nil)
9169 Equal(t, err.Error(), "validator: (nil string)")
9170
9171 err = validate.Struct(nil)
9172 NotEqual(t, err, nil)
9173 Equal(t, err.Error(), "validator: (nil)")
9174
9175 err = validate.StructPartial(nil, "SubTest.Test")
9176 NotEqual(t, err, nil)
9177 Equal(t, err.Error(), "validator: (nil)")
9178
9179 err = validate.StructExcept(nil, "SubTest.Test")
9180 NotEqual(t, err, nil)
9181 Equal(t, err.Error(), "validator: (nil)")
9182 }
9183
9184 func TestInvalidValidatorFunction(t *testing.T) {
9185 validate := New()
9186
9187 s := &SubTest{
9188 Test: "1",
9189 }
9190
9191 PanicMatches(t, func() { _ = validate.Var(s.Test, "zzxxBadFunction") }, "Undefined validation function 'zzxxBadFunction' on field ''")
9192 }
9193
9194 func TestCustomFieldName(t *testing.T) {
9195 validate := New()
9196 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
9197 name := strings.SplitN(fld.Tag.Get("schema"), ",", 2)[0]
9198
9199 if name == "-" {
9200 return ""
9201 }
9202
9203 return name
9204 })
9205
9206 type A struct {
9207 B string `schema:"b" validate:"required"`
9208 C string `schema:"c" validate:"required"`
9209 D []bool `schema:"d" validate:"required"`
9210 E string `schema:"-" validate:"required"`
9211 }
9212
9213 a := &A{}
9214
9215 err := validate.Struct(a)
9216 NotEqual(t, err, nil)
9217
9218 errs := err.(ValidationErrors)
9219 Equal(t, len(errs), 4)
9220 Equal(t, getError(errs, "A.b", "A.B").Field(), "b")
9221 Equal(t, getError(errs, "A.c", "A.C").Field(), "c")
9222 Equal(t, getError(errs, "A.d", "A.D").Field(), "d")
9223 Equal(t, getError(errs, "A.E", "A.E").Field(), "E")
9224
9225 v2 := New()
9226 err = v2.Struct(a)
9227 NotEqual(t, err, nil)
9228
9229 errs = err.(ValidationErrors)
9230 Equal(t, len(errs), 4)
9231 Equal(t, getError(errs, "A.B", "A.B").Field(), "B")
9232 Equal(t, getError(errs, "A.C", "A.C").Field(), "C")
9233 Equal(t, getError(errs, "A.D", "A.D").Field(), "D")
9234 Equal(t, getError(errs, "A.E", "A.E").Field(), "E")
9235 }
9236
9237 func TestMutipleRecursiveExtractStructCache(t *testing.T) {
9238 validate := New()
9239
9240 type Recursive struct {
9241 Field *string `validate:"required,len=5,ne=string"`
9242 }
9243
9244 var test Recursive
9245
9246 current := reflect.ValueOf(test)
9247 name := "Recursive"
9248 proceed := make(chan struct{})
9249
9250 sc := validate.extractStructCache(current, name)
9251 ptr := fmt.Sprintf("%p", sc)
9252
9253 for i := 0; i < 100; i++ {
9254 go func() {
9255 <-proceed
9256 sc := validate.extractStructCache(current, name)
9257 Equal(t, ptr, fmt.Sprintf("%p", sc))
9258 }()
9259 }
9260
9261 close(proceed)
9262 }
9263
9264
9265 func TestPointerAndOmitEmpty(t *testing.T) {
9266 validate := New()
9267
9268 type Test struct {
9269 MyInt *int `validate:"omitempty,gte=2,lte=255"`
9270 }
9271
9272 val1 := 0
9273 val2 := 256
9274
9275 t1 := Test{MyInt: &val1}
9276 t2 := Test{MyInt: &val2}
9277 t3 := Test{MyInt: nil}
9278
9279 errs := validate.Struct(t1)
9280 NotEqual(t, errs, nil)
9281 AssertError(t, errs, "Test.MyInt", "Test.MyInt", "MyInt", "MyInt", "gte")
9282
9283 errs = validate.Struct(t2)
9284 NotEqual(t, errs, nil)
9285 AssertError(t, errs, "Test.MyInt", "Test.MyInt", "MyInt", "MyInt", "lte")
9286
9287 errs = validate.Struct(t3)
9288 Equal(t, errs, nil)
9289
9290 type TestIface struct {
9291 MyInt interface{} `validate:"omitempty,gte=2,lte=255"`
9292 }
9293
9294 ti1 := TestIface{MyInt: &val1}
9295 ti2 := TestIface{MyInt: &val2}
9296 ti3 := TestIface{MyInt: nil}
9297
9298 errs = validate.Struct(ti1)
9299 NotEqual(t, errs, nil)
9300 AssertError(t, errs, "TestIface.MyInt", "TestIface.MyInt", "MyInt", "MyInt", "gte")
9301
9302 errs = validate.Struct(ti2)
9303 NotEqual(t, errs, nil)
9304 AssertError(t, errs, "TestIface.MyInt", "TestIface.MyInt", "MyInt", "MyInt", "lte")
9305
9306 errs = validate.Struct(ti3)
9307 Equal(t, errs, nil)
9308 }
9309
9310 func TestRequired(t *testing.T) {
9311 validate := New()
9312 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
9313 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
9314
9315 if name == "-" {
9316 return ""
9317 }
9318
9319 return name
9320 })
9321
9322 type Test struct {
9323 Value interface{} `validate:"required"`
9324 }
9325
9326 var test Test
9327
9328 err := validate.Struct(test)
9329 NotEqual(t, err, nil)
9330 AssertError(t, err.(ValidationErrors), "Test.Value", "Test.Value", "Value", "Value", "required")
9331 }
9332
9333 func TestBoolEqual(t *testing.T) {
9334 validate := New()
9335
9336 type Test struct {
9337 Value bool `validate:"eq=true"`
9338 }
9339
9340 var test Test
9341
9342 err := validate.Struct(test)
9343 NotEqual(t, err, nil)
9344 AssertError(t, err.(ValidationErrors), "Test.Value", "Test.Value", "Value", "Value", "eq")
9345
9346 test.Value = true
9347 err = validate.Struct(test)
9348 Equal(t, err, nil)
9349 }
9350
9351 func TestTranslations(t *testing.T) {
9352 en := en.New()
9353 uni := ut.New(en, en, fr.New())
9354
9355 trans, _ := uni.GetTranslator("en")
9356 fr, _ := uni.GetTranslator("fr")
9357
9358 validate := New()
9359 err := validate.RegisterTranslation("required", trans,
9360 func(ut ut.Translator) (err error) {
9361
9362 if err = ut.Add("required", "{0} is a required field", false); err != nil {
9363 return
9364 }
9365
9366 return
9367 }, func(ut ut.Translator, fe FieldError) string {
9368 t, err := ut.T(fe.Tag(), fe.Field())
9369 if err != nil {
9370 fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError))
9371 return fe.(*fieldError).Error()
9372 }
9373
9374 return t
9375 })
9376 Equal(t, err, nil)
9377
9378 err = validate.RegisterTranslation("required", fr,
9379 func(ut ut.Translator) (err error) {
9380
9381 if err = ut.Add("required", "{0} est un champ obligatoire", false); err != nil {
9382 return
9383 }
9384
9385 return
9386 }, func(ut ut.Translator, fe FieldError) string {
9387 t, transErr := ut.T(fe.Tag(), fe.Field())
9388 if transErr != nil {
9389 fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError))
9390 return fe.(*fieldError).Error()
9391 }
9392
9393 return t
9394 })
9395
9396 Equal(t, err, nil)
9397
9398 type Test struct {
9399 Value interface{} `validate:"required"`
9400 }
9401
9402 var test Test
9403
9404 err = validate.Struct(test)
9405 NotEqual(t, err, nil)
9406
9407 errs := err.(ValidationErrors)
9408 Equal(t, len(errs), 1)
9409
9410 fe := errs[0]
9411 Equal(t, fe.Tag(), "required")
9412 Equal(t, fe.Namespace(), "Test.Value")
9413 Equal(t, fe.Translate(trans), fmt.Sprintf("%s is a required field", fe.Field()))
9414 Equal(t, fe.Translate(fr), fmt.Sprintf("%s est un champ obligatoire", fe.Field()))
9415
9416 nl := nl.New()
9417 uni2 := ut.New(nl, nl)
9418 trans2, _ := uni2.GetTranslator("nl")
9419 Equal(t, fe.Translate(trans2), "Key: 'Test.Value' Error:Field validation for 'Value' failed on the 'required' tag")
9420
9421 terrs := errs.Translate(trans)
9422 Equal(t, len(terrs), 1)
9423
9424 v, ok := terrs["Test.Value"]
9425 Equal(t, ok, true)
9426 Equal(t, v, fmt.Sprintf("%s is a required field", fe.Field()))
9427
9428 terrs = errs.Translate(fr)
9429 Equal(t, len(terrs), 1)
9430
9431 v, ok = terrs["Test.Value"]
9432 Equal(t, ok, true)
9433 Equal(t, v, fmt.Sprintf("%s est un champ obligatoire", fe.Field()))
9434
9435 type Test2 struct {
9436 Value string `validate:"gt=1"`
9437 }
9438
9439 var t2 Test2
9440
9441 err = validate.Struct(t2)
9442 NotEqual(t, err, nil)
9443
9444 errs = err.(ValidationErrors)
9445 Equal(t, len(errs), 1)
9446
9447 fe = errs[0]
9448 Equal(t, fe.Tag(), "gt")
9449 Equal(t, fe.Namespace(), "Test2.Value")
9450 Equal(t, fe.Translate(trans), "Key: 'Test2.Value' Error:Field validation for 'Value' failed on the 'gt' tag")
9451 }
9452
9453 func TestTranslationErrors(t *testing.T) {
9454 en := en.New()
9455 uni := ut.New(en, en, fr.New())
9456
9457 trans, _ := uni.GetTranslator("en")
9458 err := trans.Add("required", "{0} is a required field", false)
9459 Equal(t, err, nil)
9460
9461 validate := New()
9462 err = validate.RegisterTranslation("required", trans,
9463 func(ut ut.Translator) (err error) {
9464
9465 if err = ut.Add("required", "{0} is a required field", false); err != nil {
9466 return
9467 }
9468
9469 return
9470 }, func(ut ut.Translator, fe FieldError) string {
9471 t, err := ut.T(fe.Tag(), fe.Field())
9472 if err != nil {
9473 fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError))
9474 return fe.(*fieldError).Error()
9475 }
9476
9477 return t
9478 })
9479
9480 NotEqual(t, err, nil)
9481 Equal(t, err.Error(), "error: conflicting key 'required' rule 'Unknown' with text '{0} is a required field' for locale 'en', value being ignored")
9482 }
9483
9484 func TestStructFiltered(t *testing.T) {
9485 p1 := func(ns []byte) bool {
9486 if bytes.HasSuffix(ns, []byte("NoTag")) || bytes.HasSuffix(ns, []byte("Required")) {
9487 return false
9488 }
9489
9490 return true
9491 }
9492
9493 p2 := func(ns []byte) bool {
9494 if bytes.HasSuffix(ns, []byte("SubSlice[0].Test")) ||
9495 bytes.HasSuffix(ns, []byte("SubSlice[0]")) ||
9496 bytes.HasSuffix(ns, []byte("SubSlice")) ||
9497 bytes.HasSuffix(ns, []byte("Sub")) ||
9498 bytes.HasSuffix(ns, []byte("SubIgnore")) ||
9499 bytes.HasSuffix(ns, []byte("Anonymous")) ||
9500 bytes.HasSuffix(ns, []byte("Anonymous.A")) {
9501 return false
9502 }
9503
9504 return true
9505 }
9506
9507 p3 := func(ns []byte) bool {
9508 return !bytes.HasSuffix(ns, []byte("SubTest.Test"))
9509 }
9510
9511
9512
9513
9514
9515 tPartial := &TestPartial{
9516 NoTag: "NoTag",
9517 Required: "Required",
9518
9519 SubSlice: []*SubTest{
9520 {
9521
9522 Test: "Required",
9523 },
9524 {
9525
9526 Test: "Required",
9527 },
9528 },
9529
9530 Sub: &SubTest{
9531 Test: "1",
9532 },
9533 SubIgnore: &SubTest{
9534 Test: "",
9535 },
9536 Anonymous: struct {
9537 A string `validate:"required"`
9538 ASubSlice []*SubTest `validate:"required,dive"`
9539 SubAnonStruct []struct {
9540 Test string `validate:"required"`
9541 OtherTest string `validate:"required"`
9542 } `validate:"required,dive"`
9543 }{
9544 A: "1",
9545 ASubSlice: []*SubTest{
9546 {
9547 Test: "Required",
9548 },
9549 {
9550 Test: "Required",
9551 },
9552 },
9553
9554 SubAnonStruct: []struct {
9555 Test string `validate:"required"`
9556 OtherTest string `validate:"required"`
9557 }{
9558 {"Required", "RequiredOther"},
9559 {"Required", "RequiredOther"},
9560 },
9561 },
9562 }
9563
9564 validate := New()
9565
9566
9567
9568 errs := validate.StructFilteredCtx(context.Background(), tPartial, p1)
9569 Equal(t, errs, nil)
9570
9571 errs = validate.StructFiltered(tPartial, p2)
9572 Equal(t, errs, nil)
9573
9574
9575 errs = validate.StructFiltered(tPartial.SubSlice[0], p3)
9576 Equal(t, errs, nil)
9577
9578
9579 tPartial.Required = ""
9580
9581
9582 errs = validate.StructFiltered(tPartial, p1)
9583 NotEqual(t, errs, nil)
9584 AssertError(t, errs, "TestPartial.Required", "TestPartial.Required", "Required", "Required", "required")
9585
9586
9587 tPartial.Required = "Required"
9588 tPartial.Anonymous.A = ""
9589
9590
9591 errs = validate.StructFiltered(tPartial, p1)
9592 Equal(t, errs, nil)
9593
9594
9595 errs = validate.StructFiltered(tPartial, p2)
9596 NotEqual(t, errs, nil)
9597 AssertError(t, errs, "TestPartial.Anonymous.A", "TestPartial.Anonymous.A", "A", "A", "required")
9598
9599
9600 tPartial.Anonymous.A = "Required"
9601 tPartial.SubSlice[0].Test = ""
9602
9603
9604 errs = validate.StructFiltered(tPartial, p1)
9605 Equal(t, errs, nil)
9606
9607 errs = validate.StructFiltered(tPartial, p2)
9608 NotEqual(t, errs, nil)
9609 AssertError(t, errs, "TestPartial.SubSlice[0].Test", "TestPartial.SubSlice[0].Test", "Test", "Test", "required")
9610 Equal(t, len(errs.(ValidationErrors)), 1)
9611
9612
9613 tPartial.SubSlice[1].Test = ""
9614
9615 errs = validate.StructFiltered(tPartial, p1)
9616 Equal(t, errs, nil)
9617
9618 errs = validate.StructFiltered(tPartial, p2)
9619 NotEqual(t, errs, nil)
9620 Equal(t, len(errs.(ValidationErrors)), 1)
9621 AssertError(t, errs, "TestPartial.SubSlice[0].Test", "TestPartial.SubSlice[0].Test", "Test", "Test", "required")
9622
9623
9624 tPartial.SubSlice[0].Test = "Required"
9625
9626
9627 errs = validate.StructFiltered(tPartial, p1)
9628 Equal(t, errs, nil)
9629
9630 errs = validate.StructFiltered(tPartial, p2)
9631 Equal(t, errs, nil)
9632
9633 tPartial.SubSlice[1].Test = "Required"
9634 tPartial.Anonymous.SubAnonStruct[0].Test = ""
9635
9636
9637 errs = validate.StructFiltered(tPartial, p1)
9638 Equal(t, errs, nil)
9639
9640 errs = validate.StructFiltered(tPartial, p2)
9641 Equal(t, errs, nil)
9642
9643 dt := time.Now()
9644 err := validate.StructFiltered(&dt, func(ns []byte) bool { return true })
9645 NotEqual(t, err, nil)
9646 Equal(t, err.Error(), "validator: (nil *time.Time)")
9647 }
9648
9649 func TestRequiredPtr(t *testing.T) {
9650 type Test struct {
9651 Bool *bool `validate:"required"`
9652 }
9653
9654 validate := New()
9655
9656 f := false
9657
9658 test := Test{
9659 Bool: &f,
9660 }
9661
9662 err := validate.Struct(test)
9663 Equal(t, err, nil)
9664
9665 tr := true
9666
9667 test.Bool = &tr
9668
9669 err = validate.Struct(test)
9670 Equal(t, err, nil)
9671
9672 test.Bool = nil
9673
9674 err = validate.Struct(test)
9675 NotEqual(t, err, nil)
9676
9677 errs, ok := err.(ValidationErrors)
9678 Equal(t, ok, true)
9679 Equal(t, len(errs), 1)
9680 AssertError(t, errs, "Test.Bool", "Test.Bool", "Bool", "Bool", "required")
9681
9682 type Test2 struct {
9683 Bool bool `validate:"required"`
9684 }
9685
9686 var test2 Test2
9687
9688 err = validate.Struct(test2)
9689 NotEqual(t, err, nil)
9690
9691 errs, ok = err.(ValidationErrors)
9692 Equal(t, ok, true)
9693 Equal(t, len(errs), 1)
9694 AssertError(t, errs, "Test2.Bool", "Test2.Bool", "Bool", "Bool", "required")
9695
9696 test2.Bool = true
9697
9698 err = validate.Struct(test2)
9699 Equal(t, err, nil)
9700
9701 type Test3 struct {
9702 Arr []string `validate:"required"`
9703 }
9704
9705 var test3 Test3
9706
9707 err = validate.Struct(test3)
9708 NotEqual(t, err, nil)
9709
9710 errs, ok = err.(ValidationErrors)
9711 Equal(t, ok, true)
9712 Equal(t, len(errs), 1)
9713 AssertError(t, errs, "Test3.Arr", "Test3.Arr", "Arr", "Arr", "required")
9714
9715 test3.Arr = make([]string, 0)
9716
9717 err = validate.Struct(test3)
9718 Equal(t, err, nil)
9719
9720 type Test4 struct {
9721 Arr *[]string `validate:"required"`
9722 }
9723
9724 var test4 Test4
9725
9726 err = validate.Struct(test4)
9727 NotEqual(t, err, nil)
9728
9729 errs, ok = err.(ValidationErrors)
9730 Equal(t, ok, true)
9731 Equal(t, len(errs), 1)
9732 AssertError(t, errs, "Test4.Arr", "Test4.Arr", "Arr", "Arr", "required")
9733
9734 arr := make([]string, 0)
9735 test4.Arr = &arr
9736
9737 err = validate.Struct(test4)
9738 Equal(t, err, nil)
9739 }
9740
9741 func TestAlphaUnicodeValidation(t *testing.T) {
9742 tests := []struct {
9743 param string
9744 expected bool
9745 }{
9746 {"", false},
9747 {"abc", true},
9748 {"this is a test string", false},
9749 {"这是一个测试字符串", true},
9750 {"123", false},
9751 {"<>@;.-=", false},
9752 {"ひらがな・カタカナ、.漢字", false},
9753 {"あいうえおfoobar", true},
9754 {"test@example.com", false},
9755 {"1234abcDE", false},
9756 {"カタカナ", true},
9757 }
9758
9759 validate := New()
9760
9761 for i, test := range tests {
9762
9763 errs := validate.Var(test.param, "alphaunicode")
9764
9765 if test.expected {
9766 if !IsEqual(errs, nil) {
9767 t.Fatalf("Index: %d Alpha Unicode failed Error: %s", i, errs)
9768 }
9769 } else {
9770 if IsEqual(errs, nil) {
9771 t.Fatalf("Index: %d Alpha Unicode failed Error: %s", i, errs)
9772 } else {
9773 val := getError(errs, "", "")
9774 if val.Tag() != "alphaunicode" {
9775 t.Fatalf("Index: %d Alpha Unicode failed Error: %s", i, errs)
9776 }
9777 }
9778 }
9779 }
9780 }
9781
9782 func TestAlphanumericUnicodeValidation(t *testing.T) {
9783 tests := []struct {
9784 param string
9785 expected bool
9786 }{
9787 {"", false},
9788 {"abc", true},
9789 {"this is a test string", false},
9790 {"这是一个测试字符串", true},
9791 {"\u0031\u0032\u0033", true},
9792 {"123", true},
9793 {"<>@;.-=", false},
9794 {"ひらがな・カタカナ、.漢字", false},
9795 {"あいうえおfoobar", true},
9796 {"test@example.com", false},
9797 {"1234abcDE", true},
9798 {"カタカナ", true},
9799 }
9800
9801 validate := New()
9802
9803 for i, test := range tests {
9804
9805 errs := validate.Var(test.param, "alphanumunicode")
9806
9807 if test.expected {
9808 if !IsEqual(errs, nil) {
9809 t.Fatalf("Index: %d Alphanum Unicode failed Error: %s", i, errs)
9810 }
9811 } else {
9812 if IsEqual(errs, nil) {
9813 t.Fatalf("Index: %d Alphanum Unicode failed Error: %s", i, errs)
9814 } else {
9815 val := getError(errs, "", "")
9816 if val.Tag() != "alphanumunicode" {
9817 t.Fatalf("Index: %d Alphanum Unicode failed Error: %s", i, errs)
9818 }
9819 }
9820 }
9821 }
9822 }
9823
9824 func TestArrayStructNamespace(t *testing.T) {
9825 validate := New()
9826 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
9827 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
9828
9829 if name == "-" {
9830 return ""
9831 }
9832
9833 return name
9834 })
9835
9836 type child struct {
9837 Name string `json:"name" validate:"required"`
9838 }
9839 var input struct {
9840 Children []child `json:"children" validate:"required,gt=0,dive"`
9841 }
9842 input.Children = []child{{"ok"}, {""}}
9843
9844 errs := validate.Struct(input)
9845 NotEqual(t, errs, nil)
9846
9847 ve := errs.(ValidationErrors)
9848 Equal(t, len(ve), 1)
9849 AssertError(t, errs, "children[1].name", "Children[1].Name", "name", "Name", "required")
9850 }
9851
9852 func TestMapStructNamespace(t *testing.T) {
9853 validate := New()
9854 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
9855 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
9856
9857 if name == "-" {
9858 return ""
9859 }
9860
9861 return name
9862 })
9863
9864 type child struct {
9865 Name string `json:"name" validate:"required"`
9866 }
9867 var input struct {
9868 Children map[int]child `json:"children" validate:"required,gt=0,dive"`
9869 }
9870 input.Children = map[int]child{
9871 0: {Name: "ok"},
9872 1: {Name: ""},
9873 }
9874
9875 errs := validate.Struct(input)
9876 NotEqual(t, errs, nil)
9877
9878 ve := errs.(ValidationErrors)
9879 Equal(t, len(ve), 1)
9880 AssertError(t, errs, "children[1].name", "Children[1].Name", "name", "Name", "required")
9881 }
9882
9883 func TestFieldLevelName(t *testing.T) {
9884 type Test struct {
9885 String string `validate:"custom1" json:"json1"`
9886 Array []string `validate:"dive,custom2" json:"json2"`
9887 Map map[string]string `validate:"dive,custom3" json:"json3"`
9888 Array2 []string `validate:"custom4" json:"json4"`
9889 Map2 map[string]string `validate:"custom5" json:"json5"`
9890 }
9891
9892 var res1, res2, res3, res4, res5, alt1, alt2, alt3, alt4, alt5 string
9893 validate := New()
9894 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
9895 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
9896
9897 if name == "-" {
9898 return ""
9899 }
9900
9901 return name
9902 })
9903 err := validate.RegisterValidation("custom1", func(fl FieldLevel) bool {
9904 res1 = fl.FieldName()
9905 alt1 = fl.StructFieldName()
9906 return true
9907 })
9908 Equal(t, err, nil)
9909
9910 err = validate.RegisterValidation("custom2", func(fl FieldLevel) bool {
9911 res2 = fl.FieldName()
9912 alt2 = fl.StructFieldName()
9913 return true
9914 })
9915 Equal(t, err, nil)
9916
9917 err = validate.RegisterValidation("custom3", func(fl FieldLevel) bool {
9918 res3 = fl.FieldName()
9919 alt3 = fl.StructFieldName()
9920 return true
9921 })
9922 Equal(t, err, nil)
9923
9924 err = validate.RegisterValidation("custom4", func(fl FieldLevel) bool {
9925 res4 = fl.FieldName()
9926 alt4 = fl.StructFieldName()
9927 return true
9928 })
9929 Equal(t, err, nil)
9930
9931 err = validate.RegisterValidation("custom5", func(fl FieldLevel) bool {
9932 res5 = fl.FieldName()
9933 alt5 = fl.StructFieldName()
9934 return true
9935 })
9936 Equal(t, err, nil)
9937
9938 test := Test{
9939 String: "test",
9940 Array: []string{"1"},
9941 Map: map[string]string{"test": "test"},
9942 }
9943
9944 errs := validate.Struct(test)
9945 Equal(t, errs, nil)
9946 Equal(t, res1, "json1")
9947 Equal(t, alt1, "String")
9948 Equal(t, res2, "json2[0]")
9949 Equal(t, alt2, "Array[0]")
9950 Equal(t, res3, "json3[test]")
9951 Equal(t, alt3, "Map[test]")
9952 Equal(t, res4, "json4")
9953 Equal(t, alt4, "Array2")
9954 Equal(t, res5, "json5")
9955 Equal(t, alt5, "Map2")
9956 }
9957
9958 func TestValidateStructRegisterCtx(t *testing.T) {
9959 var ctxVal string
9960
9961 fnCtx := func(ctx context.Context, fl FieldLevel) bool {
9962 ctxVal = ctx.Value(&ctxVal).(string)
9963 return true
9964 }
9965
9966 var ctxSlVal string
9967 slFn := func(ctx context.Context, sl StructLevel) {
9968 ctxSlVal = ctx.Value(&ctxSlVal).(string)
9969 }
9970
9971 type Test struct {
9972 Field string `validate:"val"`
9973 }
9974
9975 var tst Test
9976
9977 validate := New()
9978 err := validate.RegisterValidationCtx("val", fnCtx)
9979 Equal(t, err, nil)
9980
9981 validate.RegisterStructValidationCtx(slFn, Test{})
9982
9983 ctx := context.WithValue(context.Background(), &ctxVal, "testval")
9984 ctx = context.WithValue(ctx, &ctxSlVal, "slVal")
9985 errs := validate.StructCtx(ctx, tst)
9986 Equal(t, errs, nil)
9987 Equal(t, ctxVal, "testval")
9988 Equal(t, ctxSlVal, "slVal")
9989 }
9990
9991 func TestHostnameRFC952Validation(t *testing.T) {
9992 tests := []struct {
9993 param string
9994 expected bool
9995 }{
9996 {"test.example.com", true},
9997 {"example.com", true},
9998 {"example24.com", true},
9999 {"test.example24.com", true},
10000 {"test24.example24.com", true},
10001 {"example", true},
10002 {"EXAMPLE", true},
10003 {"1.foo.com", false},
10004 {"test.example.com.", false},
10005 {"example.com.", false},
10006 {"example24.com.", false},
10007 {"test.example24.com.", false},
10008 {"test24.example24.com.", false},
10009 {"example.", false},
10010 {"192.168.0.1", false},
10011 {"email@example.com", false},
10012 {"2001:cdba:0000:0000:0000:0000:3257:9652", false},
10013 {"2001:cdba:0:0:0:0:3257:9652", false},
10014 {"2001:cdba::3257:9652", false},
10015 {"example..........com", false},
10016 {"1234", false},
10017 {"abc1234", true},
10018 {"example. com", false},
10019 {"ex ample.com", false},
10020 }
10021
10022 validate := New()
10023
10024 for i, test := range tests {
10025
10026 errs := validate.Var(test.param, "hostname")
10027
10028 if test.expected {
10029 if !IsEqual(errs, nil) {
10030 t.Fatalf("Index: %d hostname failed Error: %v", i, errs)
10031 }
10032 } else {
10033 if IsEqual(errs, nil) {
10034 t.Fatalf("Index: %d hostname failed Error: %v", i, errs)
10035 } else {
10036 val := getError(errs, "", "")
10037 if val.Tag() != "hostname" {
10038 t.Fatalf("Index: %d hostname failed Error: %v", i, errs)
10039 }
10040 }
10041 }
10042 }
10043 }
10044
10045 func TestHostnameRFC1123Validation(t *testing.T) {
10046 tests := []struct {
10047 param string
10048 expected bool
10049 }{
10050 {"test.example.com", true},
10051 {"example.com", true},
10052 {"example24.com", true},
10053 {"test.example24.com", true},
10054 {"test24.example24.com", true},
10055 {"example", true},
10056 {"1.foo.com", true},
10057 {"test.example.com.", false},
10058 {"example.com.", false},
10059 {"example24.com.", false},
10060 {"test.example24.com.", false},
10061 {"test24.example24.com.", false},
10062 {"example.", false},
10063 {"test_example", false},
10064 {"192.168.0.1", true},
10065 {"email@example.com", false},
10066 {"2001:cdba:0000:0000:0000:0000:3257:9652", false},
10067 {"2001:cdba:0:0:0:0:3257:9652", false},
10068 {"2001:cdba::3257:9652", false},
10069 }
10070
10071 validate := New()
10072
10073 for i, test := range tests {
10074
10075 errs := validate.Var(test.param, "hostname_rfc1123")
10076
10077 if test.expected {
10078 if !IsEqual(errs, nil) {
10079 t.Fatalf("Hostname: %v failed Error: %v", test, errs)
10080 }
10081 } else {
10082 if IsEqual(errs, nil) {
10083 t.Fatalf("Hostname: %v failed Error: %v", test, errs)
10084 } else {
10085 val := getError(errs, "", "")
10086 if val.Tag() != "hostname_rfc1123" {
10087 t.Fatalf("Hostname: %v failed Error: %v", i, errs)
10088 }
10089 }
10090 }
10091 }
10092 }
10093
10094 func TestHostnameRFC1123AliasValidation(t *testing.T) {
10095 tests := []struct {
10096 param string
10097 expected bool
10098 }{
10099 {"test.example.com", true},
10100 {"example.com", true},
10101 {"example24.com", true},
10102 {"test.example24.com", true},
10103 {"test24.example24.com", true},
10104 {"example", true},
10105 {"1.foo.com", true},
10106 {"test.example.com.", false},
10107 {"example.com.", false},
10108 {"example24.com.", false},
10109 {"test.example24.com.", false},
10110 {"test24.example24.com.", false},
10111 {"example.", false},
10112 {"test_example", false},
10113 {"192.168.0.1", true},
10114 {"email@example.com", false},
10115 {"2001:cdba:0000:0000:0000:0000:3257:9652", false},
10116 {"2001:cdba:0:0:0:0:3257:9652", false},
10117 {"2001:cdba::3257:9652", false},
10118 }
10119
10120 validate := New()
10121 validate.RegisterAlias("hostname", "hostname_rfc1123")
10122
10123 for i, test := range tests {
10124
10125 errs := validate.Var(test.param, "hostname")
10126
10127 if test.expected {
10128 if !IsEqual(errs, nil) {
10129 t.Fatalf("Index: %d hostname failed Error: %v", i, errs)
10130 }
10131 } else {
10132 if IsEqual(errs, nil) {
10133 t.Fatalf("Index: %d hostname failed Error: %v", i, errs)
10134 } else {
10135 val := getError(errs, "", "")
10136 if val.Tag() != "hostname" {
10137 t.Fatalf("Index: %d hostname failed Error: %v", i, errs)
10138 }
10139 }
10140 }
10141 }
10142 }
10143
10144 func TestFQDNValidation(t *testing.T) {
10145 tests := []struct {
10146 param string
10147 expected bool
10148 }{
10149 {"test.example.com", true},
10150 {"example.com", true},
10151 {"example24.com", true},
10152 {"test.example24.com", true},
10153 {"test24.example24.com", true},
10154 {"test.example.com.", true},
10155 {"example.com.", true},
10156 {"example24.com.", true},
10157 {"test.example24.com.", true},
10158 {"test24.example24.com.", true},
10159 {"24.example24.com", true},
10160 {"test.24.example.com", true},
10161 {"test24.example24.com..", false},
10162 {"example", false},
10163 {"192.168.0.1", false},
10164 {"email@example.com", false},
10165 {"2001:cdba:0000:0000:0000:0000:3257:9652", false},
10166 {"2001:cdba:0:0:0:0:3257:9652", false},
10167 {"2001:cdba::3257:9652", false},
10168 {"", false},
10169 }
10170
10171 validate := New()
10172
10173 for i, test := range tests {
10174
10175 errs := validate.Var(test.param, "fqdn")
10176
10177 if test.expected {
10178 if !IsEqual(errs, nil) {
10179 t.Fatalf("Index: %d fqdn failed Error: %v", i, errs)
10180 }
10181 } else {
10182 if IsEqual(errs, nil) {
10183 t.Fatalf("Index: %d fqdn failed Error: %v", i, errs)
10184 } else {
10185 val := getError(errs, "", "")
10186 if val.Tag() != "fqdn" {
10187 t.Fatalf("Index: %d fqdn failed Error: %v", i, errs)
10188 }
10189 }
10190 }
10191 }
10192 }
10193
10194 func TestIsDefault(t *testing.T) {
10195 validate := New()
10196
10197 type Inner struct {
10198 String string `validate:"isdefault"`
10199 }
10200 type Test struct {
10201 String string `validate:"isdefault"`
10202 Inner *Inner `validate:"isdefault"`
10203 }
10204
10205 var tt Test
10206
10207 errs := validate.Struct(tt)
10208 Equal(t, errs, nil)
10209
10210 tt.Inner = &Inner{String: ""}
10211 errs = validate.Struct(tt)
10212 NotEqual(t, errs, nil)
10213
10214 fe := errs.(ValidationErrors)[0]
10215 Equal(t, fe.Field(), "Inner")
10216 Equal(t, fe.Namespace(), "Test.Inner")
10217 Equal(t, fe.Tag(), "isdefault")
10218
10219 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
10220 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
10221 if name == "-" {
10222 return ""
10223 }
10224 return name
10225 })
10226
10227 type Inner2 struct {
10228 String string `validate:"isdefault"`
10229 }
10230
10231 type Test2 struct {
10232 Inner Inner2 `validate:"isdefault" json:"inner"`
10233 }
10234
10235 var t2 Test2
10236 errs = validate.Struct(t2)
10237 Equal(t, errs, nil)
10238
10239 t2.Inner.String = "Changed"
10240 errs = validate.Struct(t2)
10241 NotEqual(t, errs, nil)
10242
10243 fe = errs.(ValidationErrors)[0]
10244 Equal(t, fe.Field(), "inner")
10245 Equal(t, fe.Namespace(), "Test2.inner")
10246 Equal(t, fe.Tag(), "isdefault")
10247 }
10248
10249 func TestUniqueValidation(t *testing.T) {
10250 tests := []struct {
10251 param interface{}
10252 expected bool
10253 }{
10254
10255 {[2]string{"a", "b"}, true},
10256 {[2]int{1, 2}, true},
10257 {[2]float64{1, 2}, true},
10258 {[2]interface{}{"a", "b"}, true},
10259 {[2]interface{}{"a", 1}, true},
10260 {[2]float64{1, 1}, false},
10261 {[2]int{1, 1}, false},
10262 {[2]string{"a", "a"}, false},
10263 {[2]interface{}{"a", "a"}, false},
10264 {[4]interface{}{"a", 1, "b", 1}, false},
10265 {[2]*string{stringPtr("a"), stringPtr("b")}, true},
10266 {[2]*int{intPtr(1), intPtr(2)}, true},
10267 {[2]*float64{float64Ptr(1), float64Ptr(2)}, true},
10268 {[2]*string{stringPtr("a"), stringPtr("a")}, false},
10269 {[2]*float64{float64Ptr(1), float64Ptr(1)}, false},
10270 {[2]*int{intPtr(1), intPtr(1)}, false},
10271
10272 {[]string{"a", "b"}, true},
10273 {[]int{1, 2}, true},
10274 {[]float64{1, 2}, true},
10275 {[]interface{}{"a", "b"}, true},
10276 {[]interface{}{"a", 1}, true},
10277 {[]float64{1, 1}, false},
10278 {[]int{1, 1}, false},
10279 {[]string{"a", "a"}, false},
10280 {[]interface{}{"a", "a"}, false},
10281 {[]interface{}{"a", 1, "b", 1}, false},
10282 {[]*string{stringPtr("a"), stringPtr("b")}, true},
10283 {[]*int{intPtr(1), intPtr(2)}, true},
10284 {[]*float64{float64Ptr(1), float64Ptr(2)}, true},
10285 {[]*string{stringPtr("a"), stringPtr("a")}, false},
10286 {[]*float64{float64Ptr(1), float64Ptr(1)}, false},
10287 {[]*int{intPtr(1), intPtr(1)}, false},
10288
10289 {map[string]string{"one": "a", "two": "b"}, true},
10290 {map[string]int{"one": 1, "two": 2}, true},
10291 {map[string]float64{"one": 1, "two": 2}, true},
10292 {map[string]interface{}{"one": "a", "two": "b"}, true},
10293 {map[string]interface{}{"one": "a", "two": 1}, true},
10294 {map[string]float64{"one": 1, "two": 1}, false},
10295 {map[string]int{"one": 1, "two": 1}, false},
10296 {map[string]string{"one": "a", "two": "a"}, false},
10297 {map[string]interface{}{"one": "a", "two": "a"}, false},
10298 {map[string]interface{}{"one": "a", "two": 1, "three": "b", "four": 1}, false},
10299 {map[string]*string{"one": stringPtr("a"), "two": stringPtr("a")}, false},
10300 {map[string]*string{"one": stringPtr("a"), "two": stringPtr("b")}, true},
10301 {map[string]*int{"one": intPtr(1), "two": intPtr(1)}, false},
10302 {map[string]*int{"one": intPtr(1), "two": intPtr(2)}, true},
10303 {map[string]*float64{"one": float64Ptr(1.1), "two": float64Ptr(1.1)}, false},
10304 {map[string]*float64{"one": float64Ptr(1.1), "two": float64Ptr(1.2)}, true},
10305 }
10306
10307 validate := New()
10308
10309 for i, test := range tests {
10310
10311 errs := validate.Var(test.param, "unique")
10312
10313 if test.expected {
10314 if !IsEqual(errs, nil) {
10315 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10316 }
10317 } else {
10318 if IsEqual(errs, nil) {
10319 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10320 } else {
10321 val := getError(errs, "", "")
10322 if val.Tag() != "unique" {
10323 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10324 }
10325 }
10326 }
10327 }
10328 PanicMatches(t, func() { _ = validate.Var(1.0, "unique") }, "Bad field type float64")
10329
10330 t.Run("struct", func(t *testing.T) {
10331 tests := []struct {
10332 param interface{}
10333 expected bool
10334 }{
10335 {struct {
10336 A string `validate:"unique=B"`
10337 B string
10338 }{A: "abc", B: "bcd"}, true},
10339 {struct {
10340 A string `validate:"unique=B"`
10341 B string
10342 }{A: "abc", B: "abc"}, false},
10343 }
10344 validate := New()
10345
10346 for i, test := range tests {
10347 errs := validate.Struct(test.param)
10348 if test.expected {
10349 if !IsEqual(errs, nil) {
10350 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10351 }
10352 } else {
10353 if IsEqual(errs, nil) {
10354 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10355 } else {
10356 val := getError(errs, "A", "A")
10357 if val.Tag() != "unique" {
10358 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10359 }
10360 }
10361 }
10362 }
10363 })
10364 }
10365
10366 func TestUniqueValidationStructSlice(t *testing.T) {
10367 testStructs := []struct {
10368 A string
10369 B string
10370 }{
10371 {A: "one", B: "two"},
10372 {A: "one", B: "three"},
10373 }
10374
10375 tests := []struct {
10376 target interface{}
10377 param string
10378 expected bool
10379 }{
10380 {testStructs, "unique", true},
10381 {testStructs, "unique=A", false},
10382 {testStructs, "unique=B", true},
10383 }
10384
10385 validate := New()
10386
10387 for i, test := range tests {
10388
10389 errs := validate.Var(test.target, test.param)
10390
10391 if test.expected {
10392 if !IsEqual(errs, nil) {
10393 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10394 }
10395 } else {
10396 if IsEqual(errs, nil) {
10397 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10398 } else {
10399 val := getError(errs, "", "")
10400 if val.Tag() != "unique" {
10401 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10402 }
10403 }
10404 }
10405 }
10406 PanicMatches(t, func() { _ = validate.Var(testStructs, "unique=C") }, "Bad field name C")
10407 }
10408
10409 func TestUniqueValidationStructPtrSlice(t *testing.T) {
10410 testStructs := []*struct {
10411 A *string
10412 B *string
10413 }{
10414 {A: stringPtr("one"), B: stringPtr("two")},
10415 {A: stringPtr("one"), B: stringPtr("three")},
10416 {},
10417 }
10418
10419 tests := []struct {
10420 target interface{}
10421 param string
10422 expected bool
10423 }{
10424 {testStructs, "unique", true},
10425 {testStructs, "unique=A", false},
10426 {testStructs, "unique=B", true},
10427 }
10428
10429 validate := New()
10430
10431 for i, test := range tests {
10432
10433 errs := validate.Var(test.target, test.param)
10434
10435 if test.expected {
10436 if !IsEqual(errs, nil) {
10437 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10438 }
10439 } else {
10440 if IsEqual(errs, nil) {
10441 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10442 } else {
10443 val := getError(errs, "", "")
10444 if val.Tag() != "unique" {
10445 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
10446 }
10447 }
10448 }
10449 }
10450 PanicMatches(t, func() { _ = validate.Var(testStructs, "unique=C") }, "Bad field name C")
10451 }
10452
10453 func TestHTMLValidation(t *testing.T) {
10454 tests := []struct {
10455 param string
10456 expected bool
10457 }{
10458 {"<html>", true},
10459 {"<script>", true},
10460 {"<stillworks>", true},
10461 {"</html", false},
10462 {"</script>", true},
10463 {"<//script>", false},
10464 {"<123nonsense>", false},
10465 {"test", false},
10466 {"&example", false},
10467 }
10468
10469 validate := New()
10470
10471 for i, test := range tests {
10472
10473 errs := validate.Var(test.param, "html")
10474
10475 if test.expected {
10476 if !IsEqual(errs, nil) {
10477 t.Fatalf("Index: %d html failed Error: %v", i, errs)
10478 }
10479 } else {
10480 if IsEqual(errs, nil) {
10481 t.Fatalf("Index: %d html failed Error: %v", i, errs)
10482 } else {
10483 val := getError(errs, "", "")
10484 if val.Tag() != "html" {
10485 t.Fatalf("Index: %d html failed Error: %v", i, errs)
10486 }
10487 }
10488 }
10489 }
10490 }
10491
10492 func TestHTMLEncodedValidation(t *testing.T) {
10493 tests := []struct {
10494 param string
10495 expected bool
10496 }{
10497 {"<", true},
10498 {"¯", true},
10499 {"�", true},
10500 {"ð", true},
10501 {"<", true},
10502 {"¯", true},
10503 {"�", true},
10504 {"ð", true},
10505 {"&#ab", true},
10506 {"<", true},
10507 {">", true},
10508 {""", true},
10509 {"&", true},
10510 {"#x0a", false},
10511 {"&x00", false},
10512 {"z", false},
10513 }
10514
10515 validate := New()
10516
10517 for i, test := range tests {
10518
10519 errs := validate.Var(test.param, "html_encoded")
10520
10521 if test.expected {
10522 if !IsEqual(errs, nil) {
10523 t.Fatalf("Index: %d html_encoded failed Error: %v", i, errs)
10524 }
10525 } else {
10526 if IsEqual(errs, nil) {
10527 t.Fatalf("Index: %d html_enocded failed Error: %v", i, errs)
10528 } else {
10529 val := getError(errs, "", "")
10530 if val.Tag() != "html_encoded" {
10531 t.Fatalf("Index: %d html_encoded failed Error: %v", i, errs)
10532 }
10533 }
10534 }
10535 }
10536 }
10537
10538 func TestURLEncodedValidation(t *testing.T) {
10539 tests := []struct {
10540 param string
10541 expected bool
10542 }{
10543 {"%20", true},
10544 {"%af", true},
10545 {"%ff", true},
10546 {"<%az", false},
10547 {"%test%", false},
10548 {"a%b", false},
10549 {"1%2", false},
10550 {"%%a%%", false},
10551 {"hello", true},
10552 {"", true},
10553 {"+", true},
10554 }
10555
10556 validate := New()
10557
10558 for i, test := range tests {
10559
10560 errs := validate.Var(test.param, "url_encoded")
10561
10562 if test.expected {
10563 if !IsEqual(errs, nil) {
10564 t.Fatalf("Index: %d url_encoded failed Error: %v", i, errs)
10565 }
10566 } else {
10567 if IsEqual(errs, nil) {
10568 t.Fatalf("Index: %d url_enocded failed Error: %v", i, errs)
10569 } else {
10570 val := getError(errs, "", "")
10571 if val.Tag() != "url_encoded" {
10572 t.Fatalf("Index: %d url_encoded failed Error: %v", i, errs)
10573 }
10574 }
10575 }
10576 }
10577 }
10578
10579 func TestKeys(t *testing.T) {
10580 type Test struct {
10581 Test1 map[string]string `validate:"gt=0,dive,keys,eq=testkey,endkeys,eq=testval" json:"test1"`
10582 Test2 map[int]int `validate:"gt=0,dive,keys,eq=3,endkeys,eq=4" json:"test2"`
10583 Test3 map[int]int `validate:"gt=0,dive,keys,eq=3,endkeys" json:"test3"`
10584 }
10585
10586 var tst Test
10587
10588 validate := New()
10589 err := validate.Struct(tst)
10590 NotEqual(t, err, nil)
10591 Equal(t, len(err.(ValidationErrors)), 3)
10592 AssertError(t, err.(ValidationErrors), "Test.Test1", "Test.Test1", "Test1", "Test1", "gt")
10593 AssertError(t, err.(ValidationErrors), "Test.Test2", "Test.Test2", "Test2", "Test2", "gt")
10594 AssertError(t, err.(ValidationErrors), "Test.Test3", "Test.Test3", "Test3", "Test3", "gt")
10595
10596 tst.Test1 = map[string]string{
10597 "testkey": "testval",
10598 }
10599
10600 tst.Test2 = map[int]int{
10601 3: 4,
10602 }
10603
10604 tst.Test3 = map[int]int{
10605 3: 4,
10606 }
10607
10608 err = validate.Struct(tst)
10609 Equal(t, err, nil)
10610
10611 tst.Test1["badtestkey"] = "badtestvalue"
10612 tst.Test2[10] = 11
10613
10614 err = validate.Struct(tst)
10615 NotEqual(t, err, nil)
10616
10617 errs := err.(ValidationErrors)
10618
10619 Equal(t, len(errs), 4)
10620
10621 AssertDeepError(t, errs, "Test.Test1[badtestkey]", "Test.Test1[badtestkey]", "Test1[badtestkey]", "Test1[badtestkey]", "eq", "eq")
10622 AssertDeepError(t, errs, "Test.Test1[badtestkey]", "Test.Test1[badtestkey]", "Test1[badtestkey]", "Test1[badtestkey]", "eq", "eq")
10623 AssertDeepError(t, errs, "Test.Test2[10]", "Test.Test2[10]", "Test2[10]", "Test2[10]", "eq", "eq")
10624 AssertDeepError(t, errs, "Test.Test2[10]", "Test.Test2[10]", "Test2[10]", "Test2[10]", "eq", "eq")
10625
10626 type Test2 struct {
10627 NestedKeys map[[1]string]string `validate:"gt=0,dive,keys,dive,eq=innertestkey,endkeys,eq=outertestval"`
10628 }
10629
10630 var tst2 Test2
10631
10632 err = validate.Struct(tst2)
10633 NotEqual(t, err, nil)
10634 Equal(t, len(err.(ValidationErrors)), 1)
10635 AssertError(t, err.(ValidationErrors), "Test2.NestedKeys", "Test2.NestedKeys", "NestedKeys", "NestedKeys", "gt")
10636
10637 tst2.NestedKeys = map[[1]string]string{
10638 {"innertestkey"}: "outertestval",
10639 }
10640
10641 err = validate.Struct(tst2)
10642 Equal(t, err, nil)
10643
10644 tst2.NestedKeys[[1]string{"badtestkey"}] = "badtestvalue"
10645
10646 err = validate.Struct(tst2)
10647 NotEqual(t, err, nil)
10648
10649 errs = err.(ValidationErrors)
10650
10651 Equal(t, len(errs), 2)
10652 AssertDeepError(t, errs, "Test2.NestedKeys[[badtestkey]][0]", "Test2.NestedKeys[[badtestkey]][0]", "NestedKeys[[badtestkey]][0]", "NestedKeys[[badtestkey]][0]", "eq", "eq")
10653 AssertDeepError(t, errs, "Test2.NestedKeys[[badtestkey]]", "Test2.NestedKeys[[badtestkey]]", "NestedKeys[[badtestkey]]", "NestedKeys[[badtestkey]]", "eq", "eq")
10654
10655
10656
10657 PanicMatches(t, func() { _ = validate.Var(map[string]string{"key": "val"}, "endkeys,dive,eq=val") }, "'endkeys' tag encountered without a corresponding 'keys' tag")
10658 PanicMatches(t, func() { _ = validate.Var(1, "keys,eq=1,endkeys") }, "'keys' tag must be immediately preceded by the 'dive' tag")
10659
10660
10661 validate = New()
10662 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
10663 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
10664
10665 if name == "-" {
10666 return ""
10667 }
10668 return name
10669 })
10670
10671 err = validate.Struct(tst)
10672 NotEqual(t, err, nil)
10673
10674 errs = err.(ValidationErrors)
10675
10676 Equal(t, len(errs), 4)
10677
10678 AssertDeepError(t, errs, "Test.test1[badtestkey]", "Test.Test1[badtestkey]", "test1[badtestkey]", "Test1[badtestkey]", "eq", "eq")
10679 AssertDeepError(t, errs, "Test.test1[badtestkey]", "Test.Test1[badtestkey]", "test1[badtestkey]", "Test1[badtestkey]", "eq", "eq")
10680 AssertDeepError(t, errs, "Test.test2[10]", "Test.Test2[10]", "test2[10]", "Test2[10]", "eq", "eq")
10681 AssertDeepError(t, errs, "Test.test2[10]", "Test.Test2[10]", "test2[10]", "Test2[10]", "eq", "eq")
10682 }
10683
10684
10685 func TestKeysCustomValidation(t *testing.T) {
10686 type LangCode string
10687 type Label map[LangCode]string
10688
10689 type TestMapStructPtr struct {
10690 Label Label `validate:"dive,keys,lang_code,endkeys,required"`
10691 }
10692
10693 validate := New()
10694 err := validate.RegisterValidation("lang_code", func(fl FieldLevel) bool {
10695 validLangCodes := map[LangCode]struct{}{
10696 "en": {},
10697 "es": {},
10698 "pt": {},
10699 }
10700
10701 _, ok := validLangCodes[fl.Field().Interface().(LangCode)]
10702 return ok
10703 })
10704 Equal(t, err, nil)
10705
10706 label := Label{
10707 "en": "Good morning!",
10708 "pt": "",
10709 "es": "¡Buenos días!",
10710 "xx": "Bad key",
10711 "xxx": "",
10712 }
10713
10714 err = validate.Struct(TestMapStructPtr{label})
10715 NotEqual(t, err, nil)
10716
10717 errs := err.(ValidationErrors)
10718 Equal(t, len(errs), 4)
10719
10720 AssertDeepError(t, errs, "TestMapStructPtr.Label[xx]", "TestMapStructPtr.Label[xx]", "Label[xx]", "Label[xx]", "lang_code", "lang_code")
10721 AssertDeepError(t, errs, "TestMapStructPtr.Label[pt]", "TestMapStructPtr.Label[pt]", "Label[pt]", "Label[pt]", "required", "required")
10722 AssertDeepError(t, errs, "TestMapStructPtr.Label[xxx]", "TestMapStructPtr.Label[xxx]", "Label[xxx]", "Label[xxx]", "lang_code", "lang_code")
10723 AssertDeepError(t, errs, "TestMapStructPtr.Label[xxx]", "TestMapStructPtr.Label[xxx]", "Label[xxx]", "Label[xxx]", "required", "required")
10724
10725
10726
10727 var e FieldError
10728 for _, e = range errs {
10729 if e.Namespace() == "TestMapStructPtr.Label[xxx]" {
10730 break
10731 }
10732 }
10733
10734 Equal(t, e.Param(), "")
10735 Equal(t, e.Value().(LangCode), LangCode("xxx"))
10736
10737 for _, e = range errs {
10738 if e.Namespace() == "TestMapStructPtr.Label[xxx]" && e.Tag() == "required" {
10739 break
10740 }
10741 }
10742
10743 Equal(t, e.Param(), "")
10744 Equal(t, e.Value().(string), "")
10745 }
10746
10747 func TestKeyOrs(t *testing.T) {
10748 type Test struct {
10749 Test1 map[string]string `validate:"gt=0,dive,keys,eq=testkey|eq=testkeyok,endkeys,eq=testval" json:"test1"`
10750 }
10751
10752 var tst Test
10753
10754 validate := New()
10755 err := validate.Struct(tst)
10756 NotEqual(t, err, nil)
10757 Equal(t, len(err.(ValidationErrors)), 1)
10758 AssertError(t, err.(ValidationErrors), "Test.Test1", "Test.Test1", "Test1", "Test1", "gt")
10759
10760 tst.Test1 = map[string]string{
10761 "testkey": "testval",
10762 }
10763
10764 err = validate.Struct(tst)
10765 Equal(t, err, nil)
10766
10767 tst.Test1["badtestkey"] = "badtestval"
10768
10769 err = validate.Struct(tst)
10770 NotEqual(t, err, nil)
10771
10772 errs := err.(ValidationErrors)
10773
10774 Equal(t, len(errs), 2)
10775
10776 AssertDeepError(t, errs, "Test.Test1[badtestkey]", "Test.Test1[badtestkey]", "Test1[badtestkey]", "Test1[badtestkey]", "eq=testkey|eq=testkeyok", "eq=testkey|eq=testkeyok")
10777 AssertDeepError(t, errs, "Test.Test1[badtestkey]", "Test.Test1[badtestkey]", "Test1[badtestkey]", "Test1[badtestkey]", "eq", "eq")
10778
10779 validate.RegisterAlias("okkey", "eq=testkey|eq=testkeyok")
10780
10781 type Test2 struct {
10782 Test1 map[string]string `validate:"gt=0,dive,keys,okkey,endkeys,eq=testval" json:"test1"`
10783 }
10784
10785 var tst2 Test2
10786
10787 err = validate.Struct(tst2)
10788 NotEqual(t, err, nil)
10789 Equal(t, len(err.(ValidationErrors)), 1)
10790 AssertError(t, err.(ValidationErrors), "Test2.Test1", "Test2.Test1", "Test1", "Test1", "gt")
10791
10792 tst2.Test1 = map[string]string{
10793 "testkey": "testval",
10794 }
10795
10796 err = validate.Struct(tst2)
10797 Equal(t, err, nil)
10798
10799 tst2.Test1["badtestkey"] = "badtestval"
10800
10801 err = validate.Struct(tst2)
10802 NotEqual(t, err, nil)
10803
10804 errs = err.(ValidationErrors)
10805
10806 Equal(t, len(errs), 2)
10807
10808 AssertDeepError(t, errs, "Test2.Test1[badtestkey]", "Test2.Test1[badtestkey]", "Test1[badtestkey]", "Test1[badtestkey]", "okkey", "eq=testkey|eq=testkeyok")
10809 AssertDeepError(t, errs, "Test2.Test1[badtestkey]", "Test2.Test1[badtestkey]", "Test1[badtestkey]", "Test1[badtestkey]", "eq", "eq")
10810 }
10811
10812 func TestStructLevelValidationsPointerPassing(t *testing.T) {
10813 v1 := New()
10814 v1.RegisterStructValidation(StructValidationTestStruct, &TestStruct{})
10815
10816 tst := &TestStruct{
10817 String: "good value",
10818 }
10819
10820 errs := v1.Struct(tst)
10821 NotEqual(t, errs, nil)
10822 AssertError(t, errs, "TestStruct.StringVal", "TestStruct.String", "StringVal", "String", "badvalueteststruct")
10823 }
10824
10825 func TestDirValidation(t *testing.T) {
10826 validate := New()
10827
10828 tests := []struct {
10829 title string
10830 param string
10831 expected bool
10832 }{
10833 {"existing dir", "testdata", true},
10834 {"existing self dir", ".", true},
10835 {"existing parent dir", "..", true},
10836 {"empty dir", "", false},
10837 {"missing dir", "non_existing_testdata", false},
10838 {"a file not a directory", filepath.Join("testdata", "a.go"), false},
10839 }
10840
10841 for _, test := range tests {
10842 errs := validate.Var(test.param, "dir")
10843
10844 if test.expected {
10845 if !IsEqual(errs, nil) {
10846 t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
10847 }
10848 } else {
10849 if IsEqual(errs, nil) {
10850 t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
10851 }
10852 }
10853 }
10854
10855 PanicMatches(t, func() {
10856 _ = validate.Var(2, "dir")
10857 }, "Bad field type int")
10858 }
10859
10860 func TestDirPathValidation(t *testing.T) {
10861 validate := New()
10862
10863 tests := []struct {
10864 title string
10865 param string
10866 expected bool
10867 }{
10868 {"empty dirpath", "", false},
10869 {"valid dirpath - exists", "testdata", true},
10870 {"valid dirpath - explicit", "testdatanoexist" + string(os.PathSeparator), true},
10871 {"invalid dirpath", "testdata\000" + string(os.PathSeparator), false},
10872 {"file, not a dirpath", filepath.Join("testdata", "a.go"), false},
10873 }
10874
10875 for _, test := range tests {
10876 errs := validate.Var(test.param, "dirpath")
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(6, "filepath")
10891 }, "Bad field type int")
10892 }
10893
10894 func TestStartsWithValidation(t *testing.T) {
10895 tests := []struct {
10896 Value string `validate:"startswith=(/^ヮ^)/*:・゚✧"`
10897 Tag string
10898 ExpectedNil bool
10899 }{
10900 {Value: "(/^ヮ^)/*:・゚✧ glitter", Tag: "startswith=(/^ヮ^)/*:・゚✧", ExpectedNil: true},
10901 {Value: "abcd", Tag: "startswith=(/^ヮ^)/*:・゚✧", ExpectedNil: false},
10902 }
10903
10904 validate := New()
10905
10906 for i, s := range tests {
10907 errs := validate.Var(s.Value, s.Tag)
10908
10909 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
10910 t.Fatalf("Index: %d failed Error: %s", i, errs)
10911 }
10912
10913 errs = validate.Struct(s)
10914
10915 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
10916 t.Fatalf("Index: %d failed Error: %s", i, errs)
10917 }
10918 }
10919 }
10920
10921 func TestEndsWithValidation(t *testing.T) {
10922 tests := []struct {
10923 Value string `validate:"endswith=(/^ヮ^)/*:・゚✧"`
10924 Tag string
10925 ExpectedNil bool
10926 }{
10927 {Value: "glitter (/^ヮ^)/*:・゚✧", Tag: "endswith=(/^ヮ^)/*:・゚✧", ExpectedNil: true},
10928 {Value: "(/^ヮ^)/*:・゚✧ glitter", Tag: "endswith=(/^ヮ^)/*:・゚✧", ExpectedNil: false},
10929 }
10930
10931 validate := New()
10932
10933 for i, s := range tests {
10934 errs := validate.Var(s.Value, s.Tag)
10935
10936 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
10937 t.Fatalf("Index: %d failed Error: %s", i, errs)
10938 }
10939
10940 errs = validate.Struct(s)
10941
10942 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
10943 t.Fatalf("Index: %d failed Error: %s", i, errs)
10944 }
10945 }
10946 }
10947
10948 func TestRequiredIf(t *testing.T) {
10949 type Inner struct {
10950 Field *string
10951 }
10952
10953 fieldVal := "test"
10954 test := struct {
10955 Inner *Inner
10956 FieldE string `validate:"omitempty" json:"field_e"`
10957 FieldER string `validate:"required_if=FieldE test" json:"field_er"`
10958 Field1 string `validate:"omitempty" json:"field_1"`
10959 Field2 *string `validate:"required_if=Field1 test" json:"field_2"`
10960 Field3 map[string]string `validate:"required_if=Field2 test" json:"field_3"`
10961 Field4 interface{} `validate:"required_if=Field3 1" json:"field_4"`
10962 Field5 int `validate:"required_if=Inner.Field test" json:"field_5"`
10963 Field6 uint `validate:"required_if=Field5 1" json:"field_6"`
10964 Field7 float32 `validate:"required_if=Field6 1" json:"field_7"`
10965 Field8 float64 `validate:"required_if=Field7 1.0" json:"field_8"`
10966 Field9 Inner `validate:"required_if=Field1 test" json:"field_9"`
10967 Field10 *Inner `validate:"required_if=Field1 test" json:"field_10"`
10968 }{
10969 Inner: &Inner{Field: &fieldVal},
10970 Field2: &fieldVal,
10971 Field3: map[string]string{"key": "val"},
10972 Field4: "test",
10973 Field5: 2,
10974 }
10975
10976 validate := New()
10977
10978 errs := validate.Struct(test)
10979 Equal(t, errs, nil)
10980
10981 test2 := struct {
10982 Inner *Inner
10983 Inner2 *Inner
10984 FieldE string `validate:"omitempty" json:"field_e"`
10985 FieldER string `validate:"required_if=FieldE test" json:"field_er"`
10986 Field1 string `validate:"omitempty" json:"field_1"`
10987 Field2 *string `validate:"required_if=Field1 test" json:"field_2"`
10988 Field3 map[string]string `validate:"required_if=Field2 test" json:"field_3"`
10989 Field4 interface{} `validate:"required_if=Field2 test" json:"field_4"`
10990 Field5 string `validate:"required_if=Field3 1" json:"field_5"`
10991 Field6 string `validate:"required_if=Inner.Field test" json:"field_6"`
10992 Field7 string `validate:"required_if=Inner2.Field test" json:"field_7"`
10993 Field8 Inner `validate:"required_if=Field2 test" json:"field_8"`
10994 Field9 *Inner `validate:"required_if=Field2 test" json:"field_9"`
10995 }{
10996 Inner: &Inner{Field: &fieldVal},
10997 Field2: &fieldVal,
10998 }
10999
11000 errs = validate.Struct(test2)
11001 NotEqual(t, errs, nil)
11002
11003 ve := errs.(ValidationErrors)
11004 Equal(t, len(ve), 5)
11005 AssertError(t, errs, "Field3", "Field3", "Field3", "Field3", "required_if")
11006 AssertError(t, errs, "Field4", "Field4", "Field4", "Field4", "required_if")
11007 AssertError(t, errs, "Field6", "Field6", "Field6", "Field6", "required_if")
11008 AssertError(t, errs, "Field8", "Field8", "Field8", "Field8", "required_if")
11009 AssertError(t, errs, "Field9", "Field9", "Field9", "Field9", "required_if")
11010
11011 defer func() {
11012 if r := recover(); r == nil {
11013 t.Errorf("test3 should have panicked!")
11014 }
11015 }()
11016
11017 test3 := struct {
11018 Inner *Inner
11019 Field1 string `validate:"required_if=Inner.Field" json:"field_1"`
11020 }{
11021 Inner: &Inner{Field: &fieldVal},
11022 }
11023 _ = validate.Struct(test3)
11024 }
11025
11026 func TestRequiredUnless(t *testing.T) {
11027 type Inner struct {
11028 Field *string
11029 }
11030
11031 fieldVal := "test"
11032 test := struct {
11033 Inner *Inner
11034 FieldE string `validate:"omitempty" json:"field_e"`
11035 FieldER string `validate:"required_unless=FieldE test" json:"field_er"`
11036 Field1 string `validate:"omitempty" json:"field_1"`
11037 Field2 *string `validate:"required_unless=Field1 test" json:"field_2"`
11038 Field3 map[string]string `validate:"required_unless=Field2 test" json:"field_3"`
11039 Field4 interface{} `validate:"required_unless=Field3 1" json:"field_4"`
11040 Field5 int `validate:"required_unless=Inner.Field test" json:"field_5"`
11041 Field6 uint `validate:"required_unless=Field5 2" json:"field_6"`
11042 Field7 float32 `validate:"required_unless=Field6 0" json:"field_7"`
11043 Field8 float64 `validate:"required_unless=Field7 0.0" json:"field_8"`
11044 Field9 bool `validate:"omitempty" json:"field_9"`
11045 Field10 string `validate:"required_unless=Field9 true" json:"field_10"`
11046 Field11 Inner `validate:"required_unless=Field9 true" json:"field_11"`
11047 Field12 *Inner `validate:"required_unless=Field9 true" json:"field_12"`
11048 }{
11049 FieldE: "test",
11050 Field2: &fieldVal,
11051 Field3: map[string]string{"key": "val"},
11052 Field4: "test",
11053 Field5: 2,
11054 Field9: true,
11055 }
11056
11057 validate := New()
11058
11059 errs := validate.Struct(test)
11060 Equal(t, errs, nil)
11061
11062 test2 := struct {
11063 Inner *Inner
11064 Inner2 *Inner
11065 FieldE string `validate:"omitempty" json:"field_e"`
11066 FieldER string `validate:"required_unless=FieldE test" json:"field_er"`
11067 Field1 string `validate:"omitempty" json:"field_1"`
11068 Field2 *string `validate:"required_unless=Field1 test" json:"field_2"`
11069 Field3 map[string]string `validate:"required_unless=Field2 test" json:"field_3"`
11070 Field4 interface{} `validate:"required_unless=Field2 test" json:"field_4"`
11071 Field5 string `validate:"required_unless=Field3 0" json:"field_5"`
11072 Field6 string `validate:"required_unless=Inner.Field test" json:"field_6"`
11073 Field7 string `validate:"required_unless=Inner2.Field test" json:"field_7"`
11074 Field8 bool `validate:"omitempty" json:"field_8"`
11075 Field9 string `validate:"required_unless=Field8 true" json:"field_9"`
11076 Field10 Inner `validate:"required_unless=Field9 true" json:"field_10"`
11077 Field11 *Inner `validate:"required_unless=Field9 true" json:"field_11"`
11078 }{
11079 Inner: &Inner{Field: &fieldVal},
11080 FieldE: "test",
11081 Field1: "test",
11082 }
11083
11084 errs = validate.Struct(test2)
11085 NotEqual(t, errs, nil)
11086
11087 ve := errs.(ValidationErrors)
11088 Equal(t, len(ve), 6)
11089 AssertError(t, errs, "Field3", "Field3", "Field3", "Field3", "required_unless")
11090 AssertError(t, errs, "Field4", "Field4", "Field4", "Field4", "required_unless")
11091 AssertError(t, errs, "Field7", "Field7", "Field7", "Field7", "required_unless")
11092 AssertError(t, errs, "Field9", "Field9", "Field9", "Field9", "required_unless")
11093 AssertError(t, errs, "Field10", "Field10", "Field10", "Field10", "required_unless")
11094 AssertError(t, errs, "Field11", "Field11", "Field11", "Field11", "required_unless")
11095
11096 defer func() {
11097 if r := recover(); r == nil {
11098 t.Errorf("test3 should have panicked!")
11099 }
11100 }()
11101
11102 test3 := struct {
11103 Inner *Inner
11104 Field1 string `validate:"required_unless=Inner.Field" json:"field_1"`
11105 }{
11106 Inner: &Inner{Field: &fieldVal},
11107 }
11108 _ = validate.Struct(test3)
11109 }
11110
11111 func TestSkipUnless(t *testing.T) {
11112 type Inner struct {
11113 Field *string
11114 }
11115
11116 fieldVal := "test1"
11117 test := struct {
11118 Inner *Inner
11119 FieldE string `validate:"omitempty" json:"field_e"`
11120 FieldER string `validate:"skip_unless=FieldE test" json:"field_er"`
11121 Field1 string `validate:"omitempty" json:"field_1"`
11122 Field2 *string `validate:"skip_unless=Field1 test" json:"field_2"`
11123 Field3 map[string]string `validate:"skip_unless=Field2 test" json:"field_3"`
11124 Field4 interface{} `validate:"skip_unless=Field3 1" json:"field_4"`
11125 Field5 int `validate:"skip_unless=Inner.Field test" json:"field_5"`
11126 Field6 uint `validate:"skip_unless=Field5 2" json:"field_6"`
11127 Field7 float32 `validate:"skip_unless=Field6 1" json:"field_7"`
11128 Field8 float64 `validate:"skip_unless=Field7 1.0" json:"field_8"`
11129 Field9 bool `validate:"omitempty" json:"field_9"`
11130 Field10 string `validate:"skip_unless=Field9 false" json:"field_10"`
11131 Field11 Inner `validate:"skip_unless=Field9 false" json:"field_11"`
11132 Field12 *Inner `validate:"skip_unless=Field9 false" json:"field_12"`
11133 }{
11134 FieldE: "test1",
11135 Field2: &fieldVal,
11136 Field3: map[string]string{"key": "val"},
11137 Field4: "test",
11138 Field5: 3,
11139 Field9: true,
11140 }
11141
11142 validate := New()
11143
11144 errs := validate.Struct(test)
11145 Equal(t, errs, nil)
11146
11147 test2 := struct {
11148 Inner *Inner
11149 Inner2 *Inner
11150 FieldE string `validate:"omitempty" json:"field_e"`
11151 FieldER string `validate:"skip_unless=FieldE test" json:"field_er"`
11152 Field1 string `validate:"omitempty" json:"field_1"`
11153 Field2 *string `validate:"skip_unless=Field1 test" json:"field_2"`
11154 Field3 map[string]string `validate:"skip_unless=Field2 test" json:"field_3"`
11155 Field4 interface{} `validate:"skip_unless=Field2 test" json:"field_4"`
11156 Field5 string `validate:"skip_unless=Field3 0" json:"field_5"`
11157 Field6 string `validate:"skip_unless=Inner.Field test" json:"field_6"`
11158 Field7 string `validate:"skip_unless=Inner2.Field test" json:"field_7"`
11159 Field8 bool `validate:"omitempty" json:"field_8"`
11160 Field9 string `validate:"skip_unless=Field8 true" json:"field_9"`
11161 Field10 Inner `validate:"skip_unless=Field8 false" json:"field_10"`
11162 Field11 *Inner `validate:"skip_unless=Field8 false" json:"field_11"`
11163 }{
11164 Inner: &Inner{Field: &fieldVal},
11165 FieldE: "test1",
11166 Field1: "test1",
11167 }
11168
11169 errs = validate.Struct(test2)
11170 NotEqual(t, errs, nil)
11171
11172 ve := errs.(ValidationErrors)
11173 Equal(t, len(ve), 3)
11174 AssertError(t, errs, "Field5", "Field5", "Field5", "Field5", "skip_unless")
11175 AssertError(t, errs, "Field10", "Field10", "Field10", "Field10", "skip_unless")
11176 AssertError(t, errs, "Field11", "Field11", "Field11", "Field11", "skip_unless")
11177
11178 test3 := struct {
11179 Inner *Inner
11180 Field1 string `validate:"skip_unless=Inner.Field" json:"field_1"`
11181 }{
11182 Inner: &Inner{Field: &fieldVal},
11183 }
11184 PanicMatches(t, func() {
11185 _ = validate.Struct(test3)
11186 }, "Bad param number for skip_unless Field1")
11187
11188 test4 := struct {
11189 Inner *Inner
11190 Field1 string `validate:"skip_unless=Inner.Field test1" json:"field_1"`
11191 }{
11192 Inner: &Inner{Field: &fieldVal},
11193 }
11194 errs = validate.Struct(test4)
11195 NotEqual(t, errs, nil)
11196
11197 ve = errs.(ValidationErrors)
11198 Equal(t, len(ve), 1)
11199 AssertError(t, errs, "Field1", "Field1", "Field1", "Field1", "skip_unless")
11200 }
11201
11202 func TestRequiredWith(t *testing.T) {
11203 type Inner struct {
11204 Field *string
11205 }
11206
11207 fieldVal := "test"
11208 test := struct {
11209 Inner *Inner
11210 FieldE string `validate:"omitempty" json:"field_e"`
11211 FieldER string `validate:"required_with=FieldE" json:"field_er"`
11212 Field1 string `validate:"omitempty" json:"field_1"`
11213 Field2 *string `validate:"required_with=Field1" json:"field_2"`
11214 Field3 map[string]string `validate:"required_with=Field2" json:"field_3"`
11215 Field4 interface{} `validate:"required_with=Field3" json:"field_4"`
11216 Field5 string `validate:"required_with=Field" json:"field_5"`
11217 Field6 Inner `validate:"required_with=Field2" json:"field_6"`
11218 Field7 *Inner `validate:"required_with=Field2" json:"field_7"`
11219 }{
11220 Inner: &Inner{Field: &fieldVal},
11221 Field2: &fieldVal,
11222 Field3: map[string]string{"key": "val"},
11223 Field4: "test",
11224 Field5: "test",
11225 Field6: Inner{Field: &fieldVal},
11226 Field7: &Inner{Field: &fieldVal},
11227 }
11228
11229 validate := New()
11230
11231 errs := validate.Struct(test)
11232 Equal(t, errs, nil)
11233
11234 test2 := struct {
11235 Inner *Inner
11236 Inner2 *Inner
11237 FieldE string `validate:"omitempty" json:"field_e"`
11238 FieldER string `validate:"required_with=FieldE" json:"field_er"`
11239 Field1 string `validate:"omitempty" json:"field_1"`
11240 Field2 *string `validate:"required_with=Field1" json:"field_2"`
11241 Field3 map[string]string `validate:"required_with=Field2" json:"field_3"`
11242 Field4 interface{} `validate:"required_with=Field2" json:"field_4"`
11243 Field5 string `validate:"required_with=Field3" json:"field_5"`
11244 Field6 string `validate:"required_with=Inner.Field" json:"field_6"`
11245 Field7 string `validate:"required_with=Inner2.Field" json:"field_7"`
11246 Field8 Inner `validate:"required_with=Field2" json:"field_8"`
11247 Field9 *Inner `validate:"required_with=Field2" json:"field_9"`
11248 }{
11249 Inner: &Inner{Field: &fieldVal},
11250 Field2: &fieldVal,
11251 }
11252
11253 errs = validate.Struct(test2)
11254 NotEqual(t, errs, nil)
11255
11256 ve := errs.(ValidationErrors)
11257 Equal(t, len(ve), 5)
11258 AssertError(t, errs, "Field3", "Field3", "Field3", "Field3", "required_with")
11259 AssertError(t, errs, "Field4", "Field4", "Field4", "Field4", "required_with")
11260 AssertError(t, errs, "Field6", "Field6", "Field6", "Field6", "required_with")
11261 AssertError(t, errs, "Field8", "Field8", "Field8", "Field8", "required_with")
11262 AssertError(t, errs, "Field9", "Field9", "Field9", "Field9", "required_with")
11263 }
11264
11265 func TestExcludedWith(t *testing.T) {
11266 type Inner struct {
11267 FieldE string
11268 Field *string
11269 }
11270
11271 fieldVal := "test"
11272 test := struct {
11273 Inner *Inner
11274 Inner2 *Inner
11275 Field string `validate:"omitempty" json:"field"`
11276 FieldE string `validate:"omitempty" json:"field_e"`
11277 Field1 string `validate:"excluded_with=FieldE" json:"field_1"`
11278 Field2 *string `validate:"excluded_with=FieldE" json:"field_2"`
11279 Field3 map[string]string `validate:"excluded_with=FieldE" json:"field_3"`
11280 Field4 interface{} `validate:"excluded_with=FieldE" json:"field_4"`
11281 Field5 string `validate:"excluded_with=Inner.FieldE" json:"field_5"`
11282 Field6 string `validate:"excluded_with=Inner2.FieldE" json:"field_6"`
11283 Field7 Inner `validate:"excluded_with=FieldE" json:"field_7"`
11284 Field8 *Inner `validate:"excluded_with=FieldE" json:"field_8"`
11285 }{
11286 Inner: &Inner{Field: &fieldVal},
11287 Field1: fieldVal,
11288 Field2: &fieldVal,
11289 Field3: map[string]string{"key": "val"},
11290 Field4: "test",
11291 Field5: "test",
11292 Field6: "test",
11293 }
11294
11295 validate := New()
11296
11297 errs := validate.Struct(test)
11298 Equal(t, errs, nil)
11299
11300 test2 := struct {
11301 Inner *Inner
11302 Inner2 *Inner
11303 Field string `validate:"omitempty" json:"field"`
11304 FieldE string `validate:"omitempty" json:"field_e"`
11305 Field1 string `validate:"excluded_with=Field" json:"field_1"`
11306 Field2 *string `validate:"excluded_with=Field" json:"field_2"`
11307 Field3 map[string]string `validate:"excluded_with=Field" json:"field_3"`
11308 Field4 interface{} `validate:"excluded_with=Field" json:"field_4"`
11309 Field5 string `validate:"excluded_with=Inner.Field" json:"field_5"`
11310 Field6 string `validate:"excluded_with=Inner2.Field" json:"field_6"`
11311 Field7 Inner `validate:"excluded_with=Field" json:"field_7"`
11312 Field8 *Inner `validate:"excluded_with=Field" json:"field_8"`
11313 }{
11314 Inner: &Inner{Field: &fieldVal},
11315 Field: "populated",
11316 Field1: fieldVal,
11317 Field2: &fieldVal,
11318 Field3: map[string]string{"key": "val"},
11319 Field4: "test",
11320 Field5: "test",
11321 Field6: "test",
11322 Field7: Inner{FieldE: "potato"},
11323 Field8: &Inner{FieldE: "potato"},
11324 }
11325
11326 errs = validate.Struct(test2)
11327 NotEqual(t, errs, nil)
11328
11329 ve := errs.(ValidationErrors)
11330 Equal(t, len(ve), 7)
11331 for i := 1; i <= 7; i++ {
11332
11333 if i > 5 {
11334 i++
11335 }
11336 name := fmt.Sprintf("Field%d", i)
11337 AssertError(t, errs, name, name, name, name, "excluded_with")
11338 }
11339
11340 test3 := struct {
11341 Inner *Inner
11342 Inner2 *Inner
11343 Field string `validate:"omitempty" json:"field"`
11344 FieldE string `validate:"omitempty" json:"field_e"`
11345 Field1 string `validate:"excluded_with=FieldE" json:"field_1"`
11346 Field2 *string `validate:"excluded_with=FieldE" json:"field_2"`
11347 Field3 map[string]string `validate:"excluded_with=FieldE" json:"field_3"`
11348 Field4 interface{} `validate:"excluded_with=FieldE" json:"field_4"`
11349 Field5 string `validate:"excluded_with=Inner.FieldE" json:"field_5"`
11350 Field6 string `validate:"excluded_with=Inner2.FieldE" json:"field_6"`
11351 Field7 Inner `validate:"excluded_with=FieldE" json:"field_7"`
11352 Field8 *Inner `validate:"excluded_with=FieldE" json:"field_8"`
11353 }{
11354 Inner: &Inner{FieldE: "populated"},
11355 Inner2: &Inner{FieldE: "populated"},
11356 FieldE: "populated",
11357 }
11358
11359 validate = New()
11360
11361 errs = validate.Struct(test3)
11362 Equal(t, errs, nil)
11363 }
11364
11365 func TestExcludedWithout(t *testing.T) {
11366 type Inner struct {
11367 FieldE string
11368 Field *string
11369 }
11370
11371 fieldVal := "test"
11372 test := struct {
11373 Inner *Inner
11374 Inner2 *Inner
11375 Field string `validate:"omitempty" json:"field"`
11376 FieldE string `validate:"omitempty" json:"field_e"`
11377 Field1 string `validate:"excluded_without=Field" json:"field_1"`
11378 Field2 *string `validate:"excluded_without=Field" json:"field_2"`
11379 Field3 map[string]string `validate:"excluded_without=Field" json:"field_3"`
11380 Field4 interface{} `validate:"excluded_without=Field" json:"field_4"`
11381 Field5 string `validate:"excluded_without=Inner.Field" json:"field_5"`
11382 Field6 Inner `validate:"excluded_without=Field" json:"field_6"`
11383 Field7 *Inner `validate:"excluded_without=Field" json:"field_7"`
11384 }{
11385 Inner: &Inner{Field: &fieldVal},
11386 Field: "populated",
11387 Field1: fieldVal,
11388 Field2: &fieldVal,
11389 Field3: map[string]string{"key": "val"},
11390 Field4: "test",
11391 Field5: "test",
11392 Field6: Inner{FieldE: "potato"},
11393 Field7: &Inner{FieldE: "potato"},
11394 }
11395
11396 validate := New()
11397
11398 errs := validate.Struct(test)
11399 Equal(t, errs, nil)
11400
11401 test2 := struct {
11402 Inner *Inner
11403 Inner2 *Inner
11404 Field string `validate:"omitempty" json:"field"`
11405 FieldE string `validate:"omitempty" json:"field_e"`
11406 Field1 string `validate:"excluded_without=FieldE" json:"field_1"`
11407 Field2 *string `validate:"excluded_without=FieldE" json:"field_2"`
11408 Field3 map[string]string `validate:"excluded_without=FieldE" json:"field_3"`
11409 Field4 interface{} `validate:"excluded_without=FieldE" json:"field_4"`
11410 Field5 string `validate:"excluded_without=Inner.FieldE" json:"field_5"`
11411 Field6 string `validate:"excluded_without=Inner2.FieldE" json:"field_6"`
11412 Field7 Inner `validate:"excluded_without=FieldE" json:"field_7"`
11413 Field8 *Inner `validate:"excluded_without=FieldE" json:"field_8"`
11414 }{
11415 Inner: &Inner{Field: &fieldVal},
11416 Field1: fieldVal,
11417 Field2: &fieldVal,
11418 Field3: map[string]string{"key": "val"},
11419 Field4: "test",
11420 Field5: "test",
11421 Field6: "test",
11422 Field7: Inner{FieldE: "potato"},
11423 Field8: &Inner{FieldE: "potato"},
11424 }
11425
11426 errs = validate.Struct(test2)
11427 NotEqual(t, errs, nil)
11428
11429 ve := errs.(ValidationErrors)
11430 Equal(t, len(ve), 8)
11431 for i := 1; i <= 8; i++ {
11432 name := fmt.Sprintf("Field%d", i)
11433 AssertError(t, errs, name, name, name, name, "excluded_without")
11434 }
11435
11436 test3 := struct {
11437 Inner *Inner
11438 Inner2 *Inner
11439 Field string `validate:"omitempty" json:"field"`
11440 FieldE string `validate:"omitempty" json:"field_e"`
11441 Field1 string `validate:"excluded_without=Field" json:"field_1"`
11442 Field2 *string `validate:"excluded_without=Field" json:"field_2"`
11443 Field3 map[string]string `validate:"excluded_without=Field" json:"field_3"`
11444 Field4 interface{} `validate:"excluded_without=Field" json:"field_4"`
11445 Field5 string `validate:"excluded_without=Inner.Field" json:"field_5"`
11446 Field6 Inner `validate:"excluded_without=Field" json:"field_6"`
11447 Field7 *Inner `validate:"excluded_without=Field" json:"field_7"`
11448 }{
11449 Inner: &Inner{Field: &fieldVal},
11450 Field: "populated",
11451 }
11452
11453 validate = New()
11454
11455 errs = validate.Struct(test3)
11456 Equal(t, errs, nil)
11457 }
11458
11459 func TestExcludedWithAll(t *testing.T) {
11460 type Inner struct {
11461 FieldE string
11462 Field *string
11463 }
11464
11465 fieldVal := "test"
11466 test := struct {
11467 Inner *Inner
11468 Inner2 *Inner
11469 Field string `validate:"omitempty" json:"field"`
11470 FieldE string `validate:"omitempty" json:"field_e"`
11471 Field1 string `validate:"excluded_with_all=FieldE Field" json:"field_1"`
11472 Field2 *string `validate:"excluded_with_all=FieldE Field" json:"field_2"`
11473 Field3 map[string]string `validate:"excluded_with_all=FieldE Field" json:"field_3"`
11474 Field4 interface{} `validate:"excluded_with_all=FieldE Field" json:"field_4"`
11475 Field5 string `validate:"excluded_with_all=Inner.FieldE" json:"field_5"`
11476 Field6 string `validate:"excluded_with_all=Inner2.FieldE" json:"field_6"`
11477 Field7 Inner `validate:"excluded_with_all=FieldE Field" json:"field_7"`
11478 Field8 *Inner `validate:"excluded_with_all=FieldE Field" json:"field_8"`
11479 }{
11480 Inner: &Inner{Field: &fieldVal},
11481 Field: fieldVal,
11482 Field1: fieldVal,
11483 Field2: &fieldVal,
11484 Field3: map[string]string{"key": "val"},
11485 Field4: "test",
11486 Field5: "test",
11487 Field6: "test",
11488 Field7: Inner{FieldE: "potato"},
11489 Field8: &Inner{FieldE: "potato"},
11490 }
11491
11492 validate := New()
11493
11494 errs := validate.Struct(test)
11495 Equal(t, errs, nil)
11496
11497 test2 := struct {
11498 Inner *Inner
11499 Inner2 *Inner
11500 Field string `validate:"omitempty" json:"field"`
11501 FieldE string `validate:"omitempty" json:"field_e"`
11502 Field1 string `validate:"excluded_with_all=Field FieldE" json:"field_1"`
11503 Field2 *string `validate:"excluded_with_all=Field FieldE" json:"field_2"`
11504 Field3 map[string]string `validate:"excluded_with_all=Field FieldE" json:"field_3"`
11505 Field4 interface{} `validate:"excluded_with_all=Field FieldE" json:"field_4"`
11506 Field5 string `validate:"excluded_with_all=Inner.Field" json:"field_5"`
11507 Field6 string `validate:"excluded_with_all=Inner2.Field" json:"field_6"`
11508 Field7 Inner `validate:"excluded_with_all=Field FieldE" json:"field_7"`
11509 Field8 *Inner `validate:"excluded_with_all=Field FieldE" json:"field_8"`
11510 }{
11511 Inner: &Inner{Field: &fieldVal},
11512 Field: "populated",
11513 FieldE: "populated",
11514 Field1: fieldVal,
11515 Field2: &fieldVal,
11516 Field3: map[string]string{"key": "val"},
11517 Field4: "test",
11518 Field5: "test",
11519 Field6: "test",
11520 Field7: Inner{FieldE: "potato"},
11521 Field8: &Inner{FieldE: "potato"},
11522 }
11523
11524 errs = validate.Struct(test2)
11525 NotEqual(t, errs, nil)
11526
11527 ve := errs.(ValidationErrors)
11528 Equal(t, len(ve), 7)
11529 for i := 1; i <= 7; i++ {
11530
11531 if i > 5 {
11532 i++
11533 }
11534 name := fmt.Sprintf("Field%d", i)
11535 AssertError(t, errs, name, name, name, name, "excluded_with_all")
11536 }
11537
11538 test3 := struct {
11539 Inner *Inner
11540 Inner2 *Inner
11541 Field string `validate:"omitempty" json:"field"`
11542 FieldE string `validate:"omitempty" json:"field_e"`
11543 Field1 string `validate:"excluded_with_all=FieldE Field" json:"field_1"`
11544 Field2 *string `validate:"excluded_with_all=FieldE Field" json:"field_2"`
11545 Field3 map[string]string `validate:"excluded_with_all=FieldE Field" json:"field_3"`
11546 Field4 interface{} `validate:"excluded_with_all=FieldE Field" json:"field_4"`
11547 Field5 string `validate:"excluded_with_all=Inner.FieldE" json:"field_5"`
11548 Field6 string `validate:"excluded_with_all=Inner2.FieldE" json:"field_6"`
11549 Field7 Inner `validate:"excluded_with_all=Field FieldE" json:"field_7"`
11550 Field8 *Inner `validate:"excluded_with_all=Field FieldE" json:"field_8"`
11551 }{
11552 Inner: &Inner{FieldE: "populated"},
11553 Inner2: &Inner{FieldE: "populated"},
11554 Field: "populated",
11555 FieldE: "populated",
11556 }
11557
11558 validate = New()
11559
11560 errs = validate.Struct(test3)
11561 Equal(t, errs, nil)
11562 }
11563
11564 func TestExcludedWithoutAll(t *testing.T) {
11565 type Inner struct {
11566 FieldE string
11567 Field *string
11568 }
11569
11570 fieldVal := "test"
11571 test := struct {
11572 Inner *Inner
11573 Inner2 *Inner
11574 Field string `validate:"omitempty" json:"field"`
11575 FieldE string `validate:"omitempty" json:"field_e"`
11576 Field1 string `validate:"excluded_without_all=Field FieldE" json:"field_1"`
11577 Field2 *string `validate:"excluded_without_all=Field FieldE" json:"field_2"`
11578 Field3 map[string]string `validate:"excluded_without_all=Field FieldE" json:"field_3"`
11579 Field4 interface{} `validate:"excluded_without_all=Field FieldE" json:"field_4"`
11580 Field5 string `validate:"excluded_without_all=Inner.Field Inner2.Field" json:"field_5"`
11581 Field6 Inner `validate:"excluded_without_all=Field FieldE" json:"field_6"`
11582 Field7 *Inner `validate:"excluded_without_all=Field FieldE" json:"field_7"`
11583 }{
11584 Inner: &Inner{Field: &fieldVal},
11585 Inner2: &Inner{Field: &fieldVal},
11586 Field: "populated",
11587 Field1: fieldVal,
11588 Field2: &fieldVal,
11589 Field3: map[string]string{"key": "val"},
11590 Field4: "test",
11591 Field5: "test",
11592 Field6: Inner{FieldE: "potato"},
11593 Field7: &Inner{FieldE: "potato"},
11594 }
11595
11596 validate := New()
11597
11598 errs := validate.Struct(test)
11599 Equal(t, errs, nil)
11600
11601 test2 := struct {
11602 Inner *Inner
11603 Inner2 *Inner
11604 Field string `validate:"omitempty" json:"field"`
11605 FieldE string `validate:"omitempty" json:"field_e"`
11606 Field1 string `validate:"excluded_without_all=FieldE Field" json:"field_1"`
11607 Field2 *string `validate:"excluded_without_all=FieldE Field" json:"field_2"`
11608 Field3 map[string]string `validate:"excluded_without_all=FieldE Field" json:"field_3"`
11609 Field4 interface{} `validate:"excluded_without_all=FieldE Field" json:"field_4"`
11610 Field5 string `validate:"excluded_without_all=Inner.FieldE" json:"field_5"`
11611 Field6 string `validate:"excluded_without_all=Inner2.FieldE" json:"field_6"`
11612 Field7 Inner `validate:"excluded_without_all=Field FieldE" json:"field_7"`
11613 Field8 *Inner `validate:"excluded_without_all=Field FieldE" json:"field_8"`
11614 }{
11615 Inner: &Inner{Field: &fieldVal},
11616 Field1: fieldVal,
11617 Field2: &fieldVal,
11618 Field3: map[string]string{"key": "val"},
11619 Field4: "test",
11620 Field5: "test",
11621 Field6: "test",
11622 Field7: Inner{FieldE: "potato"},
11623 Field8: &Inner{FieldE: "potato"},
11624 }
11625
11626 errs = validate.Struct(test2)
11627 NotEqual(t, errs, nil)
11628
11629 ve := errs.(ValidationErrors)
11630 Equal(t, len(ve), 8)
11631 for i := 1; i <= 8; i++ {
11632 name := fmt.Sprintf("Field%d", i)
11633 AssertError(t, errs, name, name, name, name, "excluded_without_all")
11634 }
11635
11636 test3 := struct {
11637 Inner *Inner
11638 Inner2 *Inner
11639 Field string `validate:"omitempty" json:"field"`
11640 FieldE string `validate:"omitempty" json:"field_e"`
11641 Field1 string `validate:"excluded_without_all=Field FieldE" json:"field_1"`
11642 Field2 *string `validate:"excluded_without_all=Field FieldE" json:"field_2"`
11643 Field3 map[string]string `validate:"excluded_without_all=Field FieldE" json:"field_3"`
11644 Field4 interface{} `validate:"excluded_without_all=Field FieldE" json:"field_4"`
11645 Field5 string `validate:"excluded_without_all=Inner.Field Inner2.Field" json:"field_5"`
11646 Field6 Inner `validate:"excluded_without_all=Field FieldE" json:"field_6"`
11647 Field7 *Inner `validate:"excluded_without_all=Field FieldE" json:"field_7"`
11648 }{
11649 Inner: &Inner{Field: &fieldVal},
11650 Inner2: &Inner{Field: &fieldVal},
11651 Field: "populated",
11652 FieldE: "populated",
11653 }
11654
11655 validate = New()
11656
11657 errs = validate.Struct(test3)
11658 Equal(t, errs, nil)
11659 }
11660
11661 func TestRequiredWithAll(t *testing.T) {
11662 type Inner struct {
11663 Field *string
11664 }
11665
11666 fieldVal := "test"
11667 test := struct {
11668 Inner *Inner
11669 FieldE string `validate:"omitempty" json:"field_e"`
11670 FieldER string `validate:"required_with_all=FieldE" json:"field_er"`
11671 Field1 string `validate:"omitempty" json:"field_1"`
11672 Field2 *string `validate:"required_with_all=Field1" json:"field_2"`
11673 Field3 map[string]string `validate:"required_with_all=Field2" json:"field_3"`
11674 Field4 interface{} `validate:"required_with_all=Field3" json:"field_4"`
11675 Field5 string `validate:"required_with_all=Inner.Field" json:"field_5"`
11676 Field6 Inner `validate:"required_with_all=Field1 Field2" json:"field_6"`
11677 Field7 *Inner `validate:"required_with_all=Field1 Field2" json:"field_7"`
11678 }{
11679 Inner: &Inner{Field: &fieldVal},
11680 Field1: "test_field1",
11681 Field2: &fieldVal,
11682 Field3: map[string]string{"key": "val"},
11683 Field4: "test",
11684 Field5: "test",
11685 Field6: Inner{Field: &fieldVal},
11686 Field7: &Inner{Field: &fieldVal},
11687 }
11688
11689 validate := New()
11690
11691 errs := validate.Struct(test)
11692 Equal(t, errs, nil)
11693
11694 test2 := struct {
11695 Inner *Inner
11696 Inner2 *Inner
11697 FieldE string `validate:"omitempty" json:"field_e"`
11698 FieldER string `validate:"required_with_all=FieldE" json:"field_er"`
11699 Field1 string `validate:"omitempty" json:"field_1"`
11700 Field2 *string `validate:"required_with_all=Field1" json:"field_2"`
11701 Field3 map[string]string `validate:"required_with_all=Field2" json:"field_3"`
11702 Field4 interface{} `validate:"required_with_all=Field1 FieldE" json:"field_4"`
11703 Field5 string `validate:"required_with_all=Inner.Field Field2" json:"field_5"`
11704 Field6 string `validate:"required_with_all=Inner2.Field Field2" json:"field_6"`
11705 Field7 Inner `validate:"required_with_all=Inner.Field Field2" json:"field_7"`
11706 Field8 *Inner `validate:"required_with_all=Inner.Field Field2" json:"field_8"`
11707 }{
11708 Inner: &Inner{Field: &fieldVal},
11709 Field2: &fieldVal,
11710 }
11711
11712 errs = validate.Struct(test2)
11713 NotEqual(t, errs, nil)
11714
11715 ve := errs.(ValidationErrors)
11716 Equal(t, len(ve), 4)
11717 AssertError(t, errs, "Field3", "Field3", "Field3", "Field3", "required_with_all")
11718 AssertError(t, errs, "Field5", "Field5", "Field5", "Field5", "required_with_all")
11719 AssertError(t, errs, "Field7", "Field7", "Field7", "Field7", "required_with_all")
11720 AssertError(t, errs, "Field8", "Field8", "Field8", "Field8", "required_with_all")
11721 }
11722
11723 func TestRequiredWithout(t *testing.T) {
11724 type Inner struct {
11725 Field *string
11726 }
11727
11728 fieldVal := "test"
11729 test := struct {
11730 Inner *Inner
11731 Field1 string `validate:"omitempty" json:"field_1"`
11732 Field2 *string `validate:"required_without=Field1" json:"field_2"`
11733 Field3 map[string]string `validate:"required_without=Field2" json:"field_3"`
11734 Field4 interface{} `validate:"required_without=Field3" json:"field_4"`
11735 Field5 string `validate:"required_without=Field3" json:"field_5"`
11736 Field6 Inner `validate:"required_without=Field1" json:"field_6"`
11737 Field7 *Inner `validate:"required_without=Field1" json:"field_7"`
11738 }{
11739 Inner: &Inner{Field: &fieldVal},
11740 Field2: &fieldVal,
11741 Field3: map[string]string{"key": "val"},
11742 Field4: "test",
11743 Field5: "test",
11744 Field6: Inner{Field: &fieldVal},
11745 Field7: &Inner{Field: &fieldVal},
11746 }
11747
11748 validate := New()
11749
11750 errs := validate.Struct(test)
11751 Equal(t, errs, nil)
11752
11753 test2 := struct {
11754 Inner *Inner
11755 Inner2 *Inner
11756 Field1 string `json:"field_1"`
11757 Field2 *string `validate:"required_without=Field1" json:"field_2"`
11758 Field3 map[string]string `validate:"required_without=Field2" json:"field_3"`
11759 Field4 interface{} `validate:"required_without=Field3" json:"field_4"`
11760 Field5 string `validate:"required_without=Field3" json:"field_5"`
11761 Field6 string `validate:"required_without=Field1" json:"field_6"`
11762 Field7 string `validate:"required_without=Inner.Field" json:"field_7"`
11763 Field8 string `validate:"required_without=Inner.Field" json:"field_8"`
11764 Field9 Inner `validate:"required_without=Field1" json:"field_9"`
11765 Field10 *Inner `validate:"required_without=Field1" json:"field_10"`
11766 }{
11767 Inner: &Inner{},
11768 Field3: map[string]string{"key": "val"},
11769 Field4: "test",
11770 Field5: "test",
11771 }
11772
11773 errs = validate.Struct(&test2)
11774 NotEqual(t, errs, nil)
11775
11776 ve := errs.(ValidationErrors)
11777 Equal(t, len(ve), 6)
11778 AssertError(t, errs, "Field2", "Field2", "Field2", "Field2", "required_without")
11779 AssertError(t, errs, "Field6", "Field6", "Field6", "Field6", "required_without")
11780 AssertError(t, errs, "Field7", "Field7", "Field7", "Field7", "required_without")
11781 AssertError(t, errs, "Field8", "Field8", "Field8", "Field8", "required_without")
11782 AssertError(t, errs, "Field9", "Field9", "Field9", "Field9", "required_without")
11783 AssertError(t, errs, "Field10", "Field10", "Field10", "Field10", "required_without")
11784
11785 test3 := struct {
11786 Field1 *string `validate:"required_without=Field2,omitempty,min=1" json:"field_1"`
11787 Field2 *string `validate:"required_without=Field1,omitempty,min=1" json:"field_2"`
11788 }{
11789 Field1: &fieldVal,
11790 }
11791
11792 errs = validate.Struct(&test3)
11793 Equal(t, errs, nil)
11794 }
11795
11796 func TestRequiredWithoutAll(t *testing.T) {
11797 type nested struct {
11798 value string
11799 }
11800 fieldVal := "test"
11801 test := struct {
11802 Field1 string `validate:"omitempty" json:"field_1"`
11803 Field2 *string `validate:"required_without_all=Field1" json:"field_2"`
11804 Field3 map[string]string `validate:"required_without_all=Field2" json:"field_3"`
11805 Field4 interface{} `validate:"required_without_all=Field3" json:"field_4"`
11806 Field5 string `validate:"required_without_all=Field3" json:"field_5"`
11807 Field6 nested `validate:"required_without_all=Field1" json:"field_6"`
11808 Field7 *nested `validate:"required_without_all=Field1" json:"field_7"`
11809 }{
11810 Field1: "",
11811 Field2: &fieldVal,
11812 Field3: map[string]string{"key": "val"},
11813 Field4: "test",
11814 Field5: "test",
11815 Field6: nested{"potato"},
11816 Field7: &nested{"potato"},
11817 }
11818
11819 validate := New()
11820
11821 errs := validate.Struct(test)
11822 Equal(t, errs, nil)
11823
11824 test2 := struct {
11825 Field1 string `validate:"omitempty" json:"field_1"`
11826 Field2 *string `validate:"required_without_all=Field1" json:"field_2"`
11827 Field3 map[string]string `validate:"required_without_all=Field2" json:"field_3"`
11828 Field4 interface{} `validate:"required_without_all=Field3" json:"field_4"`
11829 Field5 string `validate:"required_without_all=Field3" json:"field_5"`
11830 Field6 string `validate:"required_without_all=Field1 Field3" json:"field_6"`
11831 Field7 nested `validate:"required_without_all=Field1" json:"field_7"`
11832 Field8 *nested `validate:"required_without_all=Field1" json:"field_8"`
11833 }{
11834 Field3: map[string]string{"key": "val"},
11835 Field4: "test",
11836 Field5: "test",
11837 }
11838
11839 errs = validate.Struct(test2)
11840 NotEqual(t, errs, nil)
11841
11842 ve := errs.(ValidationErrors)
11843 Equal(t, len(ve), 3)
11844 AssertError(t, errs, "Field2", "Field2", "Field2", "Field2", "required_without_all")
11845 AssertError(t, errs, "Field7", "Field7", "Field7", "Field7", "required_without_all")
11846 AssertError(t, errs, "Field8", "Field8", "Field8", "Field8", "required_without_all")
11847 }
11848
11849 func TestExcludedIf(t *testing.T) {
11850 validate := New()
11851 type Inner struct {
11852 Field *string
11853 }
11854
11855 shouldExclude := "exclude"
11856 shouldNotExclude := "dontExclude"
11857
11858 test1 := struct {
11859 FieldE string `validate:"omitempty" json:"field_e"`
11860 FieldER *string `validate:"excluded_if=FieldE exclude" json:"field_er"`
11861 }{
11862 FieldE: shouldExclude,
11863 }
11864 errs := validate.Struct(test1)
11865 Equal(t, errs, nil)
11866
11867 test2 := struct {
11868 FieldE string `validate:"omitempty" json:"field_e"`
11869 FieldER string `validate:"excluded_if=FieldE exclude" json:"field_er"`
11870 }{
11871 FieldE: shouldExclude,
11872 FieldER: "set",
11873 }
11874 errs = validate.Struct(test2)
11875 NotEqual(t, errs, nil)
11876 ve := errs.(ValidationErrors)
11877 Equal(t, len(ve), 1)
11878 AssertError(t, errs, "FieldER", "FieldER", "FieldER", "FieldER", "excluded_if")
11879
11880 test3 := struct {
11881 FieldE string `validate:"omitempty" json:"field_e"`
11882 FieldF string `validate:"omitempty" json:"field_f"`
11883 FieldER string `validate:"excluded_if=FieldE exclude FieldF exclude" json:"field_er"`
11884 }{
11885 FieldE: shouldExclude,
11886 FieldF: shouldExclude,
11887 FieldER: "set",
11888 }
11889 errs = validate.Struct(test3)
11890 NotEqual(t, errs, nil)
11891 ve = errs.(ValidationErrors)
11892 Equal(t, len(ve), 1)
11893 AssertError(t, errs, "FieldER", "FieldER", "FieldER", "FieldER", "excluded_if")
11894
11895 test4 := struct {
11896 FieldE string `validate:"omitempty" json:"field_e"`
11897 FieldF string `validate:"omitempty" json:"field_f"`
11898 FieldER string `validate:"excluded_if=FieldE exclude FieldF exclude" json:"field_er"`
11899 }{
11900 FieldE: shouldExclude,
11901 FieldF: shouldNotExclude,
11902 FieldER: "set",
11903 }
11904 errs = validate.Struct(test4)
11905 Equal(t, errs, nil)
11906
11907 test5 := struct {
11908 FieldE string `validate:"omitempty" json:"field_e"`
11909 FieldER string `validate:"excluded_if=FieldE exclude" json:"field_er"`
11910 }{
11911 FieldE: shouldNotExclude,
11912 }
11913 errs = validate.Struct(test5)
11914 Equal(t, errs, nil)
11915
11916 test6 := struct {
11917 FieldE string `validate:"omitempty" json:"field_e"`
11918 FieldER string `validate:"excluded_if=FieldE exclude" json:"field_er"`
11919 }{
11920 FieldE: shouldNotExclude,
11921 FieldER: "set",
11922 }
11923 errs = validate.Struct(test6)
11924 Equal(t, errs, nil)
11925
11926 test7 := struct {
11927 Inner *Inner
11928 FieldE string `validate:"omitempty" json:"field_e"`
11929 Field1 int `validate:"excluded_if=Inner.Field exclude" json:"field_1"`
11930 }{
11931 Inner: &Inner{Field: &shouldExclude},
11932 }
11933 errs = validate.Struct(test7)
11934 Equal(t, errs, nil)
11935
11936 test8 := struct {
11937 Inner *Inner
11938 FieldE string `validate:"omitempty" json:"field_e"`
11939 Field1 int `validate:"excluded_if=Inner.Field exclude" json:"field_1"`
11940 }{
11941 Inner: &Inner{Field: &shouldExclude},
11942 Field1: 1,
11943 }
11944 errs = validate.Struct(test8)
11945 NotEqual(t, errs, nil)
11946 ve = errs.(ValidationErrors)
11947 Equal(t, len(ve), 1)
11948 AssertError(t, errs, "Field1", "Field1", "Field1", "Field1", "excluded_if")
11949
11950 test9 := struct {
11951 Inner *Inner
11952 FieldE string `validate:"omitempty" json:"field_e"`
11953 Field1 int `validate:"excluded_if=Inner.Field exclude" json:"field_1"`
11954 }{
11955 Inner: &Inner{Field: &shouldNotExclude},
11956 }
11957 errs = validate.Struct(test9)
11958 Equal(t, errs, nil)
11959
11960 test10 := 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: &shouldNotExclude},
11966 Field1: 1,
11967 }
11968 errs = validate.Struct(test10)
11969 Equal(t, errs, nil)
11970
11971
11972 defer func() {
11973 if r := recover(); r == nil {
11974 t.Errorf("panicTest should have panicked!")
11975 }
11976 }()
11977 fieldVal := "panicTest"
11978 panicTest := struct {
11979 Inner *Inner
11980 Field1 string `validate:"excluded_if=Inner.Field" json:"field_1"`
11981 }{
11982 Inner: &Inner{Field: &fieldVal},
11983 }
11984 _ = validate.Struct(panicTest)
11985 }
11986
11987 func TestExcludedUnless(t *testing.T) {
11988 validate := New()
11989 type Inner struct {
11990 Field *string
11991 }
11992
11993 fieldVal := "test"
11994 test := struct {
11995 FieldE string `validate:"omitempty" json:"field_e"`
11996 FieldER string `validate:"excluded_unless=FieldE test" json:"field_er"`
11997 }{
11998 FieldE: "test",
11999 FieldER: "filled",
12000 }
12001 errs := validate.Struct(test)
12002 Equal(t, errs, nil)
12003
12004 test2 := struct {
12005 FieldE string `validate:"omitempty" json:"field_e"`
12006 FieldER string `validate:"excluded_unless=FieldE test" json:"field_er"`
12007 }{
12008 FieldE: "notest",
12009 FieldER: "filled",
12010 }
12011 errs = validate.Struct(test2)
12012 NotEqual(t, errs, nil)
12013 ve := errs.(ValidationErrors)
12014 Equal(t, len(ve), 1)
12015 AssertError(t, errs, "FieldER", "FieldER", "FieldER", "FieldER", "excluded_unless")
12016
12017
12018 test5 := struct {
12019 FieldE string `validate:"omitempty" json:"field_e"`
12020 FieldER string `validate:"excluded_unless=FieldE test" json:"field_er"`
12021 }{
12022 FieldE: "test",
12023 }
12024 errs = validate.Struct(test5)
12025 Equal(t, errs, nil)
12026
12027 test6 := struct {
12028 FieldE string `validate:"omitempty" json:"field_e"`
12029 FieldER string `validate:"excluded_unless=FieldE test" json:"field_er"`
12030 }{
12031 FieldE: "notest",
12032 }
12033 errs = validate.Struct(test6)
12034 Equal(t, errs, nil)
12035
12036 shouldError := "notest"
12037 test3 := struct {
12038 Inner *Inner
12039 Field1 string `validate:"excluded_unless=Inner.Field test" json:"field_1"`
12040 }{
12041 Inner: &Inner{Field: &shouldError},
12042 Field1: "filled",
12043 }
12044 errs = validate.Struct(test3)
12045 NotEqual(t, errs, nil)
12046 ve = errs.(ValidationErrors)
12047 Equal(t, len(ve), 1)
12048 AssertError(t, errs, "Field1", "Field1", "Field1", "Field1", "excluded_unless")
12049
12050 shouldPass := "test"
12051 test4 := struct {
12052 Inner *Inner
12053 FieldE string `validate:"omitempty" json:"field_e"`
12054 Field1 string `validate:"excluded_unless=Inner.Field test" json:"field_1"`
12055 }{
12056 Inner: &Inner{Field: &shouldPass},
12057 Field1: "filled",
12058 }
12059 errs = validate.Struct(test4)
12060 Equal(t, errs, nil)
12061
12062
12063 test7 := struct {
12064 Inner *Inner
12065 FieldE string `validate:"omitempty" json:"field_e"`
12066 FieldER string `validate:"excluded_unless=Inner.Field test" json:"field_er"`
12067 }{
12068 FieldE: "test",
12069 }
12070 errs = validate.Struct(test7)
12071 Equal(t, errs, nil)
12072
12073 test8 := struct {
12074 FieldE string `validate:"omitempty" json:"field_e"`
12075 FieldER string `validate:"excluded_unless=Inner.Field test" json:"field_er"`
12076 }{
12077 FieldE: "test",
12078 }
12079 errs = validate.Struct(test8)
12080 Equal(t, errs, nil)
12081
12082
12083 defer func() {
12084 if r := recover(); r == nil {
12085 t.Errorf("panicTest should have panicked!")
12086 }
12087 }()
12088 panicTest := struct {
12089 Inner *Inner
12090 Field1 string `validate:"excluded_unless=Inner.Field" json:"field_1"`
12091 }{
12092 Inner: &Inner{Field: &fieldVal},
12093 }
12094 _ = validate.Struct(panicTest)
12095 }
12096
12097 func TestLookup(t *testing.T) {
12098 type Lookup struct {
12099 FieldA *string `json:"fieldA,omitempty" validate:"required_without=FieldB"`
12100 FieldB *string `json:"fieldB,omitempty" validate:"required_without=FieldA"`
12101 }
12102
12103 fieldAValue := "1232"
12104 lookup := Lookup{
12105 FieldA: &fieldAValue,
12106 FieldB: nil,
12107 }
12108 Equal(t, New().Struct(lookup), nil)
12109 }
12110
12111 func TestAbilityToValidateNils(t *testing.T) {
12112 type TestStruct struct {
12113 Test *string `validate:"nil"`
12114 }
12115
12116 ts := TestStruct{}
12117 val := New()
12118 fn := func(fl FieldLevel) bool {
12119 return fl.Field().Kind() == reflect.Ptr && fl.Field().IsNil()
12120 }
12121
12122 err := val.RegisterValidation("nil", fn, true)
12123 Equal(t, err, nil)
12124
12125 errs := val.Struct(ts)
12126 Equal(t, errs, nil)
12127
12128 str := "string"
12129 ts.Test = &str
12130
12131 errs = val.Struct(ts)
12132 NotEqual(t, errs, nil)
12133 }
12134
12135 func TestRequiredWithoutPointers(t *testing.T) {
12136 type Lookup struct {
12137 FieldA *bool `json:"fieldA,omitempty" validate:"required_without=FieldB"`
12138 FieldB *bool `json:"fieldB,omitempty" validate:"required_without=FieldA"`
12139 }
12140
12141 b := true
12142 lookup := Lookup{
12143 FieldA: &b,
12144 FieldB: nil,
12145 }
12146
12147 val := New()
12148 errs := val.Struct(lookup)
12149 Equal(t, errs, nil)
12150
12151 b = false
12152 lookup = Lookup{
12153 FieldA: &b,
12154 FieldB: nil,
12155 }
12156 errs = val.Struct(lookup)
12157 Equal(t, errs, nil)
12158 }
12159
12160 func TestRequiredWithoutAllPointers(t *testing.T) {
12161 type Lookup struct {
12162 FieldA *bool `json:"fieldA,omitempty" validate:"required_without_all=FieldB"`
12163 FieldB *bool `json:"fieldB,omitempty" validate:"required_without_all=FieldA"`
12164 }
12165
12166 b := true
12167 lookup := Lookup{
12168 FieldA: &b,
12169 FieldB: nil,
12170 }
12171
12172 val := New()
12173 errs := val.Struct(lookup)
12174 Equal(t, errs, nil)
12175
12176 b = false
12177 lookup = Lookup{
12178 FieldA: &b,
12179 FieldB: nil,
12180 }
12181 errs = val.Struct(lookup)
12182 Equal(t, errs, nil)
12183 }
12184
12185 func TestGetTag(t *testing.T) {
12186 var tag string
12187
12188 type Test struct {
12189 String string `validate:"mytag"`
12190 }
12191
12192 val := New()
12193 _ = val.RegisterValidation("mytag", func(fl FieldLevel) bool {
12194 tag = fl.GetTag()
12195 return true
12196 })
12197
12198 var test Test
12199 errs := val.Struct(test)
12200 Equal(t, errs, nil)
12201 Equal(t, tag, "mytag")
12202 }
12203
12204 func TestJSONValidation(t *testing.T) {
12205 tests := []struct {
12206 param interface{}
12207 expected bool
12208 }{
12209 {`foo`, false},
12210 {`}{`, false},
12211 {`{]`, false},
12212 {`{}`, true},
12213 {`{"foo":"bar"}`, true},
12214 {`{"foo":"bar","bar":{"baz":["qux"]}}`, true},
12215 {`{"foo": 3 "bar": 4}`, false},
12216 {`{"foo": 3 ,"bar": 4`, false},
12217 {`{foo": 3, "bar": 4}`, false},
12218 {`foo`, false},
12219 {`1`, true},
12220 {`true`, true},
12221 {`null`, true},
12222 {`"null"`, true},
12223 {json.RawMessage(`foo`), false},
12224 {json.RawMessage(`}{`), false},
12225 {json.RawMessage(`{]`), false},
12226 {json.RawMessage(`{}`), true},
12227 {json.RawMessage(`{"foo":"bar"}`), true},
12228 {json.RawMessage(`{"foo":"bar","bar":{"baz":["qux"]}}`), true},
12229 {json.RawMessage(`{"foo": 3 "bar": 4}`), false},
12230 {json.RawMessage(`{"foo": 3 ,"bar": 4`), false},
12231 {json.RawMessage(`{foo": 3, "bar": 4}`), false},
12232 {json.RawMessage(`foo`), false},
12233 {json.RawMessage(`1`), true},
12234 {json.RawMessage(`true`), true},
12235 {json.RawMessage(`null`), true},
12236 {json.RawMessage(`"null"`), true},
12237 {[]byte(`foo`), false},
12238 {[]byte(`}{`), false},
12239 {[]byte(`{]`), false},
12240 {[]byte(`{}`), true},
12241 {[]byte(`{"foo":"bar"}`), true},
12242 {[]byte(`{"foo":"bar","bar":{"baz":["qux"]}}`), true},
12243 {[]byte(`{"foo": 3 "bar": 4}`), false},
12244 {[]byte(`{"foo": 3 ,"bar": 4`), false},
12245 {[]byte(`{foo": 3, "bar": 4}`), false},
12246 {[]byte(`foo`), false},
12247 {[]byte(`1`), true},
12248 {[]byte(`true`), true},
12249 {[]byte(`null`), true},
12250 {[]byte(`"null"`), true},
12251 }
12252
12253 validate := New()
12254
12255 for i, test := range tests {
12256
12257 errs := validate.Var(test.param, "json")
12258
12259 if test.expected {
12260 if !IsEqual(errs, nil) {
12261 t.Fatalf("Index: %d json failed Error: %s", i, errs)
12262 }
12263 } else {
12264 if IsEqual(errs, nil) {
12265 t.Fatalf("Index: %d json failed Error: %s", i, errs)
12266 } else {
12267 val := getError(errs, "", "")
12268 if val.Tag() != "json" {
12269 t.Fatalf("Index: %d json failed Error: %s", i, errs)
12270 }
12271 }
12272 }
12273 }
12274
12275 PanicMatches(t, func() {
12276 _ = validate.Var(2, "json")
12277 }, "Bad field type int")
12278 }
12279
12280 func TestJWTValidation(t *testing.T) {
12281 tests := []struct {
12282 param string
12283 expected bool
12284 }{
12285 {"eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiZ29waGVyIn0.O_bROM_szPq9qBql-XDHMranHwP48ODdoLICWzqBr_U", true},
12286 {"acb123-_.def456-_.ghi789-_", true},
12287 {"eyJhbGciOiJOT05FIn0.e30.", true},
12288 {"eyJhbGciOiJOT05FIn0.e30.\n", false},
12289 {"\x00.\x00.\x00", false},
12290 {"", false},
12291 }
12292
12293 validate := New()
12294
12295 for i, test := range tests {
12296
12297 errs := validate.Var(test.param, "jwt")
12298
12299 if test.expected {
12300 if !IsEqual(errs, nil) {
12301 t.Fatalf("Index: %d jwt failed Error: %s", i, errs)
12302 }
12303 } else {
12304 if IsEqual(errs, nil) {
12305 t.Fatalf("Index: %d jwt failed Error: %s", i, errs)
12306 } else {
12307 val := getError(errs, "", "")
12308 if val.Tag() != "jwt" {
12309 t.Fatalf("Index: %d jwt failed Error: %s", i, errs)
12310 }
12311 }
12312 }
12313 }
12314 }
12315
12316 func Test_hostnameport_validator(t *testing.T) {
12317 type Host struct {
12318 Addr string `validate:"hostname_port"`
12319 }
12320
12321 type testInput struct {
12322 data string
12323 expected bool
12324 }
12325 testData := []testInput{
12326 {"bad..domain.name:234", false},
12327 {"extra.dot.com.", false},
12328 {"localhost:1234", true},
12329 {"192.168.1.1:1234", true},
12330 {":1234", true},
12331 {"domain.com:1334", true},
12332 {"this.domain.com:234", true},
12333 {"domain:75000", false},
12334 {"missing.port", false},
12335 }
12336 for _, td := range testData {
12337 h := Host{Addr: td.data}
12338 v := New()
12339 err := v.Struct(h)
12340 if td.expected != (err == nil) {
12341 t.Fatalf("Test failed for data: %v Error: %v", td.data, err)
12342 }
12343 }
12344 }
12345
12346 func TestLowercaseValidation(t *testing.T) {
12347 tests := []struct {
12348 param string
12349 expected bool
12350 }{
12351 {`abcdefg`, true},
12352 {`Abcdefg`, false},
12353 {"", false},
12354 }
12355
12356 validate := New()
12357
12358 for i, test := range tests {
12359
12360 errs := validate.Var(test.param, "lowercase")
12361
12362 if test.expected {
12363 if !IsEqual(errs, nil) {
12364 t.Fatalf("Index: %d lowercase failed Error: %s", i, errs)
12365 }
12366 } else {
12367 if IsEqual(errs, nil) {
12368 t.Fatalf("Index: %d lowercase failed Error: %s", i, errs)
12369 } else {
12370 val := getError(errs, "", "")
12371 if val.Tag() != "lowercase" {
12372 t.Fatalf("Index: %d lowercase failed Error: %s", i, errs)
12373 }
12374 }
12375 }
12376 }
12377
12378 PanicMatches(t, func() {
12379 _ = validate.Var(2, "lowercase")
12380 }, "Bad field type int")
12381 }
12382
12383 func TestUppercaseValidation(t *testing.T) {
12384 tests := []struct {
12385 param string
12386 expected bool
12387 }{
12388 {`ABCDEFG`, true},
12389 {`aBCDEFG`, false},
12390 {"", false},
12391 }
12392
12393 validate := New()
12394
12395 for i, test := range tests {
12396
12397 errs := validate.Var(test.param, "uppercase")
12398
12399 if test.expected {
12400 if !IsEqual(errs, nil) {
12401 t.Fatalf("Index: %d uppercase failed Error: %s", i, errs)
12402 }
12403 } else {
12404 if IsEqual(errs, nil) {
12405 t.Fatalf("Index: %d uppercase failed Error: %s", i, errs)
12406 } else {
12407 val := getError(errs, "", "")
12408 if val.Tag() != "uppercase" {
12409 t.Fatalf("Index: %d uppercase failed Error: %s", i, errs)
12410 }
12411 }
12412 }
12413 }
12414
12415 PanicMatches(t, func() {
12416 _ = validate.Var(2, "uppercase")
12417 }, "Bad field type int")
12418 }
12419
12420 func TestDatetimeValidation(t *testing.T) {
12421 tests := []struct {
12422 value string `validate:"datetime=2006-01-02"`
12423 tag string
12424 expected bool
12425 }{
12426 {"2008-02-01", `datetime=2006-01-02`, true},
12427 {"2008-Feb-01", `datetime=2006-01-02`, false},
12428 }
12429
12430 validate := New()
12431
12432 for i, test := range tests {
12433
12434 errs := validate.Var(test.value, test.tag)
12435
12436 if test.expected {
12437 if !IsEqual(errs, nil) {
12438 t.Fatalf("Index: %d datetime failed Error: %s", i, errs)
12439 }
12440 } else {
12441 if IsEqual(errs, nil) {
12442 t.Fatalf("Index: %d datetime failed Error: %s", i, errs)
12443 } else {
12444 val := getError(errs, "", "")
12445 if val.Tag() != "datetime" {
12446 t.Fatalf("Index: %d datetime failed Error: %s", i, errs)
12447 }
12448 }
12449 }
12450 }
12451
12452 PanicMatches(t, func() {
12453 _ = validate.Var(2, "datetime")
12454 }, "Bad field type int")
12455 }
12456
12457 func TestIsIso3166Alpha2Validation(t *testing.T) {
12458 tests := []struct {
12459 value string `validate:"iso3166_1_alpha2"`
12460 expected bool
12461 }{
12462 {"PL", true},
12463 {"POL", false},
12464 {"AA", false},
12465 }
12466
12467 validate := New()
12468
12469 for i, test := range tests {
12470
12471 errs := validate.Var(test.value, "iso3166_1_alpha2")
12472
12473 if test.expected {
12474 if !IsEqual(errs, nil) {
12475 t.Fatalf("Index: %d iso3166_1_alpha2 failed Error: %s", i, errs)
12476 }
12477 } else {
12478 if IsEqual(errs, nil) {
12479 t.Fatalf("Index: %d iso3166_1_alpha2 failed Error: %s", i, errs)
12480 }
12481 }
12482 }
12483 }
12484
12485 func TestIsIso31662Validation(t *testing.T) {
12486 tests := []struct {
12487 value string `validate:"iso3166_2"`
12488 expected bool
12489 }{
12490 {"US-FL", true},
12491 {"US-F", false},
12492 {"US", false},
12493 }
12494
12495 validate := New()
12496
12497 for i, test := range tests {
12498
12499 errs := validate.Var(test.value, "iso3166_2")
12500
12501 if test.expected {
12502 if !IsEqual(errs, nil) {
12503 t.Fatalf("Index: %d iso3166_2 failed Error: %s", i, errs)
12504 }
12505 } else {
12506 if IsEqual(errs, nil) {
12507 t.Fatalf("Index: %d iso3166_2 failed Error: %s", i, errs)
12508 }
12509 }
12510 }
12511 }
12512
12513 func TestIsIso3166Alpha3Validation(t *testing.T) {
12514 tests := []struct {
12515 value string `validate:"iso3166_1_alpha3"`
12516 expected bool
12517 }{
12518 {"POL", true},
12519 {"PL", false},
12520 {"AAA", false},
12521 }
12522
12523 validate := New()
12524
12525 for i, test := range tests {
12526
12527 errs := validate.Var(test.value, "iso3166_1_alpha3")
12528
12529 if test.expected {
12530 if !IsEqual(errs, nil) {
12531 t.Fatalf("Index: %d iso3166_1_alpha3 failed Error: %s", i, errs)
12532 }
12533 } else {
12534 if IsEqual(errs, nil) {
12535 t.Fatalf("Index: %d iso3166_1_alpha3 failed Error: %s", i, errs)
12536 }
12537 }
12538 }
12539 }
12540
12541 func TestIsIso3166AlphaNumericValidation(t *testing.T) {
12542 tests := []struct {
12543 value interface{}
12544 expected bool
12545 }{
12546 {248, true},
12547 {"248", true},
12548 {0, false},
12549 {1, false},
12550 {"1", false},
12551 {"invalid_int", false},
12552 }
12553
12554 validate := New()
12555
12556 for i, test := range tests {
12557
12558 errs := validate.Var(test.value, "iso3166_1_alpha_numeric")
12559
12560 if test.expected {
12561 if !IsEqual(errs, nil) {
12562 t.Fatalf("Index: %d iso3166_1_alpha_numeric failed Error: %s", i, errs)
12563 }
12564 } else {
12565 if IsEqual(errs, nil) {
12566 t.Fatalf("Index: %d iso3166_1_alpha_numeric failed Error: %s", i, errs)
12567 }
12568 }
12569 }
12570
12571 PanicMatches(t, func() {
12572 _ = validate.Var([]string{"1"}, "iso3166_1_alpha_numeric")
12573 }, "Bad field type []string")
12574 }
12575
12576 func TestCountryCodeValidation(t *testing.T) {
12577 tests := []struct {
12578 value interface{}
12579 expected bool
12580 }{
12581 {248, true},
12582 {0, false},
12583 {1, false},
12584 {"POL", true},
12585 {"NO", true},
12586 {"248", true},
12587 {"1", false},
12588 {"0", false},
12589 }
12590
12591 validate := New()
12592
12593 for i, test := range tests {
12594
12595 errs := validate.Var(test.value, "country_code")
12596
12597 if test.expected {
12598 if !IsEqual(errs, nil) {
12599 t.Fatalf("Index: %d country_code failed Error: %s", i, errs)
12600 }
12601 } else {
12602 if IsEqual(errs, nil) {
12603 t.Fatalf("Index: %d country_code failed Error: %s", i, errs)
12604 }
12605 }
12606 }
12607 }
12608
12609 func TestIsIso4217Validation(t *testing.T) {
12610 tests := []struct {
12611 value string `validate:"iso4217"`
12612 expected bool
12613 }{
12614 {"TRY", true},
12615 {"EUR", true},
12616 {"USA", false},
12617 }
12618
12619 validate := New()
12620
12621 for i, test := range tests {
12622
12623 errs := validate.Var(test.value, "iso4217")
12624
12625 if test.expected {
12626 if !IsEqual(errs, nil) {
12627 t.Fatalf("Index: %d iso4217 failed Error: %s", i, errs)
12628 }
12629 } else {
12630 if IsEqual(errs, nil) {
12631 t.Fatalf("Index: %d iso4217 failed Error: %s", i, errs)
12632 }
12633 }
12634 }
12635 }
12636
12637 func TestIsIso4217NumericValidation(t *testing.T) {
12638 tests := []struct {
12639 value int `validate:"iso4217_numeric"`
12640 expected bool
12641 }{
12642 {8, true},
12643 {12, true},
12644 {13, false},
12645 }
12646
12647 validate := New()
12648
12649 for i, test := range tests {
12650
12651 errs := validate.Var(test.value, "iso4217_numeric")
12652
12653 if test.expected {
12654 if !IsEqual(errs, nil) {
12655 t.Fatalf("Index: %d iso4217 failed Error: %s", i, errs)
12656 }
12657 } else {
12658 if IsEqual(errs, nil) {
12659 t.Fatalf("Index: %d iso4217 failed Error: %s", i, errs)
12660 }
12661 }
12662 }
12663 }
12664
12665 func TestTimeZoneValidation(t *testing.T) {
12666 tests := []struct {
12667 value string `validate:"timezone"`
12668 tag string
12669 expected bool
12670 }{
12671
12672 {"America/New_York", `timezone`, true},
12673 {"UTC", `timezone`, true},
12674 {"", `timezone`, false},
12675 {"Local", `timezone`, false},
12676 {"Unknown", `timezone`, false},
12677 }
12678
12679 validate := New()
12680
12681 for i, test := range tests {
12682
12683 errs := validate.Var(test.value, test.tag)
12684
12685 if test.expected {
12686 if !IsEqual(errs, nil) {
12687 t.Fatalf("Index: %d time zone failed Error: %s", i, errs)
12688 }
12689 } else {
12690 if IsEqual(errs, nil) {
12691 t.Fatalf("Index: %d time zone failed Error: %s", i, errs)
12692 } else {
12693 val := getError(errs, "", "")
12694 if val.Tag() != "timezone" {
12695 t.Fatalf("Index: %d time zone failed Error: %s", i, errs)
12696 }
12697 }
12698 }
12699 }
12700
12701 PanicMatches(t, func() {
12702 _ = validate.Var(2, "timezone")
12703 }, "Bad field type int")
12704 }
12705
12706 func TestDurationType(t *testing.T) {
12707 tests := []struct {
12708 name string
12709 s interface{}
12710 success bool
12711 }{
12712 {
12713 name: "valid duration string pass",
12714 s: struct {
12715 Value time.Duration `validate:"gte=500ns"`
12716 }{
12717 Value: time.Second,
12718 },
12719 success: true,
12720 },
12721 {
12722 name: "valid duration int pass",
12723 s: struct {
12724 Value time.Duration `validate:"gte=500"`
12725 }{
12726 Value: time.Second,
12727 },
12728 success: true,
12729 },
12730 }
12731
12732 validate := New()
12733
12734 for _, tc := range tests {
12735 tc := tc
12736 t.Run(tc.name, func(t *testing.T) {
12737 t.Parallel()
12738
12739 errs := validate.Struct(tc.s)
12740 if tc.success {
12741 Equal(t, errs, nil)
12742 return
12743 }
12744 NotEqual(t, errs, nil)
12745 })
12746 }
12747 }
12748
12749 func TestBCP47LanguageTagValidation(t *testing.T) {
12750 tests := []struct {
12751 value string `validate:"bcp47_language_tag"`
12752 tag string
12753 expected bool
12754 }{
12755 {"en-US", "bcp47_language_tag", true},
12756 {"en_GB", "bcp47_language_tag", true},
12757 {"es", "bcp47_language_tag", true},
12758 {"English", "bcp47_language_tag", false},
12759 {"ESES", "bcp47_language_tag", false},
12760 {"az-Cyrl-AZ", "bcp47_language_tag", true},
12761 {"en-029", "bcp47_language_tag", true},
12762 {"xog", "bcp47_language_tag", true},
12763 }
12764
12765 validate := New()
12766
12767 for i, test := range tests {
12768
12769 errs := validate.Var(test.value, test.tag)
12770
12771 if test.expected {
12772 if !IsEqual(errs, nil) {
12773 t.Fatalf("Index: %d locale failed Error: %s", i, errs)
12774 }
12775 } else {
12776 if IsEqual(errs, nil) {
12777 t.Fatalf("Index: %d locale failed Error: %s", i, errs)
12778 } else {
12779 val := getError(errs, "", "")
12780 if val.Tag() != "bcp47_language_tag" {
12781 t.Fatalf("Index: %d locale failed Error: %s", i, errs)
12782 }
12783 }
12784 }
12785 }
12786
12787 PanicMatches(t, func() {
12788 _ = validate.Var(2, "bcp47_language_tag")
12789 }, "Bad field type int")
12790 }
12791
12792 func TestBicIsoFormatValidation(t *testing.T) {
12793 tests := []struct {
12794 value string `validate:"bic"`
12795 tag string
12796 expected bool
12797 }{
12798 {"SBICKEN1345", "bic", true},
12799 {"SBICKEN1", "bic", true},
12800 {"SBICKENY", "bic", true},
12801 {"SBICKEN1YYP", "bic", true},
12802 {"SBIC23NXXX", "bic", false},
12803 {"S23CKENXXXX", "bic", false},
12804 {"SBICKENXX", "bic", false},
12805 {"SBICKENXX9", "bic", false},
12806 {"SBICKEN13458", "bic", false},
12807 {"SBICKEN", "bic", false},
12808 }
12809
12810 validate := New()
12811
12812 for i, test := range tests {
12813
12814 errs := validate.Var(test.value, test.tag)
12815
12816 if test.expected {
12817 if !IsEqual(errs, nil) {
12818 t.Fatalf("Index: %d bic failed Error: %s", i, errs)
12819 }
12820 } else {
12821 if IsEqual(errs, nil) {
12822 t.Fatalf("Index: %d bic failed Error: %s", i, errs)
12823 } else {
12824 val := getError(errs, "", "")
12825 if val.Tag() != "bic" {
12826 t.Fatalf("Index: %d bic failed Error: %s", i, errs)
12827 }
12828 }
12829 }
12830 }
12831 }
12832
12833 func TestSemverFormatValidation(t *testing.T) {
12834 tests := []struct {
12835 value string `validate:"semver"`
12836 tag string
12837 expected bool
12838 }{
12839 {"1.2.3", "semver", true},
12840 {"10.20.30", "semver", true},
12841 {"1.1.2-prerelease+meta", "semver", true},
12842 {"1.1.2+meta", "semver", true},
12843 {"1.1.2+meta-valid", "semver", true},
12844 {"1.0.0-alpha", "semver", true},
12845 {"1.0.0-alpha.1", "semver", true},
12846 {"1.0.0-alpha.beta", "semver", true},
12847 {"1.0.0-alpha.beta.1", "semver", true},
12848 {"1.0.0-alpha0.valid", "semver", true},
12849 {"1.0.0-alpha.0valid", "semver", true},
12850 {"1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay", "semver", true},
12851 {"1.0.0-rc.1+build.1", "semver", true},
12852 {"1.0.0-rc.1+build.123", "semver", true},
12853 {"1.2.3-beta", "semver", true},
12854 {"1.2.3-DEV-SNAPSHOT", "semver", true},
12855 {"1.2.3-SNAPSHOT-123", "semver", true},
12856 {"2.0.0+build.1848", "semver", true},
12857 {"2.0.1-alpha.1227", "semver", true},
12858 {"1.0.0-alpha+beta", "semver", true},
12859 {"1.2.3----RC-SNAPSHOT.12.9.1--.12+788", "semver", true},
12860 {"1.2.3----R-S.12.9.1--.12+meta", "semver", true},
12861 {"1.2.3----RC-SNAPSHOT.12.9.1--.12", "semver", true},
12862 {"1.0.0+0.build.1-rc.10000aaa-kk-0.1", "semver", true},
12863 {"99999999999999999999999.999999999999999999.99999999999999999", "semver", true},
12864 {"1.0.0-0A.is.legal", "semver", true},
12865 {"1", "semver", false},
12866 {"1.2", "semver", false},
12867 {"1.2.3-0123", "semver", false},
12868 {"1.2.3-0123.0123", "semver", false},
12869 {"1.1.2+.123", "semver", false},
12870 {"+invalid", "semver", false},
12871 {"-invalid", "semver", false},
12872 {"-invalid+invalid", "semver", false},
12873 {"alpha", "semver", false},
12874 {"alpha.beta.1", "semver", false},
12875 {"alpha.1", "semver", false},
12876 {"1.0.0-alpha_beta", "semver", false},
12877 {"1.0.0-alpha_beta", "semver", false},
12878 {"1.0.0-alpha...1", "semver", false},
12879 {"01.1.1", "semver", false},
12880 {"1.01.1", "semver", false},
12881 {"1.1.01", "semver", false},
12882 {"1.2", "semver", false},
12883 {"1.2.Dev", "semver", false},
12884 {"1.2.3.Dev", "semver", false},
12885 {"1.2-SNAPSHOT", "semver", false},
12886 }
12887
12888 validate := New()
12889
12890 for i, test := range tests {
12891
12892 errs := validate.Var(test.value, test.tag)
12893
12894 if test.expected {
12895 if !IsEqual(errs, nil) {
12896 t.Fatalf("Index: %d semver failed Error: %s", i, errs)
12897 }
12898 } else {
12899 if IsEqual(errs, nil) {
12900 t.Fatalf("Index: %d semver failed Error: %s", i, errs)
12901 } else {
12902 val := getError(errs, "", "")
12903 if val.Tag() != "semver" {
12904 t.Fatalf("Index: %d semver failed Error: %s", i, errs)
12905 }
12906 }
12907 }
12908 }
12909 }
12910
12911 func TestCveFormatValidation(t *testing.T) {
12912
12913 tests := []struct {
12914 value string `validate:"cve"`
12915 tag string
12916 expected bool
12917 }{
12918 {"CVE-1999-0001", "cve", true},
12919 {"CVE-1998-0001", "cve", false},
12920 {"CVE-2000-0001", "cve", true},
12921 {"CVE-2222-0001", "cve", true},
12922 {"2222-0001", "cve", false},
12923 {"-2222-0001", "cve", false},
12924 {"CVE22220001", "cve", false},
12925 {"CVE-2222-000001", "cve", false},
12926 {"CVE-2222-100001", "cve", true},
12927 {"CVE-2222-99999999999", "cve", true},
12928 {"CVE-3000-0001", "cve", false},
12929 {"CVE-1999-0000", "cve", false},
12930 {"CVE-2099-0000", "cve", false},
12931 }
12932
12933 validate := New()
12934
12935 for i, test := range tests {
12936 errs := validate.Var(test.value, test.tag)
12937
12938 if test.expected {
12939 if !IsEqual(errs, nil) {
12940 t.Fatalf("Index: %d cve failed Error: %s", i, errs)
12941 }
12942 } else {
12943 if IsEqual(errs, nil) {
12944 t.Fatalf("Index: %d cve failed Error: %s", i, errs)
12945 } else {
12946 val := getError(errs, "", "")
12947 if val.Tag() != "cve" {
12948 t.Fatalf("Index: %d cve failed Error: %s", i, errs)
12949 }
12950 }
12951 }
12952 }
12953 }
12954
12955 func TestRFC1035LabelFormatValidation(t *testing.T) {
12956 tests := []struct {
12957 value string `validate:"dns_rfc1035_label"`
12958 tag string
12959 expected bool
12960 }{
12961 {"abc", "dns_rfc1035_label", true},
12962 {"abc-", "dns_rfc1035_label", false},
12963 {"abc-123", "dns_rfc1035_label", true},
12964 {"ABC", "dns_rfc1035_label", false},
12965 {"ABC-123", "dns_rfc1035_label", false},
12966 {"abc-abc", "dns_rfc1035_label", true},
12967 {"ABC-ABC", "dns_rfc1035_label", false},
12968 {"123-abc", "dns_rfc1035_label", false},
12969 {"", "dns_rfc1035_label", false},
12970 }
12971
12972 validate := New()
12973
12974 for i, test := range tests {
12975 errs := validate.Var(test.value, test.tag)
12976
12977 if test.expected {
12978 if !IsEqual(errs, nil) {
12979 t.Fatalf("Index: %d dns_rfc1035_label failed Error: %s", i, errs)
12980 }
12981 } else {
12982 if IsEqual(errs, nil) {
12983 t.Fatalf("Index: %d dns_rfc1035_label failed Error: %s", i, errs)
12984 } else {
12985 val := getError(errs, "", "")
12986 if val.Tag() != "dns_rfc1035_label" {
12987 t.Fatalf("Index: %d dns_rfc1035_label failed Error: %s", i, errs)
12988 }
12989 }
12990 }
12991 }
12992 }
12993
12994 func TestPostCodeByIso3166Alpha2(t *testing.T) {
12995 tests := map[string][]struct {
12996 value string
12997 expected bool
12998 }{
12999 "VN": {
13000 {"ABC", false},
13001 {"700000", true},
13002 {"A1", false},
13003 },
13004 "GB": {
13005 {"EC1A 1BB", true},
13006 {"CF10 1B1H", false},
13007 },
13008 "VI": {
13009 {"00803", true},
13010 {"1234567", false},
13011 },
13012 "LC": {
13013
13014 {"123456", false},
13015 },
13016 "XX": {
13017
13018 {"123456", false},
13019 },
13020 }
13021
13022 validate := New()
13023
13024 for cc, ccTests := range tests {
13025 for i, test := range ccTests {
13026 errs := validate.Var(test.value, fmt.Sprintf("postcode_iso3166_alpha2=%s", cc))
13027
13028 if test.expected {
13029 if !IsEqual(errs, nil) {
13030 t.Fatalf("Index: %d postcode_iso3166_alpha2=%s failed Error: %s", i, cc, errs)
13031 }
13032 } else {
13033 if IsEqual(errs, nil) {
13034 t.Fatalf("Index: %d postcode_iso3166_alpha2=%s failed Error: %s", i, cc, errs)
13035 }
13036 }
13037 }
13038 }
13039 }
13040
13041 func TestPostCodeByIso3166Alpha2Field(t *testing.T) {
13042 tests := []struct {
13043 Value string `validate:"postcode_iso3166_alpha2_field=CountryCode"`
13044 CountryCode interface{}
13045 expected bool
13046 }{
13047 {"ABC", "VN", false},
13048 {"700000", "VN", true},
13049 {"A1", "VN", false},
13050 {"EC1A 1BB", "GB", true},
13051 {"CF10 1B1H", "GB", false},
13052 {"00803", "VI", true},
13053 {"1234567", "VI", false},
13054 {"123456", "LC", false},
13055 {"123456", "XX", false},
13056 }
13057
13058 validate := New()
13059
13060 for i, test := range tests {
13061 errs := validate.Struct(test)
13062 if test.expected {
13063 if !IsEqual(errs, nil) {
13064 t.Fatalf("Index: %d postcode_iso3166_alpha2_field=CountryCode failed Error: %s", i, errs)
13065 }
13066 } else {
13067 if IsEqual(errs, nil) {
13068 t.Fatalf("Index: %d postcode_iso3166_alpha2_field=CountryCode failed Error: %s", i, errs)
13069 }
13070 }
13071 }
13072 }
13073
13074 func TestPostCodeByIso3166Alpha2Field_WrongField(t *testing.T) {
13075 type test struct {
13076 Value string `validate:"postcode_iso3166_alpha2_field=CountryCode"`
13077 CountryCode1 interface{}
13078 expected bool
13079 }
13080
13081 errs := New().Struct(test{"ABC", "VN", false})
13082 NotEqual(t, nil, errs)
13083 }
13084
13085 func TestPostCodeByIso3166Alpha2Field_MissingParam(t *testing.T) {
13086 type test struct {
13087 Value string `validate:"postcode_iso3166_alpha2_field="`
13088 CountryCode1 interface{}
13089 expected bool
13090 }
13091
13092 errs := New().Struct(test{"ABC", "VN", false})
13093 NotEqual(t, nil, errs)
13094 }
13095
13096 func TestPostCodeByIso3166Alpha2Field_InvalidKind(t *testing.T) {
13097 type test struct {
13098 Value string `validate:"postcode_iso3166_alpha2_field=CountryCode"`
13099 CountryCode interface{}
13100 expected bool
13101 }
13102 defer func() { _ = recover() }()
13103
13104 _ = New().Struct(test{"ABC", 123, false})
13105 t.Errorf("Didn't panic as expected")
13106 }
13107
13108 func TestValidate_ValidateMapCtx(t *testing.T) {
13109
13110 type args struct {
13111 data map[string]interface{}
13112 rules map[string]interface{}
13113 }
13114 tests := []struct {
13115 name string
13116 args args
13117 want int
13118 }{
13119 {
13120 name: "test nested map in slice",
13121 args: args{
13122 data: map[string]interface{}{
13123 "Test_A": map[string]interface{}{
13124 "Test_B": "Test_B",
13125 "Test_C": []map[string]interface{}{
13126 {
13127 "Test_D": "Test_D",
13128 },
13129 },
13130 "Test_E": map[string]interface{}{
13131 "Test_F": "Test_F",
13132 },
13133 },
13134 },
13135 rules: map[string]interface{}{
13136 "Test_A": map[string]interface{}{
13137 "Test_B": "min=2",
13138 "Test_C": map[string]interface{}{
13139 "Test_D": "min=2",
13140 },
13141 "Test_E": map[string]interface{}{
13142 "Test_F": "min=2",
13143 },
13144 },
13145 },
13146 },
13147 want: 0,
13148 },
13149
13150 {
13151 name: "test nested map error",
13152 args: args{
13153 data: map[string]interface{}{
13154 "Test_A": map[string]interface{}{
13155 "Test_B": "Test_B",
13156 "Test_C": []interface{}{"Test_D"},
13157 "Test_E": map[string]interface{}{
13158 "Test_F": "Test_F",
13159 },
13160 "Test_G": "Test_G",
13161 "Test_I": []map[string]interface{}{
13162 {
13163 "Test_J": "Test_J",
13164 },
13165 },
13166 },
13167 },
13168 rules: map[string]interface{}{
13169 "Test_A": map[string]interface{}{
13170 "Test_B": "min=2",
13171 "Test_C": map[string]interface{}{
13172 "Test_D": "min=2",
13173 },
13174 "Test_E": map[string]interface{}{
13175 "Test_F": "min=100",
13176 },
13177 "Test_G": map[string]interface{}{
13178 "Test_H": "min=2",
13179 },
13180 "Test_I": map[string]interface{}{
13181 "Test_J": "min=100",
13182 },
13183 },
13184 },
13185 },
13186 want: 1,
13187 },
13188 }
13189 for _, tt := range tests {
13190 t.Run(tt.name, func(t *testing.T) {
13191 validate := New()
13192 if got := validate.ValidateMapCtx(context.Background(), tt.args.data, tt.args.rules); len(got) != tt.want {
13193 t.Errorf("ValidateMapCtx() = %v, want %v", got, tt.want)
13194 }
13195 })
13196 }
13197 }
13198
13199 func TestMongoDBObjectIDFormatValidation(t *testing.T) {
13200 tests := []struct {
13201 value string `validate:"mongodb"`
13202 tag string
13203 expected bool
13204 }{
13205 {"507f191e810c19729de860ea", "mongodb", true},
13206 {"507f191e810c19729de860eG", "mongodb", false},
13207 {"M07f191e810c19729de860eG", "mongodb", false},
13208 {"07f191e810c19729de860ea", "mongodb", false},
13209 {"507f191e810c19729de860e", "mongodb", false},
13210 {"507f191e810c19729de860ea4", "mongodb", false},
13211 }
13212
13213 validate := New()
13214
13215 for i, test := range tests {
13216 errs := validate.Var(test.value, test.tag)
13217
13218 if test.expected {
13219 if !IsEqual(errs, nil) {
13220 t.Fatalf("Index: %d mongodb failed Error: %s", i, errs)
13221 }
13222 } else {
13223 if IsEqual(errs, nil) {
13224 t.Fatalf("Index: %d mongodb failed Error: %s", i, errs)
13225 } else {
13226 val := getError(errs, "", "")
13227 if val.Tag() != "mongodb" {
13228 t.Fatalf("Index: %d mongodb failed Error: %s", i, errs)
13229 }
13230 }
13231 }
13232 }
13233 }
13234
13235 func TestSpiceDBValueFormatValidation(t *testing.T) {
13236 tests := []struct {
13237 value string
13238 tag string
13239 expected bool
13240 }{
13241
13242 {"*", "spicedb=id", true},
13243 {`azAZ09_|/-=+`, "spicedb=id", true},
13244 {`a*`, "spicedb=id", false},
13245 {`/`, "spicedb=id", true},
13246 {"*", "spicedb", true},
13247
13248
13249 {"a", "spicedb=permission", false},
13250 {"1", "spicedb=permission", false},
13251 {"a1", "spicedb=permission", false},
13252 {"a_b", "spicedb=permission", true},
13253 {"A_b", "spicedb=permission", false},
13254 {"a_B", "spicedb=permission", false},
13255 {"abcdefghijklmnopqrstuvwxyz_0123456789_abcdefghijklmnopqrstuvwxyz", "spicedb=permission", true},
13256 {"abcdefghijklmnopqrstuvwxyz_01234_56789_abcdefghijklmnopqrstuvwxyz", "spicedb=permission", false},
13257
13258
13259 {"a", "spicedb=type", false},
13260 {"1", "spicedb=type", false},
13261 {"a1", "spicedb=type", false},
13262 {"a_b", "spicedb=type", true},
13263 {"A_b", "spicedb=type", false},
13264 {"a_B", "spicedb=type", false},
13265 {"abcdefghijklmnopqrstuvwxyz_0123456789_abcdefghijklmnopqrstuvwxyz", "spicedb=type", true},
13266 {"abcdefghijklmnopqrstuvwxyz_01234_56789_abcdefghijklmnopqrstuvwxyz", "spicedb=type", false},
13267
13268 {`a_b/a`, "spicedb=type", false},
13269 {`a_b/1`, "spicedb=type", false},
13270 {`a_b/a1`, "spicedb=type", false},
13271 {`a_b/a_b`, "spicedb=type", true},
13272 {`a_b/A_b`, "spicedb=type", false},
13273 {`a_b/a_B`, "spicedb=type", false},
13274 {`a_b/abcdefghijklmnopqrstuvwxyz_0123456789_abcdefghijklmnopqrstuvwxyz`, "spicedb=type", true},
13275 {`a_b/abcdefghijklmnopqrstuvwxyz_01234_56789_abcdefghijklmnopqrstuvwxyz`, "spicedb=type", false},
13276
13277 {`a/a_b`, "spicedb=type", false},
13278 {`1/a_b`, "spicedb=type", false},
13279 {`a1/a_b`, "spicedb=type", false},
13280 {`a_b/a_b`, "spicedb=type", true},
13281 {`A_b/a_b`, "spicedb=type", false},
13282 {`a_B/a_b`, "spicedb=type", false},
13283 {`abcdefghijklmnopqrstuvwxyz_0123456789_abcdefghijklmnopqrstuvwxy/a_b`, "spicedb=type", true},
13284 {`abcdefghijklmnopqrstuvwxyz_0123456789_abcdefghijklmnopqrstuvwxyz/a_b`, "spicedb=type", false},
13285 }
13286
13287 validate := New()
13288
13289 for i, test := range tests {
13290 errs := validate.Var(test.value, test.tag)
13291
13292 if test.expected {
13293 if !IsEqual(errs, nil) {
13294 t.Fatalf("Index: %d spicedb failed Error: %s", i, errs)
13295 }
13296 } else {
13297 if IsEqual(errs, nil) {
13298 t.Fatalf("Index: %d spicedb - expected error but there was none.", i)
13299 } else {
13300 val := getError(errs, "", "")
13301 if val.Tag() != "spicedb" {
13302 t.Fatalf("Index: %d spicedb failed Error: %s", i, errs)
13303 }
13304 }
13305 }
13306 }
13307 }
13308
13309 func TestCreditCardFormatValidation(t *testing.T) {
13310 tests := []struct {
13311 value string `validate:"credit_card"`
13312 tag string
13313 expected bool
13314 }{
13315 {"586824160825533338", "credit_card", true},
13316 {"586824160825533328", "credit_card", false},
13317 {"4624748233249780", "credit_card", true},
13318 {"4624748233349780", "credit_card", false},
13319 {"378282246310005", "credit_card", true},
13320 {"378282146310005", "credit_card", false},
13321 {"4624 7482 3324 9780", "credit_card", true},
13322 {"4624 7482 3324 9780", "credit_card", false},
13323 {"4624 7482 3324 978A", "credit_card", false},
13324 {"4624 7482 332", "credit_card", false},
13325 }
13326
13327 validate := New()
13328
13329 for i, test := range tests {
13330 errs := validate.Var(test.value, test.tag)
13331
13332 if test.expected {
13333 if !IsEqual(errs, nil) {
13334 t.Fatalf("Index: %d credit_card failed Error: %s", i, errs)
13335 }
13336 } else {
13337 if IsEqual(errs, nil) {
13338 t.Fatalf("Index: %d credit_card failed Error: %s", i, errs)
13339 } else {
13340 val := getError(errs, "", "")
13341 if val.Tag() != "credit_card" {
13342 t.Fatalf("Index: %d credit_card failed Error: %s", i, errs)
13343 }
13344 }
13345 }
13346 }
13347 }
13348
13349 func TestLuhnChecksumValidation(t *testing.T) {
13350 testsUint := []struct {
13351 value interface{} `validate:"luhn_checksum"`
13352 tag string
13353 expected bool
13354 }{
13355 {uint64(586824160825533338), "luhn_checksum", true},
13356 {586824160825533338, "luhn_checksum", true},
13357 {"586824160825533338", "luhn_checksum", true},
13358 {uint64(586824160825533328), "luhn_checksum", false},
13359 {586824160825533328, "luhn_checksum", false},
13360 {"586824160825533328", "luhn_checksum", false},
13361 {10000000116, "luhn_checksum", true},
13362 {"10000000116", "luhn_checksum", true},
13363 {10000000117, "luhn_checksum", false},
13364 {"10000000117", "luhn_checksum", false},
13365 {uint64(12345678123456789011), "luhn_checksum", true},
13366 {"12345678123456789011", "luhn_checksum", true},
13367 {1, "luhn_checksum", false},
13368 {"1", "luhn_checksum", false},
13369 {-10, "luhn_checksum", false},
13370 {"abcdefghijklmnop", "luhn_checksum", false},
13371 }
13372
13373 validate := New()
13374
13375 for i, test := range testsUint {
13376 errs := validate.Var(test.value, test.tag)
13377 if test.expected {
13378 if !IsEqual(errs, nil) {
13379 t.Fatalf("Index: %d luhn_checksum failed Error: %s", i, errs)
13380 }
13381 } else {
13382 if IsEqual(errs, nil) {
13383 t.Fatalf("Index: %d luhn_checksum failed Error: %s", i, errs)
13384 } else {
13385 val := getError(errs, "", "")
13386 if val.Tag() != "luhn_checksum" {
13387 t.Fatalf("Index: %d luhn_checksum failed Error: %s", i, errs)
13388 }
13389 }
13390 }
13391 }
13392 }
13393
13394 func TestMultiOrOperatorGroup(t *testing.T) {
13395 tests := []struct {
13396 Value int `validate:"eq=1|gte=5,eq=1|lt=7"`
13397 expected bool
13398 }{
13399 {1, true}, {2, false}, {5, true}, {6, true}, {8, false},
13400 }
13401
13402 validate := New()
13403
13404 for i, test := range tests {
13405 errs := validate.Struct(test)
13406 if test.expected {
13407 if !IsEqual(errs, nil) {
13408 t.Fatalf("Index: %d multi_group_of_OR_operators failed Error: %s", i, errs)
13409 }
13410 } else {
13411 if IsEqual(errs, nil) {
13412 t.Fatalf("Index: %d multi_group_of_OR_operators should have errs", i)
13413 }
13414 }
13415 }
13416 }
13417
13418 func TestCronExpressionValidation(t *testing.T) {
13419 tests := []struct {
13420 value string `validate:"cron"`
13421 tag string
13422 expected bool
13423 }{
13424 {"0 0 12 * * ?", "cron", true},
13425 {"0 15 10 ? * *", "cron", true},
13426 {"0 15 10 * * ?", "cron", true},
13427 {"0 15 10 * * ? 2005", "cron", true},
13428 {"0 15 10 ? * 6L", "cron", true},
13429 {"0 15 10 ? * 6L 2002-2005", "cron", true},
13430 {"*/20 * * * *", "cron", true},
13431 {"0 15 10 ? * MON-FRI", "cron", true},
13432 {"0 15 10 ? * 6#3", "cron", true},
13433 {"wrong", "cron", false},
13434 }
13435
13436 validate := New()
13437
13438 for i, test := range tests {
13439 errs := validate.Var(test.value, test.tag)
13440 if test.expected {
13441 if !IsEqual(errs, nil) {
13442 t.Fatalf(`Index: %d cron "%s" failed Error: %s`, i, test.value, errs)
13443 }
13444 } else {
13445 if IsEqual(errs, nil) {
13446 t.Fatalf(`Index: %d cron "%s" should have errs`, i, test.value)
13447 }
13448 }
13449 }
13450 }
13451
13452 func TestNestedStructValidation(t *testing.T) {
13453 validator := New(WithRequiredStructEnabled())
13454
13455 t.Run("required", func(t *testing.T) {
13456 type (
13457 value struct {
13458 Field string
13459 }
13460 topLevel struct {
13461 Nested value `validate:"required"`
13462 }
13463 )
13464
13465 var validationErrs ValidationErrors
13466 if errs := validator.Struct(topLevel{}); errs != nil {
13467 validationErrs = errs.(ValidationErrors)
13468 }
13469
13470 Equal(t, 1, len(validationErrs))
13471 AssertError(t, validationErrs, "topLevel.Nested", "topLevel.Nested", "Nested", "Nested", "required")
13472
13473 Equal(t, validator.Struct(topLevel{value{"potato"}}), nil)
13474 })
13475
13476 t.Run("omitempty", func(t *testing.T) {
13477 type (
13478 value struct {
13479 Field string
13480 }
13481 topLevel struct {
13482 Nested value `validate:"omitempty,required"`
13483 }
13484 )
13485
13486 errs := validator.Struct(topLevel{})
13487 Equal(t, errs, nil)
13488 })
13489
13490 t.Run("excluded_if", func(t *testing.T) {
13491 type (
13492 value struct {
13493 Field string
13494 }
13495 topLevel struct {
13496 Field string
13497 Nested value `validate:"excluded_if=Field potato"`
13498 }
13499 )
13500
13501 errs := validator.Struct(topLevel{Field: "test", Nested: value{"potato"}})
13502 Equal(t, errs, nil)
13503
13504 errs = validator.Struct(topLevel{Field: "potato"})
13505 Equal(t, errs, nil)
13506
13507 errs = validator.Struct(topLevel{Field: "potato", Nested: value{"potato"}})
13508 AssertError(t, errs, "topLevel.Nested", "topLevel.Nested", "Nested", "Nested", "excluded_if")
13509 })
13510
13511 t.Run("excluded_unless", func(t *testing.T) {
13512 type (
13513 value struct {
13514 Field string
13515 }
13516 topLevel struct {
13517 Field string
13518 Nested value `validate:"excluded_unless=Field potato"`
13519 }
13520 )
13521
13522 errs := validator.Struct(topLevel{Field: "test"})
13523 Equal(t, errs, nil)
13524
13525 errs = validator.Struct(topLevel{Field: "potato", Nested: value{"potato"}})
13526 Equal(t, errs, nil)
13527
13528 errs = validator.Struct(topLevel{Field: "test", Nested: value{"potato"}})
13529 AssertError(t, errs, "topLevel.Nested", "topLevel.Nested", "Nested", "Nested", "excluded_unless")
13530 })
13531
13532 t.Run("nonComparableField", func(t *testing.T) {
13533 type (
13534 value struct {
13535 Field []string
13536 }
13537 topLevel struct {
13538 Nested value `validate:"required"`
13539 }
13540 )
13541
13542 errs := validator.Struct(topLevel{value{[]string{}}})
13543 Equal(t, errs, nil)
13544 })
13545
13546 type (
13547 veggyBasket struct {
13548 Root string
13549 Squash string `validate:"required"`
13550 }
13551 testErr struct {
13552 path string
13553 tag string
13554 }
13555 test struct {
13556 name string
13557 err testErr
13558 value veggyBasket
13559 }
13560 )
13561
13562 if err := validator.RegisterValidation("veggy", func(f FieldLevel) bool {
13563 v, ok := f.Field().Interface().(veggyBasket)
13564 if !ok || v.Root != "potato" {
13565 return false
13566 }
13567 return true
13568 }); err != nil {
13569 t.Fatal(fmt.Errorf("failed to register potato tag: %w", err))
13570 }
13571
13572 tests := []test{
13573 {
13574 name: "valid",
13575 value: veggyBasket{"potato", "zucchini"},
13576 }, {
13577 name: "failedCustomTag",
13578 value: veggyBasket{"zucchini", "potato"},
13579 err: testErr{"topLevel.VeggyBasket", "veggy"},
13580 }, {
13581 name: "failedInnerField",
13582 value: veggyBasket{"potato", ""},
13583 err: testErr{"topLevel.VeggyBasket.Squash", "required"},
13584 }, {
13585 name: "customTagFailurePriorityCheck",
13586 value: veggyBasket{"zucchini", ""},
13587 err: testErr{"topLevel.VeggyBasket", "veggy"},
13588 },
13589 }
13590
13591 var evaluateTest = func(tt test, errs error) {
13592 if tt.err != (testErr{}) && errs != nil {
13593 Equal(t, len(errs.(ValidationErrors)), 1)
13594
13595 segments := strings.Split(tt.err.path, ".")
13596 fieldName := segments[len(segments)-1]
13597 AssertError(t, errs, tt.err.path, tt.err.path, fieldName, fieldName, tt.err.tag)
13598 }
13599
13600 shouldFail := tt.err != (testErr{})
13601 hasFailed := errs != nil
13602 if shouldFail != hasFailed {
13603 t.Fatalf("expected failure %v, got: %v with errs: %v", shouldFail, hasFailed, errs)
13604 }
13605 }
13606
13607 for _, tt := range tests {
13608 type topLevel struct {
13609 VeggyBasket veggyBasket `validate:"veggy"`
13610 }
13611
13612 t.Run(tt.name, func(t *testing.T) {
13613 evaluateTest(tt, validator.Struct(topLevel{tt.value}))
13614 })
13615 }
13616
13617
13618 for _, tt := range tests {
13619 type topLevel struct {
13620 VeggyBasket *veggyBasket `validate:"veggy"`
13621 }
13622
13623 t.Run(tt.name+"Ptr", func(t *testing.T) {
13624 evaluateTest(tt, validator.Struct(topLevel{&tt.value}))
13625 })
13626 }
13627 }
13628
13629 func TestTimeRequired(t *testing.T) {
13630 validate := New()
13631 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
13632 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
13633
13634 if name == "-" {
13635 return ""
13636 }
13637
13638 return name
13639 })
13640
13641 type TestTime struct {
13642 Time time.Time `validate:"required"`
13643 }
13644
13645 var testTime TestTime
13646
13647 err := validate.Struct(&testTime)
13648 NotEqual(t, err, nil)
13649 AssertError(t, err.(ValidationErrors), "TestTime.Time", "TestTime.Time", "Time", "Time", "required")
13650 }
13651
13652 func TestOmitNilAndRequired(t *testing.T) {
13653 type (
13654 OmitEmpty struct {
13655 Str string `validate:"omitempty,required,min=10"`
13656 StrPtr *string `validate:"omitempty,required,min=10"`
13657 Inner *OmitEmpty
13658 }
13659 OmitNil struct {
13660 Str string `validate:"omitnil,required,min=10"`
13661 StrPtr *string `validate:"omitnil,required,min=10"`
13662 Inner *OmitNil
13663 }
13664 )
13665
13666 var (
13667 validate = New(WithRequiredStructEnabled())
13668 valid = "this is the long string to pass the validation rule"
13669 )
13670
13671 t.Run("compare using valid data", func(t *testing.T) {
13672 err1 := validate.Struct(OmitEmpty{Str: valid, StrPtr: &valid, Inner: &OmitEmpty{Str: valid, StrPtr: &valid}})
13673 err2 := validate.Struct(OmitNil{Str: valid, StrPtr: &valid, Inner: &OmitNil{Str: valid, StrPtr: &valid}})
13674
13675 Equal(t, err1, nil)
13676 Equal(t, err2, nil)
13677 })
13678
13679 t.Run("compare fully empty omitempty and omitnil", func(t *testing.T) {
13680 err1 := validate.Struct(OmitEmpty{})
13681 err2 := validate.Struct(OmitNil{})
13682
13683 Equal(t, err1, nil)
13684 AssertError(t, err2, "OmitNil.Str", "OmitNil.Str", "Str", "Str", "required")
13685 })
13686
13687 t.Run("validate in deep", func(t *testing.T) {
13688 err1 := validate.Struct(OmitEmpty{Str: valid, Inner: &OmitEmpty{}})
13689 err2 := validate.Struct(OmitNil{Str: valid, Inner: &OmitNil{}})
13690
13691 Equal(t, err1, nil)
13692 AssertError(t, err2, "OmitNil.Inner.Str", "OmitNil.Inner.Str", "Str", "Str", "required")
13693 })
13694 }
13695
View as plain text