15 . "gopkg.in/go-playground/assert.v1"
17 "github.com/go-playground/locales/en"
18 "github.com/go-playground/locales/fr"
19 "github.com/go-playground/locales/nl"
20 ut "github.com/go-playground/universal-translator"
24 // - Run "go test" to run tests
25 // - Run "gocov test | gocov report" to report on test converage by file
26 // - Run "gocov test | gocov annotate -" to report on all code and functions, those ,marked with "MISS" were never called
30 // -- may be a good idea to change to output path to somewherelike /tmp
31 // go test -coverprofile cover.out && go tool cover -html=cover.out -o cover.html
34 // go test -cpuprofile cpu.out
35 // ./validator.test -test.bench=. -test.cpuprofile=cpu.prof
36 // go tool pprof validator.test cpu.prof
39 // go test -memprofile mem.out
46 F string `validate:"len=3"`
49 func (i *Impl) Foo() string {
54 Test string `validate:"required"`
57 type TestInterface struct {
61 type TestString struct {
62 BlankTag string `validate:""`
63 Required string `validate:"required"`
64 Len string `validate:"len=10"`
65 Min string `validate:"min=1"`
66 Max string `validate:"max=10"`
67 MinMax string `validate:"min=1,max=10"`
68 Lt string `validate:"lt=10"`
69 Lte string `validate:"lte=10"`
70 Gt string `validate:"gt=10"`
71 Gte string `validate:"gte=10"`
72 OmitEmpty string `validate:"omitempty,min=1,max=10"`
74 SubIgnore *SubTest `validate:"-"`
76 A string `validate:"required"`
81 type TestUint64 struct {
82 Required uint64 `validate:"required"`
83 Len uint64 `validate:"len=10"`
84 Min uint64 `validate:"min=1"`
85 Max uint64 `validate:"max=10"`
86 MinMax uint64 `validate:"min=1,max=10"`
87 OmitEmpty uint64 `validate:"omitempty,min=1,max=10"`
90 type TestFloat64 struct {
91 Required float64 `validate:"required"`
92 Len float64 `validate:"len=10"`
93 Min float64 `validate:"min=1"`
94 Max float64 `validate:"max=10"`
95 MinMax float64 `validate:"min=1,max=10"`
96 Lte float64 `validate:"lte=10"`
97 OmitEmpty float64 `validate:"omitempty,min=1,max=10"`
100 type TestSlice struct {
101 Required []int `validate:"required"`
102 Len []int `validate:"len=10"`
103 Min []int `validate:"min=1"`
104 Max []int `validate:"max=10"`
105 MinMax []int `validate:"min=1,max=10"`
106 OmitEmpty []int `validate:"omitempty,min=1,max=10"`
109 func AssertError(t *testing.T, err error, nsKey, structNsKey, field, structField, expectedTag string) {
111 errs := err.(ValidationErrors)
116 for i := 0; i < len(errs); i++ {
117 if errs[i].Namespace() == nsKey && errs[i].StructNamespace() == structNsKey {
124 EqualSkip(t, 2, found, true)
125 NotEqualSkip(t, 2, fe, nil)
126 EqualSkip(t, 2, fe.Field(), field)
127 EqualSkip(t, 2, fe.StructField(), structField)
128 EqualSkip(t, 2, fe.Tag(), expectedTag)
131 func getError(err error, nsKey, structNsKey string) FieldError {
133 errs := err.(ValidationErrors)
137 for i := 0; i < len(errs); i++ {
138 if errs[i].Namespace() == nsKey && errs[i].StructNamespace() == structNsKey {
151 func (v valuer) Value() (driver.Value, error) {
153 if v.Name == "errorme" {
154 panic("SQL Driver Valuer error: some kind of error")
155 // return nil, errors.New("some kind of error")
158 if len(v.Name) == 0 {
165 type MadeUpCustomType struct {
170 func ValidateCustomType(field reflect.Value) interface{} {
172 if cust, ok := field.Interface().(MadeUpCustomType); ok {
174 if len(cust.FirstName) == 0 || len(cust.LastName) == 0 {
178 return cust.FirstName + " " + cust.LastName
184 func OverrideIntTypeForSomeReason(field reflect.Value) interface{} {
186 if i, ok := field.Interface().(int); ok {
199 type CustomMadeUpStruct struct {
200 MadeUp MadeUpCustomType `validate:"required"`
201 OverriddenInt int `validate:"gt=1"`
204 func ValidateValuerType(field reflect.Value) interface{} {
206 if valuer, ok := field.Interface().(driver.Valuer); ok {
208 val, err := valuer.Value()
210 // handle the error how you want
220 type TestPartial struct {
222 BlankTag string `validate:""`
223 Required string `validate:"required"`
224 SubSlice []*SubTest `validate:"required,dive"`
226 SubIgnore *SubTest `validate:"-"`
228 A string `validate:"required"`
229 ASubSlice []*SubTest `validate:"required,dive"`
231 SubAnonStruct []struct {
232 Test string `validate:"required"`
233 OtherTest string `validate:"required"`
234 } `validate:"required,dive"`
238 type TestStruct struct {
239 String string `validate:"required" json:"StringVal"`
242 func StructValidationTestStructSuccess(sl StructLevel) {
244 st := sl.Current().Interface().(TestStruct)
246 if st.String != "good value" {
247 sl.ReportError(st.String, "StringVal", "String", "badvalueteststruct", "good value")
251 func StructValidationTestStruct(sl StructLevel) {
253 st := sl.Current().Interface().(TestStruct)
255 if st.String != "bad value" {
256 sl.ReportError(st.String, "StringVal", "String", "badvalueteststruct", "bad value")
260 func StructValidationNoTestStructCustomName(sl StructLevel) {
262 st := sl.Current().Interface().(TestStruct)
264 if st.String != "bad value" {
265 sl.ReportError(st.String, "String", "", "badvalueteststruct", "bad value")
269 func StructValidationTestStructInvalid(sl StructLevel) {
271 st := sl.Current().Interface().(TestStruct)
273 if st.String != "bad value" {
274 sl.ReportError(nil, "StringVal", "String", "badvalueteststruct", "bad value")
278 func StructValidationTestStructReturnValidationErrors(sl StructLevel) {
280 s := sl.Current().Interface().(TestStructReturnValidationErrors)
282 errs := sl.Validator().Struct(s.Inner1.Inner2)
287 sl.ReportValidationErrors("Inner1.", "Inner1.", errs.(ValidationErrors))
290 func StructValidationTestStructReturnValidationErrors2(sl StructLevel) {
292 s := sl.Current().Interface().(TestStructReturnValidationErrors)
294 errs := sl.Validator().Struct(s.Inner1.Inner2)
299 sl.ReportValidationErrors("Inner1JSON.", "Inner1.", errs.(ValidationErrors))
302 type TestStructReturnValidationErrorsInner2 struct {
303 String string `validate:"required" json:"JSONString"`
306 type TestStructReturnValidationErrorsInner1 struct {
307 Inner2 *TestStructReturnValidationErrorsInner2
310 type TestStructReturnValidationErrors struct {
311 Inner1 *TestStructReturnValidationErrorsInner1 `json:"Inner1JSON"`
314 type StructLevelInvalidErr struct {
318 func StructLevelInvalidError(sl StructLevel) {
320 top := sl.Top().Interface().(StructLevelInvalidErr)
321 s := sl.Current().Interface().(StructLevelInvalidErr)
323 if top.Value == s.Value {
324 sl.ReportError(nil, "Value", "Value", "required", "")
328 func TestStructLevelInvalidError(t *testing.T) {
331 validate.RegisterStructValidation(StructLevelInvalidError, StructLevelInvalidErr{})
333 var test StructLevelInvalidErr
335 err := validate.Struct(test)
336 NotEqual(t, err, nil)
338 errs, ok := err.(ValidationErrors)
342 Equal(t, fe.Field(), "Value")
343 Equal(t, fe.StructField(), "Value")
344 Equal(t, fe.Namespace(), "StructLevelInvalidErr.Value")
345 Equal(t, fe.StructNamespace(), "StructLevelInvalidErr.Value")
346 Equal(t, fe.Tag(), "required")
347 Equal(t, fe.ActualTag(), "required")
348 Equal(t, fe.Kind(), reflect.Invalid)
349 Equal(t, fe.Type(), reflect.TypeOf(nil))
352 func TestNameNamespace(t *testing.T) {
354 type Inner2Namespace struct {
355 String []string `validate:"dive,required" json:"JSONString"`
358 type Inner1Namespace struct {
359 Inner2 *Inner2Namespace `json:"Inner2JSON"`
362 type Namespace struct {
363 Inner1 *Inner1Namespace `json:"Inner1JSON"`
367 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
368 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
377 i2 := &Inner2Namespace{String: []string{"ok", "ok", "ok"}}
378 i1 := &Inner1Namespace{Inner2: i2}
379 ns := &Namespace{Inner1: i1}
381 errs := validate.Struct(ns)
386 errs = validate.Struct(ns)
387 NotEqual(t, errs, nil)
389 ve := errs.(ValidationErrors)
391 AssertError(t, errs, "Namespace.Inner1JSON.Inner2JSON.JSONString[1]", "Namespace.Inner1.Inner2.String[1]", "JSONString[1]", "String[1]", "required")
393 fe := getError(ve, "Namespace.Inner1JSON.Inner2JSON.JSONString[1]", "Namespace.Inner1.Inner2.String[1]")
395 Equal(t, fe.Field(), "JSONString[1]")
396 Equal(t, fe.StructField(), "String[1]")
397 Equal(t, fe.Namespace(), "Namespace.Inner1JSON.Inner2JSON.JSONString[1]")
398 Equal(t, fe.StructNamespace(), "Namespace.Inner1.Inner2.String[1]")
401 func TestAnonymous(t *testing.T) {
404 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
405 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
416 A string `validate:"required" json:"EH"`
419 B string `validate:"required" json:"BEE"`
422 c string `validate:"required"`
428 A string `validate:"required" json:"EH"`
433 B string `validate:"required" json:"BEE"`
438 c string `validate:"required"`
444 err := validate.Struct(tst)
445 NotEqual(t, err, nil)
447 errs := err.(ValidationErrors)
449 Equal(t, len(errs), 1)
450 AssertError(t, errs, "Test.AnonymousB.BEE", "Test.AnonymousB.B", "BEE", "B", "required")
452 fe := getError(errs, "Test.AnonymousB.BEE", "Test.AnonymousB.B")
454 Equal(t, fe.Field(), "BEE")
455 Equal(t, fe.StructField(), "B")
458 c string `validate:"required"`
463 err = validate.Struct(s)
467 func TestAnonymousSameStructDifferentTags(t *testing.T) {
470 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
471 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
486 A string `validate:"required"`
492 err := validate.Struct(tst)
493 NotEqual(t, err, nil)
495 errs := err.(ValidationErrors)
497 Equal(t, len(errs), 1)
498 AssertError(t, errs, "Test.A.A", "Test.A.A", "A", "A", "required")
502 A string `validate:"omitempty,required"`
508 err = validate.Struct(tst)
512 func TestStructLevelReturnValidationErrors(t *testing.T) {
515 validate.RegisterStructValidation(StructValidationTestStructReturnValidationErrors, TestStructReturnValidationErrors{})
517 inner2 := &TestStructReturnValidationErrorsInner2{
521 inner1 := &TestStructReturnValidationErrorsInner1{
525 val := &TestStructReturnValidationErrors{
529 errs := validate.Struct(val)
534 errs = validate.Struct(val)
535 NotEqual(t, errs, nil)
536 Equal(t, len(errs.(ValidationErrors)), 2)
537 AssertError(t, errs, "TestStructReturnValidationErrors.Inner1.Inner2.String", "TestStructReturnValidationErrors.Inner1.Inner2.String", "String", "String", "required")
538 // this is an extra error reported from struct validation
539 AssertError(t, errs, "TestStructReturnValidationErrors.Inner1.TestStructReturnValidationErrorsInner2.String", "TestStructReturnValidationErrors.Inner1.TestStructReturnValidationErrorsInner2.String", "String", "String", "required")
542 func TestStructLevelReturnValidationErrorsWithJSON(t *testing.T) {
545 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
546 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
554 validate.RegisterStructValidation(StructValidationTestStructReturnValidationErrors2, TestStructReturnValidationErrors{})
556 inner2 := &TestStructReturnValidationErrorsInner2{
560 inner1 := &TestStructReturnValidationErrorsInner1{
564 val := &TestStructReturnValidationErrors{
568 errs := validate.Struct(val)
573 errs = validate.Struct(val)
574 NotEqual(t, errs, nil)
575 Equal(t, len(errs.(ValidationErrors)), 2)
576 AssertError(t, errs, "TestStructReturnValidationErrors.Inner1JSON.Inner2.JSONString", "TestStructReturnValidationErrors.Inner1.Inner2.String", "JSONString", "String", "required")
577 // this is an extra error reported from struct validation, it's a badly formatted one, but on purpose
578 AssertError(t, errs, "TestStructReturnValidationErrors.Inner1JSON.TestStructReturnValidationErrorsInner2.JSONString", "TestStructReturnValidationErrors.Inner1.TestStructReturnValidationErrorsInner2.String", "JSONString", "String", "required")
580 fe := getError(errs, "TestStructReturnValidationErrors.Inner1JSON.Inner2.JSONString", "TestStructReturnValidationErrors.Inner1.Inner2.String")
583 // check for proper JSON namespace
584 Equal(t, fe.Field(), "JSONString")
585 Equal(t, fe.StructField(), "String")
586 Equal(t, fe.Namespace(), "TestStructReturnValidationErrors.Inner1JSON.Inner2.JSONString")
587 Equal(t, fe.StructNamespace(), "TestStructReturnValidationErrors.Inner1.Inner2.String")
589 fe = getError(errs, "TestStructReturnValidationErrors.Inner1JSON.TestStructReturnValidationErrorsInner2.JSONString", "TestStructReturnValidationErrors.Inner1.TestStructReturnValidationErrorsInner2.String")
592 // check for proper JSON namespace
593 Equal(t, fe.Field(), "JSONString")
594 Equal(t, fe.StructField(), "String")
595 Equal(t, fe.Namespace(), "TestStructReturnValidationErrors.Inner1JSON.TestStructReturnValidationErrorsInner2.JSONString")
596 Equal(t, fe.StructNamespace(), "TestStructReturnValidationErrors.Inner1.TestStructReturnValidationErrorsInner2.String")
599 func TestStructLevelValidations(t *testing.T) {
602 v1.RegisterStructValidation(StructValidationTestStruct, TestStruct{})
605 String: "good value",
608 errs := v1.Struct(tst)
609 NotEqual(t, errs, nil)
610 AssertError(t, errs, "TestStruct.StringVal", "TestStruct.String", "StringVal", "String", "badvalueteststruct")
613 v2.RegisterStructValidation(StructValidationNoTestStructCustomName, TestStruct{})
615 errs = v2.Struct(tst)
616 NotEqual(t, errs, nil)
617 AssertError(t, errs, "TestStruct.String", "TestStruct.String", "String", "String", "badvalueteststruct")
620 v3.RegisterStructValidation(StructValidationTestStructInvalid, TestStruct{})
622 errs = v3.Struct(tst)
623 NotEqual(t, errs, nil)
624 AssertError(t, errs, "TestStruct.StringVal", "TestStruct.String", "StringVal", "String", "badvalueteststruct")
627 v4.RegisterStructValidation(StructValidationTestStructSuccess, TestStruct{})
629 errs = v4.Struct(tst)
633 func TestAliasTags(t *testing.T) {
636 validate.RegisterAlias("iscoloralias", "hexcolor|rgb|rgba|hsl|hsla")
638 s := "rgb(255,255,255)"
639 errs := validate.Var(s, "iscoloralias")
643 errs = validate.Var(s, "omitempty,iscoloralias")
647 errs = validate.Var(s, "iscoloralias,len=5")
648 NotEqual(t, errs, nil)
649 AssertError(t, errs, "", "", "", "", "len")
652 Color string `validate:"iscoloralias"`
659 errs = validate.Struct(tst)
663 errs = validate.Struct(tst)
664 NotEqual(t, errs, nil)
665 AssertError(t, errs, "Test.Color", "Test.Color", "Color", "Color", "iscoloralias")
667 fe := getError(errs, "Test.Color", "Test.Color")
669 Equal(t, fe.ActualTag(), "hexcolor|rgb|rgba|hsl|hsla")
671 validate.RegisterAlias("req", "required,dive,iscoloralias")
672 arr := []string{"val1", "#fff", "#000"}
674 errs = validate.Var(arr, "req")
675 NotEqual(t, errs, nil)
676 AssertError(t, errs, "[0]", "[0]", "[0]", "[0]", "iscoloralias")
678 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")
681 func TestNilValidator(t *testing.T) {
683 type TestStruct struct {
684 Test string `validate:"required"`
691 fn := func(fl FieldLevel) bool {
693 return fl.Parent().String() == fl.Field().String()
696 PanicMatches(t, func() { val.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{}) }, "runtime error: invalid memory address or nil pointer dereference")
697 PanicMatches(t, func() { val.RegisterValidation("something", fn) }, "runtime error: invalid memory address or nil pointer dereference")
698 PanicMatches(t, func() { val.Var(ts.Test, "required") }, "runtime error: invalid memory address or nil pointer dereference")
699 PanicMatches(t, func() { val.VarWithValue("test", ts.Test, "required") }, "runtime error: invalid memory address or nil pointer dereference")
700 PanicMatches(t, func() { val.Struct(ts) }, "runtime error: invalid memory address or nil pointer dereference")
701 PanicMatches(t, func() { val.StructExcept(ts, "Test") }, "runtime error: invalid memory address or nil pointer dereference")
702 PanicMatches(t, func() { val.StructPartial(ts, "Test") }, "runtime error: invalid memory address or nil pointer dereference")
705 func TestStructPartial(t *testing.T) {
727 tPartial := &TestPartial{
729 Required: "Required",
731 SubSlice: []*SubTest{
749 A string `validate:"required"`
750 ASubSlice []*SubTest `validate:"required,dive"`
751 SubAnonStruct []struct {
752 Test string `validate:"required"`
753 OtherTest string `validate:"required"`
754 } `validate:"required,dive"`
757 ASubSlice: []*SubTest{
766 SubAnonStruct: []struct {
767 Test string `validate:"required"`
768 OtherTest string `validate:"required"`
770 {"Required", "RequiredOther"},
771 {"Required", "RequiredOther"},
778 // the following should all return no errors as everything is valid in
780 errs := validate.StructPartialCtx(context.Background(), tPartial, p1...)
783 errs = validate.StructPartial(tPartial, p2...)
786 // this isn't really a robust test, but is ment to illustrate the ANON CASE below
787 errs = validate.StructPartial(tPartial.SubSlice[0], p3...)
790 errs = validate.StructExceptCtx(context.Background(), tPartial, p1...)
793 errs = validate.StructExcept(tPartial, p2...)
796 // mod tParial for required feild and re-test making sure invalid fields are NOT required:
797 tPartial.Required = ""
799 errs = validate.StructExcept(tPartial, p1...)
802 errs = validate.StructPartial(tPartial, p2...)
805 // inversion and retesting Partial to generate failures:
806 errs = validate.StructPartial(tPartial, p1...)
807 NotEqual(t, errs, nil)
808 AssertError(t, errs, "TestPartial.Required", "TestPartial.Required", "Required", "Required", "required")
810 errs = validate.StructExcept(tPartial, p2...)
811 AssertError(t, errs, "TestPartial.Required", "TestPartial.Required", "Required", "Required", "required")
813 // reset Required field, and set nested struct
814 tPartial.Required = "Required"
815 tPartial.Anonymous.A = ""
817 // will pass as unset feilds is not going to be tested
818 errs = validate.StructPartial(tPartial, p1...)
821 errs = validate.StructExcept(tPartial, p2...)
824 // ANON CASE the response here is strange, it clearly does what it is being told to
825 errs = validate.StructExcept(tPartial.Anonymous, p4...)
828 // will fail as unset feild is tested
829 errs = validate.StructPartial(tPartial, p2...)
830 NotEqual(t, errs, nil)
831 AssertError(t, errs, "TestPartial.Anonymous.A", "TestPartial.Anonymous.A", "A", "A", "required")
833 errs = validate.StructExcept(tPartial, p1...)
834 NotEqual(t, errs, nil)
835 AssertError(t, errs, "TestPartial.Anonymous.A", "TestPartial.Anonymous.A", "A", "A", "required")
837 // reset nested struct and unset struct in slice
838 tPartial.Anonymous.A = "Required"
839 tPartial.SubSlice[0].Test = ""
841 // these will pass as unset item is NOT tested
842 errs = validate.StructPartial(tPartial, p1...)
845 errs = validate.StructExcept(tPartial, p2...)
848 // these will fail as unset item IS tested
849 errs = validate.StructExcept(tPartial, p1...)
850 AssertError(t, errs, "TestPartial.SubSlice[0].Test", "TestPartial.SubSlice[0].Test", "Test", "Test", "required")
851 Equal(t, len(errs.(ValidationErrors)), 1)
853 errs = validate.StructPartial(tPartial, p2...)
854 NotEqual(t, errs, nil)
855 AssertError(t, errs, "TestPartial.SubSlice[0].Test", "TestPartial.SubSlice[0].Test", "Test", "Test", "required")
856 Equal(t, len(errs.(ValidationErrors)), 1)
858 // Unset second slice member concurrently to test dive behavior:
859 tPartial.SubSlice[1].Test = ""
861 errs = validate.StructPartial(tPartial, p1...)
864 // NOTE: When specifying nested items, it is still the users responsibility
865 // to specify the dive tag, the library does not override this.
866 errs = validate.StructExcept(tPartial, p2...)
867 NotEqual(t, errs, nil)
868 AssertError(t, errs, "TestPartial.SubSlice[1].Test", "TestPartial.SubSlice[1].Test", "Test", "Test", "required")
870 errs = validate.StructExcept(tPartial, p1...)
871 Equal(t, len(errs.(ValidationErrors)), 2)
872 AssertError(t, errs, "TestPartial.SubSlice[0].Test", "TestPartial.SubSlice[0].Test", "Test", "Test", "required")
873 AssertError(t, errs, "TestPartial.SubSlice[1].Test", "TestPartial.SubSlice[1].Test", "Test", "Test", "required")
875 errs = validate.StructPartial(tPartial, p2...)
876 NotEqual(t, errs, nil)
877 Equal(t, len(errs.(ValidationErrors)), 1)
878 AssertError(t, errs, "TestPartial.SubSlice[0].Test", "TestPartial.SubSlice[0].Test", "Test", "Test", "required")
880 // reset struct in slice, and unset struct in slice in unset posistion
881 tPartial.SubSlice[0].Test = "Required"
883 // these will pass as the unset item is NOT tested
884 errs = validate.StructPartial(tPartial, p1...)
887 errs = validate.StructPartial(tPartial, p2...)
890 // testing for missing item by exception, yes it dives and fails
891 errs = validate.StructExcept(tPartial, p1...)
892 NotEqual(t, errs, nil)
893 Equal(t, len(errs.(ValidationErrors)), 1)
894 AssertError(t, errs, "TestPartial.SubSlice[1].Test", "TestPartial.SubSlice[1].Test", "Test", "Test", "required")
896 errs = validate.StructExcept(tPartial, p2...)
897 NotEqual(t, errs, nil)
898 AssertError(t, errs, "TestPartial.SubSlice[1].Test", "TestPartial.SubSlice[1].Test", "Test", "Test", "required")
900 tPartial.SubSlice[1].Test = "Required"
902 tPartial.Anonymous.SubAnonStruct[0].Test = ""
903 // these will pass as the unset item is NOT tested
904 errs = validate.StructPartial(tPartial, p1...)
907 errs = validate.StructPartial(tPartial, p2...)
910 errs = validate.StructExcept(tPartial, p1...)
911 NotEqual(t, errs, nil)
912 AssertError(t, errs, "TestPartial.Anonymous.SubAnonStruct[0].Test", "TestPartial.Anonymous.SubAnonStruct[0].Test", "Test", "Test", "required")
914 errs = validate.StructExcept(tPartial, p2...)
915 NotEqual(t, errs, nil)
916 AssertError(t, errs, "TestPartial.Anonymous.SubAnonStruct[0].Test", "TestPartial.Anonymous.SubAnonStruct[0].Test", "Test", "Test", "required")
920 func TestCrossStructLteFieldValidation(t *testing.T) {
933 CreatedAt *time.Time `validate:"ltecsfield=Inner.CreatedAt"`
934 String string `validate:"ltecsfield=Inner.String"`
935 Int int `validate:"ltecsfield=Inner.Int"`
936 Uint uint `validate:"ltecsfield=Inner.Uint"`
937 Float float64 `validate:"ltecsfield=Inner.Float"`
938 Array []string `validate:"ltecsfield=Inner.Array"`
941 now := time.Now().UTC()
942 then := now.Add(time.Hour * 5)
950 Array: []string{"val1", "val2"},
960 Array: []string{"val1"},
964 errs := validate.Struct(test)
967 test.CreatedAt = &then
972 test.Array = []string{"val1", "val2"}
974 errs = validate.Struct(test)
977 after := now.Add(time.Hour * 10)
979 test.CreatedAt = &after
984 test.Array = []string{"val1", "val2", "val3"}
986 errs = validate.Struct(test)
987 NotEqual(t, errs, nil)
988 AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "ltecsfield")
989 AssertError(t, errs, "Test.String", "Test.String", "String", "String", "ltecsfield")
990 AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "ltecsfield")
991 AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "ltecsfield")
992 AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "ltecsfield")
993 AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "ltecsfield")
995 errs = validate.VarWithValueCtx(context.Background(), 1, "", "ltecsfield")
996 NotEqual(t, errs, nil)
997 AssertError(t, errs, "", "", "", "", "ltecsfield")
999 // this test is for the WARNING about unforseen validation issues.
1000 errs = validate.VarWithValue(test, now, "ltecsfield")
1001 NotEqual(t, errs, nil)
1002 Equal(t, len(errs.(ValidationErrors)), 6)
1003 AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "ltecsfield")
1004 AssertError(t, errs, "Test.String", "Test.String", "String", "String", "ltecsfield")
1005 AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "ltecsfield")
1006 AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "ltecsfield")
1007 AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "ltecsfield")
1008 AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "ltecsfield")
1016 Time time.Time `validate:"ltecsfield=Value"`
1020 Value: Other{Value: "StringVal"},
1024 errs = validate.Struct(tst)
1025 NotEqual(t, errs, nil)
1026 AssertError(t, errs, "Test2.Time", "Test2.Time", "Time", "Time", "ltecsfield")
1029 func TestCrossStructLtFieldValidation(t *testing.T) {
1032 CreatedAt *time.Time
1042 CreatedAt *time.Time `validate:"ltcsfield=Inner.CreatedAt"`
1043 String string `validate:"ltcsfield=Inner.String"`
1044 Int int `validate:"ltcsfield=Inner.Int"`
1045 Uint uint `validate:"ltcsfield=Inner.Uint"`
1046 Float float64 `validate:"ltcsfield=Inner.Float"`
1047 Array []string `validate:"ltcsfield=Inner.Array"`
1050 now := time.Now().UTC()
1051 then := now.Add(time.Hour * 5)
1059 Array: []string{"val1", "val2"},
1069 Array: []string{"val1"},
1073 errs := validate.Struct(test)
1076 test.CreatedAt = &then
1077 test.String = "abcd"
1081 test.Array = []string{"val1", "val2"}
1083 errs = validate.Struct(test)
1084 NotEqual(t, errs, nil)
1085 AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "ltcsfield")
1086 AssertError(t, errs, "Test.String", "Test.String", "String", "String", "ltcsfield")
1087 AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "ltcsfield")
1088 AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "ltcsfield")
1089 AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "ltcsfield")
1090 AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "ltcsfield")
1092 errs = validate.VarWithValue(1, "", "ltcsfield")
1093 NotEqual(t, errs, nil)
1094 AssertError(t, errs, "", "", "", "", "ltcsfield")
1096 // this test is for the WARNING about unforseen validation issues.
1097 errs = validate.VarWithValue(test, now, "ltcsfield")
1098 NotEqual(t, errs, nil)
1099 AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "ltcsfield")
1100 AssertError(t, errs, "Test.String", "Test.String", "String", "String", "ltcsfield")
1101 AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "ltcsfield")
1102 AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "ltcsfield")
1103 AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "ltcsfield")
1104 AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "ltcsfield")
1112 Time time.Time `validate:"ltcsfield=Value"`
1116 Value: Other{Value: "StringVal"},
1120 errs = validate.Struct(tst)
1121 NotEqual(t, errs, nil)
1122 AssertError(t, errs, "Test2.Time", "Test2.Time", "Time", "Time", "ltcsfield")
1125 func TestCrossStructGteFieldValidation(t *testing.T) {
1128 CreatedAt *time.Time
1138 CreatedAt *time.Time `validate:"gtecsfield=Inner.CreatedAt"`
1139 String string `validate:"gtecsfield=Inner.String"`
1140 Int int `validate:"gtecsfield=Inner.Int"`
1141 Uint uint `validate:"gtecsfield=Inner.Uint"`
1142 Float float64 `validate:"gtecsfield=Inner.Float"`
1143 Array []string `validate:"gtecsfield=Inner.Array"`
1146 now := time.Now().UTC()
1147 then := now.Add(time.Hour * -5)
1155 Array: []string{"val1", "val2"},
1165 Array: []string{"val1", "val2", "val3"},
1169 errs := validate.Struct(test)
1172 test.CreatedAt = &then
1173 test.String = "abcd"
1177 test.Array = []string{"val1", "val2"}
1179 errs = validate.Struct(test)
1182 before := now.Add(time.Hour * -10)
1184 test.CreatedAt = &before
1189 test.Array = []string{"val1"}
1191 errs = validate.Struct(test)
1192 NotEqual(t, errs, nil)
1193 AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "gtecsfield")
1194 AssertError(t, errs, "Test.String", "Test.String", "String", "String", "gtecsfield")
1195 AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "gtecsfield")
1196 AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "gtecsfield")
1197 AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "gtecsfield")
1198 AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "gtecsfield")
1200 errs = validate.VarWithValue(1, "", "gtecsfield")
1201 NotEqual(t, errs, nil)
1202 AssertError(t, errs, "", "", "", "", "gtecsfield")
1204 // this test is for the WARNING about unforseen validation issues.
1205 errs = validate.VarWithValue(test, now, "gtecsfield")
1206 NotEqual(t, errs, nil)
1207 AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "gtecsfield")
1208 AssertError(t, errs, "Test.String", "Test.String", "String", "String", "gtecsfield")
1209 AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "gtecsfield")
1210 AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "gtecsfield")
1211 AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "gtecsfield")
1212 AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "gtecsfield")
1220 Time time.Time `validate:"gtecsfield=Value"`
1224 Value: Other{Value: "StringVal"},
1228 errs = validate.Struct(tst)
1229 NotEqual(t, errs, nil)
1230 AssertError(t, errs, "Test2.Time", "Test2.Time", "Time", "Time", "gtecsfield")
1233 func TestCrossStructGtFieldValidation(t *testing.T) {
1236 CreatedAt *time.Time
1246 CreatedAt *time.Time `validate:"gtcsfield=Inner.CreatedAt"`
1247 String string `validate:"gtcsfield=Inner.String"`
1248 Int int `validate:"gtcsfield=Inner.Int"`
1249 Uint uint `validate:"gtcsfield=Inner.Uint"`
1250 Float float64 `validate:"gtcsfield=Inner.Float"`
1251 Array []string `validate:"gtcsfield=Inner.Array"`
1254 now := time.Now().UTC()
1255 then := now.Add(time.Hour * -5)
1263 Array: []string{"val1", "val2"},
1273 Array: []string{"val1", "val2", "val3"},
1277 errs := validate.Struct(test)
1280 test.CreatedAt = &then
1281 test.String = "abcd"
1285 test.Array = []string{"val1", "val2"}
1287 errs = validate.Struct(test)
1288 NotEqual(t, errs, nil)
1289 AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "gtcsfield")
1290 AssertError(t, errs, "Test.String", "Test.String", "String", "String", "gtcsfield")
1291 AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "gtcsfield")
1292 AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "gtcsfield")
1293 AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "gtcsfield")
1294 AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "gtcsfield")
1296 errs = validate.VarWithValue(1, "", "gtcsfield")
1297 NotEqual(t, errs, nil)
1298 AssertError(t, errs, "", "", "", "", "gtcsfield")
1300 // this test is for the WARNING about unforseen validation issues.
1301 errs = validate.VarWithValue(test, now, "gtcsfield")
1302 NotEqual(t, errs, nil)
1303 AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "gtcsfield")
1304 AssertError(t, errs, "Test.String", "Test.String", "String", "String", "gtcsfield")
1305 AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "gtcsfield")
1306 AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "gtcsfield")
1307 AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "gtcsfield")
1308 AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "gtcsfield")
1316 Time time.Time `validate:"gtcsfield=Value"`
1320 Value: Other{Value: "StringVal"},
1324 errs = validate.Struct(tst)
1325 NotEqual(t, errs, nil)
1326 AssertError(t, errs, "Test2.Time", "Test2.Time", "Time", "Time", "gtcsfield")
1329 func TestCrossStructNeFieldValidation(t *testing.T) {
1332 CreatedAt *time.Time
1337 CreatedAt *time.Time `validate:"necsfield=Inner.CreatedAt"`
1340 now := time.Now().UTC()
1341 then := now.Add(time.Hour * 5)
1353 errs := validate.Struct(test)
1356 test.CreatedAt = &then
1358 errs = validate.Struct(test)
1359 NotEqual(t, errs, nil)
1360 AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "necsfield")
1370 arr := []string{"test"}
1376 arr2 := []string{"test"}
1377 arr3 := []string{"test", "test2"}
1380 errs = validate.VarWithValue(s, s2, "necsfield")
1381 NotEqual(t, errs, nil)
1382 AssertError(t, errs, "", "", "", "", "necsfield")
1384 errs = validate.VarWithValue(i2, i, "necsfield")
1385 NotEqual(t, errs, nil)
1386 AssertError(t, errs, "", "", "", "", "necsfield")
1388 errs = validate.VarWithValue(j2, j, "necsfield")
1389 NotEqual(t, errs, nil)
1390 AssertError(t, errs, "", "", "", "", "necsfield")
1392 errs = validate.VarWithValue(k2, k, "necsfield")
1393 NotEqual(t, errs, nil)
1394 AssertError(t, errs, "", "", "", "", "necsfield")
1396 errs = validate.VarWithValue(arr2, arr, "necsfield")
1397 NotEqual(t, errs, nil)
1398 AssertError(t, errs, "", "", "", "", "necsfield")
1400 errs = validate.VarWithValue(now2, now, "necsfield")
1401 NotEqual(t, errs, nil)
1402 AssertError(t, errs, "", "", "", "", "necsfield")
1404 errs = validate.VarWithValue(arr3, arr, "necsfield")
1407 type SInner struct {
1411 type TStruct struct {
1413 CreatedAt *time.Time `validate:"necsfield=Inner"`
1425 errs = validate.Struct(test2)
1429 errs = validate.Struct(test2)
1432 errs = validate.VarWithValue(nil, 1, "necsfield")
1433 NotEqual(t, errs, nil)
1434 AssertError(t, errs, "", "", "", "", "necsfield")
1437 func TestCrossStructEqFieldValidation(t *testing.T) {
1440 CreatedAt *time.Time
1445 CreatedAt *time.Time `validate:"eqcsfield=Inner.CreatedAt"`
1448 now := time.Now().UTC()
1460 errs := validate.Struct(test)
1463 newTime := time.Now().UTC()
1464 test.CreatedAt = &newTime
1466 errs = validate.Struct(test)
1467 NotEqual(t, errs, nil)
1468 AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "eqcsfield")
1476 arr := []string{"test"}
1484 arr2 := []string{"test"}
1485 arr3 := []string{"test", "test2"}
1488 errs = validate.VarWithValue(s, s2, "eqcsfield")
1491 errs = validate.VarWithValue(i2, i, "eqcsfield")
1494 errs = validate.VarWithValue(j2, j, "eqcsfield")
1497 errs = validate.VarWithValue(k2, k, "eqcsfield")
1500 errs = validate.VarWithValue(arr2, arr, "eqcsfield")
1503 errs = validate.VarWithValue(now2, now, "eqcsfield")
1506 errs = validate.VarWithValue(arr3, arr, "eqcsfield")
1507 NotEqual(t, errs, nil)
1508 AssertError(t, errs, "", "", "", "", "eqcsfield")
1510 type SInner struct {
1514 type TStruct struct {
1516 CreatedAt *time.Time `validate:"eqcsfield=Inner"`
1528 errs = validate.Struct(test2)
1529 NotEqual(t, errs, nil)
1530 AssertError(t, errs, "TStruct.CreatedAt", "TStruct.CreatedAt", "CreatedAt", "CreatedAt", "eqcsfield")
1533 errs = validate.Struct(test2)
1534 NotEqual(t, errs, nil)
1535 AssertError(t, errs, "TStruct.CreatedAt", "TStruct.CreatedAt", "CreatedAt", "CreatedAt", "eqcsfield")
1537 errs = validate.VarWithValue(nil, 1, "eqcsfield")
1538 NotEqual(t, errs, nil)
1539 AssertError(t, errs, "", "", "", "", "eqcsfield")
1542 func TestCrossNamespaceFieldValidation(t *testing.T) {
1544 type SliceStruct struct {
1548 type MapStruct struct {
1553 CreatedAt *time.Time
1555 SliceStructs []*SliceStruct
1556 SliceSlice [][]string
1557 SliceSliceStruct [][]*SliceStruct
1558 SliceMap []map[string]string
1559 Map map[string]string
1560 MapMap map[string]map[string]string
1561 MapStructs map[string]*SliceStruct
1562 MapMapStruct map[string]map[string]*SliceStruct
1563 MapSlice map[string][]string
1564 MapInt map[int]string
1565 MapInt8 map[int8]string
1566 MapInt16 map[int16]string
1567 MapInt32 map[int32]string
1568 MapInt64 map[int64]string
1569 MapUint map[uint]string
1570 MapUint8 map[uint8]string
1571 MapUint16 map[uint16]string
1572 MapUint32 map[uint32]string
1573 MapUint64 map[uint64]string
1574 MapFloat32 map[float32]string
1575 MapFloat64 map[float64]string
1576 MapBool map[bool]string
1581 CreatedAt *time.Time
1588 Slice: []string{"val1", "val2", "val3"},
1589 SliceStructs: []*SliceStruct{{Name: "name1"}, {Name: "name2"}, {Name: "name3"}},
1590 SliceSlice: [][]string{{"1", "2", "3"}, {"4", "5", "6"}, {"7", "8", "9"}},
1591 SliceSliceStruct: [][]*SliceStruct{{{Name: "name1"}, {Name: "name2"}, {Name: "name3"}}, {{Name: "name4"}, {Name: "name5"}, {Name: "name6"}}, {{Name: "name7"}, {Name: "name8"}, {Name: "name9"}}},
1592 SliceMap: []map[string]string{{"key1": "val1", "key2": "val2", "key3": "val3"}, {"key4": "val4", "key5": "val5", "key6": "val6"}},
1593 Map: map[string]string{"key1": "val1", "key2": "val2", "key3": "val3"},
1594 MapStructs: map[string]*SliceStruct{"key1": {Name: "name1"}, "key2": {Name: "name2"}, "key3": {Name: "name3"}},
1595 MapMap: map[string]map[string]string{"key1": {"key1-1": "val1"}, "key2": {"key2-1": "val2"}, "key3": {"key3-1": "val3"}},
1596 MapMapStruct: map[string]map[string]*SliceStruct{"key1": {"key1-1": {Name: "name1"}}, "key2": {"key2-1": {Name: "name2"}}, "key3": {"key3-1": {Name: "name3"}}},
1597 MapSlice: map[string][]string{"key1": {"1", "2", "3"}, "key2": {"4", "5", "6"}, "key3": {"7", "8", "9"}},
1598 MapInt: map[int]string{1: "val1", 2: "val2", 3: "val3"},
1599 MapInt8: map[int8]string{1: "val1", 2: "val2", 3: "val3"},
1600 MapInt16: map[int16]string{1: "val1", 2: "val2", 3: "val3"},
1601 MapInt32: map[int32]string{1: "val1", 2: "val2", 3: "val3"},
1602 MapInt64: map[int64]string{1: "val1", 2: "val2", 3: "val3"},
1603 MapUint: map[uint]string{1: "val1", 2: "val2", 3: "val3"},
1604 MapUint8: map[uint8]string{1: "val1", 2: "val2", 3: "val3"},
1605 MapUint16: map[uint16]string{1: "val1", 2: "val2", 3: "val3"},
1606 MapUint32: map[uint32]string{1: "val1", 2: "val2", 3: "val3"},
1607 MapUint64: map[uint64]string{1: "val1", 2: "val2", 3: "val3"},
1608 MapFloat32: map[float32]string{1.01: "val1", 2.02: "val2", 3.03: "val3"},
1609 MapFloat64: map[float64]string{1.01: "val1", 2.02: "val2", 3.03: "val3"},
1610 MapBool: map[bool]string{true: "val1", false: "val2"},
1618 val := reflect.ValueOf(test)
1625 current, kind, ok := v.getStructFieldOKInternal(val, "Inner.CreatedAt")
1627 Equal(t, kind, reflect.Struct)
1628 tm, ok := current.Interface().(time.Time)
1632 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.Slice[1]")
1634 Equal(t, kind, reflect.String)
1635 Equal(t, current.String(), "val2")
1637 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.CrazyNonExistantField")
1640 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.Slice[101]")
1643 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.Map[key3]")
1645 Equal(t, kind, reflect.String)
1646 Equal(t, current.String(), "val3")
1648 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.MapMap[key2][key2-1]")
1650 Equal(t, kind, reflect.String)
1651 Equal(t, current.String(), "val2")
1653 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.MapStructs[key2].Name")
1655 Equal(t, kind, reflect.String)
1656 Equal(t, current.String(), "name2")
1658 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.MapMapStruct[key3][key3-1].Name")
1660 Equal(t, kind, reflect.String)
1661 Equal(t, current.String(), "name3")
1663 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.SliceSlice[2][0]")
1665 Equal(t, kind, reflect.String)
1666 Equal(t, current.String(), "7")
1668 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.SliceSliceStruct[2][1].Name")
1670 Equal(t, kind, reflect.String)
1671 Equal(t, current.String(), "name8")
1673 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.SliceMap[1][key5]")
1675 Equal(t, kind, reflect.String)
1676 Equal(t, current.String(), "val5")
1678 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.MapSlice[key3][2]")
1680 Equal(t, kind, reflect.String)
1681 Equal(t, current.String(), "9")
1683 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.MapInt[2]")
1685 Equal(t, kind, reflect.String)
1686 Equal(t, current.String(), "val2")
1688 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.MapInt8[2]")
1690 Equal(t, kind, reflect.String)
1691 Equal(t, current.String(), "val2")
1693 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.MapInt16[2]")
1695 Equal(t, kind, reflect.String)
1696 Equal(t, current.String(), "val2")
1698 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.MapInt32[2]")
1700 Equal(t, kind, reflect.String)
1701 Equal(t, current.String(), "val2")
1703 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.MapInt64[2]")
1705 Equal(t, kind, reflect.String)
1706 Equal(t, current.String(), "val2")
1708 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.MapUint[2]")
1710 Equal(t, kind, reflect.String)
1711 Equal(t, current.String(), "val2")
1713 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.MapUint8[2]")
1715 Equal(t, kind, reflect.String)
1716 Equal(t, current.String(), "val2")
1718 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.MapUint16[2]")
1720 Equal(t, kind, reflect.String)
1721 Equal(t, current.String(), "val2")
1723 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.MapUint32[2]")
1725 Equal(t, kind, reflect.String)
1726 Equal(t, current.String(), "val2")
1728 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.MapUint64[2]")
1730 Equal(t, kind, reflect.String)
1731 Equal(t, current.String(), "val2")
1733 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.MapFloat32[3.03]")
1735 Equal(t, kind, reflect.String)
1736 Equal(t, current.String(), "val3")
1738 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.MapFloat64[2.02]")
1740 Equal(t, kind, reflect.String)
1741 Equal(t, current.String(), "val2")
1743 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.MapBool[true]")
1745 Equal(t, kind, reflect.String)
1746 Equal(t, current.String(), "val1")
1750 Slice: []string{"val1", "val2", "val3"},
1751 SliceStructs: []*SliceStruct{{Name: "name1"}, {Name: "name2"}, nil},
1752 SliceSlice: [][]string{{"1", "2", "3"}, {"4", "5", "6"}, {"7", "8", "9"}},
1753 SliceSliceStruct: [][]*SliceStruct{{{Name: "name1"}, {Name: "name2"}, {Name: "name3"}}, {{Name: "name4"}, {Name: "name5"}, {Name: "name6"}}, {{Name: "name7"}, {Name: "name8"}, {Name: "name9"}}},
1754 SliceMap: []map[string]string{{"key1": "val1", "key2": "val2", "key3": "val3"}, {"key4": "val4", "key5": "val5", "key6": "val6"}},
1755 Map: map[string]string{"key1": "val1", "key2": "val2", "key3": "val3"},
1756 MapStructs: map[string]*SliceStruct{"key1": {Name: "name1"}, "key2": {Name: "name2"}, "key3": {Name: "name3"}},
1757 MapMap: map[string]map[string]string{"key1": {"key1-1": "val1"}, "key2": {"key2-1": "val2"}, "key3": {"key3-1": "val3"}},
1758 MapMapStruct: map[string]map[string]*SliceStruct{"key1": {"key1-1": {Name: "name1"}}, "key2": {"key2-1": {Name: "name2"}}, "key3": {"key3-1": {Name: "name3"}}},
1759 MapSlice: map[string][]string{"key1": {"1", "2", "3"}, "key2": {"4", "5", "6"}, "key3": {"7", "8", "9"}},
1767 val = reflect.ValueOf(test)
1769 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.SliceStructs[2]")
1771 Equal(t, kind, reflect.Ptr)
1772 Equal(t, current.String(), "<*validator.SliceStruct Value>")
1773 Equal(t, current.IsNil(), true)
1775 current, kind, ok = v.getStructFieldOKInternal(val, "Inner.SliceStructs[2].Name")
1777 Equal(t, kind, reflect.Ptr)
1778 Equal(t, current.String(), "<*validator.SliceStruct Value>")
1779 Equal(t, current.IsNil(), true)
1781 PanicMatches(t, func() { v.getStructFieldOKInternal(reflect.ValueOf(1), "crazyinput") }, "Invalid field namespace")
1784 func TestExistsValidation(t *testing.T) {
1786 jsonText := "{ \"truthiness2\": true }"
1789 Truthiness *bool `json:"truthiness" validate:"required"`
1794 err := json.Unmarshal([]byte(jsonText), &ting)
1796 NotEqual(t, ting, nil)
1797 Equal(t, ting.Truthiness, nil)
1800 errs := validate.Struct(ting)
1801 NotEqual(t, errs, nil)
1802 AssertError(t, errs, "Thing.Truthiness", "Thing.Truthiness", "Truthiness", "Truthiness", "required")
1804 jsonText = "{ \"truthiness\": true }"
1806 err = json.Unmarshal([]byte(jsonText), &ting)
1808 NotEqual(t, ting, nil)
1809 Equal(t, ting.Truthiness, true)
1811 errs = validate.Struct(ting)
1815 func TestSQLValue2Validation(t *testing.T) {
1818 validate.RegisterCustomTypeFunc(ValidateValuerType, valuer{}, (*driver.Valuer)(nil), sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{})
1819 validate.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{})
1820 validate.RegisterCustomTypeFunc(OverrideIntTypeForSomeReason, 1)
1826 errs := validate.Var(val, "required")
1827 NotEqual(t, errs, nil)
1828 AssertError(t, errs, "", "", "", "", "required")
1830 val.Name = "Valid Name"
1831 errs = validate.VarCtx(context.Background(), val, "required")
1834 val.Name = "errorme"
1836 PanicMatches(t, func() { validate.Var(val, "required") }, "SQL Driver Valuer error: some kind of error")
1838 type myValuer valuer
1844 errs = validate.Var(myVal, "required")
1845 NotEqual(t, errs, nil)
1846 AssertError(t, errs, "", "", "", "", "required")
1848 cust := MadeUpCustomType{
1853 c := CustomMadeUpStruct{MadeUp: cust, OverriddenInt: 2}
1855 errs = validate.Struct(c)
1858 c.MadeUp.FirstName = ""
1861 errs = validate.Struct(c)
1862 NotEqual(t, errs, nil)
1863 Equal(t, len(errs.(ValidationErrors)), 2)
1864 AssertError(t, errs, "CustomMadeUpStruct.MadeUp", "CustomMadeUpStruct.MadeUp", "MadeUp", "MadeUp", "required")
1865 AssertError(t, errs, "CustomMadeUpStruct.OverriddenInt", "CustomMadeUpStruct.OverriddenInt", "OverriddenInt", "OverriddenInt", "gt")
1868 func TestSQLValueValidation(t *testing.T) {
1871 validate.RegisterCustomTypeFunc(ValidateValuerType, (*driver.Valuer)(nil), valuer{})
1872 validate.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{})
1873 validate.RegisterCustomTypeFunc(OverrideIntTypeForSomeReason, 1)
1879 errs := validate.Var(val, "required")
1880 NotEqual(t, errs, nil)
1881 AssertError(t, errs, "", "", "", "", "required")
1883 val.Name = "Valid Name"
1884 errs = validate.Var(val, "required")
1887 val.Name = "errorme"
1889 PanicMatches(t, func() { errs = validate.Var(val, "required") }, "SQL Driver Valuer error: some kind of error")
1891 type myValuer valuer
1897 errs = validate.Var(myVal, "required")
1898 NotEqual(t, errs, nil)
1899 AssertError(t, errs, "", "", "", "", "required")
1901 cust := MadeUpCustomType{
1906 c := CustomMadeUpStruct{MadeUp: cust, OverriddenInt: 2}
1908 errs = validate.Struct(c)
1911 c.MadeUp.FirstName = ""
1914 errs = validate.Struct(c)
1915 NotEqual(t, errs, nil)
1916 Equal(t, len(errs.(ValidationErrors)), 2)
1917 AssertError(t, errs, "CustomMadeUpStruct.MadeUp", "CustomMadeUpStruct.MadeUp", "MadeUp", "MadeUp", "required")
1918 AssertError(t, errs, "CustomMadeUpStruct.OverriddenInt", "CustomMadeUpStruct.OverriddenInt", "OverriddenInt", "OverriddenInt", "gt")
1921 func TestMACValidation(t *testing.T) {
1926 {"3D:F2:C9:A6:B3:4F", true},
1927 {"3D-F2-C9-A6-B3:4F", false},
1931 {"00:25:96:FF:FE:12:34:56", true},
1932 {"0025:96FF:FE12:3456", false},
1937 for i, test := range tests {
1939 errs := validate.Var(test.param, "mac")
1942 if !IsEqual(errs, nil) {
1943 t.Fatalf("Index: %d mac failed Error: %s", i, errs)
1946 if IsEqual(errs, nil) {
1947 t.Fatalf("Index: %d mac failed Error: %s", i, errs)
1949 val := getError(errs, "", "")
1950 if val.Tag() != "mac" {
1951 t.Fatalf("Index: %d mac failed Error: %s", i, errs)
1958 func TestIPValidation(t *testing.T) {
1965 {"172.16.0.1", true},
1966 {"192.168.0.1", true},
1967 {"192.168.255.254", true},
1968 {"192.168.255.256", false},
1969 {"172.16.255.254", true},
1970 {"172.16.256.255", false},
1971 {"2001:cdba:0000:0000:0000:0000:3257:9652", true},
1972 {"2001:cdba:0:0:0:0:3257:9652", true},
1973 {"2001:cdba::3257:9652", true},
1978 for i, test := range tests {
1980 errs := validate.Var(test.param, "ip")
1983 if !IsEqual(errs, nil) {
1984 t.Fatalf("Index: %d ip failed Error: %s", i, errs)
1987 if IsEqual(errs, nil) {
1988 t.Fatalf("Index: %d ip failed Error: %s", i, errs)
1990 val := getError(errs, "", "")
1991 if val.Tag() != "ip" {
1992 t.Fatalf("Index: %d ip failed Error: %s", i, errs)
1999 func TestIPv6Validation(t *testing.T) {
2004 {"10.0.0.1", false},
2005 {"172.16.0.1", false},
2006 {"192.168.0.1", false},
2007 {"192.168.255.254", false},
2008 {"192.168.255.256", false},
2009 {"172.16.255.254", false},
2010 {"172.16.256.255", false},
2011 {"2001:cdba:0000:0000:0000:0000:3257:9652", true},
2012 {"2001:cdba:0:0:0:0:3257:9652", true},
2013 {"2001:cdba::3257:9652", true},
2018 for i, test := range tests {
2020 errs := validate.Var(test.param, "ipv6")
2023 if !IsEqual(errs, nil) {
2024 t.Fatalf("Index: %d ipv6 failed Error: %s", i, errs)
2027 if IsEqual(errs, nil) {
2028 t.Fatalf("Index: %d ipv6 failed Error: %s", i, errs)
2030 val := getError(errs, "", "")
2031 if val.Tag() != "ipv6" {
2032 t.Fatalf("Index: %d ipv6 failed Error: %s", i, errs)
2039 func TestIPv4Validation(t *testing.T) {
2045 {"172.16.0.1", true},
2046 {"192.168.0.1", true},
2047 {"192.168.255.254", true},
2048 {"192.168.255.256", false},
2049 {"172.16.255.254", true},
2050 {"172.16.256.255", false},
2051 {"2001:cdba:0000:0000:0000:0000:3257:9652", false},
2052 {"2001:cdba:0:0:0:0:3257:9652", false},
2053 {"2001:cdba::3257:9652", false},
2058 for i, test := range tests {
2060 errs := validate.Var(test.param, "ipv4")
2063 if !IsEqual(errs, nil) {
2064 t.Fatalf("Index: %d ipv4 failed Error: %s", i, errs)
2067 if IsEqual(errs, nil) {
2068 t.Fatalf("Index: %d ipv4 failed Error: %s", i, errs)
2070 val := getError(errs, "", "")
2071 if val.Tag() != "ipv4" {
2072 t.Fatalf("Index: %d ipv4 failed Error: %s", i, errs)
2079 func TestCIDRValidation(t *testing.T) {
2084 {"10.0.0.0/0", true},
2085 {"10.0.0.1/8", true},
2086 {"172.16.0.1/16", true},
2087 {"192.168.0.1/24", true},
2088 {"192.168.255.254/24", true},
2089 {"192.168.255.254/48", false},
2090 {"192.168.255.256/24", false},
2091 {"172.16.255.254/16", true},
2092 {"172.16.256.255/16", false},
2093 {"2001:cdba:0000:0000:0000:0000:3257:9652/64", true},
2094 {"2001:cdba:0000:0000:0000:0000:3257:9652/256", false},
2095 {"2001:cdba:0:0:0:0:3257:9652/32", true},
2096 {"2001:cdba::3257:9652/16", true},
2101 for i, test := range tests {
2103 errs := validate.Var(test.param, "cidr")
2106 if !IsEqual(errs, nil) {
2107 t.Fatalf("Index: %d cidr failed Error: %s", i, errs)
2110 if IsEqual(errs, nil) {
2111 t.Fatalf("Index: %d cidr failed Error: %s", i, errs)
2113 val := getError(errs, "", "")
2114 if val.Tag() != "cidr" {
2115 t.Fatalf("Index: %d cidr failed Error: %s", i, errs)
2122 func TestCIDRv6Validation(t *testing.T) {
2127 {"10.0.0.0/0", false},
2128 {"10.0.0.1/8", false},
2129 {"172.16.0.1/16", false},
2130 {"192.168.0.1/24", false},
2131 {"192.168.255.254/24", false},
2132 {"192.168.255.254/48", false},
2133 {"192.168.255.256/24", false},
2134 {"172.16.255.254/16", false},
2135 {"172.16.256.255/16", false},
2136 {"2001:cdba:0000:0000:0000:0000:3257:9652/64", true},
2137 {"2001:cdba:0000:0000:0000:0000:3257:9652/256", false},
2138 {"2001:cdba:0:0:0:0:3257:9652/32", true},
2139 {"2001:cdba::3257:9652/16", true},
2144 for i, test := range tests {
2146 errs := validate.Var(test.param, "cidrv6")
2149 if !IsEqual(errs, nil) {
2150 t.Fatalf("Index: %d cidrv6 failed Error: %s", i, errs)
2153 if IsEqual(errs, nil) {
2154 t.Fatalf("Index: %d cidrv6 failed Error: %s", i, errs)
2156 val := getError(errs, "", "")
2157 if val.Tag() != "cidrv6" {
2158 t.Fatalf("Index: %d cidrv6 failed Error: %s", i, errs)
2165 func TestCIDRv4Validation(t *testing.T) {
2170 {"10.0.0.0/0", true},
2171 {"10.0.0.1/8", true},
2172 {"172.16.0.1/16", true},
2173 {"192.168.0.1/24", true},
2174 {"192.168.255.254/24", true},
2175 {"192.168.255.254/48", false},
2176 {"192.168.255.256/24", false},
2177 {"172.16.255.254/16", true},
2178 {"172.16.256.255/16", false},
2179 {"2001:cdba:0000:0000:0000:0000:3257:9652/64", false},
2180 {"2001:cdba:0000:0000:0000:0000:3257:9652/256", false},
2181 {"2001:cdba:0:0:0:0:3257:9652/32", false},
2182 {"2001:cdba::3257:9652/16", false},
2187 for i, test := range tests {
2189 errs := validate.Var(test.param, "cidrv4")
2192 if !IsEqual(errs, nil) {
2193 t.Fatalf("Index: %d cidrv4 failed Error: %s", i, errs)
2196 if IsEqual(errs, nil) {
2197 t.Fatalf("Index: %d cidrv4 failed Error: %s", i, errs)
2199 val := getError(errs, "", "")
2200 if val.Tag() != "cidrv4" {
2201 t.Fatalf("Index: %d cidrv4 failed Error: %s", i, errs)
2208 func TestTCPAddrValidation(t *testing.T) {
2215 {"127.0.0.1:80", true},
2217 {"256.0.0.0:1", false},
2223 for i, test := range tests {
2224 errs := validate.Var(test.param, "tcp_addr")
2226 if !IsEqual(errs, nil) {
2227 t.Fatalf("Index: %d tcp_addr failed Error: %s", i, errs)
2230 if IsEqual(errs, nil) {
2231 t.Fatalf("Index: %d tcp_addr failed Error: %s", i, errs)
2233 val := getError(errs, "", "")
2234 if val.Tag() != "tcp_addr" {
2235 t.Fatalf("Index: %d tcp_addr failed Error: %s", i, errs)
2242 func TestTCP6AddrValidation(t *testing.T) {
2249 {"127.0.0.1:80", false},
2251 {"256.0.0.0:1", false},
2257 for i, test := range tests {
2258 errs := validate.Var(test.param, "tcp6_addr")
2260 if !IsEqual(errs, nil) {
2261 t.Fatalf("Index: %d tcp6_addr failed Error: %s", i, errs)
2264 if IsEqual(errs, nil) {
2265 t.Fatalf("Index: %d tcp6_addr failed Error: %s", i, errs)
2267 val := getError(errs, "", "")
2268 if val.Tag() != "tcp6_addr" {
2269 t.Fatalf("Index: %d tcp6_addr failed Error: %s", i, errs)
2276 func TestTCP4AddrValidation(t *testing.T) {
2283 {"127.0.0.1:80", true},
2284 {"[::1]:80", false}, // https://github.com/golang/go/issues/14037
2285 {"256.0.0.0:1", false},
2291 for i, test := range tests {
2292 errs := validate.Var(test.param, "tcp4_addr")
2294 if !IsEqual(errs, nil) {
2295 t.Fatalf("Index: %d tcp4_addr failed Error: %s", i, errs)
2298 if IsEqual(errs, nil) {
2299 t.Log(test.param, IsEqual(errs, nil))
2300 t.Fatalf("Index: %d tcp4_addr failed Error: %s", i, errs)
2302 val := getError(errs, "", "")
2303 if val.Tag() != "tcp4_addr" {
2304 t.Fatalf("Index: %d tcp4_addr failed Error: %s", i, errs)
2311 func TestUDPAddrValidation(t *testing.T) {
2318 {"127.0.0.1:80", true},
2320 {"256.0.0.0:1", false},
2326 for i, test := range tests {
2327 errs := validate.Var(test.param, "udp_addr")
2329 if !IsEqual(errs, nil) {
2330 t.Fatalf("Index: %d udp_addr failed Error: %s", i, errs)
2333 if IsEqual(errs, nil) {
2334 t.Fatalf("Index: %d udp_addr failed Error: %s", i, errs)
2336 val := getError(errs, "", "")
2337 if val.Tag() != "udp_addr" {
2338 t.Fatalf("Index: %d udp_addr failed Error: %s", i, errs)
2345 func TestUDP6AddrValidation(t *testing.T) {
2352 {"127.0.0.1:80", false},
2354 {"256.0.0.0:1", false},
2360 for i, test := range tests {
2361 errs := validate.Var(test.param, "udp6_addr")
2363 if !IsEqual(errs, nil) {
2364 t.Fatalf("Index: %d udp6_addr failed Error: %s", i, errs)
2367 if IsEqual(errs, nil) {
2368 t.Fatalf("Index: %d udp6_addr failed Error: %s", i, errs)
2370 val := getError(errs, "", "")
2371 if val.Tag() != "udp6_addr" {
2372 t.Fatalf("Index: %d udp6_addr failed Error: %s", i, errs)
2379 func TestUDP4AddrValidation(t *testing.T) {
2386 {"127.0.0.1:80", true},
2387 {"[::1]:80", false}, // https://github.com/golang/go/issues/14037
2388 {"256.0.0.0:1", false},
2394 for i, test := range tests {
2395 errs := validate.Var(test.param, "udp4_addr")
2397 if !IsEqual(errs, nil) {
2398 t.Fatalf("Index: %d udp4_addr failed Error: %s", i, errs)
2401 if IsEqual(errs, nil) {
2402 t.Log(test.param, IsEqual(errs, nil))
2403 t.Fatalf("Index: %d udp4_addr failed Error: %s", i, errs)
2405 val := getError(errs, "", "")
2406 if val.Tag() != "udp4_addr" {
2407 t.Fatalf("Index: %d udp4_addr failed Error: %s", i, errs)
2414 func TestIPAddrValidation(t *testing.T) {
2420 {"127.0.0.1", true},
2421 {"127.0.0.1:80", false},
2423 {"256.0.0.0", false},
2424 {"localhost", false},
2429 for i, test := range tests {
2430 errs := validate.Var(test.param, "ip_addr")
2432 if !IsEqual(errs, nil) {
2433 t.Fatalf("Index: %d ip_addr failed Error: %s", i, errs)
2436 if IsEqual(errs, nil) {
2437 t.Fatalf("Index: %d ip_addr failed Error: %s", i, errs)
2439 val := getError(errs, "", "")
2440 if val.Tag() != "ip_addr" {
2441 t.Fatalf("Index: %d ip_addr failed Error: %s", i, errs)
2448 func TestIP6AddrValidation(t *testing.T) {
2454 {"127.0.0.1", false}, // https://github.com/golang/go/issues/14037
2455 {"127.0.0.1:80", false},
2457 {"0:0:0:0:0:0:0:1", true},
2458 {"256.0.0.0", false},
2463 for i, test := range tests {
2464 errs := validate.Var(test.param, "ip6_addr")
2466 if !IsEqual(errs, nil) {
2467 t.Fatalf("Index: %d ip6_addr failed Error: %s", i, errs)
2470 if IsEqual(errs, nil) {
2471 t.Fatalf("Index: %d ip6_addr failed Error: %s", i, errs)
2473 val := getError(errs, "", "")
2474 if val.Tag() != "ip6_addr" {
2475 t.Fatalf("Index: %d ip6_addr failed Error: %s", i, errs)
2482 func TestIP4AddrValidation(t *testing.T) {
2488 {"127.0.0.1", true},
2489 {"127.0.0.1:80", false},
2490 {"::1", false}, // https://github.com/golang/go/issues/14037
2491 {"256.0.0.0", false},
2492 {"localhost", false},
2497 for i, test := range tests {
2498 errs := validate.Var(test.param, "ip4_addr")
2500 if !IsEqual(errs, nil) {
2501 t.Fatalf("Index: %d ip4_addr failed Error: %s", i, errs)
2504 if IsEqual(errs, nil) {
2505 t.Log(test.param, IsEqual(errs, nil))
2506 t.Fatalf("Index: %d ip4_addr failed Error: %s", i, errs)
2508 val := getError(errs, "", "")
2509 if val.Tag() != "ip4_addr" {
2510 t.Fatalf("Index: %d ip4_addr failed Error: %s", i, errs)
2517 func TestUnixAddrValidation(t *testing.T) {
2528 for i, test := range tests {
2529 errs := validate.Var(test.param, "unix_addr")
2531 if !IsEqual(errs, nil) {
2532 t.Fatalf("Index: %d unix_addr failed Error: %s", i, errs)
2535 if IsEqual(errs, nil) {
2536 t.Log(test.param, IsEqual(errs, nil))
2537 t.Fatalf("Index: %d unix_addr failed Error: %s", i, errs)
2539 val := getError(errs, "", "")
2540 if val.Tag() != "unix_addr" {
2541 t.Fatalf("Index: %d unix_addr failed Error: %s", i, errs)
2548 func TestSliceMapArrayChanFuncPtrInterfaceRequiredValidation(t *testing.T) {
2552 var m map[string]string
2554 errs := validate.Var(m, "required")
2555 NotEqual(t, errs, nil)
2556 AssertError(t, errs, "", "", "", "", "required")
2558 m = map[string]string{}
2559 errs = validate.Var(m, "required")
2563 errs = validate.Var(arr, "required")
2564 NotEqual(t, errs, nil)
2565 AssertError(t, errs, "", "", "", "", "required")
2568 errs = validate.Var(arr, "required")
2572 errs = validate.Var(s, "required")
2573 NotEqual(t, errs, nil)
2574 AssertError(t, errs, "", "", "", "", "required")
2577 errs = validate.Var(s, "required")
2581 errs = validate.Var(c, "required")
2582 NotEqual(t, errs, nil)
2583 AssertError(t, errs, "", "", "", "", "required")
2585 c = make(chan string)
2586 errs = validate.Var(c, "required")
2590 errs = validate.Var(tst, "required")
2591 NotEqual(t, errs, nil)
2592 AssertError(t, errs, "", "", "", "", "required")
2596 errs = validate.Var(tst, "required")
2599 var iface interface{}
2601 errs = validate.Var(iface, "required")
2602 NotEqual(t, errs, nil)
2603 AssertError(t, errs, "", "", "", "", "required")
2605 errs = validate.Var(iface, "omitempty,required")
2608 errs = validate.Var(iface, "")
2611 errs = validate.VarWithValue(nil, iface, "")
2616 errs = validate.Var(f, "required")
2617 NotEqual(t, errs, nil)
2618 AssertError(t, errs, "", "", "", "", "required")
2620 f = func(name string) {}
2622 errs = validate.Var(f, "required")
2626 func TestDatePtrValidationIssueValidation(t *testing.T) {
2629 LastViewed *time.Time
2636 errs := validate.Struct(test)
2640 func TestCommaAndPipeObfuscationValidation(t *testing.T) {
2641 s := "My Name Is, |joeybloggs|"
2645 errs := validate.Var(s, "excludesall=0x2C")
2646 NotEqual(t, errs, nil)
2647 AssertError(t, errs, "", "", "", "", "excludesall")
2649 errs = validate.Var(s, "excludesall=0x7C")
2650 NotEqual(t, errs, nil)
2651 AssertError(t, errs, "", "", "", "", "excludesall")
2654 func TestBadKeyValidation(t *testing.T) {
2656 Name string `validate:"required, "`
2665 PanicMatches(t, func() { validate.Struct(tst) }, "Undefined validation function ' ' on field 'Name'")
2668 Name string `validate:"required,,len=2"`
2675 PanicMatches(t, func() { validate.Struct(tst2) }, "Invalid validation tag on field 'Name'")
2678 func TestInterfaceErrValidation(t *testing.T) {
2687 errs := validate.Var(v1, "len=1")
2690 errs = validate.Var(v2, "len=1")
2693 type ExternalCMD struct {
2694 Userid string `json:"userid"`
2695 Action uint32 `json:"action"`
2696 Data interface{} `json:"data,omitempty" validate:"required"`
2705 errs = validate.Struct(s)
2706 NotEqual(t, errs, nil)
2707 Equal(t, len(errs.(ValidationErrors)), 1)
2708 AssertError(t, errs, "ExternalCMD.Data", "ExternalCMD.Data", "Data", "Data", "required")
2710 type ExternalCMD2 struct {
2711 Userid string `json:"userid"`
2712 Action uint32 `json:"action"`
2713 Data interface{} `json:"data,omitempty" validate:"len=1"`
2716 s2 := &ExternalCMD2{
2722 errs = validate.Struct(s2)
2723 NotEqual(t, errs, nil)
2724 Equal(t, len(errs.(ValidationErrors)), 1)
2725 AssertError(t, errs, "ExternalCMD2.Data", "ExternalCMD2.Data", "Data", "Data", "len")
2727 s3 := &ExternalCMD2{
2733 errs = validate.Struct(s3)
2734 NotEqual(t, errs, nil)
2735 Equal(t, len(errs.(ValidationErrors)), 1)
2736 AssertError(t, errs, "ExternalCMD2.Data", "ExternalCMD2.Data", "Data", "Data", "len")
2739 Name string `validate:"required"`
2752 errs = validate.Struct(s4)
2753 NotEqual(t, errs, nil)
2754 Equal(t, len(errs.(ValidationErrors)), 1)
2755 AssertError(t, errs, "ExternalCMD.Data.Name", "ExternalCMD.Data.Name", "Name", "Name", "required")
2757 type TestMapStructPtr struct {
2758 Errs map[int]interface{} `validate:"gt=0,dive,len=2"`
2761 mip := map[int]interface{}{0: &Inner{"ok"}, 3: nil, 4: &Inner{"ok"}}
2763 msp := &TestMapStructPtr{
2767 errs = validate.Struct(msp)
2768 NotEqual(t, errs, nil)
2769 Equal(t, len(errs.(ValidationErrors)), 1)
2770 AssertError(t, errs, "TestMapStructPtr.Errs[3]", "TestMapStructPtr.Errs[3]", "Errs[3]", "Errs[3]", "len")
2772 type TestMultiDimensionalStructs struct {
2773 Errs [][]interface{} `validate:"gt=0,dive,dive"`
2776 var errStructArray [][]interface{}
2778 errStructArray = append(errStructArray, []interface{}{&Inner{"ok"}, &Inner{""}, &Inner{""}})
2779 errStructArray = append(errStructArray, []interface{}{&Inner{"ok"}, &Inner{""}, &Inner{""}})
2781 tms := &TestMultiDimensionalStructs{
2782 Errs: errStructArray,
2785 errs = validate.Struct(tms)
2786 NotEqual(t, errs, nil)
2787 Equal(t, len(errs.(ValidationErrors)), 4)
2788 AssertError(t, errs, "TestMultiDimensionalStructs.Errs[0][1].Name", "TestMultiDimensionalStructs.Errs[0][1].Name", "Name", "Name", "required")
2789 AssertError(t, errs, "TestMultiDimensionalStructs.Errs[0][2].Name", "TestMultiDimensionalStructs.Errs[0][2].Name", "Name", "Name", "required")
2790 AssertError(t, errs, "TestMultiDimensionalStructs.Errs[1][1].Name", "TestMultiDimensionalStructs.Errs[1][1].Name", "Name", "Name", "required")
2791 AssertError(t, errs, "TestMultiDimensionalStructs.Errs[1][2].Name", "TestMultiDimensionalStructs.Errs[1][2].Name", "Name", "Name", "required")
2793 type TestMultiDimensionalStructsPtr2 struct {
2794 Errs [][]*Inner `validate:"gt=0,dive,dive,required"`
2797 var errStructPtr2Array [][]*Inner
2799 errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, {""}})
2800 errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, {""}})
2801 errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, nil})
2803 tmsp2 := &TestMultiDimensionalStructsPtr2{
2804 Errs: errStructPtr2Array,
2807 errs = validate.Struct(tmsp2)
2808 NotEqual(t, errs, nil)
2809 Equal(t, len(errs.(ValidationErrors)), 6)
2810 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[0][1].Name", "TestMultiDimensionalStructsPtr2.Errs[0][1].Name", "Name", "Name", "required")
2811 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[0][2].Name", "TestMultiDimensionalStructsPtr2.Errs[0][2].Name", "Name", "Name", "required")
2812 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[1][1].Name", "TestMultiDimensionalStructsPtr2.Errs[1][1].Name", "Name", "Name", "required")
2813 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[1][2].Name", "TestMultiDimensionalStructsPtr2.Errs[1][2].Name", "Name", "Name", "required")
2814 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[2][1].Name", "TestMultiDimensionalStructsPtr2.Errs[2][1].Name", "Name", "Name", "required")
2815 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[2][2]", "TestMultiDimensionalStructsPtr2.Errs[2][2]", "Errs[2][2]", "Errs[2][2]", "required")
2817 m := map[int]interface{}{0: "ok", 3: "", 4: "ok"}
2819 errs = validate.Var(m, "len=3,dive,len=2")
2820 NotEqual(t, errs, nil)
2821 Equal(t, len(errs.(ValidationErrors)), 1)
2822 AssertError(t, errs, "[3]", "[3]", "[3]", "[3]", "len")
2824 errs = validate.Var(m, "len=2,dive,required")
2825 NotEqual(t, errs, nil)
2826 Equal(t, len(errs.(ValidationErrors)), 1)
2827 AssertError(t, errs, "", "", "", "", "len")
2829 arr := []interface{}{"ok", "", "ok"}
2831 errs = validate.Var(arr, "len=3,dive,len=2")
2832 NotEqual(t, errs, nil)
2833 Equal(t, len(errs.(ValidationErrors)), 1)
2834 AssertError(t, errs, "[1]", "[1]", "[1]", "[1]", "len")
2836 errs = validate.Var(arr, "len=2,dive,required")
2837 NotEqual(t, errs, nil)
2838 Equal(t, len(errs.(ValidationErrors)), 1)
2839 AssertError(t, errs, "", "", "", "", "len")
2841 type MyStruct struct {
2851 errs = validate.Struct(a)
2855 func TestMapDiveValidation(t *testing.T) {
2859 n := map[int]interface{}{0: nil}
2860 errs := validate.Var(n, "omitempty,required")
2863 m := map[int]string{0: "ok", 3: "", 4: "ok"}
2865 errs = validate.Var(m, "len=3,dive,required")
2866 NotEqual(t, errs, nil)
2867 Equal(t, len(errs.(ValidationErrors)), 1)
2868 AssertError(t, errs, "[3]", "[3]", "[3]", "[3]", "required")
2870 errs = validate.Var(m, "len=2,dive,required")
2871 NotEqual(t, errs, nil)
2872 Equal(t, len(errs.(ValidationErrors)), 1)
2873 AssertError(t, errs, "", "", "", "", "len")
2876 Name string `validate:"required"`
2879 type TestMapStruct struct {
2880 Errs map[int]Inner `validate:"gt=0,dive"`
2883 mi := map[int]Inner{0: {"ok"}, 3: {""}, 4: {"ok"}}
2885 ms := &TestMapStruct{
2889 errs = validate.Struct(ms)
2890 NotEqual(t, errs, nil)
2891 Equal(t, len(errs.(ValidationErrors)), 1)
2892 AssertError(t, errs, "TestMapStruct.Errs[3].Name", "TestMapStruct.Errs[3].Name", "Name", "Name", "required")
2894 // for full test coverage
2895 s := fmt.Sprint(errs.Error())
2898 type TestMapTimeStruct struct {
2899 Errs map[int]*time.Time `validate:"gt=0,dive,required"`
2902 t1 := time.Now().UTC()
2904 mta := map[int]*time.Time{0: &t1, 3: nil, 4: nil}
2906 mt := &TestMapTimeStruct{
2910 errs = validate.Struct(mt)
2911 NotEqual(t, errs, nil)
2912 Equal(t, len(errs.(ValidationErrors)), 2)
2913 AssertError(t, errs, "TestMapTimeStruct.Errs[3]", "TestMapTimeStruct.Errs[3]", "Errs[3]", "Errs[3]", "required")
2914 AssertError(t, errs, "TestMapTimeStruct.Errs[4]", "TestMapTimeStruct.Errs[4]", "Errs[4]", "Errs[4]", "required")
2916 type TestMapStructPtr struct {
2917 Errs map[int]*Inner `validate:"gt=0,dive,required"`
2920 mip := map[int]*Inner{0: {"ok"}, 3: nil, 4: {"ok"}}
2922 msp := &TestMapStructPtr{
2926 errs = validate.Struct(msp)
2927 NotEqual(t, errs, nil)
2928 Equal(t, len(errs.(ValidationErrors)), 1)
2929 AssertError(t, errs, "TestMapStructPtr.Errs[3]", "TestMapStructPtr.Errs[3]", "Errs[3]", "Errs[3]", "required")
2931 type TestMapStructPtr2 struct {
2932 Errs map[int]*Inner `validate:"gt=0,dive,omitempty,required"`
2935 mip2 := map[int]*Inner{0: {"ok"}, 3: nil, 4: {"ok"}}
2937 msp2 := &TestMapStructPtr2{
2941 errs = validate.Struct(msp2)
2945 v2.RegisterTagNameFunc(func(fld reflect.StructField) string {
2946 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
2955 type MapDiveJSONTest struct {
2956 Map map[string]string `validate:"required,gte=1,dive,gte=1" json:"MyName"`
2959 mdjt := &MapDiveJSONTest{
2960 Map: map[string]string{
2966 err := v2.Struct(mdjt)
2967 NotEqual(t, err, nil)
2969 errs = err.(ValidationErrors)
2970 fe := getError(errs, "MapDiveJSONTest.MyName[Key2]", "MapDiveJSONTest.Map[Key2]")
2971 NotEqual(t, fe, nil)
2972 Equal(t, fe.Tag(), "gte")
2973 Equal(t, fe.ActualTag(), "gte")
2974 Equal(t, fe.Field(), "MyName[Key2]")
2975 Equal(t, fe.StructField(), "Map[Key2]")
2978 func TestArrayDiveValidation(t *testing.T) {
2982 arr := []string{"ok", "", "ok"}
2984 errs := validate.Var(arr, "len=3,dive,required")
2985 NotEqual(t, errs, nil)
2986 Equal(t, len(errs.(ValidationErrors)), 1)
2987 AssertError(t, errs, "[1]", "[1]", "[1]", "[1]", "required")
2989 errs = validate.Var(arr, "len=2,dive,required")
2990 NotEqual(t, errs, nil)
2991 Equal(t, len(errs.(ValidationErrors)), 1)
2992 AssertError(t, errs, "", "", "", "", "len")
2994 type BadDive struct {
2995 Name string `validate:"dive"`
3002 PanicMatches(t, func() { validate.Struct(bd) }, "dive error! can't dive on a non slice or map")
3005 Errs []string `validate:"gt=0,dive,required"`
3009 Errs: []string{"ok", "", "ok"},
3012 errs = validate.Struct(test)
3013 NotEqual(t, errs, nil)
3014 Equal(t, len(errs.(ValidationErrors)), 1)
3015 AssertError(t, errs, "Test.Errs[1]", "Test.Errs[1]", "Errs[1]", "Errs[1]", "required")
3018 Errs: []string{"ok", "ok", ""},
3021 errs = validate.Struct(test)
3022 NotEqual(t, errs, nil)
3023 Equal(t, len(errs.(ValidationErrors)), 1)
3024 AssertError(t, errs, "Test.Errs[2]", "Test.Errs[2]", "Errs[2]", "Errs[2]", "required")
3026 type TestMultiDimensional struct {
3027 Errs [][]string `validate:"gt=0,dive,dive,required"`
3030 var errArray [][]string
3032 errArray = append(errArray, []string{"ok", "", ""})
3033 errArray = append(errArray, []string{"ok", "", ""})
3035 tm := &TestMultiDimensional{
3039 errs = validate.Struct(tm)
3040 NotEqual(t, errs, nil)
3041 Equal(t, len(errs.(ValidationErrors)), 4)
3042 AssertError(t, errs, "TestMultiDimensional.Errs[0][1]", "TestMultiDimensional.Errs[0][1]", "Errs[0][1]", "Errs[0][1]", "required")
3043 AssertError(t, errs, "TestMultiDimensional.Errs[0][2]", "TestMultiDimensional.Errs[0][2]", "Errs[0][2]", "Errs[0][2]", "required")
3044 AssertError(t, errs, "TestMultiDimensional.Errs[1][1]", "TestMultiDimensional.Errs[1][1]", "Errs[1][1]", "Errs[1][1]", "required")
3045 AssertError(t, errs, "TestMultiDimensional.Errs[1][2]", "TestMultiDimensional.Errs[1][2]", "Errs[1][2]", "Errs[1][2]", "required")
3048 Name string `validate:"required"`
3051 type TestMultiDimensionalStructs struct {
3052 Errs [][]Inner `validate:"gt=0,dive,dive"`
3055 var errStructArray [][]Inner
3057 errStructArray = append(errStructArray, []Inner{{"ok"}, {""}, {""}})
3058 errStructArray = append(errStructArray, []Inner{{"ok"}, {""}, {""}})
3060 tms := &TestMultiDimensionalStructs{
3061 Errs: errStructArray,
3064 errs = validate.Struct(tms)
3065 NotEqual(t, errs, nil)
3066 Equal(t, len(errs.(ValidationErrors)), 4)
3067 AssertError(t, errs, "TestMultiDimensionalStructs.Errs[0][1].Name", "TestMultiDimensionalStructs.Errs[0][1].Name", "Name", "Name", "required")
3068 AssertError(t, errs, "TestMultiDimensionalStructs.Errs[0][2].Name", "TestMultiDimensionalStructs.Errs[0][2].Name", "Name", "Name", "required")
3069 AssertError(t, errs, "TestMultiDimensionalStructs.Errs[1][1].Name", "TestMultiDimensionalStructs.Errs[1][1].Name", "Name", "Name", "required")
3070 AssertError(t, errs, "TestMultiDimensionalStructs.Errs[1][2].Name", "TestMultiDimensionalStructs.Errs[1][2].Name", "Name", "Name", "required")
3072 type TestMultiDimensionalStructsPtr struct {
3073 Errs [][]*Inner `validate:"gt=0,dive,dive"`
3076 var errStructPtrArray [][]*Inner
3078 errStructPtrArray = append(errStructPtrArray, []*Inner{{"ok"}, {""}, {""}})
3079 errStructPtrArray = append(errStructPtrArray, []*Inner{{"ok"}, {""}, {""}})
3080 errStructPtrArray = append(errStructPtrArray, []*Inner{{"ok"}, {""}, nil})
3082 tmsp := &TestMultiDimensionalStructsPtr{
3083 Errs: errStructPtrArray,
3086 errs = validate.Struct(tmsp)
3087 NotEqual(t, errs, nil)
3088 Equal(t, len(errs.(ValidationErrors)), 5)
3089 AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[0][1].Name", "TestMultiDimensionalStructsPtr.Errs[0][1].Name", "Name", "Name", "required")
3090 AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[0][2].Name", "TestMultiDimensionalStructsPtr.Errs[0][2].Name", "Name", "Name", "required")
3091 AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[1][1].Name", "TestMultiDimensionalStructsPtr.Errs[1][1].Name", "Name", "Name", "required")
3092 AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[1][2].Name", "TestMultiDimensionalStructsPtr.Errs[1][2].Name", "Name", "Name", "required")
3093 AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[2][1].Name", "TestMultiDimensionalStructsPtr.Errs[2][1].Name", "Name", "Name", "required")
3095 // for full test coverage
3096 s := fmt.Sprint(errs.Error())
3099 type TestMultiDimensionalStructsPtr2 struct {
3100 Errs [][]*Inner `validate:"gt=0,dive,dive,required"`
3103 var errStructPtr2Array [][]*Inner
3105 errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, {""}})
3106 errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, {""}})
3107 errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, nil})
3109 tmsp2 := &TestMultiDimensionalStructsPtr2{
3110 Errs: errStructPtr2Array,
3113 errs = validate.Struct(tmsp2)
3114 NotEqual(t, errs, nil)
3115 Equal(t, len(errs.(ValidationErrors)), 6)
3116 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[0][1].Name", "TestMultiDimensionalStructsPtr2.Errs[0][1].Name", "Name", "Name", "required")
3117 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[0][2].Name", "TestMultiDimensionalStructsPtr2.Errs[0][2].Name", "Name", "Name", "required")
3118 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[1][1].Name", "TestMultiDimensionalStructsPtr2.Errs[1][1].Name", "Name", "Name", "required")
3119 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[1][2].Name", "TestMultiDimensionalStructsPtr2.Errs[1][2].Name", "Name", "Name", "required")
3120 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[2][1].Name", "TestMultiDimensionalStructsPtr2.Errs[2][1].Name", "Name", "Name", "required")
3121 AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[2][2]", "TestMultiDimensionalStructsPtr2.Errs[2][2]", "Errs[2][2]", "Errs[2][2]", "required")
3123 type TestMultiDimensionalStructsPtr3 struct {
3124 Errs [][]*Inner `validate:"gt=0,dive,dive,omitempty"`
3127 var errStructPtr3Array [][]*Inner
3129 errStructPtr3Array = append(errStructPtr3Array, []*Inner{{"ok"}, {""}, {""}})
3130 errStructPtr3Array = append(errStructPtr3Array, []*Inner{{"ok"}, {""}, {""}})
3131 errStructPtr3Array = append(errStructPtr3Array, []*Inner{{"ok"}, {""}, nil})
3133 tmsp3 := &TestMultiDimensionalStructsPtr3{
3134 Errs: errStructPtr3Array,
3137 errs = validate.Struct(tmsp3)
3138 NotEqual(t, errs, nil)
3139 Equal(t, len(errs.(ValidationErrors)), 5)
3140 AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[0][1].Name", "TestMultiDimensionalStructsPtr3.Errs[0][1].Name", "Name", "Name", "required")
3141 AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[0][2].Name", "TestMultiDimensionalStructsPtr3.Errs[0][2].Name", "Name", "Name", "required")
3142 AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[1][1].Name", "TestMultiDimensionalStructsPtr3.Errs[1][1].Name", "Name", "Name", "required")
3143 AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[1][2].Name", "TestMultiDimensionalStructsPtr3.Errs[1][2].Name", "Name", "Name", "required")
3144 AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[2][1].Name", "TestMultiDimensionalStructsPtr3.Errs[2][1].Name", "Name", "Name", "required")
3146 type TestMultiDimensionalTimeTime struct {
3147 Errs [][]*time.Time `validate:"gt=0,dive,dive,required"`
3150 var errTimePtr3Array [][]*time.Time
3152 t1 := time.Now().UTC()
3153 t2 := time.Now().UTC()
3154 t3 := time.Now().UTC().Add(time.Hour * 24)
3156 errTimePtr3Array = append(errTimePtr3Array, []*time.Time{&t1, &t2, &t3})
3157 errTimePtr3Array = append(errTimePtr3Array, []*time.Time{&t1, &t2, nil})
3158 errTimePtr3Array = append(errTimePtr3Array, []*time.Time{&t1, nil, nil})
3160 tmtp3 := &TestMultiDimensionalTimeTime{
3161 Errs: errTimePtr3Array,
3164 errs = validate.Struct(tmtp3)
3165 NotEqual(t, errs, nil)
3166 Equal(t, len(errs.(ValidationErrors)), 3)
3167 AssertError(t, errs, "TestMultiDimensionalTimeTime.Errs[1][2]", "TestMultiDimensionalTimeTime.Errs[1][2]", "Errs[1][2]", "Errs[1][2]", "required")
3168 AssertError(t, errs, "TestMultiDimensionalTimeTime.Errs[2][1]", "TestMultiDimensionalTimeTime.Errs[2][1]", "Errs[2][1]", "Errs[2][1]", "required")
3169 AssertError(t, errs, "TestMultiDimensionalTimeTime.Errs[2][2]", "TestMultiDimensionalTimeTime.Errs[2][2]", "Errs[2][2]", "Errs[2][2]", "required")
3171 type TestMultiDimensionalTimeTime2 struct {
3172 Errs [][]*time.Time `validate:"gt=0,dive,dive,required"`
3175 var errTimeArray [][]*time.Time
3177 t1 = time.Now().UTC()
3178 t2 = time.Now().UTC()
3179 t3 = time.Now().UTC().Add(time.Hour * 24)
3181 errTimeArray = append(errTimeArray, []*time.Time{&t1, &t2, &t3})
3182 errTimeArray = append(errTimeArray, []*time.Time{&t1, &t2, nil})
3183 errTimeArray = append(errTimeArray, []*time.Time{&t1, nil, nil})
3185 tmtp := &TestMultiDimensionalTimeTime2{
3189 errs = validate.Struct(tmtp)
3190 NotEqual(t, errs, nil)
3191 Equal(t, len(errs.(ValidationErrors)), 3)
3192 AssertError(t, errs, "TestMultiDimensionalTimeTime2.Errs[1][2]", "TestMultiDimensionalTimeTime2.Errs[1][2]", "Errs[1][2]", "Errs[1][2]", "required")
3193 AssertError(t, errs, "TestMultiDimensionalTimeTime2.Errs[2][1]", "TestMultiDimensionalTimeTime2.Errs[2][1]", "Errs[2][1]", "Errs[2][1]", "required")
3194 AssertError(t, errs, "TestMultiDimensionalTimeTime2.Errs[2][2]", "TestMultiDimensionalTimeTime2.Errs[2][2]", "Errs[2][2]", "Errs[2][2]", "required")
3197 func TestNilStructPointerValidation(t *testing.T) {
3203 Inner *Inner `validate:"omitempty"`
3215 errs := validate.Struct(outer)
3222 errs = validate.Struct(outer)
3225 type Inner2 struct {
3229 type Outer2 struct {
3230 Inner2 *Inner2 `validate:"required"`
3241 errs = validate.Struct(outer2)
3248 errs = validate.Struct(outer2)
3249 NotEqual(t, errs, nil)
3250 AssertError(t, errs, "Outer2.Inner2", "Outer2.Inner2", "Inner2", "Inner2", "required")
3252 type Inner3 struct {
3256 type Outer3 struct {
3268 errs = validate.Struct(outer3)
3271 type Inner4 struct {
3275 type Outer4 struct {
3276 Inner4 *Inner4 `validate:"-"`
3287 errs = validate.Struct(outer4)
3291 func TestSSNValidation(t *testing.T) {
3297 {"00-90-8787", false},
3298 {"66690-76", false},
3299 {"191 60 2869", true},
3300 {"191-60-2869", true},
3305 for i, test := range tests {
3307 errs := validate.Var(test.param, "ssn")
3310 if !IsEqual(errs, nil) {
3311 t.Fatalf("Index: %d SSN failed Error: %s", i, errs)
3314 if IsEqual(errs, nil) {
3315 t.Fatalf("Index: %d SSN failed Error: %s", i, errs)
3317 val := getError(errs, "", "")
3318 if val.Tag() != "ssn" {
3319 t.Fatalf("Index: %d Latitude failed Error: %s", i, errs)
3326 func TestLongitudeValidation(t *testing.T) {
3335 {"+382.3811", false},
3336 {"23.11111111", true},
3341 for i, test := range tests {
3343 errs := validate.Var(test.param, "longitude")
3346 if !IsEqual(errs, nil) {
3347 t.Fatalf("Index: %d Longitude failed Error: %s", i, errs)
3350 if IsEqual(errs, nil) {
3351 t.Fatalf("Index: %d Longitude failed Error: %s", i, errs)
3353 val := getError(errs, "", "")
3354 if val.Tag() != "longitude" {
3355 t.Fatalf("Index: %d Latitude failed Error: %s", i, errs)
3362 func TestLatitudeValidation(t *testing.T) {
3370 {"47.1231231", true},
3377 for i, test := range tests {
3379 errs := validate.Var(test.param, "latitude")
3382 if !IsEqual(errs, nil) {
3383 t.Fatalf("Index: %d Latitude failed Error: %s", i, errs)
3386 if IsEqual(errs, nil) {
3387 t.Fatalf("Index: %d Latitude failed Error: %s", i, errs)
3389 val := getError(errs, "", "")
3390 if val.Tag() != "latitude" {
3391 t.Fatalf("Index: %d Latitude failed Error: %s", i, errs)
3398 func TestDataURIValidation(t *testing.T) {
3403 {"data:image/png;base64,TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4=", true},
3404 {"data:text/plain;base64,Vml2YW11cyBmZXJtZW50dW0gc2VtcGVyIHBvcnRhLg==", true},
3405 {"image/gif;base64,U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", false},
3406 {"data:image/gif;base64,MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuMPNS1Ufof9EW/M98FNw" +
3407 "UAKrwflsqVxaxQjBQnHQmiI7Vac40t8x7pIb8gLGV6wL7sBTJiPovJ0V7y7oc0Ye" +
3408 "rhKh0Rm4skP2z/jHwwZICgGzBvA0rH8xlhUiTvcwDCJ0kc+fh35hNt8srZQM4619" +
3409 "FTgB66Xmp4EtVyhpQV+t02g6NzK72oZI0vnAvqhpkxLeLiMCyrI416wHm5Tkukhx" +
3410 "QmcL2a6hNOyu0ixX/x2kSFXApEnVrJ+/IxGyfyw8kf4N2IZpW5nEP847lpfj0SZZ" +
3411 "Fwrd1mnfnDbYohX2zRptLy2ZUn06Qo9pkG5ntvFEPo9bfZeULtjYzIl6K8gJ2uGZ" + "HQIDAQAB", true},
3412 {"data:image/png;base64,12345", false},
3414 {"data:text,:;base85,U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", false},
3419 for i, test := range tests {
3421 errs := validate.Var(test.param, "datauri")
3424 if !IsEqual(errs, nil) {
3425 t.Fatalf("Index: %d DataURI failed Error: %s", i, errs)
3428 if IsEqual(errs, nil) {
3429 t.Fatalf("Index: %d DataURI failed Error: %s", i, errs)
3431 val := getError(errs, "", "")
3432 if val.Tag() != "datauri" {
3433 t.Fatalf("Index: %d DataURI failed Error: %s", i, errs)
3440 func TestMultibyteValidation(t *testing.T) {
3449 {"ひらがな・カタカナ、.漢字", true},
3450 {"あいうえお foobar", true},
3451 {"test@example.com", true},
3452 {"test@example.com", true},
3453 {"1234abcDExyz", true},
3459 for i, test := range tests {
3461 errs := validate.Var(test.param, "multibyte")
3464 if !IsEqual(errs, nil) {
3465 t.Fatalf("Index: %d Multibyte failed Error: %s", i, errs)
3468 if IsEqual(errs, nil) {
3469 t.Fatalf("Index: %d Multibyte failed Error: %s", i, errs)
3471 val := getError(errs, "", "")
3472 if val.Tag() != "multibyte" {
3473 t.Fatalf("Index: %d Multibyte failed Error: %s", i, errs)
3480 func TestPrintableASCIIValidation(t *testing.T) {
3491 {"0987654321", true},
3492 {"test@example.com", true},
3493 {"1234abcDEF", true},
3494 {"newline\n", false},
3495 {"\x19test\x7F", false},
3500 for i, test := range tests {
3502 errs := validate.Var(test.param, "printascii")
3505 if !IsEqual(errs, nil) {
3506 t.Fatalf("Index: %d Printable ASCII failed Error: %s", i, errs)
3509 if IsEqual(errs, nil) {
3510 t.Fatalf("Index: %d Printable ASCII failed Error: %s", i, errs)
3512 val := getError(errs, "", "")
3513 if val.Tag() != "printascii" {
3514 t.Fatalf("Index: %d Printable ASCII failed Error: %s", i, errs)
3521 func TestASCIIValidation(t *testing.T) {
3532 {"0987654321", true},
3533 {"test@example.com", true},
3534 {"1234abcDEF", true},
3540 for i, test := range tests {
3542 errs := validate.Var(test.param, "ascii")
3545 if !IsEqual(errs, nil) {
3546 t.Fatalf("Index: %d ASCII failed Error: %s", i, errs)
3549 if IsEqual(errs, nil) {
3550 t.Fatalf("Index: %d ASCII failed Error: %s", i, errs)
3552 val := getError(errs, "", "")
3553 if val.Tag() != "ascii" {
3554 t.Fatalf("Index: %d ASCII failed Error: %s", i, errs)
3561 func TestUUID5Validation(t *testing.T) {
3568 {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
3569 {"9c858901-8a57-4791-81fe-4c455b099bc9", false},
3570 {"a987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
3571 {"987fbc97-4bed-5078-af07-9141ba07c9f3", true},
3572 {"987fbc97-4bed-5078-9f07-9141ba07c9f3", true},
3577 for i, test := range tests {
3579 errs := validate.Var(test.param, "uuid5")
3582 if !IsEqual(errs, nil) {
3583 t.Fatalf("Index: %d UUID5 failed Error: %s", i, errs)
3586 if IsEqual(errs, nil) {
3587 t.Fatalf("Index: %d UUID5 failed Error: %s", i, errs)
3589 val := getError(errs, "", "")
3590 if val.Tag() != "uuid5" {
3591 t.Fatalf("Index: %d UUID5 failed Error: %s", i, errs)
3598 func TestUUID4Validation(t *testing.T) {
3604 {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
3605 {"a987fbc9-4bed-5078-af07-9141ba07c9f3", false},
3607 {"57b73598-8764-4ad0-a76a-679bb6640eb1", true},
3608 {"625e63f3-58f5-40b7-83a1-a72ad31acffb", true},
3613 for i, test := range tests {
3615 errs := validate.Var(test.param, "uuid4")
3618 if !IsEqual(errs, nil) {
3619 t.Fatalf("Index: %d UUID4 failed Error: %s", i, errs)
3622 if IsEqual(errs, nil) {
3623 t.Fatalf("Index: %d UUID4 failed Error: %s", i, errs)
3625 val := getError(errs, "", "")
3626 if val.Tag() != "uuid4" {
3627 t.Fatalf("Index: %d UUID4 failed Error: %s", i, errs)
3634 func TestUUID3Validation(t *testing.T) {
3640 {"412452646", false},
3641 {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
3642 {"a987fbc9-4bed-4078-8f07-9141ba07c9f3", false},
3643 {"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true},
3648 for i, test := range tests {
3650 errs := validate.Var(test.param, "uuid3")
3653 if !IsEqual(errs, nil) {
3654 t.Fatalf("Index: %d UUID3 failed Error: %s", i, errs)
3657 if IsEqual(errs, nil) {
3658 t.Fatalf("Index: %d UUID3 failed Error: %s", i, errs)
3660 val := getError(errs, "", "")
3661 if val.Tag() != "uuid3" {
3662 t.Fatalf("Index: %d UUID3 failed Error: %s", i, errs)
3669 func TestUUIDValidation(t *testing.T) {
3675 {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
3676 {"a987fbc9-4bed-3078-cf07-9141ba07c9f3xxx", false},
3677 {"a987fbc94bed3078cf079141ba07c9f3", false},
3679 {"987fbc9-4bed-3078-cf07a-9141ba07c9f3", false},
3680 {"aaaaaaaa-1111-1111-aaag-111111111111", false},
3681 {"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true},
3686 for i, test := range tests {
3688 errs := validate.Var(test.param, "uuid")
3691 if !IsEqual(errs, nil) {
3692 t.Fatalf("Index: %d UUID failed Error: %s", i, errs)
3695 if IsEqual(errs, nil) {
3696 t.Fatalf("Index: %d UUID failed Error: %s", i, errs)
3698 val := getError(errs, "", "")
3699 if val.Tag() != "uuid" {
3700 t.Fatalf("Index: %d UUID failed Error: %s", i, errs)
3707 func TestISBNValidation(t *testing.T) {
3714 {"3836221195", true},
3715 {"1-61729-085-8", true},
3716 {"3 423 21412 0", true},
3717 {"3 401 01319 X", true},
3718 {"9784873113685", true},
3719 {"978-4-87311-368-5", true},
3720 {"978 3401013190", true},
3721 {"978-3-8362-2119-1", true},
3726 for i, test := range tests {
3728 errs := validate.Var(test.param, "isbn")
3731 if !IsEqual(errs, nil) {
3732 t.Fatalf("Index: %d ISBN failed Error: %s", i, errs)
3735 if IsEqual(errs, nil) {
3736 t.Fatalf("Index: %d ISBN failed Error: %s", i, errs)
3738 val := getError(errs, "", "")
3739 if val.Tag() != "isbn" {
3740 t.Fatalf("Index: %d ISBN failed Error: %s", i, errs)
3747 func TestISBN13Validation(t *testing.T) {
3754 {"3-8362-2119-5", false},
3755 {"01234567890ab", false},
3756 {"978 3 8362 2119 0", false},
3757 {"9784873113685", true},
3758 {"978-4-87311-368-5", true},
3759 {"978 3401013190", true},
3760 {"978-3-8362-2119-1", true},
3765 for i, test := range tests {
3767 errs := validate.Var(test.param, "isbn13")
3770 if !IsEqual(errs, nil) {
3771 t.Fatalf("Index: %d ISBN13 failed Error: %s", i, errs)
3774 if IsEqual(errs, nil) {
3775 t.Fatalf("Index: %d ISBN13 failed Error: %s", i, errs)
3777 val := getError(errs, "", "")
3778 if val.Tag() != "isbn13" {
3779 t.Fatalf("Index: %d ISBN13 failed Error: %s", i, errs)
3786 func TestISBN10Validation(t *testing.T) {
3793 {"3423214121", false},
3794 {"978-3836221191", false},
3795 {"3-423-21412-1", false},
3796 {"3 423 21412 1", false},
3797 {"3836221195", true},
3798 {"1-61729-085-8", true},
3799 {"3 423 21412 0", true},
3800 {"3 401 01319 X", true},
3805 for i, test := range tests {
3807 errs := validate.Var(test.param, "isbn10")
3810 if !IsEqual(errs, nil) {
3811 t.Fatalf("Index: %d ISBN10 failed Error: %s", i, errs)
3814 if IsEqual(errs, nil) {
3815 t.Fatalf("Index: %d ISBN10 failed Error: %s", i, errs)
3817 val := getError(errs, "", "")
3818 if val.Tag() != "isbn10" {
3819 t.Fatalf("Index: %d ISBN10 failed Error: %s", i, errs)
3826 func TestExcludesRuneValidation(t *testing.T) {
3829 Value string `validate:"excludesrune=☻"`
3833 {Value: "a☺b☻c☹d", Tag: "excludesrune=☻", ExpectedNil: false},
3834 {Value: "abcd", Tag: "excludesrune=☻", ExpectedNil: true},
3839 for i, s := range tests {
3840 errs := validate.Var(s.Value, s.Tag)
3842 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
3843 t.Fatalf("Index: %d failed Error: %s", i, errs)
3846 errs = validate.Struct(s)
3848 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
3849 t.Fatalf("Index: %d failed Error: %s", i, errs)
3854 func TestExcludesAllValidation(t *testing.T) {
3857 Value string `validate:"excludesall=@!{}[]"`
3861 {Value: "abcd@!jfk", Tag: "excludesall=@!{}[]", ExpectedNil: false},
3862 {Value: "abcdefg", Tag: "excludesall=@!{}[]", ExpectedNil: true},
3867 for i, s := range tests {
3868 errs := validate.Var(s.Value, s.Tag)
3870 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
3871 t.Fatalf("Index: %d failed Error: %s", i, errs)
3874 errs = validate.Struct(s)
3876 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
3877 t.Fatalf("Index: %d failed Error: %s", i, errs)
3881 username := "joeybloggs "
3883 errs := validate.Var(username, "excludesall=@ ")
3884 NotEqual(t, errs, nil)
3885 AssertError(t, errs, "", "", "", "", "excludesall")
3889 errs = validate.Var(excluded, "excludesall=!@#$%^&*()_+.0x2C?")
3890 NotEqual(t, errs, nil)
3891 AssertError(t, errs, "", "", "", "", "excludesall")
3895 errs = validate.Var(excluded, "excludesall=!@#$%^&*()_+.0x2C=?")
3896 NotEqual(t, errs, nil)
3897 AssertError(t, errs, "", "", "", "", "excludesall")
3900 func TestExcludesValidation(t *testing.T) {
3903 Value string `validate:"excludes=@"`
3907 {Value: "abcd@!jfk", Tag: "excludes=@", ExpectedNil: false},
3908 {Value: "abcdq!jfk", Tag: "excludes=@", ExpectedNil: true},
3913 for i, s := range tests {
3914 errs := validate.Var(s.Value, s.Tag)
3916 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
3917 t.Fatalf("Index: %d failed Error: %s", i, errs)
3920 errs = validate.Struct(s)
3922 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
3923 t.Fatalf("Index: %d failed Error: %s", i, errs)
3928 func TestContainsRuneValidation(t *testing.T) {
3931 Value string `validate:"containsrune=☻"`
3935 {Value: "a☺b☻c☹d", Tag: "containsrune=☻", ExpectedNil: true},
3936 {Value: "abcd", Tag: "containsrune=☻", ExpectedNil: false},
3941 for i, s := range tests {
3942 errs := validate.Var(s.Value, s.Tag)
3944 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
3945 t.Fatalf("Index: %d failed Error: %s", i, errs)
3948 errs = validate.Struct(s)
3950 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
3951 t.Fatalf("Index: %d failed Error: %s", i, errs)
3956 func TestContainsAnyValidation(t *testing.T) {
3959 Value string `validate:"containsany=@!{}[]"`
3963 {Value: "abcd@!jfk", Tag: "containsany=@!{}[]", ExpectedNil: true},
3964 {Value: "abcdefg", Tag: "containsany=@!{}[]", ExpectedNil: false},
3969 for i, s := range tests {
3970 errs := validate.Var(s.Value, s.Tag)
3972 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
3973 t.Fatalf("Index: %d failed Error: %s", i, errs)
3976 errs = validate.Struct(s)
3978 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
3979 t.Fatalf("Index: %d failed Error: %s", i, errs)
3984 func TestContainsValidation(t *testing.T) {
3987 Value string `validate:"contains=@"`
3991 {Value: "abcd@!jfk", Tag: "contains=@", ExpectedNil: true},
3992 {Value: "abcdq!jfk", Tag: "contains=@", ExpectedNil: false},
3997 for i, s := range tests {
3998 errs := validate.Var(s.Value, s.Tag)
4000 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
4001 t.Fatalf("Index: %d failed Error: %s", i, errs)
4004 errs = validate.Struct(s)
4006 if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
4007 t.Fatalf("Index: %d failed Error: %s", i, errs)
4012 func TestIsNeFieldValidation(t *testing.T) {
4022 arr := []string{"test"}
4023 now := time.Now().UTC()
4031 arr2 := []string{"test", "test2"}
4032 arr3 := []string{"test"}
4035 errs := validate.VarWithValue(s, s2, "nefield")
4038 errs = validate.VarWithValue(i2, i, "nefield")
4041 errs = validate.VarWithValue(j2, j, "nefield")
4044 errs = validate.VarWithValue(k2, k, "nefield")
4047 errs = validate.VarWithValue(arr2, arr, "nefield")
4050 errs = validate.VarWithValue(now2, now, "nefield")
4051 NotEqual(t, errs, nil)
4052 AssertError(t, errs, "", "", "", "", "nefield")
4054 errs = validate.VarWithValue(arr3, arr, "nefield")
4055 NotEqual(t, errs, nil)
4056 AssertError(t, errs, "", "", "", "", "nefield")
4059 Start *time.Time `validate:"nefield=End"`
4068 errs = validate.Struct(sv)
4069 NotEqual(t, errs, nil)
4070 AssertError(t, errs, "Test.Start", "Test.Start", "Start", "Start", "nefield")
4072 now3 := time.Now().UTC()
4079 errs = validate.Struct(sv)
4082 errs = validate.VarWithValue(nil, 1, "nefield")
4083 NotEqual(t, errs, nil)
4084 AssertError(t, errs, "", "", "", "", "nefield")
4086 errs = validate.VarWithValue(sv, now, "nefield")
4090 Start *time.Time `validate:"nefield=NonExistantField"`
4099 errs = validate.Struct(sv2)
4108 Time time.Time `validate:"nefield=Value"`
4112 Value: Other{Value: "StringVal"},
4116 errs = validate.Struct(tst)
4120 func TestIsNeValidation(t *testing.T) {
4130 arr := []string{"test"}
4131 now := time.Now().UTC()
4133 errs := validate.Var(s, "ne=abcd")
4136 errs = validate.Var(i, "ne=1")
4139 errs = validate.Var(j, "ne=1")
4142 errs = validate.Var(k, "ne=1.543")
4145 errs = validate.Var(arr, "ne=2")
4148 errs = validate.Var(arr, "ne=1")
4149 NotEqual(t, errs, nil)
4150 AssertError(t, errs, "", "", "", "", "ne")
4152 PanicMatches(t, func() { validate.Var(now, "ne=now") }, "Bad field type time.Time")
4155 func TestIsEqFieldValidation(t *testing.T) {
4165 arr := []string{"test"}
4166 now := time.Now().UTC()
4174 arr2 := []string{"test"}
4175 arr3 := []string{"test", "test2"}
4178 errs := validate.VarWithValue(s, s2, "eqfield")
4181 errs = validate.VarWithValue(i2, i, "eqfield")
4184 errs = validate.VarWithValue(j2, j, "eqfield")
4187 errs = validate.VarWithValue(k2, k, "eqfield")
4190 errs = validate.VarWithValue(arr2, arr, "eqfield")
4193 errs = validate.VarWithValue(now2, now, "eqfield")
4196 errs = validate.VarWithValue(arr3, arr, "eqfield")
4197 NotEqual(t, errs, nil)
4198 AssertError(t, errs, "", "", "", "", "eqfield")
4201 Start *time.Time `validate:"eqfield=End"`
4210 errs = validate.Struct(sv)
4213 now3 := time.Now().UTC()
4220 errs = validate.Struct(sv)
4221 NotEqual(t, errs, nil)
4222 AssertError(t, errs, "Test.Start", "Test.Start", "Start", "Start", "eqfield")
4224 errs = validate.VarWithValue(nil, 1, "eqfield")
4225 NotEqual(t, errs, nil)
4226 AssertError(t, errs, "", "", "", "", "eqfield")
4228 channel := make(chan string)
4229 errs = validate.VarWithValue(5, channel, "eqfield")
4230 NotEqual(t, errs, nil)
4231 AssertError(t, errs, "", "", "", "", "eqfield")
4233 errs = validate.VarWithValue(5, now, "eqfield")
4234 NotEqual(t, errs, nil)
4235 AssertError(t, errs, "", "", "", "", "eqfield")
4238 Start *time.Time `validate:"eqfield=NonExistantField"`
4247 errs = validate.Struct(sv2)
4248 NotEqual(t, errs, nil)
4249 AssertError(t, errs, "Test2.Start", "Test2.Start", "Start", "Start", "eqfield")
4255 type TStruct struct {
4257 CreatedAt *time.Time `validate:"eqfield=Inner"`
4269 errs = validate.Struct(test)
4270 NotEqual(t, errs, nil)
4271 AssertError(t, errs, "TStruct.CreatedAt", "TStruct.CreatedAt", "CreatedAt", "CreatedAt", "eqfield")
4274 func TestIsEqValidation(t *testing.T) {
4284 arr := []string{"test"}
4285 now := time.Now().UTC()
4287 errs := validate.Var(s, "eq=abcd")
4290 errs = validate.Var(i, "eq=1")
4293 errs = validate.Var(j, "eq=1")
4296 errs = validate.Var(k, "eq=1.543")
4299 errs = validate.Var(arr, "eq=1")
4302 errs = validate.Var(arr, "eq=2")
4303 NotEqual(t, errs, nil)
4304 AssertError(t, errs, "", "", "", "", "eq")
4306 PanicMatches(t, func() { validate.Var(now, "eq=now") }, "Bad field type time.Time")
4309 func TestBase64Validation(t *testing.T) {
4315 errs := validate.Var(s, "base64")
4318 s = "dGhpIGlzIGEgdGVzdCBiYXNlNjQ="
4319 errs = validate.Var(s, "base64")
4323 errs = validate.Var(s, "base64")
4324 NotEqual(t, errs, nil)
4325 AssertError(t, errs, "", "", "", "", "base64")
4327 s = "dW5pY29ybg== foo bar"
4328 errs = validate.Var(s, "base64")
4329 NotEqual(t, errs, nil)
4330 AssertError(t, errs, "", "", "", "", "base64")
4333 func TestNoStructLevelValidation(t *testing.T) {
4336 Test string `validate:"len=5"`
4340 InnerStruct *Inner `validate:"required,nostructlevel"`
4349 errs := validate.Struct(outer)
4350 NotEqual(t, errs, nil)
4351 AssertError(t, errs, "Outer.InnerStruct", "Outer.InnerStruct", "InnerStruct", "InnerStruct", "required")
4361 errs = validate.Struct(outer)
4365 func TestStructOnlyValidation(t *testing.T) {
4368 Test string `validate:"len=5"`
4372 InnerStruct *Inner `validate:"required,structonly"`
4381 errs := validate.Struct(outer)
4382 NotEqual(t, errs, nil)
4383 AssertError(t, errs, "Outer.InnerStruct", "Outer.InnerStruct", "InnerStruct", "InnerStruct", "required")
4393 errs = validate.Struct(outer)
4396 // Address houses a users address information
4397 type Address struct {
4398 Street string `validate:"required"`
4399 City string `validate:"required"`
4400 Planet string `validate:"required"`
4401 Phone string `validate:"required"`
4405 FirstName string `json:"fname"`
4406 LastName string `json:"lname"`
4407 Age uint8 `validate:"gte=0,lte=130"`
4408 Email string `validate:"required,email"`
4409 FavouriteColor string `validate:"hexcolor|rgb|rgba"`
4410 Addresses []*Address `validate:"required"` // a person can have a home and cottage...
4411 Address Address `validate:"structonly"` // a person can have a home and cottage...
4414 address := &Address{
4415 Street: "Eavesdown Docks",
4416 Planet: "Persphone",
4425 Email: "Badger.Smith@gmail.com",
4426 FavouriteColor: "#000",
4427 Addresses: []*Address{address},
4429 // Street: "Eavesdown Docks",
4430 Planet: "Persphone",
4436 errs = validate.Struct(user)
4440 func TestGtField(t *testing.T) {
4444 type TimeTest struct {
4445 Start *time.Time `validate:"required,gt"`
4446 End *time.Time `validate:"required,gt,gtfield=Start"`
4450 start := now.Add(time.Hour * 24)
4451 end := start.Add(time.Hour * 24)
4453 timeTest := &TimeTest{
4458 errs := validate.Struct(timeTest)
4461 timeTest = &TimeTest{
4466 errs = validate.Struct(timeTest)
4467 NotEqual(t, errs, nil)
4468 AssertError(t, errs, "TimeTest.End", "TimeTest.End", "End", "End", "gtfield")
4470 errs = validate.VarWithValue(&end, &start, "gtfield")
4473 errs = validate.VarWithValue(&start, &end, "gtfield")
4474 NotEqual(t, errs, nil)
4475 AssertError(t, errs, "", "", "", "", "gtfield")
4477 errs = validate.VarWithValue(&end, &start, "gtfield")
4480 errs = validate.VarWithValue(&timeTest, &end, "gtfield")
4481 NotEqual(t, errs, nil)
4483 errs = validate.VarWithValue("test bigger", "test", "gtfield")
4486 type IntTest struct {
4487 Val1 int `validate:"required"`
4488 Val2 int `validate:"required,gtfield=Val1"`
4491 intTest := &IntTest{
4496 errs = validate.Struct(intTest)
4504 errs = validate.Struct(intTest)
4505 NotEqual(t, errs, nil)
4506 AssertError(t, errs, "IntTest.Val2", "IntTest.Val2", "Val2", "Val2", "gtfield")
4508 errs = validate.VarWithValue(int(5), int(1), "gtfield")
4511 errs = validate.VarWithValue(int(1), int(5), "gtfield")
4512 NotEqual(t, errs, nil)
4513 AssertError(t, errs, "", "", "", "", "gtfield")
4515 type UIntTest struct {
4516 Val1 uint `validate:"required"`
4517 Val2 uint `validate:"required,gtfield=Val1"`
4520 uIntTest := &UIntTest{
4525 errs = validate.Struct(uIntTest)
4528 uIntTest = &UIntTest{
4533 errs = validate.Struct(uIntTest)
4534 NotEqual(t, errs, nil)
4535 AssertError(t, errs, "UIntTest.Val2", "UIntTest.Val2", "Val2", "Val2", "gtfield")
4537 errs = validate.VarWithValue(uint(5), uint(1), "gtfield")
4540 errs = validate.VarWithValue(uint(1), uint(5), "gtfield")
4541 NotEqual(t, errs, nil)
4542 AssertError(t, errs, "", "", "", "", "gtfield")
4544 type FloatTest struct {
4545 Val1 float64 `validate:"required"`
4546 Val2 float64 `validate:"required,gtfield=Val1"`
4549 floatTest := &FloatTest{
4554 errs = validate.Struct(floatTest)
4557 floatTest = &FloatTest{
4562 errs = validate.Struct(floatTest)
4563 NotEqual(t, errs, nil)
4564 AssertError(t, errs, "FloatTest.Val2", "FloatTest.Val2", "Val2", "Val2", "gtfield")
4566 errs = validate.VarWithValue(float32(5), float32(1), "gtfield")
4569 errs = validate.VarWithValue(float32(1), float32(5), "gtfield")
4570 NotEqual(t, errs, nil)
4571 AssertError(t, errs, "", "", "", "", "gtfield")
4573 errs = validate.VarWithValue(nil, 1, "gtfield")
4574 NotEqual(t, errs, nil)
4575 AssertError(t, errs, "", "", "", "", "gtfield")
4577 errs = validate.VarWithValue(5, "T", "gtfield")
4578 NotEqual(t, errs, nil)
4579 AssertError(t, errs, "", "", "", "", "gtfield")
4581 errs = validate.VarWithValue(5, start, "gtfield")
4582 NotEqual(t, errs, nil)
4583 AssertError(t, errs, "", "", "", "", "gtfield")
4585 type TimeTest2 struct {
4586 Start *time.Time `validate:"required"`
4587 End *time.Time `validate:"required,gtfield=NonExistantField"`
4590 timeTest2 := &TimeTest2{
4595 errs = validate.Struct(timeTest2)
4596 NotEqual(t, errs, nil)
4597 AssertError(t, errs, "TimeTest2.End", "TimeTest2.End", "End", "End", "gtfield")
4605 Time time.Time `validate:"gtfield=Value"`
4609 Value: Other{Value: "StringVal"},
4613 errs = validate.Struct(tst)
4614 NotEqual(t, errs, nil)
4615 AssertError(t, errs, "Test.Time", "Test.Time", "Time", "Time", "gtfield")
4618 func TestLtField(t *testing.T) {
4622 type TimeTest struct {
4623 Start *time.Time `validate:"required,lt,ltfield=End"`
4624 End *time.Time `validate:"required,lt"`
4628 start := now.Add(time.Hour * 24 * -1 * 2)
4629 end := start.Add(time.Hour * 24)
4631 timeTest := &TimeTest{
4636 errs := validate.Struct(timeTest)
4639 timeTest = &TimeTest{
4644 errs = validate.Struct(timeTest)
4645 NotEqual(t, errs, nil)
4646 AssertError(t, errs, "TimeTest.Start", "TimeTest.Start", "Start", "Start", "ltfield")
4648 errs = validate.VarWithValue(&start, &end, "ltfield")
4651 errs = validate.VarWithValue(&end, &start, "ltfield")
4652 NotEqual(t, errs, nil)
4653 AssertError(t, errs, "", "", "", "", "ltfield")
4655 errs = validate.VarWithValue(&end, timeTest, "ltfield")
4656 NotEqual(t, errs, nil)
4657 AssertError(t, errs, "", "", "", "", "ltfield")
4659 errs = validate.VarWithValue("tes", "test", "ltfield")
4662 type IntTest struct {
4663 Val1 int `validate:"required"`
4664 Val2 int `validate:"required,ltfield=Val1"`
4667 intTest := &IntTest{
4672 errs = validate.Struct(intTest)
4680 errs = validate.Struct(intTest)
4681 NotEqual(t, errs, nil)
4682 AssertError(t, errs, "IntTest.Val2", "IntTest.Val2", "Val2", "Val2", "ltfield")
4684 errs = validate.VarWithValue(int(1), int(5), "ltfield")
4687 errs = validate.VarWithValue(int(5), int(1), "ltfield")
4688 NotEqual(t, errs, nil)
4689 AssertError(t, errs, "", "", "", "", "ltfield")
4691 type UIntTest struct {
4692 Val1 uint `validate:"required"`
4693 Val2 uint `validate:"required,ltfield=Val1"`
4696 uIntTest := &UIntTest{
4701 errs = validate.Struct(uIntTest)
4704 uIntTest = &UIntTest{
4709 errs = validate.Struct(uIntTest)
4710 NotEqual(t, errs, nil)
4711 AssertError(t, errs, "UIntTest.Val2", "UIntTest.Val2", "Val2", "Val2", "ltfield")
4713 errs = validate.VarWithValue(uint(1), uint(5), "ltfield")
4716 errs = validate.VarWithValue(uint(5), uint(1), "ltfield")
4717 NotEqual(t, errs, nil)
4718 AssertError(t, errs, "", "", "", "", "ltfield")
4720 type FloatTest struct {
4721 Val1 float64 `validate:"required"`
4722 Val2 float64 `validate:"required,ltfield=Val1"`
4725 floatTest := &FloatTest{
4730 errs = validate.Struct(floatTest)
4733 floatTest = &FloatTest{
4738 errs = validate.Struct(floatTest)
4739 NotEqual(t, errs, nil)
4740 AssertError(t, errs, "FloatTest.Val2", "FloatTest.Val2", "Val2", "Val2", "ltfield")
4742 errs = validate.VarWithValue(float32(1), float32(5), "ltfield")
4745 errs = validate.VarWithValue(float32(5), float32(1), "ltfield")
4746 NotEqual(t, errs, nil)
4747 AssertError(t, errs, "", "", "", "", "ltfield")
4749 errs = validate.VarWithValue(nil, 5, "ltfield")
4750 NotEqual(t, errs, nil)
4751 AssertError(t, errs, "", "", "", "", "ltfield")
4753 errs = validate.VarWithValue(1, "T", "ltfield")
4754 NotEqual(t, errs, nil)
4755 AssertError(t, errs, "", "", "", "", "ltfield")
4757 errs = validate.VarWithValue(1, end, "ltfield")
4758 NotEqual(t, errs, nil)
4759 AssertError(t, errs, "", "", "", "", "ltfield")
4761 type TimeTest2 struct {
4762 Start *time.Time `validate:"required"`
4763 End *time.Time `validate:"required,ltfield=NonExistantField"`
4766 timeTest2 := &TimeTest2{
4771 errs = validate.Struct(timeTest2)
4772 NotEqual(t, errs, nil)
4773 AssertError(t, errs, "TimeTest2.End", "TimeTest2.End", "End", "End", "ltfield")
4776 func TestLteField(t *testing.T) {
4780 type TimeTest struct {
4781 Start *time.Time `validate:"required,lte,ltefield=End"`
4782 End *time.Time `validate:"required,lte"`
4786 start := now.Add(time.Hour * 24 * -1 * 2)
4787 end := start.Add(time.Hour * 24)
4789 timeTest := &TimeTest{
4794 errs := validate.Struct(timeTest)
4797 timeTest = &TimeTest{
4802 errs = validate.Struct(timeTest)
4803 NotEqual(t, errs, nil)
4804 AssertError(t, errs, "TimeTest.Start", "TimeTest.Start", "Start", "Start", "ltefield")
4806 errs = validate.VarWithValue(&start, &end, "ltefield")
4809 errs = validate.VarWithValue(&end, &start, "ltefield")
4810 NotEqual(t, errs, nil)
4811 AssertError(t, errs, "", "", "", "", "ltefield")
4813 errs = validate.VarWithValue(&end, timeTest, "ltefield")
4814 NotEqual(t, errs, nil)
4815 AssertError(t, errs, "", "", "", "", "ltefield")
4817 errs = validate.VarWithValue("tes", "test", "ltefield")
4820 errs = validate.VarWithValue("test", "test", "ltefield")
4823 type IntTest struct {
4824 Val1 int `validate:"required"`
4825 Val2 int `validate:"required,ltefield=Val1"`
4828 intTest := &IntTest{
4833 errs = validate.Struct(intTest)
4841 errs = validate.Struct(intTest)
4842 NotEqual(t, errs, nil)
4843 AssertError(t, errs, "IntTest.Val2", "IntTest.Val2", "Val2", "Val2", "ltefield")
4845 errs = validate.VarWithValue(int(1), int(5), "ltefield")
4848 errs = validate.VarWithValue(int(5), int(1), "ltefield")
4849 NotEqual(t, errs, nil)
4850 AssertError(t, errs, "", "", "", "", "ltefield")
4852 type UIntTest struct {
4853 Val1 uint `validate:"required"`
4854 Val2 uint `validate:"required,ltefield=Val1"`
4857 uIntTest := &UIntTest{
4862 errs = validate.Struct(uIntTest)
4865 uIntTest = &UIntTest{
4870 errs = validate.Struct(uIntTest)
4871 NotEqual(t, errs, nil)
4872 AssertError(t, errs, "UIntTest.Val2", "UIntTest.Val2", "Val2", "Val2", "ltefield")
4874 errs = validate.VarWithValue(uint(1), uint(5), "ltefield")
4877 errs = validate.VarWithValue(uint(5), uint(1), "ltefield")
4878 NotEqual(t, errs, nil)
4879 AssertError(t, errs, "", "", "", "", "ltefield")
4881 type FloatTest struct {
4882 Val1 float64 `validate:"required"`
4883 Val2 float64 `validate:"required,ltefield=Val1"`
4886 floatTest := &FloatTest{
4891 errs = validate.Struct(floatTest)
4894 floatTest = &FloatTest{
4899 errs = validate.Struct(floatTest)
4900 NotEqual(t, errs, nil)
4901 AssertError(t, errs, "FloatTest.Val2", "FloatTest.Val2", "Val2", "Val2", "ltefield")
4903 errs = validate.VarWithValue(float32(1), float32(5), "ltefield")
4906 errs = validate.VarWithValue(float32(5), float32(1), "ltefield")
4907 NotEqual(t, errs, nil)
4908 AssertError(t, errs, "", "", "", "", "ltefield")
4910 errs = validate.VarWithValue(nil, 5, "ltefield")
4911 NotEqual(t, errs, nil)
4912 AssertError(t, errs, "", "", "", "", "ltefield")
4914 errs = validate.VarWithValue(1, "T", "ltefield")
4915 NotEqual(t, errs, nil)
4916 AssertError(t, errs, "", "", "", "", "ltefield")
4918 errs = validate.VarWithValue(1, end, "ltefield")
4919 NotEqual(t, errs, nil)
4920 AssertError(t, errs, "", "", "", "", "ltefield")
4922 type TimeTest2 struct {
4923 Start *time.Time `validate:"required"`
4924 End *time.Time `validate:"required,ltefield=NonExistantField"`
4927 timeTest2 := &TimeTest2{
4932 errs = validate.Struct(timeTest2)
4933 NotEqual(t, errs, nil)
4934 AssertError(t, errs, "TimeTest2.End", "TimeTest2.End", "End", "End", "ltefield")
4937 func TestGteField(t *testing.T) {
4941 type TimeTest struct {
4942 Start *time.Time `validate:"required,gte"`
4943 End *time.Time `validate:"required,gte,gtefield=Start"`
4947 start := now.Add(time.Hour * 24)
4948 end := start.Add(time.Hour * 24)
4950 timeTest := &TimeTest{
4955 errs := validate.Struct(timeTest)
4958 timeTest = &TimeTest{
4963 errs = validate.Struct(timeTest)
4964 NotEqual(t, errs, nil)
4965 AssertError(t, errs, "TimeTest.End", "TimeTest.End", "End", "End", "gtefield")
4967 errs = validate.VarWithValue(&end, &start, "gtefield")
4970 errs = validate.VarWithValue(&start, &end, "gtefield")
4971 NotEqual(t, errs, nil)
4972 AssertError(t, errs, "", "", "", "", "gtefield")
4974 errs = validate.VarWithValue(&start, timeTest, "gtefield")
4975 NotEqual(t, errs, nil)
4976 AssertError(t, errs, "", "", "", "", "gtefield")
4978 errs = validate.VarWithValue("test", "test", "gtefield")
4981 errs = validate.VarWithValue("test bigger", "test", "gtefield")
4984 type IntTest struct {
4985 Val1 int `validate:"required"`
4986 Val2 int `validate:"required,gtefield=Val1"`
4989 intTest := &IntTest{
4994 errs = validate.Struct(intTest)
5002 errs = validate.Struct(intTest)
5003 NotEqual(t, errs, nil)
5004 AssertError(t, errs, "IntTest.Val2", "IntTest.Val2", "Val2", "Val2", "gtefield")
5006 errs = validate.VarWithValue(int(5), int(1), "gtefield")
5009 errs = validate.VarWithValue(int(1), int(5), "gtefield")
5010 NotEqual(t, errs, nil)
5011 AssertError(t, errs, "", "", "", "", "gtefield")
5013 type UIntTest struct {
5014 Val1 uint `validate:"required"`
5015 Val2 uint `validate:"required,gtefield=Val1"`
5018 uIntTest := &UIntTest{
5023 errs = validate.Struct(uIntTest)
5026 uIntTest = &UIntTest{
5031 errs = validate.Struct(uIntTest)
5032 NotEqual(t, errs, nil)
5033 AssertError(t, errs, "UIntTest.Val2", "UIntTest.Val2", "Val2", "Val2", "gtefield")
5035 errs = validate.VarWithValue(uint(5), uint(1), "gtefield")
5038 errs = validate.VarWithValue(uint(1), uint(5), "gtefield")
5039 NotEqual(t, errs, nil)
5040 AssertError(t, errs, "", "", "", "", "gtefield")
5042 type FloatTest struct {
5043 Val1 float64 `validate:"required"`
5044 Val2 float64 `validate:"required,gtefield=Val1"`
5047 floatTest := &FloatTest{
5052 errs = validate.Struct(floatTest)
5055 floatTest = &FloatTest{
5060 errs = validate.Struct(floatTest)
5061 NotEqual(t, errs, nil)
5062 AssertError(t, errs, "FloatTest.Val2", "FloatTest.Val2", "Val2", "Val2", "gtefield")
5064 errs = validate.VarWithValue(float32(5), float32(1), "gtefield")
5067 errs = validate.VarWithValue(float32(1), float32(5), "gtefield")
5068 NotEqual(t, errs, nil)
5069 AssertError(t, errs, "", "", "", "", "gtefield")
5071 errs = validate.VarWithValue(nil, 1, "gtefield")
5072 NotEqual(t, errs, nil)
5073 AssertError(t, errs, "", "", "", "", "gtefield")
5075 errs = validate.VarWithValue(5, "T", "gtefield")
5076 NotEqual(t, errs, nil)
5077 AssertError(t, errs, "", "", "", "", "gtefield")
5079 errs = validate.VarWithValue(5, start, "gtefield")
5080 NotEqual(t, errs, nil)
5081 AssertError(t, errs, "", "", "", "", "gtefield")
5083 type TimeTest2 struct {
5084 Start *time.Time `validate:"required"`
5085 End *time.Time `validate:"required,gtefield=NonExistantField"`
5088 timeTest2 := &TimeTest2{
5093 errs = validate.Struct(timeTest2)
5094 NotEqual(t, errs, nil)
5095 AssertError(t, errs, "TimeTest2.End", "TimeTest2.End", "End", "End", "gtefield")
5098 func TestValidateByTagAndValue(t *testing.T) {
5104 errs := validate.VarWithValue(val, field, "required")
5107 fn := func(fl FieldLevel) bool {
5109 return fl.Parent().String() == fl.Field().String()
5112 validate.RegisterValidation("isequaltestfunc", fn)
5114 errs = validate.VarWithValue(val, field, "isequaltestfunc")
5119 errs = validate.VarWithValue(val, field, "isequaltestfunc")
5120 NotEqual(t, errs, nil)
5121 AssertError(t, errs, "", "", "", "", "isequaltestfunc")
5124 func TestAddFunctions(t *testing.T) {
5126 fn := func(fl FieldLevel) bool {
5131 fnCtx := func(ctx context.Context, fl FieldLevel) bool {
5137 errs := validate.RegisterValidation("new", fn)
5140 errs = validate.RegisterValidation("", fn)
5141 NotEqual(t, errs, nil)
5143 validate.RegisterValidation("new", nil)
5144 NotEqual(t, errs, nil)
5146 errs = validate.RegisterValidation("new", fn)
5149 errs = validate.RegisterValidationCtx("new", fnCtx)
5152 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")
5155 func TestChangeTag(t *testing.T) {
5158 validate.SetTagName("val")
5161 Name string `val:"len=4"`
5167 errs := validate.Struct(s)
5172 errs = validate.Struct(s)
5173 NotEqual(t, errs, nil)
5174 AssertError(t, errs, "Test.Name", "Test.Name", "Name", "Name", "len")
5177 func TestUnexposedStruct(t *testing.T) {
5184 A string `validate:"required"`
5192 errs := validate.Struct(s)
5196 func TestBadParams(t *testing.T) {
5201 errs := validate.Var(i, "-")
5204 PanicMatches(t, func() { validate.Var(i, "len=a") }, "strconv.ParseInt: parsing \"a\": invalid syntax")
5205 PanicMatches(t, func() { validate.Var(i, "len=a") }, "strconv.ParseInt: parsing \"a\": invalid syntax")
5208 PanicMatches(t, func() { validate.Var(ui, "len=a") }, "strconv.ParseUint: parsing \"a\": invalid syntax")
5211 PanicMatches(t, func() { validate.Var(f, "len=a") }, "strconv.ParseFloat: parsing \"a\": invalid syntax")
5214 func TestLength(t *testing.T) {
5219 PanicMatches(t, func() { validate.Var(i, "len") }, "Bad field type bool")
5222 func TestIsGt(t *testing.T) {
5226 myMap := map[string]string{}
5227 errs := validate.Var(myMap, "gt=0")
5228 NotEqual(t, errs, nil)
5231 errs = validate.Var(f, "gt=5")
5232 NotEqual(t, errs, nil)
5233 AssertError(t, errs, "", "", "", "", "gt")
5236 errs = validate.Var(ui, "gt=10")
5237 NotEqual(t, errs, nil)
5238 AssertError(t, errs, "", "", "", "", "gt")
5241 PanicMatches(t, func() { validate.Var(i, "gt") }, "Bad field type bool")
5243 tm := time.Now().UTC()
5244 tm = tm.Add(time.Hour * 24)
5246 errs = validate.Var(tm, "gt")
5249 t2 := time.Now().UTC().Add(-time.Hour)
5251 errs = validate.Var(t2, "gt")
5252 NotEqual(t, errs, nil)
5253 AssertError(t, errs, "", "", "", "", "gt")
5256 Now *time.Time `validate:"gt"`
5262 errs = validate.Struct(s)
5269 errs = validate.Struct(s)
5270 NotEqual(t, errs, nil)
5271 AssertError(t, errs, "Test.Now", "Test.Now", "Now", "Now", "gt")
5274 func TestIsGte(t *testing.T) {
5279 PanicMatches(t, func() { validate.Var(i, "gte") }, "Bad field type bool")
5281 t1 := time.Now().UTC()
5282 t1 = t1.Add(time.Hour * 24)
5284 errs := validate.Var(t1, "gte")
5287 t2 := time.Now().UTC().Add(-time.Hour)
5289 errs = validate.Var(t2, "gte")
5290 NotEqual(t, errs, nil)
5291 AssertError(t, errs, "", "", "", "", "gte")
5294 Now *time.Time `validate:"gte"`
5300 errs = validate.Struct(s)
5307 errs = validate.Struct(s)
5308 NotEqual(t, errs, nil)
5309 AssertError(t, errs, "Test.Now", "Test.Now", "Now", "Now", "gte")
5312 func TestIsLt(t *testing.T) {
5316 myMap := map[string]string{}
5317 errs := validate.Var(myMap, "lt=0")
5318 NotEqual(t, errs, nil)
5319 AssertError(t, errs, "", "", "", "", "lt")
5322 errs = validate.Var(f, "lt=0")
5323 NotEqual(t, errs, nil)
5324 AssertError(t, errs, "", "", "", "", "lt")
5327 errs = validate.Var(ui, "lt=0")
5328 NotEqual(t, errs, nil)
5329 AssertError(t, errs, "", "", "", "", "lt")
5332 PanicMatches(t, func() { validate.Var(i, "lt") }, "Bad field type bool")
5334 t1 := time.Now().UTC().Add(-time.Hour)
5336 errs = validate.Var(t1, "lt")
5339 t2 := time.Now().UTC()
5340 t2 = t2.Add(time.Hour * 24)
5342 errs = validate.Var(t2, "lt")
5343 NotEqual(t, errs, nil)
5344 AssertError(t, errs, "", "", "", "", "lt")
5347 Now *time.Time `validate:"lt"`
5354 errs = validate.Struct(s)
5361 errs = validate.Struct(s)
5362 NotEqual(t, errs, nil)
5363 AssertError(t, errs, "Test.Now", "Test.Now", "Now", "Now", "lt")
5366 func TestIsLte(t *testing.T) {
5371 PanicMatches(t, func() { validate.Var(i, "lte") }, "Bad field type bool")
5373 t1 := time.Now().UTC().Add(-time.Hour)
5375 errs := validate.Var(t1, "lte")
5378 t2 := time.Now().UTC()
5379 t2 = t2.Add(time.Hour * 24)
5381 errs = validate.Var(t2, "lte")
5382 NotEqual(t, errs, nil)
5383 AssertError(t, errs, "", "", "", "", "lte")
5386 Now *time.Time `validate:"lte"`
5393 errs = validate.Struct(s)
5400 errs = validate.Struct(s)
5401 NotEqual(t, errs, nil)
5404 func TestUrl(t *testing.T) {
5406 var tests = []struct {
5410 {"http://foo.bar#com", true},
5411 {"http://foobar.com", true},
5412 {"https://foobar.com", true},
5413 {"foobar.com", false},
5414 {"http://foobar.coffee/", true},
5415 {"http://foobar.中文网/", true},
5416 {"http://foobar.org/", true},
5417 {"http://foobar.org:8080/", true},
5418 {"ftp://foobar.ru/", true},
5419 {"http://user:pass@www.foobar.com/", true},
5420 {"http://127.0.0.1/", true},
5421 {"http://duckduckgo.com/?q=%2F", true},
5422 {"http://localhost:3000/", true},
5423 {"http://foobar.com/?foo=bar#baz=qux", true},
5424 {"http://foobar.com?foo=bar", true},
5425 {"http://www.xn--froschgrn-x9a.net/", true},
5427 {"xyz://foobar.com", true},
5428 {"invalid.", false},
5430 {"rtmp://foobar.com", true},
5431 {"http://www.foo_bar.com/", true},
5432 {"http://localhost:3000/", true},
5433 {"http://foobar.com/#baz", true},
5434 {"http://foobar.com#baz=qux", true},
5435 {"http://foobar.com/t$-_.+!*\\'(),", true},
5436 {"http://www.foobar.com/~foobar", true},
5437 {"http://www.-foobar.com/", true},
5438 {"http://www.foo---bar.com/", true},
5439 {"mailto:someone@example.com", true},
5440 {"irc://irc.server.org/channel", true},
5441 {"irc://#channel@network", true},
5442 {"/abs/test/dir", false},
5443 {"./rel/test/dir", false},
5448 for i, test := range tests {
5450 errs := validate.Var(test.param, "url")
5453 if !IsEqual(errs, nil) {
5454 t.Fatalf("Index: %d URL failed Error: %s", i, errs)
5457 if IsEqual(errs, nil) {
5458 t.Fatalf("Index: %d URL failed Error: %s", i, errs)
5460 val := getError(errs, "", "")
5461 if val.Tag() != "url" {
5462 t.Fatalf("Index: %d URL failed Error: %s", i, errs)
5469 PanicMatches(t, func() { validate.Var(i, "url") }, "Bad field type int")
5472 func TestUri(t *testing.T) {
5474 var tests = []struct {
5478 {"http://foo.bar#com", true},
5479 {"http://foobar.com", true},
5480 {"https://foobar.com", true},
5481 {"foobar.com", false},
5482 {"http://foobar.coffee/", true},
5483 {"http://foobar.中文网/", true},
5484 {"http://foobar.org/", true},
5485 {"http://foobar.org:8080/", true},
5486 {"ftp://foobar.ru/", true},
5487 {"http://user:pass@www.foobar.com/", true},
5488 {"http://127.0.0.1/", true},
5489 {"http://duckduckgo.com/?q=%2F", true},
5490 {"http://localhost:3000/", true},
5491 {"http://foobar.com/?foo=bar#baz=qux", true},
5492 {"http://foobar.com?foo=bar", true},
5493 {"http://www.xn--froschgrn-x9a.net/", true},
5495 {"xyz://foobar.com", true},
5496 {"invalid.", false},
5498 {"rtmp://foobar.com", true},
5499 {"http://www.foo_bar.com/", true},
5500 {"http://localhost:3000/", true},
5501 {"http://foobar.com#baz=qux", true},
5502 {"http://foobar.com/t$-_.+!*\\'(),", true},
5503 {"http://www.foobar.com/~foobar", true},
5504 {"http://www.-foobar.com/", true},
5505 {"http://www.foo---bar.com/", true},
5506 {"mailto:someone@example.com", true},
5507 {"irc://irc.server.org/channel", true},
5508 {"irc://#channel@network", true},
5509 {"/abs/test/dir", true},
5510 {"./rel/test/dir", false},
5515 for i, test := range tests {
5517 errs := validate.Var(test.param, "uri")
5520 if !IsEqual(errs, nil) {
5521 t.Fatalf("Index: %d URI failed Error: %s", i, errs)
5524 if IsEqual(errs, nil) {
5525 t.Fatalf("Index: %d URI failed Error: %s", i, errs)
5527 val := getError(errs, "", "")
5528 if val.Tag() != "uri" {
5529 t.Fatalf("Index: %d URI failed Error: %s", i, errs)
5536 PanicMatches(t, func() { validate.Var(i, "uri") }, "Bad field type int")
5539 func TestOrTag(t *testing.T) {
5543 s := "rgba(0,31,255,0.5)"
5544 errs := validate.Var(s, "rgb|rgba")
5547 s = "rgba(0,31,255,0.5)"
5548 errs = validate.Var(s, "rgb|rgba|len=18")
5551 s = "this ain't right"
5552 errs = validate.Var(s, "rgb|rgba")
5553 NotEqual(t, errs, nil)
5554 AssertError(t, errs, "", "", "", "", "rgb|rgba")
5556 s = "this ain't right"
5557 errs = validate.Var(s, "rgb|rgba|len=10")
5558 NotEqual(t, errs, nil)
5559 AssertError(t, errs, "", "", "", "", "rgb|rgba|len=10")
5562 errs = validate.Var(s, "rgb|rgba|len=13")
5566 errs = validate.Var(s, "omitempty,rgb|rgba")
5569 s = "this is right, but a blank or isn't"
5571 PanicMatches(t, func() { validate.Var(s, "rgb||len=13") }, "Invalid validation tag on field ''")
5572 PanicMatches(t, func() { validate.Var(s, "rgb|rgbaa|len=13") }, "Undefined validation function 'rgbaa' on field ''")
5575 v2.RegisterTagNameFunc(func(fld reflect.StructField) string {
5577 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
5586 type Colors struct {
5587 Fav string `validate:"rgb|rgba" json:"fc"`
5590 c := Colors{Fav: "this ain't right"}
5593 NotEqual(t, err, nil)
5595 errs = err.(ValidationErrors)
5596 fe := getError(errs, "Colors.fc", "Colors.Fav")
5597 NotEqual(t, fe, nil)
5600 func TestHsla(t *testing.T) {
5604 s := "hsla(360,100%,100%,1)"
5605 errs := validate.Var(s, "hsla")
5608 s = "hsla(360,100%,100%,0.5)"
5609 errs = validate.Var(s, "hsla")
5612 s = "hsla(0,0%,0%, 0)"
5613 errs = validate.Var(s, "hsla")
5616 s = "hsl(361,100%,50%,1)"
5617 errs = validate.Var(s, "hsla")
5618 NotEqual(t, errs, nil)
5619 AssertError(t, errs, "", "", "", "", "hsla")
5621 s = "hsl(361,100%,50%)"
5622 errs = validate.Var(s, "hsla")
5623 NotEqual(t, errs, nil)
5624 AssertError(t, errs, "", "", "", "", "hsla")
5626 s = "hsla(361,100%,50%)"
5627 errs = validate.Var(s, "hsla")
5628 NotEqual(t, errs, nil)
5629 AssertError(t, errs, "", "", "", "", "hsla")
5631 s = "hsla(360,101%,50%)"
5632 errs = validate.Var(s, "hsla")
5633 NotEqual(t, errs, nil)
5634 AssertError(t, errs, "", "", "", "", "hsla")
5636 s = "hsla(360,100%,101%)"
5637 errs = validate.Var(s, "hsla")
5638 NotEqual(t, errs, nil)
5639 AssertError(t, errs, "", "", "", "", "hsla")
5642 validate.Var(i, "hsla")
5643 NotEqual(t, errs, nil)
5644 AssertError(t, errs, "", "", "", "", "hsla")
5647 func TestHsl(t *testing.T) {
5651 s := "hsl(360,100%,50%)"
5652 errs := validate.Var(s, "hsl")
5656 errs = validate.Var(s, "hsl")
5659 s = "hsl(361,100%,50%)"
5660 errs = validate.Var(s, "hsl")
5661 NotEqual(t, errs, nil)
5662 AssertError(t, errs, "", "", "", "", "hsl")
5664 s = "hsl(361,101%,50%)"
5665 errs = validate.Var(s, "hsl")
5666 NotEqual(t, errs, nil)
5667 AssertError(t, errs, "", "", "", "", "hsl")
5669 s = "hsl(361,100%,101%)"
5670 errs = validate.Var(s, "hsl")
5671 NotEqual(t, errs, nil)
5672 AssertError(t, errs, "", "", "", "", "hsl")
5674 s = "hsl(-10,100%,100%)"
5675 errs = validate.Var(s, "hsl")
5676 NotEqual(t, errs, nil)
5677 AssertError(t, errs, "", "", "", "", "hsl")
5680 errs = validate.Var(i, "hsl")
5681 NotEqual(t, errs, nil)
5682 AssertError(t, errs, "", "", "", "", "hsl")
5685 func TestRgba(t *testing.T) {
5689 s := "rgba(0,31,255,0.5)"
5690 errs := validate.Var(s, "rgba")
5693 s = "rgba(0,31,255,0.12)"
5694 errs = validate.Var(s, "rgba")
5697 s = "rgba(12%,55%,100%,0.12)"
5698 errs = validate.Var(s, "rgba")
5701 s = "rgba( 0, 31, 255, 0.5)"
5702 errs = validate.Var(s, "rgba")
5705 s = "rgba(12%,55,100%,0.12)"
5706 errs = validate.Var(s, "rgba")
5707 NotEqual(t, errs, nil)
5708 AssertError(t, errs, "", "", "", "", "rgba")
5710 s = "rgb(0, 31, 255)"
5711 errs = validate.Var(s, "rgba")
5712 NotEqual(t, errs, nil)
5713 AssertError(t, errs, "", "", "", "", "rgba")
5715 s = "rgb(1,349,275,0.5)"
5716 errs = validate.Var(s, "rgba")
5717 NotEqual(t, errs, nil)
5718 AssertError(t, errs, "", "", "", "", "rgba")
5720 s = "rgb(01,31,255,0.5)"
5721 errs = validate.Var(s, "rgba")
5722 NotEqual(t, errs, nil)
5723 AssertError(t, errs, "", "", "", "", "rgba")
5726 errs = validate.Var(i, "rgba")
5727 NotEqual(t, errs, nil)
5728 AssertError(t, errs, "", "", "", "", "rgba")
5731 func TestRgb(t *testing.T) {
5735 s := "rgb(0,31,255)"
5736 errs := validate.Var(s, "rgb")
5739 s = "rgb(0, 31, 255)"
5740 errs = validate.Var(s, "rgb")
5743 s = "rgb(10%, 50%, 100%)"
5744 errs = validate.Var(s, "rgb")
5747 s = "rgb(10%, 50%, 55)"
5748 errs = validate.Var(s, "rgb")
5749 NotEqual(t, errs, nil)
5750 AssertError(t, errs, "", "", "", "", "rgb")
5752 s = "rgb(1,349,275)"
5753 errs = validate.Var(s, "rgb")
5754 NotEqual(t, errs, nil)
5755 AssertError(t, errs, "", "", "", "", "rgb")
5757 s = "rgb(01,31,255)"
5758 errs = validate.Var(s, "rgb")
5759 NotEqual(t, errs, nil)
5760 AssertError(t, errs, "", "", "", "", "rgb")
5762 s = "rgba(0,31,255)"
5763 errs = validate.Var(s, "rgb")
5764 NotEqual(t, errs, nil)
5765 AssertError(t, errs, "", "", "", "", "rgb")
5768 errs = validate.Var(i, "rgb")
5769 NotEqual(t, errs, nil)
5770 AssertError(t, errs, "", "", "", "", "rgb")
5773 func TestEmail(t *testing.T) {
5777 s := "test@mail.com"
5778 errs := validate.Var(s, "email")
5781 s = "Dörte@Sörensen.example.com"
5782 errs = validate.Var(s, "email")
5785 s = "θσερ@εχαμπλε.ψομ"
5786 errs = validate.Var(s, "email")
5789 s = "юзер@екзампл.ком"
5790 errs = validate.Var(s, "email")
5793 s = "उपयोगकर्ता@उदाहरण.कॉम"
5794 errs = validate.Var(s, "email")
5798 errs = validate.Var(s, "email")
5802 errs = validate.Var(s, "email")
5803 NotEqual(t, errs, nil)
5804 AssertError(t, errs, "", "", "", "", "email")
5807 errs = validate.Var(s, "email")
5808 NotEqual(t, errs, nil)
5809 AssertError(t, errs, "", "", "", "", "email")
5812 errs = validate.Var(s, "email")
5813 NotEqual(t, errs, nil)
5814 AssertError(t, errs, "", "", "", "", "email")
5817 errs = validate.Var(s, "email")
5818 NotEqual(t, errs, nil)
5819 AssertError(t, errs, "", "", "", "", "email")
5822 errs = validate.Var(i, "email")
5823 NotEqual(t, errs, nil)
5824 AssertError(t, errs, "", "", "", "", "email")
5827 func TestHexColor(t *testing.T) {
5832 errs := validate.Var(s, "hexcolor")
5836 errs = validate.Var(s, "hexcolor")
5840 errs = validate.Var(s, "hexcolor")
5841 NotEqual(t, errs, nil)
5842 AssertError(t, errs, "", "", "", "", "hexcolor")
5845 errs = validate.Var(s, "hexcolor")
5846 NotEqual(t, errs, nil)
5847 AssertError(t, errs, "", "", "", "", "hexcolor")
5850 errs = validate.Var(i, "hexcolor")
5851 NotEqual(t, errs, nil)
5852 AssertError(t, errs, "", "", "", "", "hexcolor")
5855 func TestHexadecimal(t *testing.T) {
5860 errs := validate.Var(s, "hexadecimal")
5864 errs = validate.Var(s, "hexadecimal")
5865 NotEqual(t, errs, nil)
5866 AssertError(t, errs, "", "", "", "", "hexadecimal")
5869 errs = validate.Var(i, "hexadecimal")
5870 NotEqual(t, errs, nil)
5871 AssertError(t, errs, "", "", "", "", "hexadecimal")
5874 func TestNumber(t *testing.T) {
5879 errs := validate.Var(s, "number")
5883 errs = validate.Var(s, "number")
5884 NotEqual(t, errs, nil)
5885 AssertError(t, errs, "", "", "", "", "number")
5888 errs = validate.Var(s, "number")
5889 NotEqual(t, errs, nil)
5890 AssertError(t, errs, "", "", "", "", "number")
5893 errs = validate.Var(s, "number")
5894 NotEqual(t, errs, nil)
5895 AssertError(t, errs, "", "", "", "", "number")
5898 errs = validate.Var(s, "number")
5899 NotEqual(t, errs, nil)
5900 AssertError(t, errs, "", "", "", "", "number")
5903 errs = validate.Var(s, "number")
5904 NotEqual(t, errs, nil)
5905 AssertError(t, errs, "", "", "", "", "number")
5908 errs = validate.Var(s, "number")
5909 NotEqual(t, errs, nil)
5910 AssertError(t, errs, "", "", "", "", "number")
5913 errs = validate.Var(s, "number")
5914 NotEqual(t, errs, nil)
5915 AssertError(t, errs, "", "", "", "", "number")
5918 errs = validate.Var(i, "number")
5919 NotEqual(t, errs, nil)
5920 AssertError(t, errs, "", "", "", "", "number")
5923 func TestNumeric(t *testing.T) {
5928 errs := validate.Var(s, "numeric")
5932 errs = validate.Var(s, "numeric")
5936 errs = validate.Var(s, "numeric")
5940 errs = validate.Var(s, "numeric")
5944 errs = validate.Var(s, "numeric")
5948 errs = validate.Var(s, "numeric")
5952 errs = validate.Var(s, "numeric")
5953 NotEqual(t, errs, nil)
5954 AssertError(t, errs, "", "", "", "", "numeric")
5957 errs = validate.Var(s, "numeric")
5958 NotEqual(t, errs, nil)
5959 AssertError(t, errs, "", "", "", "", "numeric")
5962 errs = validate.Var(i, "numeric")
5963 NotEqual(t, errs, nil)
5964 AssertError(t, errs, "", "", "", "", "numeric")
5967 func TestAlphaNumeric(t *testing.T) {
5972 errs := validate.Var(s, "alphanum")
5976 errs = validate.Var(s, "alphanum")
5977 NotEqual(t, errs, nil)
5978 AssertError(t, errs, "", "", "", "", "alphanum")
5980 errs = validate.Var(1, "alphanum")
5981 NotEqual(t, errs, nil)
5982 AssertError(t, errs, "", "", "", "", "alphanum")
5985 func TestAlpha(t *testing.T) {
5990 errs := validate.Var(s, "alpha")
5994 errs = validate.Var(s, "alpha")
5995 NotEqual(t, errs, nil)
5996 AssertError(t, errs, "", "", "", "", "alpha")
5999 errs = validate.Var(s, "alpha")
6000 NotEqual(t, errs, nil)
6001 AssertError(t, errs, "", "", "", "", "alpha")
6004 errs = validate.Var(s, "alpha")
6005 NotEqual(t, errs, nil)
6006 AssertError(t, errs, "", "", "", "", "alpha")
6008 s = "this is a test string"
6009 errs = validate.Var(s, "alpha")
6010 NotEqual(t, errs, nil)
6011 AssertError(t, errs, "", "", "", "", "alpha")
6013 errs = validate.Var(1, "alpha")
6014 NotEqual(t, errs, nil)
6015 AssertError(t, errs, "", "", "", "", "alpha")
6019 func TestStructStringValidation(t *testing.T) {
6023 tSuccess := &TestString{
6024 Required: "Required",
6037 SubIgnore: &SubTest{
6041 A string `validate:"required"`
6050 errs := validate.Struct(tSuccess)
6053 tFail := &TestString{
6063 OmitEmpty: "12345678901",
6068 A string `validate:"required"`
6077 errs = validate.Struct(tFail)
6080 NotEqual(t, errs, nil)
6081 Equal(t, len(errs.(ValidationErrors)), 13)
6084 AssertError(t, errs, "TestString.Required", "TestString.Required", "Required", "Required", "required")
6085 AssertError(t, errs, "TestString.Len", "TestString.Len", "Len", "Len", "len")
6086 AssertError(t, errs, "TestString.Min", "TestString.Min", "Min", "Min", "min")
6087 AssertError(t, errs, "TestString.Max", "TestString.Max", "Max", "Max", "max")
6088 AssertError(t, errs, "TestString.MinMax", "TestString.MinMax", "MinMax", "MinMax", "min")
6089 AssertError(t, errs, "TestString.Lt", "TestString.Lt", "Lt", "Lt", "lt")
6090 AssertError(t, errs, "TestString.Lte", "TestString.Lte", "Lte", "Lte", "lte")
6091 AssertError(t, errs, "TestString.Gt", "TestString.Gt", "Gt", "Gt", "gt")
6092 AssertError(t, errs, "TestString.Gte", "TestString.Gte", "Gte", "Gte", "gte")
6093 AssertError(t, errs, "TestString.OmitEmpty", "TestString.OmitEmpty", "OmitEmpty", "OmitEmpty", "max")
6095 // Nested Struct Field Errs
6096 AssertError(t, errs, "TestString.Anonymous.A", "TestString.Anonymous.A", "A", "A", "required")
6097 AssertError(t, errs, "TestString.Sub.Test", "TestString.Sub.Test", "Test", "Test", "required")
6098 AssertError(t, errs, "TestString.Iface.F", "TestString.Iface.F", "F", "F", "len")
6101 func TestStructInt32Validation(t *testing.T) {
6103 type TestInt32 struct {
6104 Required int `validate:"required"`
6105 Len int `validate:"len=10"`
6106 Min int `validate:"min=1"`
6107 Max int `validate:"max=10"`
6108 MinMax int `validate:"min=1,max=10"`
6109 Lt int `validate:"lt=10"`
6110 Lte int `validate:"lte=10"`
6111 Gt int `validate:"gt=10"`
6112 Gte int `validate:"gte=10"`
6113 OmitEmpty int `validate:"omitempty,min=1,max=10"`
6116 tSuccess := &TestInt32{
6130 errs := validate.Struct(tSuccess)
6133 tFail := &TestInt32{
6146 errs = validate.Struct(tFail)
6149 NotEqual(t, errs, nil)
6150 Equal(t, len(errs.(ValidationErrors)), 10)
6153 AssertError(t, errs, "TestInt32.Required", "TestInt32.Required", "Required", "Required", "required")
6154 AssertError(t, errs, "TestInt32.Len", "TestInt32.Len", "Len", "Len", "len")
6155 AssertError(t, errs, "TestInt32.Min", "TestInt32.Min", "Min", "Min", "min")
6156 AssertError(t, errs, "TestInt32.Max", "TestInt32.Max", "Max", "Max", "max")
6157 AssertError(t, errs, "TestInt32.MinMax", "TestInt32.MinMax", "MinMax", "MinMax", "min")
6158 AssertError(t, errs, "TestInt32.Lt", "TestInt32.Lt", "Lt", "Lt", "lt")
6159 AssertError(t, errs, "TestInt32.Lte", "TestInt32.Lte", "Lte", "Lte", "lte")
6160 AssertError(t, errs, "TestInt32.Gt", "TestInt32.Gt", "Gt", "Gt", "gt")
6161 AssertError(t, errs, "TestInt32.Gte", "TestInt32.Gte", "Gte", "Gte", "gte")
6162 AssertError(t, errs, "TestInt32.OmitEmpty", "TestInt32.OmitEmpty", "OmitEmpty", "OmitEmpty", "max")
6165 func TestStructUint64Validation(t *testing.T) {
6169 tSuccess := &TestUint64{
6178 errs := validate.Struct(tSuccess)
6181 tFail := &TestUint64{
6190 errs = validate.Struct(tFail)
6193 NotEqual(t, errs, nil)
6194 Equal(t, len(errs.(ValidationErrors)), 6)
6197 AssertError(t, errs, "TestUint64.Required", "TestUint64.Required", "Required", "Required", "required")
6198 AssertError(t, errs, "TestUint64.Len", "TestUint64.Len", "Len", "Len", "len")
6199 AssertError(t, errs, "TestUint64.Min", "TestUint64.Min", "Min", "Min", "min")
6200 AssertError(t, errs, "TestUint64.Max", "TestUint64.Max", "Max", "Max", "max")
6201 AssertError(t, errs, "TestUint64.MinMax", "TestUint64.MinMax", "MinMax", "MinMax", "min")
6202 AssertError(t, errs, "TestUint64.OmitEmpty", "TestUint64.OmitEmpty", "OmitEmpty", "OmitEmpty", "max")
6205 func TestStructFloat64Validation(t *testing.T) {
6209 tSuccess := &TestFloat64{
6218 errs := validate.Struct(tSuccess)
6221 tFail := &TestFloat64{
6230 errs = validate.Struct(tFail)
6233 NotEqual(t, errs, nil)
6234 Equal(t, len(errs.(ValidationErrors)), 6)
6237 AssertError(t, errs, "TestFloat64.Required", "TestFloat64.Required", "Required", "Required", "required")
6238 AssertError(t, errs, "TestFloat64.Len", "TestFloat64.Len", "Len", "Len", "len")
6239 AssertError(t, errs, "TestFloat64.Min", "TestFloat64.Min", "Min", "Min", "min")
6240 AssertError(t, errs, "TestFloat64.Max", "TestFloat64.Max", "Max", "Max", "max")
6241 AssertError(t, errs, "TestFloat64.MinMax", "TestFloat64.MinMax", "MinMax", "MinMax", "min")
6242 AssertError(t, errs, "TestFloat64.OmitEmpty", "TestFloat64.OmitEmpty", "OmitEmpty", "OmitEmpty", "max")
6245 func TestStructSliceValidation(t *testing.T) {
6249 tSuccess := &TestSlice{
6251 Len: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0},
6253 Max: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0},
6254 MinMax: []int{1, 2, 3, 4, 5},
6258 errs := validate.Struct(tSuccess)
6261 tFail := &TestSlice{
6263 Len: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1},
6265 Max: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1},
6267 OmitEmpty: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1},
6270 errs = validate.Struct(tFail)
6271 NotEqual(t, errs, nil)
6272 Equal(t, len(errs.(ValidationErrors)), 6)
6274 // Assert Field Errors
6275 AssertError(t, errs, "TestSlice.Required", "TestSlice.Required", "Required", "Required", "required")
6276 AssertError(t, errs, "TestSlice.Len", "TestSlice.Len", "Len", "Len", "len")
6277 AssertError(t, errs, "TestSlice.Min", "TestSlice.Min", "Min", "Min", "min")
6278 AssertError(t, errs, "TestSlice.Max", "TestSlice.Max", "Max", "Max", "max")
6279 AssertError(t, errs, "TestSlice.MinMax", "TestSlice.MinMax", "MinMax", "MinMax", "min")
6280 AssertError(t, errs, "TestSlice.OmitEmpty", "TestSlice.OmitEmpty", "OmitEmpty", "OmitEmpty", "max")
6282 fe := getError(errs, "TestSlice.Len", "TestSlice.Len")
6283 NotEqual(t, fe, nil)
6284 Equal(t, fe.Field(), "Len")
6285 Equal(t, fe.StructField(), "Len")
6286 Equal(t, fe.Namespace(), "TestSlice.Len")
6287 Equal(t, fe.StructNamespace(), "TestSlice.Len")
6288 Equal(t, fe.Tag(), "len")
6289 Equal(t, fe.ActualTag(), "len")
6290 Equal(t, fe.Param(), "10")
6291 Equal(t, fe.Kind(), reflect.Slice)
6292 Equal(t, fe.Type(), reflect.TypeOf([]int{}))
6294 _, ok := fe.Value().([]int)
6299 func TestInvalidStruct(t *testing.T) {
6307 err := validate.Struct(s.Test)
6308 NotEqual(t, err, nil)
6309 Equal(t, err.Error(), "validator: (nil string)")
6311 err = validate.Struct(nil)
6312 NotEqual(t, err, nil)
6313 Equal(t, err.Error(), "validator: (nil)")
6315 err = validate.StructPartial(nil, "SubTest.Test")
6316 NotEqual(t, err, nil)
6317 Equal(t, err.Error(), "validator: (nil)")
6319 err = validate.StructExcept(nil, "SubTest.Test")
6320 NotEqual(t, err, nil)
6321 Equal(t, err.Error(), "validator: (nil)")
6324 func TestInvalidValidatorFunction(t *testing.T) {
6332 PanicMatches(t, func() { validate.Var(s.Test, "zzxxBadFunction") }, "Undefined validation function 'zzxxBadFunction' on field ''")
6335 func TestCustomFieldName(t *testing.T) {
6338 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
6339 name := strings.SplitN(fld.Tag.Get("schema"), ",", 2)[0]
6349 B string `schema:"b" validate:"required"`
6350 C string `schema:"c" validate:"required"`
6351 D []bool `schema:"d" validate:"required"`
6352 E string `schema:"-" validate:"required"`
6357 err := validate.Struct(a)
6358 NotEqual(t, err, nil)
6360 errs := err.(ValidationErrors)
6361 Equal(t, len(errs), 4)
6362 Equal(t, getError(errs, "A.b", "A.B").Field(), "b")
6363 Equal(t, getError(errs, "A.c", "A.C").Field(), "c")
6364 Equal(t, getError(errs, "A.d", "A.D").Field(), "d")
6365 Equal(t, getError(errs, "A.E", "A.E").Field(), "E")
6369 NotEqual(t, err, nil)
6371 errs = err.(ValidationErrors)
6372 Equal(t, len(errs), 4)
6373 Equal(t, getError(errs, "A.B", "A.B").Field(), "B")
6374 Equal(t, getError(errs, "A.C", "A.C").Field(), "C")
6375 Equal(t, getError(errs, "A.D", "A.D").Field(), "D")
6376 Equal(t, getError(errs, "A.E", "A.E").Field(), "E")
6379 func TestMutipleRecursiveExtractStructCache(t *testing.T) {
6383 type Recursive struct {
6384 Field *string `validate:"required,len=5,ne=string"`
6389 current := reflect.ValueOf(test)
6391 proceed := make(chan struct{})
6393 sc := validate.extractStructCache(current, name)
6394 ptr := fmt.Sprintf("%p", sc)
6396 for i := 0; i < 100; i++ {
6400 sc := validate.extractStructCache(current, name)
6401 Equal(t, ptr, fmt.Sprintf("%p", sc))
6408 // Thanks @robbrockbank, see https://github.com/go-playground/validator/issues/249
6409 func TestPointerAndOmitEmpty(t *testing.T) {
6414 MyInt *int `validate:"omitempty,gte=2,lte=255"`
6420 t1 := Test{MyInt: &val1} // This should fail validation on gte because value is 0
6421 t2 := Test{MyInt: &val2} // This should fail validate on lte because value is 256
6422 t3 := Test{MyInt: nil} // This should succeed validation because pointer is nil
6424 errs := validate.Struct(t1)
6425 NotEqual(t, errs, nil)
6426 AssertError(t, errs, "Test.MyInt", "Test.MyInt", "MyInt", "MyInt", "gte")
6428 errs = validate.Struct(t2)
6429 NotEqual(t, errs, nil)
6430 AssertError(t, errs, "Test.MyInt", "Test.MyInt", "MyInt", "MyInt", "lte")
6432 errs = validate.Struct(t3)
6435 type TestIface struct {
6436 MyInt interface{} `validate:"omitempty,gte=2,lte=255"`
6439 ti1 := TestIface{MyInt: &val1} // This should fail validation on gte because value is 0
6440 ti2 := TestIface{MyInt: &val2} // This should fail validate on lte because value is 256
6441 ti3 := TestIface{MyInt: nil} // This should succeed validation because pointer is nil
6443 errs = validate.Struct(ti1)
6444 NotEqual(t, errs, nil)
6445 AssertError(t, errs, "TestIface.MyInt", "TestIface.MyInt", "MyInt", "MyInt", "gte")
6447 errs = validate.Struct(ti2)
6448 NotEqual(t, errs, nil)
6449 AssertError(t, errs, "TestIface.MyInt", "TestIface.MyInt", "MyInt", "MyInt", "lte")
6451 errs = validate.Struct(ti3)
6455 func TestRequired(t *testing.T) {
6458 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
6459 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
6469 Value interface{} `validate:"required"`
6474 err := validate.Struct(test)
6475 NotEqual(t, err, nil)
6476 AssertError(t, err.(ValidationErrors), "Test.Value", "Test.Value", "Value", "Value", "required")
6479 func TestTranslations(t *testing.T) {
6481 uni := ut.New(en, en, fr.New())
6483 trans, _ := uni.GetTranslator("en")
6484 fr, _ := uni.GetTranslator("fr")
6487 err := validate.RegisterTranslation("required", trans,
6488 func(ut ut.Translator) (err error) {
6490 // using this stype because multiple translation may have to be added for the full translation
6491 if err = ut.Add("required", "{0} is a required field", false); err != nil {
6497 }, func(ut ut.Translator, fe FieldError) string {
6499 t, err := ut.T(fe.Tag(), fe.Field())
6501 fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError))
6502 return fe.(*fieldError).Error()
6509 err = validate.RegisterTranslation("required", fr,
6510 func(ut ut.Translator) (err error) {
6512 // using this stype because multiple translation may have to be added for the full translation
6513 if err = ut.Add("required", "{0} est un champ obligatoire", false); err != nil {
6519 }, func(ut ut.Translator, fe FieldError) string {
6521 t, err := ut.T(fe.Tag(), fe.Field())
6523 fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError))
6524 return fe.(*fieldError).Error()
6533 Value interface{} `validate:"required"`
6538 err = validate.Struct(test)
6539 NotEqual(t, err, nil)
6541 errs := err.(ValidationErrors)
6542 Equal(t, len(errs), 1)
6545 Equal(t, fe.Tag(), "required")
6546 Equal(t, fe.Namespace(), "Test.Value")
6547 Equal(t, fe.Translate(trans), fmt.Sprintf("%s is a required field", fe.Field()))
6548 Equal(t, fe.Translate(fr), fmt.Sprintf("%s est un champ obligatoire", fe.Field()))
6551 uni2 := ut.New(nl, nl)
6552 trans2, _ := uni2.GetTranslator("nl")
6553 Equal(t, fe.Translate(trans2), "Key: 'Test.Value' Error:Field validation for 'Value' failed on the 'required' tag")
6555 terrs := errs.Translate(trans)
6556 Equal(t, len(terrs), 1)
6558 v, ok := terrs["Test.Value"]
6560 Equal(t, v, fmt.Sprintf("%s is a required field", fe.Field()))
6562 terrs = errs.Translate(fr)
6563 Equal(t, len(terrs), 1)
6565 v, ok = terrs["Test.Value"]
6567 Equal(t, v, fmt.Sprintf("%s est un champ obligatoire", fe.Field()))
6570 Value string `validate:"gt=1"`
6575 err = validate.Struct(t2)
6576 NotEqual(t, err, nil)
6578 errs = err.(ValidationErrors)
6579 Equal(t, len(errs), 1)
6582 Equal(t, fe.Tag(), "gt")
6583 Equal(t, fe.Namespace(), "Test2.Value")
6584 Equal(t, fe.Translate(trans), "Key: 'Test2.Value' Error:Field validation for 'Value' failed on the 'gt' tag")
6587 func TestTranslationErrors(t *testing.T) {
6590 uni := ut.New(en, en, fr.New())
6592 trans, _ := uni.GetTranslator("en")
6593 trans.Add("required", "{0} is a required field", false) // using translator outside of validator also
6596 err := validate.RegisterTranslation("required", trans,
6597 func(ut ut.Translator) (err error) {
6599 // using this stype because multiple translation may have to be added for the full translation
6600 if err = ut.Add("required", "{0} is a required field", false); err != nil {
6606 }, func(ut ut.Translator, fe FieldError) string {
6608 t, err := ut.T(fe.Tag(), fe.Field())
6610 fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError))
6611 return fe.(*fieldError).Error()
6617 NotEqual(t, err, nil)
6618 Equal(t, err.Error(), "error: conflicting key 'required' rule 'Unknown' with text '{0} is a required field' for locale 'en', value being ignored")
6621 func TestStructFiltered(t *testing.T) {
6623 p1 := func(ns []byte) bool {
6624 if bytes.HasSuffix(ns, []byte("NoTag")) || bytes.HasSuffix(ns, []byte("Required")) {
6631 p2 := func(ns []byte) bool {
6632 if bytes.HasSuffix(ns, []byte("SubSlice[0].Test")) ||
6633 bytes.HasSuffix(ns, []byte("SubSlice[0]")) ||
6634 bytes.HasSuffix(ns, []byte("SubSlice")) ||
6635 bytes.HasSuffix(ns, []byte("Sub")) ||
6636 bytes.HasSuffix(ns, []byte("SubIgnore")) ||
6637 bytes.HasSuffix(ns, []byte("Anonymous")) ||
6638 bytes.HasSuffix(ns, []byte("Anonymous.A")) {
6645 p3 := func(ns []byte) bool {
6646 return !bytes.HasSuffix(ns, []byte("SubTest.Test"))
6653 tPartial := &TestPartial{
6655 Required: "Required",
6657 SubSlice: []*SubTest{
6671 SubIgnore: &SubTest{
6675 A string `validate:"required"`
6676 ASubSlice []*SubTest `validate:"required,dive"`
6677 SubAnonStruct []struct {
6678 Test string `validate:"required"`
6679 OtherTest string `validate:"required"`
6680 } `validate:"required,dive"`
6683 ASubSlice: []*SubTest{
6692 SubAnonStruct: []struct {
6693 Test string `validate:"required"`
6694 OtherTest string `validate:"required"`
6696 {"Required", "RequiredOther"},
6697 {"Required", "RequiredOther"},
6704 // the following should all return no errors as everything is valid in
6705 // the default state
6706 errs := validate.StructFilteredCtx(context.Background(), tPartial, p1)
6709 errs = validate.StructFiltered(tPartial, p2)
6712 // this isn't really a robust test, but is ment to illustrate the ANON CASE below
6713 errs = validate.StructFiltered(tPartial.SubSlice[0], p3)
6716 // mod tParial for required feild and re-test making sure invalid fields are NOT required:
6717 tPartial.Required = ""
6719 // inversion and retesting Partial to generate failures:
6720 errs = validate.StructFiltered(tPartial, p1)
6721 NotEqual(t, errs, nil)
6722 AssertError(t, errs, "TestPartial.Required", "TestPartial.Required", "Required", "Required", "required")
6724 // reset Required field, and set nested struct
6725 tPartial.Required = "Required"
6726 tPartial.Anonymous.A = ""
6728 // will pass as unset feilds is not going to be tested
6729 errs = validate.StructFiltered(tPartial, p1)
6732 // will fail as unset feild is tested
6733 errs = validate.StructFiltered(tPartial, p2)
6734 NotEqual(t, errs, nil)
6735 AssertError(t, errs, "TestPartial.Anonymous.A", "TestPartial.Anonymous.A", "A", "A", "required")
6737 // reset nested struct and unset struct in slice
6738 tPartial.Anonymous.A = "Required"
6739 tPartial.SubSlice[0].Test = ""
6741 // these will pass as unset item is NOT tested
6742 errs = validate.StructFiltered(tPartial, p1)
6745 errs = validate.StructFiltered(tPartial, p2)
6746 NotEqual(t, errs, nil)
6747 AssertError(t, errs, "TestPartial.SubSlice[0].Test", "TestPartial.SubSlice[0].Test", "Test", "Test", "required")
6748 Equal(t, len(errs.(ValidationErrors)), 1)
6750 // Unset second slice member concurrently to test dive behavior:
6751 tPartial.SubSlice[1].Test = ""
6753 errs = validate.StructFiltered(tPartial, p1)
6756 errs = validate.StructFiltered(tPartial, p2)
6757 NotEqual(t, errs, nil)
6758 Equal(t, len(errs.(ValidationErrors)), 1)
6759 AssertError(t, errs, "TestPartial.SubSlice[0].Test", "TestPartial.SubSlice[0].Test", "Test", "Test", "required")
6761 // reset struct in slice, and unset struct in slice in unset posistion
6762 tPartial.SubSlice[0].Test = "Required"
6764 // these will pass as the unset item is NOT tested
6765 errs = validate.StructFiltered(tPartial, p1)
6768 errs = validate.StructFiltered(tPartial, p2)
6771 tPartial.SubSlice[1].Test = "Required"
6772 tPartial.Anonymous.SubAnonStruct[0].Test = ""
6774 // these will pass as the unset item is NOT tested
6775 errs = validate.StructFiltered(tPartial, p1)
6778 errs = validate.StructFiltered(tPartial, p2)
6782 err := validate.StructFiltered(&dt, func(ns []byte) bool { return true })
6783 NotEqual(t, err, nil)
6784 Equal(t, err.Error(), "validator: (nil *time.Time)")
6787 func TestRequiredPtr(t *testing.T) {
6790 Bool *bool `validate:"required"`
6801 err := validate.Struct(test)
6808 err = validate.Struct(test)
6813 err = validate.Struct(test)
6814 NotEqual(t, err, nil)
6816 errs, ok := err.(ValidationErrors)
6818 Equal(t, len(errs), 1)
6819 AssertError(t, errs, "Test.Bool", "Test.Bool", "Bool", "Bool", "required")
6822 Bool bool `validate:"required"`
6827 err = validate.Struct(test2)
6828 NotEqual(t, err, nil)
6830 errs, ok = err.(ValidationErrors)
6832 Equal(t, len(errs), 1)
6833 AssertError(t, errs, "Test2.Bool", "Test2.Bool", "Bool", "Bool", "required")
6837 err = validate.Struct(test2)
6841 Arr []string `validate:"required"`
6846 err = validate.Struct(test3)
6847 NotEqual(t, err, nil)
6849 errs, ok = err.(ValidationErrors)
6851 Equal(t, len(errs), 1)
6852 AssertError(t, errs, "Test3.Arr", "Test3.Arr", "Arr", "Arr", "required")
6854 test3.Arr = make([]string, 0)
6856 err = validate.Struct(test3)
6860 Arr *[]string `validate:"required"` // I know I know pointer to array, just making sure validation works as expected...
6865 err = validate.Struct(test4)
6866 NotEqual(t, err, nil)
6868 errs, ok = err.(ValidationErrors)
6870 Equal(t, len(errs), 1)
6871 AssertError(t, errs, "Test4.Arr", "Test4.Arr", "Arr", "Arr", "required")
6873 arr := make([]string, 0)
6876 err = validate.Struct(test4)
6880 func TestAlphaUnicodeValidation(t *testing.T) {
6887 {"this is a test string", false},
6888 {"这是一个测试字符串", true},
6891 {"ひらがな・カタカナ、.漢字", false},
6892 {"あいうえおfoobar", true},
6893 {"test@example.com", false},
6894 {"1234abcDE", false},
6900 for i, test := range tests {
6902 errs := validate.Var(test.param, "alphaunicode")
6905 if !IsEqual(errs, nil) {
6906 t.Fatalf("Index: %d Alpha Unicode failed Error: %s", i, errs)
6909 if IsEqual(errs, nil) {
6910 t.Fatalf("Index: %d Alpha Unicode failed Error: %s", i, errs)
6912 val := getError(errs, "", "")
6913 if val.Tag() != "alphaunicode" {
6914 t.Fatalf("Index: %d Alpha Unicode failed Error: %s", i, errs)
6921 func TestAlphanumericUnicodeValidation(t *testing.T) {
6929 {"this is a test string", false},
6930 {"这是一个测试字符串", true},
6931 {"\u0031\u0032\u0033", true}, // unicode 5
6934 {"ひらがな・カタカナ、.漢字", false},
6935 {"あいうえおfoobar", true},
6936 {"test@example.com", false},
6937 {"1234abcDE", true},
6943 for i, test := range tests {
6945 errs := validate.Var(test.param, "alphanumunicode")
6948 if !IsEqual(errs, nil) {
6949 t.Fatalf("Index: %d Alphanum Unicode failed Error: %s", i, errs)
6952 if IsEqual(errs, nil) {
6953 t.Fatalf("Index: %d Alphanum Unicode failed Error: %s", i, errs)
6955 val := getError(errs, "", "")
6956 if val.Tag() != "alphanumunicode" {
6957 t.Fatalf("Index: %d Alphanum Unicode failed Error: %s", i, errs)
6964 func TestArrayStructNamespace(t *testing.T) {
6967 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
6968 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
6978 Name string `json:"name" validate:"required"`
6981 Children []child `json:"children" validate:"required,gt=0,dive"`
6983 input.Children = []child{{"ok"}, {""}}
6985 errs := validate.Struct(input)
6986 NotEqual(t, errs, nil)
6988 ve := errs.(ValidationErrors)
6989 Equal(t, len(ve), 1)
6990 AssertError(t, errs, "children[1].name", "Children[1].Name", "name", "Name", "required")
6993 func TestMapStructNamespace(t *testing.T) {
6996 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
6997 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
7007 Name string `json:"name" validate:"required"`
7010 Children map[int]child `json:"children" validate:"required,gt=0,dive"`
7012 input.Children = map[int]child{
7017 errs := validate.Struct(input)
7018 NotEqual(t, errs, nil)
7020 ve := errs.(ValidationErrors)
7021 Equal(t, len(ve), 1)
7022 AssertError(t, errs, "children[1].name", "Children[1].Name", "name", "Name", "required")
7025 func TestFieldLevelName(t *testing.T) {
7027 String string `validate:"custom1" json:"json1"`
7028 Array []string `validate:"dive,custom2" json:"json2"`
7029 Map map[string]string `validate:"dive,custom3" json:"json3"`
7030 Array2 []string `validate:"custom4" json:"json4"`
7031 Map2 map[string]string `validate:"custom5" json:"json5"`
7034 var res1, res2, res3, res4, res5, alt1, alt2, alt3, alt4, alt5 string
7036 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
7037 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
7045 validate.RegisterValidation("custom1", func(fl FieldLevel) bool {
7046 res1 = fl.FieldName()
7047 alt1 = fl.StructFieldName()
7050 validate.RegisterValidation("custom2", func(fl FieldLevel) bool {
7051 res2 = fl.FieldName()
7052 alt2 = fl.StructFieldName()
7055 validate.RegisterValidation("custom3", func(fl FieldLevel) bool {
7056 res3 = fl.FieldName()
7057 alt3 = fl.StructFieldName()
7060 validate.RegisterValidation("custom4", func(fl FieldLevel) bool {
7061 res4 = fl.FieldName()
7062 alt4 = fl.StructFieldName()
7065 validate.RegisterValidation("custom5", func(fl FieldLevel) bool {
7066 res5 = fl.FieldName()
7067 alt5 = fl.StructFieldName()
7073 Array: []string{"1"},
7074 Map: map[string]string{"test": "test"},
7077 errs := validate.Struct(test)
7079 Equal(t, res1, "json1")
7080 Equal(t, alt1, "String")
7081 Equal(t, res2, "json2[0]")
7082 Equal(t, alt2, "Array[0]")
7083 Equal(t, res3, "json3[test]")
7084 Equal(t, alt3, "Map[test]")
7085 Equal(t, res4, "json4")
7086 Equal(t, alt4, "Array2")
7087 Equal(t, res5, "json5")
7088 Equal(t, alt5, "Map2")
7091 func TestValidateStructRegisterCtx(t *testing.T) {
7095 fnCtx := func(ctx context.Context, fl FieldLevel) bool {
7096 ctxVal = ctx.Value(&ctxVal).(string)
7101 slFn := func(ctx context.Context, sl StructLevel) {
7102 ctxSlVal = ctx.Value(&ctxSlVal).(string)
7106 Field string `validate:"val"`
7112 validate.RegisterValidationCtx("val", fnCtx)
7113 validate.RegisterStructValidationCtx(slFn, Test{})
7115 ctx := context.WithValue(context.Background(), &ctxVal, "testval")
7116 ctx = context.WithValue(ctx, &ctxSlVal, "slVal")
7117 errs := validate.StructCtx(ctx, tst)
7119 Equal(t, ctxVal, "testval")
7120 Equal(t, ctxSlVal, "slVal")
7123 func TestHostnameValidation(t *testing.T) {
7128 {"test.example.com", true},
7129 {"example.com", true},
7130 {"example24.com", true},
7131 {"test.example24.com", true},
7132 {"test24.example24.com", true},
7134 {"test.example.com.", false},
7135 {"example.com.", false},
7136 {"example24.com.", false},
7137 {"test.example24.com.", false},
7138 {"test24.example24.com.", false},
7139 {"example.", false},
7140 {"192.168.0.1", false},
7141 {"email@example.com", false},
7142 {"2001:cdba:0000:0000:0000:0000:3257:9652", false},
7143 {"2001:cdba:0:0:0:0:3257:9652", false},
7144 {"2001:cdba::3257:9652", false},
7149 for i, test := range tests {
7151 errs := validate.Var(test.param, "hostname")
7154 if !IsEqual(errs, nil) {
7155 t.Fatalf("Index: %d hostname failed Error: %s", i, errs)
7158 if IsEqual(errs, nil) {
7159 t.Fatalf("Index: %d hostname failed Error: %s", i, errs)
7161 val := getError(errs, "", "")
7162 if val.Tag() != "hostname" {
7163 t.Fatalf("Index: %d hostname failed Error: %s", i, errs)
7170 func TestFQDNValidation(t *testing.T) {
7175 {"test.example.com", true},
7176 {"example.com", true},
7177 {"example24.com", true},
7178 {"test.example24.com", true},
7179 {"test24.example24.com", true},
7180 {"test.example.com.", true},
7181 {"example.com.", true},
7182 {"example24.com.", true},
7183 {"test.example24.com.", true},
7184 {"test24.example24.com.", true},
7185 {"test24.example24.com..", false},
7187 {"192.168.0.1", false},
7188 {"email@example.com", false},
7189 {"2001:cdba:0000:0000:0000:0000:3257:9652", false},
7190 {"2001:cdba:0:0:0:0:3257:9652", false},
7191 {"2001:cdba::3257:9652", false},
7197 for i, test := range tests {
7199 errs := validate.Var(test.param, "fqdn")
7202 if !IsEqual(errs, nil) {
7203 t.Fatalf("Index: %d fqdn failed Error: %s", i, errs)
7206 if IsEqual(errs, nil) {
7207 t.Fatalf("Index: %d fqdn failed Error: %s", i, errs)
7209 val := getError(errs, "", "")
7210 if val.Tag() != "fqdn" {
7211 t.Fatalf("Index: %d fqdn failed Error: %s", i, errs)
7218 func TestIsDefault(t *testing.T) {
7223 String string `validate:"isdefault"`
7226 String string `validate:"isdefault"`
7227 Inner *Inner `validate:"isdefault"`
7232 errs := validate.Struct(tt)
7235 tt.Inner = &Inner{String: ""}
7236 errs = validate.Struct(tt)
7237 NotEqual(t, errs, nil)
7239 fe := errs.(ValidationErrors)[0]
7240 Equal(t, fe.Field(), "Inner")
7241 Equal(t, fe.Namespace(), "Test.Inner")
7242 Equal(t, fe.Tag(), "isdefault")
7244 validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
7245 name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
7254 type Inner2 struct {
7255 String string `validate:"isdefault"`
7259 Inner Inner2 `validate:"isdefault" json:"inner"`
7263 errs = validate.Struct(t2)
7266 t2.Inner.String = "Changed"
7267 errs = validate.Struct(t2)
7268 NotEqual(t, errs, nil)
7270 fe = errs.(ValidationErrors)[0]
7271 Equal(t, fe.Field(), "inner")
7272 Equal(t, fe.Namespace(), "Test2.inner")
7273 Equal(t, fe.Tag(), "isdefault")
7276 func TestUniqueValidation(t *testing.T) {
7281 {[]string{"a", "b"}, true},
7282 {[]int{1, 2}, true},
7283 {[]float64{1, 2}, true},
7284 {[]interface{}{"a", "b"}, true},
7285 {[]interface{}{"a", 1}, true},
7286 {[]float64{1, 1}, false},
7287 {[]int{1, 1}, false},
7288 {[]string{"a", "a"}, false},
7289 {[]interface{}{"a", "a"}, false},
7290 {[]interface{}{"a", 1, "b", 1}, false},
7295 for i, test := range tests {
7297 errs := validate.Var(test.param, "unique")
7300 if !IsEqual(errs, nil) {
7301 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
7304 if IsEqual(errs, nil) {
7305 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
7307 val := getError(errs, "", "")
7308 if val.Tag() != "unique" {
7309 t.Fatalf("Index: %d unique failed Error: %v", i, errs)
7314 PanicMatches(t, func() { validate.Var(1.0, "unique") }, "Bad field type float64")