...

Source file src/github.com/go-playground/validator/v10/validator_test.go

Documentation: github.com/go-playground/validator/v10

     1  package validator
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"database/sql"
     7  	"database/sql/driver"
     8  	"encoding/base64"
     9  	"encoding/json"
    10  	"fmt"
    11  	"image"
    12  	"image/jpeg"
    13  	"image/png"
    14  	"os"
    15  	"path/filepath"
    16  	"reflect"
    17  	"strings"
    18  	"testing"
    19  	"time"
    20  
    21  	. "github.com/go-playground/assert/v2"
    22  	"github.com/go-playground/locales/en"
    23  	"github.com/go-playground/locales/fr"
    24  	"github.com/go-playground/locales/nl"
    25  	ut "github.com/go-playground/universal-translator"
    26  )
    27  
    28  // NOTES:
    29  // - Run "go test" to run tests
    30  // - Run "gocov test | gocov report" to report on test converage by file
    31  // - Run "gocov test | gocov annotate -" to report on all code and functions, those ,marked with "MISS" were never called
    32  //
    33  // or
    34  //
    35  // -- may be a good idea to change to output path to somewherelike /tmp
    36  // go test -coverprofile cover.out && go tool cover -html=cover.out -o cover.html
    37  //
    38  //
    39  // go test -cpuprofile cpu.out
    40  // ./validator.test -test.bench=. -test.cpuprofile=cpu.prof
    41  // go tool pprof validator.test cpu.prof
    42  //
    43  //
    44  // go test -memprofile mem.out
    45  
    46  type I interface {
    47  	Foo() string
    48  }
    49  
    50  type Impl struct {
    51  	F string `validate:"len=3"`
    52  }
    53  
    54  func (i *Impl) Foo() string {
    55  	return i.F
    56  }
    57  
    58  type SubTest struct {
    59  	Test string `validate:"required"`
    60  }
    61  
    62  type TestInterface struct {
    63  	Iface I
    64  }
    65  
    66  type TestString struct {
    67  	BlankTag  string `validate:""`
    68  	Required  string `validate:"required"`
    69  	Len       string `validate:"len=10"`
    70  	Min       string `validate:"min=1"`
    71  	Max       string `validate:"max=10"`
    72  	MinMax    string `validate:"min=1,max=10"`
    73  	Lt        string `validate:"lt=10"`
    74  	Lte       string `validate:"lte=10"`
    75  	Gt        string `validate:"gt=10"`
    76  	Gte       string `validate:"gte=10"`
    77  	OmitEmpty string `validate:"omitempty,min=1,max=10"`
    78  	Boolean   string `validate:"boolean"`
    79  	Sub       *SubTest
    80  	SubIgnore *SubTest `validate:"-"`
    81  	Anonymous struct {
    82  		A string `validate:"required"`
    83  	}
    84  	Iface I
    85  }
    86  
    87  type TestUint64 struct {
    88  	Required  uint64 `validate:"required"`
    89  	Len       uint64 `validate:"len=10"`
    90  	Min       uint64 `validate:"min=1"`
    91  	Max       uint64 `validate:"max=10"`
    92  	MinMax    uint64 `validate:"min=1,max=10"`
    93  	OmitEmpty uint64 `validate:"omitempty,min=1,max=10"`
    94  }
    95  
    96  type TestFloat64 struct {
    97  	Required  float64 `validate:"required"`
    98  	Len       float64 `validate:"len=10"`
    99  	Min       float64 `validate:"min=1"`
   100  	Max       float64 `validate:"max=10"`
   101  	MinMax    float64 `validate:"min=1,max=10"`
   102  	Lte       float64 `validate:"lte=10"`
   103  	OmitEmpty float64 `validate:"omitempty,min=1,max=10"`
   104  }
   105  
   106  type TestSlice struct {
   107  	Required  []int `validate:"required"`
   108  	Len       []int `validate:"len=10"`
   109  	Min       []int `validate:"min=1"`
   110  	Max       []int `validate:"max=10"`
   111  	MinMax    []int `validate:"min=1,max=10"`
   112  	OmitEmpty []int `validate:"omitempty,min=1,max=10"`
   113  }
   114  
   115  func AssertError(t *testing.T, err error, nsKey, structNsKey, field, structField, expectedTag string) {
   116  	errs := err.(ValidationErrors)
   117  
   118  	found := false
   119  	var fe FieldError
   120  
   121  	for i := 0; i < len(errs); i++ {
   122  		if errs[i].Namespace() == nsKey && errs[i].StructNamespace() == structNsKey {
   123  			found = true
   124  			fe = errs[i]
   125  			break
   126  		}
   127  	}
   128  
   129  	EqualSkip(t, 2, found, true)
   130  	NotEqualSkip(t, 2, fe, nil)
   131  	EqualSkip(t, 2, fe.Field(), field)
   132  	EqualSkip(t, 2, fe.StructField(), structField)
   133  	EqualSkip(t, 2, fe.Tag(), expectedTag)
   134  }
   135  
   136  func AssertDeepError(t *testing.T, err error, nsKey, structNsKey, field, structField, expectedTag, actualTag string) {
   137  	errs := err.(ValidationErrors)
   138  
   139  	found := false
   140  	var fe FieldError
   141  
   142  	for i := 0; i < len(errs); i++ {
   143  		if errs[i].Namespace() == nsKey && errs[i].StructNamespace() == structNsKey && errs[i].Tag() == expectedTag && errs[i].ActualTag() == actualTag {
   144  			found = true
   145  			fe = errs[i]
   146  			break
   147  		}
   148  	}
   149  
   150  	EqualSkip(t, 2, found, true)
   151  	NotEqualSkip(t, 2, fe, nil)
   152  	EqualSkip(t, 2, fe.Field(), field)
   153  	EqualSkip(t, 2, fe.StructField(), structField)
   154  }
   155  
   156  func getError(err error, nsKey, structNsKey string) FieldError {
   157  	errs := err.(ValidationErrors)
   158  
   159  	var fe FieldError
   160  
   161  	for i := 0; i < len(errs); i++ {
   162  		if errs[i].Namespace() == nsKey && errs[i].StructNamespace() == structNsKey {
   163  			fe = errs[i]
   164  			break
   165  		}
   166  	}
   167  
   168  	return fe
   169  }
   170  
   171  type valuer struct {
   172  	Name string
   173  }
   174  
   175  func (v valuer) Value() (driver.Value, error) {
   176  	if v.Name == "errorme" {
   177  		panic("SQL Driver Valuer error: some kind of error")
   178  		// return nil, errors.New("some kind of error")
   179  	}
   180  
   181  	if len(v.Name) == 0 {
   182  		return nil, nil
   183  	}
   184  
   185  	return v.Name, nil
   186  }
   187  
   188  type MadeUpCustomType struct {
   189  	FirstName string
   190  	LastName  string
   191  }
   192  
   193  func ValidateCustomType(field reflect.Value) interface{} {
   194  	if cust, ok := field.Interface().(MadeUpCustomType); ok {
   195  
   196  		if len(cust.FirstName) == 0 || len(cust.LastName) == 0 {
   197  			return ""
   198  		}
   199  
   200  		return cust.FirstName + " " + cust.LastName
   201  	}
   202  
   203  	return ""
   204  }
   205  
   206  func OverrideIntTypeForSomeReason(field reflect.Value) interface{} {
   207  	if i, ok := field.Interface().(int); ok {
   208  		if i == 1 {
   209  			return "1"
   210  		}
   211  
   212  		if i == 2 {
   213  			return "12"
   214  		}
   215  	}
   216  
   217  	return ""
   218  }
   219  
   220  type CustomMadeUpStruct struct {
   221  	MadeUp        MadeUpCustomType `validate:"required"`
   222  	OverriddenInt int              `validate:"gt=1"`
   223  }
   224  
   225  func ValidateValuerType(field reflect.Value) interface{} {
   226  	if valuer, ok := field.Interface().(driver.Valuer); ok {
   227  
   228  		val, err := valuer.Value()
   229  		if err != nil {
   230  			// handle the error how you want
   231  			return nil
   232  		}
   233  
   234  		return val
   235  	}
   236  
   237  	return nil
   238  }
   239  
   240  type TestPartial struct {
   241  	NoTag     string
   242  	BlankTag  string     `validate:""`
   243  	Required  string     `validate:"required"`
   244  	SubSlice  []*SubTest `validate:"required,dive"`
   245  	Sub       *SubTest
   246  	SubIgnore *SubTest `validate:"-"`
   247  	Anonymous struct {
   248  		A         string     `validate:"required"`
   249  		ASubSlice []*SubTest `validate:"required,dive"`
   250  
   251  		SubAnonStruct []struct {
   252  			Test      string `validate:"required"`
   253  			OtherTest string `validate:"required"`
   254  		} `validate:"required,dive"`
   255  	}
   256  }
   257  
   258  type TestStruct struct {
   259  	String string `validate:"required" json:"StringVal"`
   260  }
   261  
   262  func StructValidationTestStructSuccess(sl StructLevel) {
   263  	st := sl.Current().Interface().(TestStruct)
   264  
   265  	if st.String != "good value" {
   266  		sl.ReportError(st.String, "StringVal", "String", "badvalueteststruct", "good value")
   267  	}
   268  }
   269  
   270  func StructValidationTestStruct(sl StructLevel) {
   271  	st := sl.Current().Interface().(TestStruct)
   272  
   273  	if st.String != "bad value" {
   274  		sl.ReportError(st.String, "StringVal", "String", "badvalueteststruct", "bad value")
   275  	}
   276  }
   277  
   278  func StructValidationNoTestStructCustomName(sl StructLevel) {
   279  	st := sl.Current().Interface().(TestStruct)
   280  
   281  	if st.String != "bad value" {
   282  		sl.ReportError(st.String, "String", "", "badvalueteststruct", "bad value")
   283  	}
   284  }
   285  
   286  func StructValidationTestStructInvalid(sl StructLevel) {
   287  	st := sl.Current().Interface().(TestStruct)
   288  
   289  	if st.String != "bad value" {
   290  		sl.ReportError(nil, "StringVal", "String", "badvalueteststruct", "bad value")
   291  	}
   292  }
   293  
   294  func StructValidationTestStructReturnValidationErrors(sl StructLevel) {
   295  	s := sl.Current().Interface().(TestStructReturnValidationErrors)
   296  
   297  	errs := sl.Validator().Struct(s.Inner1.Inner2)
   298  	if errs == nil {
   299  		return
   300  	}
   301  
   302  	sl.ReportValidationErrors("Inner1.", "Inner1.", errs.(ValidationErrors))
   303  }
   304  
   305  func StructValidationTestStructReturnValidationErrors2(sl StructLevel) {
   306  	s := sl.Current().Interface().(TestStructReturnValidationErrors)
   307  
   308  	errs := sl.Validator().Struct(s.Inner1.Inner2)
   309  	if errs == nil {
   310  		return
   311  	}
   312  
   313  	sl.ReportValidationErrors("Inner1JSON.", "Inner1.", errs.(ValidationErrors))
   314  }
   315  
   316  type TestStructReturnValidationErrorsInner2 struct {
   317  	String string `validate:"required" json:"JSONString"`
   318  }
   319  
   320  type TestStructReturnValidationErrorsInner1 struct {
   321  	Inner2 *TestStructReturnValidationErrorsInner2
   322  }
   323  
   324  type TestStructReturnValidationErrors struct {
   325  	Inner1 *TestStructReturnValidationErrorsInner1 `json:"Inner1JSON"`
   326  }
   327  
   328  type StructLevelInvalidErr struct {
   329  	Value string
   330  }
   331  
   332  func StructLevelInvalidError(sl StructLevel) {
   333  	top := sl.Top().Interface().(StructLevelInvalidErr)
   334  	s := sl.Current().Interface().(StructLevelInvalidErr)
   335  
   336  	if top.Value == s.Value {
   337  		sl.ReportError(nil, "Value", "Value", "required", "")
   338  	}
   339  }
   340  
   341  func stringPtr(v string) *string {
   342  	return &v
   343  }
   344  
   345  func intPtr(v int) *int {
   346  	return &v
   347  }
   348  
   349  func float64Ptr(v float64) *float64 {
   350  	return &v
   351  }
   352  
   353  func TestStructLevelInvalidError(t *testing.T) {
   354  	validate := New()
   355  	validate.RegisterStructValidation(StructLevelInvalidError, StructLevelInvalidErr{})
   356  
   357  	var test StructLevelInvalidErr
   358  
   359  	err := validate.Struct(test)
   360  	NotEqual(t, err, nil)
   361  
   362  	errs, ok := err.(ValidationErrors)
   363  	Equal(t, ok, true)
   364  
   365  	fe := errs[0]
   366  	Equal(t, fe.Field(), "Value")
   367  	Equal(t, fe.StructField(), "Value")
   368  	Equal(t, fe.Namespace(), "StructLevelInvalidErr.Value")
   369  	Equal(t, fe.StructNamespace(), "StructLevelInvalidErr.Value")
   370  	Equal(t, fe.Tag(), "required")
   371  	Equal(t, fe.ActualTag(), "required")
   372  	Equal(t, fe.Kind(), reflect.Invalid)
   373  	Equal(t, fe.Type(), reflect.TypeOf(nil))
   374  }
   375  
   376  func TestNameNamespace(t *testing.T) {
   377  	type Inner2Namespace struct {
   378  		String []string `validate:"dive,required" json:"JSONString"`
   379  	}
   380  
   381  	type Inner1Namespace struct {
   382  		Inner2 *Inner2Namespace `json:"Inner2JSON"`
   383  	}
   384  
   385  	type Namespace struct {
   386  		Inner1 *Inner1Namespace `json:"Inner1JSON"`
   387  	}
   388  
   389  	validate := New()
   390  	validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
   391  		name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
   392  
   393  		if name == "-" {
   394  			return ""
   395  		}
   396  
   397  		return name
   398  	})
   399  
   400  	i2 := &Inner2Namespace{String: []string{"ok", "ok", "ok"}}
   401  	i1 := &Inner1Namespace{Inner2: i2}
   402  	ns := &Namespace{Inner1: i1}
   403  
   404  	errs := validate.Struct(ns)
   405  	Equal(t, errs, nil)
   406  
   407  	i2.String[1] = ""
   408  
   409  	errs = validate.Struct(ns)
   410  	NotEqual(t, errs, nil)
   411  
   412  	ve := errs.(ValidationErrors)
   413  	Equal(t, len(ve), 1)
   414  	AssertError(t, errs, "Namespace.Inner1JSON.Inner2JSON.JSONString[1]", "Namespace.Inner1.Inner2.String[1]", "JSONString[1]", "String[1]", "required")
   415  
   416  	fe := getError(ve, "Namespace.Inner1JSON.Inner2JSON.JSONString[1]", "Namespace.Inner1.Inner2.String[1]")
   417  	NotEqual(t, fe, nil)
   418  	Equal(t, fe.Field(), "JSONString[1]")
   419  	Equal(t, fe.StructField(), "String[1]")
   420  	Equal(t, fe.Namespace(), "Namespace.Inner1JSON.Inner2JSON.JSONString[1]")
   421  	Equal(t, fe.StructNamespace(), "Namespace.Inner1.Inner2.String[1]")
   422  }
   423  
   424  func TestAnonymous(t *testing.T) {
   425  	validate := New()
   426  	validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
   427  		name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
   428  
   429  		if name == "-" {
   430  			return ""
   431  		}
   432  
   433  		return name
   434  	})
   435  
   436  	type Test struct {
   437  		Anonymous struct {
   438  			A string `validate:"required" json:"EH"`
   439  		}
   440  		AnonymousB struct {
   441  			B string `validate:"required" json:"BEE"`
   442  		}
   443  		anonymousC struct {
   444  			c string `validate:"required"`
   445  		}
   446  	}
   447  
   448  	tst := &Test{
   449  		Anonymous: struct {
   450  			A string `validate:"required" json:"EH"`
   451  		}{
   452  			A: "1",
   453  		},
   454  		AnonymousB: struct {
   455  			B string `validate:"required" json:"BEE"`
   456  		}{
   457  			B: "",
   458  		},
   459  		anonymousC: struct {
   460  			c string `validate:"required"`
   461  		}{
   462  			c: "",
   463  		},
   464  	}
   465  
   466  	Equal(t, tst.anonymousC.c, "")
   467  
   468  	err := validate.Struct(tst)
   469  	NotEqual(t, err, nil)
   470  
   471  	errs := err.(ValidationErrors)
   472  
   473  	Equal(t, len(errs), 1)
   474  	AssertError(t, errs, "Test.AnonymousB.BEE", "Test.AnonymousB.B", "BEE", "B", "required")
   475  
   476  	fe := getError(errs, "Test.AnonymousB.BEE", "Test.AnonymousB.B")
   477  	NotEqual(t, fe, nil)
   478  	Equal(t, fe.Field(), "BEE")
   479  	Equal(t, fe.StructField(), "B")
   480  
   481  	s := struct {
   482  		c string `validate:"required"`
   483  	}{
   484  		c: "",
   485  	}
   486  
   487  	err = validate.Struct(s)
   488  	Equal(t, err, nil)
   489  }
   490  
   491  func TestAnonymousSameStructDifferentTags(t *testing.T) {
   492  	validate := New()
   493  	validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
   494  		name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
   495  
   496  		if name == "-" {
   497  			return ""
   498  		}
   499  
   500  		return name
   501  	})
   502  
   503  	type Test struct {
   504  		A interface{}
   505  	}
   506  
   507  	tst := &Test{
   508  		A: struct {
   509  			A string `validate:"required"`
   510  		}{
   511  			A: "",
   512  		},
   513  	}
   514  
   515  	err := validate.Struct(tst)
   516  	NotEqual(t, err, nil)
   517  
   518  	errs := err.(ValidationErrors)
   519  
   520  	Equal(t, len(errs), 1)
   521  	AssertError(t, errs, "Test.A.A", "Test.A.A", "A", "A", "required")
   522  
   523  	tst = &Test{
   524  		A: struct {
   525  			A string `validate:"omitempty,required"`
   526  		}{
   527  			A: "",
   528  		},
   529  	}
   530  
   531  	err = validate.Struct(tst)
   532  	Equal(t, err, nil)
   533  }
   534  
   535  func TestStructLevelReturnValidationErrors(t *testing.T) {
   536  	validate := New()
   537  	validate.RegisterStructValidation(StructValidationTestStructReturnValidationErrors, TestStructReturnValidationErrors{})
   538  
   539  	inner2 := &TestStructReturnValidationErrorsInner2{
   540  		String: "I'm HERE",
   541  	}
   542  
   543  	inner1 := &TestStructReturnValidationErrorsInner1{
   544  		Inner2: inner2,
   545  	}
   546  
   547  	val := &TestStructReturnValidationErrors{
   548  		Inner1: inner1,
   549  	}
   550  
   551  	errs := validate.Struct(val)
   552  	Equal(t, errs, nil)
   553  
   554  	inner2.String = ""
   555  
   556  	errs = validate.Struct(val)
   557  	NotEqual(t, errs, nil)
   558  	Equal(t, len(errs.(ValidationErrors)), 2)
   559  	AssertError(t, errs, "TestStructReturnValidationErrors.Inner1.Inner2.String", "TestStructReturnValidationErrors.Inner1.Inner2.String", "String", "String", "required")
   560  	// this is an extra error reported from struct validation
   561  	AssertError(t, errs, "TestStructReturnValidationErrors.Inner1.TestStructReturnValidationErrorsInner2.String", "TestStructReturnValidationErrors.Inner1.TestStructReturnValidationErrorsInner2.String", "String", "String", "required")
   562  }
   563  
   564  func TestStructLevelReturnValidationErrorsWithJSON(t *testing.T) {
   565  	validate := New()
   566  	validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
   567  		name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
   568  
   569  		if name == "-" {
   570  			return ""
   571  		}
   572  
   573  		return name
   574  	})
   575  	validate.RegisterStructValidation(StructValidationTestStructReturnValidationErrors2, TestStructReturnValidationErrors{})
   576  
   577  	inner2 := &TestStructReturnValidationErrorsInner2{
   578  		String: "I'm HERE",
   579  	}
   580  
   581  	inner1 := &TestStructReturnValidationErrorsInner1{
   582  		Inner2: inner2,
   583  	}
   584  
   585  	val := &TestStructReturnValidationErrors{
   586  		Inner1: inner1,
   587  	}
   588  
   589  	errs := validate.Struct(val)
   590  	Equal(t, errs, nil)
   591  
   592  	inner2.String = ""
   593  
   594  	errs = validate.Struct(val)
   595  	NotEqual(t, errs, nil)
   596  	Equal(t, len(errs.(ValidationErrors)), 2)
   597  	AssertError(t, errs, "TestStructReturnValidationErrors.Inner1JSON.Inner2.JSONString", "TestStructReturnValidationErrors.Inner1.Inner2.String", "JSONString", "String", "required")
   598  	// this is an extra error reported from struct validation, it's a badly formatted one, but on purpose
   599  	AssertError(t, errs, "TestStructReturnValidationErrors.Inner1JSON.TestStructReturnValidationErrorsInner2.JSONString", "TestStructReturnValidationErrors.Inner1.TestStructReturnValidationErrorsInner2.String", "JSONString", "String", "required")
   600  
   601  	fe := getError(errs, "TestStructReturnValidationErrors.Inner1JSON.Inner2.JSONString", "TestStructReturnValidationErrors.Inner1.Inner2.String")
   602  	NotEqual(t, fe, nil)
   603  
   604  	// check for proper JSON namespace
   605  	Equal(t, fe.Field(), "JSONString")
   606  	Equal(t, fe.StructField(), "String")
   607  	Equal(t, fe.Namespace(), "TestStructReturnValidationErrors.Inner1JSON.Inner2.JSONString")
   608  	Equal(t, fe.StructNamespace(), "TestStructReturnValidationErrors.Inner1.Inner2.String")
   609  
   610  	fe = getError(errs, "TestStructReturnValidationErrors.Inner1JSON.TestStructReturnValidationErrorsInner2.JSONString", "TestStructReturnValidationErrors.Inner1.TestStructReturnValidationErrorsInner2.String")
   611  	NotEqual(t, fe, nil)
   612  
   613  	// check for proper JSON namespace
   614  	Equal(t, fe.Field(), "JSONString")
   615  	Equal(t, fe.StructField(), "String")
   616  	Equal(t, fe.Namespace(), "TestStructReturnValidationErrors.Inner1JSON.TestStructReturnValidationErrorsInner2.JSONString")
   617  	Equal(t, fe.StructNamespace(), "TestStructReturnValidationErrors.Inner1.TestStructReturnValidationErrorsInner2.String")
   618  }
   619  
   620  func TestStructLevelValidations(t *testing.T) {
   621  	v1 := New()
   622  	v1.RegisterStructValidation(StructValidationTestStruct, TestStruct{})
   623  
   624  	tst := &TestStruct{
   625  		String: "good value",
   626  	}
   627  
   628  	errs := v1.Struct(tst)
   629  	NotEqual(t, errs, nil)
   630  	AssertError(t, errs, "TestStruct.StringVal", "TestStruct.String", "StringVal", "String", "badvalueteststruct")
   631  
   632  	v2 := New()
   633  	v2.RegisterStructValidation(StructValidationNoTestStructCustomName, TestStruct{})
   634  
   635  	errs = v2.Struct(tst)
   636  	NotEqual(t, errs, nil)
   637  	AssertError(t, errs, "TestStruct.String", "TestStruct.String", "String", "String", "badvalueteststruct")
   638  
   639  	v3 := New()
   640  	v3.RegisterStructValidation(StructValidationTestStructInvalid, TestStruct{})
   641  
   642  	errs = v3.Struct(tst)
   643  	NotEqual(t, errs, nil)
   644  	AssertError(t, errs, "TestStruct.StringVal", "TestStruct.String", "StringVal", "String", "badvalueteststruct")
   645  
   646  	v4 := New()
   647  	v4.RegisterStructValidation(StructValidationTestStructSuccess, TestStruct{})
   648  
   649  	errs = v4.Struct(tst)
   650  	Equal(t, errs, nil)
   651  }
   652  
   653  func TestAliasTags(t *testing.T) {
   654  	validate := New()
   655  	validate.RegisterAlias("iscoloralias", "hexcolor|rgb|rgba|hsl|hsla")
   656  
   657  	s := "rgb(255,255,255)"
   658  	errs := validate.Var(s, "iscoloralias")
   659  	Equal(t, errs, nil)
   660  
   661  	s = ""
   662  	errs = validate.Var(s, "omitempty,iscoloralias")
   663  	Equal(t, errs, nil)
   664  
   665  	s = "rgb(255,255,0)"
   666  	errs = validate.Var(s, "iscoloralias,len=5")
   667  	NotEqual(t, errs, nil)
   668  	AssertError(t, errs, "", "", "", "", "len")
   669  
   670  	type Test struct {
   671  		Color string `validate:"iscoloralias"`
   672  	}
   673  
   674  	tst := &Test{
   675  		Color: "#000",
   676  	}
   677  
   678  	errs = validate.Struct(tst)
   679  	Equal(t, errs, nil)
   680  
   681  	tst.Color = "cfvre"
   682  	errs = validate.Struct(tst)
   683  	NotEqual(t, errs, nil)
   684  	AssertError(t, errs, "Test.Color", "Test.Color", "Color", "Color", "iscoloralias")
   685  
   686  	fe := getError(errs, "Test.Color", "Test.Color")
   687  	NotEqual(t, fe, nil)
   688  	Equal(t, fe.ActualTag(), "hexcolor|rgb|rgba|hsl|hsla")
   689  
   690  	validate.RegisterAlias("req", "required,dive,iscoloralias")
   691  	arr := []string{"val1", "#fff", "#000"}
   692  
   693  	errs = validate.Var(arr, "req")
   694  	NotEqual(t, errs, nil)
   695  	AssertError(t, errs, "[0]", "[0]", "[0]", "[0]", "iscoloralias")
   696  
   697  	PanicMatches(t, func() { validate.RegisterAlias("exists!", "gt=5,lt=10") }, "Alias 'exists!' either contains restricted characters or is the same as a restricted tag needed for normal operation")
   698  }
   699  
   700  func TestNilValidator(t *testing.T) {
   701  	type TestStruct struct {
   702  		Test string `validate:"required"`
   703  	}
   704  
   705  	ts := TestStruct{}
   706  
   707  	var val *Validate
   708  
   709  	fn := func(fl FieldLevel) bool {
   710  		return fl.Parent().String() == fl.Field().String()
   711  	}
   712  
   713  	PanicMatches(t, func() { val.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{}) }, "runtime error: invalid memory address or nil pointer dereference")
   714  	PanicMatches(t, func() { _ = val.RegisterValidation("something", fn) }, "runtime error: invalid memory address or nil pointer dereference")
   715  	PanicMatches(t, func() { _ = val.Var(ts.Test, "required") }, "runtime error: invalid memory address or nil pointer dereference")
   716  	PanicMatches(t, func() { _ = val.VarWithValue("test", ts.Test, "required") }, "runtime error: invalid memory address or nil pointer dereference")
   717  	PanicMatches(t, func() { _ = val.Struct(ts) }, "runtime error: invalid memory address or nil pointer dereference")
   718  	PanicMatches(t, func() { _ = val.StructExcept(ts, "Test") }, "runtime error: invalid memory address or nil pointer dereference")
   719  	PanicMatches(t, func() { _ = val.StructPartial(ts, "Test") }, "runtime error: invalid memory address or nil pointer dereference")
   720  }
   721  
   722  func TestStructPartial(t *testing.T) {
   723  	p1 := []string{
   724  		"NoTag",
   725  		"Required",
   726  	}
   727  
   728  	p2 := []string{
   729  		"SubSlice[0].Test",
   730  		"Sub",
   731  		"SubIgnore",
   732  		"Anonymous.A",
   733  	}
   734  
   735  	p3 := []string{
   736  		"SubTest.Test",
   737  	}
   738  
   739  	p4 := []string{
   740  		"A",
   741  	}
   742  
   743  	tPartial := &TestPartial{
   744  		NoTag:    "NoTag",
   745  		Required: "Required",
   746  
   747  		SubSlice: []*SubTest{
   748  			{
   749  
   750  				Test: "Required",
   751  			},
   752  			{
   753  
   754  				Test: "Required",
   755  			},
   756  		},
   757  
   758  		Sub: &SubTest{
   759  			Test: "1",
   760  		},
   761  		SubIgnore: &SubTest{
   762  			Test: "",
   763  		},
   764  		Anonymous: struct {
   765  			A             string     `validate:"required"`
   766  			ASubSlice     []*SubTest `validate:"required,dive"`
   767  			SubAnonStruct []struct {
   768  				Test      string `validate:"required"`
   769  				OtherTest string `validate:"required"`
   770  			} `validate:"required,dive"`
   771  		}{
   772  			A: "1",
   773  			ASubSlice: []*SubTest{
   774  				{
   775  					Test: "Required",
   776  				},
   777  				{
   778  					Test: "Required",
   779  				},
   780  			},
   781  
   782  			SubAnonStruct: []struct {
   783  				Test      string `validate:"required"`
   784  				OtherTest string `validate:"required"`
   785  			}{
   786  				{"Required", "RequiredOther"},
   787  				{"Required", "RequiredOther"},
   788  			},
   789  		},
   790  	}
   791  
   792  	validate := New()
   793  
   794  	// the following should all return no errors as everything is valid in
   795  	// the default state
   796  	errs := validate.StructPartialCtx(context.Background(), tPartial, p1...)
   797  	Equal(t, errs, nil)
   798  
   799  	errs = validate.StructPartial(tPartial, p2...)
   800  	Equal(t, errs, nil)
   801  
   802  	// this isn't really a robust test, but is ment to illustrate the ANON CASE below
   803  	errs = validate.StructPartial(tPartial.SubSlice[0], p3...)
   804  	Equal(t, errs, nil)
   805  
   806  	errs = validate.StructExceptCtx(context.Background(), tPartial, p1...)
   807  	Equal(t, errs, nil)
   808  
   809  	errs = validate.StructExcept(tPartial, p2...)
   810  	Equal(t, errs, nil)
   811  
   812  	// mod tParial for required feild and re-test making sure invalid fields are NOT required:
   813  	tPartial.Required = ""
   814  
   815  	errs = validate.StructExcept(tPartial, p1...)
   816  	Equal(t, errs, nil)
   817  
   818  	errs = validate.StructPartial(tPartial, p2...)
   819  	Equal(t, errs, nil)
   820  
   821  	// inversion and retesting Partial to generate failures:
   822  	errs = validate.StructPartial(tPartial, p1...)
   823  	NotEqual(t, errs, nil)
   824  	AssertError(t, errs, "TestPartial.Required", "TestPartial.Required", "Required", "Required", "required")
   825  
   826  	errs = validate.StructExcept(tPartial, p2...)
   827  	AssertError(t, errs, "TestPartial.Required", "TestPartial.Required", "Required", "Required", "required")
   828  
   829  	// reset Required field, and set nested struct
   830  	tPartial.Required = "Required"
   831  	tPartial.Anonymous.A = ""
   832  
   833  	// will pass as unset feilds is not going to be tested
   834  	errs = validate.StructPartial(tPartial, p1...)
   835  	Equal(t, errs, nil)
   836  
   837  	errs = validate.StructExcept(tPartial, p2...)
   838  	Equal(t, errs, nil)
   839  
   840  	// ANON CASE the response here is strange, it clearly does what it is being told to
   841  	errs = validate.StructExcept(tPartial.Anonymous, p4...)
   842  	Equal(t, errs, nil)
   843  
   844  	// will fail as unset feild is tested
   845  	errs = validate.StructPartial(tPartial, p2...)
   846  	NotEqual(t, errs, nil)
   847  	AssertError(t, errs, "TestPartial.Anonymous.A", "TestPartial.Anonymous.A", "A", "A", "required")
   848  
   849  	errs = validate.StructExcept(tPartial, p1...)
   850  	NotEqual(t, errs, nil)
   851  	AssertError(t, errs, "TestPartial.Anonymous.A", "TestPartial.Anonymous.A", "A", "A", "required")
   852  
   853  	// reset nested struct and unset struct in slice
   854  	tPartial.Anonymous.A = "Required"
   855  	tPartial.SubSlice[0].Test = ""
   856  
   857  	// these will pass as unset item is NOT tested
   858  	errs = validate.StructPartial(tPartial, p1...)
   859  	Equal(t, errs, nil)
   860  
   861  	errs = validate.StructExcept(tPartial, p2...)
   862  	Equal(t, errs, nil)
   863  
   864  	// these will fail as unset item IS tested
   865  	errs = validate.StructExcept(tPartial, p1...)
   866  	AssertError(t, errs, "TestPartial.SubSlice[0].Test", "TestPartial.SubSlice[0].Test", "Test", "Test", "required")
   867  	Equal(t, len(errs.(ValidationErrors)), 1)
   868  
   869  	errs = validate.StructPartial(tPartial, p2...)
   870  	NotEqual(t, errs, nil)
   871  	AssertError(t, errs, "TestPartial.SubSlice[0].Test", "TestPartial.SubSlice[0].Test", "Test", "Test", "required")
   872  	Equal(t, len(errs.(ValidationErrors)), 1)
   873  
   874  	// Unset second slice member concurrently to test dive behavior:
   875  	tPartial.SubSlice[1].Test = ""
   876  
   877  	errs = validate.StructPartial(tPartial, p1...)
   878  	Equal(t, errs, nil)
   879  
   880  	// NOTE: When specifying nested items, it is still the users responsibility
   881  	// to specify the dive tag, the library does not override this.
   882  	errs = validate.StructExcept(tPartial, p2...)
   883  	NotEqual(t, errs, nil)
   884  	AssertError(t, errs, "TestPartial.SubSlice[1].Test", "TestPartial.SubSlice[1].Test", "Test", "Test", "required")
   885  
   886  	errs = validate.StructExcept(tPartial, p1...)
   887  	Equal(t, len(errs.(ValidationErrors)), 2)
   888  	AssertError(t, errs, "TestPartial.SubSlice[0].Test", "TestPartial.SubSlice[0].Test", "Test", "Test", "required")
   889  	AssertError(t, errs, "TestPartial.SubSlice[1].Test", "TestPartial.SubSlice[1].Test", "Test", "Test", "required")
   890  
   891  	errs = validate.StructPartial(tPartial, p2...)
   892  	NotEqual(t, errs, nil)
   893  	Equal(t, len(errs.(ValidationErrors)), 1)
   894  	AssertError(t, errs, "TestPartial.SubSlice[0].Test", "TestPartial.SubSlice[0].Test", "Test", "Test", "required")
   895  
   896  	// reset struct in slice, and unset struct in slice in unset posistion
   897  	tPartial.SubSlice[0].Test = "Required"
   898  
   899  	// these will pass as the unset item is NOT tested
   900  	errs = validate.StructPartial(tPartial, p1...)
   901  	Equal(t, errs, nil)
   902  
   903  	errs = validate.StructPartial(tPartial, p2...)
   904  	Equal(t, errs, nil)
   905  
   906  	// testing for missing item by exception, yes it dives and fails
   907  	errs = validate.StructExcept(tPartial, p1...)
   908  	NotEqual(t, errs, nil)
   909  	Equal(t, len(errs.(ValidationErrors)), 1)
   910  	AssertError(t, errs, "TestPartial.SubSlice[1].Test", "TestPartial.SubSlice[1].Test", "Test", "Test", "required")
   911  
   912  	errs = validate.StructExcept(tPartial, p2...)
   913  	NotEqual(t, errs, nil)
   914  	AssertError(t, errs, "TestPartial.SubSlice[1].Test", "TestPartial.SubSlice[1].Test", "Test", "Test", "required")
   915  
   916  	tPartial.SubSlice[1].Test = "Required"
   917  
   918  	tPartial.Anonymous.SubAnonStruct[0].Test = ""
   919  	// these will pass as the unset item is NOT tested
   920  	errs = validate.StructPartial(tPartial, p1...)
   921  	Equal(t, errs, nil)
   922  
   923  	errs = validate.StructPartial(tPartial, p2...)
   924  	Equal(t, errs, nil)
   925  
   926  	errs = validate.StructExcept(tPartial, p1...)
   927  	NotEqual(t, errs, nil)
   928  	AssertError(t, errs, "TestPartial.Anonymous.SubAnonStruct[0].Test", "TestPartial.Anonymous.SubAnonStruct[0].Test", "Test", "Test", "required")
   929  
   930  	errs = validate.StructExcept(tPartial, p2...)
   931  	NotEqual(t, errs, nil)
   932  	AssertError(t, errs, "TestPartial.Anonymous.SubAnonStruct[0].Test", "TestPartial.Anonymous.SubAnonStruct[0].Test", "Test", "Test", "required")
   933  
   934  	// Test for unnamed struct
   935  	testStruct := &TestStruct{
   936  		String: "test",
   937  	}
   938  	unnamedStruct := struct {
   939  		String string `validate:"required" json:"StringVal"`
   940  	}{String: "test"}
   941  	composedUnnamedStruct := struct{ *TestStruct }{&TestStruct{String: "test"}}
   942  
   943  	errs = validate.StructPartial(testStruct, "String")
   944  	Equal(t, errs, nil)
   945  
   946  	errs = validate.StructPartial(unnamedStruct, "String")
   947  	Equal(t, errs, nil)
   948  
   949  	errs = validate.StructPartial(composedUnnamedStruct, "TestStruct.String")
   950  	Equal(t, errs, nil)
   951  
   952  	testStruct.String = ""
   953  	errs = validate.StructPartial(testStruct, "String")
   954  	NotEqual(t, errs, nil)
   955  	AssertError(t, errs, "TestStruct.String", "TestStruct.String", "String", "String", "required")
   956  
   957  	unnamedStruct.String = ""
   958  	errs = validate.StructPartial(unnamedStruct, "String")
   959  	NotEqual(t, errs, nil)
   960  	AssertError(t, errs, "String", "String", "String", "String", "required")
   961  
   962  	composedUnnamedStruct.String = ""
   963  	errs = validate.StructPartial(composedUnnamedStruct, "TestStruct.String")
   964  	NotEqual(t, errs, nil)
   965  	AssertError(t, errs, "TestStruct.String", "TestStruct.String", "String", "String", "required")
   966  }
   967  
   968  func TestCrossStructLteFieldValidation(t *testing.T) {
   969  	var errs error
   970  	validate := New()
   971  
   972  	type Inner struct {
   973  		CreatedAt *time.Time
   974  		String    string
   975  		Int       int
   976  		Uint      uint
   977  		Float     float64
   978  		Array     []string
   979  	}
   980  
   981  	type Test struct {
   982  		Inner     *Inner
   983  		CreatedAt *time.Time `validate:"ltecsfield=Inner.CreatedAt"`
   984  		String    string     `validate:"ltecsfield=Inner.String"`
   985  		Int       int        `validate:"ltecsfield=Inner.Int"`
   986  		Uint      uint       `validate:"ltecsfield=Inner.Uint"`
   987  		Float     float64    `validate:"ltecsfield=Inner.Float"`
   988  		Array     []string   `validate:"ltecsfield=Inner.Array"`
   989  	}
   990  
   991  	now := time.Now().UTC()
   992  	then := now.Add(time.Hour * 5)
   993  
   994  	inner := &Inner{
   995  		CreatedAt: &then,
   996  		String:    "abcd",
   997  		Int:       13,
   998  		Uint:      13,
   999  		Float:     1.13,
  1000  		Array:     []string{"val1", "val2"},
  1001  	}
  1002  
  1003  	test := &Test{
  1004  		Inner:     inner,
  1005  		CreatedAt: &now,
  1006  		String:    "abc",
  1007  		Int:       12,
  1008  		Uint:      12,
  1009  		Float:     1.12,
  1010  		Array:     []string{"val1"},
  1011  	}
  1012  
  1013  	errs = validate.Struct(test)
  1014  	Equal(t, errs, nil)
  1015  
  1016  	test.CreatedAt = &then
  1017  	test.String = "abcd"
  1018  	test.Int = 13
  1019  	test.Uint = 13
  1020  	test.Float = 1.13
  1021  	test.Array = []string{"val1", "val2"}
  1022  
  1023  	errs = validate.Struct(test)
  1024  	Equal(t, errs, nil)
  1025  
  1026  	after := now.Add(time.Hour * 10)
  1027  
  1028  	test.CreatedAt = &after
  1029  	test.String = "abce"
  1030  	test.Int = 14
  1031  	test.Uint = 14
  1032  	test.Float = 1.14
  1033  	test.Array = []string{"val1", "val2", "val3"}
  1034  
  1035  	errs = validate.Struct(test)
  1036  	NotEqual(t, errs, nil)
  1037  	AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "ltecsfield")
  1038  	AssertError(t, errs, "Test.String", "Test.String", "String", "String", "ltecsfield")
  1039  	AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "ltecsfield")
  1040  	AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "ltecsfield")
  1041  	AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "ltecsfield")
  1042  	AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "ltecsfield")
  1043  
  1044  	errs = validate.VarWithValueCtx(context.Background(), 1, "", "ltecsfield")
  1045  	NotEqual(t, errs, nil)
  1046  	AssertError(t, errs, "", "", "", "", "ltecsfield")
  1047  
  1048  	// this test is for the WARNING about unforeseen validation issues.
  1049  	errs = validate.VarWithValue(test, now, "ltecsfield")
  1050  	NotEqual(t, errs, nil)
  1051  	Equal(t, len(errs.(ValidationErrors)), 6)
  1052  	AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "ltecsfield")
  1053  	AssertError(t, errs, "Test.String", "Test.String", "String", "String", "ltecsfield")
  1054  	AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "ltecsfield")
  1055  	AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "ltecsfield")
  1056  	AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "ltecsfield")
  1057  	AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "ltecsfield")
  1058  
  1059  	type Other struct {
  1060  		Value string
  1061  	}
  1062  
  1063  	type Test2 struct {
  1064  		Value Other
  1065  		Time  time.Time `validate:"ltecsfield=Value"`
  1066  	}
  1067  
  1068  	tst := Test2{
  1069  		Value: Other{Value: "StringVal"},
  1070  		Time:  then,
  1071  	}
  1072  
  1073  	errs = validate.Struct(tst)
  1074  	NotEqual(t, errs, nil)
  1075  	AssertError(t, errs, "Test2.Time", "Test2.Time", "Time", "Time", "ltecsfield")
  1076  
  1077  	// Tests for time.Duration type.
  1078  
  1079  	// -- Validations for variables of time.Duration type.
  1080  
  1081  	errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "ltecsfield")
  1082  	Equal(t, errs, nil)
  1083  
  1084  	errs = validate.VarWithValue(time.Hour, time.Hour, "ltecsfield")
  1085  	Equal(t, errs, nil)
  1086  
  1087  	errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "ltecsfield")
  1088  	NotEqual(t, errs, nil)
  1089  	AssertError(t, errs, "", "", "", "", "ltecsfield")
  1090  
  1091  	errs = validate.VarWithValue(time.Duration(0), -time.Minute, "omitempty,ltecsfield")
  1092  	Equal(t, errs, nil)
  1093  
  1094  	// -- Validations for a struct and an inner struct with time.Duration type fields.
  1095  
  1096  	type TimeDurationInner struct {
  1097  		Duration time.Duration
  1098  	}
  1099  	var timeDurationInner *TimeDurationInner
  1100  
  1101  	type TimeDurationTest struct {
  1102  		Inner    *TimeDurationInner
  1103  		Duration time.Duration `validate:"ltecsfield=Inner.Duration"`
  1104  	}
  1105  	var timeDurationTest *TimeDurationTest
  1106  
  1107  	timeDurationInner = &TimeDurationInner{time.Hour + time.Minute}
  1108  	timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
  1109  	errs = validate.Struct(timeDurationTest)
  1110  	Equal(t, errs, nil)
  1111  
  1112  	timeDurationInner = &TimeDurationInner{time.Hour}
  1113  	timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
  1114  	errs = validate.Struct(timeDurationTest)
  1115  	Equal(t, errs, nil)
  1116  
  1117  	timeDurationInner = &TimeDurationInner{time.Hour - time.Minute}
  1118  	timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
  1119  	errs = validate.Struct(timeDurationTest)
  1120  	NotEqual(t, errs, nil)
  1121  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "ltecsfield")
  1122  
  1123  	type TimeDurationOmitemptyTest struct {
  1124  		Inner    *TimeDurationInner
  1125  		Duration time.Duration `validate:"omitempty,ltecsfield=Inner.Duration"`
  1126  	}
  1127  	var timeDurationOmitemptyTest *TimeDurationOmitemptyTest
  1128  
  1129  	timeDurationInner = &TimeDurationInner{-time.Minute}
  1130  	timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)}
  1131  	errs = validate.Struct(timeDurationOmitemptyTest)
  1132  	Equal(t, errs, nil)
  1133  }
  1134  
  1135  func TestCrossStructLtFieldValidation(t *testing.T) {
  1136  	var errs error
  1137  	validate := New()
  1138  
  1139  	type Inner struct {
  1140  		CreatedAt *time.Time
  1141  		String    string
  1142  		Int       int
  1143  		Uint      uint
  1144  		Float     float64
  1145  		Array     []string
  1146  	}
  1147  
  1148  	type Test struct {
  1149  		Inner     *Inner
  1150  		CreatedAt *time.Time `validate:"ltcsfield=Inner.CreatedAt"`
  1151  		String    string     `validate:"ltcsfield=Inner.String"`
  1152  		Int       int        `validate:"ltcsfield=Inner.Int"`
  1153  		Uint      uint       `validate:"ltcsfield=Inner.Uint"`
  1154  		Float     float64    `validate:"ltcsfield=Inner.Float"`
  1155  		Array     []string   `validate:"ltcsfield=Inner.Array"`
  1156  	}
  1157  
  1158  	now := time.Now().UTC()
  1159  	then := now.Add(time.Hour * 5)
  1160  
  1161  	inner := &Inner{
  1162  		CreatedAt: &then,
  1163  		String:    "abcd",
  1164  		Int:       13,
  1165  		Uint:      13,
  1166  		Float:     1.13,
  1167  		Array:     []string{"val1", "val2"},
  1168  	}
  1169  
  1170  	test := &Test{
  1171  		Inner:     inner,
  1172  		CreatedAt: &now,
  1173  		String:    "abc",
  1174  		Int:       12,
  1175  		Uint:      12,
  1176  		Float:     1.12,
  1177  		Array:     []string{"val1"},
  1178  	}
  1179  
  1180  	errs = validate.Struct(test)
  1181  	Equal(t, errs, nil)
  1182  
  1183  	test.CreatedAt = &then
  1184  	test.String = "abcd"
  1185  	test.Int = 13
  1186  	test.Uint = 13
  1187  	test.Float = 1.13
  1188  	test.Array = []string{"val1", "val2"}
  1189  
  1190  	errs = validate.Struct(test)
  1191  	NotEqual(t, errs, nil)
  1192  	AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "ltcsfield")
  1193  	AssertError(t, errs, "Test.String", "Test.String", "String", "String", "ltcsfield")
  1194  	AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "ltcsfield")
  1195  	AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "ltcsfield")
  1196  	AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "ltcsfield")
  1197  	AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "ltcsfield")
  1198  
  1199  	errs = validate.VarWithValue(1, "", "ltcsfield")
  1200  	NotEqual(t, errs, nil)
  1201  	AssertError(t, errs, "", "", "", "", "ltcsfield")
  1202  
  1203  	// this test is for the WARNING about unforeseen validation issues.
  1204  	errs = validate.VarWithValue(test, now, "ltcsfield")
  1205  	NotEqual(t, errs, nil)
  1206  	AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "ltcsfield")
  1207  	AssertError(t, errs, "Test.String", "Test.String", "String", "String", "ltcsfield")
  1208  	AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "ltcsfield")
  1209  	AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "ltcsfield")
  1210  	AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "ltcsfield")
  1211  	AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "ltcsfield")
  1212  
  1213  	type Other struct {
  1214  		Value string
  1215  	}
  1216  
  1217  	type Test2 struct {
  1218  		Value Other
  1219  		Time  time.Time `validate:"ltcsfield=Value"`
  1220  	}
  1221  
  1222  	tst := Test2{
  1223  		Value: Other{Value: "StringVal"},
  1224  		Time:  then,
  1225  	}
  1226  
  1227  	errs = validate.Struct(tst)
  1228  	NotEqual(t, errs, nil)
  1229  	AssertError(t, errs, "Test2.Time", "Test2.Time", "Time", "Time", "ltcsfield")
  1230  
  1231  	// Tests for time.Duration type.
  1232  
  1233  	// -- Validations for variables of time.Duration type.
  1234  
  1235  	errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "ltcsfield")
  1236  	Equal(t, errs, nil)
  1237  
  1238  	errs = validate.VarWithValue(time.Hour, time.Hour, "ltcsfield")
  1239  	NotEqual(t, errs, nil)
  1240  	AssertError(t, errs, "", "", "", "", "ltcsfield")
  1241  
  1242  	errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "ltcsfield")
  1243  	NotEqual(t, errs, nil)
  1244  	AssertError(t, errs, "", "", "", "", "ltcsfield")
  1245  
  1246  	errs = validate.VarWithValue(time.Duration(0), -time.Minute, "omitempty,ltcsfield")
  1247  	Equal(t, errs, nil)
  1248  
  1249  	// -- Validations for a struct and an inner struct with time.Duration type fields.
  1250  
  1251  	type TimeDurationInner struct {
  1252  		Duration time.Duration
  1253  	}
  1254  	var timeDurationInner *TimeDurationInner
  1255  
  1256  	type TimeDurationTest struct {
  1257  		Inner    *TimeDurationInner
  1258  		Duration time.Duration `validate:"ltcsfield=Inner.Duration"`
  1259  	}
  1260  	var timeDurationTest *TimeDurationTest
  1261  
  1262  	timeDurationInner = &TimeDurationInner{time.Hour + time.Minute}
  1263  	timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
  1264  	errs = validate.Struct(timeDurationTest)
  1265  	Equal(t, errs, nil)
  1266  
  1267  	timeDurationInner = &TimeDurationInner{time.Hour}
  1268  	timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
  1269  	errs = validate.Struct(timeDurationTest)
  1270  	NotEqual(t, errs, nil)
  1271  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "ltcsfield")
  1272  
  1273  	timeDurationInner = &TimeDurationInner{time.Hour - time.Minute}
  1274  	timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
  1275  	errs = validate.Struct(timeDurationTest)
  1276  	NotEqual(t, errs, nil)
  1277  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "ltcsfield")
  1278  
  1279  	type TimeDurationOmitemptyTest struct {
  1280  		Inner    *TimeDurationInner
  1281  		Duration time.Duration `validate:"omitempty,ltcsfield=Inner.Duration"`
  1282  	}
  1283  	var timeDurationOmitemptyTest *TimeDurationOmitemptyTest
  1284  
  1285  	timeDurationInner = &TimeDurationInner{-time.Minute}
  1286  	timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)}
  1287  	errs = validate.Struct(timeDurationOmitemptyTest)
  1288  	Equal(t, errs, nil)
  1289  }
  1290  
  1291  func TestCrossStructGteFieldValidation(t *testing.T) {
  1292  	var errs error
  1293  	validate := New()
  1294  
  1295  	type Inner struct {
  1296  		CreatedAt *time.Time
  1297  		String    string
  1298  		Int       int
  1299  		Uint      uint
  1300  		Float     float64
  1301  		Array     []string
  1302  	}
  1303  
  1304  	type Test struct {
  1305  		Inner     *Inner
  1306  		CreatedAt *time.Time `validate:"gtecsfield=Inner.CreatedAt"`
  1307  		String    string     `validate:"gtecsfield=Inner.String"`
  1308  		Int       int        `validate:"gtecsfield=Inner.Int"`
  1309  		Uint      uint       `validate:"gtecsfield=Inner.Uint"`
  1310  		Float     float64    `validate:"gtecsfield=Inner.Float"`
  1311  		Array     []string   `validate:"gtecsfield=Inner.Array"`
  1312  	}
  1313  
  1314  	now := time.Now().UTC()
  1315  	then := now.Add(time.Hour * -5)
  1316  
  1317  	inner := &Inner{
  1318  		CreatedAt: &then,
  1319  		String:    "abcd",
  1320  		Int:       13,
  1321  		Uint:      13,
  1322  		Float:     1.13,
  1323  		Array:     []string{"val1", "val2"},
  1324  	}
  1325  
  1326  	test := &Test{
  1327  		Inner:     inner,
  1328  		CreatedAt: &now,
  1329  		String:    "abcde",
  1330  		Int:       14,
  1331  		Uint:      14,
  1332  		Float:     1.14,
  1333  		Array:     []string{"val1", "val2", "val3"},
  1334  	}
  1335  
  1336  	errs = validate.Struct(test)
  1337  	Equal(t, errs, nil)
  1338  
  1339  	test.CreatedAt = &then
  1340  	test.String = "abcd"
  1341  	test.Int = 13
  1342  	test.Uint = 13
  1343  	test.Float = 1.13
  1344  	test.Array = []string{"val1", "val2"}
  1345  
  1346  	errs = validate.Struct(test)
  1347  	Equal(t, errs, nil)
  1348  
  1349  	before := now.Add(time.Hour * -10)
  1350  
  1351  	test.CreatedAt = &before
  1352  	test.String = "abc"
  1353  	test.Int = 12
  1354  	test.Uint = 12
  1355  	test.Float = 1.12
  1356  	test.Array = []string{"val1"}
  1357  
  1358  	errs = validate.Struct(test)
  1359  	NotEqual(t, errs, nil)
  1360  	AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "gtecsfield")
  1361  	AssertError(t, errs, "Test.String", "Test.String", "String", "String", "gtecsfield")
  1362  	AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "gtecsfield")
  1363  	AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "gtecsfield")
  1364  	AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "gtecsfield")
  1365  	AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "gtecsfield")
  1366  
  1367  	errs = validate.VarWithValue(1, "", "gtecsfield")
  1368  	NotEqual(t, errs, nil)
  1369  	AssertError(t, errs, "", "", "", "", "gtecsfield")
  1370  
  1371  	// this test is for the WARNING about unforeseen validation issues.
  1372  	errs = validate.VarWithValue(test, now, "gtecsfield")
  1373  	NotEqual(t, errs, nil)
  1374  	AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "gtecsfield")
  1375  	AssertError(t, errs, "Test.String", "Test.String", "String", "String", "gtecsfield")
  1376  	AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "gtecsfield")
  1377  	AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "gtecsfield")
  1378  	AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "gtecsfield")
  1379  	AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "gtecsfield")
  1380  
  1381  	type Other struct {
  1382  		Value string
  1383  	}
  1384  
  1385  	type Test2 struct {
  1386  		Value Other
  1387  		Time  time.Time `validate:"gtecsfield=Value"`
  1388  	}
  1389  
  1390  	tst := Test2{
  1391  		Value: Other{Value: "StringVal"},
  1392  		Time:  then,
  1393  	}
  1394  
  1395  	errs = validate.Struct(tst)
  1396  	NotEqual(t, errs, nil)
  1397  	AssertError(t, errs, "Test2.Time", "Test2.Time", "Time", "Time", "gtecsfield")
  1398  
  1399  	// Tests for time.Duration type.
  1400  
  1401  	// -- Validations for variables of time.Duration type.
  1402  
  1403  	errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "gtecsfield")
  1404  	Equal(t, errs, nil)
  1405  
  1406  	errs = validate.VarWithValue(time.Hour, time.Hour, "gtecsfield")
  1407  	Equal(t, errs, nil)
  1408  
  1409  	errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "gtecsfield")
  1410  	NotEqual(t, errs, nil)
  1411  	AssertError(t, errs, "", "", "", "", "gtecsfield")
  1412  
  1413  	errs = validate.VarWithValue(time.Duration(0), time.Hour, "omitempty,gtecsfield")
  1414  	Equal(t, errs, nil)
  1415  
  1416  	// -- Validations for a struct and an inner struct with time.Duration type fields.
  1417  
  1418  	type TimeDurationInner struct {
  1419  		Duration time.Duration
  1420  	}
  1421  	var timeDurationInner *TimeDurationInner
  1422  
  1423  	type TimeDurationTest struct {
  1424  		Inner    *TimeDurationInner
  1425  		Duration time.Duration `validate:"gtecsfield=Inner.Duration"`
  1426  	}
  1427  	var timeDurationTest *TimeDurationTest
  1428  
  1429  	timeDurationInner = &TimeDurationInner{time.Hour - time.Minute}
  1430  	timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
  1431  	errs = validate.Struct(timeDurationTest)
  1432  	Equal(t, errs, nil)
  1433  
  1434  	timeDurationInner = &TimeDurationInner{time.Hour}
  1435  	timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
  1436  	errs = validate.Struct(timeDurationTest)
  1437  	Equal(t, errs, nil)
  1438  
  1439  	timeDurationInner = &TimeDurationInner{time.Hour + time.Minute}
  1440  	timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
  1441  	errs = validate.Struct(timeDurationTest)
  1442  	NotEqual(t, errs, nil)
  1443  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "gtecsfield")
  1444  
  1445  	type TimeDurationOmitemptyTest struct {
  1446  		Inner    *TimeDurationInner
  1447  		Duration time.Duration `validate:"omitempty,gtecsfield=Inner.Duration"`
  1448  	}
  1449  	var timeDurationOmitemptyTest *TimeDurationOmitemptyTest
  1450  
  1451  	timeDurationInner = &TimeDurationInner{time.Hour}
  1452  	timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)}
  1453  	errs = validate.Struct(timeDurationOmitemptyTest)
  1454  	Equal(t, errs, nil)
  1455  }
  1456  
  1457  func TestCrossStructGtFieldValidation(t *testing.T) {
  1458  	var errs error
  1459  	validate := New()
  1460  
  1461  	type Inner struct {
  1462  		CreatedAt *time.Time
  1463  		String    string
  1464  		Int       int
  1465  		Uint      uint
  1466  		Float     float64
  1467  		Array     []string
  1468  	}
  1469  
  1470  	type Test struct {
  1471  		Inner     *Inner
  1472  		CreatedAt *time.Time `validate:"gtcsfield=Inner.CreatedAt"`
  1473  		String    string     `validate:"gtcsfield=Inner.String"`
  1474  		Int       int        `validate:"gtcsfield=Inner.Int"`
  1475  		Uint      uint       `validate:"gtcsfield=Inner.Uint"`
  1476  		Float     float64    `validate:"gtcsfield=Inner.Float"`
  1477  		Array     []string   `validate:"gtcsfield=Inner.Array"`
  1478  	}
  1479  
  1480  	now := time.Now().UTC()
  1481  	then := now.Add(time.Hour * -5)
  1482  
  1483  	inner := &Inner{
  1484  		CreatedAt: &then,
  1485  		String:    "abcd",
  1486  		Int:       13,
  1487  		Uint:      13,
  1488  		Float:     1.13,
  1489  		Array:     []string{"val1", "val2"},
  1490  	}
  1491  
  1492  	test := &Test{
  1493  		Inner:     inner,
  1494  		CreatedAt: &now,
  1495  		String:    "abcde",
  1496  		Int:       14,
  1497  		Uint:      14,
  1498  		Float:     1.14,
  1499  		Array:     []string{"val1", "val2", "val3"},
  1500  	}
  1501  
  1502  	errs = validate.Struct(test)
  1503  	Equal(t, errs, nil)
  1504  
  1505  	test.CreatedAt = &then
  1506  	test.String = "abcd"
  1507  	test.Int = 13
  1508  	test.Uint = 13
  1509  	test.Float = 1.13
  1510  	test.Array = []string{"val1", "val2"}
  1511  
  1512  	errs = validate.Struct(test)
  1513  	NotEqual(t, errs, nil)
  1514  	AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "gtcsfield")
  1515  	AssertError(t, errs, "Test.String", "Test.String", "String", "String", "gtcsfield")
  1516  	AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "gtcsfield")
  1517  	AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "gtcsfield")
  1518  	AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "gtcsfield")
  1519  	AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "gtcsfield")
  1520  
  1521  	errs = validate.VarWithValue(1, "", "gtcsfield")
  1522  	NotEqual(t, errs, nil)
  1523  	AssertError(t, errs, "", "", "", "", "gtcsfield")
  1524  
  1525  	// this test is for the WARNING about unforeseen validation issues.
  1526  	errs = validate.VarWithValue(test, now, "gtcsfield")
  1527  	NotEqual(t, errs, nil)
  1528  	AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "gtcsfield")
  1529  	AssertError(t, errs, "Test.String", "Test.String", "String", "String", "gtcsfield")
  1530  	AssertError(t, errs, "Test.Int", "Test.Int", "Int", "Int", "gtcsfield")
  1531  	AssertError(t, errs, "Test.Uint", "Test.Uint", "Uint", "Uint", "gtcsfield")
  1532  	AssertError(t, errs, "Test.Float", "Test.Float", "Float", "Float", "gtcsfield")
  1533  	AssertError(t, errs, "Test.Array", "Test.Array", "Array", "Array", "gtcsfield")
  1534  
  1535  	type Other struct {
  1536  		Value string
  1537  	}
  1538  
  1539  	type Test2 struct {
  1540  		Value Other
  1541  		Time  time.Time `validate:"gtcsfield=Value"`
  1542  	}
  1543  
  1544  	tst := Test2{
  1545  		Value: Other{Value: "StringVal"},
  1546  		Time:  then,
  1547  	}
  1548  
  1549  	errs = validate.Struct(tst)
  1550  	NotEqual(t, errs, nil)
  1551  	AssertError(t, errs, "Test2.Time", "Test2.Time", "Time", "Time", "gtcsfield")
  1552  
  1553  	// Tests for time.Duration type.
  1554  
  1555  	// -- Validations for variables of time.Duration type.
  1556  
  1557  	errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "gtcsfield")
  1558  	Equal(t, errs, nil)
  1559  
  1560  	errs = validate.VarWithValue(time.Hour, time.Hour, "gtcsfield")
  1561  	NotEqual(t, errs, nil)
  1562  	AssertError(t, errs, "", "", "", "", "gtcsfield")
  1563  
  1564  	errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "gtcsfield")
  1565  	NotEqual(t, errs, nil)
  1566  	AssertError(t, errs, "", "", "", "", "gtcsfield")
  1567  
  1568  	errs = validate.VarWithValue(time.Duration(0), time.Hour, "omitempty,gtcsfield")
  1569  	Equal(t, errs, nil)
  1570  
  1571  	// -- Validations for a struct and an inner struct with time.Duration type fields.
  1572  
  1573  	type TimeDurationInner struct {
  1574  		Duration time.Duration
  1575  	}
  1576  	var timeDurationInner *TimeDurationInner
  1577  
  1578  	type TimeDurationTest struct {
  1579  		Inner    *TimeDurationInner
  1580  		Duration time.Duration `validate:"gtcsfield=Inner.Duration"`
  1581  	}
  1582  	var timeDurationTest *TimeDurationTest
  1583  
  1584  	timeDurationInner = &TimeDurationInner{time.Hour - time.Minute}
  1585  	timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
  1586  	errs = validate.Struct(timeDurationTest)
  1587  	Equal(t, errs, nil)
  1588  
  1589  	timeDurationInner = &TimeDurationInner{time.Hour}
  1590  	timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
  1591  	errs = validate.Struct(timeDurationTest)
  1592  	NotEqual(t, errs, nil)
  1593  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "gtcsfield")
  1594  
  1595  	timeDurationInner = &TimeDurationInner{time.Hour + time.Minute}
  1596  	timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
  1597  	errs = validate.Struct(timeDurationTest)
  1598  	NotEqual(t, errs, nil)
  1599  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "gtcsfield")
  1600  
  1601  	type TimeDurationOmitemptyTest struct {
  1602  		Inner    *TimeDurationInner
  1603  		Duration time.Duration `validate:"omitempty,gtcsfield=Inner.Duration"`
  1604  	}
  1605  	var timeDurationOmitemptyTest *TimeDurationOmitemptyTest
  1606  
  1607  	timeDurationInner = &TimeDurationInner{time.Hour}
  1608  	timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)}
  1609  	errs = validate.Struct(timeDurationOmitemptyTest)
  1610  	Equal(t, errs, nil)
  1611  }
  1612  
  1613  func TestCrossStructNeFieldValidation(t *testing.T) {
  1614  	var errs error
  1615  	validate := New()
  1616  
  1617  	type Inner struct {
  1618  		CreatedAt *time.Time
  1619  	}
  1620  
  1621  	type Test struct {
  1622  		Inner     *Inner
  1623  		CreatedAt *time.Time `validate:"necsfield=Inner.CreatedAt"`
  1624  	}
  1625  
  1626  	now := time.Now().UTC()
  1627  	then := now.Add(time.Hour * 5)
  1628  
  1629  	inner := &Inner{
  1630  		CreatedAt: &then,
  1631  	}
  1632  
  1633  	test := &Test{
  1634  		Inner:     inner,
  1635  		CreatedAt: &now,
  1636  	}
  1637  
  1638  	errs = validate.Struct(test)
  1639  	Equal(t, errs, nil)
  1640  
  1641  	test.CreatedAt = &then
  1642  
  1643  	errs = validate.Struct(test)
  1644  	NotEqual(t, errs, nil)
  1645  	AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "necsfield")
  1646  
  1647  	var j uint64
  1648  	var k float64
  1649  	var j2 uint64
  1650  	var k2 float64
  1651  	s := "abcd"
  1652  	i := 1
  1653  	j = 1
  1654  	k = 1.543
  1655  	b := true
  1656  	arr := []string{"test"}
  1657  
  1658  	s2 := "abcd"
  1659  	i2 := 1
  1660  	j2 = 1
  1661  	k2 = 1.543
  1662  	b2 := true
  1663  	arr2 := []string{"test"}
  1664  	arr3 := []string{"test", "test2"}
  1665  	now2 := now
  1666  
  1667  	errs = validate.VarWithValue(s, s2, "necsfield")
  1668  	NotEqual(t, errs, nil)
  1669  	AssertError(t, errs, "", "", "", "", "necsfield")
  1670  
  1671  	errs = validate.VarWithValue(i2, i, "necsfield")
  1672  	NotEqual(t, errs, nil)
  1673  	AssertError(t, errs, "", "", "", "", "necsfield")
  1674  
  1675  	errs = validate.VarWithValue(j2, j, "necsfield")
  1676  	NotEqual(t, errs, nil)
  1677  	AssertError(t, errs, "", "", "", "", "necsfield")
  1678  
  1679  	errs = validate.VarWithValue(k2, k, "necsfield")
  1680  	NotEqual(t, errs, nil)
  1681  	AssertError(t, errs, "", "", "", "", "necsfield")
  1682  
  1683  	errs = validate.VarWithValue(b2, b, "necsfield")
  1684  	NotEqual(t, errs, nil)
  1685  	AssertError(t, errs, "", "", "", "", "necsfield")
  1686  
  1687  	errs = validate.VarWithValue(arr2, arr, "necsfield")
  1688  	NotEqual(t, errs, nil)
  1689  	AssertError(t, errs, "", "", "", "", "necsfield")
  1690  
  1691  	errs = validate.VarWithValue(now2, now, "necsfield")
  1692  	NotEqual(t, errs, nil)
  1693  	AssertError(t, errs, "", "", "", "", "necsfield")
  1694  
  1695  	errs = validate.VarWithValue(arr3, arr, "necsfield")
  1696  	Equal(t, errs, nil)
  1697  
  1698  	type SInner struct {
  1699  		Name string
  1700  	}
  1701  
  1702  	type TStruct struct {
  1703  		Inner     *SInner
  1704  		CreatedAt *time.Time `validate:"necsfield=Inner"`
  1705  	}
  1706  
  1707  	sinner := &SInner{
  1708  		Name: "NAME",
  1709  	}
  1710  
  1711  	test2 := &TStruct{
  1712  		Inner:     sinner,
  1713  		CreatedAt: &now,
  1714  	}
  1715  
  1716  	errs = validate.Struct(test2)
  1717  	Equal(t, errs, nil)
  1718  
  1719  	test2.Inner = nil
  1720  	errs = validate.Struct(test2)
  1721  	Equal(t, errs, nil)
  1722  
  1723  	errs = validate.VarWithValue(nil, 1, "necsfield")
  1724  	NotEqual(t, errs, nil)
  1725  	AssertError(t, errs, "", "", "", "", "necsfield")
  1726  
  1727  	// Tests for time.Duration type.
  1728  
  1729  	// -- Validations for variables of time.Duration type.
  1730  
  1731  	errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "necsfield")
  1732  	Equal(t, errs, nil)
  1733  
  1734  	errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "necsfield")
  1735  	Equal(t, errs, nil)
  1736  
  1737  	errs = validate.VarWithValue(time.Hour, time.Hour, "necsfield")
  1738  	NotEqual(t, errs, nil)
  1739  	AssertError(t, errs, "", "", "", "", "necsfield")
  1740  
  1741  	errs = validate.VarWithValue(time.Duration(0), time.Duration(0), "omitempty,necsfield")
  1742  	Equal(t, errs, nil)
  1743  
  1744  	// -- Validations for a struct and an inner struct with time.Duration type fields.
  1745  
  1746  	type TimeDurationInner struct {
  1747  		Duration time.Duration
  1748  	}
  1749  	var timeDurationInner *TimeDurationInner
  1750  
  1751  	type TimeDurationTest struct {
  1752  		Inner    *TimeDurationInner
  1753  		Duration time.Duration `validate:"necsfield=Inner.Duration"`
  1754  	}
  1755  	var timeDurationTest *TimeDurationTest
  1756  
  1757  	timeDurationInner = &TimeDurationInner{time.Hour - time.Minute}
  1758  	timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
  1759  	errs = validate.Struct(timeDurationTest)
  1760  	Equal(t, errs, nil)
  1761  
  1762  	timeDurationInner = &TimeDurationInner{time.Hour + time.Minute}
  1763  	timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
  1764  	errs = validate.Struct(timeDurationTest)
  1765  	Equal(t, errs, nil)
  1766  
  1767  	timeDurationInner = &TimeDurationInner{time.Hour}
  1768  	timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
  1769  	errs = validate.Struct(timeDurationTest)
  1770  	NotEqual(t, errs, nil)
  1771  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "necsfield")
  1772  
  1773  	type TimeDurationOmitemptyTest struct {
  1774  		Inner    *TimeDurationInner
  1775  		Duration time.Duration `validate:"omitempty,necsfield=Inner.Duration"`
  1776  	}
  1777  	var timeDurationOmitemptyTest *TimeDurationOmitemptyTest
  1778  
  1779  	timeDurationInner = &TimeDurationInner{time.Duration(0)}
  1780  	timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)}
  1781  	errs = validate.Struct(timeDurationOmitemptyTest)
  1782  	Equal(t, errs, nil)
  1783  }
  1784  
  1785  func TestCrossStructEqFieldValidation(t *testing.T) {
  1786  	var errs error
  1787  	validate := New()
  1788  
  1789  	type Inner struct {
  1790  		CreatedAt *time.Time
  1791  	}
  1792  
  1793  	type Test struct {
  1794  		Inner     *Inner
  1795  		CreatedAt *time.Time `validate:"eqcsfield=Inner.CreatedAt"`
  1796  	}
  1797  
  1798  	now := time.Now().UTC()
  1799  
  1800  	inner := &Inner{
  1801  		CreatedAt: &now,
  1802  	}
  1803  
  1804  	test := &Test{
  1805  		Inner:     inner,
  1806  		CreatedAt: &now,
  1807  	}
  1808  
  1809  	errs = validate.Struct(test)
  1810  	Equal(t, errs, nil)
  1811  
  1812  	newTime := time.Now().Add(time.Hour).UTC()
  1813  	test.CreatedAt = &newTime
  1814  
  1815  	errs = validate.Struct(test)
  1816  	NotEqual(t, errs, nil)
  1817  	AssertError(t, errs, "Test.CreatedAt", "Test.CreatedAt", "CreatedAt", "CreatedAt", "eqcsfield")
  1818  
  1819  	var j uint64
  1820  	var k float64
  1821  	s := "abcd"
  1822  	i := 1
  1823  	j = 1
  1824  	k = 1.543
  1825  	b := true
  1826  	arr := []string{"test"}
  1827  
  1828  	var j2 uint64
  1829  	var k2 float64
  1830  	s2 := "abcd"
  1831  	i2 := 1
  1832  	j2 = 1
  1833  	k2 = 1.543
  1834  	b2 := true
  1835  	arr2 := []string{"test"}
  1836  	arr3 := []string{"test", "test2"}
  1837  	now2 := now
  1838  
  1839  	errs = validate.VarWithValue(s, s2, "eqcsfield")
  1840  	Equal(t, errs, nil)
  1841  
  1842  	errs = validate.VarWithValue(i2, i, "eqcsfield")
  1843  	Equal(t, errs, nil)
  1844  
  1845  	errs = validate.VarWithValue(j2, j, "eqcsfield")
  1846  	Equal(t, errs, nil)
  1847  
  1848  	errs = validate.VarWithValue(k2, k, "eqcsfield")
  1849  	Equal(t, errs, nil)
  1850  
  1851  	errs = validate.VarWithValue(b2, b, "eqcsfield")
  1852  	Equal(t, errs, nil)
  1853  
  1854  	errs = validate.VarWithValue(arr2, arr, "eqcsfield")
  1855  	Equal(t, errs, nil)
  1856  
  1857  	errs = validate.VarWithValue(now2, now, "eqcsfield")
  1858  	Equal(t, errs, nil)
  1859  
  1860  	errs = validate.VarWithValue(arr3, arr, "eqcsfield")
  1861  	NotEqual(t, errs, nil)
  1862  	AssertError(t, errs, "", "", "", "", "eqcsfield")
  1863  
  1864  	type SInner struct {
  1865  		Name string
  1866  	}
  1867  
  1868  	type TStruct struct {
  1869  		Inner     *SInner
  1870  		CreatedAt *time.Time `validate:"eqcsfield=Inner"`
  1871  	}
  1872  
  1873  	sinner := &SInner{
  1874  		Name: "NAME",
  1875  	}
  1876  
  1877  	test2 := &TStruct{
  1878  		Inner:     sinner,
  1879  		CreatedAt: &now,
  1880  	}
  1881  
  1882  	errs = validate.Struct(test2)
  1883  	NotEqual(t, errs, nil)
  1884  	AssertError(t, errs, "TStruct.CreatedAt", "TStruct.CreatedAt", "CreatedAt", "CreatedAt", "eqcsfield")
  1885  
  1886  	test2.Inner = nil
  1887  	errs = validate.Struct(test2)
  1888  	NotEqual(t, errs, nil)
  1889  	AssertError(t, errs, "TStruct.CreatedAt", "TStruct.CreatedAt", "CreatedAt", "CreatedAt", "eqcsfield")
  1890  
  1891  	errs = validate.VarWithValue(nil, 1, "eqcsfield")
  1892  	NotEqual(t, errs, nil)
  1893  	AssertError(t, errs, "", "", "", "", "eqcsfield")
  1894  
  1895  	// Tests for time.Duration type.
  1896  
  1897  	// -- Validations for variables of time.Duration type.
  1898  
  1899  	errs = validate.VarWithValue(time.Hour, time.Hour, "eqcsfield")
  1900  	Equal(t, errs, nil)
  1901  
  1902  	errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "eqcsfield")
  1903  	NotEqual(t, errs, nil)
  1904  	AssertError(t, errs, "", "", "", "", "eqcsfield")
  1905  
  1906  	errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "eqcsfield")
  1907  	NotEqual(t, errs, nil)
  1908  	AssertError(t, errs, "", "", "", "", "eqcsfield")
  1909  
  1910  	errs = validate.VarWithValue(time.Duration(0), time.Hour, "omitempty,eqcsfield")
  1911  	Equal(t, errs, nil)
  1912  
  1913  	// -- Validations for a struct and an inner struct with time.Duration type fields.
  1914  
  1915  	type TimeDurationInner struct {
  1916  		Duration time.Duration
  1917  	}
  1918  	var timeDurationInner *TimeDurationInner
  1919  
  1920  	type TimeDurationTest struct {
  1921  		Inner    *TimeDurationInner
  1922  		Duration time.Duration `validate:"eqcsfield=Inner.Duration"`
  1923  	}
  1924  	var timeDurationTest *TimeDurationTest
  1925  
  1926  	timeDurationInner = &TimeDurationInner{time.Hour}
  1927  	timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
  1928  	errs = validate.Struct(timeDurationTest)
  1929  	Equal(t, errs, nil)
  1930  
  1931  	timeDurationInner = &TimeDurationInner{time.Hour - time.Minute}
  1932  	timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
  1933  	errs = validate.Struct(timeDurationTest)
  1934  	NotEqual(t, errs, nil)
  1935  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "eqcsfield")
  1936  
  1937  	timeDurationInner = &TimeDurationInner{time.Hour + time.Minute}
  1938  	timeDurationTest = &TimeDurationTest{timeDurationInner, time.Hour}
  1939  	errs = validate.Struct(timeDurationTest)
  1940  	NotEqual(t, errs, nil)
  1941  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "eqcsfield")
  1942  
  1943  	type TimeDurationOmitemptyTest struct {
  1944  		Inner    *TimeDurationInner
  1945  		Duration time.Duration `validate:"omitempty,eqcsfield=Inner.Duration"`
  1946  	}
  1947  	var timeDurationOmitemptyTest *TimeDurationOmitemptyTest
  1948  
  1949  	timeDurationInner = &TimeDurationInner{time.Hour}
  1950  	timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)}
  1951  	errs = validate.Struct(timeDurationOmitemptyTest)
  1952  	Equal(t, errs, nil)
  1953  }
  1954  
  1955  func TestCrossNamespaceFieldValidation(t *testing.T) {
  1956  	type SliceStruct struct {
  1957  		Name string
  1958  	}
  1959  
  1960  	type Inner struct {
  1961  		CreatedAt        *time.Time
  1962  		Slice            []string
  1963  		SliceStructs     []*SliceStruct
  1964  		SliceSlice       [][]string
  1965  		SliceSliceStruct [][]*SliceStruct
  1966  		SliceMap         []map[string]string
  1967  		Map              map[string]string
  1968  		MapMap           map[string]map[string]string
  1969  		MapStructs       map[string]*SliceStruct
  1970  		MapMapStruct     map[string]map[string]*SliceStruct
  1971  		MapSlice         map[string][]string
  1972  		MapInt           map[int]string
  1973  		MapInt8          map[int8]string
  1974  		MapInt16         map[int16]string
  1975  		MapInt32         map[int32]string
  1976  		MapInt64         map[int64]string
  1977  		MapUint          map[uint]string
  1978  		MapUint8         map[uint8]string
  1979  		MapUint16        map[uint16]string
  1980  		MapUint32        map[uint32]string
  1981  		MapUint64        map[uint64]string
  1982  		MapFloat32       map[float32]string
  1983  		MapFloat64       map[float64]string
  1984  		MapBool          map[bool]string
  1985  	}
  1986  
  1987  	type Test struct {
  1988  		Inner     *Inner
  1989  		CreatedAt *time.Time
  1990  	}
  1991  
  1992  	now := time.Now()
  1993  
  1994  	inner := &Inner{
  1995  		CreatedAt:        &now,
  1996  		Slice:            []string{"val1", "val2", "val3"},
  1997  		SliceStructs:     []*SliceStruct{{Name: "name1"}, {Name: "name2"}, {Name: "name3"}},
  1998  		SliceSlice:       [][]string{{"1", "2", "3"}, {"4", "5", "6"}, {"7", "8", "9"}},
  1999  		SliceSliceStruct: [][]*SliceStruct{{{Name: "name1"}, {Name: "name2"}, {Name: "name3"}}, {{Name: "name4"}, {Name: "name5"}, {Name: "name6"}}, {{Name: "name7"}, {Name: "name8"}, {Name: "name9"}}},
  2000  		SliceMap:         []map[string]string{{"key1": "val1", "key2": "val2", "key3": "val3"}, {"key4": "val4", "key5": "val5", "key6": "val6"}},
  2001  		Map:              map[string]string{"key1": "val1", "key2": "val2", "key3": "val3"},
  2002  		MapStructs:       map[string]*SliceStruct{"key1": {Name: "name1"}, "key2": {Name: "name2"}, "key3": {Name: "name3"}},
  2003  		MapMap:           map[string]map[string]string{"key1": {"key1-1": "val1"}, "key2": {"key2-1": "val2"}, "key3": {"key3-1": "val3"}},
  2004  		MapMapStruct:     map[string]map[string]*SliceStruct{"key1": {"key1-1": {Name: "name1"}}, "key2": {"key2-1": {Name: "name2"}}, "key3": {"key3-1": {Name: "name3"}}},
  2005  		MapSlice:         map[string][]string{"key1": {"1", "2", "3"}, "key2": {"4", "5", "6"}, "key3": {"7", "8", "9"}},
  2006  		MapInt:           map[int]string{1: "val1", 2: "val2", 3: "val3"},
  2007  		MapInt8:          map[int8]string{1: "val1", 2: "val2", 3: "val3"},
  2008  		MapInt16:         map[int16]string{1: "val1", 2: "val2", 3: "val3"},
  2009  		MapInt32:         map[int32]string{1: "val1", 2: "val2", 3: "val3"},
  2010  		MapInt64:         map[int64]string{1: "val1", 2: "val2", 3: "val3"},
  2011  		MapUint:          map[uint]string{1: "val1", 2: "val2", 3: "val3"},
  2012  		MapUint8:         map[uint8]string{1: "val1", 2: "val2", 3: "val3"},
  2013  		MapUint16:        map[uint16]string{1: "val1", 2: "val2", 3: "val3"},
  2014  		MapUint32:        map[uint32]string{1: "val1", 2: "val2", 3: "val3"},
  2015  		MapUint64:        map[uint64]string{1: "val1", 2: "val2", 3: "val3"},
  2016  		MapFloat32:       map[float32]string{1.01: "val1", 2.02: "val2", 3.03: "val3"},
  2017  		MapFloat64:       map[float64]string{1.01: "val1", 2.02: "val2", 3.03: "val3"},
  2018  		MapBool:          map[bool]string{true: "val1", false: "val2"},
  2019  	}
  2020  
  2021  	test := &Test{
  2022  		Inner:     inner,
  2023  		CreatedAt: &now,
  2024  	}
  2025  
  2026  	val := reflect.ValueOf(test)
  2027  
  2028  	vd := New()
  2029  	v := &validate{
  2030  		v: vd,
  2031  	}
  2032  
  2033  	current, kind, _, ok := v.getStructFieldOKInternal(val, "Inner.CreatedAt")
  2034  	Equal(t, ok, true)
  2035  	Equal(t, kind, reflect.Struct)
  2036  	tm, ok := current.Interface().(time.Time)
  2037  	Equal(t, ok, true)
  2038  	Equal(t, tm, now)
  2039  
  2040  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.Slice[1]")
  2041  	Equal(t, ok, true)
  2042  	Equal(t, kind, reflect.String)
  2043  	Equal(t, current.String(), "val2")
  2044  
  2045  	_, _, _, ok = v.getStructFieldOKInternal(val, "Inner.CrazyNonExistantField")
  2046  	Equal(t, ok, false)
  2047  
  2048  	_, _, _, ok = v.getStructFieldOKInternal(val, "Inner.Slice[101]")
  2049  	Equal(t, ok, false)
  2050  
  2051  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.Map[key3]")
  2052  	Equal(t, ok, true)
  2053  	Equal(t, kind, reflect.String)
  2054  	Equal(t, current.String(), "val3")
  2055  
  2056  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapMap[key2][key2-1]")
  2057  	Equal(t, ok, true)
  2058  	Equal(t, kind, reflect.String)
  2059  	Equal(t, current.String(), "val2")
  2060  
  2061  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapStructs[key2].Name")
  2062  	Equal(t, ok, true)
  2063  	Equal(t, kind, reflect.String)
  2064  	Equal(t, current.String(), "name2")
  2065  
  2066  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapMapStruct[key3][key3-1].Name")
  2067  	Equal(t, ok, true)
  2068  	Equal(t, kind, reflect.String)
  2069  	Equal(t, current.String(), "name3")
  2070  
  2071  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.SliceSlice[2][0]")
  2072  	Equal(t, ok, true)
  2073  	Equal(t, kind, reflect.String)
  2074  	Equal(t, current.String(), "7")
  2075  
  2076  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.SliceSliceStruct[2][1].Name")
  2077  	Equal(t, ok, true)
  2078  	Equal(t, kind, reflect.String)
  2079  	Equal(t, current.String(), "name8")
  2080  
  2081  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.SliceMap[1][key5]")
  2082  	Equal(t, ok, true)
  2083  	Equal(t, kind, reflect.String)
  2084  	Equal(t, current.String(), "val5")
  2085  
  2086  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapSlice[key3][2]")
  2087  	Equal(t, ok, true)
  2088  	Equal(t, kind, reflect.String)
  2089  	Equal(t, current.String(), "9")
  2090  
  2091  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapInt[2]")
  2092  	Equal(t, ok, true)
  2093  	Equal(t, kind, reflect.String)
  2094  	Equal(t, current.String(), "val2")
  2095  
  2096  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapInt8[2]")
  2097  	Equal(t, ok, true)
  2098  	Equal(t, kind, reflect.String)
  2099  	Equal(t, current.String(), "val2")
  2100  
  2101  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapInt16[2]")
  2102  	Equal(t, ok, true)
  2103  	Equal(t, kind, reflect.String)
  2104  	Equal(t, current.String(), "val2")
  2105  
  2106  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapInt32[2]")
  2107  	Equal(t, ok, true)
  2108  	Equal(t, kind, reflect.String)
  2109  	Equal(t, current.String(), "val2")
  2110  
  2111  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapInt64[2]")
  2112  	Equal(t, ok, true)
  2113  	Equal(t, kind, reflect.String)
  2114  	Equal(t, current.String(), "val2")
  2115  
  2116  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapUint[2]")
  2117  	Equal(t, ok, true)
  2118  	Equal(t, kind, reflect.String)
  2119  	Equal(t, current.String(), "val2")
  2120  
  2121  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapUint8[2]")
  2122  	Equal(t, ok, true)
  2123  	Equal(t, kind, reflect.String)
  2124  	Equal(t, current.String(), "val2")
  2125  
  2126  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapUint16[2]")
  2127  	Equal(t, ok, true)
  2128  	Equal(t, kind, reflect.String)
  2129  	Equal(t, current.String(), "val2")
  2130  
  2131  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapUint32[2]")
  2132  	Equal(t, ok, true)
  2133  	Equal(t, kind, reflect.String)
  2134  	Equal(t, current.String(), "val2")
  2135  
  2136  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapUint64[2]")
  2137  	Equal(t, ok, true)
  2138  	Equal(t, kind, reflect.String)
  2139  	Equal(t, current.String(), "val2")
  2140  
  2141  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapFloat32[3.03]")
  2142  	Equal(t, ok, true)
  2143  	Equal(t, kind, reflect.String)
  2144  	Equal(t, current.String(), "val3")
  2145  
  2146  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapFloat64[2.02]")
  2147  	Equal(t, ok, true)
  2148  	Equal(t, kind, reflect.String)
  2149  	Equal(t, current.String(), "val2")
  2150  
  2151  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.MapBool[true]")
  2152  	Equal(t, ok, true)
  2153  	Equal(t, kind, reflect.String)
  2154  	Equal(t, current.String(), "val1")
  2155  
  2156  	inner = &Inner{
  2157  		CreatedAt:        &now,
  2158  		Slice:            []string{"val1", "val2", "val3"},
  2159  		SliceStructs:     []*SliceStruct{{Name: "name1"}, {Name: "name2"}, nil},
  2160  		SliceSlice:       [][]string{{"1", "2", "3"}, {"4", "5", "6"}, {"7", "8", "9"}},
  2161  		SliceSliceStruct: [][]*SliceStruct{{{Name: "name1"}, {Name: "name2"}, {Name: "name3"}}, {{Name: "name4"}, {Name: "name5"}, {Name: "name6"}}, {{Name: "name7"}, {Name: "name8"}, {Name: "name9"}}},
  2162  		SliceMap:         []map[string]string{{"key1": "val1", "key2": "val2", "key3": "val3"}, {"key4": "val4", "key5": "val5", "key6": "val6"}},
  2163  		Map:              map[string]string{"key1": "val1", "key2": "val2", "key3": "val3"},
  2164  		MapStructs:       map[string]*SliceStruct{"key1": {Name: "name1"}, "key2": {Name: "name2"}, "key3": {Name: "name3"}},
  2165  		MapMap:           map[string]map[string]string{"key1": {"key1-1": "val1"}, "key2": {"key2-1": "val2"}, "key3": {"key3-1": "val3"}},
  2166  		MapMapStruct:     map[string]map[string]*SliceStruct{"key1": {"key1-1": {Name: "name1"}}, "key2": {"key2-1": {Name: "name2"}}, "key3": {"key3-1": {Name: "name3"}}},
  2167  		MapSlice:         map[string][]string{"key1": {"1", "2", "3"}, "key2": {"4", "5", "6"}, "key3": {"7", "8", "9"}},
  2168  	}
  2169  
  2170  	test = &Test{
  2171  		Inner:     inner,
  2172  		CreatedAt: nil,
  2173  	}
  2174  
  2175  	val = reflect.ValueOf(test)
  2176  
  2177  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.SliceStructs[2]")
  2178  	Equal(t, ok, true)
  2179  	Equal(t, kind, reflect.Ptr)
  2180  	Equal(t, current.String(), "<*validator.SliceStruct Value>")
  2181  	Equal(t, current.IsNil(), true)
  2182  
  2183  	current, kind, _, ok = v.getStructFieldOKInternal(val, "Inner.SliceStructs[2].Name")
  2184  	Equal(t, ok, false)
  2185  	Equal(t, kind, reflect.Ptr)
  2186  	Equal(t, current.String(), "<*validator.SliceStruct Value>")
  2187  	Equal(t, current.IsNil(), true)
  2188  
  2189  	PanicMatches(t, func() { v.getStructFieldOKInternal(reflect.ValueOf(1), "crazyinput") }, "Invalid field namespace")
  2190  }
  2191  
  2192  func TestExistsValidation(t *testing.T) {
  2193  	jsonText := "{ \"truthiness2\": true }"
  2194  
  2195  	type Thing struct {
  2196  		Truthiness *bool `json:"truthiness" validate:"required"`
  2197  	}
  2198  
  2199  	var ting Thing
  2200  
  2201  	err := json.Unmarshal([]byte(jsonText), &ting)
  2202  	Equal(t, err, nil)
  2203  	NotEqual(t, ting, nil)
  2204  	Equal(t, ting.Truthiness, nil)
  2205  
  2206  	validate := New()
  2207  	errs := validate.Struct(ting)
  2208  	NotEqual(t, errs, nil)
  2209  	AssertError(t, errs, "Thing.Truthiness", "Thing.Truthiness", "Truthiness", "Truthiness", "required")
  2210  
  2211  	jsonText = "{ \"truthiness\": true }"
  2212  
  2213  	err = json.Unmarshal([]byte(jsonText), &ting)
  2214  	Equal(t, err, nil)
  2215  	NotEqual(t, ting, nil)
  2216  	Equal(t, ting.Truthiness, true)
  2217  
  2218  	errs = validate.Struct(ting)
  2219  	Equal(t, errs, nil)
  2220  }
  2221  
  2222  func TestSQLValue2Validation(t *testing.T) {
  2223  	validate := New()
  2224  	validate.RegisterCustomTypeFunc(ValidateValuerType, valuer{}, (*driver.Valuer)(nil), sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{})
  2225  	validate.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{})
  2226  	validate.RegisterCustomTypeFunc(OverrideIntTypeForSomeReason, 1)
  2227  
  2228  	val := valuer{
  2229  		Name: "",
  2230  	}
  2231  
  2232  	errs := validate.Var(val, "required")
  2233  	NotEqual(t, errs, nil)
  2234  	AssertError(t, errs, "", "", "", "", "required")
  2235  
  2236  	val.Name = "Valid Name"
  2237  	errs = validate.VarCtx(context.Background(), val, "required")
  2238  	Equal(t, errs, nil)
  2239  
  2240  	val.Name = "errorme"
  2241  
  2242  	PanicMatches(t, func() { _ = validate.Var(val, "required") }, "SQL Driver Valuer error: some kind of error")
  2243  
  2244  	myVal := valuer{
  2245  		Name: "",
  2246  	}
  2247  
  2248  	errs = validate.Var(myVal, "required")
  2249  	NotEqual(t, errs, nil)
  2250  	AssertError(t, errs, "", "", "", "", "required")
  2251  
  2252  	cust := MadeUpCustomType{
  2253  		FirstName: "Joey",
  2254  		LastName:  "Bloggs",
  2255  	}
  2256  
  2257  	c := CustomMadeUpStruct{MadeUp: cust, OverriddenInt: 2}
  2258  
  2259  	errs = validate.Struct(c)
  2260  	Equal(t, errs, nil)
  2261  
  2262  	c.MadeUp.FirstName = ""
  2263  	c.OverriddenInt = 1
  2264  
  2265  	errs = validate.Struct(c)
  2266  	NotEqual(t, errs, nil)
  2267  	Equal(t, len(errs.(ValidationErrors)), 2)
  2268  	AssertError(t, errs, "CustomMadeUpStruct.MadeUp", "CustomMadeUpStruct.MadeUp", "MadeUp", "MadeUp", "required")
  2269  	AssertError(t, errs, "CustomMadeUpStruct.OverriddenInt", "CustomMadeUpStruct.OverriddenInt", "OverriddenInt", "OverriddenInt", "gt")
  2270  }
  2271  
  2272  func TestSQLValueValidation(t *testing.T) {
  2273  	validate := New()
  2274  	validate.RegisterCustomTypeFunc(ValidateValuerType, (*driver.Valuer)(nil), valuer{})
  2275  	validate.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{})
  2276  	validate.RegisterCustomTypeFunc(OverrideIntTypeForSomeReason, 1)
  2277  
  2278  	val := valuer{
  2279  		Name: "",
  2280  	}
  2281  
  2282  	errs := validate.Var(val, "required")
  2283  	NotEqual(t, errs, nil)
  2284  	AssertError(t, errs, "", "", "", "", "required")
  2285  
  2286  	val.Name = "Valid Name"
  2287  	errs = validate.Var(val, "required")
  2288  	Equal(t, errs, nil)
  2289  
  2290  	val.Name = "errorme"
  2291  
  2292  	PanicMatches(t, func() { errs = validate.Var(val, "required") }, "SQL Driver Valuer error: some kind of error")
  2293  
  2294  	myVal := valuer{
  2295  		Name: "",
  2296  	}
  2297  
  2298  	errs = validate.Var(myVal, "required")
  2299  	NotEqual(t, errs, nil)
  2300  	AssertError(t, errs, "", "", "", "", "required")
  2301  
  2302  	cust := MadeUpCustomType{
  2303  		FirstName: "Joey",
  2304  		LastName:  "Bloggs",
  2305  	}
  2306  
  2307  	c := CustomMadeUpStruct{MadeUp: cust, OverriddenInt: 2}
  2308  
  2309  	errs = validate.Struct(c)
  2310  	Equal(t, errs, nil)
  2311  
  2312  	c.MadeUp.FirstName = ""
  2313  	c.OverriddenInt = 1
  2314  
  2315  	errs = validate.Struct(c)
  2316  	NotEqual(t, errs, nil)
  2317  	Equal(t, len(errs.(ValidationErrors)), 2)
  2318  	AssertError(t, errs, "CustomMadeUpStruct.MadeUp", "CustomMadeUpStruct.MadeUp", "MadeUp", "MadeUp", "required")
  2319  	AssertError(t, errs, "CustomMadeUpStruct.OverriddenInt", "CustomMadeUpStruct.OverriddenInt", "OverriddenInt", "OverriddenInt", "gt")
  2320  
  2321  	// Test for empty field on structs without tags
  2322  	type InvalidValuePanicSafetyTest struct {
  2323  		V valuer
  2324  	}
  2325  	errs = validate.Struct(InvalidValuePanicSafetyTest{})
  2326  	Equal(t, errs, nil)
  2327  }
  2328  
  2329  func TestMACValidation(t *testing.T) {
  2330  	tests := []struct {
  2331  		param    string
  2332  		expected bool
  2333  	}{
  2334  		{"3D:F2:C9:A6:B3:4F", true},
  2335  		{"3D-F2-C9-A6-B3:4F", false},
  2336  		{"123", false},
  2337  		{"", false},
  2338  		{"abacaba", false},
  2339  		{"00:25:96:FF:FE:12:34:56", true},
  2340  		{"0025:96FF:FE12:3456", false},
  2341  	}
  2342  
  2343  	validate := New()
  2344  
  2345  	for i, test := range tests {
  2346  
  2347  		errs := validate.Var(test.param, "mac")
  2348  
  2349  		if test.expected {
  2350  			if !IsEqual(errs, nil) {
  2351  				t.Fatalf("Index: %d mac failed Error: %s", i, errs)
  2352  			}
  2353  		} else {
  2354  			if IsEqual(errs, nil) {
  2355  				t.Fatalf("Index: %d mac failed Error: %s", i, errs)
  2356  			} else {
  2357  				val := getError(errs, "", "")
  2358  				if val.Tag() != "mac" {
  2359  					t.Fatalf("Index: %d mac failed Error: %s", i, errs)
  2360  				}
  2361  			}
  2362  		}
  2363  	}
  2364  }
  2365  
  2366  func TestIPValidation(t *testing.T) {
  2367  	tests := []struct {
  2368  		param    string
  2369  		expected bool
  2370  	}{
  2371  		{"", false},
  2372  		{"10.0.0.1", true},
  2373  		{"172.16.0.1", true},
  2374  		{"192.168.0.1", true},
  2375  		{"192.168.255.254", true},
  2376  		{"192.168.255.256", false},
  2377  		{"172.16.255.254", true},
  2378  		{"172.16.256.255", false},
  2379  		{"2001:cdba:0000:0000:0000:0000:3257:9652", true},
  2380  		{"2001:cdba:0:0:0:0:3257:9652", true},
  2381  		{"2001:cdba::3257:9652", true},
  2382  	}
  2383  
  2384  	validate := New()
  2385  
  2386  	for i, test := range tests {
  2387  
  2388  		errs := validate.Var(test.param, "ip")
  2389  
  2390  		if test.expected {
  2391  			if !IsEqual(errs, nil) {
  2392  				t.Fatalf("Index: %d ip failed Error: %s", i, errs)
  2393  			}
  2394  		} else {
  2395  			if IsEqual(errs, nil) {
  2396  				t.Fatalf("Index: %d ip failed Error: %s", i, errs)
  2397  			} else {
  2398  				val := getError(errs, "", "")
  2399  				if val.Tag() != "ip" {
  2400  					t.Fatalf("Index: %d ip failed Error: %s", i, errs)
  2401  				}
  2402  			}
  2403  		}
  2404  	}
  2405  }
  2406  
  2407  func TestIPv6Validation(t *testing.T) {
  2408  	tests := []struct {
  2409  		param    string
  2410  		expected bool
  2411  	}{
  2412  		{"10.0.0.1", false},
  2413  		{"172.16.0.1", false},
  2414  		{"192.168.0.1", false},
  2415  		{"192.168.255.254", false},
  2416  		{"192.168.255.256", false},
  2417  		{"172.16.255.254", false},
  2418  		{"172.16.256.255", false},
  2419  		{"2001:cdba:0000:0000:0000:0000:3257:9652", true},
  2420  		{"2001:cdba:0:0:0:0:3257:9652", true},
  2421  		{"2001:cdba::3257:9652", true},
  2422  	}
  2423  
  2424  	validate := New()
  2425  
  2426  	for i, test := range tests {
  2427  
  2428  		errs := validate.Var(test.param, "ipv6")
  2429  
  2430  		if test.expected {
  2431  			if !IsEqual(errs, nil) {
  2432  				t.Fatalf("Index: %d ipv6 failed Error: %s", i, errs)
  2433  			}
  2434  		} else {
  2435  			if IsEqual(errs, nil) {
  2436  				t.Fatalf("Index: %d ipv6 failed Error: %s", i, errs)
  2437  			} else {
  2438  				val := getError(errs, "", "")
  2439  				if val.Tag() != "ipv6" {
  2440  					t.Fatalf("Index: %d ipv6 failed Error: %s", i, errs)
  2441  				}
  2442  			}
  2443  		}
  2444  	}
  2445  }
  2446  
  2447  func TestIPv4Validation(t *testing.T) {
  2448  	tests := []struct {
  2449  		param    string
  2450  		expected bool
  2451  	}{
  2452  		{"10.0.0.1", true},
  2453  		{"172.16.0.1", true},
  2454  		{"192.168.0.1", true},
  2455  		{"192.168.255.254", true},
  2456  		{"192.168.255.256", false},
  2457  		{"172.16.255.254", true},
  2458  		{"172.16.256.255", false},
  2459  		{"2001:cdba:0000:0000:0000:0000:3257:9652", false},
  2460  		{"2001:cdba:0:0:0:0:3257:9652", false},
  2461  		{"2001:cdba::3257:9652", false},
  2462  	}
  2463  
  2464  	validate := New()
  2465  
  2466  	for i, test := range tests {
  2467  
  2468  		errs := validate.Var(test.param, "ipv4")
  2469  
  2470  		if test.expected {
  2471  			if !IsEqual(errs, nil) {
  2472  				t.Fatalf("Index: %d ipv4 failed Error: %s", i, errs)
  2473  			}
  2474  		} else {
  2475  			if IsEqual(errs, nil) {
  2476  				t.Fatalf("Index: %d ipv4 failed Error: %s", i, errs)
  2477  			} else {
  2478  				val := getError(errs, "", "")
  2479  				if val.Tag() != "ipv4" {
  2480  					t.Fatalf("Index: %d ipv4 failed Error: %s", i, errs)
  2481  				}
  2482  			}
  2483  		}
  2484  	}
  2485  }
  2486  
  2487  func TestCIDRValidation(t *testing.T) {
  2488  	tests := []struct {
  2489  		param    string
  2490  		expected bool
  2491  	}{
  2492  		{"10.0.0.0/0", true},
  2493  		{"10.0.0.1/8", true},
  2494  		{"172.16.0.1/16", true},
  2495  		{"192.168.0.1/24", true},
  2496  		{"192.168.255.254/24", true},
  2497  		{"192.168.255.254/48", false},
  2498  		{"192.168.255.256/24", false},
  2499  		{"172.16.255.254/16", true},
  2500  		{"172.16.256.255/16", false},
  2501  		{"2001:cdba:0000:0000:0000:0000:3257:9652/64", true},
  2502  		{"2001:cdba:0000:0000:0000:0000:3257:9652/256", false},
  2503  		{"2001:cdba:0:0:0:0:3257:9652/32", true},
  2504  		{"2001:cdba::3257:9652/16", true},
  2505  	}
  2506  
  2507  	validate := New()
  2508  
  2509  	for i, test := range tests {
  2510  
  2511  		errs := validate.Var(test.param, "cidr")
  2512  
  2513  		if test.expected {
  2514  			if !IsEqual(errs, nil) {
  2515  				t.Fatalf("Index: %d cidr failed Error: %s", i, errs)
  2516  			}
  2517  		} else {
  2518  			if IsEqual(errs, nil) {
  2519  				t.Fatalf("Index: %d cidr failed Error: %s", i, errs)
  2520  			} else {
  2521  				val := getError(errs, "", "")
  2522  				if val.Tag() != "cidr" {
  2523  					t.Fatalf("Index: %d cidr failed Error: %s", i, errs)
  2524  				}
  2525  			}
  2526  		}
  2527  	}
  2528  }
  2529  
  2530  func TestCIDRv6Validation(t *testing.T) {
  2531  	tests := []struct {
  2532  		param    string
  2533  		expected bool
  2534  	}{
  2535  		{"10.0.0.0/0", false},
  2536  		{"10.0.0.1/8", false},
  2537  		{"172.16.0.1/16", false},
  2538  		{"192.168.0.1/24", false},
  2539  		{"192.168.255.254/24", false},
  2540  		{"192.168.255.254/48", false},
  2541  		{"192.168.255.256/24", false},
  2542  		{"172.16.255.254/16", false},
  2543  		{"172.16.256.255/16", false},
  2544  		{"2001:cdba:0000:0000:0000:0000:3257:9652/64", true},
  2545  		{"2001:cdba:0000:0000:0000:0000:3257:9652/256", false},
  2546  		{"2001:cdba:0:0:0:0:3257:9652/32", true},
  2547  		{"2001:cdba::3257:9652/16", true},
  2548  	}
  2549  
  2550  	validate := New()
  2551  
  2552  	for i, test := range tests {
  2553  
  2554  		errs := validate.Var(test.param, "cidrv6")
  2555  
  2556  		if test.expected {
  2557  			if !IsEqual(errs, nil) {
  2558  				t.Fatalf("Index: %d cidrv6 failed Error: %s", i, errs)
  2559  			}
  2560  		} else {
  2561  			if IsEqual(errs, nil) {
  2562  				t.Fatalf("Index: %d cidrv6 failed Error: %s", i, errs)
  2563  			} else {
  2564  				val := getError(errs, "", "")
  2565  				if val.Tag() != "cidrv6" {
  2566  					t.Fatalf("Index: %d cidrv6 failed Error: %s", i, errs)
  2567  				}
  2568  			}
  2569  		}
  2570  	}
  2571  }
  2572  
  2573  func TestCIDRv4Validation(t *testing.T) {
  2574  	tests := []struct {
  2575  		param    string
  2576  		expected bool
  2577  	}{
  2578  		{"0.0.0.0/0", true},
  2579  		{"10.0.0.0/0", false},
  2580  		{"10.0.0.0/8", true},
  2581  		{"10.0.0.1/8", false},
  2582  		{"172.16.0.0/16", true},
  2583  		{"172.16.0.1/16", false},
  2584  		{"192.168.0.0/24", true},
  2585  		{"192.168.0.1/24", false},
  2586  		{"192.168.255.0/24", true},
  2587  		{"192.168.255.254/24", false},
  2588  		{"192.168.255.254/48", false},
  2589  		{"192.168.255.256/24", false},
  2590  		{"172.16.0.0/16", true},
  2591  		{"172.16.255.254/16", false},
  2592  		{"172.16.256.255/16", false},
  2593  		{"2001:cdba:0000:0000:0000:0000:3257:9652/64", false},
  2594  		{"2001:cdba:0000:0000:0000:0000:3257:9652/256", false},
  2595  		{"2001:cdba:0:0:0:0:3257:9652/32", false},
  2596  		{"2001:cdba::3257:9652/16", false},
  2597  		{"172.56.1.0/16", false},
  2598  	}
  2599  
  2600  	validate := New()
  2601  
  2602  	for i, test := range tests {
  2603  
  2604  		errs := validate.Var(test.param, "cidrv4")
  2605  
  2606  		if test.expected {
  2607  			if !IsEqual(errs, nil) {
  2608  				t.Fatalf("Index: %d cidrv4 failed Error: %s", i, errs)
  2609  			}
  2610  		} else {
  2611  			if IsEqual(errs, nil) {
  2612  				t.Fatalf("Index: %d cidrv4 failed Error: %s", i, errs)
  2613  			} else {
  2614  				val := getError(errs, "", "")
  2615  				if val.Tag() != "cidrv4" {
  2616  					t.Fatalf("Index: %d cidrv4 failed Error: %s", i, errs)
  2617  				}
  2618  			}
  2619  		}
  2620  	}
  2621  }
  2622  
  2623  func TestTCPAddrValidation(t *testing.T) {
  2624  	tests := []struct {
  2625  		param    string
  2626  		expected bool
  2627  	}{
  2628  		{"", false},
  2629  		{":80", false},
  2630  		{"127.0.0.1:80", true},
  2631  		{"[::1]:80", true},
  2632  		{"256.0.0.0:1", false},
  2633  		{"[::1]", false},
  2634  	}
  2635  
  2636  	validate := New()
  2637  
  2638  	for i, test := range tests {
  2639  		errs := validate.Var(test.param, "tcp_addr")
  2640  		if test.expected {
  2641  			if !IsEqual(errs, nil) {
  2642  				t.Fatalf("Index: %d tcp_addr failed Error: %s", i, errs)
  2643  			}
  2644  		} else {
  2645  			if IsEqual(errs, nil) {
  2646  				t.Fatalf("Index: %d tcp_addr failed Error: %s", i, errs)
  2647  			} else {
  2648  				val := getError(errs, "", "")
  2649  				if val.Tag() != "tcp_addr" {
  2650  					t.Fatalf("Index: %d tcp_addr failed Error: %s", i, errs)
  2651  				}
  2652  			}
  2653  		}
  2654  	}
  2655  }
  2656  
  2657  func TestTCP6AddrValidation(t *testing.T) {
  2658  	tests := []struct {
  2659  		param    string
  2660  		expected bool
  2661  	}{
  2662  		{"", false},
  2663  		{":80", false},
  2664  		{"127.0.0.1:80", false},
  2665  		{"[::1]:80", true},
  2666  		{"256.0.0.0:1", false},
  2667  		{"[::1]", false},
  2668  	}
  2669  
  2670  	validate := New()
  2671  
  2672  	for i, test := range tests {
  2673  		errs := validate.Var(test.param, "tcp6_addr")
  2674  		if test.expected {
  2675  			if !IsEqual(errs, nil) {
  2676  				t.Fatalf("Index: %d tcp6_addr failed Error: %s", i, errs)
  2677  			}
  2678  		} else {
  2679  			if IsEqual(errs, nil) {
  2680  				t.Fatalf("Index: %d tcp6_addr failed Error: %s", i, errs)
  2681  			} else {
  2682  				val := getError(errs, "", "")
  2683  				if val.Tag() != "tcp6_addr" {
  2684  					t.Fatalf("Index: %d tcp6_addr failed Error: %s", i, errs)
  2685  				}
  2686  			}
  2687  		}
  2688  	}
  2689  }
  2690  
  2691  func TestTCP4AddrValidation(t *testing.T) {
  2692  	tests := []struct {
  2693  		param    string
  2694  		expected bool
  2695  	}{
  2696  		{"", false},
  2697  		{":80", false},
  2698  		{"127.0.0.1:80", true},
  2699  		{"[::1]:80", false}, // https://github.com/golang/go/issues/14037
  2700  		{"256.0.0.0:1", false},
  2701  		{"[::1]", false},
  2702  	}
  2703  
  2704  	validate := New()
  2705  
  2706  	for i, test := range tests {
  2707  		errs := validate.Var(test.param, "tcp4_addr")
  2708  		if test.expected {
  2709  			if !IsEqual(errs, nil) {
  2710  				t.Fatalf("Index: %d tcp4_addr failed Error: %s", i, errs)
  2711  			}
  2712  		} else {
  2713  			if IsEqual(errs, nil) {
  2714  				t.Log(test.param, IsEqual(errs, nil))
  2715  				t.Fatalf("Index: %d tcp4_addr failed Error: %s", i, errs)
  2716  			} else {
  2717  				val := getError(errs, "", "")
  2718  				if val.Tag() != "tcp4_addr" {
  2719  					t.Fatalf("Index: %d tcp4_addr failed Error: %s", i, errs)
  2720  				}
  2721  			}
  2722  		}
  2723  	}
  2724  }
  2725  
  2726  func TestUDPAddrValidation(t *testing.T) {
  2727  	tests := []struct {
  2728  		param    string
  2729  		expected bool
  2730  	}{
  2731  		{"", false},
  2732  		{":80", false},
  2733  		{"127.0.0.1:80", true},
  2734  		{"[::1]:80", true},
  2735  		{"256.0.0.0:1", false},
  2736  		{"[::1]", false},
  2737  	}
  2738  
  2739  	validate := New()
  2740  
  2741  	for i, test := range tests {
  2742  		errs := validate.Var(test.param, "udp_addr")
  2743  		if test.expected {
  2744  			if !IsEqual(errs, nil) {
  2745  				t.Fatalf("Index: %d udp_addr failed Error: %s", i, errs)
  2746  			}
  2747  		} else {
  2748  			if IsEqual(errs, nil) {
  2749  				t.Fatalf("Index: %d udp_addr failed Error: %s", i, errs)
  2750  			} else {
  2751  				val := getError(errs, "", "")
  2752  				if val.Tag() != "udp_addr" {
  2753  					t.Fatalf("Index: %d udp_addr failed Error: %s", i, errs)
  2754  				}
  2755  			}
  2756  		}
  2757  	}
  2758  }
  2759  
  2760  func TestUDP6AddrValidation(t *testing.T) {
  2761  	tests := []struct {
  2762  		param    string
  2763  		expected bool
  2764  	}{
  2765  		{"", false},
  2766  		{":80", false},
  2767  		{"127.0.0.1:80", false},
  2768  		{"[::1]:80", true},
  2769  		{"256.0.0.0:1", false},
  2770  		{"[::1]", false},
  2771  	}
  2772  
  2773  	validate := New()
  2774  
  2775  	for i, test := range tests {
  2776  		errs := validate.Var(test.param, "udp6_addr")
  2777  		if test.expected {
  2778  			if !IsEqual(errs, nil) {
  2779  				t.Fatalf("Index: %d udp6_addr failed Error: %s", i, errs)
  2780  			}
  2781  		} else {
  2782  			if IsEqual(errs, nil) {
  2783  				t.Fatalf("Index: %d udp6_addr failed Error: %s", i, errs)
  2784  			} else {
  2785  				val := getError(errs, "", "")
  2786  				if val.Tag() != "udp6_addr" {
  2787  					t.Fatalf("Index: %d udp6_addr failed Error: %s", i, errs)
  2788  				}
  2789  			}
  2790  		}
  2791  	}
  2792  }
  2793  
  2794  func TestUDP4AddrValidation(t *testing.T) {
  2795  	tests := []struct {
  2796  		param    string
  2797  		expected bool
  2798  	}{
  2799  		{"", false},
  2800  		{":80", false},
  2801  		{"127.0.0.1:80", true},
  2802  		{"[::1]:80", false}, // https://github.com/golang/go/issues/14037
  2803  		{"256.0.0.0:1", false},
  2804  		{"[::1]", false},
  2805  	}
  2806  
  2807  	validate := New()
  2808  
  2809  	for i, test := range tests {
  2810  		errs := validate.Var(test.param, "udp4_addr")
  2811  		if test.expected {
  2812  			if !IsEqual(errs, nil) {
  2813  				t.Fatalf("Index: %d udp4_addr failed Error: %s", i, errs)
  2814  			}
  2815  		} else {
  2816  			if IsEqual(errs, nil) {
  2817  				t.Log(test.param, IsEqual(errs, nil))
  2818  				t.Fatalf("Index: %d udp4_addr failed Error: %s", i, errs)
  2819  			} else {
  2820  				val := getError(errs, "", "")
  2821  				if val.Tag() != "udp4_addr" {
  2822  					t.Fatalf("Index: %d udp4_addr failed Error: %s", i, errs)
  2823  				}
  2824  			}
  2825  		}
  2826  	}
  2827  }
  2828  
  2829  func TestIPAddrValidation(t *testing.T) {
  2830  	tests := []struct {
  2831  		param    string
  2832  		expected bool
  2833  	}{
  2834  		{"", false},
  2835  		{"127.0.0.1", true},
  2836  		{"127.0.0.1:80", false},
  2837  		{"::1", true},
  2838  		{"256.0.0.0", false},
  2839  		{"localhost", false},
  2840  	}
  2841  
  2842  	validate := New()
  2843  
  2844  	for i, test := range tests {
  2845  		errs := validate.Var(test.param, "ip_addr")
  2846  		if test.expected {
  2847  			if !IsEqual(errs, nil) {
  2848  				t.Fatalf("Index: %d ip_addr failed Error: %s", i, errs)
  2849  			}
  2850  		} else {
  2851  			if IsEqual(errs, nil) {
  2852  				t.Fatalf("Index: %d ip_addr failed Error: %s", i, errs)
  2853  			} else {
  2854  				val := getError(errs, "", "")
  2855  				if val.Tag() != "ip_addr" {
  2856  					t.Fatalf("Index: %d ip_addr failed Error: %s", i, errs)
  2857  				}
  2858  			}
  2859  		}
  2860  	}
  2861  }
  2862  
  2863  func TestIP6AddrValidation(t *testing.T) {
  2864  	tests := []struct {
  2865  		param    string
  2866  		expected bool
  2867  	}{
  2868  		{"", false},
  2869  		{"127.0.0.1", false}, // https://github.com/golang/go/issues/14037
  2870  		{"127.0.0.1:80", false},
  2871  		{"::1", true},
  2872  		{"0:0:0:0:0:0:0:1", true},
  2873  		{"256.0.0.0", false},
  2874  	}
  2875  
  2876  	validate := New()
  2877  
  2878  	for i, test := range tests {
  2879  		errs := validate.Var(test.param, "ip6_addr")
  2880  		if test.expected {
  2881  			if !IsEqual(errs, nil) {
  2882  				t.Fatalf("Index: %d ip6_addr failed Error: %s", i, errs)
  2883  			}
  2884  		} else {
  2885  			if IsEqual(errs, nil) {
  2886  				t.Fatalf("Index: %d ip6_addr failed Error: %s", i, errs)
  2887  			} else {
  2888  				val := getError(errs, "", "")
  2889  				if val.Tag() != "ip6_addr" {
  2890  					t.Fatalf("Index: %d ip6_addr failed Error: %s", i, errs)
  2891  				}
  2892  			}
  2893  		}
  2894  	}
  2895  }
  2896  
  2897  func TestIP4AddrValidation(t *testing.T) {
  2898  	tests := []struct {
  2899  		param    string
  2900  		expected bool
  2901  	}{
  2902  		{"", false},
  2903  		{"127.0.0.1", true},
  2904  		{"127.0.0.1:80", false},
  2905  		{"::1", false}, // https://github.com/golang/go/issues/14037
  2906  		{"256.0.0.0", false},
  2907  		{"localhost", false},
  2908  	}
  2909  
  2910  	validate := New()
  2911  
  2912  	for i, test := range tests {
  2913  		errs := validate.Var(test.param, "ip4_addr")
  2914  		if test.expected {
  2915  			if !IsEqual(errs, nil) {
  2916  				t.Fatalf("Index: %d ip4_addr failed Error: %s", i, errs)
  2917  			}
  2918  		} else {
  2919  			if IsEqual(errs, nil) {
  2920  				t.Log(test.param, IsEqual(errs, nil))
  2921  				t.Fatalf("Index: %d ip4_addr failed Error: %s", i, errs)
  2922  			} else {
  2923  				val := getError(errs, "", "")
  2924  				if val.Tag() != "ip4_addr" {
  2925  					t.Fatalf("Index: %d ip4_addr failed Error: %s", i, errs)
  2926  				}
  2927  			}
  2928  		}
  2929  	}
  2930  }
  2931  
  2932  func TestUnixAddrValidation(t *testing.T) {
  2933  	tests := []struct {
  2934  		param    string
  2935  		expected bool
  2936  	}{
  2937  		{"", true},
  2938  		{"v.sock", true},
  2939  	}
  2940  
  2941  	validate := New()
  2942  
  2943  	for i, test := range tests {
  2944  		errs := validate.Var(test.param, "unix_addr")
  2945  		if test.expected {
  2946  			if !IsEqual(errs, nil) {
  2947  				t.Fatalf("Index: %d unix_addr failed Error: %s", i, errs)
  2948  			}
  2949  		} else {
  2950  			if IsEqual(errs, nil) {
  2951  				t.Log(test.param, IsEqual(errs, nil))
  2952  				t.Fatalf("Index: %d unix_addr failed Error: %s", i, errs)
  2953  			} else {
  2954  				val := getError(errs, "", "")
  2955  				if val.Tag() != "unix_addr" {
  2956  					t.Fatalf("Index: %d unix_addr failed Error: %s", i, errs)
  2957  				}
  2958  			}
  2959  		}
  2960  	}
  2961  }
  2962  
  2963  func TestSliceMapArrayChanFuncPtrInterfaceRequiredValidation(t *testing.T) {
  2964  	validate := New()
  2965  
  2966  	var m map[string]string
  2967  
  2968  	errs := validate.Var(m, "required")
  2969  	NotEqual(t, errs, nil)
  2970  	AssertError(t, errs, "", "", "", "", "required")
  2971  
  2972  	m = map[string]string{}
  2973  	errs = validate.Var(m, "required")
  2974  	Equal(t, errs, nil)
  2975  
  2976  	var arr [5]string
  2977  	errs = validate.Var(arr, "required")
  2978  	NotEqual(t, errs, nil)
  2979  	AssertError(t, errs, "", "", "", "", "required")
  2980  
  2981  	arr[0] = "ok"
  2982  	errs = validate.Var(arr, "required")
  2983  	Equal(t, errs, nil)
  2984  
  2985  	var s []string
  2986  	errs = validate.Var(s, "required")
  2987  	NotEqual(t, errs, nil)
  2988  	AssertError(t, errs, "", "", "", "", "required")
  2989  
  2990  	s = []string{}
  2991  	errs = validate.Var(s, "required")
  2992  	Equal(t, errs, nil)
  2993  
  2994  	var c chan string
  2995  	errs = validate.Var(c, "required")
  2996  	NotEqual(t, errs, nil)
  2997  	AssertError(t, errs, "", "", "", "", "required")
  2998  
  2999  	c = make(chan string)
  3000  	errs = validate.Var(c, "required")
  3001  	Equal(t, errs, nil)
  3002  
  3003  	var tst *int
  3004  	errs = validate.Var(tst, "required")
  3005  	NotEqual(t, errs, nil)
  3006  	AssertError(t, errs, "", "", "", "", "required")
  3007  
  3008  	one := 1
  3009  	tst = &one
  3010  	errs = validate.Var(tst, "required")
  3011  	Equal(t, errs, nil)
  3012  
  3013  	var iface interface{}
  3014  
  3015  	errs = validate.Var(iface, "required")
  3016  	NotEqual(t, errs, nil)
  3017  	AssertError(t, errs, "", "", "", "", "required")
  3018  
  3019  	errs = validate.Var(iface, "omitempty,required")
  3020  	Equal(t, errs, nil)
  3021  
  3022  	errs = validate.Var(iface, "")
  3023  	Equal(t, errs, nil)
  3024  
  3025  	errs = validate.VarWithValue(nil, iface, "")
  3026  	Equal(t, errs, nil)
  3027  
  3028  	var f func(string)
  3029  
  3030  	errs = validate.Var(f, "required")
  3031  	NotEqual(t, errs, nil)
  3032  	AssertError(t, errs, "", "", "", "", "required")
  3033  
  3034  	f = func(name string) {}
  3035  
  3036  	errs = validate.Var(f, "required")
  3037  	Equal(t, errs, nil)
  3038  }
  3039  
  3040  func TestDatePtrValidationIssueValidation(t *testing.T) {
  3041  	type Test struct {
  3042  		LastViewed *time.Time
  3043  		Reminder   *time.Time
  3044  	}
  3045  
  3046  	test := &Test{}
  3047  
  3048  	validate := New()
  3049  	errs := validate.Struct(test)
  3050  	Equal(t, errs, nil)
  3051  }
  3052  
  3053  func TestCommaAndPipeObfuscationValidation(t *testing.T) {
  3054  	s := "My Name Is, |joeybloggs|"
  3055  
  3056  	validate := New()
  3057  
  3058  	errs := validate.Var(s, "excludesall=0x2C")
  3059  	NotEqual(t, errs, nil)
  3060  	AssertError(t, errs, "", "", "", "", "excludesall")
  3061  
  3062  	errs = validate.Var(s, "excludesall=0x7C")
  3063  	NotEqual(t, errs, nil)
  3064  	AssertError(t, errs, "", "", "", "", "excludesall")
  3065  }
  3066  
  3067  func TestBadKeyValidation(t *testing.T) {
  3068  	type Test struct {
  3069  		Name string `validate:"required, "`
  3070  	}
  3071  
  3072  	tst := &Test{
  3073  		Name: "test",
  3074  	}
  3075  
  3076  	validate := New()
  3077  
  3078  	PanicMatches(t, func() { _ = validate.Struct(tst) }, "Undefined validation function ' ' on field 'Name'")
  3079  
  3080  	type Test2 struct {
  3081  		Name string `validate:"required,,len=2"`
  3082  	}
  3083  
  3084  	tst2 := &Test2{
  3085  		Name: "test",
  3086  	}
  3087  
  3088  	PanicMatches(t, func() { _ = validate.Struct(tst2) }, "Invalid validation tag on field 'Name'")
  3089  }
  3090  
  3091  func TestInterfaceErrValidation(t *testing.T) {
  3092  	var v2 interface{} = 1
  3093  	var v1 interface{} = v2
  3094  
  3095  	validate := New()
  3096  	errs := validate.Var(v1, "len=1")
  3097  	Equal(t, errs, nil)
  3098  
  3099  	errs = validate.Var(v2, "len=1")
  3100  	Equal(t, errs, nil)
  3101  
  3102  	type ExternalCMD struct {
  3103  		Userid string      `json:"userid"`
  3104  		Action uint32      `json:"action"`
  3105  		Data   interface{} `json:"data,omitempty" validate:"required"`
  3106  	}
  3107  
  3108  	s := &ExternalCMD{
  3109  		Userid: "123456",
  3110  		Action: 10000,
  3111  		// Data:   1,
  3112  	}
  3113  
  3114  	errs = validate.Struct(s)
  3115  	NotEqual(t, errs, nil)
  3116  	Equal(t, len(errs.(ValidationErrors)), 1)
  3117  	AssertError(t, errs, "ExternalCMD.Data", "ExternalCMD.Data", "Data", "Data", "required")
  3118  
  3119  	type ExternalCMD2 struct {
  3120  		Userid string      `json:"userid"`
  3121  		Action uint32      `json:"action"`
  3122  		Data   interface{} `json:"data,omitempty" validate:"len=1"`
  3123  	}
  3124  
  3125  	s2 := &ExternalCMD2{
  3126  		Userid: "123456",
  3127  		Action: 10000,
  3128  		// Data:   1,
  3129  	}
  3130  
  3131  	errs = validate.Struct(s2)
  3132  	NotEqual(t, errs, nil)
  3133  	Equal(t, len(errs.(ValidationErrors)), 1)
  3134  	AssertError(t, errs, "ExternalCMD2.Data", "ExternalCMD2.Data", "Data", "Data", "len")
  3135  
  3136  	s3 := &ExternalCMD2{
  3137  		Userid: "123456",
  3138  		Action: 10000,
  3139  		Data:   2,
  3140  	}
  3141  
  3142  	errs = validate.Struct(s3)
  3143  	NotEqual(t, errs, nil)
  3144  	Equal(t, len(errs.(ValidationErrors)), 1)
  3145  	AssertError(t, errs, "ExternalCMD2.Data", "ExternalCMD2.Data", "Data", "Data", "len")
  3146  
  3147  	type Inner struct {
  3148  		Name string `validate:"required"`
  3149  	}
  3150  
  3151  	inner := &Inner{
  3152  		Name: "",
  3153  	}
  3154  
  3155  	s4 := &ExternalCMD{
  3156  		Userid: "123456",
  3157  		Action: 10000,
  3158  		Data:   inner,
  3159  	}
  3160  
  3161  	errs = validate.Struct(s4)
  3162  	NotEqual(t, errs, nil)
  3163  	Equal(t, len(errs.(ValidationErrors)), 1)
  3164  	AssertError(t, errs, "ExternalCMD.Data.Name", "ExternalCMD.Data.Name", "Name", "Name", "required")
  3165  
  3166  	type TestMapStructPtr struct {
  3167  		Errs map[int]interface{} `validate:"gt=0,dive,required"`
  3168  	}
  3169  
  3170  	mip := map[int]interface{}{0: &Inner{"ok"}, 3: nil, 4: &Inner{"ok"}}
  3171  
  3172  	msp := &TestMapStructPtr{
  3173  		Errs: mip,
  3174  	}
  3175  
  3176  	errs = validate.Struct(msp)
  3177  	NotEqual(t, errs, nil)
  3178  	Equal(t, len(errs.(ValidationErrors)), 1)
  3179  	AssertError(t, errs, "TestMapStructPtr.Errs[3]", "TestMapStructPtr.Errs[3]", "Errs[3]", "Errs[3]", "required")
  3180  
  3181  	type TestMultiDimensionalStructs struct {
  3182  		Errs [][]interface{} `validate:"gt=0,dive,dive"`
  3183  	}
  3184  
  3185  	var errStructArray [][]interface{}
  3186  
  3187  	errStructArray = append(errStructArray, []interface{}{&Inner{"ok"}, &Inner{""}, &Inner{""}})
  3188  	errStructArray = append(errStructArray, []interface{}{&Inner{"ok"}, &Inner{""}, &Inner{""}})
  3189  
  3190  	tms := &TestMultiDimensionalStructs{
  3191  		Errs: errStructArray,
  3192  	}
  3193  
  3194  	errs = validate.Struct(tms)
  3195  	NotEqual(t, errs, nil)
  3196  	Equal(t, len(errs.(ValidationErrors)), 4)
  3197  	AssertError(t, errs, "TestMultiDimensionalStructs.Errs[0][1].Name", "TestMultiDimensionalStructs.Errs[0][1].Name", "Name", "Name", "required")
  3198  	AssertError(t, errs, "TestMultiDimensionalStructs.Errs[0][2].Name", "TestMultiDimensionalStructs.Errs[0][2].Name", "Name", "Name", "required")
  3199  	AssertError(t, errs, "TestMultiDimensionalStructs.Errs[1][1].Name", "TestMultiDimensionalStructs.Errs[1][1].Name", "Name", "Name", "required")
  3200  	AssertError(t, errs, "TestMultiDimensionalStructs.Errs[1][2].Name", "TestMultiDimensionalStructs.Errs[1][2].Name", "Name", "Name", "required")
  3201  
  3202  	type TestMultiDimensionalStructsPtr2 struct {
  3203  		Errs [][]*Inner `validate:"gt=0,dive,dive,required"`
  3204  	}
  3205  
  3206  	var errStructPtr2Array [][]*Inner
  3207  
  3208  	errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, {""}})
  3209  	errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, {""}})
  3210  	errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, nil})
  3211  
  3212  	tmsp2 := &TestMultiDimensionalStructsPtr2{
  3213  		Errs: errStructPtr2Array,
  3214  	}
  3215  
  3216  	errs = validate.Struct(tmsp2)
  3217  	NotEqual(t, errs, nil)
  3218  	Equal(t, len(errs.(ValidationErrors)), 6)
  3219  	AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[0][1].Name", "TestMultiDimensionalStructsPtr2.Errs[0][1].Name", "Name", "Name", "required")
  3220  	AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[0][2].Name", "TestMultiDimensionalStructsPtr2.Errs[0][2].Name", "Name", "Name", "required")
  3221  	AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[1][1].Name", "TestMultiDimensionalStructsPtr2.Errs[1][1].Name", "Name", "Name", "required")
  3222  	AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[1][2].Name", "TestMultiDimensionalStructsPtr2.Errs[1][2].Name", "Name", "Name", "required")
  3223  	AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[2][1].Name", "TestMultiDimensionalStructsPtr2.Errs[2][1].Name", "Name", "Name", "required")
  3224  	AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[2][2]", "TestMultiDimensionalStructsPtr2.Errs[2][2]", "Errs[2][2]", "Errs[2][2]", "required")
  3225  
  3226  	m := map[int]interface{}{0: "ok", 3: "", 4: "ok"}
  3227  
  3228  	errs = validate.Var(m, "len=3,dive,len=2")
  3229  	NotEqual(t, errs, nil)
  3230  	Equal(t, len(errs.(ValidationErrors)), 1)
  3231  	AssertError(t, errs, "[3]", "[3]", "[3]", "[3]", "len")
  3232  
  3233  	errs = validate.Var(m, "len=2,dive,required")
  3234  	NotEqual(t, errs, nil)
  3235  	Equal(t, len(errs.(ValidationErrors)), 1)
  3236  	AssertError(t, errs, "", "", "", "", "len")
  3237  
  3238  	arr := []interface{}{"ok", "", "ok"}
  3239  
  3240  	errs = validate.Var(arr, "len=3,dive,len=2")
  3241  	NotEqual(t, errs, nil)
  3242  	Equal(t, len(errs.(ValidationErrors)), 1)
  3243  	AssertError(t, errs, "[1]", "[1]", "[1]", "[1]", "len")
  3244  
  3245  	errs = validate.Var(arr, "len=2,dive,required")
  3246  	NotEqual(t, errs, nil)
  3247  	Equal(t, len(errs.(ValidationErrors)), 1)
  3248  	AssertError(t, errs, "", "", "", "", "len")
  3249  
  3250  	type MyStruct struct {
  3251  		A, B string
  3252  		C    interface{}
  3253  	}
  3254  
  3255  	var a MyStruct
  3256  
  3257  	a.A = "value"
  3258  	a.C = "nu"
  3259  
  3260  	errs = validate.Struct(a)
  3261  	Equal(t, errs, nil)
  3262  }
  3263  
  3264  func TestMapDiveValidation(t *testing.T) {
  3265  	validate := New()
  3266  
  3267  	n := map[int]interface{}{0: nil}
  3268  	errs := validate.Var(n, "omitempty,required")
  3269  	Equal(t, errs, nil)
  3270  
  3271  	m := map[int]string{0: "ok", 3: "", 4: "ok"}
  3272  
  3273  	errs = validate.Var(m, "len=3,dive,required")
  3274  	NotEqual(t, errs, nil)
  3275  	Equal(t, len(errs.(ValidationErrors)), 1)
  3276  	AssertError(t, errs, "[3]", "[3]", "[3]", "[3]", "required")
  3277  
  3278  	errs = validate.Var(m, "len=2,dive,required")
  3279  	NotEqual(t, errs, nil)
  3280  	Equal(t, len(errs.(ValidationErrors)), 1)
  3281  	AssertError(t, errs, "", "", "", "", "len")
  3282  
  3283  	type Inner struct {
  3284  		Name string `validate:"required"`
  3285  	}
  3286  
  3287  	type TestMapStruct struct {
  3288  		Errs map[int]Inner `validate:"gt=0,dive"`
  3289  	}
  3290  
  3291  	mi := map[int]Inner{0: {"ok"}, 3: {""}, 4: {"ok"}}
  3292  
  3293  	ms := &TestMapStruct{
  3294  		Errs: mi,
  3295  	}
  3296  
  3297  	errs = validate.Struct(ms)
  3298  	NotEqual(t, errs, nil)
  3299  	Equal(t, len(errs.(ValidationErrors)), 1)
  3300  	AssertError(t, errs, "TestMapStruct.Errs[3].Name", "TestMapStruct.Errs[3].Name", "Name", "Name", "required")
  3301  
  3302  	// for full test coverage
  3303  	s := fmt.Sprint(errs.Error())
  3304  	NotEqual(t, s, "")
  3305  
  3306  	type TestMapInterface struct {
  3307  		Errs map[int]interface{} `validate:"dive"`
  3308  	}
  3309  
  3310  	mit := map[int]interface{}{0: Inner{"ok"}, 1: Inner{""}, 3: nil, 5: "string", 6: 33}
  3311  
  3312  	msi := &TestMapInterface{
  3313  		Errs: mit,
  3314  	}
  3315  
  3316  	errs = validate.Struct(msi)
  3317  	NotEqual(t, errs, nil)
  3318  	Equal(t, len(errs.(ValidationErrors)), 1)
  3319  	AssertError(t, errs, "TestMapInterface.Errs[1].Name", "TestMapInterface.Errs[1].Name", "Name", "Name", "required")
  3320  
  3321  	type TestMapTimeStruct struct {
  3322  		Errs map[int]*time.Time `validate:"gt=0,dive,required"`
  3323  	}
  3324  
  3325  	t1 := time.Now().UTC()
  3326  
  3327  	mta := map[int]*time.Time{0: &t1, 3: nil, 4: nil}
  3328  
  3329  	mt := &TestMapTimeStruct{
  3330  		Errs: mta,
  3331  	}
  3332  
  3333  	errs = validate.Struct(mt)
  3334  	NotEqual(t, errs, nil)
  3335  	Equal(t, len(errs.(ValidationErrors)), 2)
  3336  	AssertError(t, errs, "TestMapTimeStruct.Errs[3]", "TestMapTimeStruct.Errs[3]", "Errs[3]", "Errs[3]", "required")
  3337  	AssertError(t, errs, "TestMapTimeStruct.Errs[4]", "TestMapTimeStruct.Errs[4]", "Errs[4]", "Errs[4]", "required")
  3338  
  3339  	type TestMapStructPtr struct {
  3340  		Errs map[int]*Inner `validate:"gt=0,dive,required"`
  3341  	}
  3342  
  3343  	mip := map[int]*Inner{0: {"ok"}, 3: nil, 4: {"ok"}}
  3344  
  3345  	msp := &TestMapStructPtr{
  3346  		Errs: mip,
  3347  	}
  3348  
  3349  	errs = validate.Struct(msp)
  3350  	NotEqual(t, errs, nil)
  3351  	Equal(t, len(errs.(ValidationErrors)), 1)
  3352  	AssertError(t, errs, "TestMapStructPtr.Errs[3]", "TestMapStructPtr.Errs[3]", "Errs[3]", "Errs[3]", "required")
  3353  
  3354  	type TestMapStructPtr2 struct {
  3355  		Errs map[int]*Inner `validate:"gt=0,dive,omitempty,required"`
  3356  	}
  3357  
  3358  	mip2 := map[int]*Inner{0: {"ok"}, 3: nil, 4: {"ok"}}
  3359  
  3360  	msp2 := &TestMapStructPtr2{
  3361  		Errs: mip2,
  3362  	}
  3363  
  3364  	errs = validate.Struct(msp2)
  3365  	Equal(t, errs, nil)
  3366  
  3367  	v2 := New()
  3368  	v2.RegisterTagNameFunc(func(fld reflect.StructField) string {
  3369  		name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
  3370  
  3371  		if name == "-" {
  3372  			return ""
  3373  		}
  3374  
  3375  		return name
  3376  	})
  3377  
  3378  	type MapDiveJSONTest struct {
  3379  		Map map[string]string `validate:"required,gte=1,dive,gte=1" json:"MyName"`
  3380  	}
  3381  
  3382  	mdjt := &MapDiveJSONTest{
  3383  		Map: map[string]string{
  3384  			"Key1": "Value1",
  3385  			"Key2": "",
  3386  		},
  3387  	}
  3388  
  3389  	err := v2.Struct(mdjt)
  3390  	NotEqual(t, err, nil)
  3391  
  3392  	errs = err.(ValidationErrors)
  3393  	fe := getError(errs, "MapDiveJSONTest.MyName[Key2]", "MapDiveJSONTest.Map[Key2]")
  3394  	NotEqual(t, fe, nil)
  3395  	Equal(t, fe.Tag(), "gte")
  3396  	Equal(t, fe.ActualTag(), "gte")
  3397  	Equal(t, fe.Field(), "MyName[Key2]")
  3398  	Equal(t, fe.StructField(), "Map[Key2]")
  3399  }
  3400  
  3401  func TestArrayDiveValidation(t *testing.T) {
  3402  	validate := New()
  3403  
  3404  	arr := []string{"ok", "", "ok"}
  3405  
  3406  	errs := validate.Var(arr, "len=3,dive,required")
  3407  	NotEqual(t, errs, nil)
  3408  	Equal(t, len(errs.(ValidationErrors)), 1)
  3409  	AssertError(t, errs, "[1]", "[1]", "[1]", "[1]", "required")
  3410  
  3411  	errs = validate.Var(arr, "len=2,dive,required")
  3412  	NotEqual(t, errs, nil)
  3413  	Equal(t, len(errs.(ValidationErrors)), 1)
  3414  	AssertError(t, errs, "", "", "", "", "len")
  3415  
  3416  	type BadDive struct {
  3417  		Name string `validate:"dive"`
  3418  	}
  3419  
  3420  	bd := &BadDive{
  3421  		Name: "TEST",
  3422  	}
  3423  
  3424  	PanicMatches(t, func() { _ = validate.Struct(bd) }, "dive error! can't dive on a non slice or map")
  3425  
  3426  	type Test struct {
  3427  		Errs []string `validate:"gt=0,dive,required"`
  3428  	}
  3429  
  3430  	test := &Test{
  3431  		Errs: []string{"ok", "", "ok"},
  3432  	}
  3433  
  3434  	errs = validate.Struct(test)
  3435  	NotEqual(t, errs, nil)
  3436  	Equal(t, len(errs.(ValidationErrors)), 1)
  3437  	AssertError(t, errs, "Test.Errs[1]", "Test.Errs[1]", "Errs[1]", "Errs[1]", "required")
  3438  
  3439  	test = &Test{
  3440  		Errs: []string{"ok", "ok", ""},
  3441  	}
  3442  
  3443  	errs = validate.Struct(test)
  3444  	NotEqual(t, errs, nil)
  3445  	Equal(t, len(errs.(ValidationErrors)), 1)
  3446  	AssertError(t, errs, "Test.Errs[2]", "Test.Errs[2]", "Errs[2]", "Errs[2]", "required")
  3447  
  3448  	type TestMultiDimensional struct {
  3449  		Errs [][]string `validate:"gt=0,dive,dive,required"`
  3450  	}
  3451  
  3452  	var errArray [][]string
  3453  
  3454  	errArray = append(errArray, []string{"ok", "", ""})
  3455  	errArray = append(errArray, []string{"ok", "", ""})
  3456  
  3457  	tm := &TestMultiDimensional{
  3458  		Errs: errArray,
  3459  	}
  3460  
  3461  	errs = validate.Struct(tm)
  3462  	NotEqual(t, errs, nil)
  3463  	Equal(t, len(errs.(ValidationErrors)), 4)
  3464  	AssertError(t, errs, "TestMultiDimensional.Errs[0][1]", "TestMultiDimensional.Errs[0][1]", "Errs[0][1]", "Errs[0][1]", "required")
  3465  	AssertError(t, errs, "TestMultiDimensional.Errs[0][2]", "TestMultiDimensional.Errs[0][2]", "Errs[0][2]", "Errs[0][2]", "required")
  3466  	AssertError(t, errs, "TestMultiDimensional.Errs[1][1]", "TestMultiDimensional.Errs[1][1]", "Errs[1][1]", "Errs[1][1]", "required")
  3467  	AssertError(t, errs, "TestMultiDimensional.Errs[1][2]", "TestMultiDimensional.Errs[1][2]", "Errs[1][2]", "Errs[1][2]", "required")
  3468  
  3469  	type Inner struct {
  3470  		Name string `validate:"required"`
  3471  	}
  3472  
  3473  	type TestMultiDimensionalStructs struct {
  3474  		Errs [][]Inner `validate:"gt=0,dive,dive"`
  3475  	}
  3476  
  3477  	var errStructArray [][]Inner
  3478  
  3479  	errStructArray = append(errStructArray, []Inner{{"ok"}, {""}, {""}})
  3480  	errStructArray = append(errStructArray, []Inner{{"ok"}, {""}, {""}})
  3481  
  3482  	tms := &TestMultiDimensionalStructs{
  3483  		Errs: errStructArray,
  3484  	}
  3485  
  3486  	errs = validate.Struct(tms)
  3487  	NotEqual(t, errs, nil)
  3488  	Equal(t, len(errs.(ValidationErrors)), 4)
  3489  	AssertError(t, errs, "TestMultiDimensionalStructs.Errs[0][1].Name", "TestMultiDimensionalStructs.Errs[0][1].Name", "Name", "Name", "required")
  3490  	AssertError(t, errs, "TestMultiDimensionalStructs.Errs[0][2].Name", "TestMultiDimensionalStructs.Errs[0][2].Name", "Name", "Name", "required")
  3491  	AssertError(t, errs, "TestMultiDimensionalStructs.Errs[1][1].Name", "TestMultiDimensionalStructs.Errs[1][1].Name", "Name", "Name", "required")
  3492  	AssertError(t, errs, "TestMultiDimensionalStructs.Errs[1][2].Name", "TestMultiDimensionalStructs.Errs[1][2].Name", "Name", "Name", "required")
  3493  
  3494  	type TestMultiDimensionalStructsPtr struct {
  3495  		Errs [][]*Inner `validate:"gt=0,dive,dive"`
  3496  	}
  3497  
  3498  	var errStructPtrArray [][]*Inner
  3499  
  3500  	errStructPtrArray = append(errStructPtrArray, []*Inner{{"ok"}, {""}, {""}})
  3501  	errStructPtrArray = append(errStructPtrArray, []*Inner{{"ok"}, {""}, {""}})
  3502  	errStructPtrArray = append(errStructPtrArray, []*Inner{{"ok"}, {""}, nil})
  3503  
  3504  	tmsp := &TestMultiDimensionalStructsPtr{
  3505  		Errs: errStructPtrArray,
  3506  	}
  3507  
  3508  	errs = validate.Struct(tmsp)
  3509  	NotEqual(t, errs, nil)
  3510  	Equal(t, len(errs.(ValidationErrors)), 5)
  3511  	AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[0][1].Name", "TestMultiDimensionalStructsPtr.Errs[0][1].Name", "Name", "Name", "required")
  3512  	AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[0][2].Name", "TestMultiDimensionalStructsPtr.Errs[0][2].Name", "Name", "Name", "required")
  3513  	AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[1][1].Name", "TestMultiDimensionalStructsPtr.Errs[1][1].Name", "Name", "Name", "required")
  3514  	AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[1][2].Name", "TestMultiDimensionalStructsPtr.Errs[1][2].Name", "Name", "Name", "required")
  3515  	AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[2][1].Name", "TestMultiDimensionalStructsPtr.Errs[2][1].Name", "Name", "Name", "required")
  3516  
  3517  	// for full test coverage
  3518  	s := fmt.Sprint(errs.Error())
  3519  	NotEqual(t, s, "")
  3520  
  3521  	type TestMultiDimensionalStructsPtr2 struct {
  3522  		Errs [][]*Inner `validate:"gt=0,dive,dive,required"`
  3523  	}
  3524  
  3525  	var errStructPtr2Array [][]*Inner
  3526  
  3527  	errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, {""}})
  3528  	errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, {""}})
  3529  	errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, nil})
  3530  
  3531  	tmsp2 := &TestMultiDimensionalStructsPtr2{
  3532  		Errs: errStructPtr2Array,
  3533  	}
  3534  
  3535  	errs = validate.Struct(tmsp2)
  3536  	NotEqual(t, errs, nil)
  3537  	Equal(t, len(errs.(ValidationErrors)), 6)
  3538  	AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[0][1].Name", "TestMultiDimensionalStructsPtr2.Errs[0][1].Name", "Name", "Name", "required")
  3539  	AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[0][2].Name", "TestMultiDimensionalStructsPtr2.Errs[0][2].Name", "Name", "Name", "required")
  3540  	AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[1][1].Name", "TestMultiDimensionalStructsPtr2.Errs[1][1].Name", "Name", "Name", "required")
  3541  	AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[1][2].Name", "TestMultiDimensionalStructsPtr2.Errs[1][2].Name", "Name", "Name", "required")
  3542  	AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[2][1].Name", "TestMultiDimensionalStructsPtr2.Errs[2][1].Name", "Name", "Name", "required")
  3543  	AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[2][2]", "TestMultiDimensionalStructsPtr2.Errs[2][2]", "Errs[2][2]", "Errs[2][2]", "required")
  3544  
  3545  	type TestMultiDimensionalStructsPtr3 struct {
  3546  		Errs [][]*Inner `validate:"gt=0,dive,dive,omitempty"`
  3547  	}
  3548  
  3549  	var errStructPtr3Array [][]*Inner
  3550  
  3551  	errStructPtr3Array = append(errStructPtr3Array, []*Inner{{"ok"}, {""}, {""}})
  3552  	errStructPtr3Array = append(errStructPtr3Array, []*Inner{{"ok"}, {""}, {""}})
  3553  	errStructPtr3Array = append(errStructPtr3Array, []*Inner{{"ok"}, {""}, nil})
  3554  
  3555  	tmsp3 := &TestMultiDimensionalStructsPtr3{
  3556  		Errs: errStructPtr3Array,
  3557  	}
  3558  
  3559  	errs = validate.Struct(tmsp3)
  3560  	NotEqual(t, errs, nil)
  3561  	Equal(t, len(errs.(ValidationErrors)), 5)
  3562  	AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[0][1].Name", "TestMultiDimensionalStructsPtr3.Errs[0][1].Name", "Name", "Name", "required")
  3563  	AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[0][2].Name", "TestMultiDimensionalStructsPtr3.Errs[0][2].Name", "Name", "Name", "required")
  3564  	AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[1][1].Name", "TestMultiDimensionalStructsPtr3.Errs[1][1].Name", "Name", "Name", "required")
  3565  	AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[1][2].Name", "TestMultiDimensionalStructsPtr3.Errs[1][2].Name", "Name", "Name", "required")
  3566  	AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[2][1].Name", "TestMultiDimensionalStructsPtr3.Errs[2][1].Name", "Name", "Name", "required")
  3567  
  3568  	type TestMultiDimensionalTimeTime struct {
  3569  		Errs [][]*time.Time `validate:"gt=0,dive,dive,required"`
  3570  	}
  3571  
  3572  	var errTimePtr3Array [][]*time.Time
  3573  
  3574  	t1 := time.Now().UTC()
  3575  	t2 := time.Now().UTC()
  3576  	t3 := time.Now().UTC().Add(time.Hour * 24)
  3577  
  3578  	errTimePtr3Array = append(errTimePtr3Array, []*time.Time{&t1, &t2, &t3})
  3579  	errTimePtr3Array = append(errTimePtr3Array, []*time.Time{&t1, &t2, nil})
  3580  	errTimePtr3Array = append(errTimePtr3Array, []*time.Time{&t1, nil, nil})
  3581  
  3582  	tmtp3 := &TestMultiDimensionalTimeTime{
  3583  		Errs: errTimePtr3Array,
  3584  	}
  3585  
  3586  	errs = validate.Struct(tmtp3)
  3587  	NotEqual(t, errs, nil)
  3588  	Equal(t, len(errs.(ValidationErrors)), 3)
  3589  	AssertError(t, errs, "TestMultiDimensionalTimeTime.Errs[1][2]", "TestMultiDimensionalTimeTime.Errs[1][2]", "Errs[1][2]", "Errs[1][2]", "required")
  3590  	AssertError(t, errs, "TestMultiDimensionalTimeTime.Errs[2][1]", "TestMultiDimensionalTimeTime.Errs[2][1]", "Errs[2][1]", "Errs[2][1]", "required")
  3591  	AssertError(t, errs, "TestMultiDimensionalTimeTime.Errs[2][2]", "TestMultiDimensionalTimeTime.Errs[2][2]", "Errs[2][2]", "Errs[2][2]", "required")
  3592  
  3593  	type TestMultiDimensionalTimeTime2 struct {
  3594  		Errs [][]*time.Time `validate:"gt=0,dive,dive,required"`
  3595  	}
  3596  
  3597  	var errTimeArray [][]*time.Time
  3598  
  3599  	t1 = time.Now().UTC()
  3600  	t2 = time.Now().UTC()
  3601  	t3 = time.Now().UTC().Add(time.Hour * 24)
  3602  
  3603  	errTimeArray = append(errTimeArray, []*time.Time{&t1, &t2, &t3})
  3604  	errTimeArray = append(errTimeArray, []*time.Time{&t1, &t2, nil})
  3605  	errTimeArray = append(errTimeArray, []*time.Time{&t1, nil, nil})
  3606  
  3607  	tmtp := &TestMultiDimensionalTimeTime2{
  3608  		Errs: errTimeArray,
  3609  	}
  3610  
  3611  	errs = validate.Struct(tmtp)
  3612  	NotEqual(t, errs, nil)
  3613  	Equal(t, len(errs.(ValidationErrors)), 3)
  3614  	AssertError(t, errs, "TestMultiDimensionalTimeTime2.Errs[1][2]", "TestMultiDimensionalTimeTime2.Errs[1][2]", "Errs[1][2]", "Errs[1][2]", "required")
  3615  	AssertError(t, errs, "TestMultiDimensionalTimeTime2.Errs[2][1]", "TestMultiDimensionalTimeTime2.Errs[2][1]", "Errs[2][1]", "Errs[2][1]", "required")
  3616  	AssertError(t, errs, "TestMultiDimensionalTimeTime2.Errs[2][2]", "TestMultiDimensionalTimeTime2.Errs[2][2]", "Errs[2][2]", "Errs[2][2]", "required")
  3617  }
  3618  
  3619  func TestNilStructPointerValidation(t *testing.T) {
  3620  	type Inner struct {
  3621  		Data string
  3622  	}
  3623  
  3624  	type Outer struct {
  3625  		Inner *Inner `validate:"omitempty"`
  3626  	}
  3627  
  3628  	inner := &Inner{
  3629  		Data: "test",
  3630  	}
  3631  
  3632  	outer := &Outer{
  3633  		Inner: inner,
  3634  	}
  3635  
  3636  	validate := New()
  3637  	errs := validate.Struct(outer)
  3638  	Equal(t, errs, nil)
  3639  
  3640  	outer = &Outer{
  3641  		Inner: nil,
  3642  	}
  3643  
  3644  	errs = validate.Struct(outer)
  3645  	Equal(t, errs, nil)
  3646  
  3647  	type Inner2 struct {
  3648  		Data string
  3649  	}
  3650  
  3651  	type Outer2 struct {
  3652  		Inner2 *Inner2 `validate:"required"`
  3653  	}
  3654  
  3655  	inner2 := &Inner2{
  3656  		Data: "test",
  3657  	}
  3658  
  3659  	outer2 := &Outer2{
  3660  		Inner2: inner2,
  3661  	}
  3662  
  3663  	errs = validate.Struct(outer2)
  3664  	Equal(t, errs, nil)
  3665  
  3666  	outer2 = &Outer2{
  3667  		Inner2: nil,
  3668  	}
  3669  
  3670  	errs = validate.Struct(outer2)
  3671  	NotEqual(t, errs, nil)
  3672  	AssertError(t, errs, "Outer2.Inner2", "Outer2.Inner2", "Inner2", "Inner2", "required")
  3673  
  3674  	type Inner3 struct {
  3675  		Data string
  3676  	}
  3677  
  3678  	type Outer3 struct {
  3679  		Inner3 *Inner3
  3680  	}
  3681  
  3682  	inner3 := &Inner3{
  3683  		Data: "test",
  3684  	}
  3685  
  3686  	outer3 := &Outer3{
  3687  		Inner3: inner3,
  3688  	}
  3689  
  3690  	errs = validate.Struct(outer3)
  3691  	Equal(t, errs, nil)
  3692  
  3693  	type Inner4 struct {
  3694  		Data string
  3695  	}
  3696  
  3697  	type Outer4 struct {
  3698  		Inner4 *Inner4 `validate:"-"`
  3699  	}
  3700  
  3701  	inner4 := &Inner4{
  3702  		Data: "test",
  3703  	}
  3704  
  3705  	outer4 := &Outer4{
  3706  		Inner4: inner4,
  3707  	}
  3708  
  3709  	errs = validate.Struct(outer4)
  3710  	Equal(t, errs, nil)
  3711  }
  3712  
  3713  func TestSSNValidation(t *testing.T) {
  3714  	tests := []struct {
  3715  		param    string
  3716  		expected bool
  3717  	}{
  3718  		{"", false},
  3719  		{"00-90-8787", false},
  3720  		{"66690-76", false},
  3721  		{"191 60 2869", true},
  3722  		{"191-60-2869", true},
  3723  	}
  3724  
  3725  	validate := New()
  3726  
  3727  	for i, test := range tests {
  3728  
  3729  		errs := validate.Var(test.param, "ssn")
  3730  
  3731  		if test.expected {
  3732  			if !IsEqual(errs, nil) {
  3733  				t.Fatalf("Index: %d SSN failed Error: %s", i, errs)
  3734  			}
  3735  		} else {
  3736  			if IsEqual(errs, nil) {
  3737  				t.Fatalf("Index: %d SSN failed Error: %s", i, errs)
  3738  			} else {
  3739  				val := getError(errs, "", "")
  3740  				if val.Tag() != "ssn" {
  3741  					t.Fatalf("Index: %d Latitude failed Error: %s", i, errs)
  3742  				}
  3743  			}
  3744  		}
  3745  	}
  3746  }
  3747  
  3748  func TestLongitudeValidation(t *testing.T) {
  3749  	tests := []struct {
  3750  		param    interface{}
  3751  		expected bool
  3752  	}{
  3753  		{"", false},
  3754  		{"-180.000", true},
  3755  		{"180.1", false},
  3756  		{"+73.234", true},
  3757  		{"+382.3811", false},
  3758  		{"23.11111111", true},
  3759  		{uint(180), true},
  3760  		{float32(-180.0), true},
  3761  		{-180, true},
  3762  		{180.1, false},
  3763  	}
  3764  
  3765  	validate := New()
  3766  
  3767  	for i, test := range tests {
  3768  
  3769  		errs := validate.Var(test.param, "longitude")
  3770  
  3771  		if test.expected {
  3772  			if !IsEqual(errs, nil) {
  3773  				t.Fatalf("Index: %d Longitude failed Error: %s", i, errs)
  3774  			}
  3775  		} else {
  3776  			if IsEqual(errs, nil) {
  3777  				t.Fatalf("Index: %d Longitude failed Error: %s", i, errs)
  3778  			} else {
  3779  				val := getError(errs, "", "")
  3780  				if val.Tag() != "longitude" {
  3781  					t.Fatalf("Index: %d Longitude failed Error: %s", i, errs)
  3782  				}
  3783  			}
  3784  		}
  3785  	}
  3786  
  3787  	PanicMatches(t, func() { _ = validate.Var(true, "longitude") }, "Bad field type bool")
  3788  }
  3789  
  3790  func TestLatitudeValidation(t *testing.T) {
  3791  	tests := []struct {
  3792  		param    interface{}
  3793  		expected bool
  3794  	}{
  3795  		{"", false},
  3796  		{"-90.000", true},
  3797  		{"+90", true},
  3798  		{"47.1231231", true},
  3799  		{"+99.9", false},
  3800  		{"108", false},
  3801  		{uint(90), true},
  3802  		{float32(-90.0), true},
  3803  		{-90, true},
  3804  		{90.1, false},
  3805  	}
  3806  
  3807  	validate := New()
  3808  
  3809  	for i, test := range tests {
  3810  
  3811  		errs := validate.Var(test.param, "latitude")
  3812  
  3813  		if test.expected {
  3814  			if !IsEqual(errs, nil) {
  3815  				t.Fatalf("Index: %d Latitude failed Error: %s", i, errs)
  3816  			}
  3817  		} else {
  3818  			if IsEqual(errs, nil) {
  3819  				t.Fatalf("Index: %d Latitude failed Error: %s", i, errs)
  3820  			} else {
  3821  				val := getError(errs, "", "")
  3822  				if val.Tag() != "latitude" {
  3823  					t.Fatalf("Index: %d Latitude failed Error: %s", i, errs)
  3824  				}
  3825  			}
  3826  		}
  3827  	}
  3828  
  3829  	PanicMatches(t, func() { _ = validate.Var(true, "latitude") }, "Bad field type bool")
  3830  }
  3831  
  3832  func TestDataURIValidation(t *testing.T) {
  3833  	tests := []struct {
  3834  		param    string
  3835  		expected bool
  3836  	}{
  3837  		{"data:image/png;base64,TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4=", true},
  3838  		{"data:text/plain;base64,Vml2YW11cyBmZXJtZW50dW0gc2VtcGVyIHBvcnRhLg==", true},
  3839  		{"image/gif;base64,U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", false},
  3840  		{
  3841  			"data:image/gif;base64,MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuMPNS1Ufof9EW/M98FNw" +
  3842  				"UAKrwflsqVxaxQjBQnHQmiI7Vac40t8x7pIb8gLGV6wL7sBTJiPovJ0V7y7oc0Ye" +
  3843  				"rhKh0Rm4skP2z/jHwwZICgGzBvA0rH8xlhUiTvcwDCJ0kc+fh35hNt8srZQM4619" +
  3844  				"FTgB66Xmp4EtVyhpQV+t02g6NzK72oZI0vnAvqhpkxLeLiMCyrI416wHm5Tkukhx" +
  3845  				"QmcL2a6hNOyu0ixX/x2kSFXApEnVrJ+/IxGyfyw8kf4N2IZpW5nEP847lpfj0SZZ" +
  3846  				"Fwrd1mnfnDbYohX2zRptLy2ZUn06Qo9pkG5ntvFEPo9bfZeULtjYzIl6K8gJ2uGZ" + "HQIDAQAB", true,
  3847  		},
  3848  		{"data:image/png;base64,12345", false},
  3849  		{"", false},
  3850  		{"data:text,:;base85,U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", false},
  3851  		{"data:image/jpeg;key=value;base64,UEsDBBQAAAAI", true},
  3852  		{"data:image/jpeg;key=value,UEsDBBQAAAAI", true},
  3853  		{"data:;base64;sdfgsdfgsdfasdfa=s,UEsDBBQAAAAI", true},
  3854  		{"data:,UEsDBBQAAAAI", true},
  3855  	}
  3856  
  3857  	validate := New()
  3858  
  3859  	for i, test := range tests {
  3860  		errs := validate.Var(test.param, "datauri")
  3861  
  3862  		if test.expected {
  3863  			if !IsEqual(errs, nil) {
  3864  				t.Fatalf("Index: %d DataURI failed Error: %s", i, errs)
  3865  			}
  3866  		} else {
  3867  			if IsEqual(errs, nil) {
  3868  				t.Fatalf("Index: %d DataURI failed Error: %s", i, errs)
  3869  			} else {
  3870  				val := getError(errs, "", "")
  3871  				if val.Tag() != "datauri" {
  3872  					t.Fatalf("Index: %d DataURI failed Error: %s", i, errs)
  3873  				}
  3874  			}
  3875  		}
  3876  	}
  3877  }
  3878  
  3879  func TestMultibyteValidation(t *testing.T) {
  3880  	tests := []struct {
  3881  		param    string
  3882  		expected bool
  3883  	}{
  3884  		{"", true},
  3885  		{"abc", false},
  3886  		{"123", false},
  3887  		{"<>@;.-=", false},
  3888  		{"ひらがな・カタカナ、.漢字", true},
  3889  		{"あいうえお foobar", true},
  3890  		{"test@example.com", true},
  3891  		{"test@example.com", true},
  3892  		{"1234abcDExyz", true},
  3893  		{"カタカナ", true},
  3894  	}
  3895  
  3896  	validate := New()
  3897  
  3898  	for i, test := range tests {
  3899  
  3900  		errs := validate.Var(test.param, "multibyte")
  3901  
  3902  		if test.expected {
  3903  			if !IsEqual(errs, nil) {
  3904  				t.Fatalf("Index: %d Multibyte failed Error: %s", i, errs)
  3905  			}
  3906  		} else {
  3907  			if IsEqual(errs, nil) {
  3908  				t.Fatalf("Index: %d Multibyte failed Error: %s", i, errs)
  3909  			} else {
  3910  				val := getError(errs, "", "")
  3911  				if val.Tag() != "multibyte" {
  3912  					t.Fatalf("Index: %d Multibyte failed Error: %s", i, errs)
  3913  				}
  3914  			}
  3915  		}
  3916  	}
  3917  }
  3918  
  3919  func TestPrintableASCIIValidation(t *testing.T) {
  3920  	tests := []struct {
  3921  		param    string
  3922  		expected bool
  3923  	}{
  3924  		{"", true},
  3925  		{"foobar", false},
  3926  		{"xyz098", false},
  3927  		{"123456", false},
  3928  		{"カタカナ", false},
  3929  		{"foobar", true},
  3930  		{"0987654321", true},
  3931  		{"test@example.com", true},
  3932  		{"1234abcDEF", true},
  3933  		{"newline\n", false},
  3934  		{"\x19test\x7F", false},
  3935  	}
  3936  
  3937  	validate := New()
  3938  
  3939  	for i, test := range tests {
  3940  
  3941  		errs := validate.Var(test.param, "printascii")
  3942  
  3943  		if test.expected {
  3944  			if !IsEqual(errs, nil) {
  3945  				t.Fatalf("Index: %d Printable ASCII failed Error: %s", i, errs)
  3946  			}
  3947  		} else {
  3948  			if IsEqual(errs, nil) {
  3949  				t.Fatalf("Index: %d Printable ASCII failed Error: %s", i, errs)
  3950  			} else {
  3951  				val := getError(errs, "", "")
  3952  				if val.Tag() != "printascii" {
  3953  					t.Fatalf("Index: %d Printable ASCII failed Error: %s", i, errs)
  3954  				}
  3955  			}
  3956  		}
  3957  	}
  3958  }
  3959  
  3960  func TestASCIIValidation(t *testing.T) {
  3961  	tests := []struct {
  3962  		param    string
  3963  		expected bool
  3964  	}{
  3965  		{"", true},
  3966  		{"foobar", false},
  3967  		{"xyz098", false},
  3968  		{"123456", false},
  3969  		{"カタカナ", false},
  3970  		{"foobar", true},
  3971  		{"0987654321", true},
  3972  		{"test@example.com", true},
  3973  		{"1234abcDEF", true},
  3974  		{"", true},
  3975  	}
  3976  
  3977  	validate := New()
  3978  
  3979  	for i, test := range tests {
  3980  
  3981  		errs := validate.Var(test.param, "ascii")
  3982  
  3983  		if test.expected {
  3984  			if !IsEqual(errs, nil) {
  3985  				t.Fatalf("Index: %d ASCII failed Error: %s", i, errs)
  3986  			}
  3987  		} else {
  3988  			if IsEqual(errs, nil) {
  3989  				t.Fatalf("Index: %d ASCII failed Error: %s", i, errs)
  3990  			} else {
  3991  				val := getError(errs, "", "")
  3992  				if val.Tag() != "ascii" {
  3993  					t.Fatalf("Index: %d ASCII failed Error: %s", i, errs)
  3994  				}
  3995  			}
  3996  		}
  3997  	}
  3998  }
  3999  
  4000  func TestUUID5Validation(t *testing.T) {
  4001  	tests := []struct {
  4002  		param    string
  4003  		expected bool
  4004  	}{
  4005  
  4006  		{"", false},
  4007  		{"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
  4008  		{"9c858901-8a57-4791-81fe-4c455b099bc9", false},
  4009  		{"a987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
  4010  		{"987fbc97-4bed-5078-af07-9141ba07c9f3", true},
  4011  		{"987fbc97-4bed-5078-9f07-9141ba07c9f3", true},
  4012  	}
  4013  
  4014  	validate := New()
  4015  
  4016  	for i, test := range tests {
  4017  
  4018  		errs := validate.Var(test.param, "uuid5")
  4019  
  4020  		if test.expected {
  4021  			if !IsEqual(errs, nil) {
  4022  				t.Fatalf("Index: %d UUID5 failed Error: %s", i, errs)
  4023  			}
  4024  		} else {
  4025  			if IsEqual(errs, nil) {
  4026  				t.Fatalf("Index: %d UUID5 failed Error: %s", i, errs)
  4027  			} else {
  4028  				val := getError(errs, "", "")
  4029  				if val.Tag() != "uuid5" {
  4030  					t.Fatalf("Index: %d UUID5 failed Error: %s", i, errs)
  4031  				}
  4032  			}
  4033  		}
  4034  	}
  4035  }
  4036  
  4037  func TestUUID4Validation(t *testing.T) {
  4038  	tests := []struct {
  4039  		param    string
  4040  		expected bool
  4041  	}{
  4042  		{"", false},
  4043  		{"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
  4044  		{"a987fbc9-4bed-5078-af07-9141ba07c9f3", false},
  4045  		{"934859", false},
  4046  		{"57b73598-8764-4ad0-a76a-679bb6640eb1", true},
  4047  		{"625e63f3-58f5-40b7-83a1-a72ad31acffb", true},
  4048  	}
  4049  
  4050  	validate := New()
  4051  
  4052  	for i, test := range tests {
  4053  
  4054  		errs := validate.Var(test.param, "uuid4")
  4055  
  4056  		if test.expected {
  4057  			if !IsEqual(errs, nil) {
  4058  				t.Fatalf("Index: %d UUID4 failed Error: %s", i, errs)
  4059  			}
  4060  		} else {
  4061  			if IsEqual(errs, nil) {
  4062  				t.Fatalf("Index: %d UUID4 failed Error: %s", i, errs)
  4063  			} else {
  4064  				val := getError(errs, "", "")
  4065  				if val.Tag() != "uuid4" {
  4066  					t.Fatalf("Index: %d UUID4 failed Error: %s", i, errs)
  4067  				}
  4068  			}
  4069  		}
  4070  	}
  4071  }
  4072  
  4073  func TestUUID3Validation(t *testing.T) {
  4074  	tests := []struct {
  4075  		param    string
  4076  		expected bool
  4077  	}{
  4078  		{"", false},
  4079  		{"412452646", false},
  4080  		{"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
  4081  		{"a987fbc9-4bed-4078-8f07-9141ba07c9f3", false},
  4082  		{"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true},
  4083  	}
  4084  
  4085  	validate := New()
  4086  
  4087  	for i, test := range tests {
  4088  
  4089  		errs := validate.Var(test.param, "uuid3")
  4090  
  4091  		if test.expected {
  4092  			if !IsEqual(errs, nil) {
  4093  				t.Fatalf("Index: %d UUID3 failed Error: %s", i, errs)
  4094  			}
  4095  		} else {
  4096  			if IsEqual(errs, nil) {
  4097  				t.Fatalf("Index: %d UUID3 failed Error: %s", i, errs)
  4098  			} else {
  4099  				val := getError(errs, "", "")
  4100  				if val.Tag() != "uuid3" {
  4101  					t.Fatalf("Index: %d UUID3 failed Error: %s", i, errs)
  4102  				}
  4103  			}
  4104  		}
  4105  	}
  4106  }
  4107  
  4108  type uuidTestType struct {
  4109  	val string
  4110  }
  4111  
  4112  func (u uuidTestType) String() string {
  4113  	return u.val
  4114  }
  4115  
  4116  type uuidAlias string
  4117  
  4118  func (u uuidAlias) String() string {
  4119  	return "This is a UUID " + string(u)
  4120  }
  4121  
  4122  var _ fmt.Stringer = uuidTestType{}
  4123  var _ fmt.Stringer = uuidAlias("")
  4124  
  4125  func TestUUIDValidation(t *testing.T) {
  4126  	tests := []struct {
  4127  		param    string
  4128  		expected bool
  4129  	}{
  4130  		{"", false},
  4131  		{"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
  4132  		{"a987fbc9-4bed-3078-cf07-9141ba07c9f3xxx", false},
  4133  		{"a987fbc94bed3078cf079141ba07c9f3", false},
  4134  		{"934859", false},
  4135  		{"987fbc9-4bed-3078-cf07a-9141ba07c9f3", false},
  4136  		{"aaaaaaaa-1111-1111-aaag-111111111111", false},
  4137  		{"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true},
  4138  	}
  4139  
  4140  	validate := New()
  4141  
  4142  	for i, test := range tests {
  4143  
  4144  		errs := validate.Var(test.param, "uuid")
  4145  
  4146  		if test.expected {
  4147  			if !IsEqual(errs, nil) {
  4148  				t.Fatalf("Index: %d UUID failed Error: %s", i, errs)
  4149  			}
  4150  		} else {
  4151  			if IsEqual(errs, nil) {
  4152  				t.Fatalf("Index: %d UUID failed Error: %s", i, errs)
  4153  			} else {
  4154  				val := getError(errs, "", "")
  4155  				if val.Tag() != "uuid" {
  4156  					t.Fatalf("Index: %d UUID failed Error: %s", i, errs)
  4157  				}
  4158  			}
  4159  		}
  4160  	}
  4161  
  4162  	// Test UUID validation on uuid structs type that implements Stringer interface.
  4163  	structWithValidUUID := struct {
  4164  		UUID uuidTestType `validate:"uuid"`
  4165  	}{
  4166  		UUID: uuidTestType{val: "a987fbc9-4bed-3078-cf07-9141ba07c9f3"},
  4167  	}
  4168  	structWithInvalidUUID := struct {
  4169  		UUID uuidTestType `validate:"uuid"`
  4170  	}{
  4171  		UUID: uuidTestType{val: "934859"},
  4172  	}
  4173  
  4174  	if err := validate.Struct(structWithValidUUID); err != nil {
  4175  		t.Fatalf("UUID failed Error: %s", err)
  4176  	}
  4177  	if err := validate.Struct(structWithInvalidUUID); err == nil {
  4178  		t.Fatal("UUID failed Error expected but received nil")
  4179  	}
  4180  
  4181  	// Test on Alias type with Stringer interface.
  4182  	alias := uuidAlias("a987fbc9-4bed-3078-cf07-9141ba07c9f3")
  4183  	if err := validate.Var(alias, "uuid"); err != nil {
  4184  		t.Fatalf("UUID failed Error: %s", err)
  4185  	}
  4186  }
  4187  
  4188  func TestUUID5RFC4122Validation(t *testing.T) {
  4189  	tests := []struct {
  4190  		param    string
  4191  		expected bool
  4192  	}{
  4193  
  4194  		{"", false},
  4195  		{"xxxa987Fbc9-4bed-3078-cf07-9141ba07c9f3", false},
  4196  		{"9c858901-8a57-4791-81Fe-4c455b099bc9", false},
  4197  		{"a987Fbc9-4bed-3078-cf07-9141ba07c9f3", false},
  4198  		{"987Fbc97-4bed-5078-af07-9141ba07c9f3", true},
  4199  		{"987Fbc97-4bed-5078-9f07-9141ba07c9f3", true},
  4200  	}
  4201  
  4202  	validate := New()
  4203  
  4204  	for i, test := range tests {
  4205  
  4206  		errs := validate.Var(test.param, "uuid5_rfc4122")
  4207  
  4208  		if test.expected {
  4209  			if !IsEqual(errs, nil) {
  4210  				t.Fatalf("Index: %d UUID5RFC4122 failed Error: %s", i, errs)
  4211  			}
  4212  		} else {
  4213  			if IsEqual(errs, nil) {
  4214  				t.Fatalf("Index: %d UUID5RFC4122 failed Error: %s", i, errs)
  4215  			} else {
  4216  				val := getError(errs, "", "")
  4217  				if val.Tag() != "uuid5_rfc4122" {
  4218  					t.Fatalf("Index: %d UUID5RFC4122 failed Error: %s", i, errs)
  4219  				}
  4220  			}
  4221  		}
  4222  	}
  4223  }
  4224  
  4225  func TestUUID4RFC4122Validation(t *testing.T) {
  4226  	tests := []struct {
  4227  		param    string
  4228  		expected bool
  4229  	}{
  4230  		{"", false},
  4231  		{"xxxa987fbc9-4bed-3078-cf07-9141ba07c9F3", false},
  4232  		{"a987fbc9-4bed-5078-af07-9141ba07c9F3", false},
  4233  		{"934859", false},
  4234  		{"57b73598-8764-4ad0-a76A-679bb6640eb1", true},
  4235  		{"625e63f3-58f5-40b7-83a1-a72ad31acFfb", true},
  4236  	}
  4237  
  4238  	validate := New()
  4239  
  4240  	for i, test := range tests {
  4241  
  4242  		errs := validate.Var(test.param, "uuid4_rfc4122")
  4243  
  4244  		if test.expected {
  4245  			if !IsEqual(errs, nil) {
  4246  				t.Fatalf("Index: %d UUID4RFC4122 failed Error: %s", i, errs)
  4247  			}
  4248  		} else {
  4249  			if IsEqual(errs, nil) {
  4250  				t.Fatalf("Index: %d UUID4RFC4122 failed Error: %s", i, errs)
  4251  			} else {
  4252  				val := getError(errs, "", "")
  4253  				if val.Tag() != "uuid4_rfc4122" {
  4254  					t.Fatalf("Index: %d UUID4RFC4122 failed Error: %s", i, errs)
  4255  				}
  4256  			}
  4257  		}
  4258  	}
  4259  }
  4260  
  4261  func TestUUID3RFC4122Validation(t *testing.T) {
  4262  	tests := []struct {
  4263  		param    string
  4264  		expected bool
  4265  	}{
  4266  		{"", false},
  4267  		{"412452646", false},
  4268  		{"xxxa987fbc9-4bed-3078-cf07-9141ba07c9F3", false},
  4269  		{"a987fbc9-4bed-4078-8f07-9141ba07c9F3", false},
  4270  		{"a987fbc9-4bed-3078-cf07-9141ba07c9F3", true},
  4271  	}
  4272  
  4273  	validate := New()
  4274  
  4275  	for i, test := range tests {
  4276  
  4277  		errs := validate.Var(test.param, "uuid3_rfc4122")
  4278  
  4279  		if test.expected {
  4280  			if !IsEqual(errs, nil) {
  4281  				t.Fatalf("Index: %d UUID3RFC4122 failed Error: %s", i, errs)
  4282  			}
  4283  		} else {
  4284  			if IsEqual(errs, nil) {
  4285  				t.Fatalf("Index: %d UUID3RFC4122 failed Error: %s", i, errs)
  4286  			} else {
  4287  				val := getError(errs, "", "")
  4288  				if val.Tag() != "uuid3_rfc4122" {
  4289  					t.Fatalf("Index: %d UUID3RFC4122 failed Error: %s", i, errs)
  4290  				}
  4291  			}
  4292  		}
  4293  	}
  4294  }
  4295  
  4296  func TestUUIDRFC4122Validation(t *testing.T) {
  4297  	tests := []struct {
  4298  		param    string
  4299  		expected bool
  4300  	}{
  4301  		{"", false},
  4302  		{"xxxa987Fbc9-4bed-3078-cf07-9141ba07c9f3", false},
  4303  		{"a987Fbc9-4bed-3078-cf07-9141ba07c9f3xxx", false},
  4304  		{"a987Fbc94bed3078cf079141ba07c9f3", false},
  4305  		{"934859", false},
  4306  		{"987fbc9-4bed-3078-cf07a-9141ba07c9F3", false},
  4307  		{"aaaaaaaa-1111-1111-aaaG-111111111111", false},
  4308  		{"a987Fbc9-4bed-3078-cf07-9141ba07c9f3", true},
  4309  	}
  4310  
  4311  	validate := New()
  4312  
  4313  	for i, test := range tests {
  4314  
  4315  		errs := validate.Var(test.param, "uuid_rfc4122")
  4316  
  4317  		if test.expected {
  4318  			if !IsEqual(errs, nil) {
  4319  				t.Fatalf("Index: %d UUIDRFC4122 failed Error: %s", i, errs)
  4320  			}
  4321  		} else {
  4322  			if IsEqual(errs, nil) {
  4323  				t.Fatalf("Index: %d UUIDRFC4122 failed Error: %s", i, errs)
  4324  			} else {
  4325  				val := getError(errs, "", "")
  4326  				if val.Tag() != "uuid_rfc4122" {
  4327  					t.Fatalf("Index: %d UUIDRFC4122 failed Error: %s", i, errs)
  4328  				}
  4329  			}
  4330  		}
  4331  	}
  4332  }
  4333  
  4334  func TestULIDValidation(t *testing.T) {
  4335  	tests := []struct {
  4336  		param    string
  4337  		expected bool
  4338  	}{
  4339  		{"", false},
  4340  		{"01BX5ZZKBKACT-V9WEVGEMMVRZ", false},
  4341  		{"01bx5zzkbkactav9wevgemmvrz", false},
  4342  		{"a987Fbc9-4bed-3078-cf07-9141ba07c9f3xxx", false},
  4343  		{"01BX5ZZKBKACTAV9WEVGEMMVRZABC", false},
  4344  		{"01BX5ZZKBKACTAV9WEVGEMMVRZABC", false},
  4345  		{"0IBX5ZZKBKACTAV9WEVGEMMVRZ", false},
  4346  		{"O1BX5ZZKBKACTAV9WEVGEMMVRZ", false},
  4347  		{"01BX5ZZKBKACTAVLWEVGEMMVRZ", false},
  4348  		{"01BX5ZZKBKACTAV9WEVGEMMVRZ", true},
  4349  	}
  4350  
  4351  	validate := New()
  4352  
  4353  	for i, test := range tests {
  4354  
  4355  		errs := validate.Var(test.param, "ulid")
  4356  
  4357  		if test.expected {
  4358  			if !IsEqual(errs, nil) {
  4359  				t.Fatalf("Index: %d ULID failed Error: %s", i, errs)
  4360  			}
  4361  		} else {
  4362  			if IsEqual(errs, nil) {
  4363  				t.Fatalf("Index: %d ULID failed Error: %s", i, errs)
  4364  			} else {
  4365  				val := getError(errs, "", "")
  4366  				if val.Tag() != "ulid" {
  4367  					t.Fatalf("Index: %d ULID failed Error: %s", i, errs)
  4368  				}
  4369  			}
  4370  		}
  4371  	}
  4372  }
  4373  
  4374  func TestMD4Validation(t *testing.T) {
  4375  	tests := []struct {
  4376  		param    string
  4377  		expected bool
  4378  	}{
  4379  		{"", false},
  4380  		{"6f5902ac237024bdd0c176cb93063dc4", true},
  4381  		{"6f5902ac237024bdd0c176cb93063dc-", false},
  4382  		{"6f5902ac237024bdd0c176cb93063dc41", false},
  4383  		{"6f5902ac237024bdd0c176cb93063dcC", false},
  4384  		{"6f5902ac237024bdd0c176cb93063dc", false},
  4385  	}
  4386  
  4387  	validate := New()
  4388  
  4389  	for i, test := range tests {
  4390  
  4391  		errs := validate.Var(test.param, "md4")
  4392  
  4393  		if test.expected {
  4394  			if !IsEqual(errs, nil) {
  4395  				t.Fatalf("Index: %d MD4 failed Error: %s", i, errs)
  4396  			}
  4397  		} else {
  4398  			if IsEqual(errs, nil) {
  4399  				t.Fatalf("Index: %d MD4 failed Error: %s", i, errs)
  4400  			} else {
  4401  				val := getError(errs, "", "")
  4402  				if val.Tag() != "md4" {
  4403  					t.Fatalf("Index: %d MD4 failed Error: %s", i, errs)
  4404  				}
  4405  			}
  4406  		}
  4407  	}
  4408  }
  4409  
  4410  func TestMD5Validation(t *testing.T) {
  4411  	tests := []struct {
  4412  		param    string
  4413  		expected bool
  4414  	}{
  4415  		{"", false},
  4416  		{"6f5902ac237024bdd0c176cb93063dc4", true},
  4417  		{"6f5902ac237024bdd0c176cb93063dc-", false},
  4418  		{"6f5902ac237024bdd0c176cb93063dc41", false},
  4419  		{"6f5902ac237024bdd0c176cb93063dcC", false},
  4420  		{"6f5902ac237024bdd0c176cb93063dc", false},
  4421  	}
  4422  
  4423  	validate := New()
  4424  
  4425  	for i, test := range tests {
  4426  
  4427  		errs := validate.Var(test.param, "md5")
  4428  
  4429  		if test.expected {
  4430  			if !IsEqual(errs, nil) {
  4431  				t.Fatalf("Index: %d MD5 failed Error: %s", i, errs)
  4432  			}
  4433  		} else {
  4434  			if IsEqual(errs, nil) {
  4435  				t.Fatalf("Index: %d MD5 failed Error: %s", i, errs)
  4436  			} else {
  4437  				val := getError(errs, "", "")
  4438  				if val.Tag() != "md5" {
  4439  					t.Fatalf("Index: %d MD5 failed Error: %s", i, errs)
  4440  				}
  4441  			}
  4442  		}
  4443  	}
  4444  }
  4445  
  4446  func TestSHA256Validation(t *testing.T) {
  4447  	tests := []struct {
  4448  		param    string
  4449  		expected bool
  4450  	}{
  4451  		{"", false},
  4452  		{"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc4", true},
  4453  		{"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc-", false},
  4454  		{"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc41", false},
  4455  		{"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dcC", false},
  4456  		{"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc", false},
  4457  	}
  4458  
  4459  	validate := New()
  4460  
  4461  	for i, test := range tests {
  4462  
  4463  		errs := validate.Var(test.param, "sha256")
  4464  		if test.expected {
  4465  			if !IsEqual(errs, nil) {
  4466  				t.Fatalf("Index: %d SHA256 failed Error: %s", i, errs)
  4467  			}
  4468  		} else {
  4469  			if IsEqual(errs, nil) {
  4470  				t.Fatalf("Index: %d SHA256 failed Error: %s", i, errs)
  4471  			} else {
  4472  				val := getError(errs, "", "")
  4473  				if val.Tag() != "sha256" {
  4474  					t.Fatalf("Index: %d SHA256 failed Error: %s", i, errs)
  4475  				}
  4476  			}
  4477  		}
  4478  	}
  4479  }
  4480  
  4481  func TestSHA384Validation(t *testing.T) {
  4482  	tests := []struct {
  4483  		param    string
  4484  		expected bool
  4485  	}{
  4486  		{"", false},
  4487  		{"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc4", true},
  4488  		{"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc-", false},
  4489  		{"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc41", false},
  4490  		{"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dcC", false},
  4491  		{"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc", false},
  4492  	}
  4493  
  4494  	validate := New()
  4495  
  4496  	for i, test := range tests {
  4497  
  4498  		errs := validate.Var(test.param, "sha384")
  4499  
  4500  		if test.expected {
  4501  			if !IsEqual(errs, nil) {
  4502  				t.Fatalf("Index: %d SHA384 failed Error: %s", i, errs)
  4503  			}
  4504  		} else {
  4505  			if IsEqual(errs, nil) {
  4506  				t.Fatalf("Index: %d SHA384 failed Error: %s", i, errs)
  4507  			} else {
  4508  				val := getError(errs, "", "")
  4509  				if val.Tag() != "sha384" {
  4510  					t.Fatalf("Index: %d SHA384 failed Error: %s", i, errs)
  4511  				}
  4512  			}
  4513  		}
  4514  	}
  4515  }
  4516  
  4517  func TestSHA512Validation(t *testing.T) {
  4518  	tests := []struct {
  4519  		param    string
  4520  		expected bool
  4521  	}{
  4522  		{"", false},
  4523  		{"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc4", true},
  4524  		{"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc-", false},
  4525  		{"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc41", false},
  4526  		{"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dcC", false},
  4527  		{"6f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc46f5902ac237024bdd0c176cb93063dc", false},
  4528  	}
  4529  
  4530  	validate := New()
  4531  
  4532  	for i, test := range tests {
  4533  
  4534  		errs := validate.Var(test.param, "sha512")
  4535  
  4536  		if test.expected {
  4537  			if !IsEqual(errs, nil) {
  4538  				t.Fatalf("Index: %d SHA512 failed Error: %s", i, errs)
  4539  			}
  4540  		} else {
  4541  			if IsEqual(errs, nil) {
  4542  				t.Fatalf("Index: %d SHA512 failed Error: %s", i, errs)
  4543  			} else {
  4544  				val := getError(errs, "", "")
  4545  				if val.Tag() != "sha512" {
  4546  					t.Fatalf("Index: %d SHA512 failed Error: %s", i, errs)
  4547  				}
  4548  			}
  4549  		}
  4550  	}
  4551  }
  4552  
  4553  func TestRIPEMD128Validation(t *testing.T) {
  4554  	tests := []struct {
  4555  		param    string
  4556  		expected bool
  4557  	}{
  4558  		{"", false},
  4559  		{"6f5902ac237024bdd0c176cb93063dc4", true},
  4560  		{"6f5902ac237024bdd0c176cb93063dc-", false},
  4561  		{"6f5902ac237024bdd0c176cb93063dc41", false},
  4562  		{"6f5902ac237024bdd0c176cb93063dcC", false},
  4563  		{"6f5902ac237024bdd0c176cb93063dc", false},
  4564  	}
  4565  
  4566  	validate := New()
  4567  
  4568  	for i, test := range tests {
  4569  
  4570  		errs := validate.Var(test.param, "ripemd128")
  4571  
  4572  		if test.expected {
  4573  			if !IsEqual(errs, nil) {
  4574  				t.Fatalf("Index: %d RIPEMD128 failed Error: %s", i, errs)
  4575  			}
  4576  		} else {
  4577  			if IsEqual(errs, nil) {
  4578  				t.Fatalf("Index: %d RIPEMD128 failed Error: %s", i, errs)
  4579  			} else {
  4580  				val := getError(errs, "", "")
  4581  				if val.Tag() != "ripemd128" {
  4582  					t.Fatalf("Index: %d RIPEMD128 failed Error: %s", i, errs)
  4583  				}
  4584  			}
  4585  		}
  4586  	}
  4587  }
  4588  
  4589  func TestRIPEMD160Validation(t *testing.T) {
  4590  	tests := []struct {
  4591  		param    string
  4592  		expected bool
  4593  	}{
  4594  		{"", false},
  4595  		{"6f5902ac6f5902ac237024bdd0c176cb93063dc4", true},
  4596  		{"6f5902ac6f5902ac237024bdd0c176cb93063dc-", false},
  4597  		{"6f5902ac6f5902ac237024bdd0c176cb93063dc41", false},
  4598  		{"6f5902ac6f5902ac237024bdd0c176cb93063dcC", false},
  4599  		{"6f5902ac6f5902ac237024bdd0c176cb93063dc", false},
  4600  	}
  4601  
  4602  	validate := New()
  4603  
  4604  	for i, test := range tests {
  4605  
  4606  		errs := validate.Var(test.param, "ripemd160")
  4607  
  4608  		if test.expected {
  4609  			if !IsEqual(errs, nil) {
  4610  				t.Fatalf("Index: %d RIPEMD160 failed Error: %s", i, errs)
  4611  			}
  4612  		} else {
  4613  			if IsEqual(errs, nil) {
  4614  				t.Fatalf("Index: %d RIPEMD160 failed Error: %s", i, errs)
  4615  			} else {
  4616  				val := getError(errs, "", "")
  4617  				if val.Tag() != "ripemd160" {
  4618  					t.Fatalf("Index: %d RIPEMD160 failed Error: %s", i, errs)
  4619  				}
  4620  			}
  4621  		}
  4622  	}
  4623  }
  4624  
  4625  func TestTIGER128Validation(t *testing.T) {
  4626  	tests := []struct {
  4627  		param    string
  4628  		expected bool
  4629  	}{
  4630  		{"", false},
  4631  		{"6f5902ac237024bdd0c176cb93063dc4", true},
  4632  		{"6f5902ac237024bdd0c176cb93063dc-", false},
  4633  		{"6f5902ac237024bdd0c176cb93063dc41", false},
  4634  		{"6f5902ac237024bdd0c176cb93063dcC", false},
  4635  		{"6f5902ac237024bdd0c176cb93063dc", false},
  4636  	}
  4637  
  4638  	validate := New()
  4639  
  4640  	for i, test := range tests {
  4641  
  4642  		errs := validate.Var(test.param, "tiger128")
  4643  
  4644  		if test.expected {
  4645  			if !IsEqual(errs, nil) {
  4646  				t.Fatalf("Index: %d TIGER128 failed Error: %s", i, errs)
  4647  			}
  4648  		} else {
  4649  			if IsEqual(errs, nil) {
  4650  				t.Fatalf("Index: %d TIGER128 failed Error: %s", i, errs)
  4651  			} else {
  4652  				val := getError(errs, "", "")
  4653  				if val.Tag() != "tiger128" {
  4654  					t.Fatalf("Index: %d TIGER128 failed Error: %s", i, errs)
  4655  				}
  4656  			}
  4657  		}
  4658  	}
  4659  }
  4660  
  4661  func TestTIGER160Validation(t *testing.T) {
  4662  	tests := []struct {
  4663  		param    string
  4664  		expected bool
  4665  	}{
  4666  		{"", false},
  4667  		{"6f5902ac6f5902ac237024bdd0c176cb93063dc4", true},
  4668  		{"6f5902ac6f5902ac237024bdd0c176cb93063dc-", false},
  4669  		{"6f5902ac6f5902ac237024bdd0c176cb93063dc41", false},
  4670  		{"6f5902ac6f5902ac237024bdd0c176cb93063dcC", false},
  4671  		{"6f5902ac6f5902ac237024bdd0c176cb93063dc", false},
  4672  	}
  4673  
  4674  	validate := New()
  4675  
  4676  	for i, test := range tests {
  4677  
  4678  		errs := validate.Var(test.param, "tiger160")
  4679  
  4680  		if test.expected {
  4681  			if !IsEqual(errs, nil) {
  4682  				t.Fatalf("Index: %d TIGER160 failed Error: %s", i, errs)
  4683  			}
  4684  		} else {
  4685  			if IsEqual(errs, nil) {
  4686  				t.Fatalf("Index: %d TIGER160 failed Error: %s", i, errs)
  4687  			} else {
  4688  				val := getError(errs, "", "")
  4689  				if val.Tag() != "tiger160" {
  4690  					t.Fatalf("Index: %d TIGER160 failed Error: %s", i, errs)
  4691  				}
  4692  			}
  4693  		}
  4694  	}
  4695  }
  4696  
  4697  func TestTIGER192Validation(t *testing.T) {
  4698  	tests := []struct {
  4699  		param    string
  4700  		expected bool
  4701  	}{
  4702  		{"", false},
  4703  		{"6f5902ac237024bd6f5902ac237024bdd0c176cb93063dc4", true},
  4704  		{"6f5902ac237024bd6f5902ac237024bdd0c176cb93063dc-", false},
  4705  		{"6f5902ac237024bd6f5902ac237024bdd0c176cb93063dc41", false},
  4706  		{"6f5902ac237024bd6f5902ac237024bdd0c176cb93063dcC", false},
  4707  		{"6f5902ac237024bd6f5902ac237024bdd0c176cb93063dc", false},
  4708  	}
  4709  
  4710  	validate := New()
  4711  
  4712  	for i, test := range tests {
  4713  
  4714  		errs := validate.Var(test.param, "tiger192")
  4715  
  4716  		if test.expected {
  4717  			if !IsEqual(errs, nil) {
  4718  				t.Fatalf("Index: %d TIGER192 failed Error: %s", i, errs)
  4719  			}
  4720  		} else {
  4721  			if IsEqual(errs, nil) {
  4722  				t.Fatalf("Index: %d TIGER192 failed Error: %s", i, errs)
  4723  			} else {
  4724  				val := getError(errs, "", "")
  4725  				if val.Tag() != "tiger192" {
  4726  					t.Fatalf("Index: %d TIGER192 failed Error: %s", i, errs)
  4727  				}
  4728  			}
  4729  		}
  4730  	}
  4731  }
  4732  
  4733  func TestISBNValidation(t *testing.T) {
  4734  	tests := []struct {
  4735  		param    string
  4736  		expected bool
  4737  	}{
  4738  		{"", false},
  4739  		{"foo", false},
  4740  		{"3836221195", true},
  4741  		{"1-61729-085-8", true},
  4742  		{"3 423 21412 0", true},
  4743  		{"3 401 01319 X", true},
  4744  		{"9784873113685", true},
  4745  		{"978-4-87311-368-5", true},
  4746  		{"978 3401013190", true},
  4747  		{"978-3-8362-2119-1", true},
  4748  	}
  4749  
  4750  	validate := New()
  4751  
  4752  	for i, test := range tests {
  4753  
  4754  		errs := validate.Var(test.param, "isbn")
  4755  
  4756  		if test.expected {
  4757  			if !IsEqual(errs, nil) {
  4758  				t.Fatalf("Index: %d ISBN failed Error: %s", i, errs)
  4759  			}
  4760  		} else {
  4761  			if IsEqual(errs, nil) {
  4762  				t.Fatalf("Index: %d ISBN failed Error: %s", i, errs)
  4763  			} else {
  4764  				val := getError(errs, "", "")
  4765  				if val.Tag() != "isbn" {
  4766  					t.Fatalf("Index: %d ISBN failed Error: %s", i, errs)
  4767  				}
  4768  			}
  4769  		}
  4770  	}
  4771  }
  4772  
  4773  func TestISBN13Validation(t *testing.T) {
  4774  	tests := []struct {
  4775  		param    string
  4776  		expected bool
  4777  	}{
  4778  		{"", false},
  4779  		{"foo", false},
  4780  		{"3-8362-2119-5", false},
  4781  		{"01234567890ab", false},
  4782  		{"978 3 8362 2119 0", false},
  4783  		{"9784873113685", true},
  4784  		{"978-4-87311-368-5", true},
  4785  		{"978 3401013190", true},
  4786  		{"978-3-8362-2119-1", true},
  4787  	}
  4788  
  4789  	validate := New()
  4790  
  4791  	for i, test := range tests {
  4792  
  4793  		errs := validate.Var(test.param, "isbn13")
  4794  
  4795  		if test.expected {
  4796  			if !IsEqual(errs, nil) {
  4797  				t.Fatalf("Index: %d ISBN13 failed Error: %s", i, errs)
  4798  			}
  4799  		} else {
  4800  			if IsEqual(errs, nil) {
  4801  				t.Fatalf("Index: %d ISBN13 failed Error: %s", i, errs)
  4802  			} else {
  4803  				val := getError(errs, "", "")
  4804  				if val.Tag() != "isbn13" {
  4805  					t.Fatalf("Index: %d ISBN13 failed Error: %s", i, errs)
  4806  				}
  4807  			}
  4808  		}
  4809  	}
  4810  }
  4811  
  4812  func TestISBN10Validation(t *testing.T) {
  4813  	tests := []struct {
  4814  		param    string
  4815  		expected bool
  4816  	}{
  4817  		{"", false},
  4818  		{"foo", false},
  4819  		{"3423214121", false},
  4820  		{"978-3836221191", false},
  4821  		{"3-423-21412-1", false},
  4822  		{"3 423 21412 1", false},
  4823  		{"3836221195", true},
  4824  		{"1-61729-085-8", true},
  4825  		{"3 423 21412 0", true},
  4826  		{"3 401 01319 X", true},
  4827  	}
  4828  
  4829  	validate := New()
  4830  
  4831  	for i, test := range tests {
  4832  
  4833  		errs := validate.Var(test.param, "isbn10")
  4834  
  4835  		if test.expected {
  4836  			if !IsEqual(errs, nil) {
  4837  				t.Fatalf("Index: %d ISBN10 failed Error: %s", i, errs)
  4838  			}
  4839  		} else {
  4840  			if IsEqual(errs, nil) {
  4841  				t.Fatalf("Index: %d ISBN10 failed Error: %s", i, errs)
  4842  			} else {
  4843  				val := getError(errs, "", "")
  4844  				if val.Tag() != "isbn10" {
  4845  					t.Fatalf("Index: %d ISBN10 failed Error: %s", i, errs)
  4846  				}
  4847  			}
  4848  		}
  4849  	}
  4850  }
  4851  
  4852  func TestISSNValidation(t *testing.T) {
  4853  	tests := []struct {
  4854  		param    string
  4855  		expected bool
  4856  	}{
  4857  		{"", false},
  4858  		{"foo", false},
  4859  		{"20519990", false},
  4860  		{"2051-9991", false},
  4861  		{"2051-999X", false},
  4862  		{"1050-124X", true},
  4863  		{"0317-8471", true},
  4864  	}
  4865  
  4866  	validate := New()
  4867  
  4868  	for i, test := range tests {
  4869  		errs := validate.Var(test.param, "issn")
  4870  
  4871  		if test.expected {
  4872  			if !IsEqual(errs, nil) {
  4873  				t.Fatalf("Index: %d ISSN failed Error: %s", i, errs)
  4874  			}
  4875  		} else {
  4876  			if IsEqual(errs, nil) {
  4877  				t.Fatalf("Index: %d ISSN failed Error: %s", i, errs)
  4878  			} else {
  4879  				val := getError(errs, "", "")
  4880  				if val.Tag() != "issn" {
  4881  					t.Fatalf("Index: %d ISSN failed Error: %s", i, errs)
  4882  				}
  4883  			}
  4884  		}
  4885  	}
  4886  }
  4887  
  4888  func TestExcludesRuneValidation(t *testing.T) {
  4889  	tests := []struct {
  4890  		Value       string `validate:"excludesrune=☻"`
  4891  		Tag         string
  4892  		ExpectedNil bool
  4893  	}{
  4894  		{Value: "a☺b☻c☹d", Tag: "excludesrune=☻", ExpectedNil: false},
  4895  		{Value: "abcd", Tag: "excludesrune=☻", ExpectedNil: true},
  4896  	}
  4897  
  4898  	validate := New()
  4899  
  4900  	for i, s := range tests {
  4901  		errs := validate.Var(s.Value, s.Tag)
  4902  
  4903  		if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
  4904  			t.Fatalf("Index: %d failed Error: %s", i, errs)
  4905  		}
  4906  
  4907  		errs = validate.Struct(s)
  4908  
  4909  		if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
  4910  			t.Fatalf("Index: %d failed Error: %s", i, errs)
  4911  		}
  4912  	}
  4913  }
  4914  
  4915  func TestExcludesAllValidation(t *testing.T) {
  4916  	tests := []struct {
  4917  		Value       string `validate:"excludesall=@!{}[]"`
  4918  		Tag         string
  4919  		ExpectedNil bool
  4920  	}{
  4921  		{Value: "abcd@!jfk", Tag: "excludesall=@!{}[]", ExpectedNil: false},
  4922  		{Value: "abcdefg", Tag: "excludesall=@!{}[]", ExpectedNil: true},
  4923  	}
  4924  
  4925  	validate := New()
  4926  
  4927  	for i, s := range tests {
  4928  		errs := validate.Var(s.Value, s.Tag)
  4929  
  4930  		if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
  4931  			t.Fatalf("Index: %d failed Error: %s", i, errs)
  4932  		}
  4933  
  4934  		errs = validate.Struct(s)
  4935  
  4936  		if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
  4937  			t.Fatalf("Index: %d failed Error: %s", i, errs)
  4938  		}
  4939  	}
  4940  
  4941  	username := "joeybloggs "
  4942  
  4943  	errs := validate.Var(username, "excludesall=@ ")
  4944  	NotEqual(t, errs, nil)
  4945  	AssertError(t, errs, "", "", "", "", "excludesall")
  4946  
  4947  	excluded := ","
  4948  
  4949  	errs = validate.Var(excluded, "excludesall=!@#$%^&*()_+.0x2C?")
  4950  	NotEqual(t, errs, nil)
  4951  	AssertError(t, errs, "", "", "", "", "excludesall")
  4952  
  4953  	excluded = "="
  4954  
  4955  	errs = validate.Var(excluded, "excludesall=!@#$%^&*()_+.0x2C=?")
  4956  	NotEqual(t, errs, nil)
  4957  	AssertError(t, errs, "", "", "", "", "excludesall")
  4958  }
  4959  
  4960  func TestExcludesValidation(t *testing.T) {
  4961  	tests := []struct {
  4962  		Value       string `validate:"excludes=@"`
  4963  		Tag         string
  4964  		ExpectedNil bool
  4965  	}{
  4966  		{Value: "abcd@!jfk", Tag: "excludes=@", ExpectedNil: false},
  4967  		{Value: "abcdq!jfk", Tag: "excludes=@", ExpectedNil: true},
  4968  	}
  4969  
  4970  	validate := New()
  4971  
  4972  	for i, s := range tests {
  4973  		errs := validate.Var(s.Value, s.Tag)
  4974  
  4975  		if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
  4976  			t.Fatalf("Index: %d failed Error: %s", i, errs)
  4977  		}
  4978  
  4979  		errs = validate.Struct(s)
  4980  
  4981  		if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
  4982  			t.Fatalf("Index: %d failed Error: %s", i, errs)
  4983  		}
  4984  	}
  4985  }
  4986  
  4987  func TestContainsRuneValidation(t *testing.T) {
  4988  	tests := []struct {
  4989  		Value       string `validate:"containsrune=☻"`
  4990  		Tag         string
  4991  		ExpectedNil bool
  4992  	}{
  4993  		{Value: "a☺b☻c☹d", Tag: "containsrune=☻", ExpectedNil: true},
  4994  		{Value: "abcd", Tag: "containsrune=☻", ExpectedNil: false},
  4995  	}
  4996  
  4997  	validate := New()
  4998  
  4999  	for i, s := range tests {
  5000  		errs := validate.Var(s.Value, s.Tag)
  5001  
  5002  		if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
  5003  			t.Fatalf("Index: %d failed Error: %s", i, errs)
  5004  		}
  5005  
  5006  		errs = validate.Struct(s)
  5007  
  5008  		if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
  5009  			t.Fatalf("Index: %d failed Error: %s", i, errs)
  5010  		}
  5011  	}
  5012  }
  5013  
  5014  func TestContainsAnyValidation(t *testing.T) {
  5015  	tests := []struct {
  5016  		Value       string `validate:"containsany=@!{}[]"`
  5017  		Tag         string
  5018  		ExpectedNil bool
  5019  	}{
  5020  		{Value: "abcd@!jfk", Tag: "containsany=@!{}[]", ExpectedNil: true},
  5021  		{Value: "abcdefg", Tag: "containsany=@!{}[]", ExpectedNil: false},
  5022  	}
  5023  
  5024  	validate := New()
  5025  
  5026  	for i, s := range tests {
  5027  		errs := validate.Var(s.Value, s.Tag)
  5028  
  5029  		if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
  5030  			t.Fatalf("Index: %d failed Error: %s", i, errs)
  5031  		}
  5032  
  5033  		errs = validate.Struct(s)
  5034  
  5035  		if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
  5036  			t.Fatalf("Index: %d failed Error: %s", i, errs)
  5037  		}
  5038  	}
  5039  }
  5040  
  5041  func TestContainsValidation(t *testing.T) {
  5042  	tests := []struct {
  5043  		Value       string `validate:"contains=@"`
  5044  		Tag         string
  5045  		ExpectedNil bool
  5046  	}{
  5047  		{Value: "abcd@!jfk", Tag: "contains=@", ExpectedNil: true},
  5048  		{Value: "abcdq!jfk", Tag: "contains=@", ExpectedNil: false},
  5049  	}
  5050  
  5051  	validate := New()
  5052  
  5053  	for i, s := range tests {
  5054  		errs := validate.Var(s.Value, s.Tag)
  5055  
  5056  		if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
  5057  			t.Fatalf("Index: %d failed Error: %s", i, errs)
  5058  		}
  5059  
  5060  		errs = validate.Struct(s)
  5061  
  5062  		if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
  5063  			t.Fatalf("Index: %d failed Error: %s", i, errs)
  5064  		}
  5065  	}
  5066  }
  5067  
  5068  func TestIsNeFieldValidation(t *testing.T) {
  5069  	var errs error
  5070  	validate := New()
  5071  
  5072  	var j uint64
  5073  	var k float64
  5074  	s := "abcd"
  5075  	i := 1
  5076  	j = 1
  5077  	k = 1.543
  5078  	b := true
  5079  	arr := []string{"test"}
  5080  	now := time.Now().UTC()
  5081  
  5082  	var j2 uint64
  5083  	var k2 float64
  5084  	s2 := "abcdef"
  5085  	i2 := 3
  5086  	j2 = 2
  5087  	k2 = 1.5434456
  5088  	b2 := false
  5089  	arr2 := []string{"test", "test2"}
  5090  	arr3 := []string{"test"}
  5091  	now2 := now
  5092  
  5093  	errs = validate.VarWithValue(s, s2, "nefield")
  5094  	Equal(t, errs, nil)
  5095  
  5096  	errs = validate.VarWithValue(i2, i, "nefield")
  5097  	Equal(t, errs, nil)
  5098  
  5099  	errs = validate.VarWithValue(j2, j, "nefield")
  5100  	Equal(t, errs, nil)
  5101  
  5102  	errs = validate.VarWithValue(k2, k, "nefield")
  5103  	Equal(t, errs, nil)
  5104  
  5105  	errs = validate.VarWithValue(b2, b, "nefield")
  5106  	Equal(t, errs, nil)
  5107  
  5108  	errs = validate.VarWithValue(arr2, arr, "nefield")
  5109  	Equal(t, errs, nil)
  5110  
  5111  	errs = validate.VarWithValue(now2, now, "nefield")
  5112  	NotEqual(t, errs, nil)
  5113  	AssertError(t, errs, "", "", "", "", "nefield")
  5114  
  5115  	errs = validate.VarWithValue(arr3, arr, "nefield")
  5116  	NotEqual(t, errs, nil)
  5117  	AssertError(t, errs, "", "", "", "", "nefield")
  5118  
  5119  	type Test struct {
  5120  		Start *time.Time `validate:"nefield=End"`
  5121  		End   *time.Time
  5122  	}
  5123  
  5124  	sv := &Test{
  5125  		Start: &now,
  5126  		End:   &now,
  5127  	}
  5128  
  5129  	errs = validate.Struct(sv)
  5130  	NotEqual(t, errs, nil)
  5131  	AssertError(t, errs, "Test.Start", "Test.Start", "Start", "Start", "nefield")
  5132  
  5133  	now3 := time.Now().Add(time.Hour).UTC()
  5134  
  5135  	sv = &Test{
  5136  		Start: &now,
  5137  		End:   &now3,
  5138  	}
  5139  
  5140  	errs = validate.Struct(sv)
  5141  	Equal(t, errs, nil)
  5142  
  5143  	errs = validate.VarWithValue(nil, 1, "nefield")
  5144  	NotEqual(t, errs, nil)
  5145  	AssertError(t, errs, "", "", "", "", "nefield")
  5146  
  5147  	errs = validate.VarWithValue(sv, now, "nefield")
  5148  	Equal(t, errs, nil)
  5149  
  5150  	type Test2 struct {
  5151  		Start *time.Time `validate:"nefield=NonExistantField"`
  5152  		End   *time.Time
  5153  	}
  5154  
  5155  	sv2 := &Test2{
  5156  		Start: &now,
  5157  		End:   &now,
  5158  	}
  5159  
  5160  	errs = validate.Struct(sv2)
  5161  	Equal(t, errs, nil)
  5162  
  5163  	type Other struct {
  5164  		Value string
  5165  	}
  5166  
  5167  	type Test3 struct {
  5168  		Value Other
  5169  		Time  time.Time `validate:"nefield=Value"`
  5170  	}
  5171  
  5172  	tst := Test3{
  5173  		Value: Other{Value: "StringVal"},
  5174  		Time:  now,
  5175  	}
  5176  
  5177  	errs = validate.Struct(tst)
  5178  	Equal(t, errs, nil)
  5179  
  5180  	// Tests for time.Duration type.
  5181  
  5182  	// -- Validations for variables of time.Duration type.
  5183  
  5184  	errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "nefield")
  5185  	Equal(t, errs, nil)
  5186  
  5187  	errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "nefield")
  5188  	Equal(t, errs, nil)
  5189  
  5190  	errs = validate.VarWithValue(time.Hour, time.Hour, "nefield")
  5191  	NotEqual(t, errs, nil)
  5192  	AssertError(t, errs, "", "", "", "", "nefield")
  5193  
  5194  	errs = validate.VarWithValue(time.Duration(0), time.Duration(0), "omitempty,nefield")
  5195  	Equal(t, errs, nil)
  5196  
  5197  	// -- Validations for a struct with time.Duration type fields.
  5198  
  5199  	type TimeDurationTest struct {
  5200  		First  time.Duration `validate:"nefield=Second"`
  5201  		Second time.Duration
  5202  	}
  5203  	var timeDurationTest *TimeDurationTest
  5204  
  5205  	timeDurationTest = &TimeDurationTest{time.Hour, time.Hour - time.Minute}
  5206  	errs = validate.Struct(timeDurationTest)
  5207  	Equal(t, errs, nil)
  5208  
  5209  	timeDurationTest = &TimeDurationTest{time.Hour, time.Hour + time.Minute}
  5210  	errs = validate.Struct(timeDurationTest)
  5211  	Equal(t, errs, nil)
  5212  
  5213  	timeDurationTest = &TimeDurationTest{time.Hour, time.Hour}
  5214  	errs = validate.Struct(timeDurationTest)
  5215  	NotEqual(t, errs, nil)
  5216  	AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "nefield")
  5217  
  5218  	type TimeDurationOmitemptyTest struct {
  5219  		First  time.Duration `validate:"omitempty,nefield=Second"`
  5220  		Second time.Duration
  5221  	}
  5222  
  5223  	timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0), time.Duration(0)}
  5224  	errs = validate.Struct(timeDurationOmitemptyTest)
  5225  	Equal(t, errs, nil)
  5226  }
  5227  
  5228  func TestIsNeValidation(t *testing.T) {
  5229  	var errs error
  5230  	validate := New()
  5231  
  5232  	var j uint64
  5233  	var k float64
  5234  	s := "abcdef"
  5235  	i := 3
  5236  	j = 2
  5237  	k = 1.5434
  5238  	arr := []string{"test"}
  5239  	now := time.Now().UTC()
  5240  
  5241  	errs = validate.Var(s, "ne=abcd")
  5242  	Equal(t, errs, nil)
  5243  
  5244  	errs = validate.Var(i, "ne=1")
  5245  	Equal(t, errs, nil)
  5246  
  5247  	errs = validate.Var(j, "ne=1")
  5248  	Equal(t, errs, nil)
  5249  
  5250  	errs = validate.Var(k, "ne=1.543")
  5251  	Equal(t, errs, nil)
  5252  
  5253  	errs = validate.Var(arr, "ne=2")
  5254  	Equal(t, errs, nil)
  5255  
  5256  	errs = validate.Var(arr, "ne=1")
  5257  	NotEqual(t, errs, nil)
  5258  	AssertError(t, errs, "", "", "", "", "ne")
  5259  
  5260  	PanicMatches(t, func() { _ = validate.Var(now, "ne=now") }, "Bad field type time.Time")
  5261  
  5262  	// Tests for time.Duration type.
  5263  
  5264  	// -- Validations for a variable of time.Duration type.
  5265  
  5266  	errs = validate.Var(time.Hour-time.Minute, "ne=1h")
  5267  	Equal(t, errs, nil)
  5268  
  5269  	errs = validate.Var(time.Hour+time.Minute, "ne=1h")
  5270  	Equal(t, errs, nil)
  5271  
  5272  	errs = validate.Var(time.Hour, "ne=1h")
  5273  	NotEqual(t, errs, nil)
  5274  	AssertError(t, errs, "", "", "", "", "ne")
  5275  
  5276  	errs = validate.Var(time.Duration(0), "omitempty,ne=0")
  5277  	Equal(t, errs, nil)
  5278  
  5279  	// -- Validations for a struct with a time.Duration type field.
  5280  
  5281  	type TimeDurationTest struct {
  5282  		Duration time.Duration `validate:"ne=1h"`
  5283  	}
  5284  	var timeDurationTest *TimeDurationTest
  5285  
  5286  	timeDurationTest = &TimeDurationTest{time.Hour - time.Minute}
  5287  	errs = validate.Struct(timeDurationTest)
  5288  	Equal(t, errs, nil)
  5289  
  5290  	timeDurationTest = &TimeDurationTest{time.Hour + time.Minute}
  5291  	errs = validate.Struct(timeDurationTest)
  5292  	Equal(t, errs, nil)
  5293  
  5294  	timeDurationTest = &TimeDurationTest{time.Hour}
  5295  	errs = validate.Struct(timeDurationTest)
  5296  	NotEqual(t, errs, nil)
  5297  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "ne")
  5298  
  5299  	type TimeDurationOmitemptyTest struct {
  5300  		Duration time.Duration `validate:"omitempty,ne=0"`
  5301  	}
  5302  
  5303  	timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
  5304  	errs = validate.Struct(timeDurationOmitemptyTest)
  5305  	Equal(t, errs, nil)
  5306  }
  5307  
  5308  func TestIsNeIgnoreCaseValidation(t *testing.T) {
  5309  	var errs error
  5310  	validate := New()
  5311  	s := "abcd"
  5312  	now := time.Now()
  5313  
  5314  	errs = validate.Var(s, "ne_ignore_case=efgh")
  5315  	Equal(t, errs, nil)
  5316  
  5317  	errs = validate.Var(s, "ne_ignore_case=AbCd")
  5318  	NotEqual(t, errs, nil)
  5319  	AssertError(t, errs, "", "", "", "", "ne_ignore_case")
  5320  
  5321  	PanicMatches(
  5322  		t, func() { _ = validate.Var(now, "ne_ignore_case=abcd") }, "Bad field type time.Time",
  5323  	)
  5324  }
  5325  
  5326  func TestIsEqFieldValidation(t *testing.T) {
  5327  	var errs error
  5328  	validate := New()
  5329  
  5330  	var j uint64
  5331  	var k float64
  5332  	s := "abcd"
  5333  	i := 1
  5334  	j = 1
  5335  	k = 1.543
  5336  	b := true
  5337  	arr := []string{"test"}
  5338  	now := time.Now().UTC()
  5339  
  5340  	var j2 uint64
  5341  	var k2 float64
  5342  	s2 := "abcd"
  5343  	i2 := 1
  5344  	j2 = 1
  5345  	k2 = 1.543
  5346  	b2 := true
  5347  	arr2 := []string{"test"}
  5348  	arr3 := []string{"test", "test2"}
  5349  	now2 := now
  5350  
  5351  	errs = validate.VarWithValue(s, s2, "eqfield")
  5352  	Equal(t, errs, nil)
  5353  
  5354  	errs = validate.VarWithValue(i2, i, "eqfield")
  5355  	Equal(t, errs, nil)
  5356  
  5357  	errs = validate.VarWithValue(j2, j, "eqfield")
  5358  	Equal(t, errs, nil)
  5359  
  5360  	errs = validate.VarWithValue(k2, k, "eqfield")
  5361  	Equal(t, errs, nil)
  5362  
  5363  	errs = validate.VarWithValue(b2, b, "eqfield")
  5364  	Equal(t, errs, nil)
  5365  
  5366  	errs = validate.VarWithValue(arr2, arr, "eqfield")
  5367  	Equal(t, errs, nil)
  5368  
  5369  	errs = validate.VarWithValue(now2, now, "eqfield")
  5370  	Equal(t, errs, nil)
  5371  
  5372  	errs = validate.VarWithValue(arr3, arr, "eqfield")
  5373  	NotEqual(t, errs, nil)
  5374  	AssertError(t, errs, "", "", "", "", "eqfield")
  5375  
  5376  	type Test struct {
  5377  		Start *time.Time `validate:"eqfield=End"`
  5378  		End   *time.Time
  5379  	}
  5380  
  5381  	sv := &Test{
  5382  		Start: &now,
  5383  		End:   &now,
  5384  	}
  5385  
  5386  	errs = validate.Struct(sv)
  5387  	Equal(t, errs, nil)
  5388  
  5389  	now3 := time.Now().Add(time.Hour).UTC()
  5390  
  5391  	sv = &Test{
  5392  		Start: &now,
  5393  		End:   &now3,
  5394  	}
  5395  
  5396  	errs = validate.Struct(sv)
  5397  	NotEqual(t, errs, nil)
  5398  	AssertError(t, errs, "Test.Start", "Test.Start", "Start", "Start", "eqfield")
  5399  
  5400  	errs = validate.VarWithValue(nil, 1, "eqfield")
  5401  	NotEqual(t, errs, nil)
  5402  	AssertError(t, errs, "", "", "", "", "eqfield")
  5403  
  5404  	channel := make(chan string)
  5405  	errs = validate.VarWithValue(5, channel, "eqfield")
  5406  	NotEqual(t, errs, nil)
  5407  	AssertError(t, errs, "", "", "", "", "eqfield")
  5408  
  5409  	errs = validate.VarWithValue(5, now, "eqfield")
  5410  	NotEqual(t, errs, nil)
  5411  	AssertError(t, errs, "", "", "", "", "eqfield")
  5412  
  5413  	type Test2 struct {
  5414  		Start *time.Time `validate:"eqfield=NonExistantField"`
  5415  		End   *time.Time
  5416  	}
  5417  
  5418  	sv2 := &Test2{
  5419  		Start: &now,
  5420  		End:   &now,
  5421  	}
  5422  
  5423  	errs = validate.Struct(sv2)
  5424  	NotEqual(t, errs, nil)
  5425  	AssertError(t, errs, "Test2.Start", "Test2.Start", "Start", "Start", "eqfield")
  5426  
  5427  	type Inner struct {
  5428  		Name string
  5429  	}
  5430  
  5431  	type TStruct struct {
  5432  		Inner     *Inner
  5433  		CreatedAt *time.Time `validate:"eqfield=Inner"`
  5434  	}
  5435  
  5436  	inner := &Inner{
  5437  		Name: "NAME",
  5438  	}
  5439  
  5440  	test := &TStruct{
  5441  		Inner:     inner,
  5442  		CreatedAt: &now,
  5443  	}
  5444  
  5445  	errs = validate.Struct(test)
  5446  	NotEqual(t, errs, nil)
  5447  	AssertError(t, errs, "TStruct.CreatedAt", "TStruct.CreatedAt", "CreatedAt", "CreatedAt", "eqfield")
  5448  
  5449  	// Tests for time.Duration type.
  5450  
  5451  	// -- Validations for variables of time.Duration type.
  5452  
  5453  	errs = validate.VarWithValue(time.Hour, time.Hour, "eqfield")
  5454  	Equal(t, errs, nil)
  5455  
  5456  	errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "eqfield")
  5457  	NotEqual(t, errs, nil)
  5458  	AssertError(t, errs, "", "", "", "", "eqfield")
  5459  
  5460  	errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "eqfield")
  5461  	NotEqual(t, errs, nil)
  5462  	AssertError(t, errs, "", "", "", "", "eqfield")
  5463  
  5464  	errs = validate.VarWithValue(time.Duration(0), time.Hour, "omitempty,eqfield")
  5465  	Equal(t, errs, nil)
  5466  
  5467  	// -- Validations for a struct with time.Duration type fields.
  5468  
  5469  	type TimeDurationTest struct {
  5470  		First  time.Duration `validate:"eqfield=Second"`
  5471  		Second time.Duration
  5472  	}
  5473  	var timeDurationTest *TimeDurationTest
  5474  
  5475  	timeDurationTest = &TimeDurationTest{time.Hour, time.Hour}
  5476  	errs = validate.Struct(timeDurationTest)
  5477  	Equal(t, errs, nil)
  5478  
  5479  	timeDurationTest = &TimeDurationTest{time.Hour, time.Hour - time.Minute}
  5480  	errs = validate.Struct(timeDurationTest)
  5481  	NotEqual(t, errs, nil)
  5482  	AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "eqfield")
  5483  
  5484  	timeDurationTest = &TimeDurationTest{time.Hour, time.Hour + time.Minute}
  5485  	errs = validate.Struct(timeDurationTest)
  5486  	NotEqual(t, errs, nil)
  5487  	AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "eqfield")
  5488  
  5489  	type TimeDurationOmitemptyTest struct {
  5490  		First  time.Duration `validate:"omitempty,eqfield=Second"`
  5491  		Second time.Duration
  5492  	}
  5493  
  5494  	timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0), time.Hour}
  5495  	errs = validate.Struct(timeDurationOmitemptyTest)
  5496  	Equal(t, errs, nil)
  5497  }
  5498  
  5499  func TestIsEqFieldValidationWithAliasTime(t *testing.T) {
  5500  	var errs error
  5501  	validate := New()
  5502  
  5503  	type CustomTime time.Time
  5504  
  5505  	type Test struct {
  5506  		Start CustomTime `validate:"eqfield=End"`
  5507  		End   *time.Time
  5508  	}
  5509  
  5510  	now := time.Now().UTC()
  5511  
  5512  	sv := &Test{
  5513  		Start: CustomTime(now),
  5514  		End:   &now,
  5515  	}
  5516  
  5517  	errs = validate.Struct(sv)
  5518  	Equal(t, errs, nil)
  5519  }
  5520  
  5521  func TestIsEqValidation(t *testing.T) {
  5522  	var errs error
  5523  	validate := New()
  5524  
  5525  	var j uint64
  5526  	var k float64
  5527  	s := "abcd"
  5528  	i := 1
  5529  	j = 1
  5530  	k = 1.543
  5531  	arr := []string{"test"}
  5532  	now := time.Now().UTC()
  5533  
  5534  	errs = validate.Var(s, "eq=abcd")
  5535  	Equal(t, errs, nil)
  5536  
  5537  	errs = validate.Var(i, "eq=1")
  5538  	Equal(t, errs, nil)
  5539  
  5540  	errs = validate.Var(j, "eq=1")
  5541  	Equal(t, errs, nil)
  5542  
  5543  	errs = validate.Var(k, "eq=1.543")
  5544  	Equal(t, errs, nil)
  5545  
  5546  	errs = validate.Var(arr, "eq=1")
  5547  	Equal(t, errs, nil)
  5548  
  5549  	errs = validate.Var(arr, "eq=2")
  5550  	NotEqual(t, errs, nil)
  5551  	AssertError(t, errs, "", "", "", "", "eq")
  5552  
  5553  	PanicMatches(t, func() { _ = validate.Var(now, "eq=now") }, "Bad field type time.Time")
  5554  
  5555  	// Tests for time.Duration type.
  5556  
  5557  	// -- Validations for a variable of time.Duration type.
  5558  
  5559  	errs = validate.Var(time.Hour, "eq=1h")
  5560  	Equal(t, errs, nil)
  5561  
  5562  	errs = validate.Var(time.Hour-time.Minute, "eq=1h")
  5563  	NotEqual(t, errs, nil)
  5564  	AssertError(t, errs, "", "", "", "", "eq")
  5565  
  5566  	errs = validate.Var(time.Hour+time.Minute, "eq=1h")
  5567  	NotEqual(t, errs, nil)
  5568  	AssertError(t, errs, "", "", "", "", "eq")
  5569  
  5570  	errs = validate.Var(time.Duration(0), "omitempty,eq=1h")
  5571  	Equal(t, errs, nil)
  5572  
  5573  	// -- Validations for a struct with a time.Duration type field.
  5574  
  5575  	type TimeDurationTest struct {
  5576  		Duration time.Duration `validate:"eq=1h"`
  5577  	}
  5578  	var timeDurationTest *TimeDurationTest
  5579  
  5580  	timeDurationTest = &TimeDurationTest{time.Hour}
  5581  	errs = validate.Struct(timeDurationTest)
  5582  	Equal(t, errs, nil)
  5583  
  5584  	timeDurationTest = &TimeDurationTest{time.Hour - time.Minute}
  5585  	errs = validate.Struct(timeDurationTest)
  5586  	NotEqual(t, errs, nil)
  5587  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "eq")
  5588  
  5589  	timeDurationTest = &TimeDurationTest{time.Hour + time.Minute}
  5590  	errs = validate.Struct(timeDurationTest)
  5591  	NotEqual(t, errs, nil)
  5592  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "eq")
  5593  
  5594  	type TimeDurationOmitemptyTest struct {
  5595  		Duration time.Duration `validate:"omitempty,eq=1h"`
  5596  	}
  5597  
  5598  	timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
  5599  	errs = validate.Struct(timeDurationOmitemptyTest)
  5600  	Equal(t, errs, nil)
  5601  }
  5602  
  5603  func TestIsEqIgnoreCaseValidation(t *testing.T) {
  5604  	var errs error
  5605  	validate := New()
  5606  	s := "abcd"
  5607  	now := time.Now()
  5608  
  5609  	errs = validate.Var(s, "eq_ignore_case=abcd")
  5610  	Equal(t, errs, nil)
  5611  
  5612  	errs = validate.Var(s, "eq_ignore_case=AbCd")
  5613  	Equal(t, errs, nil)
  5614  
  5615  	PanicMatches(
  5616  		t, func() { _ = validate.Var(now, "eq_ignore_case=abcd") }, "Bad field type time.Time",
  5617  	)
  5618  }
  5619  
  5620  func TestOneOfValidation(t *testing.T) {
  5621  	validate := New()
  5622  
  5623  	passSpecs := []struct {
  5624  		f interface{}
  5625  		t string
  5626  	}{
  5627  		{f: "red", t: "oneof=red green"},
  5628  		{f: "green", t: "oneof=red green"},
  5629  		{f: "red green", t: "oneof='red green' blue"},
  5630  		{f: "blue", t: "oneof='red green' blue"},
  5631  		{f: 5, t: "oneof=5 6"},
  5632  		{f: 6, t: "oneof=5 6"},
  5633  		{f: int8(6), t: "oneof=5 6"},
  5634  		{f: int16(6), t: "oneof=5 6"},
  5635  		{f: int32(6), t: "oneof=5 6"},
  5636  		{f: int64(6), t: "oneof=5 6"},
  5637  		{f: uint(6), t: "oneof=5 6"},
  5638  		{f: uint8(6), t: "oneof=5 6"},
  5639  		{f: uint16(6), t: "oneof=5 6"},
  5640  		{f: uint32(6), t: "oneof=5 6"},
  5641  		{f: uint64(6), t: "oneof=5 6"},
  5642  	}
  5643  
  5644  	for _, spec := range passSpecs {
  5645  		t.Logf("%#v", spec)
  5646  		errs := validate.Var(spec.f, spec.t)
  5647  		Equal(t, errs, nil)
  5648  	}
  5649  
  5650  	failSpecs := []struct {
  5651  		f interface{}
  5652  		t string
  5653  	}{
  5654  		{f: "", t: "oneof=red green"},
  5655  		{f: "yellow", t: "oneof=red green"},
  5656  		{f: "green", t: "oneof='red green' blue"},
  5657  		{f: 5, t: "oneof=red green"},
  5658  		{f: 6, t: "oneof=red green"},
  5659  		{f: 6, t: "oneof=7"},
  5660  		{f: uint(6), t: "oneof=7"},
  5661  		{f: int8(5), t: "oneof=red green"},
  5662  		{f: int16(5), t: "oneof=red green"},
  5663  		{f: int32(5), t: "oneof=red green"},
  5664  		{f: int64(5), t: "oneof=red green"},
  5665  		{f: uint(5), t: "oneof=red green"},
  5666  		{f: uint8(5), t: "oneof=red green"},
  5667  		{f: uint16(5), t: "oneof=red green"},
  5668  		{f: uint32(5), t: "oneof=red green"},
  5669  		{f: uint64(5), t: "oneof=red green"},
  5670  	}
  5671  
  5672  	for _, spec := range failSpecs {
  5673  		t.Logf("%#v", spec)
  5674  		errs := validate.Var(spec.f, spec.t)
  5675  		AssertError(t, errs, "", "", "", "", "oneof")
  5676  	}
  5677  
  5678  	PanicMatches(t, func() {
  5679  		_ = validate.Var(3.14, "oneof=red green")
  5680  	}, "Bad field type float64")
  5681  }
  5682  
  5683  func TestBase64Validation(t *testing.T) {
  5684  	validate := New()
  5685  
  5686  	s := "dW5pY29ybg=="
  5687  
  5688  	errs := validate.Var(s, "base64")
  5689  	Equal(t, errs, nil)
  5690  
  5691  	s = "dGhpIGlzIGEgdGVzdCBiYXNlNjQ="
  5692  	errs = validate.Var(s, "base64")
  5693  	Equal(t, errs, nil)
  5694  
  5695  	s = ""
  5696  	errs = validate.Var(s, "base64")
  5697  	NotEqual(t, errs, nil)
  5698  	AssertError(t, errs, "", "", "", "", "base64")
  5699  
  5700  	s = "dW5pY29ybg== foo bar"
  5701  	errs = validate.Var(s, "base64")
  5702  	NotEqual(t, errs, nil)
  5703  	AssertError(t, errs, "", "", "", "", "base64")
  5704  }
  5705  
  5706  func TestBase64URLValidation(t *testing.T) {
  5707  	validate := New()
  5708  
  5709  	testCases := []struct {
  5710  		decoded, encoded string
  5711  		success          bool
  5712  	}{
  5713  		// empty string, although a valid base64 string, should fail
  5714  		{"", "", false},
  5715  		// invalid length
  5716  		{"", "a", false},
  5717  		// base64 with padding
  5718  		{"f", "Zg==", true},
  5719  		{"fo", "Zm8=", true},
  5720  		// base64 without padding
  5721  		{"foo", "Zm9v", true},
  5722  		{"", "Zg", false},
  5723  		{"", "Zm8", false},
  5724  		// base64 URL safe encoding with invalid, special characters '+' and '/'
  5725  		{"\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l+", false},
  5726  		{"\x14\xfb\x9c\x03\xf9\x73", "FPucA/lz", false},
  5727  		// base64 URL safe encoding with valid, special characters '-' and '_'
  5728  		{"\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l-", true},
  5729  		{"\x14\xfb\x9c\x03\xf9\x73", "FPucA_lz", true},
  5730  		// non base64 characters
  5731  		{"", "@mc=", false},
  5732  		{"", "Zm 9", false},
  5733  	}
  5734  	for _, tc := range testCases {
  5735  		err := validate.Var(tc.encoded, "base64url")
  5736  		if tc.success {
  5737  			Equal(t, err, nil)
  5738  			// make sure encoded value is decoded back to the expected value
  5739  			d, innerErr := base64.URLEncoding.DecodeString(tc.encoded)
  5740  			Equal(t, innerErr, nil)
  5741  			Equal(t, tc.decoded, string(d))
  5742  		} else {
  5743  			NotEqual(t, err, nil)
  5744  			if len(tc.encoded) > 0 {
  5745  				// make sure that indeed the encoded value was faulty
  5746  				_, err := base64.URLEncoding.DecodeString(tc.encoded)
  5747  				NotEqual(t, err, nil)
  5748  			}
  5749  		}
  5750  	}
  5751  }
  5752  
  5753  func TestBase64RawURLValidation(t *testing.T) {
  5754  	validate := New()
  5755  
  5756  	testCases := []struct {
  5757  		decoded, encoded string
  5758  		success          bool
  5759  	}{
  5760  		// empty string, although a valid base64 string, should fail
  5761  		{"", "", false},
  5762  		// invalid length
  5763  		{"", "a", false},
  5764  		// base64 with padding should fail
  5765  		{"f", "Zg==", false},
  5766  		{"fo", "Zm8=", false},
  5767  		// base64 without padding
  5768  		{"foo", "Zm9v", true},
  5769  		{"hello", "aGVsbG8", true},
  5770  		{"", "aGVsb", false},
  5771  		// // base64 URL safe encoding with invalid, special characters '+' and '/'
  5772  		{"\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l+", false},
  5773  		{"\x14\xfb\x9c\x03\xf9\x73", "FPucA/lz", false},
  5774  		// // base64 URL safe encoding with valid, special characters '-' and '_'
  5775  		{"\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l-", true},
  5776  		{"\x14\xfb\x9c\x03\xf9\x73", "FPucA_lz", true},
  5777  		// non base64 characters
  5778  		{"", "@mc=", false},
  5779  		{"", "Zm 9", false},
  5780  	}
  5781  	for _, tc := range testCases {
  5782  		err := validate.Var(tc.encoded, "base64rawurl")
  5783  		if tc.success {
  5784  			Equal(t, err, nil)
  5785  			// make sure encoded value is decoded back to the expected value
  5786  			d, innerErr := base64.RawURLEncoding.DecodeString(tc.encoded)
  5787  			Equal(t, innerErr, nil)
  5788  			Equal(t, tc.decoded, string(d))
  5789  		} else {
  5790  			NotEqual(t, err, nil)
  5791  			if len(tc.encoded) > 0 {
  5792  				// make sure that indeed the encoded value was faulty
  5793  				_, err := base64.RawURLEncoding.DecodeString(tc.encoded)
  5794  				NotEqual(t, err, nil)
  5795  			}
  5796  		}
  5797  	}
  5798  }
  5799  
  5800  func TestFileValidation(t *testing.T) {
  5801  	validate := New()
  5802  
  5803  	tests := []struct {
  5804  		title    string
  5805  		param    string
  5806  		expected bool
  5807  	}{
  5808  		{"empty path", "", false},
  5809  		{"regular file", filepath.Join("testdata", "a.go"), true},
  5810  		{"missing file", filepath.Join("testdata", "no.go"), false},
  5811  		{"directory, not a file", "testdata", false},
  5812  	}
  5813  
  5814  	for _, test := range tests {
  5815  		errs := validate.Var(test.param, "file")
  5816  
  5817  		if test.expected {
  5818  			if !IsEqual(errs, nil) {
  5819  				t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
  5820  			}
  5821  		} else {
  5822  			if IsEqual(errs, nil) {
  5823  				t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
  5824  			}
  5825  		}
  5826  	}
  5827  
  5828  	PanicMatches(t, func() {
  5829  		_ = validate.Var(6, "file")
  5830  	}, "Bad field type int")
  5831  }
  5832  
  5833  func TestImageValidation(t *testing.T) {
  5834  	validate := New()
  5835  
  5836  	paths := map[string]string{
  5837  		"empty":     "",
  5838  		"directory": "testdata",
  5839  		"missing":   filepath.Join("testdata", "none.png"),
  5840  		"png":       filepath.Join("testdata", "image.png"),
  5841  		"jpeg":      filepath.Join("testdata", "image.jpg"),
  5842  		"mp3":       filepath.Join("testdata", "music.mp3"),
  5843  	}
  5844  
  5845  	tests := []struct {
  5846  		title        string
  5847  		param        string
  5848  		expected     bool
  5849  		createImage  func()
  5850  		destroyImage func()
  5851  	}{
  5852  		{
  5853  			"empty path",
  5854  			paths["empty"], false,
  5855  			func() {},
  5856  			func() {},
  5857  		},
  5858  		{
  5859  			"directory, not a file",
  5860  			paths["directory"],
  5861  			false,
  5862  			func() {},
  5863  			func() {},
  5864  		},
  5865  		{
  5866  			"missing file",
  5867  			paths["missing"],
  5868  			false,
  5869  			func() {},
  5870  			func() {},
  5871  		},
  5872  		{
  5873  			"valid png",
  5874  			paths["png"],
  5875  			true,
  5876  			func() {
  5877  				img := image.NewRGBA(image.Rectangle{image.Point{0, 0}, image.Point{10, 10}})
  5878  				f, _ := os.Create(paths["png"])
  5879  				err := png.Encode(f, img)
  5880  				if err != nil {
  5881  					panic(fmt.Sprintf("Could not encode file in PNG. Error: %s", err))
  5882  				}
  5883  			},
  5884  			func() {
  5885  				os.Remove(paths["png"])
  5886  			},
  5887  		},
  5888  		{
  5889  			"valid jpeg",
  5890  			paths["jpeg"],
  5891  			true,
  5892  			func() {
  5893  				var opt jpeg.Options
  5894  				img := image.NewGray(image.Rect(0, 0, 10, 10))
  5895  				f, _ := os.Create(paths["jpeg"])
  5896  				err := jpeg.Encode(f, img, &opt)
  5897  				if err != nil {
  5898  					panic(fmt.Sprintf("Could not encode file in JPEG. Error: %s", err))
  5899  				}
  5900  			},
  5901  			func() {
  5902  				os.Remove(paths["jpeg"])
  5903  			},
  5904  		},
  5905  		{
  5906  			"valid mp3",
  5907  			paths["mp3"],
  5908  			false,
  5909  			func() {},
  5910  			func() {},
  5911  		},
  5912  	}
  5913  
  5914  	for _, test := range tests {
  5915  		test.createImage()
  5916  		errs := validate.Var(test.param, "image")
  5917  
  5918  		if test.expected {
  5919  			if !IsEqual(errs, nil) {
  5920  				t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
  5921  			}
  5922  		} else {
  5923  			if IsEqual(errs, nil) {
  5924  				t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
  5925  			}
  5926  		}
  5927  		test.destroyImage()
  5928  	}
  5929  
  5930  	PanicMatches(t, func() {
  5931  		_ = validate.Var(6, "file")
  5932  	}, "Bad field type int")
  5933  }
  5934  
  5935  func TestFilePathValidation(t *testing.T) {
  5936  	validate := New()
  5937  
  5938  	tests := []struct {
  5939  		title    string
  5940  		param    string
  5941  		expected bool
  5942  	}{
  5943  		{"empty filepath", "", false},
  5944  		{"valid filepath", filepath.Join("testdata", "a.go"), true},
  5945  		{"invalid filepath", filepath.Join("testdata", "no\000.go"), false},
  5946  		{"directory, not a filepath", "testdata" + string(os.PathSeparator), false},
  5947  		{"directory", "testdata", false},
  5948  	}
  5949  
  5950  	for _, test := range tests {
  5951  		errs := validate.Var(test.param, "filepath")
  5952  
  5953  		if test.expected {
  5954  			if !IsEqual(errs, nil) {
  5955  				t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
  5956  			}
  5957  		} else {
  5958  			if IsEqual(errs, nil) {
  5959  				t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
  5960  			}
  5961  		}
  5962  
  5963  	}
  5964  
  5965  	PanicMatches(t, func() {
  5966  		_ = validate.Var(6, "filepath")
  5967  	}, "Bad field type int")
  5968  }
  5969  
  5970  func TestEthereumAddressValidation(t *testing.T) {
  5971  	validate := New()
  5972  
  5973  	tests := []struct {
  5974  		param    string
  5975  		expected bool
  5976  	}{
  5977  		// All caps.
  5978  		{"0x52908400098527886E0F7030069857D2E4169EE7", true},
  5979  		{"0x8617E340B3D01FA5F11F306F4090FD50E238070D", true},
  5980  
  5981  		// All lower.
  5982  		{"0xde709f2102306220921060314715629080e2fb77", true},
  5983  		{"0x27b1fdb04752bbc536007a920d24acb045561c26", true},
  5984  		{"0x123f681646d4a755815f9cb19e1acc8565a0c2ac", true},
  5985  
  5986  		// Mixed case: runs checksum validation.
  5987  		{"0x02F9AE5f22EA3fA88F05780B30385bECFacbf130", true},
  5988  		{"0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed", true},
  5989  		{"0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359", true},
  5990  		{"0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB", true},
  5991  		{"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb", true},
  5992  		{"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDB", true}, // Invalid checksum, but valid address.
  5993  
  5994  		// Other.
  5995  		{"", false},
  5996  		{"D1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb", false},    // Missing "0x" prefix.
  5997  		{"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDbc", false}, // More than 40 hex digits.
  5998  		{"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aD", false},   // Less than 40 hex digits.
  5999  		{"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDw", false},  // Invalid hex digit "w".
  6000  	}
  6001  
  6002  	for i, test := range tests {
  6003  
  6004  		errs := validate.Var(test.param, "eth_addr")
  6005  
  6006  		if test.expected {
  6007  			if !IsEqual(errs, nil) {
  6008  				t.Fatalf("Index: %d eth_addr failed Error: %s", i, errs)
  6009  			}
  6010  		} else {
  6011  			if IsEqual(errs, nil) {
  6012  				t.Fatalf("Index: %d eth_addr failed Error: %s", i, errs)
  6013  			} else {
  6014  				val := getError(errs, "", "")
  6015  				if val.Tag() != "eth_addr" {
  6016  					t.Fatalf("Index: %d Latitude failed Error: %s", i, errs)
  6017  				}
  6018  			}
  6019  		}
  6020  	}
  6021  }
  6022  
  6023  func TestEthereumAddressChecksumValidation(t *testing.T) {
  6024  	validate := New()
  6025  
  6026  	tests := []struct {
  6027  		param    string
  6028  		expected bool
  6029  	}{
  6030  		// All caps.
  6031  		{"0x52908400098527886E0F7030069857D2E4169EE7", true},
  6032  		{"0x8617E340B3D01FA5F11F306F4090FD50E238070D", true},
  6033  
  6034  		// All lower.
  6035  		{"0x27b1fdb04752bbc536007a920d24acb045561c26", true},
  6036  		{"0x123f681646d4a755815f9cb19e1acc8565a0c2ac", false},
  6037  
  6038  		// Mixed case: runs checksum validation.
  6039  		{"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb", true},
  6040  		{"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDB", false}, // Invalid checksum.
  6041  		{"0x000000000000000000000000000000000000dead", false}, // Invalid checksum.
  6042  		{"0x000000000000000000000000000000000000dEaD", true},  // Valid checksum.
  6043  
  6044  		// Other.
  6045  		{"", false},
  6046  		{"D1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb", false},    // Missing "0x" prefix.
  6047  		{"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDbc", false}, // More than 40 hex digits.
  6048  		{"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aD", false},   // Less than 40 hex digits.
  6049  		{"0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDw", false},  // Invalid hex digit "w".
  6050  	}
  6051  
  6052  	for i, test := range tests {
  6053  
  6054  		errs := validate.Var(test.param, "eth_addr_checksum")
  6055  
  6056  		if test.expected {
  6057  			if !IsEqual(errs, nil) {
  6058  				t.Fatalf("Index: %d eth_addr_checksum failed Error: %s", i, errs)
  6059  			}
  6060  		} else {
  6061  			if IsEqual(errs, nil) {
  6062  				t.Fatalf("Index: %d eth_addr_checksum failed Error: %s", i, errs)
  6063  			} else {
  6064  				val := getError(errs, "", "")
  6065  				if val.Tag() != "eth_addr_checksum" {
  6066  					t.Fatalf("Index: %d Latitude failed Error: %s", i, errs)
  6067  				}
  6068  			}
  6069  		}
  6070  	}
  6071  }
  6072  
  6073  func TestBitcoinAddressValidation(t *testing.T) {
  6074  	validate := New()
  6075  
  6076  	tests := []struct {
  6077  		param    string
  6078  		expected bool
  6079  	}{
  6080  		{"", false},
  6081  		{"x", false},
  6082  		{"0x02F9AE5f22EA3fA88F05780B30385bEC", false},
  6083  		{"1A1zP1ePQGefi2DMPTifTL5SLmv7DivfNa", false},
  6084  		{"1P9RQEr2XeE3PEb44ZE35sfZRRW1JH8Uqx", false},
  6085  		{"3P14159I73E4gFr7JterCCQh9QjiTjiZrG", false},
  6086  		{"3P141597f3E4gFr7JterCCQh9QjiTjiZrG", false},
  6087  		{"37qgekLpCCHrQuSjvX3fs496FWTGsHFHizjJAs6NPcR47aefnnCWECAhHV6E3g4YN7u7Yuwod5Y", false},
  6088  		{"dzb7VV1Ui55BARxv7ATxAtCUeJsANKovDGWFVgpTbhq9gvPqP3yv", false},
  6089  		{"MuNu7ZAEDFiHthiunm7dPjwKqrVNCM3mAz6rP9zFveQu14YA8CxExSJTHcVP9DErn6u84E6Ej7S", false},
  6090  		{"rPpQpYknyNQ5AEHuY6H8ijJJrYc2nDKKk9jjmKEXsWzyAQcFGpDLU2Zvsmoi8JLR7hAwoy3RQWf", false},
  6091  		{"4Uc3FmN6NQ6zLBK5QQBXRBUREaaHwCZYsGCueHauuDmJpZKn6jkEskMB2Zi2CNgtb5r6epWEFfUJq", false},
  6092  		{"7aQgR5DFQ25vyXmqZAWmnVCjL3PkBcdVkBUpjrjMTcghHx3E8wb", false},
  6093  		{"17QpPprjeg69fW1DV8DcYYCKvWjYhXvWkov6MJ1iTTvMFj6weAqW7wybZeH57WTNxXVCRH4veVs", false},
  6094  		{"KxuACDviz8Xvpn1xAh9MfopySZNuyajYMZWz16Dv2mHHryznWUp3", false},
  6095  		{"7nK3GSmqdXJQtdohvGfJ7KsSmn3TmGqExug49583bDAL91pVSGq5xS9SHoAYL3Wv3ijKTit65th", false},
  6096  		{"cTivdBmq7bay3RFGEBBuNfMh2P1pDCgRYN2Wbxmgwr4ki3jNUL2va", false},
  6097  		{"gjMV4vjNjyMrna4fsAr8bWxAbwtmMUBXJS3zL4NJt5qjozpbQLmAfK1uA3CquSqsZQMpoD1g2nk", false},
  6098  		{"emXm1naBMoVzPjbk7xpeTVMFy4oDEe25UmoyGgKEB1gGWsK8kRGs", false},
  6099  		{"7VThQnNRj1o3Zyvc7XHPRrjDf8j2oivPTeDXnRPYWeYGE4pXeRJDZgf28ppti5hsHWXS2GSobdqyo", false},
  6100  		{"1G9u6oCVCPh2o8m3t55ACiYvG1y5BHewUkDSdiQarDcYXXhFHYdzMdYfUAhfxn5vNZBwpgUNpso", false},
  6101  		{"31QQ7ZMLkScDiB4VyZjuptr7AEc9j1SjstF7pRoLhHTGkW4Q2y9XELobQmhhWxeRvqcukGd1XCq", false},
  6102  		{"DHqKSnpxa8ZdQyH8keAhvLTrfkyBMQxqngcQA5N8LQ9KVt25kmGN", false},
  6103  		{"2LUHcJPbwLCy9GLH1qXmfmAwvadWw4bp4PCpDfduLqV17s6iDcy1imUwhQJhAoNoN1XNmweiJP4i", false},
  6104  		{"7USRzBXAnmck8fX9HmW7RAb4qt92VFX6soCnts9s74wxm4gguVhtG5of8fZGbNPJA83irHVY6bCos", false},
  6105  		{"1DGezo7BfVebZxAbNT3XGujdeHyNNBF3vnficYoTSp4PfK2QaML9bHzAMxke3wdKdHYWmsMTJVu", false},
  6106  		{"2D12DqDZKwCxxkzs1ZATJWvgJGhQ4cFi3WrizQ5zLAyhN5HxuAJ1yMYaJp8GuYsTLLxTAz6otCfb", false},
  6107  		{"8AFJzuTujXjw1Z6M3fWhQ1ujDW7zsV4ePeVjVo7D1egERqSW9nZ", false},
  6108  		{"163Q17qLbTCue8YY3AvjpUhotuaodLm2uqMhpYirsKjVqnxJRWTEoywMVY3NbBAHuhAJ2cF9GAZ", false},
  6109  		{"2MnmgiRH4eGLyLc9eAqStzk7dFgBjFtUCtu", false},
  6110  		{"461QQ2sYWxU7H2PV4oBwJGNch8XVTYYbZxU", false},
  6111  		{"2UCtv53VttmQYkVU4VMtXB31REvQg4ABzs41AEKZ8UcB7DAfVzdkV9JDErwGwyj5AUHLkmgZeobs", false},
  6112  		{"cSNjAsnhgtiFMi6MtfvgscMB2Cbhn2v1FUYfviJ1CdjfidvmeW6mn", false},
  6113  		{"gmsow2Y6EWAFDFE1CE4Hd3Tpu2BvfmBfG1SXsuRARbnt1WjkZnFh1qGTiptWWbjsq2Q6qvpgJVj", false},
  6114  		{"nksUKSkzS76v8EsSgozXGMoQFiCoCHzCVajFKAXqzK5on9ZJYVHMD5CKwgmX3S3c7M1U3xabUny", false},
  6115  		{"L3favK1UzFGgdzYBF2oBT5tbayCo4vtVBLJhg2iYuMeePxWG8SQc", false},
  6116  		{"7VxLxGGtYT6N99GdEfi6xz56xdQ8nP2dG1CavuXx7Rf2PrvNMTBNevjkfgs9JmkcGm6EXpj8ipyPZ ", false},
  6117  		{"2mbZwFXF6cxShaCo2czTRB62WTx9LxhTtpP", false},
  6118  		{"dB7cwYdcPSgiyAwKWL3JwCVwSk6epU2txw", false},
  6119  		{"HPhFUhUAh8ZQQisH8QQWafAxtQYju3SFTX", false},
  6120  		{"4ctAH6AkHzq5ioiM1m9T3E2hiYEev5mTsB", false},
  6121  		{"31uEbMgunupShBVTewXjtqbBv5MndwfXhb", false},
  6122  		{"175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W", false},
  6123  		{"Hn1uFi4dNexWrqARpjMqgT6cX1UsNPuV3cHdGg9ExyXw8HTKadbktRDtdeVmY3M1BxJStiL4vjJ", false},
  6124  		{"Sq3fDbvutABmnAHHExJDgPLQn44KnNC7UsXuT7KZecpaYDMU9Txs", false},
  6125  		{"6TqWyrqdgUEYDQU1aChMuFMMEimHX44qHFzCUgGfqxGgZNMUVWJ", false},
  6126  		{"giqJo7oWqFxNKWyrgcBxAVHXnjJ1t6cGoEffce5Y1y7u649Noj5wJ4mmiUAKEVVrYAGg2KPB3Y4", false},
  6127  		{"cNzHY5e8vcmM3QVJUcjCyiKMYfeYvyueq5qCMV3kqcySoLyGLYUK", false},
  6128  		{"37uTe568EYc9WLoHEd9jXEvUiWbq5LFLscNyqvAzLU5vBArUJA6eydkLmnMwJDjkL5kXc2VK7ig", false},
  6129  		{"EsYbG4tWWWY45G31nox838qNdzksbPySWc", false},
  6130  		{"nbuzhfwMoNzA3PaFnyLcRxE9bTJPDkjZ6Rf6Y6o2ckXZfzZzXBT", false},
  6131  		{"cQN9PoxZeCWK1x56xnz6QYAsvR11XAce3Ehp3gMUdfSQ53Y2mPzx", false},
  6132  		{"1Gm3N3rkef6iMbx4voBzaxtXcmmiMTqZPhcuAepRzYUJQW4qRpEnHvMojzof42hjFRf8PE2jPde", false},
  6133  		{"2TAq2tuN6x6m233bpT7yqdYQPELdTDJn1eU", false},
  6134  		{"ntEtnnGhqPii4joABvBtSEJG6BxjT2tUZqE8PcVYgk3RHpgxgHDCQxNbLJf7ardf1dDk2oCQ7Cf", false},
  6135  		{"Ky1YjoZNgQ196HJV3HpdkecfhRBmRZdMJk89Hi5KGfpfPwS2bUbfd", false},
  6136  		{"2A1q1YsMZowabbvta7kTy2Fd6qN4r5ZCeG3qLpvZBMzCixMUdkN2Y4dHB1wPsZAeVXUGD83MfRED", false},
  6137  		{"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", true},
  6138  		{"1Ax4gZtb7gAit2TivwejZHYtNNLT18PUXJ", true},
  6139  		{"1C5bSj1iEGUgSTbziymG7Cn18ENQuT36vv", true},
  6140  		{"1Gqk4Tv79P91Cc1STQtU3s1W6277M2CVWu", true},
  6141  		{"1JwMWBVLtiqtscbaRHai4pqHokhFCbtoB4", true},
  6142  		{"19dcawoKcZdQz365WpXWMhX6QCUpR9SY4r", true},
  6143  		{"13p1ijLwsnrcuyqcTvJXkq2ASdXqcnEBLE", true},
  6144  		{"1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2", true},
  6145  		{"3P14159f73E4gFr7JterCCQh9QjiTjiZrG", true},
  6146  		{"3CMNFxN1oHBc4R1EpboAL5yzHGgE611Xou", true},
  6147  		{"3QjYXhTkvuj8qPaXHTTWb5wjXhdsLAAWVy", true},
  6148  		{"3AnNxabYGoTxYiTEZwFEnerUoeFXK2Zoks", true},
  6149  		{"33vt8ViH5jsr115AGkW6cEmEz9MpvJSwDk", true},
  6150  		{"3QCzvfL4ZRvmJFiWWBVwxfdaNBT8EtxB5y", true},
  6151  		{"37Sp6Rv3y4kVd1nQ1JV5pfqXccHNyZm1x3", true},
  6152  		{"3ALJH9Y951VCGcVZYAdpA3KchoP9McEj1G", true},
  6153  		{"12KYrjTdVGjFMtaxERSk3gphreJ5US8aUP", true},
  6154  		{"12QeMLzSrB8XH8FvEzPMVoRxVAzTr5XM2y", true},
  6155  		{"1oNLrsHnBcR6dpaBpwz3LSwutbUNkNSjs", true},
  6156  		{"1SQHtwR5oJRKLfiWQ2APsAd9miUc4k2ez", true},
  6157  		{"116CGDLddrZhMrTwhCVJXtXQpxygTT1kHd", true},
  6158  		{"3NJZLcZEEYBpxYEUGewU4knsQRn1WM5Fkt", true},
  6159  	}
  6160  
  6161  	for i, test := range tests {
  6162  
  6163  		errs := validate.Var(test.param, "btc_addr")
  6164  
  6165  		if test.expected {
  6166  			if !IsEqual(errs, nil) {
  6167  				t.Fatalf("Index: %d btc_addr failed with Error: %s", i, errs)
  6168  			}
  6169  		} else {
  6170  			if IsEqual(errs, nil) {
  6171  				t.Fatalf("Index: %d btc_addr failed with Error: %s", i, errs)
  6172  			} else {
  6173  				val := getError(errs, "", "")
  6174  				if val.Tag() != "btc_addr" {
  6175  					t.Fatalf("Index: %d Latitude failed with Error: %s", i, errs)
  6176  				}
  6177  			}
  6178  		}
  6179  	}
  6180  }
  6181  
  6182  func TestBitcoinBech32AddressValidation(t *testing.T) {
  6183  	validate := New()
  6184  
  6185  	tests := []struct {
  6186  		param    string
  6187  		expected bool
  6188  	}{
  6189  		{"", false},
  6190  		{"bc1rw5uspcuh", false},
  6191  		{"bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5", false},
  6192  		{"BC13W508D6QEJXTDG4Y5R3ZARVARY0C5XW7KN40WF2", false},
  6193  		{"qw508d6qejxtdg4y5r3zarvary0c5xw7kg3g4ty", false},
  6194  		{"bc1rw5uspcuh", false},
  6195  		{"bc10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90", false},
  6196  		{"BC1QW508d6QEJxTDG4y5R3ZArVARY0C5XW7KV8F3T4", false},
  6197  		{"BC1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P", false},
  6198  		{"bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5", false},
  6199  		{"bc10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90", false},
  6200  		{"bc1pw508d6qejxtdg4y5r3zarqfsj6c3", false},
  6201  		{"bc1zw508d6qejxtdg4y5r3zarvaryvqyzf3du", false},
  6202  		{"bc1gmk9yu", false},
  6203  		{"bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv", false},
  6204  		{"BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4", true},
  6205  		{"bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx", true},
  6206  		{"bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3", true},
  6207  		{"BC1SW50QA3JX3S", true},
  6208  		{"bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj", true},
  6209  	}
  6210  
  6211  	for i, test := range tests {
  6212  
  6213  		errs := validate.Var(test.param, "btc_addr_bech32")
  6214  
  6215  		if test.expected {
  6216  			if !IsEqual(errs, nil) {
  6217  				t.Fatalf("Index: %d btc_addr_bech32 failed with Error: %s", i, errs)
  6218  			}
  6219  		} else {
  6220  			if IsEqual(errs, nil) {
  6221  				t.Fatalf("Index: %d btc_addr_bech32 failed with Error: %s", i, errs)
  6222  			} else {
  6223  				val := getError(errs, "", "")
  6224  				if val.Tag() != "btc_addr_bech32" {
  6225  					t.Fatalf("Index: %d Latitude failed with Error: %s", i, errs)
  6226  				}
  6227  			}
  6228  		}
  6229  	}
  6230  }
  6231  
  6232  func TestNoStructLevelValidation(t *testing.T) {
  6233  	type Inner struct {
  6234  		Test string `validate:"len=5"`
  6235  	}
  6236  
  6237  	type Outer struct {
  6238  		InnerStruct    Inner  `validate:"required,nostructlevel"`
  6239  		InnerStructPtr *Inner `validate:"required,nostructlevel"`
  6240  	}
  6241  
  6242  	outer := &Outer{
  6243  		InnerStructPtr: nil,
  6244  		InnerStruct:    Inner{},
  6245  	}
  6246  
  6247  	// test with struct required failing on
  6248  	validate := New(WithRequiredStructEnabled())
  6249  
  6250  	errs := validate.Struct(outer)
  6251  	NotEqual(t, errs, nil)
  6252  	AssertError(t, errs, "Outer.InnerStruct", "Outer.InnerStruct", "InnerStruct", "InnerStruct", "required")
  6253  	AssertError(t, errs, "Outer.InnerStructPtr", "Outer.InnerStructPtr", "InnerStructPtr", "InnerStructPtr", "required")
  6254  
  6255  	inner := Inner{
  6256  		Test: "1234",
  6257  	}
  6258  
  6259  	outer = &Outer{
  6260  		InnerStruct:    inner,
  6261  		InnerStructPtr: &inner,
  6262  	}
  6263  
  6264  	errs = validate.Struct(outer)
  6265  	Equal(t, errs, nil)
  6266  
  6267  	// test with struct required failing off
  6268  
  6269  	outer = &Outer{
  6270  		InnerStructPtr: nil,
  6271  		InnerStruct:    Inner{},
  6272  	}
  6273  	validate = New()
  6274  
  6275  	errs = validate.Struct(outer)
  6276  	NotEqual(t, errs, nil)
  6277  	AssertError(t, errs, "Outer.InnerStructPtr", "Outer.InnerStructPtr", "InnerStructPtr", "InnerStructPtr", "required")
  6278  
  6279  	inner = Inner{
  6280  		Test: "1234",
  6281  	}
  6282  
  6283  	outer = &Outer{
  6284  		InnerStruct:    inner,
  6285  		InnerStructPtr: &inner,
  6286  	}
  6287  
  6288  	errs = validate.Struct(outer)
  6289  	Equal(t, errs, nil)
  6290  }
  6291  
  6292  func TestStructOnlyValidation(t *testing.T) {
  6293  	type Inner struct {
  6294  		Test string `validate:"len=5"`
  6295  	}
  6296  
  6297  	type Outer struct {
  6298  		InnerStruct    Inner  `validate:"required,structonly"`
  6299  		InnerStructPtr *Inner `validate:"required,structonly"`
  6300  	}
  6301  
  6302  	outer := &Outer{
  6303  		InnerStruct:    Inner{},
  6304  		InnerStructPtr: nil,
  6305  	}
  6306  
  6307  	// without required struct on
  6308  	validate := New()
  6309  
  6310  	errs := validate.Struct(outer)
  6311  	NotEqual(t, errs, nil)
  6312  	AssertError(t, errs, "Outer.InnerStructPtr", "Outer.InnerStructPtr", "InnerStructPtr", "InnerStructPtr", "required")
  6313  
  6314  	// with required struct on
  6315  	validate.requiredStructEnabled = true
  6316  
  6317  	errs = validate.Struct(outer)
  6318  	NotEqual(t, errs, nil)
  6319  	AssertError(t, errs, "Outer.InnerStruct", "Outer.InnerStruct", "InnerStruct", "InnerStruct", "required")
  6320  	AssertError(t, errs, "Outer.InnerStructPtr", "Outer.InnerStructPtr", "InnerStructPtr", "InnerStructPtr", "required")
  6321  
  6322  	inner := Inner{
  6323  		Test: "1234",
  6324  	}
  6325  
  6326  	outer = &Outer{
  6327  		InnerStruct:    inner,
  6328  		InnerStructPtr: &inner,
  6329  	}
  6330  
  6331  	errs = validate.Struct(outer)
  6332  	Equal(t, errs, nil)
  6333  
  6334  	// Address houses a users address information
  6335  	type Address struct {
  6336  		Street string `validate:"required"`
  6337  		City   string `validate:"required"`
  6338  		Planet string `validate:"required"`
  6339  		Phone  string `validate:"required"`
  6340  	}
  6341  
  6342  	type User struct {
  6343  		FirstName      string     `json:"fname"`
  6344  		LastName       string     `json:"lname"`
  6345  		Age            uint8      `validate:"gte=0,lte=130"`
  6346  		Number         string     `validate:"required,e164"`
  6347  		Email          string     `validate:"required,email"`
  6348  		FavouriteColor string     `validate:"hexcolor|rgb|rgba"`
  6349  		Addresses      []*Address `validate:"required"`   // a person can have a home and cottage...
  6350  		Address        Address    `validate:"structonly"` // a person can have a home and cottage...
  6351  	}
  6352  
  6353  	address := &Address{
  6354  		Street: "Eavesdown Docks",
  6355  		Planet: "Persphone",
  6356  		Phone:  "none",
  6357  		City:   "Unknown",
  6358  	}
  6359  
  6360  	user := &User{
  6361  		FirstName:      "",
  6362  		LastName:       "",
  6363  		Age:            45,
  6364  		Number:         "+1123456789",
  6365  		Email:          "Badger.Smith@gmail.com",
  6366  		FavouriteColor: "#000",
  6367  		Addresses:      []*Address{address},
  6368  		Address: Address{
  6369  			// Street: "Eavesdown Docks",
  6370  			Planet: "Persphone",
  6371  			Phone:  "none",
  6372  			City:   "Unknown",
  6373  		},
  6374  	}
  6375  
  6376  	errs = validate.Struct(user)
  6377  	Equal(t, errs, nil)
  6378  }
  6379  
  6380  func TestGtField(t *testing.T) {
  6381  	var errs error
  6382  	validate := New()
  6383  
  6384  	type TimeTest struct {
  6385  		Start *time.Time `validate:"required,gt"`
  6386  		End   *time.Time `validate:"required,gt,gtfield=Start"`
  6387  	}
  6388  
  6389  	now := time.Now()
  6390  	start := now.Add(time.Hour * 24)
  6391  	end := start.Add(time.Hour * 24)
  6392  
  6393  	timeTest := &TimeTest{
  6394  		Start: &start,
  6395  		End:   &end,
  6396  	}
  6397  
  6398  	errs = validate.Struct(timeTest)
  6399  	Equal(t, errs, nil)
  6400  
  6401  	timeTest = &TimeTest{
  6402  		Start: &end,
  6403  		End:   &start,
  6404  	}
  6405  
  6406  	errs = validate.Struct(timeTest)
  6407  	NotEqual(t, errs, nil)
  6408  	AssertError(t, errs, "TimeTest.End", "TimeTest.End", "End", "End", "gtfield")
  6409  
  6410  	errs = validate.VarWithValue(&end, &start, "gtfield")
  6411  	Equal(t, errs, nil)
  6412  
  6413  	errs = validate.VarWithValue(&start, &end, "gtfield")
  6414  	NotEqual(t, errs, nil)
  6415  	AssertError(t, errs, "", "", "", "", "gtfield")
  6416  
  6417  	errs = validate.VarWithValue(&end, &start, "gtfield")
  6418  	Equal(t, errs, nil)
  6419  
  6420  	errs = validate.VarWithValue(&timeTest, &end, "gtfield")
  6421  	NotEqual(t, errs, nil)
  6422  
  6423  	errs = validate.VarWithValue("test bigger", "test", "gtfield")
  6424  	Equal(t, errs, nil)
  6425  
  6426  	// Tests for time.Duration type.
  6427  
  6428  	// -- Validations for variables of time.Duration type.
  6429  
  6430  	errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "gtfield")
  6431  	Equal(t, errs, nil)
  6432  
  6433  	errs = validate.VarWithValue(time.Hour, time.Hour, "gtfield")
  6434  	NotEqual(t, errs, nil)
  6435  	AssertError(t, errs, "", "", "", "", "gtfield")
  6436  
  6437  	errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "gtfield")
  6438  	NotEqual(t, errs, nil)
  6439  	AssertError(t, errs, "", "", "", "", "gtfield")
  6440  
  6441  	errs = validate.VarWithValue(time.Duration(0), time.Hour, "omitempty,gtfield")
  6442  	Equal(t, errs, nil)
  6443  
  6444  	// -- Validations for a struct with time.Duration type fields.
  6445  
  6446  	type TimeDurationTest struct {
  6447  		First  time.Duration `validate:"gtfield=Second"`
  6448  		Second time.Duration
  6449  	}
  6450  	var timeDurationTest *TimeDurationTest
  6451  
  6452  	timeDurationTest = &TimeDurationTest{time.Hour, time.Hour - time.Minute}
  6453  	errs = validate.Struct(timeDurationTest)
  6454  	Equal(t, errs, nil)
  6455  
  6456  	timeDurationTest = &TimeDurationTest{time.Hour, time.Hour}
  6457  	errs = validate.Struct(timeDurationTest)
  6458  	NotEqual(t, errs, nil)
  6459  	AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "gtfield")
  6460  
  6461  	timeDurationTest = &TimeDurationTest{time.Hour, time.Hour + time.Minute}
  6462  	errs = validate.Struct(timeDurationTest)
  6463  	NotEqual(t, errs, nil)
  6464  	AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "gtfield")
  6465  
  6466  	type TimeDurationOmitemptyTest struct {
  6467  		First  time.Duration `validate:"omitempty,gtfield=Second"`
  6468  		Second time.Duration
  6469  	}
  6470  
  6471  	timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0), time.Hour}
  6472  	errs = validate.Struct(timeDurationOmitemptyTest)
  6473  	Equal(t, errs, nil)
  6474  
  6475  	// Tests for Ints types.
  6476  
  6477  	type IntTest struct {
  6478  		Val1 int `validate:"required"`
  6479  		Val2 int `validate:"required,gtfield=Val1"`
  6480  	}
  6481  
  6482  	intTest := &IntTest{
  6483  		Val1: 1,
  6484  		Val2: 5,
  6485  	}
  6486  
  6487  	errs = validate.Struct(intTest)
  6488  	Equal(t, errs, nil)
  6489  
  6490  	intTest = &IntTest{
  6491  		Val1: 5,
  6492  		Val2: 1,
  6493  	}
  6494  
  6495  	errs = validate.Struct(intTest)
  6496  	NotEqual(t, errs, nil)
  6497  	AssertError(t, errs, "IntTest.Val2", "IntTest.Val2", "Val2", "Val2", "gtfield")
  6498  
  6499  	errs = validate.VarWithValue(int(5), int(1), "gtfield")
  6500  	Equal(t, errs, nil)
  6501  
  6502  	errs = validate.VarWithValue(int(1), int(5), "gtfield")
  6503  	NotEqual(t, errs, nil)
  6504  	AssertError(t, errs, "", "", "", "", "gtfield")
  6505  
  6506  	type UIntTest struct {
  6507  		Val1 uint `validate:"required"`
  6508  		Val2 uint `validate:"required,gtfield=Val1"`
  6509  	}
  6510  
  6511  	uIntTest := &UIntTest{
  6512  		Val1: 1,
  6513  		Val2: 5,
  6514  	}
  6515  
  6516  	errs = validate.Struct(uIntTest)
  6517  	Equal(t, errs, nil)
  6518  
  6519  	uIntTest = &UIntTest{
  6520  		Val1: 5,
  6521  		Val2: 1,
  6522  	}
  6523  
  6524  	errs = validate.Struct(uIntTest)
  6525  	NotEqual(t, errs, nil)
  6526  	AssertError(t, errs, "UIntTest.Val2", "UIntTest.Val2", "Val2", "Val2", "gtfield")
  6527  
  6528  	errs = validate.VarWithValue(uint(5), uint(1), "gtfield")
  6529  	Equal(t, errs, nil)
  6530  
  6531  	errs = validate.VarWithValue(uint(1), uint(5), "gtfield")
  6532  	NotEqual(t, errs, nil)
  6533  	AssertError(t, errs, "", "", "", "", "gtfield")
  6534  
  6535  	type FloatTest struct {
  6536  		Val1 float64 `validate:"required"`
  6537  		Val2 float64 `validate:"required,gtfield=Val1"`
  6538  	}
  6539  
  6540  	floatTest := &FloatTest{
  6541  		Val1: 1,
  6542  		Val2: 5,
  6543  	}
  6544  
  6545  	errs = validate.Struct(floatTest)
  6546  	Equal(t, errs, nil)
  6547  
  6548  	floatTest = &FloatTest{
  6549  		Val1: 5,
  6550  		Val2: 1,
  6551  	}
  6552  
  6553  	errs = validate.Struct(floatTest)
  6554  	NotEqual(t, errs, nil)
  6555  	AssertError(t, errs, "FloatTest.Val2", "FloatTest.Val2", "Val2", "Val2", "gtfield")
  6556  
  6557  	errs = validate.VarWithValue(float32(5), float32(1), "gtfield")
  6558  	Equal(t, errs, nil)
  6559  
  6560  	errs = validate.VarWithValue(float32(1), float32(5), "gtfield")
  6561  	NotEqual(t, errs, nil)
  6562  	AssertError(t, errs, "", "", "", "", "gtfield")
  6563  
  6564  	errs = validate.VarWithValue(nil, 1, "gtfield")
  6565  	NotEqual(t, errs, nil)
  6566  	AssertError(t, errs, "", "", "", "", "gtfield")
  6567  
  6568  	errs = validate.VarWithValue(5, "T", "gtfield")
  6569  	NotEqual(t, errs, nil)
  6570  	AssertError(t, errs, "", "", "", "", "gtfield")
  6571  
  6572  	errs = validate.VarWithValue(5, start, "gtfield")
  6573  	NotEqual(t, errs, nil)
  6574  	AssertError(t, errs, "", "", "", "", "gtfield")
  6575  
  6576  	type TimeTest2 struct {
  6577  		Start *time.Time `validate:"required"`
  6578  		End   *time.Time `validate:"required,gtfield=NonExistantField"`
  6579  	}
  6580  
  6581  	timeTest2 := &TimeTest2{
  6582  		Start: &start,
  6583  		End:   &end,
  6584  	}
  6585  
  6586  	errs = validate.Struct(timeTest2)
  6587  	NotEqual(t, errs, nil)
  6588  	AssertError(t, errs, "TimeTest2.End", "TimeTest2.End", "End", "End", "gtfield")
  6589  
  6590  	type Other struct {
  6591  		Value string
  6592  	}
  6593  
  6594  	type Test struct {
  6595  		Value Other
  6596  		Time  time.Time `validate:"gtfield=Value"`
  6597  	}
  6598  
  6599  	tst := Test{
  6600  		Value: Other{Value: "StringVal"},
  6601  		Time:  end,
  6602  	}
  6603  
  6604  	errs = validate.Struct(tst)
  6605  	NotEqual(t, errs, nil)
  6606  	AssertError(t, errs, "Test.Time", "Test.Time", "Time", "Time", "gtfield")
  6607  }
  6608  
  6609  func TestLtField(t *testing.T) {
  6610  	var errs error
  6611  	validate := New()
  6612  
  6613  	type TimeTest struct {
  6614  		Start *time.Time `validate:"required,lt,ltfield=End"`
  6615  		End   *time.Time `validate:"required,lt"`
  6616  	}
  6617  
  6618  	now := time.Now()
  6619  	start := now.Add(time.Hour * 24 * -1 * 2)
  6620  	end := start.Add(time.Hour * 24)
  6621  
  6622  	timeTest := &TimeTest{
  6623  		Start: &start,
  6624  		End:   &end,
  6625  	}
  6626  
  6627  	errs = validate.Struct(timeTest)
  6628  	Equal(t, errs, nil)
  6629  
  6630  	timeTest = &TimeTest{
  6631  		Start: &end,
  6632  		End:   &start,
  6633  	}
  6634  
  6635  	errs = validate.Struct(timeTest)
  6636  	NotEqual(t, errs, nil)
  6637  	AssertError(t, errs, "TimeTest.Start", "TimeTest.Start", "Start", "Start", "ltfield")
  6638  
  6639  	errs = validate.VarWithValue(&start, &end, "ltfield")
  6640  	Equal(t, errs, nil)
  6641  
  6642  	errs = validate.VarWithValue(&end, &start, "ltfield")
  6643  	NotEqual(t, errs, nil)
  6644  	AssertError(t, errs, "", "", "", "", "ltfield")
  6645  
  6646  	errs = validate.VarWithValue(&end, timeTest, "ltfield")
  6647  	NotEqual(t, errs, nil)
  6648  	AssertError(t, errs, "", "", "", "", "ltfield")
  6649  
  6650  	errs = validate.VarWithValue("tes", "test", "ltfield")
  6651  	Equal(t, errs, nil)
  6652  
  6653  	// Tests for time.Duration type.
  6654  
  6655  	// -- Validations for variables of time.Duration type.
  6656  
  6657  	errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "ltfield")
  6658  	Equal(t, errs, nil)
  6659  
  6660  	errs = validate.VarWithValue(time.Hour, time.Hour, "ltfield")
  6661  	NotEqual(t, errs, nil)
  6662  	AssertError(t, errs, "", "", "", "", "ltfield")
  6663  
  6664  	errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "ltfield")
  6665  	NotEqual(t, errs, nil)
  6666  	AssertError(t, errs, "", "", "", "", "ltfield")
  6667  
  6668  	errs = validate.VarWithValue(time.Duration(0), -time.Minute, "omitempty,ltfield")
  6669  	Equal(t, errs, nil)
  6670  
  6671  	// -- Validations for a struct with time.Duration type fields.
  6672  
  6673  	type TimeDurationTest struct {
  6674  		First  time.Duration `validate:"ltfield=Second"`
  6675  		Second time.Duration
  6676  	}
  6677  	var timeDurationTest *TimeDurationTest
  6678  
  6679  	timeDurationTest = &TimeDurationTest{time.Hour, time.Hour + time.Minute}
  6680  	errs = validate.Struct(timeDurationTest)
  6681  	Equal(t, errs, nil)
  6682  
  6683  	timeDurationTest = &TimeDurationTest{time.Hour, time.Hour}
  6684  	errs = validate.Struct(timeDurationTest)
  6685  	NotEqual(t, errs, nil)
  6686  	AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "ltfield")
  6687  
  6688  	timeDurationTest = &TimeDurationTest{time.Hour, time.Hour - time.Minute}
  6689  	errs = validate.Struct(timeDurationTest)
  6690  	NotEqual(t, errs, nil)
  6691  	AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "ltfield")
  6692  
  6693  	type TimeDurationOmitemptyTest struct {
  6694  		First  time.Duration `validate:"omitempty,ltfield=Second"`
  6695  		Second time.Duration
  6696  	}
  6697  
  6698  	timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0), -time.Minute}
  6699  	errs = validate.Struct(timeDurationOmitemptyTest)
  6700  	Equal(t, errs, nil)
  6701  
  6702  	// Tests for Ints types.
  6703  
  6704  	type IntTest struct {
  6705  		Val1 int `validate:"required"`
  6706  		Val2 int `validate:"required,ltfield=Val1"`
  6707  	}
  6708  
  6709  	intTest := &IntTest{
  6710  		Val1: 5,
  6711  		Val2: 1,
  6712  	}
  6713  
  6714  	errs = validate.Struct(intTest)
  6715  	Equal(t, errs, nil)
  6716  
  6717  	intTest = &IntTest{
  6718  		Val1: 1,
  6719  		Val2: 5,
  6720  	}
  6721  
  6722  	errs = validate.Struct(intTest)
  6723  	NotEqual(t, errs, nil)
  6724  	AssertError(t, errs, "IntTest.Val2", "IntTest.Val2", "Val2", "Val2", "ltfield")
  6725  
  6726  	errs = validate.VarWithValue(int(1), int(5), "ltfield")
  6727  	Equal(t, errs, nil)
  6728  
  6729  	errs = validate.VarWithValue(int(5), int(1), "ltfield")
  6730  	NotEqual(t, errs, nil)
  6731  	AssertError(t, errs, "", "", "", "", "ltfield")
  6732  
  6733  	type UIntTest struct {
  6734  		Val1 uint `validate:"required"`
  6735  		Val2 uint `validate:"required,ltfield=Val1"`
  6736  	}
  6737  
  6738  	uIntTest := &UIntTest{
  6739  		Val1: 5,
  6740  		Val2: 1,
  6741  	}
  6742  
  6743  	errs = validate.Struct(uIntTest)
  6744  	Equal(t, errs, nil)
  6745  
  6746  	uIntTest = &UIntTest{
  6747  		Val1: 1,
  6748  		Val2: 5,
  6749  	}
  6750  
  6751  	errs = validate.Struct(uIntTest)
  6752  	NotEqual(t, errs, nil)
  6753  	AssertError(t, errs, "UIntTest.Val2", "UIntTest.Val2", "Val2", "Val2", "ltfield")
  6754  
  6755  	errs = validate.VarWithValue(uint(1), uint(5), "ltfield")
  6756  	Equal(t, errs, nil)
  6757  
  6758  	errs = validate.VarWithValue(uint(5), uint(1), "ltfield")
  6759  	NotEqual(t, errs, nil)
  6760  	AssertError(t, errs, "", "", "", "", "ltfield")
  6761  
  6762  	type FloatTest struct {
  6763  		Val1 float64 `validate:"required"`
  6764  		Val2 float64 `validate:"required,ltfield=Val1"`
  6765  	}
  6766  
  6767  	floatTest := &FloatTest{
  6768  		Val1: 5,
  6769  		Val2: 1,
  6770  	}
  6771  
  6772  	errs = validate.Struct(floatTest)
  6773  	Equal(t, errs, nil)
  6774  
  6775  	floatTest = &FloatTest{
  6776  		Val1: 1,
  6777  		Val2: 5,
  6778  	}
  6779  
  6780  	errs = validate.Struct(floatTest)
  6781  	NotEqual(t, errs, nil)
  6782  	AssertError(t, errs, "FloatTest.Val2", "FloatTest.Val2", "Val2", "Val2", "ltfield")
  6783  
  6784  	errs = validate.VarWithValue(float32(1), float32(5), "ltfield")
  6785  	Equal(t, errs, nil)
  6786  
  6787  	errs = validate.VarWithValue(float32(5), float32(1), "ltfield")
  6788  	NotEqual(t, errs, nil)
  6789  	AssertError(t, errs, "", "", "", "", "ltfield")
  6790  
  6791  	errs = validate.VarWithValue(nil, 5, "ltfield")
  6792  	NotEqual(t, errs, nil)
  6793  	AssertError(t, errs, "", "", "", "", "ltfield")
  6794  
  6795  	errs = validate.VarWithValue(1, "T", "ltfield")
  6796  	NotEqual(t, errs, nil)
  6797  	AssertError(t, errs, "", "", "", "", "ltfield")
  6798  
  6799  	errs = validate.VarWithValue(1, end, "ltfield")
  6800  	NotEqual(t, errs, nil)
  6801  	AssertError(t, errs, "", "", "", "", "ltfield")
  6802  
  6803  	type TimeTest2 struct {
  6804  		Start *time.Time `validate:"required"`
  6805  		End   *time.Time `validate:"required,ltfield=NonExistantField"`
  6806  	}
  6807  
  6808  	timeTest2 := &TimeTest2{
  6809  		Start: &end,
  6810  		End:   &start,
  6811  	}
  6812  
  6813  	errs = validate.Struct(timeTest2)
  6814  	NotEqual(t, errs, nil)
  6815  	AssertError(t, errs, "TimeTest2.End", "TimeTest2.End", "End", "End", "ltfield")
  6816  }
  6817  
  6818  func TestFieldContains(t *testing.T) {
  6819  	validate := New()
  6820  
  6821  	type StringTest struct {
  6822  		Foo string `validate:"fieldcontains=Bar"`
  6823  		Bar string
  6824  	}
  6825  
  6826  	stringTest := &StringTest{
  6827  		Foo: "foobar",
  6828  		Bar: "bar",
  6829  	}
  6830  
  6831  	errs := validate.Struct(stringTest)
  6832  	Equal(t, errs, nil)
  6833  
  6834  	stringTest = &StringTest{
  6835  		Foo: "foo",
  6836  		Bar: "bar",
  6837  	}
  6838  
  6839  	errs = validate.Struct(stringTest)
  6840  	NotEqual(t, errs, nil)
  6841  	AssertError(t, errs, "StringTest.Foo", "StringTest.Foo", "Foo", "Foo", "fieldcontains")
  6842  
  6843  	errs = validate.VarWithValue("foo", "bar", "fieldcontains")
  6844  	NotEqual(t, errs, nil)
  6845  	AssertError(t, errs, "", "", "", "", "fieldcontains")
  6846  
  6847  	errs = validate.VarWithValue("bar", "foobarfoo", "fieldcontains")
  6848  	NotEqual(t, errs, nil)
  6849  	AssertError(t, errs, "", "", "", "", "fieldcontains")
  6850  
  6851  	errs = validate.VarWithValue("foobarfoo", "bar", "fieldcontains")
  6852  	Equal(t, errs, nil)
  6853  
  6854  	type StringTestMissingField struct {
  6855  		Foo string `validate:"fieldcontains=Bar"`
  6856  	}
  6857  
  6858  	stringTestMissingField := &StringTestMissingField{
  6859  		Foo: "foo",
  6860  	}
  6861  
  6862  	errs = validate.Struct(stringTestMissingField)
  6863  	NotEqual(t, errs, nil)
  6864  	AssertError(t, errs, "StringTestMissingField.Foo", "StringTestMissingField.Foo", "Foo", "Foo", "fieldcontains")
  6865  }
  6866  
  6867  func TestFieldExcludes(t *testing.T) {
  6868  	validate := New()
  6869  
  6870  	type StringTest struct {
  6871  		Foo string `validate:"fieldexcludes=Bar"`
  6872  		Bar string
  6873  	}
  6874  
  6875  	stringTest := &StringTest{
  6876  		Foo: "foobar",
  6877  		Bar: "bar",
  6878  	}
  6879  
  6880  	errs := validate.Struct(stringTest)
  6881  	NotEqual(t, errs, nil)
  6882  	AssertError(t, errs, "StringTest.Foo", "StringTest.Foo", "Foo", "Foo", "fieldexcludes")
  6883  
  6884  	stringTest = &StringTest{
  6885  		Foo: "foo",
  6886  		Bar: "bar",
  6887  	}
  6888  
  6889  	errs = validate.Struct(stringTest)
  6890  	Equal(t, errs, nil)
  6891  
  6892  	errs = validate.VarWithValue("foo", "bar", "fieldexcludes")
  6893  	Equal(t, errs, nil)
  6894  
  6895  	errs = validate.VarWithValue("bar", "foobarfoo", "fieldexcludes")
  6896  	Equal(t, errs, nil)
  6897  
  6898  	errs = validate.VarWithValue("foobarfoo", "bar", "fieldexcludes")
  6899  	NotEqual(t, errs, nil)
  6900  	AssertError(t, errs, "", "", "", "", "fieldexcludes")
  6901  
  6902  	type StringTestMissingField struct {
  6903  		Foo string `validate:"fieldexcludes=Bar"`
  6904  	}
  6905  
  6906  	stringTestMissingField := &StringTestMissingField{
  6907  		Foo: "foo",
  6908  	}
  6909  
  6910  	errs = validate.Struct(stringTestMissingField)
  6911  	Equal(t, errs, nil)
  6912  }
  6913  
  6914  func TestContainsAndExcludes(t *testing.T) {
  6915  	validate := New()
  6916  
  6917  	type ImpossibleStringTest struct {
  6918  		Foo string `validate:"fieldcontains=Bar"`
  6919  		Bar string `validate:"fieldexcludes=Foo"`
  6920  	}
  6921  
  6922  	impossibleStringTest := &ImpossibleStringTest{
  6923  		Foo: "foo",
  6924  		Bar: "bar",
  6925  	}
  6926  
  6927  	errs := validate.Struct(impossibleStringTest)
  6928  	NotEqual(t, errs, nil)
  6929  	AssertError(t, errs, "ImpossibleStringTest.Foo", "ImpossibleStringTest.Foo", "Foo", "Foo", "fieldcontains")
  6930  
  6931  	impossibleStringTest = &ImpossibleStringTest{
  6932  		Foo: "bar",
  6933  		Bar: "foo",
  6934  	}
  6935  
  6936  	errs = validate.Struct(impossibleStringTest)
  6937  	NotEqual(t, errs, nil)
  6938  	AssertError(t, errs, "ImpossibleStringTest.Foo", "ImpossibleStringTest.Foo", "Foo", "Foo", "fieldcontains")
  6939  }
  6940  
  6941  func TestLteField(t *testing.T) {
  6942  	var errs error
  6943  	validate := New()
  6944  
  6945  	type TimeTest struct {
  6946  		Start *time.Time `validate:"required,lte,ltefield=End"`
  6947  		End   *time.Time `validate:"required,lte"`
  6948  	}
  6949  
  6950  	now := time.Now()
  6951  	start := now.Add(time.Hour * 24 * -1 * 2)
  6952  	end := start.Add(time.Hour * 24)
  6953  
  6954  	timeTest := &TimeTest{
  6955  		Start: &start,
  6956  		End:   &end,
  6957  	}
  6958  
  6959  	errs = validate.Struct(timeTest)
  6960  	Equal(t, errs, nil)
  6961  
  6962  	timeTest = &TimeTest{
  6963  		Start: &end,
  6964  		End:   &start,
  6965  	}
  6966  
  6967  	errs = validate.Struct(timeTest)
  6968  	NotEqual(t, errs, nil)
  6969  	AssertError(t, errs, "TimeTest.Start", "TimeTest.Start", "Start", "Start", "ltefield")
  6970  
  6971  	errs = validate.VarWithValue(&start, &end, "ltefield")
  6972  	Equal(t, errs, nil)
  6973  
  6974  	errs = validate.VarWithValue(&end, &start, "ltefield")
  6975  	NotEqual(t, errs, nil)
  6976  	AssertError(t, errs, "", "", "", "", "ltefield")
  6977  
  6978  	errs = validate.VarWithValue(&end, timeTest, "ltefield")
  6979  	NotEqual(t, errs, nil)
  6980  	AssertError(t, errs, "", "", "", "", "ltefield")
  6981  
  6982  	errs = validate.VarWithValue("tes", "test", "ltefield")
  6983  	Equal(t, errs, nil)
  6984  
  6985  	errs = validate.VarWithValue("test", "test", "ltefield")
  6986  	Equal(t, errs, nil)
  6987  
  6988  	// Tests for time.Duration type.
  6989  
  6990  	// -- Validations for variables of time.Duration type.
  6991  
  6992  	errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "ltefield")
  6993  	Equal(t, errs, nil)
  6994  
  6995  	errs = validate.VarWithValue(time.Hour, time.Hour, "ltefield")
  6996  	Equal(t, errs, nil)
  6997  
  6998  	errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "ltefield")
  6999  	NotEqual(t, errs, nil)
  7000  	AssertError(t, errs, "", "", "", "", "ltefield")
  7001  
  7002  	errs = validate.VarWithValue(time.Duration(0), -time.Minute, "omitempty,ltefield")
  7003  	Equal(t, errs, nil)
  7004  
  7005  	// -- Validations for a struct with time.Duration type fields.
  7006  
  7007  	type TimeDurationTest struct {
  7008  		First  time.Duration `validate:"ltefield=Second"`
  7009  		Second time.Duration
  7010  	}
  7011  	var timeDurationTest *TimeDurationTest
  7012  
  7013  	timeDurationTest = &TimeDurationTest{time.Hour, time.Hour + time.Minute}
  7014  	errs = validate.Struct(timeDurationTest)
  7015  	Equal(t, errs, nil)
  7016  
  7017  	timeDurationTest = &TimeDurationTest{time.Hour, time.Hour}
  7018  	errs = validate.Struct(timeDurationTest)
  7019  	Equal(t, errs, nil)
  7020  
  7021  	timeDurationTest = &TimeDurationTest{time.Hour, time.Hour - time.Minute}
  7022  	errs = validate.Struct(timeDurationTest)
  7023  	NotEqual(t, errs, nil)
  7024  	AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "ltefield")
  7025  
  7026  	type TimeDurationOmitemptyTest struct {
  7027  		First  time.Duration `validate:"omitempty,ltefield=Second"`
  7028  		Second time.Duration
  7029  	}
  7030  
  7031  	timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0), -time.Minute}
  7032  	errs = validate.Struct(timeDurationOmitemptyTest)
  7033  	Equal(t, errs, nil)
  7034  
  7035  	// Tests for Ints types.
  7036  
  7037  	type IntTest struct {
  7038  		Val1 int `validate:"required"`
  7039  		Val2 int `validate:"required,ltefield=Val1"`
  7040  	}
  7041  
  7042  	intTest := &IntTest{
  7043  		Val1: 5,
  7044  		Val2: 1,
  7045  	}
  7046  
  7047  	errs = validate.Struct(intTest)
  7048  	Equal(t, errs, nil)
  7049  
  7050  	intTest = &IntTest{
  7051  		Val1: 1,
  7052  		Val2: 5,
  7053  	}
  7054  
  7055  	errs = validate.Struct(intTest)
  7056  	NotEqual(t, errs, nil)
  7057  	AssertError(t, errs, "IntTest.Val2", "IntTest.Val2", "Val2", "Val2", "ltefield")
  7058  
  7059  	errs = validate.VarWithValue(int(1), int(5), "ltefield")
  7060  	Equal(t, errs, nil)
  7061  
  7062  	errs = validate.VarWithValue(int(5), int(1), "ltefield")
  7063  	NotEqual(t, errs, nil)
  7064  	AssertError(t, errs, "", "", "", "", "ltefield")
  7065  
  7066  	type UIntTest struct {
  7067  		Val1 uint `validate:"required"`
  7068  		Val2 uint `validate:"required,ltefield=Val1"`
  7069  	}
  7070  
  7071  	uIntTest := &UIntTest{
  7072  		Val1: 5,
  7073  		Val2: 1,
  7074  	}
  7075  
  7076  	errs = validate.Struct(uIntTest)
  7077  	Equal(t, errs, nil)
  7078  
  7079  	uIntTest = &UIntTest{
  7080  		Val1: 1,
  7081  		Val2: 5,
  7082  	}
  7083  
  7084  	errs = validate.Struct(uIntTest)
  7085  	NotEqual(t, errs, nil)
  7086  	AssertError(t, errs, "UIntTest.Val2", "UIntTest.Val2", "Val2", "Val2", "ltefield")
  7087  
  7088  	errs = validate.VarWithValue(uint(1), uint(5), "ltefield")
  7089  	Equal(t, errs, nil)
  7090  
  7091  	errs = validate.VarWithValue(uint(5), uint(1), "ltefield")
  7092  	NotEqual(t, errs, nil)
  7093  	AssertError(t, errs, "", "", "", "", "ltefield")
  7094  
  7095  	type FloatTest struct {
  7096  		Val1 float64 `validate:"required"`
  7097  		Val2 float64 `validate:"required,ltefield=Val1"`
  7098  	}
  7099  
  7100  	floatTest := &FloatTest{
  7101  		Val1: 5,
  7102  		Val2: 1,
  7103  	}
  7104  
  7105  	errs = validate.Struct(floatTest)
  7106  	Equal(t, errs, nil)
  7107  
  7108  	floatTest = &FloatTest{
  7109  		Val1: 1,
  7110  		Val2: 5,
  7111  	}
  7112  
  7113  	errs = validate.Struct(floatTest)
  7114  	NotEqual(t, errs, nil)
  7115  	AssertError(t, errs, "FloatTest.Val2", "FloatTest.Val2", "Val2", "Val2", "ltefield")
  7116  
  7117  	errs = validate.VarWithValue(float32(1), float32(5), "ltefield")
  7118  	Equal(t, errs, nil)
  7119  
  7120  	errs = validate.VarWithValue(float32(5), float32(1), "ltefield")
  7121  	NotEqual(t, errs, nil)
  7122  	AssertError(t, errs, "", "", "", "", "ltefield")
  7123  
  7124  	errs = validate.VarWithValue(nil, 5, "ltefield")
  7125  	NotEqual(t, errs, nil)
  7126  	AssertError(t, errs, "", "", "", "", "ltefield")
  7127  
  7128  	errs = validate.VarWithValue(1, "T", "ltefield")
  7129  	NotEqual(t, errs, nil)
  7130  	AssertError(t, errs, "", "", "", "", "ltefield")
  7131  
  7132  	errs = validate.VarWithValue(1, end, "ltefield")
  7133  	NotEqual(t, errs, nil)
  7134  	AssertError(t, errs, "", "", "", "", "ltefield")
  7135  
  7136  	type TimeTest2 struct {
  7137  		Start *time.Time `validate:"required"`
  7138  		End   *time.Time `validate:"required,ltefield=NonExistantField"`
  7139  	}
  7140  
  7141  	timeTest2 := &TimeTest2{
  7142  		Start: &end,
  7143  		End:   &start,
  7144  	}
  7145  
  7146  	errs = validate.Struct(timeTest2)
  7147  	NotEqual(t, errs, nil)
  7148  	AssertError(t, errs, "TimeTest2.End", "TimeTest2.End", "End", "End", "ltefield")
  7149  }
  7150  
  7151  func TestGteField(t *testing.T) {
  7152  	var errs error
  7153  	validate := New()
  7154  
  7155  	type TimeTest struct {
  7156  		Start *time.Time `validate:"required,gte"`
  7157  		End   *time.Time `validate:"required,gte,gtefield=Start"`
  7158  	}
  7159  
  7160  	now := time.Now()
  7161  	start := now.Add(time.Hour * 24)
  7162  	end := start.Add(time.Hour * 24)
  7163  
  7164  	timeTest := &TimeTest{
  7165  		Start: &start,
  7166  		End:   &end,
  7167  	}
  7168  
  7169  	errs = validate.Struct(timeTest)
  7170  	Equal(t, errs, nil)
  7171  
  7172  	timeTest = &TimeTest{
  7173  		Start: &end,
  7174  		End:   &start,
  7175  	}
  7176  
  7177  	errs = validate.Struct(timeTest)
  7178  	NotEqual(t, errs, nil)
  7179  	AssertError(t, errs, "TimeTest.End", "TimeTest.End", "End", "End", "gtefield")
  7180  
  7181  	errs = validate.VarWithValue(&end, &start, "gtefield")
  7182  	Equal(t, errs, nil)
  7183  
  7184  	errs = validate.VarWithValue(&start, &end, "gtefield")
  7185  	NotEqual(t, errs, nil)
  7186  	AssertError(t, errs, "", "", "", "", "gtefield")
  7187  
  7188  	errs = validate.VarWithValue(&start, timeTest, "gtefield")
  7189  	NotEqual(t, errs, nil)
  7190  	AssertError(t, errs, "", "", "", "", "gtefield")
  7191  
  7192  	errs = validate.VarWithValue("test", "test", "gtefield")
  7193  	Equal(t, errs, nil)
  7194  
  7195  	errs = validate.VarWithValue("test bigger", "test", "gtefield")
  7196  	Equal(t, errs, nil)
  7197  
  7198  	// Tests for time.Duration type.
  7199  
  7200  	// -- Validations for variables of time.Duration type.
  7201  
  7202  	errs = validate.VarWithValue(time.Hour, time.Hour-time.Minute, "gtefield")
  7203  	Equal(t, errs, nil)
  7204  
  7205  	errs = validate.VarWithValue(time.Hour, time.Hour, "gtefield")
  7206  	Equal(t, errs, nil)
  7207  
  7208  	errs = validate.VarWithValue(time.Hour, time.Hour+time.Minute, "gtefield")
  7209  	NotEqual(t, errs, nil)
  7210  	AssertError(t, errs, "", "", "", "", "gtefield")
  7211  
  7212  	errs = validate.VarWithValue(time.Duration(0), time.Hour, "omitempty,gtefield")
  7213  	Equal(t, errs, nil)
  7214  
  7215  	// -- Validations for a struct with time.Duration type fields.
  7216  
  7217  	type TimeDurationTest struct {
  7218  		First  time.Duration `validate:"gtefield=Second"`
  7219  		Second time.Duration
  7220  	}
  7221  	var timeDurationTest *TimeDurationTest
  7222  
  7223  	timeDurationTest = &TimeDurationTest{time.Hour, time.Hour - time.Minute}
  7224  	errs = validate.Struct(timeDurationTest)
  7225  	Equal(t, errs, nil)
  7226  
  7227  	timeDurationTest = &TimeDurationTest{time.Hour, time.Hour}
  7228  	errs = validate.Struct(timeDurationTest)
  7229  	Equal(t, errs, nil)
  7230  
  7231  	timeDurationTest = &TimeDurationTest{time.Hour, time.Hour + time.Minute}
  7232  	errs = validate.Struct(timeDurationTest)
  7233  	NotEqual(t, errs, nil)
  7234  	AssertError(t, errs, "TimeDurationTest.First", "TimeDurationTest.First", "First", "First", "gtefield")
  7235  
  7236  	type TimeDurationOmitemptyTest struct {
  7237  		First  time.Duration `validate:"omitempty,gtefield=Second"`
  7238  		Second time.Duration
  7239  	}
  7240  
  7241  	timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0), time.Hour}
  7242  	errs = validate.Struct(timeDurationOmitemptyTest)
  7243  	Equal(t, errs, nil)
  7244  
  7245  	// Tests for Ints types.
  7246  
  7247  	type IntTest struct {
  7248  		Val1 int `validate:"required"`
  7249  		Val2 int `validate:"required,gtefield=Val1"`
  7250  	}
  7251  
  7252  	intTest := &IntTest{
  7253  		Val1: 1,
  7254  		Val2: 5,
  7255  	}
  7256  
  7257  	errs = validate.Struct(intTest)
  7258  	Equal(t, errs, nil)
  7259  
  7260  	intTest = &IntTest{
  7261  		Val1: 5,
  7262  		Val2: 1,
  7263  	}
  7264  
  7265  	errs = validate.Struct(intTest)
  7266  	NotEqual(t, errs, nil)
  7267  	AssertError(t, errs, "IntTest.Val2", "IntTest.Val2", "Val2", "Val2", "gtefield")
  7268  
  7269  	errs = validate.VarWithValue(int(5), int(1), "gtefield")
  7270  	Equal(t, errs, nil)
  7271  
  7272  	errs = validate.VarWithValue(int(1), int(5), "gtefield")
  7273  	NotEqual(t, errs, nil)
  7274  	AssertError(t, errs, "", "", "", "", "gtefield")
  7275  
  7276  	type UIntTest struct {
  7277  		Val1 uint `validate:"required"`
  7278  		Val2 uint `validate:"required,gtefield=Val1"`
  7279  	}
  7280  
  7281  	uIntTest := &UIntTest{
  7282  		Val1: 1,
  7283  		Val2: 5,
  7284  	}
  7285  
  7286  	errs = validate.Struct(uIntTest)
  7287  	Equal(t, errs, nil)
  7288  
  7289  	uIntTest = &UIntTest{
  7290  		Val1: 5,
  7291  		Val2: 1,
  7292  	}
  7293  
  7294  	errs = validate.Struct(uIntTest)
  7295  	NotEqual(t, errs, nil)
  7296  	AssertError(t, errs, "UIntTest.Val2", "UIntTest.Val2", "Val2", "Val2", "gtefield")
  7297  
  7298  	errs = validate.VarWithValue(uint(5), uint(1), "gtefield")
  7299  	Equal(t, errs, nil)
  7300  
  7301  	errs = validate.VarWithValue(uint(1), uint(5), "gtefield")
  7302  	NotEqual(t, errs, nil)
  7303  	AssertError(t, errs, "", "", "", "", "gtefield")
  7304  
  7305  	type FloatTest struct {
  7306  		Val1 float64 `validate:"required"`
  7307  		Val2 float64 `validate:"required,gtefield=Val1"`
  7308  	}
  7309  
  7310  	floatTest := &FloatTest{
  7311  		Val1: 1,
  7312  		Val2: 5,
  7313  	}
  7314  
  7315  	errs = validate.Struct(floatTest)
  7316  	Equal(t, errs, nil)
  7317  
  7318  	floatTest = &FloatTest{
  7319  		Val1: 5,
  7320  		Val2: 1,
  7321  	}
  7322  
  7323  	errs = validate.Struct(floatTest)
  7324  	NotEqual(t, errs, nil)
  7325  	AssertError(t, errs, "FloatTest.Val2", "FloatTest.Val2", "Val2", "Val2", "gtefield")
  7326  
  7327  	errs = validate.VarWithValue(float32(5), float32(1), "gtefield")
  7328  	Equal(t, errs, nil)
  7329  
  7330  	errs = validate.VarWithValue(float32(1), float32(5), "gtefield")
  7331  	NotEqual(t, errs, nil)
  7332  	AssertError(t, errs, "", "", "", "", "gtefield")
  7333  
  7334  	errs = validate.VarWithValue(nil, 1, "gtefield")
  7335  	NotEqual(t, errs, nil)
  7336  	AssertError(t, errs, "", "", "", "", "gtefield")
  7337  
  7338  	errs = validate.VarWithValue(5, "T", "gtefield")
  7339  	NotEqual(t, errs, nil)
  7340  	AssertError(t, errs, "", "", "", "", "gtefield")
  7341  
  7342  	errs = validate.VarWithValue(5, start, "gtefield")
  7343  	NotEqual(t, errs, nil)
  7344  	AssertError(t, errs, "", "", "", "", "gtefield")
  7345  
  7346  	type TimeTest2 struct {
  7347  		Start *time.Time `validate:"required"`
  7348  		End   *time.Time `validate:"required,gtefield=NonExistantField"`
  7349  	}
  7350  
  7351  	timeTest2 := &TimeTest2{
  7352  		Start: &start,
  7353  		End:   &end,
  7354  	}
  7355  
  7356  	errs = validate.Struct(timeTest2)
  7357  	NotEqual(t, errs, nil)
  7358  	AssertError(t, errs, "TimeTest2.End", "TimeTest2.End", "End", "End", "gtefield")
  7359  }
  7360  
  7361  func TestValidateByTagAndValue(t *testing.T) {
  7362  	validate := New()
  7363  
  7364  	val := "test"
  7365  	field := "test"
  7366  	errs := validate.VarWithValue(val, field, "required")
  7367  	Equal(t, errs, nil)
  7368  
  7369  	fn := func(fl FieldLevel) bool {
  7370  		return fl.Parent().String() == fl.Field().String()
  7371  	}
  7372  
  7373  	errs = validate.RegisterValidation("isequaltestfunc", fn)
  7374  	Equal(t, errs, nil)
  7375  
  7376  	errs = validate.VarWithValue(val, field, "isequaltestfunc")
  7377  	Equal(t, errs, nil)
  7378  
  7379  	val = "unequal"
  7380  
  7381  	errs = validate.VarWithValue(val, field, "isequaltestfunc")
  7382  	NotEqual(t, errs, nil)
  7383  	AssertError(t, errs, "", "", "", "", "isequaltestfunc")
  7384  }
  7385  
  7386  func TestAddFunctions(t *testing.T) {
  7387  	fn := func(fl FieldLevel) bool {
  7388  		return true
  7389  	}
  7390  
  7391  	fnCtx := func(ctx context.Context, fl FieldLevel) bool {
  7392  		return true
  7393  	}
  7394  
  7395  	validate := New()
  7396  
  7397  	errs := validate.RegisterValidation("new", fn)
  7398  	Equal(t, errs, nil)
  7399  
  7400  	errs = validate.RegisterValidation("", fn)
  7401  	NotEqual(t, errs, nil)
  7402  
  7403  	errs = validate.RegisterValidation("new", nil)
  7404  	NotEqual(t, errs, nil)
  7405  
  7406  	errs = validate.RegisterValidation("new", fn)
  7407  	Equal(t, errs, nil)
  7408  
  7409  	errs = validate.RegisterValidationCtx("new", fnCtx)
  7410  	Equal(t, errs, nil)
  7411  
  7412  	PanicMatches(t, func() { _ = validate.RegisterValidation("dive", fn) }, "Tag 'dive' either contains restricted characters or is the same as a restricted tag needed for normal operation")
  7413  }
  7414  
  7415  func TestChangeTag(t *testing.T) {
  7416  	validate := New()
  7417  	validate.SetTagName("val")
  7418  
  7419  	type Test struct {
  7420  		Name string `val:"len=4"`
  7421  	}
  7422  	s := &Test{
  7423  		Name: "TEST",
  7424  	}
  7425  
  7426  	errs := validate.Struct(s)
  7427  	Equal(t, errs, nil)
  7428  
  7429  	s.Name = ""
  7430  
  7431  	errs = validate.Struct(s)
  7432  	NotEqual(t, errs, nil)
  7433  	AssertError(t, errs, "Test.Name", "Test.Name", "Name", "Name", "len")
  7434  }
  7435  
  7436  func TestUnexposedStruct(t *testing.T) {
  7437  	validate := New()
  7438  
  7439  	type Test struct {
  7440  		Name      string
  7441  		unexposed struct {
  7442  			A string `validate:"required"`
  7443  		}
  7444  	}
  7445  
  7446  	s := &Test{
  7447  		Name: "TEST",
  7448  	}
  7449  	Equal(t, s.unexposed.A, "")
  7450  
  7451  	errs := validate.Struct(s)
  7452  	Equal(t, errs, nil)
  7453  }
  7454  
  7455  func TestBadParams(t *testing.T) {
  7456  	validate := New()
  7457  	i := 1
  7458  	errs := validate.Var(i, "-")
  7459  	Equal(t, errs, nil)
  7460  
  7461  	PanicMatches(t, func() { _ = validate.Var(i, "len=a") }, "strconv.ParseInt: parsing \"a\": invalid syntax")
  7462  	PanicMatches(t, func() { _ = validate.Var(i, "len=a") }, "strconv.ParseInt: parsing \"a\": invalid syntax")
  7463  
  7464  	var ui uint = 1
  7465  	PanicMatches(t, func() { _ = validate.Var(ui, "len=a") }, "strconv.ParseUint: parsing \"a\": invalid syntax")
  7466  
  7467  	f := 1.23
  7468  	PanicMatches(t, func() { _ = validate.Var(f, "len=a") }, "strconv.ParseFloat: parsing \"a\": invalid syntax")
  7469  }
  7470  
  7471  func TestLength(t *testing.T) {
  7472  	validate := New()
  7473  	i := true
  7474  	PanicMatches(t, func() { _ = validate.Var(i, "len") }, "Bad field type bool")
  7475  }
  7476  
  7477  func TestIsGt(t *testing.T) {
  7478  	var errs error
  7479  	validate := New()
  7480  
  7481  	myMap := map[string]string{}
  7482  	errs = validate.Var(myMap, "gt=0")
  7483  	NotEqual(t, errs, nil)
  7484  
  7485  	f := 1.23
  7486  	errs = validate.Var(f, "gt=5")
  7487  	NotEqual(t, errs, nil)
  7488  	AssertError(t, errs, "", "", "", "", "gt")
  7489  
  7490  	var ui uint = 5
  7491  	errs = validate.Var(ui, "gt=10")
  7492  	NotEqual(t, errs, nil)
  7493  	AssertError(t, errs, "", "", "", "", "gt")
  7494  
  7495  	i := true
  7496  	PanicMatches(t, func() { _ = validate.Var(i, "gt") }, "Bad field type bool")
  7497  
  7498  	tm := time.Now().UTC()
  7499  	tm = tm.Add(time.Hour * 24)
  7500  
  7501  	errs = validate.Var(tm, "gt")
  7502  	Equal(t, errs, nil)
  7503  
  7504  	t2 := time.Now().UTC().Add(-time.Hour)
  7505  
  7506  	errs = validate.Var(t2, "gt")
  7507  	NotEqual(t, errs, nil)
  7508  	AssertError(t, errs, "", "", "", "", "gt")
  7509  
  7510  	type Test struct {
  7511  		Now *time.Time `validate:"gt"`
  7512  	}
  7513  	s := &Test{
  7514  		Now: &tm,
  7515  	}
  7516  
  7517  	errs = validate.Struct(s)
  7518  	Equal(t, errs, nil)
  7519  
  7520  	s = &Test{
  7521  		Now: &t2,
  7522  	}
  7523  
  7524  	errs = validate.Struct(s)
  7525  	NotEqual(t, errs, nil)
  7526  	AssertError(t, errs, "Test.Now", "Test.Now", "Now", "Now", "gt")
  7527  
  7528  	// Tests for time.Duration type.
  7529  
  7530  	// -- Validations for a variable of time.Duration type.
  7531  
  7532  	errs = validate.Var(time.Hour, "gt=59m")
  7533  	Equal(t, errs, nil)
  7534  
  7535  	errs = validate.Var(time.Hour-time.Minute, "gt=59m")
  7536  	NotEqual(t, errs, nil)
  7537  	AssertError(t, errs, "", "", "", "", "gt")
  7538  
  7539  	errs = validate.Var(time.Hour-2*time.Minute, "gt=59m")
  7540  	NotEqual(t, errs, nil)
  7541  	AssertError(t, errs, "", "", "", "", "gt")
  7542  
  7543  	errs = validate.Var(time.Duration(0), "omitempty,gt=59m")
  7544  	Equal(t, errs, nil)
  7545  
  7546  	// -- Validations for a struct with a time.Duration type field.
  7547  
  7548  	type TimeDurationTest struct {
  7549  		Duration time.Duration `validate:"gt=59m"`
  7550  	}
  7551  	var timeDurationTest *TimeDurationTest
  7552  
  7553  	timeDurationTest = &TimeDurationTest{time.Hour}
  7554  	errs = validate.Struct(timeDurationTest)
  7555  	Equal(t, errs, nil)
  7556  
  7557  	timeDurationTest = &TimeDurationTest{time.Hour - time.Minute}
  7558  	errs = validate.Struct(timeDurationTest)
  7559  	NotEqual(t, errs, nil)
  7560  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "gt")
  7561  
  7562  	timeDurationTest = &TimeDurationTest{time.Hour - 2*time.Minute}
  7563  	errs = validate.Struct(timeDurationTest)
  7564  	NotEqual(t, errs, nil)
  7565  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "gt")
  7566  
  7567  	type TimeDurationOmitemptyTest struct {
  7568  		Duration time.Duration `validate:"omitempty,gt=59m"`
  7569  	}
  7570  
  7571  	timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
  7572  	errs = validate.Struct(timeDurationOmitemptyTest)
  7573  	Equal(t, errs, nil)
  7574  }
  7575  
  7576  func TestIsGte(t *testing.T) {
  7577  	var errs error
  7578  	validate := New()
  7579  
  7580  	i := true
  7581  	PanicMatches(t, func() { _ = validate.Var(i, "gte") }, "Bad field type bool")
  7582  
  7583  	t1 := time.Now().UTC()
  7584  	t1 = t1.Add(time.Hour * 24)
  7585  
  7586  	errs = validate.Var(t1, "gte")
  7587  	Equal(t, errs, nil)
  7588  
  7589  	t2 := time.Now().UTC().Add(-time.Hour)
  7590  
  7591  	errs = validate.Var(t2, "gte")
  7592  	NotEqual(t, errs, nil)
  7593  	AssertError(t, errs, "", "", "", "", "gte")
  7594  
  7595  	type Test struct {
  7596  		Now *time.Time `validate:"gte"`
  7597  	}
  7598  	s := &Test{
  7599  		Now: &t1,
  7600  	}
  7601  
  7602  	errs = validate.Struct(s)
  7603  	Equal(t, errs, nil)
  7604  
  7605  	s = &Test{
  7606  		Now: &t2,
  7607  	}
  7608  
  7609  	errs = validate.Struct(s)
  7610  	NotEqual(t, errs, nil)
  7611  	AssertError(t, errs, "Test.Now", "Test.Now", "Now", "Now", "gte")
  7612  
  7613  	// Tests for time.Duration type.
  7614  
  7615  	// -- Validations for a variable of time.Duration type.
  7616  
  7617  	errs = validate.Var(time.Hour, "gte=59m")
  7618  	Equal(t, errs, nil)
  7619  
  7620  	errs = validate.Var(time.Hour-time.Minute, "gte=59m")
  7621  	Equal(t, errs, nil)
  7622  
  7623  	errs = validate.Var(time.Hour-2*time.Minute, "gte=59m")
  7624  	NotEqual(t, errs, nil)
  7625  	AssertError(t, errs, "", "", "", "", "gte")
  7626  
  7627  	errs = validate.Var(time.Duration(0), "omitempty,gte=59m")
  7628  	Equal(t, errs, nil)
  7629  
  7630  	// -- Validations for a struct with a time.Duration type field.
  7631  
  7632  	type TimeDurationTest struct {
  7633  		Duration time.Duration `validate:"gte=59m"`
  7634  	}
  7635  	var timeDurationTest *TimeDurationTest
  7636  
  7637  	timeDurationTest = &TimeDurationTest{time.Hour}
  7638  	errs = validate.Struct(timeDurationTest)
  7639  	Equal(t, errs, nil)
  7640  
  7641  	timeDurationTest = &TimeDurationTest{time.Hour - time.Minute}
  7642  	errs = validate.Struct(timeDurationTest)
  7643  	Equal(t, errs, nil)
  7644  
  7645  	timeDurationTest = &TimeDurationTest{time.Hour - 2*time.Minute}
  7646  	errs = validate.Struct(timeDurationTest)
  7647  	NotEqual(t, errs, nil)
  7648  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "gte")
  7649  
  7650  	type TimeDurationOmitemptyTest struct {
  7651  		Duration time.Duration `validate:"omitempty,gte=59m"`
  7652  	}
  7653  
  7654  	timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
  7655  	errs = validate.Struct(timeDurationOmitemptyTest)
  7656  	Equal(t, errs, nil)
  7657  }
  7658  
  7659  func TestMinValidation(t *testing.T) {
  7660  	var errs error
  7661  	validate := New()
  7662  
  7663  	// Tests for time.Duration type.
  7664  
  7665  	// -- Validations for a variable of time.Duration type.
  7666  
  7667  	errs = validate.Var(time.Hour, "min=59m")
  7668  	Equal(t, errs, nil)
  7669  
  7670  	errs = validate.Var(time.Hour-time.Minute, "min=59m")
  7671  	Equal(t, errs, nil)
  7672  
  7673  	errs = validate.Var(time.Hour-2*time.Minute, "min=59m")
  7674  	NotEqual(t, errs, nil)
  7675  	AssertError(t, errs, "", "", "", "", "min")
  7676  
  7677  	errs = validate.Var(time.Duration(0), "omitempty,min=59m")
  7678  	Equal(t, errs, nil)
  7679  
  7680  	// -- Validations for a struct with a time.Duration type field.
  7681  
  7682  	type TimeDurationTest struct {
  7683  		Duration time.Duration `validate:"min=59m"`
  7684  	}
  7685  	var timeDurationTest *TimeDurationTest
  7686  
  7687  	timeDurationTest = &TimeDurationTest{time.Hour}
  7688  	errs = validate.Struct(timeDurationTest)
  7689  	Equal(t, errs, nil)
  7690  
  7691  	timeDurationTest = &TimeDurationTest{time.Hour - time.Minute}
  7692  	errs = validate.Struct(timeDurationTest)
  7693  	Equal(t, errs, nil)
  7694  
  7695  	timeDurationTest = &TimeDurationTest{time.Hour - 2*time.Minute}
  7696  	errs = validate.Struct(timeDurationTest)
  7697  	NotEqual(t, errs, nil)
  7698  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "min")
  7699  
  7700  	type TimeDurationOmitemptyTest struct {
  7701  		Duration time.Duration `validate:"omitempty,min=59m"`
  7702  	}
  7703  
  7704  	timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
  7705  	errs = validate.Struct(timeDurationOmitemptyTest)
  7706  	Equal(t, errs, nil)
  7707  }
  7708  
  7709  func TestMaxValidation(t *testing.T) {
  7710  	var errs error
  7711  	validate := New()
  7712  
  7713  	// Tests for time.Duration type.
  7714  
  7715  	// -- Validations for a variable of time.Duration type.
  7716  
  7717  	errs = validate.Var(time.Hour, "max=1h1m")
  7718  	Equal(t, errs, nil)
  7719  
  7720  	errs = validate.Var(time.Hour+time.Minute, "max=1h1m")
  7721  	Equal(t, errs, nil)
  7722  
  7723  	errs = validate.Var(time.Hour+2*time.Minute, "max=1h1m")
  7724  	NotEqual(t, errs, nil)
  7725  	AssertError(t, errs, "", "", "", "", "max")
  7726  
  7727  	errs = validate.Var(time.Duration(0), "omitempty,max=-1s")
  7728  	Equal(t, errs, nil)
  7729  
  7730  	// -- Validations for a struct with a time.Duration type field.
  7731  
  7732  	type TimeDurationTest struct {
  7733  		Duration time.Duration `validate:"max=1h1m"`
  7734  	}
  7735  	var timeDurationTest *TimeDurationTest
  7736  
  7737  	timeDurationTest = &TimeDurationTest{time.Hour}
  7738  	errs = validate.Struct(timeDurationTest)
  7739  	Equal(t, errs, nil)
  7740  
  7741  	timeDurationTest = &TimeDurationTest{time.Hour + time.Minute}
  7742  	errs = validate.Struct(timeDurationTest)
  7743  	Equal(t, errs, nil)
  7744  
  7745  	timeDurationTest = &TimeDurationTest{time.Hour + 2*time.Minute}
  7746  	errs = validate.Struct(timeDurationTest)
  7747  	NotEqual(t, errs, nil)
  7748  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "max")
  7749  
  7750  	type TimeDurationOmitemptyTest struct {
  7751  		Duration time.Duration `validate:"omitempty,max=-1s"`
  7752  	}
  7753  
  7754  	timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
  7755  	errs = validate.Struct(timeDurationOmitemptyTest)
  7756  	Equal(t, errs, nil)
  7757  }
  7758  
  7759  func TestMinMaxValidation(t *testing.T) {
  7760  	var errs error
  7761  	validate := New()
  7762  
  7763  	// Tests for time.Duration type.
  7764  
  7765  	// -- Validations for a variable of time.Duration type.
  7766  
  7767  	errs = validate.Var(time.Hour, "min=59m,max=1h1m")
  7768  	Equal(t, errs, nil)
  7769  
  7770  	errs = validate.Var(time.Hour-time.Minute, "min=59m,max=1h1m")
  7771  	Equal(t, errs, nil)
  7772  
  7773  	errs = validate.Var(time.Hour+time.Minute, "min=59m,max=1h1m")
  7774  	Equal(t, errs, nil)
  7775  
  7776  	errs = validate.Var(time.Hour-2*time.Minute, "min=59m,max=1h1m")
  7777  	NotEqual(t, errs, nil)
  7778  	AssertError(t, errs, "", "", "", "", "min")
  7779  
  7780  	errs = validate.Var(time.Hour+2*time.Minute, "min=59m,max=1h1m")
  7781  	NotEqual(t, errs, nil)
  7782  	AssertError(t, errs, "", "", "", "", "max")
  7783  
  7784  	errs = validate.Var(time.Duration(0), "omitempty,min=59m,max=1h1m")
  7785  	Equal(t, errs, nil)
  7786  
  7787  	// -- Validations for a struct with a time.Duration type field.
  7788  
  7789  	type TimeDurationTest struct {
  7790  		Duration time.Duration `validate:"min=59m,max=1h1m"`
  7791  	}
  7792  	var timeDurationTest *TimeDurationTest
  7793  
  7794  	timeDurationTest = &TimeDurationTest{time.Hour}
  7795  	errs = validate.Struct(timeDurationTest)
  7796  	Equal(t, errs, nil)
  7797  
  7798  	timeDurationTest = &TimeDurationTest{time.Hour - time.Minute}
  7799  	errs = validate.Struct(timeDurationTest)
  7800  	Equal(t, errs, nil)
  7801  
  7802  	timeDurationTest = &TimeDurationTest{time.Hour + time.Minute}
  7803  	errs = validate.Struct(timeDurationTest)
  7804  	Equal(t, errs, nil)
  7805  
  7806  	timeDurationTest = &TimeDurationTest{time.Hour - 2*time.Minute}
  7807  	errs = validate.Struct(timeDurationTest)
  7808  	NotEqual(t, errs, nil)
  7809  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "min")
  7810  
  7811  	timeDurationTest = &TimeDurationTest{time.Hour + 2*time.Minute}
  7812  	errs = validate.Struct(timeDurationTest)
  7813  	NotEqual(t, errs, nil)
  7814  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "max")
  7815  
  7816  	type TimeDurationOmitemptyTest struct {
  7817  		Duration time.Duration `validate:"omitempty,min=59m,max=1h1m"`
  7818  	}
  7819  
  7820  	timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
  7821  	errs = validate.Struct(timeDurationOmitemptyTest)
  7822  	Equal(t, errs, nil)
  7823  }
  7824  
  7825  func TestLenValidation(t *testing.T) {
  7826  	var errs error
  7827  	validate := New()
  7828  
  7829  	// Tests for time.Duration type.
  7830  
  7831  	// -- Validations for a variable of time.Duration type.
  7832  
  7833  	errs = validate.Var(time.Hour, "len=1h")
  7834  	Equal(t, errs, nil)
  7835  
  7836  	errs = validate.Var(time.Hour-time.Minute, "len=1h")
  7837  	NotEqual(t, errs, nil)
  7838  	AssertError(t, errs, "", "", "", "", "len")
  7839  
  7840  	errs = validate.Var(time.Hour+time.Minute, "len=1h")
  7841  	NotEqual(t, errs, nil)
  7842  	AssertError(t, errs, "", "", "", "", "len")
  7843  
  7844  	errs = validate.Var(time.Duration(0), "omitempty,len=1h")
  7845  	Equal(t, errs, nil)
  7846  
  7847  	// -- Validations for a struct with a time.Duration type field.
  7848  
  7849  	type TimeDurationTest struct {
  7850  		Duration time.Duration `validate:"len=1h"`
  7851  	}
  7852  	var timeDurationTest *TimeDurationTest
  7853  
  7854  	timeDurationTest = &TimeDurationTest{time.Hour}
  7855  	errs = validate.Struct(timeDurationTest)
  7856  	Equal(t, errs, nil)
  7857  
  7858  	timeDurationTest = &TimeDurationTest{time.Hour - time.Minute}
  7859  	errs = validate.Struct(timeDurationTest)
  7860  	NotEqual(t, errs, nil)
  7861  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "len")
  7862  
  7863  	timeDurationTest = &TimeDurationTest{time.Hour + time.Minute}
  7864  	errs = validate.Struct(timeDurationTest)
  7865  	NotEqual(t, errs, nil)
  7866  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "len")
  7867  
  7868  	type TimeDurationOmitemptyTest struct {
  7869  		Duration time.Duration `validate:"omitempty,len=1h"`
  7870  	}
  7871  
  7872  	timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
  7873  	errs = validate.Struct(timeDurationOmitemptyTest)
  7874  	Equal(t, errs, nil)
  7875  }
  7876  
  7877  func TestIsLt(t *testing.T) {
  7878  	var errs error
  7879  	validate := New()
  7880  
  7881  	myMap := map[string]string{}
  7882  	errs = validate.Var(myMap, "lt=0")
  7883  	NotEqual(t, errs, nil)
  7884  	AssertError(t, errs, "", "", "", "", "lt")
  7885  
  7886  	f := 1.23
  7887  	errs = validate.Var(f, "lt=0")
  7888  	NotEqual(t, errs, nil)
  7889  	AssertError(t, errs, "", "", "", "", "lt")
  7890  
  7891  	var ui uint = 5
  7892  	errs = validate.Var(ui, "lt=0")
  7893  	NotEqual(t, errs, nil)
  7894  	AssertError(t, errs, "", "", "", "", "lt")
  7895  
  7896  	i := true
  7897  	PanicMatches(t, func() { _ = validate.Var(i, "lt") }, "Bad field type bool")
  7898  
  7899  	t1 := time.Now().UTC().Add(-time.Hour)
  7900  
  7901  	errs = validate.Var(t1, "lt")
  7902  	Equal(t, errs, nil)
  7903  
  7904  	t2 := time.Now().UTC()
  7905  	t2 = t2.Add(time.Hour * 24)
  7906  
  7907  	errs = validate.Var(t2, "lt")
  7908  	NotEqual(t, errs, nil)
  7909  	AssertError(t, errs, "", "", "", "", "lt")
  7910  
  7911  	type Test struct {
  7912  		Now *time.Time `validate:"lt"`
  7913  	}
  7914  
  7915  	s := &Test{
  7916  		Now: &t1,
  7917  	}
  7918  
  7919  	errs = validate.Struct(s)
  7920  	Equal(t, errs, nil)
  7921  
  7922  	s = &Test{
  7923  		Now: &t2,
  7924  	}
  7925  
  7926  	errs = validate.Struct(s)
  7927  	NotEqual(t, errs, nil)
  7928  	AssertError(t, errs, "Test.Now", "Test.Now", "Now", "Now", "lt")
  7929  
  7930  	// Tests for time.Duration type.
  7931  
  7932  	// -- Validations for a variable of time.Duration type.
  7933  
  7934  	errs = validate.Var(time.Hour, "lt=1h1m")
  7935  	Equal(t, errs, nil)
  7936  
  7937  	errs = validate.Var(time.Hour+time.Minute, "lt=1h1m")
  7938  	NotEqual(t, errs, nil)
  7939  	AssertError(t, errs, "", "", "", "", "lt")
  7940  
  7941  	errs = validate.Var(time.Hour+2*time.Minute, "lt=1h1m")
  7942  	NotEqual(t, errs, nil)
  7943  	AssertError(t, errs, "", "", "", "", "lt")
  7944  
  7945  	errs = validate.Var(time.Duration(0), "omitempty,lt=0")
  7946  	Equal(t, errs, nil)
  7947  
  7948  	// -- Validations for a struct with a time.Duration type field.
  7949  
  7950  	type TimeDurationTest struct {
  7951  		Duration time.Duration `validate:"lt=1h1m"`
  7952  	}
  7953  	var timeDurationTest *TimeDurationTest
  7954  
  7955  	timeDurationTest = &TimeDurationTest{time.Hour}
  7956  	errs = validate.Struct(timeDurationTest)
  7957  	Equal(t, errs, nil)
  7958  
  7959  	timeDurationTest = &TimeDurationTest{time.Hour + time.Minute}
  7960  	errs = validate.Struct(timeDurationTest)
  7961  	NotEqual(t, errs, nil)
  7962  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "lt")
  7963  
  7964  	timeDurationTest = &TimeDurationTest{time.Hour + 2*time.Minute}
  7965  	errs = validate.Struct(timeDurationTest)
  7966  	NotEqual(t, errs, nil)
  7967  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "lt")
  7968  
  7969  	type TimeDurationOmitemptyTest struct {
  7970  		Duration time.Duration `validate:"omitempty,lt=0"`
  7971  	}
  7972  
  7973  	timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
  7974  	errs = validate.Struct(timeDurationOmitemptyTest)
  7975  	Equal(t, errs, nil)
  7976  }
  7977  
  7978  func TestIsLte(t *testing.T) {
  7979  	var errs error
  7980  	validate := New()
  7981  
  7982  	i := true
  7983  	PanicMatches(t, func() { _ = validate.Var(i, "lte") }, "Bad field type bool")
  7984  
  7985  	t1 := time.Now().UTC().Add(-time.Hour)
  7986  
  7987  	errs = validate.Var(t1, "lte")
  7988  	Equal(t, errs, nil)
  7989  
  7990  	t2 := time.Now().UTC()
  7991  	t2 = t2.Add(time.Hour * 24)
  7992  
  7993  	errs = validate.Var(t2, "lte")
  7994  	NotEqual(t, errs, nil)
  7995  	AssertError(t, errs, "", "", "", "", "lte")
  7996  
  7997  	type Test struct {
  7998  		Now *time.Time `validate:"lte"`
  7999  	}
  8000  
  8001  	s := &Test{
  8002  		Now: &t1,
  8003  	}
  8004  
  8005  	errs = validate.Struct(s)
  8006  	Equal(t, errs, nil)
  8007  
  8008  	s = &Test{
  8009  		Now: &t2,
  8010  	}
  8011  
  8012  	errs = validate.Struct(s)
  8013  	NotEqual(t, errs, nil)
  8014  
  8015  	// Tests for time.Duration type.
  8016  
  8017  	// -- Validations for a variable of time.Duration type.
  8018  
  8019  	errs = validate.Var(time.Hour, "lte=1h1m")
  8020  	Equal(t, errs, nil)
  8021  
  8022  	errs = validate.Var(time.Hour+time.Minute, "lte=1h1m")
  8023  	Equal(t, errs, nil)
  8024  
  8025  	errs = validate.Var(time.Hour+2*time.Minute, "lte=1h1m")
  8026  	NotEqual(t, errs, nil)
  8027  	AssertError(t, errs, "", "", "", "", "lte")
  8028  
  8029  	errs = validate.Var(time.Duration(0), "omitempty,lte=-1s")
  8030  	Equal(t, errs, nil)
  8031  
  8032  	// -- Validations for a struct with a time.Duration type field.
  8033  
  8034  	type TimeDurationTest struct {
  8035  		Duration time.Duration `validate:"lte=1h1m"`
  8036  	}
  8037  	var timeDurationTest *TimeDurationTest
  8038  
  8039  	timeDurationTest = &TimeDurationTest{time.Hour}
  8040  	errs = validate.Struct(timeDurationTest)
  8041  	Equal(t, errs, nil)
  8042  
  8043  	timeDurationTest = &TimeDurationTest{time.Hour + time.Minute}
  8044  	errs = validate.Struct(timeDurationTest)
  8045  	Equal(t, errs, nil)
  8046  
  8047  	timeDurationTest = &TimeDurationTest{time.Hour + 2*time.Minute}
  8048  	errs = validate.Struct(timeDurationTest)
  8049  	NotEqual(t, errs, nil)
  8050  	AssertError(t, errs, "TimeDurationTest.Duration", "TimeDurationTest.Duration", "Duration", "Duration", "lte")
  8051  
  8052  	type TimeDurationOmitemptyTest struct {
  8053  		Duration time.Duration `validate:"omitempty,lte=-1s"`
  8054  	}
  8055  
  8056  	timeDurationOmitemptyTest := &TimeDurationOmitemptyTest{time.Duration(0)}
  8057  	errs = validate.Struct(timeDurationOmitemptyTest)
  8058  	Equal(t, errs, nil)
  8059  }
  8060  
  8061  func TestUrnRFC2141(t *testing.T) {
  8062  	tests := []struct {
  8063  		param    string
  8064  		expected bool
  8065  	}{
  8066  		{"urn:a:b", true},
  8067  		{"urn:a::", true},
  8068  		{"urn:a:-", true},
  8069  		{"URN:simple:simple", true},
  8070  		{"urn:urna:simple", true},
  8071  		{"urn:burnout:nss", true},
  8072  		{"urn:burn:nss", true},
  8073  		{"urn:urnurnurn:x", true},
  8074  		{"urn:abcdefghilmnopqrstuvzabcdefghilm:x", true},
  8075  		{"URN:123:x", true},
  8076  		{"URN:abcd-:x", true},
  8077  		{"URN:abcd-abcd:x", true},
  8078  		{"urn:urnx:urn", true},
  8079  		{"urn:ciao:a:b:c", true},
  8080  		{"urn:aaa:x:y:", true},
  8081  		{"urn:ciao:-", true},
  8082  		{"urn:colon:::::nss", true},
  8083  		{"urn:ciao:@!=%2C(xyz)+a,b.*@g=$_'", true},
  8084  		{"URN:hexes:%25", true},
  8085  		{"URN:x:abc%1Dz%2F%3az", true},
  8086  		{"URN:foo:a123,456", true},
  8087  		{"urn:foo:a123,456", true},
  8088  		{"urn:FOO:a123,456", true},
  8089  		{"urn:foo:A123,456", true},
  8090  		{"urn:foo:a123%2C456", true},
  8091  		{"URN:FOO:a123%2c456", true},
  8092  		{"URN:FOO:ABC%FFabc123%2c456", true},
  8093  		{"URN:FOO:ABC%FFabc123%2C456%9A", true},
  8094  		{"urn:ietf:params:scim:schemas:core:2.0:User", true},
  8095  		{"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:meta.lastModified", true},
  8096  		{"URN:-xxx:x", false},
  8097  		{"urn::colon:nss", false},
  8098  		{"urn:abcdefghilmnopqrstuvzabcdefghilmn:specificstring", false},
  8099  		{"URN:a!?:x", false},
  8100  		{"URN:#,:x", false},
  8101  		{"urn:urn:NSS", false},
  8102  		{"urn:URN:NSS", false},
  8103  		{"urn:white space:NSS", false},
  8104  		{"urn:concat:no spaces", false},
  8105  		{"urn:a:%", false},
  8106  		{"urn:", false},
  8107  	}
  8108  
  8109  	tag := "urn_rfc2141"
  8110  
  8111  	validate := New()
  8112  
  8113  	for i, test := range tests {
  8114  
  8115  		errs := validate.Var(test.param, tag)
  8116  
  8117  		if test.expected {
  8118  			if !IsEqual(errs, nil) {
  8119  				t.Fatalf("Index: %d URN failed Error: %s", i, errs)
  8120  			}
  8121  		} else {
  8122  			if IsEqual(errs, nil) {
  8123  				t.Fatalf("Index: %d URN failed Error: %s", i, errs)
  8124  			} else {
  8125  				val := getError(errs, "", "")
  8126  				if val.Tag() != tag {
  8127  					t.Fatalf("Index: %d URN failed Error: %s", i, errs)
  8128  				}
  8129  			}
  8130  		}
  8131  	}
  8132  
  8133  	i := 1
  8134  	PanicMatches(t, func() { _ = validate.Var(i, tag) }, "Bad field type int")
  8135  }
  8136  
  8137  func TestUrl(t *testing.T) {
  8138  	tests := []struct {
  8139  		param    string
  8140  		expected bool
  8141  	}{
  8142  		{"http://foo.bar#com", true},
  8143  		{"http://foobar.com", true},
  8144  		{"https://foobar.com", true},
  8145  		{"foobar.com", false},
  8146  		{"http://foobar.coffee/", true},
  8147  		{"http://foobar.中文网/", true},
  8148  		{"http://foobar.org/", true},
  8149  		{"http://foobar.org:8080/", true},
  8150  		{"ftp://foobar.ru/", true},
  8151  		{"http://user:pass@www.foobar.com/", true},
  8152  		{"http://127.0.0.1/", true},
  8153  		{"http://duckduckgo.com/?q=%2F", true},
  8154  		{"http://localhost:3000/", true},
  8155  		{"http://foobar.com/?foo=bar#baz=qux", true},
  8156  		{"http://foobar.com?foo=bar", true},
  8157  		{"http://www.xn--froschgrn-x9a.net/", true},
  8158  		{"", false},
  8159  		{"xyz://foobar.com", true},
  8160  		{"invalid.", false},
  8161  		{".com", false},
  8162  		{"rtmp://foobar.com", true},
  8163  		{"http://www.foo_bar.com/", true},
  8164  		{"http://localhost:3000/", true},
  8165  		{"http://foobar.com/#baz", true},
  8166  		{"http://foobar.com#baz=qux", true},
  8167  		{"http://foobar.com/t$-_.+!*\\'(),", true},
  8168  		{"http://www.foobar.com/~foobar", true},
  8169  		{"http://www.-foobar.com/", true},
  8170  		{"http://www.foo---bar.com/", true},
  8171  		{"mailto:someone@example.com", true},
  8172  		{"irc://irc.server.org/channel", true},
  8173  		{"irc://#channel@network", true},
  8174  		{"/abs/test/dir", false},
  8175  		{"./rel/test/dir", false},
  8176  		{"irc:", false},
  8177  		{"http://", false},
  8178  		{"file://path/to/file.txt", true},
  8179  		{"file:///c:/Windows/file.txt", true},
  8180  		{"file://localhost/path/to/file.txt", true},
  8181  		{"file://localhost/c:/WINDOWS/file.txt", true},
  8182  		{"file://", true},
  8183  		{"file:////remotehost/path/file.txt", true},
  8184  	}
  8185  
  8186  	validate := New()
  8187  
  8188  	for i, test := range tests {
  8189  
  8190  		errs := validate.Var(test.param, "url")
  8191  
  8192  		if test.expected {
  8193  			if !IsEqual(errs, nil) {
  8194  				t.Fatalf("Index: %d URL failed Error: %s", i, errs)
  8195  			}
  8196  		} else {
  8197  			if IsEqual(errs, nil) {
  8198  				t.Fatalf("Index: %d URL failed Error: %s", i, errs)
  8199  			} else {
  8200  				val := getError(errs, "", "")
  8201  				if val.Tag() != "url" {
  8202  					t.Fatalf("Index: %d URL failed Error: %s", i, errs)
  8203  				}
  8204  			}
  8205  		}
  8206  	}
  8207  
  8208  	i := 1
  8209  	PanicMatches(t, func() { _ = validate.Var(i, "url") }, "Bad field type int")
  8210  }
  8211  
  8212  func TestHttpUrl(t *testing.T) {
  8213  	tests := []struct {
  8214  		param    string
  8215  		expected bool
  8216  	}{
  8217  		{"http://foo.bar#com", true},
  8218  		{"http://foobar.com", true},
  8219  		{"HTTP://foobar.com", true},
  8220  		{"https://foobar.com", true},
  8221  		{"foobar.com", false},
  8222  		{"http://foobar.coffee/", true},
  8223  		{"http://foobar.中文网/", true},
  8224  		{"http://foobar.org/", true},
  8225  		{"http://foobar.org:8080/", true},
  8226  		{"ftp://foobar.ru/", false},
  8227  		{"file:///etc/passwd", false},
  8228  		{"file://C:/windows/win.ini", false},
  8229  		{"http://user:pass@www.foobar.com/", true},
  8230  		{"http://127.0.0.1/", true},
  8231  		{"http://duckduckgo.com/?q=%2F", true},
  8232  		{"http://localhost:3000/", true},
  8233  		{"http://foobar.com/?foo=bar#baz=qux", true},
  8234  		{"http://foobar.com?foo=bar", true},
  8235  		{"http://www.xn--froschgrn-x9a.net/", true},
  8236  		{"", false},
  8237  		{"a://b", false},
  8238  		{"xyz://foobar.com", false},
  8239  		{"invalid.", false},
  8240  		{".com", false},
  8241  		{"rtmp://foobar.com", false},
  8242  		{"http://www.foo_bar.com/", true},
  8243  		{"http://localhost:3000/", true},
  8244  		{"http://foobar.com/#baz", true},
  8245  		{"http://foobar.com#baz=qux", true},
  8246  		{"http://foobar.com/t$-_.+!*\\'(),", true},
  8247  		{"http://www.foobar.com/~foobar", true},
  8248  		{"http://www.-foobar.com/", true},
  8249  		{"http://www.foo---bar.com/", true},
  8250  		{"mailto:someone@example.com", false},
  8251  		{"irc://irc.server.org/channel", false},
  8252  		{"irc://#channel@network", false},
  8253  		{"/abs/test/dir", false},
  8254  		{"./rel/test/dir", false},
  8255  		{"http:", false},
  8256  		{"http://", false},
  8257  		{"http://#invalid", false},
  8258  		{"https://1.1.1.1", true},
  8259  	}
  8260  
  8261  	validate := New()
  8262  
  8263  	for i, test := range tests {
  8264  
  8265  		errs := validate.Var(test.param, "http_url")
  8266  
  8267  		if test.expected {
  8268  			if !IsEqual(errs, nil) {
  8269  				t.Fatalf("Index: %d HTTP URL failed Error: %s", i, errs)
  8270  			}
  8271  		} else {
  8272  			if IsEqual(errs, nil) {
  8273  				t.Fatalf("Index: %d HTTP URL failed Error: %s", i, errs)
  8274  			} else {
  8275  				val := getError(errs, "", "")
  8276  				if val.Tag() != "http_url" {
  8277  					t.Fatalf("Index: %d HTTP URL failed Error: %s", i, errs)
  8278  				}
  8279  			}
  8280  		}
  8281  	}
  8282  
  8283  	i := 1
  8284  	PanicMatches(t, func() { _ = validate.Var(i, "http_url") }, "Bad field type int")
  8285  }
  8286  
  8287  func TestUri(t *testing.T) {
  8288  	tests := []struct {
  8289  		param    string
  8290  		expected bool
  8291  	}{
  8292  		{"http://foo.bar#com", true},
  8293  		{"http://foobar.com", true},
  8294  		{"https://foobar.com", true},
  8295  		{"foobar.com", false},
  8296  		{"http://foobar.coffee/", true},
  8297  		{"http://foobar.中文网/", true},
  8298  		{"http://foobar.org/", true},
  8299  		{"http://foobar.org:8080/", true},
  8300  		{"ftp://foobar.ru/", true},
  8301  		{"http://user:pass@www.foobar.com/", true},
  8302  		{"http://127.0.0.1/", true},
  8303  		{"http://duckduckgo.com/?q=%2F", true},
  8304  		{"http://localhost:3000/", true},
  8305  		{"http://foobar.com/?foo=bar#baz=qux", true},
  8306  		{"http://foobar.com?foo=bar", true},
  8307  		{"http://www.xn--froschgrn-x9a.net/", true},
  8308  		{"", false},
  8309  		{"xyz://foobar.com", true},
  8310  		{"invalid.", false},
  8311  		{".com", false},
  8312  		{"rtmp://foobar.com", true},
  8313  		{"http://www.foo_bar.com/", true},
  8314  		{"http://localhost:3000/", true},
  8315  		{"http://foobar.com#baz=qux", true},
  8316  		{"http://foobar.com/t$-_.+!*\\'(),", true},
  8317  		{"http://www.foobar.com/~foobar", true},
  8318  		{"http://www.-foobar.com/", true},
  8319  		{"http://www.foo---bar.com/", true},
  8320  		{"mailto:someone@example.com", true},
  8321  		{"irc://irc.server.org/channel", true},
  8322  		{"irc://#channel@network", true},
  8323  		{"/abs/test/dir", true},
  8324  		{"./rel/test/dir", false},
  8325  	}
  8326  
  8327  	validate := New()
  8328  
  8329  	for i, test := range tests {
  8330  
  8331  		errs := validate.Var(test.param, "uri")
  8332  
  8333  		if test.expected {
  8334  			if !IsEqual(errs, nil) {
  8335  				t.Fatalf("Index: %d URI failed Error: %s", i, errs)
  8336  			}
  8337  		} else {
  8338  			if IsEqual(errs, nil) {
  8339  				t.Fatalf("Index: %d URI failed Error: %s", i, errs)
  8340  			} else {
  8341  				val := getError(errs, "", "")
  8342  				if val.Tag() != "uri" {
  8343  					t.Fatalf("Index: %d URI failed Error: %s", i, errs)
  8344  				}
  8345  			}
  8346  		}
  8347  	}
  8348  
  8349  	i := 1
  8350  	PanicMatches(t, func() { _ = validate.Var(i, "uri") }, "Bad field type int")
  8351  }
  8352  
  8353  func TestOrTag(t *testing.T) {
  8354  	validate := New()
  8355  
  8356  	s := "rgba(0,31,255,0.5)"
  8357  	errs := validate.Var(s, "rgb|rgba")
  8358  	Equal(t, errs, nil)
  8359  
  8360  	s = "rgba(0,31,255,0.5)"
  8361  	errs = validate.Var(s, "rgb|rgba|len=18")
  8362  	Equal(t, errs, nil)
  8363  
  8364  	s = "this ain't right"
  8365  	errs = validate.Var(s, "rgb|rgba")
  8366  	NotEqual(t, errs, nil)
  8367  	AssertError(t, errs, "", "", "", "", "rgb|rgba")
  8368  
  8369  	s = "this ain't right"
  8370  	errs = validate.Var(s, "rgb|rgba|len=10")
  8371  	NotEqual(t, errs, nil)
  8372  	AssertError(t, errs, "", "", "", "", "rgb|rgba|len=10")
  8373  
  8374  	s = "this is right"
  8375  	errs = validate.Var(s, "rgb|rgba|len=13")
  8376  	Equal(t, errs, nil)
  8377  
  8378  	s = ""
  8379  	errs = validate.Var(s, "omitempty,rgb|rgba")
  8380  	Equal(t, errs, nil)
  8381  
  8382  	s = "green"
  8383  	errs = validate.Var(s, "eq=|eq=blue,rgb|rgba") // should fail on first validation block
  8384  	NotEqual(t, errs, nil)
  8385  	ve := errs.(ValidationErrors)
  8386  	Equal(t, len(ve), 1)
  8387  	Equal(t, ve[0].Tag(), "eq=|eq=blue")
  8388  
  8389  	s = "this is right, but a blank or isn't"
  8390  
  8391  	PanicMatches(t, func() { _ = validate.Var(s, "rgb||len=13") }, "Invalid validation tag on field ''")
  8392  	PanicMatches(t, func() { _ = validate.Var(s, "rgb|rgbaa|len=13") }, "Undefined validation function 'rgbaa' on field ''")
  8393  
  8394  	v2 := New()
  8395  	v2.RegisterTagNameFunc(func(fld reflect.StructField) string {
  8396  		name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
  8397  
  8398  		if name == "-" {
  8399  			return ""
  8400  		}
  8401  
  8402  		return name
  8403  	})
  8404  
  8405  	type Colors struct {
  8406  		Fav string `validate:"rgb|rgba" json:"fc"`
  8407  	}
  8408  
  8409  	c := Colors{Fav: "this ain't right"}
  8410  
  8411  	err := v2.Struct(c)
  8412  	NotEqual(t, err, nil)
  8413  
  8414  	errs = err.(ValidationErrors)
  8415  	fe := getError(errs, "Colors.fc", "Colors.Fav")
  8416  	NotEqual(t, fe, nil)
  8417  }
  8418  
  8419  func TestHsla(t *testing.T) {
  8420  	validate := New()
  8421  
  8422  	s := "hsla(360,100%,100%,1)"
  8423  	errs := validate.Var(s, "hsla")
  8424  	Equal(t, errs, nil)
  8425  
  8426  	s = "hsla(360,100%,100%,0.5)"
  8427  	errs = validate.Var(s, "hsla")
  8428  	Equal(t, errs, nil)
  8429  
  8430  	s = "hsla(0,0%,0%, 0)"
  8431  	errs = validate.Var(s, "hsla")
  8432  	Equal(t, errs, nil)
  8433  
  8434  	s = "hsl(361,100%,50%,1)"
  8435  	errs = validate.Var(s, "hsla")
  8436  	NotEqual(t, errs, nil)
  8437  	AssertError(t, errs, "", "", "", "", "hsla")
  8438  
  8439  	s = "hsl(361,100%,50%)"
  8440  	errs = validate.Var(s, "hsla")
  8441  	NotEqual(t, errs, nil)
  8442  	AssertError(t, errs, "", "", "", "", "hsla")
  8443  
  8444  	s = "hsla(361,100%,50%)"
  8445  	errs = validate.Var(s, "hsla")
  8446  	NotEqual(t, errs, nil)
  8447  	AssertError(t, errs, "", "", "", "", "hsla")
  8448  
  8449  	s = "hsla(360,101%,50%)"
  8450  	errs = validate.Var(s, "hsla")
  8451  	NotEqual(t, errs, nil)
  8452  	AssertError(t, errs, "", "", "", "", "hsla")
  8453  
  8454  	s = "hsla(360,100%,101%)"
  8455  	errs = validate.Var(s, "hsla")
  8456  	NotEqual(t, errs, nil)
  8457  	AssertError(t, errs, "", "", "", "", "hsla")
  8458  
  8459  	i := 1
  8460  	errs = validate.Var(i, "hsla")
  8461  	NotEqual(t, errs, nil)
  8462  	AssertError(t, errs, "", "", "", "", "hsla")
  8463  }
  8464  
  8465  func TestHsl(t *testing.T) {
  8466  	validate := New()
  8467  
  8468  	s := "hsl(360,100%,50%)"
  8469  	errs := validate.Var(s, "hsl")
  8470  	Equal(t, errs, nil)
  8471  
  8472  	s = "hsl(0,0%,0%)"
  8473  	errs = validate.Var(s, "hsl")
  8474  	Equal(t, errs, nil)
  8475  
  8476  	s = "hsl(361,100%,50%)"
  8477  	errs = validate.Var(s, "hsl")
  8478  	NotEqual(t, errs, nil)
  8479  	AssertError(t, errs, "", "", "", "", "hsl")
  8480  
  8481  	s = "hsl(361,101%,50%)"
  8482  	errs = validate.Var(s, "hsl")
  8483  	NotEqual(t, errs, nil)
  8484  	AssertError(t, errs, "", "", "", "", "hsl")
  8485  
  8486  	s = "hsl(361,100%,101%)"
  8487  	errs = validate.Var(s, "hsl")
  8488  	NotEqual(t, errs, nil)
  8489  	AssertError(t, errs, "", "", "", "", "hsl")
  8490  
  8491  	s = "hsl(-10,100%,100%)"
  8492  	errs = validate.Var(s, "hsl")
  8493  	NotEqual(t, errs, nil)
  8494  	AssertError(t, errs, "", "", "", "", "hsl")
  8495  
  8496  	i := 1
  8497  	errs = validate.Var(i, "hsl")
  8498  	NotEqual(t, errs, nil)
  8499  	AssertError(t, errs, "", "", "", "", "hsl")
  8500  }
  8501  
  8502  func TestRgba(t *testing.T) {
  8503  	validate := New()
  8504  
  8505  	s := "rgba(0,31,255,0.5)"
  8506  	errs := validate.Var(s, "rgba")
  8507  	Equal(t, errs, nil)
  8508  
  8509  	s = "rgba(0,31,255,0.12)"
  8510  	errs = validate.Var(s, "rgba")
  8511  	Equal(t, errs, nil)
  8512  
  8513  	s = "rgba(12%,55%,100%,0.12)"
  8514  	errs = validate.Var(s, "rgba")
  8515  	Equal(t, errs, nil)
  8516  
  8517  	s = "rgba( 0,  31, 255, 0.5)"
  8518  	errs = validate.Var(s, "rgba")
  8519  	Equal(t, errs, nil)
  8520  
  8521  	s = "rgba(12%,55,100%,0.12)"
  8522  	errs = validate.Var(s, "rgba")
  8523  	NotEqual(t, errs, nil)
  8524  	AssertError(t, errs, "", "", "", "", "rgba")
  8525  
  8526  	s = "rgb(0,  31, 255)"
  8527  	errs = validate.Var(s, "rgba")
  8528  	NotEqual(t, errs, nil)
  8529  	AssertError(t, errs, "", "", "", "", "rgba")
  8530  
  8531  	s = "rgb(1,349,275,0.5)"
  8532  	errs = validate.Var(s, "rgba")
  8533  	NotEqual(t, errs, nil)
  8534  	AssertError(t, errs, "", "", "", "", "rgba")
  8535  
  8536  	s = "rgb(01,31,255,0.5)"
  8537  	errs = validate.Var(s, "rgba")
  8538  	NotEqual(t, errs, nil)
  8539  	AssertError(t, errs, "", "", "", "", "rgba")
  8540  
  8541  	i := 1
  8542  	errs = validate.Var(i, "rgba")
  8543  	NotEqual(t, errs, nil)
  8544  	AssertError(t, errs, "", "", "", "", "rgba")
  8545  }
  8546  
  8547  func TestRgb(t *testing.T) {
  8548  	validate := New()
  8549  
  8550  	s := "rgb(0,31,255)"
  8551  	errs := validate.Var(s, "rgb")
  8552  	Equal(t, errs, nil)
  8553  
  8554  	s = "rgb(0,  31, 255)"
  8555  	errs = validate.Var(s, "rgb")
  8556  	Equal(t, errs, nil)
  8557  
  8558  	s = "rgb(10%,  50%, 100%)"
  8559  	errs = validate.Var(s, "rgb")
  8560  	Equal(t, errs, nil)
  8561  
  8562  	s = "rgb(10%,  50%, 55)"
  8563  	errs = validate.Var(s, "rgb")
  8564  	NotEqual(t, errs, nil)
  8565  	AssertError(t, errs, "", "", "", "", "rgb")
  8566  
  8567  	s = "rgb(1,349,275)"
  8568  	errs = validate.Var(s, "rgb")
  8569  	NotEqual(t, errs, nil)
  8570  	AssertError(t, errs, "", "", "", "", "rgb")
  8571  
  8572  	s = "rgb(01,31,255)"
  8573  	errs = validate.Var(s, "rgb")
  8574  	NotEqual(t, errs, nil)
  8575  	AssertError(t, errs, "", "", "", "", "rgb")
  8576  
  8577  	s = "rgba(0,31,255)"
  8578  	errs = validate.Var(s, "rgb")
  8579  	NotEqual(t, errs, nil)
  8580  	AssertError(t, errs, "", "", "", "", "rgb")
  8581  
  8582  	i := 1
  8583  	errs = validate.Var(i, "rgb")
  8584  	NotEqual(t, errs, nil)
  8585  	AssertError(t, errs, "", "", "", "", "rgb")
  8586  }
  8587  
  8588  func TestEmail(t *testing.T) {
  8589  	validate := New()
  8590  
  8591  	s := "test@mail.com"
  8592  	errs := validate.Var(s, "email")
  8593  	Equal(t, errs, nil)
  8594  
  8595  	s = "Dörte@Sörensen.example.com"
  8596  	errs = validate.Var(s, "email")
  8597  	Equal(t, errs, nil)
  8598  
  8599  	s = "θσερ@εχαμπλε.ψομ"
  8600  	errs = validate.Var(s, "email")
  8601  	Equal(t, errs, nil)
  8602  
  8603  	s = "юзер@екзампл.ком"
  8604  	errs = validate.Var(s, "email")
  8605  	Equal(t, errs, nil)
  8606  
  8607  	s = "उपयोगकर्ता@उदाहरण.कॉम"
  8608  	errs = validate.Var(s, "email")
  8609  	Equal(t, errs, nil)
  8610  
  8611  	s = "用户@例子.广告"
  8612  	errs = validate.Var(s, "email")
  8613  	Equal(t, errs, nil)
  8614  
  8615  	s = "mail@domain_with_underscores.org"
  8616  	errs = validate.Var(s, "email")
  8617  	NotEqual(t, errs, nil)
  8618  	AssertError(t, errs, "", "", "", "", "email")
  8619  
  8620  	s = ""
  8621  	errs = validate.Var(s, "email")
  8622  	NotEqual(t, errs, nil)
  8623  	AssertError(t, errs, "", "", "", "", "email")
  8624  
  8625  	s = "test@email"
  8626  	errs = validate.Var(s, "email")
  8627  	NotEqual(t, errs, nil)
  8628  	AssertError(t, errs, "", "", "", "", "email")
  8629  
  8630  	s = "test@email."
  8631  	errs = validate.Var(s, "email")
  8632  	NotEqual(t, errs, nil)
  8633  	AssertError(t, errs, "", "", "", "", "email")
  8634  
  8635  	s = "@email.com"
  8636  	errs = validate.Var(s, "email")
  8637  	NotEqual(t, errs, nil)
  8638  	AssertError(t, errs, "", "", "", "", "email")
  8639  
  8640  	s = `"test test"@email.com`
  8641  	errs = validate.Var(s, "email")
  8642  	Equal(t, errs, nil)
  8643  
  8644  	s = `"@email.com`
  8645  	errs = validate.Var(s, "email")
  8646  	NotEqual(t, errs, nil)
  8647  	AssertError(t, errs, "", "", "", "", "email")
  8648  
  8649  	i := true
  8650  	errs = validate.Var(i, "email")
  8651  	NotEqual(t, errs, nil)
  8652  	AssertError(t, errs, "", "", "", "", "email")
  8653  }
  8654  
  8655  func TestHexColor(t *testing.T) {
  8656  	validate := New()
  8657  
  8658  	s := "#fff"
  8659  	errs := validate.Var(s, "hexcolor")
  8660  	Equal(t, errs, nil)
  8661  
  8662  	s = "#c2c2c2"
  8663  	errs = validate.Var(s, "hexcolor")
  8664  	Equal(t, errs, nil)
  8665  
  8666  	s = "fff"
  8667  	errs = validate.Var(s, "hexcolor")
  8668  	NotEqual(t, errs, nil)
  8669  	AssertError(t, errs, "", "", "", "", "hexcolor")
  8670  
  8671  	s = "fffFF"
  8672  	errs = validate.Var(s, "hexcolor")
  8673  	NotEqual(t, errs, nil)
  8674  	AssertError(t, errs, "", "", "", "", "hexcolor")
  8675  
  8676  	i := true
  8677  	errs = validate.Var(i, "hexcolor")
  8678  	NotEqual(t, errs, nil)
  8679  	AssertError(t, errs, "", "", "", "", "hexcolor")
  8680  }
  8681  
  8682  func TestHexadecimal(t *testing.T) {
  8683  	validate := New()
  8684  
  8685  	s := "ff0044"
  8686  	errs := validate.Var(s, "hexadecimal")
  8687  	Equal(t, errs, nil)
  8688  
  8689  	s = "0xff0044"
  8690  	errs = validate.Var(s, "hexadecimal")
  8691  	Equal(t, errs, nil)
  8692  
  8693  	s = "0Xff0044"
  8694  	errs = validate.Var(s, "hexadecimal")
  8695  	Equal(t, errs, nil)
  8696  
  8697  	s = "abcdefg"
  8698  	errs = validate.Var(s, "hexadecimal")
  8699  	NotEqual(t, errs, nil)
  8700  	AssertError(t, errs, "", "", "", "", "hexadecimal")
  8701  
  8702  	i := true
  8703  	errs = validate.Var(i, "hexadecimal")
  8704  	NotEqual(t, errs, nil)
  8705  	AssertError(t, errs, "", "", "", "", "hexadecimal")
  8706  }
  8707  
  8708  func TestNumber(t *testing.T) {
  8709  	validate := New()
  8710  
  8711  	s := "1"
  8712  	errs := validate.Var(s, "number")
  8713  	Equal(t, errs, nil)
  8714  
  8715  	s = "+1"
  8716  	errs = validate.Var(s, "number")
  8717  	NotEqual(t, errs, nil)
  8718  	AssertError(t, errs, "", "", "", "", "number")
  8719  
  8720  	s = "-1"
  8721  	errs = validate.Var(s, "number")
  8722  	NotEqual(t, errs, nil)
  8723  	AssertError(t, errs, "", "", "", "", "number")
  8724  
  8725  	s = "1.12"
  8726  	errs = validate.Var(s, "number")
  8727  	NotEqual(t, errs, nil)
  8728  	AssertError(t, errs, "", "", "", "", "number")
  8729  
  8730  	s = "+1.12"
  8731  	errs = validate.Var(s, "number")
  8732  	NotEqual(t, errs, nil)
  8733  	AssertError(t, errs, "", "", "", "", "number")
  8734  
  8735  	s = "-1.12"
  8736  	errs = validate.Var(s, "number")
  8737  	NotEqual(t, errs, nil)
  8738  	AssertError(t, errs, "", "", "", "", "number")
  8739  
  8740  	s = "1."
  8741  	errs = validate.Var(s, "number")
  8742  	NotEqual(t, errs, nil)
  8743  	AssertError(t, errs, "", "", "", "", "number")
  8744  
  8745  	s = "1.o"
  8746  	errs = validate.Var(s, "number")
  8747  	NotEqual(t, errs, nil)
  8748  	AssertError(t, errs, "", "", "", "", "number")
  8749  
  8750  	i := 1
  8751  	errs = validate.Var(i, "number")
  8752  	Equal(t, errs, nil)
  8753  }
  8754  
  8755  func TestNumeric(t *testing.T) {
  8756  	validate := New()
  8757  
  8758  	s := "1"
  8759  	errs := validate.Var(s, "numeric")
  8760  	Equal(t, errs, nil)
  8761  
  8762  	s = "+1"
  8763  	errs = validate.Var(s, "numeric")
  8764  	Equal(t, errs, nil)
  8765  
  8766  	s = "-1"
  8767  	errs = validate.Var(s, "numeric")
  8768  	Equal(t, errs, nil)
  8769  
  8770  	s = "1.12"
  8771  	errs = validate.Var(s, "numeric")
  8772  	Equal(t, errs, nil)
  8773  
  8774  	s = "+1.12"
  8775  	errs = validate.Var(s, "numeric")
  8776  	Equal(t, errs, nil)
  8777  
  8778  	s = "-1.12"
  8779  	errs = validate.Var(s, "numeric")
  8780  	Equal(t, errs, nil)
  8781  
  8782  	s = "1."
  8783  	errs = validate.Var(s, "numeric")
  8784  	NotEqual(t, errs, nil)
  8785  	AssertError(t, errs, "", "", "", "", "numeric")
  8786  
  8787  	s = "1.o"
  8788  	errs = validate.Var(s, "numeric")
  8789  	NotEqual(t, errs, nil)
  8790  	AssertError(t, errs, "", "", "", "", "numeric")
  8791  
  8792  	i := 1
  8793  	errs = validate.Var(i, "numeric")
  8794  	Equal(t, errs, nil)
  8795  }
  8796  func TestBoolean(t *testing.T) {
  8797  	validate := New()
  8798  
  8799  	b := true
  8800  	errs := validate.Var(b, "boolean")
  8801  	Equal(t, errs, nil)
  8802  
  8803  	b = false
  8804  	errs = validate.Var(b, "boolean")
  8805  	Equal(t, errs, nil)
  8806  
  8807  	s := "true"
  8808  	errs = validate.Var(s, "boolean")
  8809  	Equal(t, errs, nil)
  8810  
  8811  	s = "false"
  8812  	errs = validate.Var(s, "boolean")
  8813  	Equal(t, errs, nil)
  8814  
  8815  	s = "0"
  8816  	errs = validate.Var(s, "boolean")
  8817  	Equal(t, errs, nil)
  8818  
  8819  	s = "1"
  8820  	errs = validate.Var(s, "boolean")
  8821  	Equal(t, errs, nil)
  8822  
  8823  	s = "xyz"
  8824  	errs = validate.Var(s, "boolean")
  8825  	NotEqual(t, errs, nil)
  8826  	AssertError(t, errs, "", "", "", "", "boolean")
  8827  
  8828  	s = "1."
  8829  	errs = validate.Var(s, "boolean")
  8830  	NotEqual(t, errs, nil)
  8831  	AssertError(t, errs, "", "", "", "", "boolean")
  8832  }
  8833  
  8834  func TestAlphaNumeric(t *testing.T) {
  8835  	validate := New()
  8836  
  8837  	s := "abcd123"
  8838  	errs := validate.Var(s, "alphanum")
  8839  	Equal(t, errs, nil)
  8840  
  8841  	s = "abc!23"
  8842  	errs = validate.Var(s, "alphanum")
  8843  	NotEqual(t, errs, nil)
  8844  	AssertError(t, errs, "", "", "", "", "alphanum")
  8845  
  8846  	errs = validate.Var(1, "alphanum")
  8847  	NotEqual(t, errs, nil)
  8848  	AssertError(t, errs, "", "", "", "", "alphanum")
  8849  }
  8850  
  8851  func TestAlpha(t *testing.T) {
  8852  	validate := New()
  8853  
  8854  	s := "abcd"
  8855  	errs := validate.Var(s, "alpha")
  8856  	Equal(t, errs, nil)
  8857  
  8858  	s = "abc®"
  8859  	errs = validate.Var(s, "alpha")
  8860  	NotEqual(t, errs, nil)
  8861  	AssertError(t, errs, "", "", "", "", "alpha")
  8862  
  8863  	s = "abc÷"
  8864  	errs = validate.Var(s, "alpha")
  8865  	NotEqual(t, errs, nil)
  8866  	AssertError(t, errs, "", "", "", "", "alpha")
  8867  
  8868  	s = "abc1"
  8869  	errs = validate.Var(s, "alpha")
  8870  	NotEqual(t, errs, nil)
  8871  	AssertError(t, errs, "", "", "", "", "alpha")
  8872  
  8873  	s = "this is a test string"
  8874  	errs = validate.Var(s, "alpha")
  8875  	NotEqual(t, errs, nil)
  8876  	AssertError(t, errs, "", "", "", "", "alpha")
  8877  
  8878  	errs = validate.Var(1, "alpha")
  8879  	NotEqual(t, errs, nil)
  8880  	AssertError(t, errs, "", "", "", "", "alpha")
  8881  }
  8882  
  8883  func TestStructStringValidation(t *testing.T) {
  8884  	validate := New()
  8885  
  8886  	tSuccess := &TestString{
  8887  		Required:  "Required",
  8888  		Len:       "length==10",
  8889  		Min:       "min=1",
  8890  		Max:       "1234567890",
  8891  		MinMax:    "12345",
  8892  		Lt:        "012345678",
  8893  		Lte:       "0123456789",
  8894  		Gt:        "01234567890",
  8895  		Gte:       "0123456789",
  8896  		Boolean:   "true",
  8897  		OmitEmpty: "",
  8898  		Sub: &SubTest{
  8899  			Test: "1",
  8900  		},
  8901  		SubIgnore: &SubTest{
  8902  			Test: "",
  8903  		},
  8904  		Anonymous: struct {
  8905  			A string `validate:"required"`
  8906  		}{
  8907  			A: "1",
  8908  		},
  8909  		Iface: &Impl{
  8910  			F: "123",
  8911  		},
  8912  	}
  8913  
  8914  	errs := validate.Struct(tSuccess)
  8915  	Equal(t, errs, nil)
  8916  
  8917  	tFail := &TestString{
  8918  		Required:  "",
  8919  		Len:       "",
  8920  		Min:       "",
  8921  		Max:       "12345678901",
  8922  		MinMax:    "",
  8923  		Lt:        "0123456789",
  8924  		Lte:       "01234567890",
  8925  		Gt:        "1",
  8926  		Gte:       "1",
  8927  		OmitEmpty: "12345678901",
  8928  		Boolean:   "nope",
  8929  		Sub: &SubTest{
  8930  			Test: "",
  8931  		},
  8932  		Anonymous: struct {
  8933  			A string `validate:"required"`
  8934  		}{
  8935  			A: "",
  8936  		},
  8937  		Iface: &Impl{
  8938  			F: "12",
  8939  		},
  8940  	}
  8941  
  8942  	errs = validate.Struct(tFail)
  8943  
  8944  	// Assert Top Level
  8945  	NotEqual(t, errs, nil)
  8946  	Equal(t, len(errs.(ValidationErrors)), 14)
  8947  
  8948  	// Assert Fields
  8949  	AssertError(t, errs, "TestString.Required", "TestString.Required", "Required", "Required", "required")
  8950  	AssertError(t, errs, "TestString.Len", "TestString.Len", "Len", "Len", "len")
  8951  	AssertError(t, errs, "TestString.Min", "TestString.Min", "Min", "Min", "min")
  8952  	AssertError(t, errs, "TestString.Max", "TestString.Max", "Max", "Max", "max")
  8953  	AssertError(t, errs, "TestString.MinMax", "TestString.MinMax", "MinMax", "MinMax", "min")
  8954  	AssertError(t, errs, "TestString.Lt", "TestString.Lt", "Lt", "Lt", "lt")
  8955  	AssertError(t, errs, "TestString.Lte", "TestString.Lte", "Lte", "Lte", "lte")
  8956  	AssertError(t, errs, "TestString.Gt", "TestString.Gt", "Gt", "Gt", "gt")
  8957  	AssertError(t, errs, "TestString.Gte", "TestString.Gte", "Gte", "Gte", "gte")
  8958  	AssertError(t, errs, "TestString.OmitEmpty", "TestString.OmitEmpty", "OmitEmpty", "OmitEmpty", "max")
  8959  	AssertError(t, errs, "TestString.Boolean", "TestString.Boolean", "Boolean", "Boolean", "boolean")
  8960  
  8961  	// Nested Struct Field Errs
  8962  	AssertError(t, errs, "TestString.Anonymous.A", "TestString.Anonymous.A", "A", "A", "required")
  8963  	AssertError(t, errs, "TestString.Sub.Test", "TestString.Sub.Test", "Test", "Test", "required")
  8964  	AssertError(t, errs, "TestString.Iface.F", "TestString.Iface.F", "F", "F", "len")
  8965  }
  8966  
  8967  func TestStructInt32Validation(t *testing.T) {
  8968  	type TestInt32 struct {
  8969  		Required  int `validate:"required"`
  8970  		Len       int `validate:"len=10"`
  8971  		Min       int `validate:"min=1"`
  8972  		Max       int `validate:"max=10"`
  8973  		MinMax    int `validate:"min=1,max=10"`
  8974  		Lt        int `validate:"lt=10"`
  8975  		Lte       int `validate:"lte=10"`
  8976  		Gt        int `validate:"gt=10"`
  8977  		Gte       int `validate:"gte=10"`
  8978  		OmitEmpty int `validate:"omitempty,min=1,max=10"`
  8979  	}
  8980  
  8981  	tSuccess := &TestInt32{
  8982  		Required:  1,
  8983  		Len:       10,
  8984  		Min:       1,
  8985  		Max:       10,
  8986  		MinMax:    5,
  8987  		Lt:        9,
  8988  		Lte:       10,
  8989  		Gt:        11,
  8990  		Gte:       10,
  8991  		OmitEmpty: 0,
  8992  	}
  8993  
  8994  	validate := New()
  8995  	errs := validate.Struct(tSuccess)
  8996  	Equal(t, errs, nil)
  8997  
  8998  	tFail := &TestInt32{
  8999  		Required:  0,
  9000  		Len:       11,
  9001  		Min:       -1,
  9002  		Max:       11,
  9003  		MinMax:    -1,
  9004  		Lt:        10,
  9005  		Lte:       11,
  9006  		Gt:        10,
  9007  		Gte:       9,
  9008  		OmitEmpty: 11,
  9009  	}
  9010  
  9011  	errs = validate.Struct(tFail)
  9012  
  9013  	// Assert Top Level
  9014  	NotEqual(t, errs, nil)
  9015  	Equal(t, len(errs.(ValidationErrors)), 10)
  9016  
  9017  	// Assert Fields
  9018  	AssertError(t, errs, "TestInt32.Required", "TestInt32.Required", "Required", "Required", "required")
  9019  	AssertError(t, errs, "TestInt32.Len", "TestInt32.Len", "Len", "Len", "len")
  9020  	AssertError(t, errs, "TestInt32.Min", "TestInt32.Min", "Min", "Min", "min")
  9021  	AssertError(t, errs, "TestInt32.Max", "TestInt32.Max", "Max", "Max", "max")
  9022  	AssertError(t, errs, "TestInt32.MinMax", "TestInt32.MinMax", "MinMax", "MinMax", "min")
  9023  	AssertError(t, errs, "TestInt32.Lt", "TestInt32.Lt", "Lt", "Lt", "lt")
  9024  	AssertError(t, errs, "TestInt32.Lte", "TestInt32.Lte", "Lte", "Lte", "lte")
  9025  	AssertError(t, errs, "TestInt32.Gt", "TestInt32.Gt", "Gt", "Gt", "gt")
  9026  	AssertError(t, errs, "TestInt32.Gte", "TestInt32.Gte", "Gte", "Gte", "gte")
  9027  	AssertError(t, errs, "TestInt32.OmitEmpty", "TestInt32.OmitEmpty", "OmitEmpty", "OmitEmpty", "max")
  9028  }
  9029  
  9030  func TestStructUint64Validation(t *testing.T) {
  9031  	validate := New()
  9032  
  9033  	tSuccess := &TestUint64{
  9034  		Required:  1,
  9035  		Len:       10,
  9036  		Min:       1,
  9037  		Max:       10,
  9038  		MinMax:    5,
  9039  		OmitEmpty: 0,
  9040  	}
  9041  
  9042  	errs := validate.Struct(tSuccess)
  9043  	Equal(t, errs, nil)
  9044  
  9045  	tFail := &TestUint64{
  9046  		Required:  0,
  9047  		Len:       11,
  9048  		Min:       0,
  9049  		Max:       11,
  9050  		MinMax:    0,
  9051  		OmitEmpty: 11,
  9052  	}
  9053  
  9054  	errs = validate.Struct(tFail)
  9055  
  9056  	// Assert Top Level
  9057  	NotEqual(t, errs, nil)
  9058  	Equal(t, len(errs.(ValidationErrors)), 6)
  9059  
  9060  	// Assert Fields
  9061  	AssertError(t, errs, "TestUint64.Required", "TestUint64.Required", "Required", "Required", "required")
  9062  	AssertError(t, errs, "TestUint64.Len", "TestUint64.Len", "Len", "Len", "len")
  9063  	AssertError(t, errs, "TestUint64.Min", "TestUint64.Min", "Min", "Min", "min")
  9064  	AssertError(t, errs, "TestUint64.Max", "TestUint64.Max", "Max", "Max", "max")
  9065  	AssertError(t, errs, "TestUint64.MinMax", "TestUint64.MinMax", "MinMax", "MinMax", "min")
  9066  	AssertError(t, errs, "TestUint64.OmitEmpty", "TestUint64.OmitEmpty", "OmitEmpty", "OmitEmpty", "max")
  9067  }
  9068  
  9069  func TestStructFloat64Validation(t *testing.T) {
  9070  	validate := New()
  9071  
  9072  	tSuccess := &TestFloat64{
  9073  		Required:  1,
  9074  		Len:       10,
  9075  		Min:       1,
  9076  		Max:       10,
  9077  		MinMax:    5,
  9078  		OmitEmpty: 0,
  9079  	}
  9080  
  9081  	errs := validate.Struct(tSuccess)
  9082  	Equal(t, errs, nil)
  9083  
  9084  	tFail := &TestFloat64{
  9085  		Required:  0,
  9086  		Len:       11,
  9087  		Min:       0,
  9088  		Max:       11,
  9089  		MinMax:    0,
  9090  		OmitEmpty: 11,
  9091  	}
  9092  
  9093  	errs = validate.Struct(tFail)
  9094  
  9095  	// Assert Top Level
  9096  	NotEqual(t, errs, nil)
  9097  	Equal(t, len(errs.(ValidationErrors)), 6)
  9098  
  9099  	// Assert Fields
  9100  	AssertError(t, errs, "TestFloat64.Required", "TestFloat64.Required", "Required", "Required", "required")
  9101  	AssertError(t, errs, "TestFloat64.Len", "TestFloat64.Len", "Len", "Len", "len")
  9102  	AssertError(t, errs, "TestFloat64.Min", "TestFloat64.Min", "Min", "Min", "min")
  9103  	AssertError(t, errs, "TestFloat64.Max", "TestFloat64.Max", "Max", "Max", "max")
  9104  	AssertError(t, errs, "TestFloat64.MinMax", "TestFloat64.MinMax", "MinMax", "MinMax", "min")
  9105  	AssertError(t, errs, "TestFloat64.OmitEmpty", "TestFloat64.OmitEmpty", "OmitEmpty", "OmitEmpty", "max")
  9106  }
  9107  
  9108  func TestStructSliceValidation(t *testing.T) {
  9109  	validate := New()
  9110  
  9111  	tSuccess := &TestSlice{
  9112  		Required:  []int{1},
  9113  		Len:       []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0},
  9114  		Min:       []int{1, 2},
  9115  		Max:       []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0},
  9116  		MinMax:    []int{1, 2, 3, 4, 5},
  9117  		OmitEmpty: nil,
  9118  	}
  9119  
  9120  	errs := validate.Struct(tSuccess)
  9121  	Equal(t, errs, nil)
  9122  
  9123  	tFail := &TestSlice{
  9124  		Required:  nil,
  9125  		Len:       []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1},
  9126  		Min:       []int{},
  9127  		Max:       []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1},
  9128  		MinMax:    []int{},
  9129  		OmitEmpty: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1},
  9130  	}
  9131  
  9132  	errs = validate.Struct(tFail)
  9133  	NotEqual(t, errs, nil)
  9134  	Equal(t, len(errs.(ValidationErrors)), 6)
  9135  
  9136  	// Assert Field Errors
  9137  	AssertError(t, errs, "TestSlice.Required", "TestSlice.Required", "Required", "Required", "required")
  9138  	AssertError(t, errs, "TestSlice.Len", "TestSlice.Len", "Len", "Len", "len")
  9139  	AssertError(t, errs, "TestSlice.Min", "TestSlice.Min", "Min", "Min", "min")
  9140  	AssertError(t, errs, "TestSlice.Max", "TestSlice.Max", "Max", "Max", "max")
  9141  	AssertError(t, errs, "TestSlice.MinMax", "TestSlice.MinMax", "MinMax", "MinMax", "min")
  9142  	AssertError(t, errs, "TestSlice.OmitEmpty", "TestSlice.OmitEmpty", "OmitEmpty", "OmitEmpty", "max")
  9143  
  9144  	fe := getError(errs, "TestSlice.Len", "TestSlice.Len")
  9145  	NotEqual(t, fe, nil)
  9146  	Equal(t, fe.Field(), "Len")
  9147  	Equal(t, fe.StructField(), "Len")
  9148  	Equal(t, fe.Namespace(), "TestSlice.Len")
  9149  	Equal(t, fe.StructNamespace(), "TestSlice.Len")
  9150  	Equal(t, fe.Tag(), "len")
  9151  	Equal(t, fe.ActualTag(), "len")
  9152  	Equal(t, fe.Param(), "10")
  9153  	Equal(t, fe.Kind(), reflect.Slice)
  9154  	Equal(t, fe.Type(), reflect.TypeOf([]int{}))
  9155  
  9156  	_, ok := fe.Value().([]int)
  9157  	Equal(t, ok, true)
  9158  }
  9159  
  9160  func TestInvalidStruct(t *testing.T) {
  9161  	validate := New()
  9162  
  9163  	s := &SubTest{
  9164  		Test: "1",
  9165  	}
  9166  
  9167  	err := validate.Struct(s.Test)
  9168  	NotEqual(t, err, nil)
  9169  	Equal(t, err.Error(), "validator: (nil string)")
  9170  
  9171  	err = validate.Struct(nil)
  9172  	NotEqual(t, err, nil)
  9173  	Equal(t, err.Error(), "validator: (nil)")
  9174  
  9175  	err = validate.StructPartial(nil, "SubTest.Test")
  9176  	NotEqual(t, err, nil)
  9177  	Equal(t, err.Error(), "validator: (nil)")
  9178  
  9179  	err = validate.StructExcept(nil, "SubTest.Test")
  9180  	NotEqual(t, err, nil)
  9181  	Equal(t, err.Error(), "validator: (nil)")
  9182  }
  9183  
  9184  func TestInvalidValidatorFunction(t *testing.T) {
  9185  	validate := New()
  9186  
  9187  	s := &SubTest{
  9188  		Test: "1",
  9189  	}
  9190  
  9191  	PanicMatches(t, func() { _ = validate.Var(s.Test, "zzxxBadFunction") }, "Undefined validation function 'zzxxBadFunction' on field ''")
  9192  }
  9193  
  9194  func TestCustomFieldName(t *testing.T) {
  9195  	validate := New()
  9196  	validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
  9197  		name := strings.SplitN(fld.Tag.Get("schema"), ",", 2)[0]
  9198  
  9199  		if name == "-" {
  9200  			return ""
  9201  		}
  9202  
  9203  		return name
  9204  	})
  9205  
  9206  	type A struct {
  9207  		B string `schema:"b" validate:"required"`
  9208  		C string `schema:"c" validate:"required"`
  9209  		D []bool `schema:"d" validate:"required"`
  9210  		E string `schema:"-" validate:"required"`
  9211  	}
  9212  
  9213  	a := &A{}
  9214  
  9215  	err := validate.Struct(a)
  9216  	NotEqual(t, err, nil)
  9217  
  9218  	errs := err.(ValidationErrors)
  9219  	Equal(t, len(errs), 4)
  9220  	Equal(t, getError(errs, "A.b", "A.B").Field(), "b")
  9221  	Equal(t, getError(errs, "A.c", "A.C").Field(), "c")
  9222  	Equal(t, getError(errs, "A.d", "A.D").Field(), "d")
  9223  	Equal(t, getError(errs, "A.E", "A.E").Field(), "E")
  9224  
  9225  	v2 := New()
  9226  	err = v2.Struct(a)
  9227  	NotEqual(t, err, nil)
  9228  
  9229  	errs = err.(ValidationErrors)
  9230  	Equal(t, len(errs), 4)
  9231  	Equal(t, getError(errs, "A.B", "A.B").Field(), "B")
  9232  	Equal(t, getError(errs, "A.C", "A.C").Field(), "C")
  9233  	Equal(t, getError(errs, "A.D", "A.D").Field(), "D")
  9234  	Equal(t, getError(errs, "A.E", "A.E").Field(), "E")
  9235  }
  9236  
  9237  func TestMutipleRecursiveExtractStructCache(t *testing.T) {
  9238  	validate := New()
  9239  
  9240  	type Recursive struct {
  9241  		Field *string `validate:"required,len=5,ne=string"`
  9242  	}
  9243  
  9244  	var test Recursive
  9245  
  9246  	current := reflect.ValueOf(test)
  9247  	name := "Recursive"
  9248  	proceed := make(chan struct{})
  9249  
  9250  	sc := validate.extractStructCache(current, name)
  9251  	ptr := fmt.Sprintf("%p", sc)
  9252  
  9253  	for i := 0; i < 100; i++ {
  9254  		go func() {
  9255  			<-proceed
  9256  			sc := validate.extractStructCache(current, name)
  9257  			Equal(t, ptr, fmt.Sprintf("%p", sc))
  9258  		}()
  9259  	}
  9260  
  9261  	close(proceed)
  9262  }
  9263  
  9264  // Thanks @robbrockbank, see https://github.com/go-playground/validator/issues/249
  9265  func TestPointerAndOmitEmpty(t *testing.T) {
  9266  	validate := New()
  9267  
  9268  	type Test struct {
  9269  		MyInt *int `validate:"omitempty,gte=2,lte=255"`
  9270  	}
  9271  
  9272  	val1 := 0
  9273  	val2 := 256
  9274  
  9275  	t1 := Test{MyInt: &val1} // This should fail validation on gte because value is 0
  9276  	t2 := Test{MyInt: &val2} // This should fail validate on lte because value is 256
  9277  	t3 := Test{MyInt: nil}   // This should succeed validation because pointer is nil
  9278  
  9279  	errs := validate.Struct(t1)
  9280  	NotEqual(t, errs, nil)
  9281  	AssertError(t, errs, "Test.MyInt", "Test.MyInt", "MyInt", "MyInt", "gte")
  9282  
  9283  	errs = validate.Struct(t2)
  9284  	NotEqual(t, errs, nil)
  9285  	AssertError(t, errs, "Test.MyInt", "Test.MyInt", "MyInt", "MyInt", "lte")
  9286  
  9287  	errs = validate.Struct(t3)
  9288  	Equal(t, errs, nil)
  9289  
  9290  	type TestIface struct {
  9291  		MyInt interface{} `validate:"omitempty,gte=2,lte=255"`
  9292  	}
  9293  
  9294  	ti1 := TestIface{MyInt: &val1} // This should fail validation on gte because value is 0
  9295  	ti2 := TestIface{MyInt: &val2} // This should fail validate on lte because value is 256
  9296  	ti3 := TestIface{MyInt: nil}   // This should succeed validation because pointer is nil
  9297  
  9298  	errs = validate.Struct(ti1)
  9299  	NotEqual(t, errs, nil)
  9300  	AssertError(t, errs, "TestIface.MyInt", "TestIface.MyInt", "MyInt", "MyInt", "gte")
  9301  
  9302  	errs = validate.Struct(ti2)
  9303  	NotEqual(t, errs, nil)
  9304  	AssertError(t, errs, "TestIface.MyInt", "TestIface.MyInt", "MyInt", "MyInt", "lte")
  9305  
  9306  	errs = validate.Struct(ti3)
  9307  	Equal(t, errs, nil)
  9308  }
  9309  
  9310  func TestRequired(t *testing.T) {
  9311  	validate := New()
  9312  	validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
  9313  		name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
  9314  
  9315  		if name == "-" {
  9316  			return ""
  9317  		}
  9318  
  9319  		return name
  9320  	})
  9321  
  9322  	type Test struct {
  9323  		Value interface{} `validate:"required"`
  9324  	}
  9325  
  9326  	var test Test
  9327  
  9328  	err := validate.Struct(test)
  9329  	NotEqual(t, err, nil)
  9330  	AssertError(t, err.(ValidationErrors), "Test.Value", "Test.Value", "Value", "Value", "required")
  9331  }
  9332  
  9333  func TestBoolEqual(t *testing.T) {
  9334  	validate := New()
  9335  
  9336  	type Test struct {
  9337  		Value bool `validate:"eq=true"`
  9338  	}
  9339  
  9340  	var test Test
  9341  
  9342  	err := validate.Struct(test)
  9343  	NotEqual(t, err, nil)
  9344  	AssertError(t, err.(ValidationErrors), "Test.Value", "Test.Value", "Value", "Value", "eq")
  9345  
  9346  	test.Value = true
  9347  	err = validate.Struct(test)
  9348  	Equal(t, err, nil)
  9349  }
  9350  
  9351  func TestTranslations(t *testing.T) {
  9352  	en := en.New()
  9353  	uni := ut.New(en, en, fr.New())
  9354  
  9355  	trans, _ := uni.GetTranslator("en")
  9356  	fr, _ := uni.GetTranslator("fr")
  9357  
  9358  	validate := New()
  9359  	err := validate.RegisterTranslation("required", trans,
  9360  		func(ut ut.Translator) (err error) {
  9361  			// using this stype because multiple translation may have to be added for the full translation
  9362  			if err = ut.Add("required", "{0} is a required field", false); err != nil {
  9363  				return
  9364  			}
  9365  
  9366  			return
  9367  		}, func(ut ut.Translator, fe FieldError) string {
  9368  			t, err := ut.T(fe.Tag(), fe.Field())
  9369  			if err != nil {
  9370  				fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError))
  9371  				return fe.(*fieldError).Error()
  9372  			}
  9373  
  9374  			return t
  9375  		})
  9376  	Equal(t, err, nil)
  9377  
  9378  	err = validate.RegisterTranslation("required", fr,
  9379  		func(ut ut.Translator) (err error) {
  9380  			// using this stype because multiple translation may have to be added for the full translation
  9381  			if err = ut.Add("required", "{0} est un champ obligatoire", false); err != nil {
  9382  				return
  9383  			}
  9384  
  9385  			return
  9386  		}, func(ut ut.Translator, fe FieldError) string {
  9387  			t, transErr := ut.T(fe.Tag(), fe.Field())
  9388  			if transErr != nil {
  9389  				fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError))
  9390  				return fe.(*fieldError).Error()
  9391  			}
  9392  
  9393  			return t
  9394  		})
  9395  
  9396  	Equal(t, err, nil)
  9397  
  9398  	type Test struct {
  9399  		Value interface{} `validate:"required"`
  9400  	}
  9401  
  9402  	var test Test
  9403  
  9404  	err = validate.Struct(test)
  9405  	NotEqual(t, err, nil)
  9406  
  9407  	errs := err.(ValidationErrors)
  9408  	Equal(t, len(errs), 1)
  9409  
  9410  	fe := errs[0]
  9411  	Equal(t, fe.Tag(), "required")
  9412  	Equal(t, fe.Namespace(), "Test.Value")
  9413  	Equal(t, fe.Translate(trans), fmt.Sprintf("%s is a required field", fe.Field()))
  9414  	Equal(t, fe.Translate(fr), fmt.Sprintf("%s est un champ obligatoire", fe.Field()))
  9415  
  9416  	nl := nl.New()
  9417  	uni2 := ut.New(nl, nl)
  9418  	trans2, _ := uni2.GetTranslator("nl")
  9419  	Equal(t, fe.Translate(trans2), "Key: 'Test.Value' Error:Field validation for 'Value' failed on the 'required' tag")
  9420  
  9421  	terrs := errs.Translate(trans)
  9422  	Equal(t, len(terrs), 1)
  9423  
  9424  	v, ok := terrs["Test.Value"]
  9425  	Equal(t, ok, true)
  9426  	Equal(t, v, fmt.Sprintf("%s is a required field", fe.Field()))
  9427  
  9428  	terrs = errs.Translate(fr)
  9429  	Equal(t, len(terrs), 1)
  9430  
  9431  	v, ok = terrs["Test.Value"]
  9432  	Equal(t, ok, true)
  9433  	Equal(t, v, fmt.Sprintf("%s est un champ obligatoire", fe.Field()))
  9434  
  9435  	type Test2 struct {
  9436  		Value string `validate:"gt=1"`
  9437  	}
  9438  
  9439  	var t2 Test2
  9440  
  9441  	err = validate.Struct(t2)
  9442  	NotEqual(t, err, nil)
  9443  
  9444  	errs = err.(ValidationErrors)
  9445  	Equal(t, len(errs), 1)
  9446  
  9447  	fe = errs[0]
  9448  	Equal(t, fe.Tag(), "gt")
  9449  	Equal(t, fe.Namespace(), "Test2.Value")
  9450  	Equal(t, fe.Translate(trans), "Key: 'Test2.Value' Error:Field validation for 'Value' failed on the 'gt' tag")
  9451  }
  9452  
  9453  func TestTranslationErrors(t *testing.T) {
  9454  	en := en.New()
  9455  	uni := ut.New(en, en, fr.New())
  9456  
  9457  	trans, _ := uni.GetTranslator("en")
  9458  	err := trans.Add("required", "{0} is a required field", false) // using translator outside of validator also
  9459  	Equal(t, err, nil)
  9460  
  9461  	validate := New()
  9462  	err = validate.RegisterTranslation("required", trans,
  9463  		func(ut ut.Translator) (err error) {
  9464  			// using this stype because multiple translation may have to be added for the full translation
  9465  			if err = ut.Add("required", "{0} is a required field", false); err != nil {
  9466  				return
  9467  			}
  9468  
  9469  			return
  9470  		}, func(ut ut.Translator, fe FieldError) string {
  9471  			t, err := ut.T(fe.Tag(), fe.Field())
  9472  			if err != nil {
  9473  				fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError))
  9474  				return fe.(*fieldError).Error()
  9475  			}
  9476  
  9477  			return t
  9478  		})
  9479  
  9480  	NotEqual(t, err, nil)
  9481  	Equal(t, err.Error(), "error: conflicting key 'required' rule 'Unknown' with text '{0} is a required field' for locale 'en', value being ignored")
  9482  }
  9483  
  9484  func TestStructFiltered(t *testing.T) {
  9485  	p1 := func(ns []byte) bool {
  9486  		if bytes.HasSuffix(ns, []byte("NoTag")) || bytes.HasSuffix(ns, []byte("Required")) {
  9487  			return false
  9488  		}
  9489  
  9490  		return true
  9491  	}
  9492  
  9493  	p2 := func(ns []byte) bool {
  9494  		if bytes.HasSuffix(ns, []byte("SubSlice[0].Test")) ||
  9495  			bytes.HasSuffix(ns, []byte("SubSlice[0]")) ||
  9496  			bytes.HasSuffix(ns, []byte("SubSlice")) ||
  9497  			bytes.HasSuffix(ns, []byte("Sub")) ||
  9498  			bytes.HasSuffix(ns, []byte("SubIgnore")) ||
  9499  			bytes.HasSuffix(ns, []byte("Anonymous")) ||
  9500  			bytes.HasSuffix(ns, []byte("Anonymous.A")) {
  9501  			return false
  9502  		}
  9503  
  9504  		return true
  9505  	}
  9506  
  9507  	p3 := func(ns []byte) bool {
  9508  		return !bytes.HasSuffix(ns, []byte("SubTest.Test"))
  9509  	}
  9510  
  9511  	// p4 := []string{
  9512  	// 	"A",
  9513  	// }
  9514  
  9515  	tPartial := &TestPartial{
  9516  		NoTag:    "NoTag",
  9517  		Required: "Required",
  9518  
  9519  		SubSlice: []*SubTest{
  9520  			{
  9521  
  9522  				Test: "Required",
  9523  			},
  9524  			{
  9525  
  9526  				Test: "Required",
  9527  			},
  9528  		},
  9529  
  9530  		Sub: &SubTest{
  9531  			Test: "1",
  9532  		},
  9533  		SubIgnore: &SubTest{
  9534  			Test: "",
  9535  		},
  9536  		Anonymous: struct {
  9537  			A             string     `validate:"required"`
  9538  			ASubSlice     []*SubTest `validate:"required,dive"`
  9539  			SubAnonStruct []struct {
  9540  				Test      string `validate:"required"`
  9541  				OtherTest string `validate:"required"`
  9542  			} `validate:"required,dive"`
  9543  		}{
  9544  			A: "1",
  9545  			ASubSlice: []*SubTest{
  9546  				{
  9547  					Test: "Required",
  9548  				},
  9549  				{
  9550  					Test: "Required",
  9551  				},
  9552  			},
  9553  
  9554  			SubAnonStruct: []struct {
  9555  				Test      string `validate:"required"`
  9556  				OtherTest string `validate:"required"`
  9557  			}{
  9558  				{"Required", "RequiredOther"},
  9559  				{"Required", "RequiredOther"},
  9560  			},
  9561  		},
  9562  	}
  9563  
  9564  	validate := New()
  9565  
  9566  	// the following should all return no errors as everything is valid in
  9567  	// the default state
  9568  	errs := validate.StructFilteredCtx(context.Background(), tPartial, p1)
  9569  	Equal(t, errs, nil)
  9570  
  9571  	errs = validate.StructFiltered(tPartial, p2)
  9572  	Equal(t, errs, nil)
  9573  
  9574  	// this isn't really a robust test, but is meant to illustrate the ANON CASE below
  9575  	errs = validate.StructFiltered(tPartial.SubSlice[0], p3)
  9576  	Equal(t, errs, nil)
  9577  
  9578  	// mod tParial for required field and re-test making sure invalid fields are NOT required:
  9579  	tPartial.Required = ""
  9580  
  9581  	// inversion and retesting Partial to generate failures:
  9582  	errs = validate.StructFiltered(tPartial, p1)
  9583  	NotEqual(t, errs, nil)
  9584  	AssertError(t, errs, "TestPartial.Required", "TestPartial.Required", "Required", "Required", "required")
  9585  
  9586  	// reset Required field, and set nested struct
  9587  	tPartial.Required = "Required"
  9588  	tPartial.Anonymous.A = ""
  9589  
  9590  	// will pass as unset feilds is not going to be tested
  9591  	errs = validate.StructFiltered(tPartial, p1)
  9592  	Equal(t, errs, nil)
  9593  
  9594  	// will fail as unset field is tested
  9595  	errs = validate.StructFiltered(tPartial, p2)
  9596  	NotEqual(t, errs, nil)
  9597  	AssertError(t, errs, "TestPartial.Anonymous.A", "TestPartial.Anonymous.A", "A", "A", "required")
  9598  
  9599  	// reset nested struct and unset struct in slice
  9600  	tPartial.Anonymous.A = "Required"
  9601  	tPartial.SubSlice[0].Test = ""
  9602  
  9603  	// these will pass as unset item is NOT tested
  9604  	errs = validate.StructFiltered(tPartial, p1)
  9605  	Equal(t, errs, nil)
  9606  
  9607  	errs = validate.StructFiltered(tPartial, p2)
  9608  	NotEqual(t, errs, nil)
  9609  	AssertError(t, errs, "TestPartial.SubSlice[0].Test", "TestPartial.SubSlice[0].Test", "Test", "Test", "required")
  9610  	Equal(t, len(errs.(ValidationErrors)), 1)
  9611  
  9612  	// Unset second slice member concurrently to test dive behavior:
  9613  	tPartial.SubSlice[1].Test = ""
  9614  
  9615  	errs = validate.StructFiltered(tPartial, p1)
  9616  	Equal(t, errs, nil)
  9617  
  9618  	errs = validate.StructFiltered(tPartial, p2)
  9619  	NotEqual(t, errs, nil)
  9620  	Equal(t, len(errs.(ValidationErrors)), 1)
  9621  	AssertError(t, errs, "TestPartial.SubSlice[0].Test", "TestPartial.SubSlice[0].Test", "Test", "Test", "required")
  9622  
  9623  	// reset struct in slice, and unset struct in slice in unset position
  9624  	tPartial.SubSlice[0].Test = "Required"
  9625  
  9626  	// these will pass as the unset item is NOT tested
  9627  	errs = validate.StructFiltered(tPartial, p1)
  9628  	Equal(t, errs, nil)
  9629  
  9630  	errs = validate.StructFiltered(tPartial, p2)
  9631  	Equal(t, errs, nil)
  9632  
  9633  	tPartial.SubSlice[1].Test = "Required"
  9634  	tPartial.Anonymous.SubAnonStruct[0].Test = ""
  9635  
  9636  	// these will pass as the unset item is NOT tested
  9637  	errs = validate.StructFiltered(tPartial, p1)
  9638  	Equal(t, errs, nil)
  9639  
  9640  	errs = validate.StructFiltered(tPartial, p2)
  9641  	Equal(t, errs, nil)
  9642  
  9643  	dt := time.Now()
  9644  	err := validate.StructFiltered(&dt, func(ns []byte) bool { return true })
  9645  	NotEqual(t, err, nil)
  9646  	Equal(t, err.Error(), "validator: (nil *time.Time)")
  9647  }
  9648  
  9649  func TestRequiredPtr(t *testing.T) {
  9650  	type Test struct {
  9651  		Bool *bool `validate:"required"`
  9652  	}
  9653  
  9654  	validate := New()
  9655  
  9656  	f := false
  9657  
  9658  	test := Test{
  9659  		Bool: &f,
  9660  	}
  9661  
  9662  	err := validate.Struct(test)
  9663  	Equal(t, err, nil)
  9664  
  9665  	tr := true
  9666  
  9667  	test.Bool = &tr
  9668  
  9669  	err = validate.Struct(test)
  9670  	Equal(t, err, nil)
  9671  
  9672  	test.Bool = nil
  9673  
  9674  	err = validate.Struct(test)
  9675  	NotEqual(t, err, nil)
  9676  
  9677  	errs, ok := err.(ValidationErrors)
  9678  	Equal(t, ok, true)
  9679  	Equal(t, len(errs), 1)
  9680  	AssertError(t, errs, "Test.Bool", "Test.Bool", "Bool", "Bool", "required")
  9681  
  9682  	type Test2 struct {
  9683  		Bool bool `validate:"required"`
  9684  	}
  9685  
  9686  	var test2 Test2
  9687  
  9688  	err = validate.Struct(test2)
  9689  	NotEqual(t, err, nil)
  9690  
  9691  	errs, ok = err.(ValidationErrors)
  9692  	Equal(t, ok, true)
  9693  	Equal(t, len(errs), 1)
  9694  	AssertError(t, errs, "Test2.Bool", "Test2.Bool", "Bool", "Bool", "required")
  9695  
  9696  	test2.Bool = true
  9697  
  9698  	err = validate.Struct(test2)
  9699  	Equal(t, err, nil)
  9700  
  9701  	type Test3 struct {
  9702  		Arr []string `validate:"required"`
  9703  	}
  9704  
  9705  	var test3 Test3
  9706  
  9707  	err = validate.Struct(test3)
  9708  	NotEqual(t, err, nil)
  9709  
  9710  	errs, ok = err.(ValidationErrors)
  9711  	Equal(t, ok, true)
  9712  	Equal(t, len(errs), 1)
  9713  	AssertError(t, errs, "Test3.Arr", "Test3.Arr", "Arr", "Arr", "required")
  9714  
  9715  	test3.Arr = make([]string, 0)
  9716  
  9717  	err = validate.Struct(test3)
  9718  	Equal(t, err, nil)
  9719  
  9720  	type Test4 struct {
  9721  		Arr *[]string `validate:"required"` // I know I know pointer to array, just making sure validation works as expected...
  9722  	}
  9723  
  9724  	var test4 Test4
  9725  
  9726  	err = validate.Struct(test4)
  9727  	NotEqual(t, err, nil)
  9728  
  9729  	errs, ok = err.(ValidationErrors)
  9730  	Equal(t, ok, true)
  9731  	Equal(t, len(errs), 1)
  9732  	AssertError(t, errs, "Test4.Arr", "Test4.Arr", "Arr", "Arr", "required")
  9733  
  9734  	arr := make([]string, 0)
  9735  	test4.Arr = &arr
  9736  
  9737  	err = validate.Struct(test4)
  9738  	Equal(t, err, nil)
  9739  }
  9740  
  9741  func TestAlphaUnicodeValidation(t *testing.T) {
  9742  	tests := []struct {
  9743  		param    string
  9744  		expected bool
  9745  	}{
  9746  		{"", false},
  9747  		{"abc", true},
  9748  		{"this is a test string", false},
  9749  		{"这是一个测试字符串", true},
  9750  		{"123", false},
  9751  		{"<>@;.-=", false},
  9752  		{"ひらがな・カタカナ、.漢字", false},
  9753  		{"あいうえおfoobar", true},
  9754  		{"test@example.com", false},
  9755  		{"1234abcDE", false},
  9756  		{"カタカナ", true},
  9757  	}
  9758  
  9759  	validate := New()
  9760  
  9761  	for i, test := range tests {
  9762  
  9763  		errs := validate.Var(test.param, "alphaunicode")
  9764  
  9765  		if test.expected {
  9766  			if !IsEqual(errs, nil) {
  9767  				t.Fatalf("Index: %d Alpha Unicode failed Error: %s", i, errs)
  9768  			}
  9769  		} else {
  9770  			if IsEqual(errs, nil) {
  9771  				t.Fatalf("Index: %d Alpha Unicode failed Error: %s", i, errs)
  9772  			} else {
  9773  				val := getError(errs, "", "")
  9774  				if val.Tag() != "alphaunicode" {
  9775  					t.Fatalf("Index: %d Alpha Unicode failed Error: %s", i, errs)
  9776  				}
  9777  			}
  9778  		}
  9779  	}
  9780  }
  9781  
  9782  func TestAlphanumericUnicodeValidation(t *testing.T) {
  9783  	tests := []struct {
  9784  		param    string
  9785  		expected bool
  9786  	}{
  9787  		{"", false},
  9788  		{"abc", true},
  9789  		{"this is a test string", false},
  9790  		{"这是一个测试字符串", true},
  9791  		{"\u0031\u0032\u0033", true}, // unicode 5
  9792  		{"123", true},
  9793  		{"<>@;.-=", false},
  9794  		{"ひらがな・カタカナ、.漢字", false},
  9795  		{"あいうえおfoobar", true},
  9796  		{"test@example.com", false},
  9797  		{"1234abcDE", true},
  9798  		{"カタカナ", true},
  9799  	}
  9800  
  9801  	validate := New()
  9802  
  9803  	for i, test := range tests {
  9804  
  9805  		errs := validate.Var(test.param, "alphanumunicode")
  9806  
  9807  		if test.expected {
  9808  			if !IsEqual(errs, nil) {
  9809  				t.Fatalf("Index: %d Alphanum Unicode failed Error: %s", i, errs)
  9810  			}
  9811  		} else {
  9812  			if IsEqual(errs, nil) {
  9813  				t.Fatalf("Index: %d Alphanum Unicode failed Error: %s", i, errs)
  9814  			} else {
  9815  				val := getError(errs, "", "")
  9816  				if val.Tag() != "alphanumunicode" {
  9817  					t.Fatalf("Index: %d Alphanum Unicode failed Error: %s", i, errs)
  9818  				}
  9819  			}
  9820  		}
  9821  	}
  9822  }
  9823  
  9824  func TestArrayStructNamespace(t *testing.T) {
  9825  	validate := New()
  9826  	validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
  9827  		name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
  9828  
  9829  		if name == "-" {
  9830  			return ""
  9831  		}
  9832  
  9833  		return name
  9834  	})
  9835  
  9836  	type child struct {
  9837  		Name string `json:"name" validate:"required"`
  9838  	}
  9839  	var input struct {
  9840  		Children []child `json:"children" validate:"required,gt=0,dive"`
  9841  	}
  9842  	input.Children = []child{{"ok"}, {""}}
  9843  
  9844  	errs := validate.Struct(input)
  9845  	NotEqual(t, errs, nil)
  9846  
  9847  	ve := errs.(ValidationErrors)
  9848  	Equal(t, len(ve), 1)
  9849  	AssertError(t, errs, "children[1].name", "Children[1].Name", "name", "Name", "required")
  9850  }
  9851  
  9852  func TestMapStructNamespace(t *testing.T) {
  9853  	validate := New()
  9854  	validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
  9855  		name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
  9856  
  9857  		if name == "-" {
  9858  			return ""
  9859  		}
  9860  
  9861  		return name
  9862  	})
  9863  
  9864  	type child struct {
  9865  		Name string `json:"name" validate:"required"`
  9866  	}
  9867  	var input struct {
  9868  		Children map[int]child `json:"children" validate:"required,gt=0,dive"`
  9869  	}
  9870  	input.Children = map[int]child{
  9871  		0: {Name: "ok"},
  9872  		1: {Name: ""},
  9873  	}
  9874  
  9875  	errs := validate.Struct(input)
  9876  	NotEqual(t, errs, nil)
  9877  
  9878  	ve := errs.(ValidationErrors)
  9879  	Equal(t, len(ve), 1)
  9880  	AssertError(t, errs, "children[1].name", "Children[1].Name", "name", "Name", "required")
  9881  }
  9882  
  9883  func TestFieldLevelName(t *testing.T) {
  9884  	type Test struct {
  9885  		String string            `validate:"custom1"      json:"json1"`
  9886  		Array  []string          `validate:"dive,custom2" json:"json2"`
  9887  		Map    map[string]string `validate:"dive,custom3" json:"json3"`
  9888  		Array2 []string          `validate:"custom4"      json:"json4"`
  9889  		Map2   map[string]string `validate:"custom5"      json:"json5"`
  9890  	}
  9891  
  9892  	var res1, res2, res3, res4, res5, alt1, alt2, alt3, alt4, alt5 string
  9893  	validate := New()
  9894  	validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
  9895  		name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
  9896  
  9897  		if name == "-" {
  9898  			return ""
  9899  		}
  9900  
  9901  		return name
  9902  	})
  9903  	err := validate.RegisterValidation("custom1", func(fl FieldLevel) bool {
  9904  		res1 = fl.FieldName()
  9905  		alt1 = fl.StructFieldName()
  9906  		return true
  9907  	})
  9908  	Equal(t, err, nil)
  9909  
  9910  	err = validate.RegisterValidation("custom2", func(fl FieldLevel) bool {
  9911  		res2 = fl.FieldName()
  9912  		alt2 = fl.StructFieldName()
  9913  		return true
  9914  	})
  9915  	Equal(t, err, nil)
  9916  
  9917  	err = validate.RegisterValidation("custom3", func(fl FieldLevel) bool {
  9918  		res3 = fl.FieldName()
  9919  		alt3 = fl.StructFieldName()
  9920  		return true
  9921  	})
  9922  	Equal(t, err, nil)
  9923  
  9924  	err = validate.RegisterValidation("custom4", func(fl FieldLevel) bool {
  9925  		res4 = fl.FieldName()
  9926  		alt4 = fl.StructFieldName()
  9927  		return true
  9928  	})
  9929  	Equal(t, err, nil)
  9930  
  9931  	err = validate.RegisterValidation("custom5", func(fl FieldLevel) bool {
  9932  		res5 = fl.FieldName()
  9933  		alt5 = fl.StructFieldName()
  9934  		return true
  9935  	})
  9936  	Equal(t, err, nil)
  9937  
  9938  	test := Test{
  9939  		String: "test",
  9940  		Array:  []string{"1"},
  9941  		Map:    map[string]string{"test": "test"},
  9942  	}
  9943  
  9944  	errs := validate.Struct(test)
  9945  	Equal(t, errs, nil)
  9946  	Equal(t, res1, "json1")
  9947  	Equal(t, alt1, "String")
  9948  	Equal(t, res2, "json2[0]")
  9949  	Equal(t, alt2, "Array[0]")
  9950  	Equal(t, res3, "json3[test]")
  9951  	Equal(t, alt3, "Map[test]")
  9952  	Equal(t, res4, "json4")
  9953  	Equal(t, alt4, "Array2")
  9954  	Equal(t, res5, "json5")
  9955  	Equal(t, alt5, "Map2")
  9956  }
  9957  
  9958  func TestValidateStructRegisterCtx(t *testing.T) {
  9959  	var ctxVal string
  9960  
  9961  	fnCtx := func(ctx context.Context, fl FieldLevel) bool {
  9962  		ctxVal = ctx.Value(&ctxVal).(string)
  9963  		return true
  9964  	}
  9965  
  9966  	var ctxSlVal string
  9967  	slFn := func(ctx context.Context, sl StructLevel) {
  9968  		ctxSlVal = ctx.Value(&ctxSlVal).(string)
  9969  	}
  9970  
  9971  	type Test struct {
  9972  		Field string `validate:"val"`
  9973  	}
  9974  
  9975  	var tst Test
  9976  
  9977  	validate := New()
  9978  	err := validate.RegisterValidationCtx("val", fnCtx)
  9979  	Equal(t, err, nil)
  9980  
  9981  	validate.RegisterStructValidationCtx(slFn, Test{})
  9982  
  9983  	ctx := context.WithValue(context.Background(), &ctxVal, "testval")
  9984  	ctx = context.WithValue(ctx, &ctxSlVal, "slVal")
  9985  	errs := validate.StructCtx(ctx, tst)
  9986  	Equal(t, errs, nil)
  9987  	Equal(t, ctxVal, "testval")
  9988  	Equal(t, ctxSlVal, "slVal")
  9989  }
  9990  
  9991  func TestHostnameRFC952Validation(t *testing.T) {
  9992  	tests := []struct {
  9993  		param    string
  9994  		expected bool
  9995  	}{
  9996  		{"test.example.com", true},
  9997  		{"example.com", true},
  9998  		{"example24.com", true},
  9999  		{"test.example24.com", true},
 10000  		{"test24.example24.com", true},
 10001  		{"example", true},
 10002  		{"EXAMPLE", true},
 10003  		{"1.foo.com", false},
 10004  		{"test.example.com.", false},
 10005  		{"example.com.", false},
 10006  		{"example24.com.", false},
 10007  		{"test.example24.com.", false},
 10008  		{"test24.example24.com.", false},
 10009  		{"example.", false},
 10010  		{"192.168.0.1", false},
 10011  		{"email@example.com", false},
 10012  		{"2001:cdba:0000:0000:0000:0000:3257:9652", false},
 10013  		{"2001:cdba:0:0:0:0:3257:9652", false},
 10014  		{"2001:cdba::3257:9652", false},
 10015  		{"example..........com", false},
 10016  		{"1234", false},
 10017  		{"abc1234", true},
 10018  		{"example. com", false},
 10019  		{"ex ample.com", false},
 10020  	}
 10021  
 10022  	validate := New()
 10023  
 10024  	for i, test := range tests {
 10025  
 10026  		errs := validate.Var(test.param, "hostname")
 10027  
 10028  		if test.expected {
 10029  			if !IsEqual(errs, nil) {
 10030  				t.Fatalf("Index: %d hostname failed Error: %v", i, errs)
 10031  			}
 10032  		} else {
 10033  			if IsEqual(errs, nil) {
 10034  				t.Fatalf("Index: %d hostname failed Error: %v", i, errs)
 10035  			} else {
 10036  				val := getError(errs, "", "")
 10037  				if val.Tag() != "hostname" {
 10038  					t.Fatalf("Index: %d hostname failed Error: %v", i, errs)
 10039  				}
 10040  			}
 10041  		}
 10042  	}
 10043  }
 10044  
 10045  func TestHostnameRFC1123Validation(t *testing.T) {
 10046  	tests := []struct {
 10047  		param    string
 10048  		expected bool
 10049  	}{
 10050  		{"test.example.com", true},
 10051  		{"example.com", true},
 10052  		{"example24.com", true},
 10053  		{"test.example24.com", true},
 10054  		{"test24.example24.com", true},
 10055  		{"example", true},
 10056  		{"1.foo.com", true},
 10057  		{"test.example.com.", false},
 10058  		{"example.com.", false},
 10059  		{"example24.com.", false},
 10060  		{"test.example24.com.", false},
 10061  		{"test24.example24.com.", false},
 10062  		{"example.", false},
 10063  		{"test_example", false},
 10064  		{"192.168.0.1", true},
 10065  		{"email@example.com", false},
 10066  		{"2001:cdba:0000:0000:0000:0000:3257:9652", false},
 10067  		{"2001:cdba:0:0:0:0:3257:9652", false},
 10068  		{"2001:cdba::3257:9652", false},
 10069  	}
 10070  
 10071  	validate := New()
 10072  
 10073  	for i, test := range tests {
 10074  
 10075  		errs := validate.Var(test.param, "hostname_rfc1123")
 10076  
 10077  		if test.expected {
 10078  			if !IsEqual(errs, nil) {
 10079  				t.Fatalf("Hostname: %v failed Error: %v", test, errs)
 10080  			}
 10081  		} else {
 10082  			if IsEqual(errs, nil) {
 10083  				t.Fatalf("Hostname: %v failed Error: %v", test, errs)
 10084  			} else {
 10085  				val := getError(errs, "", "")
 10086  				if val.Tag() != "hostname_rfc1123" {
 10087  					t.Fatalf("Hostname: %v failed Error: %v", i, errs)
 10088  				}
 10089  			}
 10090  		}
 10091  	}
 10092  }
 10093  
 10094  func TestHostnameRFC1123AliasValidation(t *testing.T) {
 10095  	tests := []struct {
 10096  		param    string
 10097  		expected bool
 10098  	}{
 10099  		{"test.example.com", true},
 10100  		{"example.com", true},
 10101  		{"example24.com", true},
 10102  		{"test.example24.com", true},
 10103  		{"test24.example24.com", true},
 10104  		{"example", true},
 10105  		{"1.foo.com", true},
 10106  		{"test.example.com.", false},
 10107  		{"example.com.", false},
 10108  		{"example24.com.", false},
 10109  		{"test.example24.com.", false},
 10110  		{"test24.example24.com.", false},
 10111  		{"example.", false},
 10112  		{"test_example", false},
 10113  		{"192.168.0.1", true},
 10114  		{"email@example.com", false},
 10115  		{"2001:cdba:0000:0000:0000:0000:3257:9652", false},
 10116  		{"2001:cdba:0:0:0:0:3257:9652", false},
 10117  		{"2001:cdba::3257:9652", false},
 10118  	}
 10119  
 10120  	validate := New()
 10121  	validate.RegisterAlias("hostname", "hostname_rfc1123")
 10122  
 10123  	for i, test := range tests {
 10124  
 10125  		errs := validate.Var(test.param, "hostname")
 10126  
 10127  		if test.expected {
 10128  			if !IsEqual(errs, nil) {
 10129  				t.Fatalf("Index: %d hostname failed Error: %v", i, errs)
 10130  			}
 10131  		} else {
 10132  			if IsEqual(errs, nil) {
 10133  				t.Fatalf("Index: %d hostname failed Error: %v", i, errs)
 10134  			} else {
 10135  				val := getError(errs, "", "")
 10136  				if val.Tag() != "hostname" {
 10137  					t.Fatalf("Index: %d hostname failed Error: %v", i, errs)
 10138  				}
 10139  			}
 10140  		}
 10141  	}
 10142  }
 10143  
 10144  func TestFQDNValidation(t *testing.T) {
 10145  	tests := []struct {
 10146  		param    string
 10147  		expected bool
 10148  	}{
 10149  		{"test.example.com", true},
 10150  		{"example.com", true},
 10151  		{"example24.com", true},
 10152  		{"test.example24.com", true},
 10153  		{"test24.example24.com", true},
 10154  		{"test.example.com.", true},
 10155  		{"example.com.", true},
 10156  		{"example24.com.", true},
 10157  		{"test.example24.com.", true},
 10158  		{"test24.example24.com.", true},
 10159  		{"24.example24.com", true},
 10160  		{"test.24.example.com", true},
 10161  		{"test24.example24.com..", false},
 10162  		{"example", false},
 10163  		{"192.168.0.1", false},
 10164  		{"email@example.com", false},
 10165  		{"2001:cdba:0000:0000:0000:0000:3257:9652", false},
 10166  		{"2001:cdba:0:0:0:0:3257:9652", false},
 10167  		{"2001:cdba::3257:9652", false},
 10168  		{"", false},
 10169  	}
 10170  
 10171  	validate := New()
 10172  
 10173  	for i, test := range tests {
 10174  
 10175  		errs := validate.Var(test.param, "fqdn")
 10176  
 10177  		if test.expected {
 10178  			if !IsEqual(errs, nil) {
 10179  				t.Fatalf("Index: %d fqdn failed Error: %v", i, errs)
 10180  			}
 10181  		} else {
 10182  			if IsEqual(errs, nil) {
 10183  				t.Fatalf("Index: %d fqdn failed Error: %v", i, errs)
 10184  			} else {
 10185  				val := getError(errs, "", "")
 10186  				if val.Tag() != "fqdn" {
 10187  					t.Fatalf("Index: %d fqdn failed Error: %v", i, errs)
 10188  				}
 10189  			}
 10190  		}
 10191  	}
 10192  }
 10193  
 10194  func TestIsDefault(t *testing.T) {
 10195  	validate := New()
 10196  
 10197  	type Inner struct {
 10198  		String string `validate:"isdefault"`
 10199  	}
 10200  	type Test struct {
 10201  		String string `validate:"isdefault"`
 10202  		Inner  *Inner `validate:"isdefault"`
 10203  	}
 10204  
 10205  	var tt Test
 10206  
 10207  	errs := validate.Struct(tt)
 10208  	Equal(t, errs, nil)
 10209  
 10210  	tt.Inner = &Inner{String: ""}
 10211  	errs = validate.Struct(tt)
 10212  	NotEqual(t, errs, nil)
 10213  
 10214  	fe := errs.(ValidationErrors)[0]
 10215  	Equal(t, fe.Field(), "Inner")
 10216  	Equal(t, fe.Namespace(), "Test.Inner")
 10217  	Equal(t, fe.Tag(), "isdefault")
 10218  
 10219  	validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
 10220  		name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
 10221  		if name == "-" {
 10222  			return ""
 10223  		}
 10224  		return name
 10225  	})
 10226  
 10227  	type Inner2 struct {
 10228  		String string `validate:"isdefault"`
 10229  	}
 10230  
 10231  	type Test2 struct {
 10232  		Inner Inner2 `validate:"isdefault" json:"inner"`
 10233  	}
 10234  
 10235  	var t2 Test2
 10236  	errs = validate.Struct(t2)
 10237  	Equal(t, errs, nil)
 10238  
 10239  	t2.Inner.String = "Changed"
 10240  	errs = validate.Struct(t2)
 10241  	NotEqual(t, errs, nil)
 10242  
 10243  	fe = errs.(ValidationErrors)[0]
 10244  	Equal(t, fe.Field(), "inner")
 10245  	Equal(t, fe.Namespace(), "Test2.inner")
 10246  	Equal(t, fe.Tag(), "isdefault")
 10247  }
 10248  
 10249  func TestUniqueValidation(t *testing.T) {
 10250  	tests := []struct {
 10251  		param    interface{}
 10252  		expected bool
 10253  	}{
 10254  		// Arrays
 10255  		{[2]string{"a", "b"}, true},
 10256  		{[2]int{1, 2}, true},
 10257  		{[2]float64{1, 2}, true},
 10258  		{[2]interface{}{"a", "b"}, true},
 10259  		{[2]interface{}{"a", 1}, true},
 10260  		{[2]float64{1, 1}, false},
 10261  		{[2]int{1, 1}, false},
 10262  		{[2]string{"a", "a"}, false},
 10263  		{[2]interface{}{"a", "a"}, false},
 10264  		{[4]interface{}{"a", 1, "b", 1}, false},
 10265  		{[2]*string{stringPtr("a"), stringPtr("b")}, true},
 10266  		{[2]*int{intPtr(1), intPtr(2)}, true},
 10267  		{[2]*float64{float64Ptr(1), float64Ptr(2)}, true},
 10268  		{[2]*string{stringPtr("a"), stringPtr("a")}, false},
 10269  		{[2]*float64{float64Ptr(1), float64Ptr(1)}, false},
 10270  		{[2]*int{intPtr(1), intPtr(1)}, false},
 10271  		// Slices
 10272  		{[]string{"a", "b"}, true},
 10273  		{[]int{1, 2}, true},
 10274  		{[]float64{1, 2}, true},
 10275  		{[]interface{}{"a", "b"}, true},
 10276  		{[]interface{}{"a", 1}, true},
 10277  		{[]float64{1, 1}, false},
 10278  		{[]int{1, 1}, false},
 10279  		{[]string{"a", "a"}, false},
 10280  		{[]interface{}{"a", "a"}, false},
 10281  		{[]interface{}{"a", 1, "b", 1}, false},
 10282  		{[]*string{stringPtr("a"), stringPtr("b")}, true},
 10283  		{[]*int{intPtr(1), intPtr(2)}, true},
 10284  		{[]*float64{float64Ptr(1), float64Ptr(2)}, true},
 10285  		{[]*string{stringPtr("a"), stringPtr("a")}, false},
 10286  		{[]*float64{float64Ptr(1), float64Ptr(1)}, false},
 10287  		{[]*int{intPtr(1), intPtr(1)}, false},
 10288  		// Maps
 10289  		{map[string]string{"one": "a", "two": "b"}, true},
 10290  		{map[string]int{"one": 1, "two": 2}, true},
 10291  		{map[string]float64{"one": 1, "two": 2}, true},
 10292  		{map[string]interface{}{"one": "a", "two": "b"}, true},
 10293  		{map[string]interface{}{"one": "a", "two": 1}, true},
 10294  		{map[string]float64{"one": 1, "two": 1}, false},
 10295  		{map[string]int{"one": 1, "two": 1}, false},
 10296  		{map[string]string{"one": "a", "two": "a"}, false},
 10297  		{map[string]interface{}{"one": "a", "two": "a"}, false},
 10298  		{map[string]interface{}{"one": "a", "two": 1, "three": "b", "four": 1}, false},
 10299  		{map[string]*string{"one": stringPtr("a"), "two": stringPtr("a")}, false},
 10300  		{map[string]*string{"one": stringPtr("a"), "two": stringPtr("b")}, true},
 10301  		{map[string]*int{"one": intPtr(1), "two": intPtr(1)}, false},
 10302  		{map[string]*int{"one": intPtr(1), "two": intPtr(2)}, true},
 10303  		{map[string]*float64{"one": float64Ptr(1.1), "two": float64Ptr(1.1)}, false},
 10304  		{map[string]*float64{"one": float64Ptr(1.1), "two": float64Ptr(1.2)}, true},
 10305  	}
 10306  
 10307  	validate := New()
 10308  
 10309  	for i, test := range tests {
 10310  
 10311  		errs := validate.Var(test.param, "unique")
 10312  
 10313  		if test.expected {
 10314  			if !IsEqual(errs, nil) {
 10315  				t.Fatalf("Index: %d unique failed Error: %v", i, errs)
 10316  			}
 10317  		} else {
 10318  			if IsEqual(errs, nil) {
 10319  				t.Fatalf("Index: %d unique failed Error: %v", i, errs)
 10320  			} else {
 10321  				val := getError(errs, "", "")
 10322  				if val.Tag() != "unique" {
 10323  					t.Fatalf("Index: %d unique failed Error: %v", i, errs)
 10324  				}
 10325  			}
 10326  		}
 10327  	}
 10328  	PanicMatches(t, func() { _ = validate.Var(1.0, "unique") }, "Bad field type float64")
 10329  
 10330  	t.Run("struct", func(t *testing.T) {
 10331  		tests := []struct {
 10332  			param    interface{}
 10333  			expected bool
 10334  		}{
 10335  			{struct {
 10336  				A string `validate:"unique=B"`
 10337  				B string
 10338  			}{A: "abc", B: "bcd"}, true},
 10339  			{struct {
 10340  				A string `validate:"unique=B"`
 10341  				B string
 10342  			}{A: "abc", B: "abc"}, false},
 10343  		}
 10344  		validate := New()
 10345  
 10346  		for i, test := range tests {
 10347  			errs := validate.Struct(test.param)
 10348  			if test.expected {
 10349  				if !IsEqual(errs, nil) {
 10350  					t.Fatalf("Index: %d unique failed Error: %v", i, errs)
 10351  				}
 10352  			} else {
 10353  				if IsEqual(errs, nil) {
 10354  					t.Fatalf("Index: %d unique failed Error: %v", i, errs)
 10355  				} else {
 10356  					val := getError(errs, "A", "A")
 10357  					if val.Tag() != "unique" {
 10358  						t.Fatalf("Index: %d unique failed Error: %v", i, errs)
 10359  					}
 10360  				}
 10361  			}
 10362  		}
 10363  	})
 10364  }
 10365  
 10366  func TestUniqueValidationStructSlice(t *testing.T) {
 10367  	testStructs := []struct {
 10368  		A string
 10369  		B string
 10370  	}{
 10371  		{A: "one", B: "two"},
 10372  		{A: "one", B: "three"},
 10373  	}
 10374  
 10375  	tests := []struct {
 10376  		target   interface{}
 10377  		param    string
 10378  		expected bool
 10379  	}{
 10380  		{testStructs, "unique", true},
 10381  		{testStructs, "unique=A", false},
 10382  		{testStructs, "unique=B", true},
 10383  	}
 10384  
 10385  	validate := New()
 10386  
 10387  	for i, test := range tests {
 10388  
 10389  		errs := validate.Var(test.target, test.param)
 10390  
 10391  		if test.expected {
 10392  			if !IsEqual(errs, nil) {
 10393  				t.Fatalf("Index: %d unique failed Error: %v", i, errs)
 10394  			}
 10395  		} else {
 10396  			if IsEqual(errs, nil) {
 10397  				t.Fatalf("Index: %d unique failed Error: %v", i, errs)
 10398  			} else {
 10399  				val := getError(errs, "", "")
 10400  				if val.Tag() != "unique" {
 10401  					t.Fatalf("Index: %d unique failed Error: %v", i, errs)
 10402  				}
 10403  			}
 10404  		}
 10405  	}
 10406  	PanicMatches(t, func() { _ = validate.Var(testStructs, "unique=C") }, "Bad field name C")
 10407  }
 10408  
 10409  func TestUniqueValidationStructPtrSlice(t *testing.T) {
 10410  	testStructs := []*struct {
 10411  		A *string
 10412  		B *string
 10413  	}{
 10414  		{A: stringPtr("one"), B: stringPtr("two")},
 10415  		{A: stringPtr("one"), B: stringPtr("three")},
 10416  		{},
 10417  	}
 10418  
 10419  	tests := []struct {
 10420  		target   interface{}
 10421  		param    string
 10422  		expected bool
 10423  	}{
 10424  		{testStructs, "unique", true},
 10425  		{testStructs, "unique=A", false},
 10426  		{testStructs, "unique=B", true},
 10427  	}
 10428  
 10429  	validate := New()
 10430  
 10431  	for i, test := range tests {
 10432  
 10433  		errs := validate.Var(test.target, test.param)
 10434  
 10435  		if test.expected {
 10436  			if !IsEqual(errs, nil) {
 10437  				t.Fatalf("Index: %d unique failed Error: %v", i, errs)
 10438  			}
 10439  		} else {
 10440  			if IsEqual(errs, nil) {
 10441  				t.Fatalf("Index: %d unique failed Error: %v", i, errs)
 10442  			} else {
 10443  				val := getError(errs, "", "")
 10444  				if val.Tag() != "unique" {
 10445  					t.Fatalf("Index: %d unique failed Error: %v", i, errs)
 10446  				}
 10447  			}
 10448  		}
 10449  	}
 10450  	PanicMatches(t, func() { _ = validate.Var(testStructs, "unique=C") }, "Bad field name C")
 10451  }
 10452  
 10453  func TestHTMLValidation(t *testing.T) {
 10454  	tests := []struct {
 10455  		param    string
 10456  		expected bool
 10457  	}{
 10458  		{"<html>", true},
 10459  		{"<script>", true},
 10460  		{"<stillworks>", true},
 10461  		{"</html", false},
 10462  		{"</script>", true},
 10463  		{"<//script>", false},
 10464  		{"<123nonsense>", false},
 10465  		{"test", false},
 10466  		{"&example", false},
 10467  	}
 10468  
 10469  	validate := New()
 10470  
 10471  	for i, test := range tests {
 10472  
 10473  		errs := validate.Var(test.param, "html")
 10474  
 10475  		if test.expected {
 10476  			if !IsEqual(errs, nil) {
 10477  				t.Fatalf("Index: %d html failed Error: %v", i, errs)
 10478  			}
 10479  		} else {
 10480  			if IsEqual(errs, nil) {
 10481  				t.Fatalf("Index: %d html failed Error: %v", i, errs)
 10482  			} else {
 10483  				val := getError(errs, "", "")
 10484  				if val.Tag() != "html" {
 10485  					t.Fatalf("Index: %d html failed Error: %v", i, errs)
 10486  				}
 10487  			}
 10488  		}
 10489  	}
 10490  }
 10491  
 10492  func TestHTMLEncodedValidation(t *testing.T) {
 10493  	tests := []struct {
 10494  		param    string
 10495  		expected bool
 10496  	}{
 10497  		{"&#x3c;", true},
 10498  		{"&#xaf;", true},
 10499  		{"&#x00;", true},
 10500  		{"&#xf0;", true},
 10501  		{"&#x3c", true},
 10502  		{"&#xaf", true},
 10503  		{"&#x00", true},
 10504  		{"&#xf0", true},
 10505  		{"&#ab", true},
 10506  		{"&lt;", true},
 10507  		{"&gt;", true},
 10508  		{"&quot;", true},
 10509  		{"&amp;", true},
 10510  		{"#x0a", false},
 10511  		{"&x00", false},
 10512  		{"&#x1z", false},
 10513  	}
 10514  
 10515  	validate := New()
 10516  
 10517  	for i, test := range tests {
 10518  
 10519  		errs := validate.Var(test.param, "html_encoded")
 10520  
 10521  		if test.expected {
 10522  			if !IsEqual(errs, nil) {
 10523  				t.Fatalf("Index: %d html_encoded failed Error: %v", i, errs)
 10524  			}
 10525  		} else {
 10526  			if IsEqual(errs, nil) {
 10527  				t.Fatalf("Index: %d html_enocded failed Error: %v", i, errs)
 10528  			} else {
 10529  				val := getError(errs, "", "")
 10530  				if val.Tag() != "html_encoded" {
 10531  					t.Fatalf("Index: %d html_encoded failed Error: %v", i, errs)
 10532  				}
 10533  			}
 10534  		}
 10535  	}
 10536  }
 10537  
 10538  func TestURLEncodedValidation(t *testing.T) {
 10539  	tests := []struct {
 10540  		param    string
 10541  		expected bool
 10542  	}{
 10543  		{"%20", true},
 10544  		{"%af", true},
 10545  		{"%ff", true},
 10546  		{"<%az", false},
 10547  		{"%test%", false},
 10548  		{"a%b", false},
 10549  		{"1%2", false},
 10550  		{"%%a%%", false},
 10551  		{"hello", true},
 10552  		{"", true},
 10553  		{"+", true},
 10554  	}
 10555  
 10556  	validate := New()
 10557  
 10558  	for i, test := range tests {
 10559  
 10560  		errs := validate.Var(test.param, "url_encoded")
 10561  
 10562  		if test.expected {
 10563  			if !IsEqual(errs, nil) {
 10564  				t.Fatalf("Index: %d url_encoded failed Error: %v", i, errs)
 10565  			}
 10566  		} else {
 10567  			if IsEqual(errs, nil) {
 10568  				t.Fatalf("Index: %d url_enocded failed Error: %v", i, errs)
 10569  			} else {
 10570  				val := getError(errs, "", "")
 10571  				if val.Tag() != "url_encoded" {
 10572  					t.Fatalf("Index: %d url_encoded failed Error: %v", i, errs)
 10573  				}
 10574  			}
 10575  		}
 10576  	}
 10577  }
 10578  
 10579  func TestKeys(t *testing.T) {
 10580  	type Test struct {
 10581  		Test1 map[string]string `validate:"gt=0,dive,keys,eq=testkey,endkeys,eq=testval" json:"test1"`
 10582  		Test2 map[int]int       `validate:"gt=0,dive,keys,eq=3,endkeys,eq=4"             json:"test2"`
 10583  		Test3 map[int]int       `validate:"gt=0,dive,keys,eq=3,endkeys"                  json:"test3"`
 10584  	}
 10585  
 10586  	var tst Test
 10587  
 10588  	validate := New()
 10589  	err := validate.Struct(tst)
 10590  	NotEqual(t, err, nil)
 10591  	Equal(t, len(err.(ValidationErrors)), 3)
 10592  	AssertError(t, err.(ValidationErrors), "Test.Test1", "Test.Test1", "Test1", "Test1", "gt")
 10593  	AssertError(t, err.(ValidationErrors), "Test.Test2", "Test.Test2", "Test2", "Test2", "gt")
 10594  	AssertError(t, err.(ValidationErrors), "Test.Test3", "Test.Test3", "Test3", "Test3", "gt")
 10595  
 10596  	tst.Test1 = map[string]string{
 10597  		"testkey": "testval",
 10598  	}
 10599  
 10600  	tst.Test2 = map[int]int{
 10601  		3: 4,
 10602  	}
 10603  
 10604  	tst.Test3 = map[int]int{
 10605  		3: 4,
 10606  	}
 10607  
 10608  	err = validate.Struct(tst)
 10609  	Equal(t, err, nil)
 10610  
 10611  	tst.Test1["badtestkey"] = "badtestvalue"
 10612  	tst.Test2[10] = 11
 10613  
 10614  	err = validate.Struct(tst)
 10615  	NotEqual(t, err, nil)
 10616  
 10617  	errs := err.(ValidationErrors)
 10618  
 10619  	Equal(t, len(errs), 4)
 10620  
 10621  	AssertDeepError(t, errs, "Test.Test1[badtestkey]", "Test.Test1[badtestkey]", "Test1[badtestkey]", "Test1[badtestkey]", "eq", "eq")
 10622  	AssertDeepError(t, errs, "Test.Test1[badtestkey]", "Test.Test1[badtestkey]", "Test1[badtestkey]", "Test1[badtestkey]", "eq", "eq")
 10623  	AssertDeepError(t, errs, "Test.Test2[10]", "Test.Test2[10]", "Test2[10]", "Test2[10]", "eq", "eq")
 10624  	AssertDeepError(t, errs, "Test.Test2[10]", "Test.Test2[10]", "Test2[10]", "Test2[10]", "eq", "eq")
 10625  
 10626  	type Test2 struct {
 10627  		NestedKeys map[[1]string]string `validate:"gt=0,dive,keys,dive,eq=innertestkey,endkeys,eq=outertestval"`
 10628  	}
 10629  
 10630  	var tst2 Test2
 10631  
 10632  	err = validate.Struct(tst2)
 10633  	NotEqual(t, err, nil)
 10634  	Equal(t, len(err.(ValidationErrors)), 1)
 10635  	AssertError(t, err.(ValidationErrors), "Test2.NestedKeys", "Test2.NestedKeys", "NestedKeys", "NestedKeys", "gt")
 10636  
 10637  	tst2.NestedKeys = map[[1]string]string{
 10638  		{"innertestkey"}: "outertestval",
 10639  	}
 10640  
 10641  	err = validate.Struct(tst2)
 10642  	Equal(t, err, nil)
 10643  
 10644  	tst2.NestedKeys[[1]string{"badtestkey"}] = "badtestvalue"
 10645  
 10646  	err = validate.Struct(tst2)
 10647  	NotEqual(t, err, nil)
 10648  
 10649  	errs = err.(ValidationErrors)
 10650  
 10651  	Equal(t, len(errs), 2)
 10652  	AssertDeepError(t, errs, "Test2.NestedKeys[[badtestkey]][0]", "Test2.NestedKeys[[badtestkey]][0]", "NestedKeys[[badtestkey]][0]", "NestedKeys[[badtestkey]][0]", "eq", "eq")
 10653  	AssertDeepError(t, errs, "Test2.NestedKeys[[badtestkey]]", "Test2.NestedKeys[[badtestkey]]", "NestedKeys[[badtestkey]]", "NestedKeys[[badtestkey]]", "eq", "eq")
 10654  
 10655  	// test bad tag definitions
 10656  
 10657  	PanicMatches(t, func() { _ = validate.Var(map[string]string{"key": "val"}, "endkeys,dive,eq=val") }, "'endkeys' tag encountered without a corresponding 'keys' tag")
 10658  	PanicMatches(t, func() { _ = validate.Var(1, "keys,eq=1,endkeys") }, "'keys' tag must be immediately preceded by the 'dive' tag")
 10659  
 10660  	// test custom tag name
 10661  	validate = New()
 10662  	validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
 10663  		name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
 10664  
 10665  		if name == "-" {
 10666  			return ""
 10667  		}
 10668  		return name
 10669  	})
 10670  
 10671  	err = validate.Struct(tst)
 10672  	NotEqual(t, err, nil)
 10673  
 10674  	errs = err.(ValidationErrors)
 10675  
 10676  	Equal(t, len(errs), 4)
 10677  
 10678  	AssertDeepError(t, errs, "Test.test1[badtestkey]", "Test.Test1[badtestkey]", "test1[badtestkey]", "Test1[badtestkey]", "eq", "eq")
 10679  	AssertDeepError(t, errs, "Test.test1[badtestkey]", "Test.Test1[badtestkey]", "test1[badtestkey]", "Test1[badtestkey]", "eq", "eq")
 10680  	AssertDeepError(t, errs, "Test.test2[10]", "Test.Test2[10]", "test2[10]", "Test2[10]", "eq", "eq")
 10681  	AssertDeepError(t, errs, "Test.test2[10]", "Test.Test2[10]", "test2[10]", "Test2[10]", "eq", "eq")
 10682  }
 10683  
 10684  // Thanks @adrian-sgn specific test for your specific scenario
 10685  func TestKeysCustomValidation(t *testing.T) {
 10686  	type LangCode string
 10687  	type Label map[LangCode]string
 10688  
 10689  	type TestMapStructPtr struct {
 10690  		Label Label `validate:"dive,keys,lang_code,endkeys,required"`
 10691  	}
 10692  
 10693  	validate := New()
 10694  	err := validate.RegisterValidation("lang_code", func(fl FieldLevel) bool {
 10695  		validLangCodes := map[LangCode]struct{}{
 10696  			"en": {},
 10697  			"es": {},
 10698  			"pt": {},
 10699  		}
 10700  
 10701  		_, ok := validLangCodes[fl.Field().Interface().(LangCode)]
 10702  		return ok
 10703  	})
 10704  	Equal(t, err, nil)
 10705  
 10706  	label := Label{
 10707  		"en":  "Good morning!",
 10708  		"pt":  "",
 10709  		"es":  "¡Buenos días!",
 10710  		"xx":  "Bad key",
 10711  		"xxx": "",
 10712  	}
 10713  
 10714  	err = validate.Struct(TestMapStructPtr{label})
 10715  	NotEqual(t, err, nil)
 10716  
 10717  	errs := err.(ValidationErrors)
 10718  	Equal(t, len(errs), 4)
 10719  
 10720  	AssertDeepError(t, errs, "TestMapStructPtr.Label[xx]", "TestMapStructPtr.Label[xx]", "Label[xx]", "Label[xx]", "lang_code", "lang_code")
 10721  	AssertDeepError(t, errs, "TestMapStructPtr.Label[pt]", "TestMapStructPtr.Label[pt]", "Label[pt]", "Label[pt]", "required", "required")
 10722  	AssertDeepError(t, errs, "TestMapStructPtr.Label[xxx]", "TestMapStructPtr.Label[xxx]", "Label[xxx]", "Label[xxx]", "lang_code", "lang_code")
 10723  	AssertDeepError(t, errs, "TestMapStructPtr.Label[xxx]", "TestMapStructPtr.Label[xxx]", "Label[xxx]", "Label[xxx]", "required", "required")
 10724  
 10725  	// find specific error
 10726  
 10727  	var e FieldError
 10728  	for _, e = range errs {
 10729  		if e.Namespace() == "TestMapStructPtr.Label[xxx]" {
 10730  			break
 10731  		}
 10732  	}
 10733  
 10734  	Equal(t, e.Param(), "")
 10735  	Equal(t, e.Value().(LangCode), LangCode("xxx"))
 10736  
 10737  	for _, e = range errs {
 10738  		if e.Namespace() == "TestMapStructPtr.Label[xxx]" && e.Tag() == "required" {
 10739  			break
 10740  		}
 10741  	}
 10742  
 10743  	Equal(t, e.Param(), "")
 10744  	Equal(t, e.Value().(string), "")
 10745  }
 10746  
 10747  func TestKeyOrs(t *testing.T) {
 10748  	type Test struct {
 10749  		Test1 map[string]string `validate:"gt=0,dive,keys,eq=testkey|eq=testkeyok,endkeys,eq=testval" json:"test1"`
 10750  	}
 10751  
 10752  	var tst Test
 10753  
 10754  	validate := New()
 10755  	err := validate.Struct(tst)
 10756  	NotEqual(t, err, nil)
 10757  	Equal(t, len(err.(ValidationErrors)), 1)
 10758  	AssertError(t, err.(ValidationErrors), "Test.Test1", "Test.Test1", "Test1", "Test1", "gt")
 10759  
 10760  	tst.Test1 = map[string]string{
 10761  		"testkey": "testval",
 10762  	}
 10763  
 10764  	err = validate.Struct(tst)
 10765  	Equal(t, err, nil)
 10766  
 10767  	tst.Test1["badtestkey"] = "badtestval"
 10768  
 10769  	err = validate.Struct(tst)
 10770  	NotEqual(t, err, nil)
 10771  
 10772  	errs := err.(ValidationErrors)
 10773  
 10774  	Equal(t, len(errs), 2)
 10775  
 10776  	AssertDeepError(t, errs, "Test.Test1[badtestkey]", "Test.Test1[badtestkey]", "Test1[badtestkey]", "Test1[badtestkey]", "eq=testkey|eq=testkeyok", "eq=testkey|eq=testkeyok")
 10777  	AssertDeepError(t, errs, "Test.Test1[badtestkey]", "Test.Test1[badtestkey]", "Test1[badtestkey]", "Test1[badtestkey]", "eq", "eq")
 10778  
 10779  	validate.RegisterAlias("okkey", "eq=testkey|eq=testkeyok")
 10780  
 10781  	type Test2 struct {
 10782  		Test1 map[string]string `validate:"gt=0,dive,keys,okkey,endkeys,eq=testval" json:"test1"`
 10783  	}
 10784  
 10785  	var tst2 Test2
 10786  
 10787  	err = validate.Struct(tst2)
 10788  	NotEqual(t, err, nil)
 10789  	Equal(t, len(err.(ValidationErrors)), 1)
 10790  	AssertError(t, err.(ValidationErrors), "Test2.Test1", "Test2.Test1", "Test1", "Test1", "gt")
 10791  
 10792  	tst2.Test1 = map[string]string{
 10793  		"testkey": "testval",
 10794  	}
 10795  
 10796  	err = validate.Struct(tst2)
 10797  	Equal(t, err, nil)
 10798  
 10799  	tst2.Test1["badtestkey"] = "badtestval"
 10800  
 10801  	err = validate.Struct(tst2)
 10802  	NotEqual(t, err, nil)
 10803  
 10804  	errs = err.(ValidationErrors)
 10805  
 10806  	Equal(t, len(errs), 2)
 10807  
 10808  	AssertDeepError(t, errs, "Test2.Test1[badtestkey]", "Test2.Test1[badtestkey]", "Test1[badtestkey]", "Test1[badtestkey]", "okkey", "eq=testkey|eq=testkeyok")
 10809  	AssertDeepError(t, errs, "Test2.Test1[badtestkey]", "Test2.Test1[badtestkey]", "Test1[badtestkey]", "Test1[badtestkey]", "eq", "eq")
 10810  }
 10811  
 10812  func TestStructLevelValidationsPointerPassing(t *testing.T) {
 10813  	v1 := New()
 10814  	v1.RegisterStructValidation(StructValidationTestStruct, &TestStruct{})
 10815  
 10816  	tst := &TestStruct{
 10817  		String: "good value",
 10818  	}
 10819  
 10820  	errs := v1.Struct(tst)
 10821  	NotEqual(t, errs, nil)
 10822  	AssertError(t, errs, "TestStruct.StringVal", "TestStruct.String", "StringVal", "String", "badvalueteststruct")
 10823  }
 10824  
 10825  func TestDirValidation(t *testing.T) {
 10826  	validate := New()
 10827  
 10828  	tests := []struct {
 10829  		title    string
 10830  		param    string
 10831  		expected bool
 10832  	}{
 10833  		{"existing dir", "testdata", true},
 10834  		{"existing self dir", ".", true},
 10835  		{"existing parent dir", "..", true},
 10836  		{"empty dir", "", false},
 10837  		{"missing dir", "non_existing_testdata", false},
 10838  		{"a file not a directory", filepath.Join("testdata", "a.go"), false},
 10839  	}
 10840  
 10841  	for _, test := range tests {
 10842  		errs := validate.Var(test.param, "dir")
 10843  
 10844  		if test.expected {
 10845  			if !IsEqual(errs, nil) {
 10846  				t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
 10847  			}
 10848  		} else {
 10849  			if IsEqual(errs, nil) {
 10850  				t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
 10851  			}
 10852  		}
 10853  	}
 10854  
 10855  	PanicMatches(t, func() {
 10856  		_ = validate.Var(2, "dir")
 10857  	}, "Bad field type int")
 10858  }
 10859  
 10860  func TestDirPathValidation(t *testing.T) {
 10861  	validate := New()
 10862  
 10863  	tests := []struct {
 10864  		title    string
 10865  		param    string
 10866  		expected bool
 10867  	}{
 10868  		{"empty dirpath", "", false},
 10869  		{"valid dirpath - exists", "testdata", true},
 10870  		{"valid dirpath - explicit", "testdatanoexist" + string(os.PathSeparator), true},
 10871  		{"invalid dirpath", "testdata\000" + string(os.PathSeparator), false},
 10872  		{"file, not a dirpath", filepath.Join("testdata", "a.go"), false},
 10873  	}
 10874  
 10875  	for _, test := range tests {
 10876  		errs := validate.Var(test.param, "dirpath")
 10877  
 10878  		if test.expected {
 10879  			if !IsEqual(errs, nil) {
 10880  				t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
 10881  			}
 10882  		} else {
 10883  			if IsEqual(errs, nil) {
 10884  				t.Fatalf("Test: '%s' failed Error: %s", test.title, errs)
 10885  			}
 10886  		}
 10887  	}
 10888  
 10889  	PanicMatches(t, func() {
 10890  		_ = validate.Var(6, "filepath")
 10891  	}, "Bad field type int")
 10892  }
 10893  
 10894  func TestStartsWithValidation(t *testing.T) {
 10895  	tests := []struct {
 10896  		Value       string `validate:"startswith=(/^ヮ^)/*:・゚✧"`
 10897  		Tag         string
 10898  		ExpectedNil bool
 10899  	}{
 10900  		{Value: "(/^ヮ^)/*:・゚✧ glitter", Tag: "startswith=(/^ヮ^)/*:・゚✧", ExpectedNil: true},
 10901  		{Value: "abcd", Tag: "startswith=(/^ヮ^)/*:・゚✧", ExpectedNil: false},
 10902  	}
 10903  
 10904  	validate := New()
 10905  
 10906  	for i, s := range tests {
 10907  		errs := validate.Var(s.Value, s.Tag)
 10908  
 10909  		if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
 10910  			t.Fatalf("Index: %d failed Error: %s", i, errs)
 10911  		}
 10912  
 10913  		errs = validate.Struct(s)
 10914  
 10915  		if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
 10916  			t.Fatalf("Index: %d failed Error: %s", i, errs)
 10917  		}
 10918  	}
 10919  }
 10920  
 10921  func TestEndsWithValidation(t *testing.T) {
 10922  	tests := []struct {
 10923  		Value       string `validate:"endswith=(/^ヮ^)/*:・゚✧"`
 10924  		Tag         string
 10925  		ExpectedNil bool
 10926  	}{
 10927  		{Value: "glitter (/^ヮ^)/*:・゚✧", Tag: "endswith=(/^ヮ^)/*:・゚✧", ExpectedNil: true},
 10928  		{Value: "(/^ヮ^)/*:・゚✧ glitter", Tag: "endswith=(/^ヮ^)/*:・゚✧", ExpectedNil: false},
 10929  	}
 10930  
 10931  	validate := New()
 10932  
 10933  	for i, s := range tests {
 10934  		errs := validate.Var(s.Value, s.Tag)
 10935  
 10936  		if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
 10937  			t.Fatalf("Index: %d failed Error: %s", i, errs)
 10938  		}
 10939  
 10940  		errs = validate.Struct(s)
 10941  
 10942  		if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) {
 10943  			t.Fatalf("Index: %d failed Error: %s", i, errs)
 10944  		}
 10945  	}
 10946  }
 10947  
 10948  func TestRequiredIf(t *testing.T) {
 10949  	type Inner struct {
 10950  		Field *string
 10951  	}
 10952  
 10953  	fieldVal := "test"
 10954  	test := struct {
 10955  		Inner   *Inner
 10956  		FieldE  string            `validate:"omitempty" json:"field_e"`
 10957  		FieldER string            `validate:"required_if=FieldE test" json:"field_er"`
 10958  		Field1  string            `validate:"omitempty" json:"field_1"`
 10959  		Field2  *string           `validate:"required_if=Field1 test" json:"field_2"`
 10960  		Field3  map[string]string `validate:"required_if=Field2 test" json:"field_3"`
 10961  		Field4  interface{}       `validate:"required_if=Field3 1" json:"field_4"`
 10962  		Field5  int               `validate:"required_if=Inner.Field test" json:"field_5"`
 10963  		Field6  uint              `validate:"required_if=Field5 1" json:"field_6"`
 10964  		Field7  float32           `validate:"required_if=Field6 1" json:"field_7"`
 10965  		Field8  float64           `validate:"required_if=Field7 1.0" json:"field_8"`
 10966  		Field9  Inner             `validate:"required_if=Field1 test" json:"field_9"`
 10967  		Field10 *Inner            `validate:"required_if=Field1 test" json:"field_10"`
 10968  	}{
 10969  		Inner:  &Inner{Field: &fieldVal},
 10970  		Field2: &fieldVal,
 10971  		Field3: map[string]string{"key": "val"},
 10972  		Field4: "test",
 10973  		Field5: 2,
 10974  	}
 10975  
 10976  	validate := New()
 10977  
 10978  	errs := validate.Struct(test)
 10979  	Equal(t, errs, nil)
 10980  
 10981  	test2 := struct {
 10982  		Inner   *Inner
 10983  		Inner2  *Inner
 10984  		FieldE  string            `validate:"omitempty" json:"field_e"`
 10985  		FieldER string            `validate:"required_if=FieldE test" json:"field_er"`
 10986  		Field1  string            `validate:"omitempty" json:"field_1"`
 10987  		Field2  *string           `validate:"required_if=Field1 test" json:"field_2"`
 10988  		Field3  map[string]string `validate:"required_if=Field2 test" json:"field_3"`
 10989  		Field4  interface{}       `validate:"required_if=Field2 test" json:"field_4"`
 10990  		Field5  string            `validate:"required_if=Field3 1" json:"field_5"`
 10991  		Field6  string            `validate:"required_if=Inner.Field test" json:"field_6"`
 10992  		Field7  string            `validate:"required_if=Inner2.Field test" json:"field_7"`
 10993  		Field8  Inner             `validate:"required_if=Field2 test" json:"field_8"`
 10994  		Field9  *Inner            `validate:"required_if=Field2 test" json:"field_9"`
 10995  	}{
 10996  		Inner:  &Inner{Field: &fieldVal},
 10997  		Field2: &fieldVal,
 10998  	}
 10999  
 11000  	errs = validate.Struct(test2)
 11001  	NotEqual(t, errs, nil)
 11002  
 11003  	ve := errs.(ValidationErrors)
 11004  	Equal(t, len(ve), 5)
 11005  	AssertError(t, errs, "Field3", "Field3", "Field3", "Field3", "required_if")
 11006  	AssertError(t, errs, "Field4", "Field4", "Field4", "Field4", "required_if")
 11007  	AssertError(t, errs, "Field6", "Field6", "Field6", "Field6", "required_if")
 11008  	AssertError(t, errs, "Field8", "Field8", "Field8", "Field8", "required_if")
 11009  	AssertError(t, errs, "Field9", "Field9", "Field9", "Field9", "required_if")
 11010  
 11011  	defer func() {
 11012  		if r := recover(); r == nil {
 11013  			t.Errorf("test3 should have panicked!")
 11014  		}
 11015  	}()
 11016  
 11017  	test3 := struct {
 11018  		Inner  *Inner
 11019  		Field1 string `validate:"required_if=Inner.Field" json:"field_1"`
 11020  	}{
 11021  		Inner: &Inner{Field: &fieldVal},
 11022  	}
 11023  	_ = validate.Struct(test3)
 11024  }
 11025  
 11026  func TestRequiredUnless(t *testing.T) {
 11027  	type Inner struct {
 11028  		Field *string
 11029  	}
 11030  
 11031  	fieldVal := "test"
 11032  	test := struct {
 11033  		Inner   *Inner
 11034  		FieldE  string            `validate:"omitempty" json:"field_e"`
 11035  		FieldER string            `validate:"required_unless=FieldE test" json:"field_er"`
 11036  		Field1  string            `validate:"omitempty" json:"field_1"`
 11037  		Field2  *string           `validate:"required_unless=Field1 test" json:"field_2"`
 11038  		Field3  map[string]string `validate:"required_unless=Field2 test" json:"field_3"`
 11039  		Field4  interface{}       `validate:"required_unless=Field3 1" json:"field_4"`
 11040  		Field5  int               `validate:"required_unless=Inner.Field test" json:"field_5"`
 11041  		Field6  uint              `validate:"required_unless=Field5 2" json:"field_6"`
 11042  		Field7  float32           `validate:"required_unless=Field6 0" json:"field_7"`
 11043  		Field8  float64           `validate:"required_unless=Field7 0.0" json:"field_8"`
 11044  		Field9  bool              `validate:"omitempty" json:"field_9"`
 11045  		Field10 string            `validate:"required_unless=Field9 true" json:"field_10"`
 11046  		Field11 Inner             `validate:"required_unless=Field9 true" json:"field_11"`
 11047  		Field12 *Inner            `validate:"required_unless=Field9 true" json:"field_12"`
 11048  	}{
 11049  		FieldE: "test",
 11050  		Field2: &fieldVal,
 11051  		Field3: map[string]string{"key": "val"},
 11052  		Field4: "test",
 11053  		Field5: 2,
 11054  		Field9: true,
 11055  	}
 11056  
 11057  	validate := New()
 11058  
 11059  	errs := validate.Struct(test)
 11060  	Equal(t, errs, nil)
 11061  
 11062  	test2 := struct {
 11063  		Inner   *Inner
 11064  		Inner2  *Inner
 11065  		FieldE  string            `validate:"omitempty" json:"field_e"`
 11066  		FieldER string            `validate:"required_unless=FieldE test" json:"field_er"`
 11067  		Field1  string            `validate:"omitempty" json:"field_1"`
 11068  		Field2  *string           `validate:"required_unless=Field1 test" json:"field_2"`
 11069  		Field3  map[string]string `validate:"required_unless=Field2 test" json:"field_3"`
 11070  		Field4  interface{}       `validate:"required_unless=Field2 test" json:"field_4"`
 11071  		Field5  string            `validate:"required_unless=Field3 0" json:"field_5"`
 11072  		Field6  string            `validate:"required_unless=Inner.Field test" json:"field_6"`
 11073  		Field7  string            `validate:"required_unless=Inner2.Field test" json:"field_7"`
 11074  		Field8  bool              `validate:"omitempty" json:"field_8"`
 11075  		Field9  string            `validate:"required_unless=Field8 true" json:"field_9"`
 11076  		Field10 Inner             `validate:"required_unless=Field9 true" json:"field_10"`
 11077  		Field11 *Inner            `validate:"required_unless=Field9 true" json:"field_11"`
 11078  	}{
 11079  		Inner:  &Inner{Field: &fieldVal},
 11080  		FieldE: "test",
 11081  		Field1: "test",
 11082  	}
 11083  
 11084  	errs = validate.Struct(test2)
 11085  	NotEqual(t, errs, nil)
 11086  
 11087  	ve := errs.(ValidationErrors)
 11088  	Equal(t, len(ve), 6)
 11089  	AssertError(t, errs, "Field3", "Field3", "Field3", "Field3", "required_unless")
 11090  	AssertError(t, errs, "Field4", "Field4", "Field4", "Field4", "required_unless")
 11091  	AssertError(t, errs, "Field7", "Field7", "Field7", "Field7", "required_unless")
 11092  	AssertError(t, errs, "Field9", "Field9", "Field9", "Field9", "required_unless")
 11093  	AssertError(t, errs, "Field10", "Field10", "Field10", "Field10", "required_unless")
 11094  	AssertError(t, errs, "Field11", "Field11", "Field11", "Field11", "required_unless")
 11095  
 11096  	defer func() {
 11097  		if r := recover(); r == nil {
 11098  			t.Errorf("test3 should have panicked!")
 11099  		}
 11100  	}()
 11101  
 11102  	test3 := struct {
 11103  		Inner  *Inner
 11104  		Field1 string `validate:"required_unless=Inner.Field" json:"field_1"`
 11105  	}{
 11106  		Inner: &Inner{Field: &fieldVal},
 11107  	}
 11108  	_ = validate.Struct(test3)
 11109  }
 11110  
 11111  func TestSkipUnless(t *testing.T) {
 11112  	type Inner struct {
 11113  		Field *string
 11114  	}
 11115  
 11116  	fieldVal := "test1"
 11117  	test := struct {
 11118  		Inner   *Inner
 11119  		FieldE  string            `validate:"omitempty" json:"field_e"`
 11120  		FieldER string            `validate:"skip_unless=FieldE test" json:"field_er"`
 11121  		Field1  string            `validate:"omitempty" json:"field_1"`
 11122  		Field2  *string           `validate:"skip_unless=Field1 test" json:"field_2"`
 11123  		Field3  map[string]string `validate:"skip_unless=Field2 test" json:"field_3"`
 11124  		Field4  interface{}       `validate:"skip_unless=Field3 1" json:"field_4"`
 11125  		Field5  int               `validate:"skip_unless=Inner.Field test" json:"field_5"`
 11126  		Field6  uint              `validate:"skip_unless=Field5 2" json:"field_6"`
 11127  		Field7  float32           `validate:"skip_unless=Field6 1" json:"field_7"`
 11128  		Field8  float64           `validate:"skip_unless=Field7 1.0" json:"field_8"`
 11129  		Field9  bool              `validate:"omitempty" json:"field_9"`
 11130  		Field10 string            `validate:"skip_unless=Field9 false" json:"field_10"`
 11131  		Field11 Inner             `validate:"skip_unless=Field9 false" json:"field_11"`
 11132  		Field12 *Inner            `validate:"skip_unless=Field9 false" json:"field_12"`
 11133  	}{
 11134  		FieldE: "test1",
 11135  		Field2: &fieldVal,
 11136  		Field3: map[string]string{"key": "val"},
 11137  		Field4: "test",
 11138  		Field5: 3,
 11139  		Field9: true,
 11140  	}
 11141  
 11142  	validate := New()
 11143  
 11144  	errs := validate.Struct(test)
 11145  	Equal(t, errs, nil)
 11146  
 11147  	test2 := struct {
 11148  		Inner   *Inner
 11149  		Inner2  *Inner
 11150  		FieldE  string            `validate:"omitempty" json:"field_e"`
 11151  		FieldER string            `validate:"skip_unless=FieldE test" json:"field_er"`
 11152  		Field1  string            `validate:"omitempty" json:"field_1"`
 11153  		Field2  *string           `validate:"skip_unless=Field1 test" json:"field_2"`
 11154  		Field3  map[string]string `validate:"skip_unless=Field2 test" json:"field_3"`
 11155  		Field4  interface{}       `validate:"skip_unless=Field2 test" json:"field_4"`
 11156  		Field5  string            `validate:"skip_unless=Field3 0" json:"field_5"`
 11157  		Field6  string            `validate:"skip_unless=Inner.Field test" json:"field_6"`
 11158  		Field7  string            `validate:"skip_unless=Inner2.Field test" json:"field_7"`
 11159  		Field8  bool              `validate:"omitempty" json:"field_8"`
 11160  		Field9  string            `validate:"skip_unless=Field8 true" json:"field_9"`
 11161  		Field10 Inner             `validate:"skip_unless=Field8 false" json:"field_10"`
 11162  		Field11 *Inner            `validate:"skip_unless=Field8 false" json:"field_11"`
 11163  	}{
 11164  		Inner:  &Inner{Field: &fieldVal},
 11165  		FieldE: "test1",
 11166  		Field1: "test1",
 11167  	}
 11168  
 11169  	errs = validate.Struct(test2)
 11170  	NotEqual(t, errs, nil)
 11171  
 11172  	ve := errs.(ValidationErrors)
 11173  	Equal(t, len(ve), 3)
 11174  	AssertError(t, errs, "Field5", "Field5", "Field5", "Field5", "skip_unless")
 11175  	AssertError(t, errs, "Field10", "Field10", "Field10", "Field10", "skip_unless")
 11176  	AssertError(t, errs, "Field11", "Field11", "Field11", "Field11", "skip_unless")
 11177  
 11178  	test3 := struct {
 11179  		Inner  *Inner
 11180  		Field1 string `validate:"skip_unless=Inner.Field" json:"field_1"`
 11181  	}{
 11182  		Inner: &Inner{Field: &fieldVal},
 11183  	}
 11184  	PanicMatches(t, func() {
 11185  		_ = validate.Struct(test3)
 11186  	}, "Bad param number for skip_unless Field1")
 11187  
 11188  	test4 := struct {
 11189  		Inner  *Inner
 11190  		Field1 string `validate:"skip_unless=Inner.Field test1" json:"field_1"`
 11191  	}{
 11192  		Inner: &Inner{Field: &fieldVal},
 11193  	}
 11194  	errs = validate.Struct(test4)
 11195  	NotEqual(t, errs, nil)
 11196  
 11197  	ve = errs.(ValidationErrors)
 11198  	Equal(t, len(ve), 1)
 11199  	AssertError(t, errs, "Field1", "Field1", "Field1", "Field1", "skip_unless")
 11200  }
 11201  
 11202  func TestRequiredWith(t *testing.T) {
 11203  	type Inner struct {
 11204  		Field *string
 11205  	}
 11206  
 11207  	fieldVal := "test"
 11208  	test := struct {
 11209  		Inner   *Inner
 11210  		FieldE  string            `validate:"omitempty" json:"field_e"`
 11211  		FieldER string            `validate:"required_with=FieldE" json:"field_er"`
 11212  		Field1  string            `validate:"omitempty" json:"field_1"`
 11213  		Field2  *string           `validate:"required_with=Field1" json:"field_2"`
 11214  		Field3  map[string]string `validate:"required_with=Field2" json:"field_3"`
 11215  		Field4  interface{}       `validate:"required_with=Field3" json:"field_4"`
 11216  		Field5  string            `validate:"required_with=Field" json:"field_5"`
 11217  		Field6  Inner             `validate:"required_with=Field2" json:"field_6"`
 11218  		Field7  *Inner            `validate:"required_with=Field2" json:"field_7"`
 11219  	}{
 11220  		Inner:  &Inner{Field: &fieldVal},
 11221  		Field2: &fieldVal,
 11222  		Field3: map[string]string{"key": "val"},
 11223  		Field4: "test",
 11224  		Field5: "test",
 11225  		Field6: Inner{Field: &fieldVal},
 11226  		Field7: &Inner{Field: &fieldVal},
 11227  	}
 11228  
 11229  	validate := New()
 11230  
 11231  	errs := validate.Struct(test)
 11232  	Equal(t, errs, nil)
 11233  
 11234  	test2 := struct {
 11235  		Inner   *Inner
 11236  		Inner2  *Inner
 11237  		FieldE  string            `validate:"omitempty" json:"field_e"`
 11238  		FieldER string            `validate:"required_with=FieldE" json:"field_er"`
 11239  		Field1  string            `validate:"omitempty" json:"field_1"`
 11240  		Field2  *string           `validate:"required_with=Field1" json:"field_2"`
 11241  		Field3  map[string]string `validate:"required_with=Field2" json:"field_3"`
 11242  		Field4  interface{}       `validate:"required_with=Field2" json:"field_4"`
 11243  		Field5  string            `validate:"required_with=Field3" json:"field_5"`
 11244  		Field6  string            `validate:"required_with=Inner.Field" json:"field_6"`
 11245  		Field7  string            `validate:"required_with=Inner2.Field" json:"field_7"`
 11246  		Field8  Inner             `validate:"required_with=Field2" json:"field_8"`
 11247  		Field9  *Inner            `validate:"required_with=Field2" json:"field_9"`
 11248  	}{
 11249  		Inner:  &Inner{Field: &fieldVal},
 11250  		Field2: &fieldVal,
 11251  	}
 11252  
 11253  	errs = validate.Struct(test2)
 11254  	NotEqual(t, errs, nil)
 11255  
 11256  	ve := errs.(ValidationErrors)
 11257  	Equal(t, len(ve), 5)
 11258  	AssertError(t, errs, "Field3", "Field3", "Field3", "Field3", "required_with")
 11259  	AssertError(t, errs, "Field4", "Field4", "Field4", "Field4", "required_with")
 11260  	AssertError(t, errs, "Field6", "Field6", "Field6", "Field6", "required_with")
 11261  	AssertError(t, errs, "Field8", "Field8", "Field8", "Field8", "required_with")
 11262  	AssertError(t, errs, "Field9", "Field9", "Field9", "Field9", "required_with")
 11263  }
 11264  
 11265  func TestExcludedWith(t *testing.T) {
 11266  	type Inner struct {
 11267  		FieldE string
 11268  		Field  *string
 11269  	}
 11270  
 11271  	fieldVal := "test"
 11272  	test := struct {
 11273  		Inner  *Inner
 11274  		Inner2 *Inner
 11275  		Field  string            `validate:"omitempty" json:"field"`
 11276  		FieldE string            `validate:"omitempty" json:"field_e"`
 11277  		Field1 string            `validate:"excluded_with=FieldE" json:"field_1"`
 11278  		Field2 *string           `validate:"excluded_with=FieldE" json:"field_2"`
 11279  		Field3 map[string]string `validate:"excluded_with=FieldE" json:"field_3"`
 11280  		Field4 interface{}       `validate:"excluded_with=FieldE" json:"field_4"`
 11281  		Field5 string            `validate:"excluded_with=Inner.FieldE" json:"field_5"`
 11282  		Field6 string            `validate:"excluded_with=Inner2.FieldE" json:"field_6"`
 11283  		Field7 Inner             `validate:"excluded_with=FieldE" json:"field_7"`
 11284  		Field8 *Inner            `validate:"excluded_with=FieldE" json:"field_8"`
 11285  	}{
 11286  		Inner:  &Inner{Field: &fieldVal},
 11287  		Field1: fieldVal,
 11288  		Field2: &fieldVal,
 11289  		Field3: map[string]string{"key": "val"},
 11290  		Field4: "test",
 11291  		Field5: "test",
 11292  		Field6: "test",
 11293  	}
 11294  
 11295  	validate := New()
 11296  
 11297  	errs := validate.Struct(test)
 11298  	Equal(t, errs, nil)
 11299  
 11300  	test2 := struct {
 11301  		Inner  *Inner
 11302  		Inner2 *Inner
 11303  		Field  string            `validate:"omitempty" json:"field"`
 11304  		FieldE string            `validate:"omitempty" json:"field_e"`
 11305  		Field1 string            `validate:"excluded_with=Field" json:"field_1"`
 11306  		Field2 *string           `validate:"excluded_with=Field" json:"field_2"`
 11307  		Field3 map[string]string `validate:"excluded_with=Field" json:"field_3"`
 11308  		Field4 interface{}       `validate:"excluded_with=Field" json:"field_4"`
 11309  		Field5 string            `validate:"excluded_with=Inner.Field" json:"field_5"`
 11310  		Field6 string            `validate:"excluded_with=Inner2.Field" json:"field_6"`
 11311  		Field7 Inner             `validate:"excluded_with=Field" json:"field_7"`
 11312  		Field8 *Inner            `validate:"excluded_with=Field" json:"field_8"`
 11313  	}{
 11314  		Inner:  &Inner{Field: &fieldVal},
 11315  		Field:  "populated",
 11316  		Field1: fieldVal,
 11317  		Field2: &fieldVal,
 11318  		Field3: map[string]string{"key": "val"},
 11319  		Field4: "test",
 11320  		Field5: "test",
 11321  		Field6: "test",
 11322  		Field7: Inner{FieldE: "potato"},
 11323  		Field8: &Inner{FieldE: "potato"},
 11324  	}
 11325  
 11326  	errs = validate.Struct(test2)
 11327  	NotEqual(t, errs, nil)
 11328  
 11329  	ve := errs.(ValidationErrors)
 11330  	Equal(t, len(ve), 7)
 11331  	for i := 1; i <= 7; i++ {
 11332  		// accounting for field 7 & 8 failures, 6 skipped because no failure
 11333  		if i > 5 {
 11334  			i++
 11335  		}
 11336  		name := fmt.Sprintf("Field%d", i)
 11337  		AssertError(t, errs, name, name, name, name, "excluded_with")
 11338  	}
 11339  
 11340  	test3 := struct {
 11341  		Inner  *Inner
 11342  		Inner2 *Inner
 11343  		Field  string            `validate:"omitempty" json:"field"`
 11344  		FieldE string            `validate:"omitempty" json:"field_e"`
 11345  		Field1 string            `validate:"excluded_with=FieldE" json:"field_1"`
 11346  		Field2 *string           `validate:"excluded_with=FieldE" json:"field_2"`
 11347  		Field3 map[string]string `validate:"excluded_with=FieldE" json:"field_3"`
 11348  		Field4 interface{}       `validate:"excluded_with=FieldE" json:"field_4"`
 11349  		Field5 string            `validate:"excluded_with=Inner.FieldE" json:"field_5"`
 11350  		Field6 string            `validate:"excluded_with=Inner2.FieldE" json:"field_6"`
 11351  		Field7 Inner             `validate:"excluded_with=FieldE" json:"field_7"`
 11352  		Field8 *Inner            `validate:"excluded_with=FieldE" json:"field_8"`
 11353  	}{
 11354  		Inner:  &Inner{FieldE: "populated"},
 11355  		Inner2: &Inner{FieldE: "populated"},
 11356  		FieldE: "populated",
 11357  	}
 11358  
 11359  	validate = New()
 11360  
 11361  	errs = validate.Struct(test3)
 11362  	Equal(t, errs, nil)
 11363  }
 11364  
 11365  func TestExcludedWithout(t *testing.T) {
 11366  	type Inner struct {
 11367  		FieldE string
 11368  		Field  *string
 11369  	}
 11370  
 11371  	fieldVal := "test"
 11372  	test := struct {
 11373  		Inner  *Inner
 11374  		Inner2 *Inner
 11375  		Field  string            `validate:"omitempty" json:"field"`
 11376  		FieldE string            `validate:"omitempty" json:"field_e"`
 11377  		Field1 string            `validate:"excluded_without=Field" json:"field_1"`
 11378  		Field2 *string           `validate:"excluded_without=Field" json:"field_2"`
 11379  		Field3 map[string]string `validate:"excluded_without=Field" json:"field_3"`
 11380  		Field4 interface{}       `validate:"excluded_without=Field" json:"field_4"`
 11381  		Field5 string            `validate:"excluded_without=Inner.Field" json:"field_5"`
 11382  		Field6 Inner             `validate:"excluded_without=Field" json:"field_6"`
 11383  		Field7 *Inner            `validate:"excluded_without=Field" json:"field_7"`
 11384  	}{
 11385  		Inner:  &Inner{Field: &fieldVal},
 11386  		Field:  "populated",
 11387  		Field1: fieldVal,
 11388  		Field2: &fieldVal,
 11389  		Field3: map[string]string{"key": "val"},
 11390  		Field4: "test",
 11391  		Field5: "test",
 11392  		Field6: Inner{FieldE: "potato"},
 11393  		Field7: &Inner{FieldE: "potato"},
 11394  	}
 11395  
 11396  	validate := New()
 11397  
 11398  	errs := validate.Struct(test)
 11399  	Equal(t, errs, nil)
 11400  
 11401  	test2 := struct {
 11402  		Inner  *Inner
 11403  		Inner2 *Inner
 11404  		Field  string            `validate:"omitempty" json:"field"`
 11405  		FieldE string            `validate:"omitempty" json:"field_e"`
 11406  		Field1 string            `validate:"excluded_without=FieldE" json:"field_1"`
 11407  		Field2 *string           `validate:"excluded_without=FieldE" json:"field_2"`
 11408  		Field3 map[string]string `validate:"excluded_without=FieldE" json:"field_3"`
 11409  		Field4 interface{}       `validate:"excluded_without=FieldE" json:"field_4"`
 11410  		Field5 string            `validate:"excluded_without=Inner.FieldE" json:"field_5"`
 11411  		Field6 string            `validate:"excluded_without=Inner2.FieldE" json:"field_6"`
 11412  		Field7 Inner             `validate:"excluded_without=FieldE" json:"field_7"`
 11413  		Field8 *Inner            `validate:"excluded_without=FieldE" json:"field_8"`
 11414  	}{
 11415  		Inner:  &Inner{Field: &fieldVal},
 11416  		Field1: fieldVal,
 11417  		Field2: &fieldVal,
 11418  		Field3: map[string]string{"key": "val"},
 11419  		Field4: "test",
 11420  		Field5: "test",
 11421  		Field6: "test",
 11422  		Field7: Inner{FieldE: "potato"},
 11423  		Field8: &Inner{FieldE: "potato"},
 11424  	}
 11425  
 11426  	errs = validate.Struct(test2)
 11427  	NotEqual(t, errs, nil)
 11428  
 11429  	ve := errs.(ValidationErrors)
 11430  	Equal(t, len(ve), 8)
 11431  	for i := 1; i <= 8; i++ {
 11432  		name := fmt.Sprintf("Field%d", i)
 11433  		AssertError(t, errs, name, name, name, name, "excluded_without")
 11434  	}
 11435  
 11436  	test3 := struct {
 11437  		Inner  *Inner
 11438  		Inner2 *Inner
 11439  		Field  string            `validate:"omitempty" json:"field"`
 11440  		FieldE string            `validate:"omitempty" json:"field_e"`
 11441  		Field1 string            `validate:"excluded_without=Field" json:"field_1"`
 11442  		Field2 *string           `validate:"excluded_without=Field" json:"field_2"`
 11443  		Field3 map[string]string `validate:"excluded_without=Field" json:"field_3"`
 11444  		Field4 interface{}       `validate:"excluded_without=Field" json:"field_4"`
 11445  		Field5 string            `validate:"excluded_without=Inner.Field" json:"field_5"`
 11446  		Field6 Inner             `validate:"excluded_without=Field" json:"field_6"`
 11447  		Field7 *Inner            `validate:"excluded_without=Field" json:"field_7"`
 11448  	}{
 11449  		Inner: &Inner{Field: &fieldVal},
 11450  		Field: "populated",
 11451  	}
 11452  
 11453  	validate = New()
 11454  
 11455  	errs = validate.Struct(test3)
 11456  	Equal(t, errs, nil)
 11457  }
 11458  
 11459  func TestExcludedWithAll(t *testing.T) {
 11460  	type Inner struct {
 11461  		FieldE string
 11462  		Field  *string
 11463  	}
 11464  
 11465  	fieldVal := "test"
 11466  	test := struct {
 11467  		Inner  *Inner
 11468  		Inner2 *Inner
 11469  		Field  string            `validate:"omitempty" json:"field"`
 11470  		FieldE string            `validate:"omitempty" json:"field_e"`
 11471  		Field1 string            `validate:"excluded_with_all=FieldE Field" json:"field_1"`
 11472  		Field2 *string           `validate:"excluded_with_all=FieldE Field" json:"field_2"`
 11473  		Field3 map[string]string `validate:"excluded_with_all=FieldE Field" json:"field_3"`
 11474  		Field4 interface{}       `validate:"excluded_with_all=FieldE Field" json:"field_4"`
 11475  		Field5 string            `validate:"excluded_with_all=Inner.FieldE" json:"field_5"`
 11476  		Field6 string            `validate:"excluded_with_all=Inner2.FieldE" json:"field_6"`
 11477  		Field7 Inner             `validate:"excluded_with_all=FieldE Field" json:"field_7"`
 11478  		Field8 *Inner            `validate:"excluded_with_all=FieldE Field" json:"field_8"`
 11479  	}{
 11480  		Inner:  &Inner{Field: &fieldVal},
 11481  		Field:  fieldVal,
 11482  		Field1: fieldVal,
 11483  		Field2: &fieldVal,
 11484  		Field3: map[string]string{"key": "val"},
 11485  		Field4: "test",
 11486  		Field5: "test",
 11487  		Field6: "test",
 11488  		Field7: Inner{FieldE: "potato"},
 11489  		Field8: &Inner{FieldE: "potato"},
 11490  	}
 11491  
 11492  	validate := New()
 11493  
 11494  	errs := validate.Struct(test)
 11495  	Equal(t, errs, nil)
 11496  
 11497  	test2 := struct {
 11498  		Inner  *Inner
 11499  		Inner2 *Inner
 11500  		Field  string            `validate:"omitempty" json:"field"`
 11501  		FieldE string            `validate:"omitempty" json:"field_e"`
 11502  		Field1 string            `validate:"excluded_with_all=Field FieldE" json:"field_1"`
 11503  		Field2 *string           `validate:"excluded_with_all=Field FieldE" json:"field_2"`
 11504  		Field3 map[string]string `validate:"excluded_with_all=Field FieldE" json:"field_3"`
 11505  		Field4 interface{}       `validate:"excluded_with_all=Field FieldE" json:"field_4"`
 11506  		Field5 string            `validate:"excluded_with_all=Inner.Field" json:"field_5"`
 11507  		Field6 string            `validate:"excluded_with_all=Inner2.Field" json:"field_6"`
 11508  		Field7 Inner             `validate:"excluded_with_all=Field FieldE" json:"field_7"`
 11509  		Field8 *Inner            `validate:"excluded_with_all=Field FieldE" json:"field_8"`
 11510  	}{
 11511  		Inner:  &Inner{Field: &fieldVal},
 11512  		Field:  "populated",
 11513  		FieldE: "populated",
 11514  		Field1: fieldVal,
 11515  		Field2: &fieldVal,
 11516  		Field3: map[string]string{"key": "val"},
 11517  		Field4: "test",
 11518  		Field5: "test",
 11519  		Field6: "test",
 11520  		Field7: Inner{FieldE: "potato"},
 11521  		Field8: &Inner{FieldE: "potato"},
 11522  	}
 11523  
 11524  	errs = validate.Struct(test2)
 11525  	NotEqual(t, errs, nil)
 11526  
 11527  	ve := errs.(ValidationErrors)
 11528  	Equal(t, len(ve), 7)
 11529  	for i := 1; i <= 7; i++ {
 11530  		// accounting for no err for field 6
 11531  		if i > 5 {
 11532  			i++
 11533  		}
 11534  		name := fmt.Sprintf("Field%d", i)
 11535  		AssertError(t, errs, name, name, name, name, "excluded_with_all")
 11536  	}
 11537  
 11538  	test3 := struct {
 11539  		Inner  *Inner
 11540  		Inner2 *Inner
 11541  		Field  string            `validate:"omitempty" json:"field"`
 11542  		FieldE string            `validate:"omitempty" json:"field_e"`
 11543  		Field1 string            `validate:"excluded_with_all=FieldE Field" json:"field_1"`
 11544  		Field2 *string           `validate:"excluded_with_all=FieldE Field" json:"field_2"`
 11545  		Field3 map[string]string `validate:"excluded_with_all=FieldE Field" json:"field_3"`
 11546  		Field4 interface{}       `validate:"excluded_with_all=FieldE Field" json:"field_4"`
 11547  		Field5 string            `validate:"excluded_with_all=Inner.FieldE" json:"field_5"`
 11548  		Field6 string            `validate:"excluded_with_all=Inner2.FieldE" json:"field_6"`
 11549  		Field7 Inner             `validate:"excluded_with_all=Field FieldE" json:"field_7"`
 11550  		Field8 *Inner            `validate:"excluded_with_all=Field FieldE" json:"field_8"`
 11551  	}{
 11552  		Inner:  &Inner{FieldE: "populated"},
 11553  		Inner2: &Inner{FieldE: "populated"},
 11554  		Field:  "populated",
 11555  		FieldE: "populated",
 11556  	}
 11557  
 11558  	validate = New()
 11559  
 11560  	errs = validate.Struct(test3)
 11561  	Equal(t, errs, nil)
 11562  }
 11563  
 11564  func TestExcludedWithoutAll(t *testing.T) {
 11565  	type Inner struct {
 11566  		FieldE string
 11567  		Field  *string
 11568  	}
 11569  
 11570  	fieldVal := "test"
 11571  	test := struct {
 11572  		Inner  *Inner
 11573  		Inner2 *Inner
 11574  		Field  string            `validate:"omitempty" json:"field"`
 11575  		FieldE string            `validate:"omitempty" json:"field_e"`
 11576  		Field1 string            `validate:"excluded_without_all=Field FieldE" json:"field_1"`
 11577  		Field2 *string           `validate:"excluded_without_all=Field FieldE" json:"field_2"`
 11578  		Field3 map[string]string `validate:"excluded_without_all=Field FieldE" json:"field_3"`
 11579  		Field4 interface{}       `validate:"excluded_without_all=Field FieldE" json:"field_4"`
 11580  		Field5 string            `validate:"excluded_without_all=Inner.Field Inner2.Field" json:"field_5"`
 11581  		Field6 Inner             `validate:"excluded_without_all=Field FieldE" json:"field_6"`
 11582  		Field7 *Inner            `validate:"excluded_without_all=Field FieldE" json:"field_7"`
 11583  	}{
 11584  		Inner:  &Inner{Field: &fieldVal},
 11585  		Inner2: &Inner{Field: &fieldVal},
 11586  		Field:  "populated",
 11587  		Field1: fieldVal,
 11588  		Field2: &fieldVal,
 11589  		Field3: map[string]string{"key": "val"},
 11590  		Field4: "test",
 11591  		Field5: "test",
 11592  		Field6: Inner{FieldE: "potato"},
 11593  		Field7: &Inner{FieldE: "potato"},
 11594  	}
 11595  
 11596  	validate := New()
 11597  
 11598  	errs := validate.Struct(test)
 11599  	Equal(t, errs, nil)
 11600  
 11601  	test2 := struct {
 11602  		Inner  *Inner
 11603  		Inner2 *Inner
 11604  		Field  string            `validate:"omitempty" json:"field"`
 11605  		FieldE string            `validate:"omitempty" json:"field_e"`
 11606  		Field1 string            `validate:"excluded_without_all=FieldE Field" json:"field_1"`
 11607  		Field2 *string           `validate:"excluded_without_all=FieldE Field" json:"field_2"`
 11608  		Field3 map[string]string `validate:"excluded_without_all=FieldE Field" json:"field_3"`
 11609  		Field4 interface{}       `validate:"excluded_without_all=FieldE Field" json:"field_4"`
 11610  		Field5 string            `validate:"excluded_without_all=Inner.FieldE" json:"field_5"`
 11611  		Field6 string            `validate:"excluded_without_all=Inner2.FieldE" json:"field_6"`
 11612  		Field7 Inner             `validate:"excluded_without_all=Field FieldE" json:"field_7"`
 11613  		Field8 *Inner            `validate:"excluded_without_all=Field FieldE" json:"field_8"`
 11614  	}{
 11615  		Inner:  &Inner{Field: &fieldVal},
 11616  		Field1: fieldVal,
 11617  		Field2: &fieldVal,
 11618  		Field3: map[string]string{"key": "val"},
 11619  		Field4: "test",
 11620  		Field5: "test",
 11621  		Field6: "test",
 11622  		Field7: Inner{FieldE: "potato"},
 11623  		Field8: &Inner{FieldE: "potato"},
 11624  	}
 11625  
 11626  	errs = validate.Struct(test2)
 11627  	NotEqual(t, errs, nil)
 11628  
 11629  	ve := errs.(ValidationErrors)
 11630  	Equal(t, len(ve), 8)
 11631  	for i := 1; i <= 8; i++ {
 11632  		name := fmt.Sprintf("Field%d", i)
 11633  		AssertError(t, errs, name, name, name, name, "excluded_without_all")
 11634  	}
 11635  
 11636  	test3 := struct {
 11637  		Inner  *Inner
 11638  		Inner2 *Inner
 11639  		Field  string            `validate:"omitempty" json:"field"`
 11640  		FieldE string            `validate:"omitempty" json:"field_e"`
 11641  		Field1 string            `validate:"excluded_without_all=Field FieldE" json:"field_1"`
 11642  		Field2 *string           `validate:"excluded_without_all=Field FieldE" json:"field_2"`
 11643  		Field3 map[string]string `validate:"excluded_without_all=Field FieldE" json:"field_3"`
 11644  		Field4 interface{}       `validate:"excluded_without_all=Field FieldE" json:"field_4"`
 11645  		Field5 string            `validate:"excluded_without_all=Inner.Field Inner2.Field" json:"field_5"`
 11646  		Field6 Inner             `validate:"excluded_without_all=Field FieldE" json:"field_6"`
 11647  		Field7 *Inner            `validate:"excluded_without_all=Field FieldE" json:"field_7"`
 11648  	}{
 11649  		Inner:  &Inner{Field: &fieldVal},
 11650  		Inner2: &Inner{Field: &fieldVal},
 11651  		Field:  "populated",
 11652  		FieldE: "populated",
 11653  	}
 11654  
 11655  	validate = New()
 11656  
 11657  	errs = validate.Struct(test3)
 11658  	Equal(t, errs, nil)
 11659  }
 11660  
 11661  func TestRequiredWithAll(t *testing.T) {
 11662  	type Inner struct {
 11663  		Field *string
 11664  	}
 11665  
 11666  	fieldVal := "test"
 11667  	test := struct {
 11668  		Inner   *Inner
 11669  		FieldE  string            `validate:"omitempty" json:"field_e"`
 11670  		FieldER string            `validate:"required_with_all=FieldE" json:"field_er"`
 11671  		Field1  string            `validate:"omitempty" json:"field_1"`
 11672  		Field2  *string           `validate:"required_with_all=Field1" json:"field_2"`
 11673  		Field3  map[string]string `validate:"required_with_all=Field2" json:"field_3"`
 11674  		Field4  interface{}       `validate:"required_with_all=Field3" json:"field_4"`
 11675  		Field5  string            `validate:"required_with_all=Inner.Field" json:"field_5"`
 11676  		Field6  Inner             `validate:"required_with_all=Field1 Field2" json:"field_6"`
 11677  		Field7  *Inner            `validate:"required_with_all=Field1 Field2" json:"field_7"`
 11678  	}{
 11679  		Inner:  &Inner{Field: &fieldVal},
 11680  		Field1: "test_field1",
 11681  		Field2: &fieldVal,
 11682  		Field3: map[string]string{"key": "val"},
 11683  		Field4: "test",
 11684  		Field5: "test",
 11685  		Field6: Inner{Field: &fieldVal},
 11686  		Field7: &Inner{Field: &fieldVal},
 11687  	}
 11688  
 11689  	validate := New()
 11690  
 11691  	errs := validate.Struct(test)
 11692  	Equal(t, errs, nil)
 11693  
 11694  	test2 := struct {
 11695  		Inner   *Inner
 11696  		Inner2  *Inner
 11697  		FieldE  string            `validate:"omitempty" json:"field_e"`
 11698  		FieldER string            `validate:"required_with_all=FieldE" json:"field_er"`
 11699  		Field1  string            `validate:"omitempty" json:"field_1"`
 11700  		Field2  *string           `validate:"required_with_all=Field1" json:"field_2"`
 11701  		Field3  map[string]string `validate:"required_with_all=Field2" json:"field_3"`
 11702  		Field4  interface{}       `validate:"required_with_all=Field1 FieldE" json:"field_4"`
 11703  		Field5  string            `validate:"required_with_all=Inner.Field Field2" json:"field_5"`
 11704  		Field6  string            `validate:"required_with_all=Inner2.Field Field2" json:"field_6"`
 11705  		Field7  Inner             `validate:"required_with_all=Inner.Field Field2" json:"field_7"`
 11706  		Field8  *Inner            `validate:"required_with_all=Inner.Field Field2" json:"field_8"`
 11707  	}{
 11708  		Inner:  &Inner{Field: &fieldVal},
 11709  		Field2: &fieldVal,
 11710  	}
 11711  
 11712  	errs = validate.Struct(test2)
 11713  	NotEqual(t, errs, nil)
 11714  
 11715  	ve := errs.(ValidationErrors)
 11716  	Equal(t, len(ve), 4)
 11717  	AssertError(t, errs, "Field3", "Field3", "Field3", "Field3", "required_with_all")
 11718  	AssertError(t, errs, "Field5", "Field5", "Field5", "Field5", "required_with_all")
 11719  	AssertError(t, errs, "Field7", "Field7", "Field7", "Field7", "required_with_all")
 11720  	AssertError(t, errs, "Field8", "Field8", "Field8", "Field8", "required_with_all")
 11721  }
 11722  
 11723  func TestRequiredWithout(t *testing.T) {
 11724  	type Inner struct {
 11725  		Field *string
 11726  	}
 11727  
 11728  	fieldVal := "test"
 11729  	test := struct {
 11730  		Inner  *Inner
 11731  		Field1 string            `validate:"omitempty" json:"field_1"`
 11732  		Field2 *string           `validate:"required_without=Field1" json:"field_2"`
 11733  		Field3 map[string]string `validate:"required_without=Field2" json:"field_3"`
 11734  		Field4 interface{}       `validate:"required_without=Field3" json:"field_4"`
 11735  		Field5 string            `validate:"required_without=Field3" json:"field_5"`
 11736  		Field6 Inner             `validate:"required_without=Field1" json:"field_6"`
 11737  		Field7 *Inner            `validate:"required_without=Field1" json:"field_7"`
 11738  	}{
 11739  		Inner:  &Inner{Field: &fieldVal},
 11740  		Field2: &fieldVal,
 11741  		Field3: map[string]string{"key": "val"},
 11742  		Field4: "test",
 11743  		Field5: "test",
 11744  		Field6: Inner{Field: &fieldVal},
 11745  		Field7: &Inner{Field: &fieldVal},
 11746  	}
 11747  
 11748  	validate := New()
 11749  
 11750  	errs := validate.Struct(test)
 11751  	Equal(t, errs, nil)
 11752  
 11753  	test2 := struct {
 11754  		Inner   *Inner
 11755  		Inner2  *Inner
 11756  		Field1  string            `json:"field_1"`
 11757  		Field2  *string           `validate:"required_without=Field1" json:"field_2"`
 11758  		Field3  map[string]string `validate:"required_without=Field2" json:"field_3"`
 11759  		Field4  interface{}       `validate:"required_without=Field3" json:"field_4"`
 11760  		Field5  string            `validate:"required_without=Field3" json:"field_5"`
 11761  		Field6  string            `validate:"required_without=Field1" json:"field_6"`
 11762  		Field7  string            `validate:"required_without=Inner.Field" json:"field_7"`
 11763  		Field8  string            `validate:"required_without=Inner.Field" json:"field_8"`
 11764  		Field9  Inner             `validate:"required_without=Field1" json:"field_9"`
 11765  		Field10 *Inner            `validate:"required_without=Field1" json:"field_10"`
 11766  	}{
 11767  		Inner:  &Inner{},
 11768  		Field3: map[string]string{"key": "val"},
 11769  		Field4: "test",
 11770  		Field5: "test",
 11771  	}
 11772  
 11773  	errs = validate.Struct(&test2)
 11774  	NotEqual(t, errs, nil)
 11775  
 11776  	ve := errs.(ValidationErrors)
 11777  	Equal(t, len(ve), 6)
 11778  	AssertError(t, errs, "Field2", "Field2", "Field2", "Field2", "required_without")
 11779  	AssertError(t, errs, "Field6", "Field6", "Field6", "Field6", "required_without")
 11780  	AssertError(t, errs, "Field7", "Field7", "Field7", "Field7", "required_without")
 11781  	AssertError(t, errs, "Field8", "Field8", "Field8", "Field8", "required_without")
 11782  	AssertError(t, errs, "Field9", "Field9", "Field9", "Field9", "required_without")
 11783  	AssertError(t, errs, "Field10", "Field10", "Field10", "Field10", "required_without")
 11784  
 11785  	test3 := struct {
 11786  		Field1 *string `validate:"required_without=Field2,omitempty,min=1" json:"field_1"`
 11787  		Field2 *string `validate:"required_without=Field1,omitempty,min=1" json:"field_2"`
 11788  	}{
 11789  		Field1: &fieldVal,
 11790  	}
 11791  
 11792  	errs = validate.Struct(&test3)
 11793  	Equal(t, errs, nil)
 11794  }
 11795  
 11796  func TestRequiredWithoutAll(t *testing.T) {
 11797  	type nested struct {
 11798  		value string
 11799  	}
 11800  	fieldVal := "test"
 11801  	test := struct {
 11802  		Field1 string            `validate:"omitempty" json:"field_1"`
 11803  		Field2 *string           `validate:"required_without_all=Field1" json:"field_2"`
 11804  		Field3 map[string]string `validate:"required_without_all=Field2" json:"field_3"`
 11805  		Field4 interface{}       `validate:"required_without_all=Field3" json:"field_4"`
 11806  		Field5 string            `validate:"required_without_all=Field3" json:"field_5"`
 11807  		Field6 nested            `validate:"required_without_all=Field1" json:"field_6"`
 11808  		Field7 *nested           `validate:"required_without_all=Field1" json:"field_7"`
 11809  	}{
 11810  		Field1: "",
 11811  		Field2: &fieldVal,
 11812  		Field3: map[string]string{"key": "val"},
 11813  		Field4: "test",
 11814  		Field5: "test",
 11815  		Field6: nested{"potato"},
 11816  		Field7: &nested{"potato"},
 11817  	}
 11818  
 11819  	validate := New()
 11820  
 11821  	errs := validate.Struct(test)
 11822  	Equal(t, errs, nil)
 11823  
 11824  	test2 := struct {
 11825  		Field1 string            `validate:"omitempty" json:"field_1"`
 11826  		Field2 *string           `validate:"required_without_all=Field1" json:"field_2"`
 11827  		Field3 map[string]string `validate:"required_without_all=Field2" json:"field_3"`
 11828  		Field4 interface{}       `validate:"required_without_all=Field3" json:"field_4"`
 11829  		Field5 string            `validate:"required_without_all=Field3" json:"field_5"`
 11830  		Field6 string            `validate:"required_without_all=Field1 Field3" json:"field_6"`
 11831  		Field7 nested            `validate:"required_without_all=Field1" json:"field_7"`
 11832  		Field8 *nested           `validate:"required_without_all=Field1" json:"field_8"`
 11833  	}{
 11834  		Field3: map[string]string{"key": "val"},
 11835  		Field4: "test",
 11836  		Field5: "test",
 11837  	}
 11838  
 11839  	errs = validate.Struct(test2)
 11840  	NotEqual(t, errs, nil)
 11841  
 11842  	ve := errs.(ValidationErrors)
 11843  	Equal(t, len(ve), 3)
 11844  	AssertError(t, errs, "Field2", "Field2", "Field2", "Field2", "required_without_all")
 11845  	AssertError(t, errs, "Field7", "Field7", "Field7", "Field7", "required_without_all")
 11846  	AssertError(t, errs, "Field8", "Field8", "Field8", "Field8", "required_without_all")
 11847  }
 11848  
 11849  func TestExcludedIf(t *testing.T) {
 11850  	validate := New()
 11851  	type Inner struct {
 11852  		Field *string
 11853  	}
 11854  
 11855  	shouldExclude := "exclude"
 11856  	shouldNotExclude := "dontExclude"
 11857  
 11858  	test1 := struct {
 11859  		FieldE  string  `validate:"omitempty" json:"field_e"`
 11860  		FieldER *string `validate:"excluded_if=FieldE exclude" json:"field_er"`
 11861  	}{
 11862  		FieldE: shouldExclude,
 11863  	}
 11864  	errs := validate.Struct(test1)
 11865  	Equal(t, errs, nil)
 11866  
 11867  	test2 := struct {
 11868  		FieldE  string `validate:"omitempty" json:"field_e"`
 11869  		FieldER string `validate:"excluded_if=FieldE exclude" json:"field_er"`
 11870  	}{
 11871  		FieldE:  shouldExclude,
 11872  		FieldER: "set",
 11873  	}
 11874  	errs = validate.Struct(test2)
 11875  	NotEqual(t, errs, nil)
 11876  	ve := errs.(ValidationErrors)
 11877  	Equal(t, len(ve), 1)
 11878  	AssertError(t, errs, "FieldER", "FieldER", "FieldER", "FieldER", "excluded_if")
 11879  
 11880  	test3 := struct {
 11881  		FieldE  string `validate:"omitempty" json:"field_e"`
 11882  		FieldF  string `validate:"omitempty" json:"field_f"`
 11883  		FieldER string `validate:"excluded_if=FieldE exclude FieldF exclude" json:"field_er"`
 11884  	}{
 11885  		FieldE:  shouldExclude,
 11886  		FieldF:  shouldExclude,
 11887  		FieldER: "set",
 11888  	}
 11889  	errs = validate.Struct(test3)
 11890  	NotEqual(t, errs, nil)
 11891  	ve = errs.(ValidationErrors)
 11892  	Equal(t, len(ve), 1)
 11893  	AssertError(t, errs, "FieldER", "FieldER", "FieldER", "FieldER", "excluded_if")
 11894  
 11895  	test4 := struct {
 11896  		FieldE  string `validate:"omitempty" json:"field_e"`
 11897  		FieldF  string `validate:"omitempty" json:"field_f"`
 11898  		FieldER string `validate:"excluded_if=FieldE exclude FieldF exclude" json:"field_er"`
 11899  	}{
 11900  		FieldE:  shouldExclude,
 11901  		FieldF:  shouldNotExclude,
 11902  		FieldER: "set",
 11903  	}
 11904  	errs = validate.Struct(test4)
 11905  	Equal(t, errs, nil)
 11906  
 11907  	test5 := struct {
 11908  		FieldE  string `validate:"omitempty" json:"field_e"`
 11909  		FieldER string `validate:"excluded_if=FieldE exclude" json:"field_er"`
 11910  	}{
 11911  		FieldE: shouldNotExclude,
 11912  	}
 11913  	errs = validate.Struct(test5)
 11914  	Equal(t, errs, nil)
 11915  
 11916  	test6 := struct {
 11917  		FieldE  string `validate:"omitempty" json:"field_e"`
 11918  		FieldER string `validate:"excluded_if=FieldE exclude" json:"field_er"`
 11919  	}{
 11920  		FieldE:  shouldNotExclude,
 11921  		FieldER: "set",
 11922  	}
 11923  	errs = validate.Struct(test6)
 11924  	Equal(t, errs, nil)
 11925  
 11926  	test7 := struct {
 11927  		Inner  *Inner
 11928  		FieldE string `validate:"omitempty" json:"field_e"`
 11929  		Field1 int    `validate:"excluded_if=Inner.Field exclude" json:"field_1"`
 11930  	}{
 11931  		Inner: &Inner{Field: &shouldExclude},
 11932  	}
 11933  	errs = validate.Struct(test7)
 11934  	Equal(t, errs, nil)
 11935  
 11936  	test8 := struct {
 11937  		Inner  *Inner
 11938  		FieldE string `validate:"omitempty" json:"field_e"`
 11939  		Field1 int    `validate:"excluded_if=Inner.Field exclude" json:"field_1"`
 11940  	}{
 11941  		Inner:  &Inner{Field: &shouldExclude},
 11942  		Field1: 1,
 11943  	}
 11944  	errs = validate.Struct(test8)
 11945  	NotEqual(t, errs, nil)
 11946  	ve = errs.(ValidationErrors)
 11947  	Equal(t, len(ve), 1)
 11948  	AssertError(t, errs, "Field1", "Field1", "Field1", "Field1", "excluded_if")
 11949  
 11950  	test9 := struct {
 11951  		Inner  *Inner
 11952  		FieldE string `validate:"omitempty" json:"field_e"`
 11953  		Field1 int    `validate:"excluded_if=Inner.Field exclude" json:"field_1"`
 11954  	}{
 11955  		Inner: &Inner{Field: &shouldNotExclude},
 11956  	}
 11957  	errs = validate.Struct(test9)
 11958  	Equal(t, errs, nil)
 11959  
 11960  	test10 := struct {
 11961  		Inner  *Inner
 11962  		FieldE string `validate:"omitempty" json:"field_e"`
 11963  		Field1 int    `validate:"excluded_if=Inner.Field exclude" json:"field_1"`
 11964  	}{
 11965  		Inner:  &Inner{Field: &shouldNotExclude},
 11966  		Field1: 1,
 11967  	}
 11968  	errs = validate.Struct(test10)
 11969  	Equal(t, errs, nil)
 11970  
 11971  	// Checks number of params in struct tag is correct
 11972  	defer func() {
 11973  		if r := recover(); r == nil {
 11974  			t.Errorf("panicTest should have panicked!")
 11975  		}
 11976  	}()
 11977  	fieldVal := "panicTest"
 11978  	panicTest := struct {
 11979  		Inner  *Inner
 11980  		Field1 string `validate:"excluded_if=Inner.Field" json:"field_1"`
 11981  	}{
 11982  		Inner: &Inner{Field: &fieldVal},
 11983  	}
 11984  	_ = validate.Struct(panicTest)
 11985  }
 11986  
 11987  func TestExcludedUnless(t *testing.T) {
 11988  	validate := New()
 11989  	type Inner struct {
 11990  		Field *string
 11991  	}
 11992  
 11993  	fieldVal := "test"
 11994  	test := struct {
 11995  		FieldE  string `validate:"omitempty" json:"field_e"`
 11996  		FieldER string `validate:"excluded_unless=FieldE test" json:"field_er"`
 11997  	}{
 11998  		FieldE:  "test",
 11999  		FieldER: "filled",
 12000  	}
 12001  	errs := validate.Struct(test)
 12002  	Equal(t, errs, nil)
 12003  
 12004  	test2 := struct {
 12005  		FieldE  string `validate:"omitempty" json:"field_e"`
 12006  		FieldER string `validate:"excluded_unless=FieldE test" json:"field_er"`
 12007  	}{
 12008  		FieldE:  "notest",
 12009  		FieldER: "filled",
 12010  	}
 12011  	errs = validate.Struct(test2)
 12012  	NotEqual(t, errs, nil)
 12013  	ve := errs.(ValidationErrors)
 12014  	Equal(t, len(ve), 1)
 12015  	AssertError(t, errs, "FieldER", "FieldER", "FieldER", "FieldER", "excluded_unless")
 12016  
 12017  	// test5 and test6: excluded_unless has no effect if FieldER is left blank
 12018  	test5 := struct {
 12019  		FieldE  string `validate:"omitempty" json:"field_e"`
 12020  		FieldER string `validate:"excluded_unless=FieldE test" json:"field_er"`
 12021  	}{
 12022  		FieldE: "test",
 12023  	}
 12024  	errs = validate.Struct(test5)
 12025  	Equal(t, errs, nil)
 12026  
 12027  	test6 := struct {
 12028  		FieldE  string `validate:"omitempty" json:"field_e"`
 12029  		FieldER string `validate:"excluded_unless=FieldE test" json:"field_er"`
 12030  	}{
 12031  		FieldE: "notest",
 12032  	}
 12033  	errs = validate.Struct(test6)
 12034  	Equal(t, errs, nil)
 12035  
 12036  	shouldError := "notest"
 12037  	test3 := struct {
 12038  		Inner  *Inner
 12039  		Field1 string `validate:"excluded_unless=Inner.Field test" json:"field_1"`
 12040  	}{
 12041  		Inner:  &Inner{Field: &shouldError},
 12042  		Field1: "filled",
 12043  	}
 12044  	errs = validate.Struct(test3)
 12045  	NotEqual(t, errs, nil)
 12046  	ve = errs.(ValidationErrors)
 12047  	Equal(t, len(ve), 1)
 12048  	AssertError(t, errs, "Field1", "Field1", "Field1", "Field1", "excluded_unless")
 12049  
 12050  	shouldPass := "test"
 12051  	test4 := struct {
 12052  		Inner  *Inner
 12053  		FieldE string `validate:"omitempty" json:"field_e"`
 12054  		Field1 string `validate:"excluded_unless=Inner.Field test" json:"field_1"`
 12055  	}{
 12056  		Inner:  &Inner{Field: &shouldPass},
 12057  		Field1: "filled",
 12058  	}
 12059  	errs = validate.Struct(test4)
 12060  	Equal(t, errs, nil)
 12061  
 12062  	// test7 and test8: excluded_unless has no effect if FieldER is left blank
 12063  	test7 := struct {
 12064  		Inner   *Inner
 12065  		FieldE  string `validate:"omitempty" json:"field_e"`
 12066  		FieldER string `validate:"excluded_unless=Inner.Field test" json:"field_er"`
 12067  	}{
 12068  		FieldE: "test",
 12069  	}
 12070  	errs = validate.Struct(test7)
 12071  	Equal(t, errs, nil)
 12072  
 12073  	test8 := struct {
 12074  		FieldE  string `validate:"omitempty" json:"field_e"`
 12075  		FieldER string `validate:"excluded_unless=Inner.Field test" json:"field_er"`
 12076  	}{
 12077  		FieldE: "test",
 12078  	}
 12079  	errs = validate.Struct(test8)
 12080  	Equal(t, errs, nil)
 12081  
 12082  	// Checks number of params in struct tag is correct
 12083  	defer func() {
 12084  		if r := recover(); r == nil {
 12085  			t.Errorf("panicTest should have panicked!")
 12086  		}
 12087  	}()
 12088  	panicTest := struct {
 12089  		Inner  *Inner
 12090  		Field1 string `validate:"excluded_unless=Inner.Field" json:"field_1"`
 12091  	}{
 12092  		Inner: &Inner{Field: &fieldVal},
 12093  	}
 12094  	_ = validate.Struct(panicTest)
 12095  }
 12096  
 12097  func TestLookup(t *testing.T) {
 12098  	type Lookup struct {
 12099  		FieldA *string `json:"fieldA,omitempty" validate:"required_without=FieldB"`
 12100  		FieldB *string `json:"fieldB,omitempty" validate:"required_without=FieldA"`
 12101  	}
 12102  
 12103  	fieldAValue := "1232"
 12104  	lookup := Lookup{
 12105  		FieldA: &fieldAValue,
 12106  		FieldB: nil,
 12107  	}
 12108  	Equal(t, New().Struct(lookup), nil)
 12109  }
 12110  
 12111  func TestAbilityToValidateNils(t *testing.T) {
 12112  	type TestStruct struct {
 12113  		Test *string `validate:"nil"`
 12114  	}
 12115  
 12116  	ts := TestStruct{}
 12117  	val := New()
 12118  	fn := func(fl FieldLevel) bool {
 12119  		return fl.Field().Kind() == reflect.Ptr && fl.Field().IsNil()
 12120  	}
 12121  
 12122  	err := val.RegisterValidation("nil", fn, true)
 12123  	Equal(t, err, nil)
 12124  
 12125  	errs := val.Struct(ts)
 12126  	Equal(t, errs, nil)
 12127  
 12128  	str := "string"
 12129  	ts.Test = &str
 12130  
 12131  	errs = val.Struct(ts)
 12132  	NotEqual(t, errs, nil)
 12133  }
 12134  
 12135  func TestRequiredWithoutPointers(t *testing.T) {
 12136  	type Lookup struct {
 12137  		FieldA *bool `json:"fieldA,omitempty" validate:"required_without=FieldB"`
 12138  		FieldB *bool `json:"fieldB,omitempty" validate:"required_without=FieldA"`
 12139  	}
 12140  
 12141  	b := true
 12142  	lookup := Lookup{
 12143  		FieldA: &b,
 12144  		FieldB: nil,
 12145  	}
 12146  
 12147  	val := New()
 12148  	errs := val.Struct(lookup)
 12149  	Equal(t, errs, nil)
 12150  
 12151  	b = false
 12152  	lookup = Lookup{
 12153  		FieldA: &b,
 12154  		FieldB: nil,
 12155  	}
 12156  	errs = val.Struct(lookup)
 12157  	Equal(t, errs, nil)
 12158  }
 12159  
 12160  func TestRequiredWithoutAllPointers(t *testing.T) {
 12161  	type Lookup struct {
 12162  		FieldA *bool `json:"fieldA,omitempty" validate:"required_without_all=FieldB"`
 12163  		FieldB *bool `json:"fieldB,omitempty" validate:"required_without_all=FieldA"`
 12164  	}
 12165  
 12166  	b := true
 12167  	lookup := Lookup{
 12168  		FieldA: &b,
 12169  		FieldB: nil,
 12170  	}
 12171  
 12172  	val := New()
 12173  	errs := val.Struct(lookup)
 12174  	Equal(t, errs, nil)
 12175  
 12176  	b = false
 12177  	lookup = Lookup{
 12178  		FieldA: &b,
 12179  		FieldB: nil,
 12180  	}
 12181  	errs = val.Struct(lookup)
 12182  	Equal(t, errs, nil)
 12183  }
 12184  
 12185  func TestGetTag(t *testing.T) {
 12186  	var tag string
 12187  
 12188  	type Test struct {
 12189  		String string `validate:"mytag"`
 12190  	}
 12191  
 12192  	val := New()
 12193  	_ = val.RegisterValidation("mytag", func(fl FieldLevel) bool {
 12194  		tag = fl.GetTag()
 12195  		return true
 12196  	})
 12197  
 12198  	var test Test
 12199  	errs := val.Struct(test)
 12200  	Equal(t, errs, nil)
 12201  	Equal(t, tag, "mytag")
 12202  }
 12203  
 12204  func TestJSONValidation(t *testing.T) {
 12205  	tests := []struct {
 12206  		param    interface{}
 12207  		expected bool
 12208  	}{
 12209  		{`foo`, false},
 12210  		{`}{`, false},
 12211  		{`{]`, false},
 12212  		{`{}`, true},
 12213  		{`{"foo":"bar"}`, true},
 12214  		{`{"foo":"bar","bar":{"baz":["qux"]}}`, true},
 12215  		{`{"foo": 3 "bar": 4}`, false},
 12216  		{`{"foo": 3 ,"bar": 4`, false},
 12217  		{`{foo": 3, "bar": 4}`, false},
 12218  		{`foo`, false},
 12219  		{`1`, true},
 12220  		{`true`, true},
 12221  		{`null`, true},
 12222  		{`"null"`, true},
 12223  		{json.RawMessage(`foo`), false},
 12224  		{json.RawMessage(`}{`), false},
 12225  		{json.RawMessage(`{]`), false},
 12226  		{json.RawMessage(`{}`), true},
 12227  		{json.RawMessage(`{"foo":"bar"}`), true},
 12228  		{json.RawMessage(`{"foo":"bar","bar":{"baz":["qux"]}}`), true},
 12229  		{json.RawMessage(`{"foo": 3 "bar": 4}`), false},
 12230  		{json.RawMessage(`{"foo": 3 ,"bar": 4`), false},
 12231  		{json.RawMessage(`{foo": 3, "bar": 4}`), false},
 12232  		{json.RawMessage(`foo`), false},
 12233  		{json.RawMessage(`1`), true},
 12234  		{json.RawMessage(`true`), true},
 12235  		{json.RawMessage(`null`), true},
 12236  		{json.RawMessage(`"null"`), true},
 12237  		{[]byte(`foo`), false},
 12238  		{[]byte(`}{`), false},
 12239  		{[]byte(`{]`), false},
 12240  		{[]byte(`{}`), true},
 12241  		{[]byte(`{"foo":"bar"}`), true},
 12242  		{[]byte(`{"foo":"bar","bar":{"baz":["qux"]}}`), true},
 12243  		{[]byte(`{"foo": 3 "bar": 4}`), false},
 12244  		{[]byte(`{"foo": 3 ,"bar": 4`), false},
 12245  		{[]byte(`{foo": 3, "bar": 4}`), false},
 12246  		{[]byte(`foo`), false},
 12247  		{[]byte(`1`), true},
 12248  		{[]byte(`true`), true},
 12249  		{[]byte(`null`), true},
 12250  		{[]byte(`"null"`), true},
 12251  	}
 12252  
 12253  	validate := New()
 12254  
 12255  	for i, test := range tests {
 12256  
 12257  		errs := validate.Var(test.param, "json")
 12258  
 12259  		if test.expected {
 12260  			if !IsEqual(errs, nil) {
 12261  				t.Fatalf("Index: %d json failed Error: %s", i, errs)
 12262  			}
 12263  		} else {
 12264  			if IsEqual(errs, nil) {
 12265  				t.Fatalf("Index: %d json failed Error: %s", i, errs)
 12266  			} else {
 12267  				val := getError(errs, "", "")
 12268  				if val.Tag() != "json" {
 12269  					t.Fatalf("Index: %d json failed Error: %s", i, errs)
 12270  				}
 12271  			}
 12272  		}
 12273  	}
 12274  
 12275  	PanicMatches(t, func() {
 12276  		_ = validate.Var(2, "json")
 12277  	}, "Bad field type int")
 12278  }
 12279  
 12280  func TestJWTValidation(t *testing.T) {
 12281  	tests := []struct {
 12282  		param    string
 12283  		expected bool
 12284  	}{
 12285  		{"eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiZ29waGVyIn0.O_bROM_szPq9qBql-XDHMranHwP48ODdoLICWzqBr_U", true},
 12286  		{"acb123-_.def456-_.ghi789-_", true},
 12287  		{"eyJhbGciOiJOT05FIn0.e30.", true},
 12288  		{"eyJhbGciOiJOT05FIn0.e30.\n", false},
 12289  		{"\x00.\x00.\x00", false},
 12290  		{"", false},
 12291  	}
 12292  
 12293  	validate := New()
 12294  
 12295  	for i, test := range tests {
 12296  
 12297  		errs := validate.Var(test.param, "jwt")
 12298  
 12299  		if test.expected {
 12300  			if !IsEqual(errs, nil) {
 12301  				t.Fatalf("Index: %d jwt failed Error: %s", i, errs)
 12302  			}
 12303  		} else {
 12304  			if IsEqual(errs, nil) {
 12305  				t.Fatalf("Index: %d jwt failed Error: %s", i, errs)
 12306  			} else {
 12307  				val := getError(errs, "", "")
 12308  				if val.Tag() != "jwt" {
 12309  					t.Fatalf("Index: %d jwt failed Error: %s", i, errs)
 12310  				}
 12311  			}
 12312  		}
 12313  	}
 12314  }
 12315  
 12316  func Test_hostnameport_validator(t *testing.T) {
 12317  	type Host struct {
 12318  		Addr string `validate:"hostname_port"`
 12319  	}
 12320  
 12321  	type testInput struct {
 12322  		data     string
 12323  		expected bool
 12324  	}
 12325  	testData := []testInput{
 12326  		{"bad..domain.name:234", false},
 12327  		{"extra.dot.com.", false},
 12328  		{"localhost:1234", true},
 12329  		{"192.168.1.1:1234", true},
 12330  		{":1234", true},
 12331  		{"domain.com:1334", true},
 12332  		{"this.domain.com:234", true},
 12333  		{"domain:75000", false},
 12334  		{"missing.port", false},
 12335  	}
 12336  	for _, td := range testData {
 12337  		h := Host{Addr: td.data}
 12338  		v := New()
 12339  		err := v.Struct(h)
 12340  		if td.expected != (err == nil) {
 12341  			t.Fatalf("Test failed for data: %v Error: %v", td.data, err)
 12342  		}
 12343  	}
 12344  }
 12345  
 12346  func TestLowercaseValidation(t *testing.T) {
 12347  	tests := []struct {
 12348  		param    string
 12349  		expected bool
 12350  	}{
 12351  		{`abcdefg`, true},
 12352  		{`Abcdefg`, false},
 12353  		{"", false},
 12354  	}
 12355  
 12356  	validate := New()
 12357  
 12358  	for i, test := range tests {
 12359  
 12360  		errs := validate.Var(test.param, "lowercase")
 12361  
 12362  		if test.expected {
 12363  			if !IsEqual(errs, nil) {
 12364  				t.Fatalf("Index: %d lowercase failed Error: %s", i, errs)
 12365  			}
 12366  		} else {
 12367  			if IsEqual(errs, nil) {
 12368  				t.Fatalf("Index: %d lowercase failed Error: %s", i, errs)
 12369  			} else {
 12370  				val := getError(errs, "", "")
 12371  				if val.Tag() != "lowercase" {
 12372  					t.Fatalf("Index: %d lowercase failed Error: %s", i, errs)
 12373  				}
 12374  			}
 12375  		}
 12376  	}
 12377  
 12378  	PanicMatches(t, func() {
 12379  		_ = validate.Var(2, "lowercase")
 12380  	}, "Bad field type int")
 12381  }
 12382  
 12383  func TestUppercaseValidation(t *testing.T) {
 12384  	tests := []struct {
 12385  		param    string
 12386  		expected bool
 12387  	}{
 12388  		{`ABCDEFG`, true},
 12389  		{`aBCDEFG`, false},
 12390  		{"", false},
 12391  	}
 12392  
 12393  	validate := New()
 12394  
 12395  	for i, test := range tests {
 12396  
 12397  		errs := validate.Var(test.param, "uppercase")
 12398  
 12399  		if test.expected {
 12400  			if !IsEqual(errs, nil) {
 12401  				t.Fatalf("Index: %d uppercase failed Error: %s", i, errs)
 12402  			}
 12403  		} else {
 12404  			if IsEqual(errs, nil) {
 12405  				t.Fatalf("Index: %d uppercase failed Error: %s", i, errs)
 12406  			} else {
 12407  				val := getError(errs, "", "")
 12408  				if val.Tag() != "uppercase" {
 12409  					t.Fatalf("Index: %d uppercase failed Error: %s", i, errs)
 12410  				}
 12411  			}
 12412  		}
 12413  	}
 12414  
 12415  	PanicMatches(t, func() {
 12416  		_ = validate.Var(2, "uppercase")
 12417  	}, "Bad field type int")
 12418  }
 12419  
 12420  func TestDatetimeValidation(t *testing.T) {
 12421  	tests := []struct {
 12422  		value    string `validate:"datetime=2006-01-02"`
 12423  		tag      string
 12424  		expected bool
 12425  	}{
 12426  		{"2008-02-01", `datetime=2006-01-02`, true},
 12427  		{"2008-Feb-01", `datetime=2006-01-02`, false},
 12428  	}
 12429  
 12430  	validate := New()
 12431  
 12432  	for i, test := range tests {
 12433  
 12434  		errs := validate.Var(test.value, test.tag)
 12435  
 12436  		if test.expected {
 12437  			if !IsEqual(errs, nil) {
 12438  				t.Fatalf("Index: %d datetime failed Error: %s", i, errs)
 12439  			}
 12440  		} else {
 12441  			if IsEqual(errs, nil) {
 12442  				t.Fatalf("Index: %d datetime failed Error: %s", i, errs)
 12443  			} else {
 12444  				val := getError(errs, "", "")
 12445  				if val.Tag() != "datetime" {
 12446  					t.Fatalf("Index: %d datetime failed Error: %s", i, errs)
 12447  				}
 12448  			}
 12449  		}
 12450  	}
 12451  
 12452  	PanicMatches(t, func() {
 12453  		_ = validate.Var(2, "datetime")
 12454  	}, "Bad field type int")
 12455  }
 12456  
 12457  func TestIsIso3166Alpha2Validation(t *testing.T) {
 12458  	tests := []struct {
 12459  		value    string `validate:"iso3166_1_alpha2"`
 12460  		expected bool
 12461  	}{
 12462  		{"PL", true},
 12463  		{"POL", false},
 12464  		{"AA", false},
 12465  	}
 12466  
 12467  	validate := New()
 12468  
 12469  	for i, test := range tests {
 12470  
 12471  		errs := validate.Var(test.value, "iso3166_1_alpha2")
 12472  
 12473  		if test.expected {
 12474  			if !IsEqual(errs, nil) {
 12475  				t.Fatalf("Index: %d iso3166_1_alpha2 failed Error: %s", i, errs)
 12476  			}
 12477  		} else {
 12478  			if IsEqual(errs, nil) {
 12479  				t.Fatalf("Index: %d iso3166_1_alpha2 failed Error: %s", i, errs)
 12480  			}
 12481  		}
 12482  	}
 12483  }
 12484  
 12485  func TestIsIso31662Validation(t *testing.T) {
 12486  	tests := []struct {
 12487  		value    string `validate:"iso3166_2"`
 12488  		expected bool
 12489  	}{
 12490  		{"US-FL", true},
 12491  		{"US-F", false},
 12492  		{"US", false},
 12493  	}
 12494  
 12495  	validate := New()
 12496  
 12497  	for i, test := range tests {
 12498  
 12499  		errs := validate.Var(test.value, "iso3166_2")
 12500  
 12501  		if test.expected {
 12502  			if !IsEqual(errs, nil) {
 12503  				t.Fatalf("Index: %d iso3166_2 failed Error: %s", i, errs)
 12504  			}
 12505  		} else {
 12506  			if IsEqual(errs, nil) {
 12507  				t.Fatalf("Index: %d iso3166_2 failed Error: %s", i, errs)
 12508  			}
 12509  		}
 12510  	}
 12511  }
 12512  
 12513  func TestIsIso3166Alpha3Validation(t *testing.T) {
 12514  	tests := []struct {
 12515  		value    string `validate:"iso3166_1_alpha3"`
 12516  		expected bool
 12517  	}{
 12518  		{"POL", true},
 12519  		{"PL", false},
 12520  		{"AAA", false},
 12521  	}
 12522  
 12523  	validate := New()
 12524  
 12525  	for i, test := range tests {
 12526  
 12527  		errs := validate.Var(test.value, "iso3166_1_alpha3")
 12528  
 12529  		if test.expected {
 12530  			if !IsEqual(errs, nil) {
 12531  				t.Fatalf("Index: %d iso3166_1_alpha3 failed Error: %s", i, errs)
 12532  			}
 12533  		} else {
 12534  			if IsEqual(errs, nil) {
 12535  				t.Fatalf("Index: %d iso3166_1_alpha3 failed Error: %s", i, errs)
 12536  			}
 12537  		}
 12538  	}
 12539  }
 12540  
 12541  func TestIsIso3166AlphaNumericValidation(t *testing.T) {
 12542  	tests := []struct {
 12543  		value    interface{}
 12544  		expected bool
 12545  	}{
 12546  		{248, true},
 12547  		{"248", true},
 12548  		{0, false},
 12549  		{1, false},
 12550  		{"1", false},
 12551  		{"invalid_int", false},
 12552  	}
 12553  
 12554  	validate := New()
 12555  
 12556  	for i, test := range tests {
 12557  
 12558  		errs := validate.Var(test.value, "iso3166_1_alpha_numeric")
 12559  
 12560  		if test.expected {
 12561  			if !IsEqual(errs, nil) {
 12562  				t.Fatalf("Index: %d iso3166_1_alpha_numeric failed Error: %s", i, errs)
 12563  			}
 12564  		} else {
 12565  			if IsEqual(errs, nil) {
 12566  				t.Fatalf("Index: %d iso3166_1_alpha_numeric failed Error: %s", i, errs)
 12567  			}
 12568  		}
 12569  	}
 12570  
 12571  	PanicMatches(t, func() {
 12572  		_ = validate.Var([]string{"1"}, "iso3166_1_alpha_numeric")
 12573  	}, "Bad field type []string")
 12574  }
 12575  
 12576  func TestCountryCodeValidation(t *testing.T) {
 12577  	tests := []struct {
 12578  		value    interface{}
 12579  		expected bool
 12580  	}{
 12581  		{248, true},
 12582  		{0, false},
 12583  		{1, false},
 12584  		{"POL", true},
 12585  		{"NO", true},
 12586  		{"248", true},
 12587  		{"1", false},
 12588  		{"0", false},
 12589  	}
 12590  
 12591  	validate := New()
 12592  
 12593  	for i, test := range tests {
 12594  
 12595  		errs := validate.Var(test.value, "country_code")
 12596  
 12597  		if test.expected {
 12598  			if !IsEqual(errs, nil) {
 12599  				t.Fatalf("Index: %d country_code failed Error: %s", i, errs)
 12600  			}
 12601  		} else {
 12602  			if IsEqual(errs, nil) {
 12603  				t.Fatalf("Index: %d country_code failed Error: %s", i, errs)
 12604  			}
 12605  		}
 12606  	}
 12607  }
 12608  
 12609  func TestIsIso4217Validation(t *testing.T) {
 12610  	tests := []struct {
 12611  		value    string `validate:"iso4217"`
 12612  		expected bool
 12613  	}{
 12614  		{"TRY", true},
 12615  		{"EUR", true},
 12616  		{"USA", false},
 12617  	}
 12618  
 12619  	validate := New()
 12620  
 12621  	for i, test := range tests {
 12622  
 12623  		errs := validate.Var(test.value, "iso4217")
 12624  
 12625  		if test.expected {
 12626  			if !IsEqual(errs, nil) {
 12627  				t.Fatalf("Index: %d iso4217 failed Error: %s", i, errs)
 12628  			}
 12629  		} else {
 12630  			if IsEqual(errs, nil) {
 12631  				t.Fatalf("Index: %d iso4217 failed Error: %s", i, errs)
 12632  			}
 12633  		}
 12634  	}
 12635  }
 12636  
 12637  func TestIsIso4217NumericValidation(t *testing.T) {
 12638  	tests := []struct {
 12639  		value    int `validate:"iso4217_numeric"`
 12640  		expected bool
 12641  	}{
 12642  		{8, true},
 12643  		{12, true},
 12644  		{13, false},
 12645  	}
 12646  
 12647  	validate := New()
 12648  
 12649  	for i, test := range tests {
 12650  
 12651  		errs := validate.Var(test.value, "iso4217_numeric")
 12652  
 12653  		if test.expected {
 12654  			if !IsEqual(errs, nil) {
 12655  				t.Fatalf("Index: %d iso4217 failed Error: %s", i, errs)
 12656  			}
 12657  		} else {
 12658  			if IsEqual(errs, nil) {
 12659  				t.Fatalf("Index: %d iso4217 failed Error: %s", i, errs)
 12660  			}
 12661  		}
 12662  	}
 12663  }
 12664  
 12665  func TestTimeZoneValidation(t *testing.T) {
 12666  	tests := []struct {
 12667  		value    string `validate:"timezone"`
 12668  		tag      string
 12669  		expected bool
 12670  	}{
 12671  		// systems may have different time zone database, some systems time zone are case insensitive
 12672  		{"America/New_York", `timezone`, true},
 12673  		{"UTC", `timezone`, true},
 12674  		{"", `timezone`, false},
 12675  		{"Local", `timezone`, false},
 12676  		{"Unknown", `timezone`, false},
 12677  	}
 12678  
 12679  	validate := New()
 12680  
 12681  	for i, test := range tests {
 12682  
 12683  		errs := validate.Var(test.value, test.tag)
 12684  
 12685  		if test.expected {
 12686  			if !IsEqual(errs, nil) {
 12687  				t.Fatalf("Index: %d time zone failed Error: %s", i, errs)
 12688  			}
 12689  		} else {
 12690  			if IsEqual(errs, nil) {
 12691  				t.Fatalf("Index: %d time zone failed Error: %s", i, errs)
 12692  			} else {
 12693  				val := getError(errs, "", "")
 12694  				if val.Tag() != "timezone" {
 12695  					t.Fatalf("Index: %d time zone failed Error: %s", i, errs)
 12696  				}
 12697  			}
 12698  		}
 12699  	}
 12700  
 12701  	PanicMatches(t, func() {
 12702  		_ = validate.Var(2, "timezone")
 12703  	}, "Bad field type int")
 12704  }
 12705  
 12706  func TestDurationType(t *testing.T) {
 12707  	tests := []struct {
 12708  		name    string
 12709  		s       interface{} // struct
 12710  		success bool
 12711  	}{
 12712  		{
 12713  			name: "valid duration string pass",
 12714  			s: struct {
 12715  				Value time.Duration `validate:"gte=500ns"`
 12716  			}{
 12717  				Value: time.Second,
 12718  			},
 12719  			success: true,
 12720  		},
 12721  		{
 12722  			name: "valid duration int pass",
 12723  			s: struct {
 12724  				Value time.Duration `validate:"gte=500"`
 12725  			}{
 12726  				Value: time.Second,
 12727  			},
 12728  			success: true,
 12729  		},
 12730  	}
 12731  
 12732  	validate := New()
 12733  
 12734  	for _, tc := range tests {
 12735  		tc := tc
 12736  		t.Run(tc.name, func(t *testing.T) {
 12737  			t.Parallel()
 12738  
 12739  			errs := validate.Struct(tc.s)
 12740  			if tc.success {
 12741  				Equal(t, errs, nil)
 12742  				return
 12743  			}
 12744  			NotEqual(t, errs, nil)
 12745  		})
 12746  	}
 12747  }
 12748  
 12749  func TestBCP47LanguageTagValidation(t *testing.T) {
 12750  	tests := []struct {
 12751  		value    string `validate:"bcp47_language_tag"`
 12752  		tag      string
 12753  		expected bool
 12754  	}{
 12755  		{"en-US", "bcp47_language_tag", true},
 12756  		{"en_GB", "bcp47_language_tag", true},
 12757  		{"es", "bcp47_language_tag", true},
 12758  		{"English", "bcp47_language_tag", false},
 12759  		{"ESES", "bcp47_language_tag", false},
 12760  		{"az-Cyrl-AZ", "bcp47_language_tag", true},
 12761  		{"en-029", "bcp47_language_tag", true},
 12762  		{"xog", "bcp47_language_tag", true},
 12763  	}
 12764  
 12765  	validate := New()
 12766  
 12767  	for i, test := range tests {
 12768  
 12769  		errs := validate.Var(test.value, test.tag)
 12770  
 12771  		if test.expected {
 12772  			if !IsEqual(errs, nil) {
 12773  				t.Fatalf("Index: %d locale failed Error: %s", i, errs)
 12774  			}
 12775  		} else {
 12776  			if IsEqual(errs, nil) {
 12777  				t.Fatalf("Index: %d locale failed Error: %s", i, errs)
 12778  			} else {
 12779  				val := getError(errs, "", "")
 12780  				if val.Tag() != "bcp47_language_tag" {
 12781  					t.Fatalf("Index: %d locale failed Error: %s", i, errs)
 12782  				}
 12783  			}
 12784  		}
 12785  	}
 12786  
 12787  	PanicMatches(t, func() {
 12788  		_ = validate.Var(2, "bcp47_language_tag")
 12789  	}, "Bad field type int")
 12790  }
 12791  
 12792  func TestBicIsoFormatValidation(t *testing.T) {
 12793  	tests := []struct {
 12794  		value    string `validate:"bic"`
 12795  		tag      string
 12796  		expected bool
 12797  	}{
 12798  		{"SBICKEN1345", "bic", true},
 12799  		{"SBICKEN1", "bic", true},
 12800  		{"SBICKENY", "bic", true},
 12801  		{"SBICKEN1YYP", "bic", true},
 12802  		{"SBIC23NXXX", "bic", false},
 12803  		{"S23CKENXXXX", "bic", false},
 12804  		{"SBICKENXX", "bic", false},
 12805  		{"SBICKENXX9", "bic", false},
 12806  		{"SBICKEN13458", "bic", false},
 12807  		{"SBICKEN", "bic", false},
 12808  	}
 12809  
 12810  	validate := New()
 12811  
 12812  	for i, test := range tests {
 12813  
 12814  		errs := validate.Var(test.value, test.tag)
 12815  
 12816  		if test.expected {
 12817  			if !IsEqual(errs, nil) {
 12818  				t.Fatalf("Index: %d bic failed Error: %s", i, errs)
 12819  			}
 12820  		} else {
 12821  			if IsEqual(errs, nil) {
 12822  				t.Fatalf("Index: %d bic failed Error: %s", i, errs)
 12823  			} else {
 12824  				val := getError(errs, "", "")
 12825  				if val.Tag() != "bic" {
 12826  					t.Fatalf("Index: %d bic failed Error: %s", i, errs)
 12827  				}
 12828  			}
 12829  		}
 12830  	}
 12831  }
 12832  
 12833  func TestSemverFormatValidation(t *testing.T) {
 12834  	tests := []struct {
 12835  		value    string `validate:"semver"`
 12836  		tag      string
 12837  		expected bool
 12838  	}{
 12839  		{"1.2.3", "semver", true},
 12840  		{"10.20.30", "semver", true},
 12841  		{"1.1.2-prerelease+meta", "semver", true},
 12842  		{"1.1.2+meta", "semver", true},
 12843  		{"1.1.2+meta-valid", "semver", true},
 12844  		{"1.0.0-alpha", "semver", true},
 12845  		{"1.0.0-alpha.1", "semver", true},
 12846  		{"1.0.0-alpha.beta", "semver", true},
 12847  		{"1.0.0-alpha.beta.1", "semver", true},
 12848  		{"1.0.0-alpha0.valid", "semver", true},
 12849  		{"1.0.0-alpha.0valid", "semver", true},
 12850  		{"1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay", "semver", true},
 12851  		{"1.0.0-rc.1+build.1", "semver", true},
 12852  		{"1.0.0-rc.1+build.123", "semver", true},
 12853  		{"1.2.3-beta", "semver", true},
 12854  		{"1.2.3-DEV-SNAPSHOT", "semver", true},
 12855  		{"1.2.3-SNAPSHOT-123", "semver", true},
 12856  		{"2.0.0+build.1848", "semver", true},
 12857  		{"2.0.1-alpha.1227", "semver", true},
 12858  		{"1.0.0-alpha+beta", "semver", true},
 12859  		{"1.2.3----RC-SNAPSHOT.12.9.1--.12+788", "semver", true},
 12860  		{"1.2.3----R-S.12.9.1--.12+meta", "semver", true},
 12861  		{"1.2.3----RC-SNAPSHOT.12.9.1--.12", "semver", true},
 12862  		{"1.0.0+0.build.1-rc.10000aaa-kk-0.1", "semver", true},
 12863  		{"99999999999999999999999.999999999999999999.99999999999999999", "semver", true},
 12864  		{"1.0.0-0A.is.legal", "semver", true},
 12865  		{"1", "semver", false},
 12866  		{"1.2", "semver", false},
 12867  		{"1.2.3-0123", "semver", false},
 12868  		{"1.2.3-0123.0123", "semver", false},
 12869  		{"1.1.2+.123", "semver", false},
 12870  		{"+invalid", "semver", false},
 12871  		{"-invalid", "semver", false},
 12872  		{"-invalid+invalid", "semver", false},
 12873  		{"alpha", "semver", false},
 12874  		{"alpha.beta.1", "semver", false},
 12875  		{"alpha.1", "semver", false},
 12876  		{"1.0.0-alpha_beta", "semver", false},
 12877  		{"1.0.0-alpha_beta", "semver", false},
 12878  		{"1.0.0-alpha...1", "semver", false},
 12879  		{"01.1.1", "semver", false},
 12880  		{"1.01.1", "semver", false},
 12881  		{"1.1.01", "semver", false},
 12882  		{"1.2", "semver", false},
 12883  		{"1.2.Dev", "semver", false},
 12884  		{"1.2.3.Dev", "semver", false},
 12885  		{"1.2-SNAPSHOT", "semver", false},
 12886  	}
 12887  
 12888  	validate := New()
 12889  
 12890  	for i, test := range tests {
 12891  
 12892  		errs := validate.Var(test.value, test.tag)
 12893  
 12894  		if test.expected {
 12895  			if !IsEqual(errs, nil) {
 12896  				t.Fatalf("Index: %d semver failed Error: %s", i, errs)
 12897  			}
 12898  		} else {
 12899  			if IsEqual(errs, nil) {
 12900  				t.Fatalf("Index: %d semver failed Error: %s", i, errs)
 12901  			} else {
 12902  				val := getError(errs, "", "")
 12903  				if val.Tag() != "semver" {
 12904  					t.Fatalf("Index: %d semver failed Error: %s", i, errs)
 12905  				}
 12906  			}
 12907  		}
 12908  	}
 12909  }
 12910  
 12911  func TestCveFormatValidation(t *testing.T) {
 12912  
 12913  	tests := []struct {
 12914  		value    string `validate:"cve"`
 12915  		tag      string
 12916  		expected bool
 12917  	}{
 12918  		{"CVE-1999-0001", "cve", true},
 12919  		{"CVE-1998-0001", "cve", false},
 12920  		{"CVE-2000-0001", "cve", true},
 12921  		{"CVE-2222-0001", "cve", true},
 12922  		{"2222-0001", "cve", false},
 12923  		{"-2222-0001", "cve", false},
 12924  		{"CVE22220001", "cve", false},
 12925  		{"CVE-2222-000001", "cve", false},
 12926  		{"CVE-2222-100001", "cve", true},
 12927  		{"CVE-2222-99999999999", "cve", true},
 12928  		{"CVE-3000-0001", "cve", false},
 12929  		{"CVE-1999-0000", "cve", false},
 12930  		{"CVE-2099-0000", "cve", false},
 12931  	}
 12932  
 12933  	validate := New()
 12934  
 12935  	for i, test := range tests {
 12936  		errs := validate.Var(test.value, test.tag)
 12937  
 12938  		if test.expected {
 12939  			if !IsEqual(errs, nil) {
 12940  				t.Fatalf("Index: %d cve failed Error: %s", i, errs)
 12941  			}
 12942  		} else {
 12943  			if IsEqual(errs, nil) {
 12944  				t.Fatalf("Index: %d cve failed Error: %s", i, errs)
 12945  			} else {
 12946  				val := getError(errs, "", "")
 12947  				if val.Tag() != "cve" {
 12948  					t.Fatalf("Index: %d cve failed Error: %s", i, errs)
 12949  				}
 12950  			}
 12951  		}
 12952  	}
 12953  }
 12954  
 12955  func TestRFC1035LabelFormatValidation(t *testing.T) {
 12956  	tests := []struct {
 12957  		value    string `validate:"dns_rfc1035_label"`
 12958  		tag      string
 12959  		expected bool
 12960  	}{
 12961  		{"abc", "dns_rfc1035_label", true},
 12962  		{"abc-", "dns_rfc1035_label", false},
 12963  		{"abc-123", "dns_rfc1035_label", true},
 12964  		{"ABC", "dns_rfc1035_label", false},
 12965  		{"ABC-123", "dns_rfc1035_label", false},
 12966  		{"abc-abc", "dns_rfc1035_label", true},
 12967  		{"ABC-ABC", "dns_rfc1035_label", false},
 12968  		{"123-abc", "dns_rfc1035_label", false},
 12969  		{"", "dns_rfc1035_label", false},
 12970  	}
 12971  
 12972  	validate := New()
 12973  
 12974  	for i, test := range tests {
 12975  		errs := validate.Var(test.value, test.tag)
 12976  
 12977  		if test.expected {
 12978  			if !IsEqual(errs, nil) {
 12979  				t.Fatalf("Index: %d dns_rfc1035_label failed Error: %s", i, errs)
 12980  			}
 12981  		} else {
 12982  			if IsEqual(errs, nil) {
 12983  				t.Fatalf("Index: %d dns_rfc1035_label failed Error: %s", i, errs)
 12984  			} else {
 12985  				val := getError(errs, "", "")
 12986  				if val.Tag() != "dns_rfc1035_label" {
 12987  					t.Fatalf("Index: %d dns_rfc1035_label failed Error: %s", i, errs)
 12988  				}
 12989  			}
 12990  		}
 12991  	}
 12992  }
 12993  
 12994  func TestPostCodeByIso3166Alpha2(t *testing.T) {
 12995  	tests := map[string][]struct {
 12996  		value    string
 12997  		expected bool
 12998  	}{
 12999  		"VN": {
 13000  			{"ABC", false},
 13001  			{"700000", true},
 13002  			{"A1", false},
 13003  		},
 13004  		"GB": {
 13005  			{"EC1A 1BB", true},
 13006  			{"CF10 1B1H", false},
 13007  		},
 13008  		"VI": {
 13009  			{"00803", true},
 13010  			{"1234567", false},
 13011  		},
 13012  		"LC": {
 13013  			// not support regexp for post code
 13014  			{"123456", false},
 13015  		},
 13016  		"XX": {
 13017  			// not support country
 13018  			{"123456", false},
 13019  		},
 13020  	}
 13021  
 13022  	validate := New()
 13023  
 13024  	for cc, ccTests := range tests {
 13025  		for i, test := range ccTests {
 13026  			errs := validate.Var(test.value, fmt.Sprintf("postcode_iso3166_alpha2=%s", cc))
 13027  
 13028  			if test.expected {
 13029  				if !IsEqual(errs, nil) {
 13030  					t.Fatalf("Index: %d postcode_iso3166_alpha2=%s failed Error: %s", i, cc, errs)
 13031  				}
 13032  			} else {
 13033  				if IsEqual(errs, nil) {
 13034  					t.Fatalf("Index: %d postcode_iso3166_alpha2=%s failed Error: %s", i, cc, errs)
 13035  				}
 13036  			}
 13037  		}
 13038  	}
 13039  }
 13040  
 13041  func TestPostCodeByIso3166Alpha2Field(t *testing.T) {
 13042  	tests := []struct {
 13043  		Value       string `validate:"postcode_iso3166_alpha2_field=CountryCode"`
 13044  		CountryCode interface{}
 13045  		expected    bool
 13046  	}{
 13047  		{"ABC", "VN", false},
 13048  		{"700000", "VN", true},
 13049  		{"A1", "VN", false},
 13050  		{"EC1A 1BB", "GB", true},
 13051  		{"CF10 1B1H", "GB", false},
 13052  		{"00803", "VI", true},
 13053  		{"1234567", "VI", false},
 13054  		{"123456", "LC", false}, // not support regexp for post code
 13055  		{"123456", "XX", false}, // not support country
 13056  	}
 13057  
 13058  	validate := New()
 13059  
 13060  	for i, test := range tests {
 13061  		errs := validate.Struct(test)
 13062  		if test.expected {
 13063  			if !IsEqual(errs, nil) {
 13064  				t.Fatalf("Index: %d postcode_iso3166_alpha2_field=CountryCode failed Error: %s", i, errs)
 13065  			}
 13066  		} else {
 13067  			if IsEqual(errs, nil) {
 13068  				t.Fatalf("Index: %d postcode_iso3166_alpha2_field=CountryCode failed Error: %s", i, errs)
 13069  			}
 13070  		}
 13071  	}
 13072  }
 13073  
 13074  func TestPostCodeByIso3166Alpha2Field_WrongField(t *testing.T) {
 13075  	type test struct {
 13076  		Value        string `validate:"postcode_iso3166_alpha2_field=CountryCode"`
 13077  		CountryCode1 interface{}
 13078  		expected     bool
 13079  	}
 13080  
 13081  	errs := New().Struct(test{"ABC", "VN", false})
 13082  	NotEqual(t, nil, errs)
 13083  }
 13084  
 13085  func TestPostCodeByIso3166Alpha2Field_MissingParam(t *testing.T) {
 13086  	type test struct {
 13087  		Value        string `validate:"postcode_iso3166_alpha2_field="`
 13088  		CountryCode1 interface{}
 13089  		expected     bool
 13090  	}
 13091  
 13092  	errs := New().Struct(test{"ABC", "VN", false})
 13093  	NotEqual(t, nil, errs)
 13094  }
 13095  
 13096  func TestPostCodeByIso3166Alpha2Field_InvalidKind(t *testing.T) {
 13097  	type test struct {
 13098  		Value       string `validate:"postcode_iso3166_alpha2_field=CountryCode"`
 13099  		CountryCode interface{}
 13100  		expected    bool
 13101  	}
 13102  	defer func() { _ = recover() }()
 13103  
 13104  	_ = New().Struct(test{"ABC", 123, false})
 13105  	t.Errorf("Didn't panic as expected")
 13106  }
 13107  
 13108  func TestValidate_ValidateMapCtx(t *testing.T) {
 13109  
 13110  	type args struct {
 13111  		data  map[string]interface{}
 13112  		rules map[string]interface{}
 13113  	}
 13114  	tests := []struct {
 13115  		name string
 13116  		args args
 13117  		want int
 13118  	}{
 13119  		{
 13120  			name: "test nested map in slice",
 13121  			args: args{
 13122  				data: map[string]interface{}{
 13123  					"Test_A": map[string]interface{}{
 13124  						"Test_B": "Test_B",
 13125  						"Test_C": []map[string]interface{}{
 13126  							{
 13127  								"Test_D": "Test_D",
 13128  							},
 13129  						},
 13130  						"Test_E": map[string]interface{}{
 13131  							"Test_F": "Test_F",
 13132  						},
 13133  					},
 13134  				},
 13135  				rules: map[string]interface{}{
 13136  					"Test_A": map[string]interface{}{
 13137  						"Test_B": "min=2",
 13138  						"Test_C": map[string]interface{}{
 13139  							"Test_D": "min=2",
 13140  						},
 13141  						"Test_E": map[string]interface{}{
 13142  							"Test_F": "min=2",
 13143  						},
 13144  					},
 13145  				},
 13146  			},
 13147  			want: 0,
 13148  		},
 13149  
 13150  		{
 13151  			name: "test nested map error",
 13152  			args: args{
 13153  				data: map[string]interface{}{
 13154  					"Test_A": map[string]interface{}{
 13155  						"Test_B": "Test_B",
 13156  						"Test_C": []interface{}{"Test_D"},
 13157  						"Test_E": map[string]interface{}{
 13158  							"Test_F": "Test_F",
 13159  						},
 13160  						"Test_G": "Test_G",
 13161  						"Test_I": []map[string]interface{}{
 13162  							{
 13163  								"Test_J": "Test_J",
 13164  							},
 13165  						},
 13166  					},
 13167  				},
 13168  				rules: map[string]interface{}{
 13169  					"Test_A": map[string]interface{}{
 13170  						"Test_B": "min=2",
 13171  						"Test_C": map[string]interface{}{
 13172  							"Test_D": "min=2",
 13173  						},
 13174  						"Test_E": map[string]interface{}{
 13175  							"Test_F": "min=100",
 13176  						},
 13177  						"Test_G": map[string]interface{}{
 13178  							"Test_H": "min=2",
 13179  						},
 13180  						"Test_I": map[string]interface{}{
 13181  							"Test_J": "min=100",
 13182  						},
 13183  					},
 13184  				},
 13185  			},
 13186  			want: 1,
 13187  		},
 13188  	}
 13189  	for _, tt := range tests {
 13190  		t.Run(tt.name, func(t *testing.T) {
 13191  			validate := New()
 13192  			if got := validate.ValidateMapCtx(context.Background(), tt.args.data, tt.args.rules); len(got) != tt.want {
 13193  				t.Errorf("ValidateMapCtx() = %v, want %v", got, tt.want)
 13194  			}
 13195  		})
 13196  	}
 13197  }
 13198  
 13199  func TestMongoDBObjectIDFormatValidation(t *testing.T) {
 13200  	tests := []struct {
 13201  		value    string `validate:"mongodb"`
 13202  		tag      string
 13203  		expected bool
 13204  	}{
 13205  		{"507f191e810c19729de860ea", "mongodb", true},
 13206  		{"507f191e810c19729de860eG", "mongodb", false},
 13207  		{"M07f191e810c19729de860eG", "mongodb", false},
 13208  		{"07f191e810c19729de860ea", "mongodb", false},
 13209  		{"507f191e810c19729de860e", "mongodb", false},
 13210  		{"507f191e810c19729de860ea4", "mongodb", false},
 13211  	}
 13212  
 13213  	validate := New()
 13214  
 13215  	for i, test := range tests {
 13216  		errs := validate.Var(test.value, test.tag)
 13217  
 13218  		if test.expected {
 13219  			if !IsEqual(errs, nil) {
 13220  				t.Fatalf("Index: %d mongodb failed Error: %s", i, errs)
 13221  			}
 13222  		} else {
 13223  			if IsEqual(errs, nil) {
 13224  				t.Fatalf("Index: %d mongodb failed Error: %s", i, errs)
 13225  			} else {
 13226  				val := getError(errs, "", "")
 13227  				if val.Tag() != "mongodb" {
 13228  					t.Fatalf("Index: %d mongodb failed Error: %s", i, errs)
 13229  				}
 13230  			}
 13231  		}
 13232  	}
 13233  }
 13234  
 13235  func TestSpiceDBValueFormatValidation(t *testing.T) {
 13236  	tests := []struct {
 13237  		value    string
 13238  		tag      string
 13239  		expected bool
 13240  	}{
 13241  		// Must be an asterisk OR a string containing alphanumeric characters and a restricted set a special symbols: _ | / - = +
 13242  		{"*", "spicedb=id", true},
 13243  		{`azAZ09_|/-=+`, "spicedb=id", true},
 13244  		{`a*`, "spicedb=id", false},
 13245  		{`/`, "spicedb=id", true},
 13246  		{"*", "spicedb", true},
 13247  
 13248  		// Must begin and end with a lowercase letter, may also contain numbers and underscores between, min length 3, max length 64
 13249  		{"a", "spicedb=permission", false},
 13250  		{"1", "spicedb=permission", false},
 13251  		{"a1", "spicedb=permission", false},
 13252  		{"a_b", "spicedb=permission", true},
 13253  		{"A_b", "spicedb=permission", false},
 13254  		{"a_B", "spicedb=permission", false},
 13255  		{"abcdefghijklmnopqrstuvwxyz_0123456789_abcdefghijklmnopqrstuvwxyz", "spicedb=permission", true},
 13256  		{"abcdefghijklmnopqrstuvwxyz_01234_56789_abcdefghijklmnopqrstuvwxyz", "spicedb=permission", false},
 13257  
 13258  		// Object types follow the same rules as permissions for the type name plus an optional prefix up to 63 characters with a /
 13259  		{"a", "spicedb=type", false},
 13260  		{"1", "spicedb=type", false},
 13261  		{"a1", "spicedb=type", false},
 13262  		{"a_b", "spicedb=type", true},
 13263  		{"A_b", "spicedb=type", false},
 13264  		{"a_B", "spicedb=type", false},
 13265  		{"abcdefghijklmnopqrstuvwxyz_0123456789_abcdefghijklmnopqrstuvwxyz", "spicedb=type", true},
 13266  		{"abcdefghijklmnopqrstuvwxyz_01234_56789_abcdefghijklmnopqrstuvwxyz", "spicedb=type", false},
 13267  
 13268  		{`a_b/a`, "spicedb=type", false},
 13269  		{`a_b/1`, "spicedb=type", false},
 13270  		{`a_b/a1`, "spicedb=type", false},
 13271  		{`a_b/a_b`, "spicedb=type", true},
 13272  		{`a_b/A_b`, "spicedb=type", false},
 13273  		{`a_b/a_B`, "spicedb=type", false},
 13274  		{`a_b/abcdefghijklmnopqrstuvwxyz_0123456789_abcdefghijklmnopqrstuvwxyz`, "spicedb=type", true},
 13275  		{`a_b/abcdefghijklmnopqrstuvwxyz_01234_56789_abcdefghijklmnopqrstuvwxyz`, "spicedb=type", false},
 13276  
 13277  		{`a/a_b`, "spicedb=type", false},
 13278  		{`1/a_b`, "spicedb=type", false},
 13279  		{`a1/a_b`, "spicedb=type", false},
 13280  		{`a_b/a_b`, "spicedb=type", true},
 13281  		{`A_b/a_b`, "spicedb=type", false},
 13282  		{`a_B/a_b`, "spicedb=type", false},
 13283  		{`abcdefghijklmnopqrstuvwxyz_0123456789_abcdefghijklmnopqrstuvwxy/a_b`, "spicedb=type", true},
 13284  		{`abcdefghijklmnopqrstuvwxyz_0123456789_abcdefghijklmnopqrstuvwxyz/a_b`, "spicedb=type", false},
 13285  	}
 13286  
 13287  	validate := New()
 13288  
 13289  	for i, test := range tests {
 13290  		errs := validate.Var(test.value, test.tag)
 13291  
 13292  		if test.expected {
 13293  			if !IsEqual(errs, nil) {
 13294  				t.Fatalf("Index: %d spicedb failed Error: %s", i, errs)
 13295  			}
 13296  		} else {
 13297  			if IsEqual(errs, nil) {
 13298  				t.Fatalf("Index: %d spicedb - expected error but there was none.", i)
 13299  			} else {
 13300  				val := getError(errs, "", "")
 13301  				if val.Tag() != "spicedb" {
 13302  					t.Fatalf("Index: %d spicedb failed Error: %s", i, errs)
 13303  				}
 13304  			}
 13305  		}
 13306  	}
 13307  }
 13308  
 13309  func TestCreditCardFormatValidation(t *testing.T) {
 13310  	tests := []struct {
 13311  		value    string `validate:"credit_card"`
 13312  		tag      string
 13313  		expected bool
 13314  	}{
 13315  		{"586824160825533338", "credit_card", true},
 13316  		{"586824160825533328", "credit_card", false},
 13317  		{"4624748233249780", "credit_card", true},
 13318  		{"4624748233349780", "credit_card", false},
 13319  		{"378282246310005", "credit_card", true},
 13320  		{"378282146310005", "credit_card", false},
 13321  		{"4624 7482 3324 9780", "credit_card", true},
 13322  		{"4624 7482 3324  9780", "credit_card", false},
 13323  		{"4624 7482 3324 978A", "credit_card", false},
 13324  		{"4624 7482 332", "credit_card", false},
 13325  	}
 13326  
 13327  	validate := New()
 13328  
 13329  	for i, test := range tests {
 13330  		errs := validate.Var(test.value, test.tag)
 13331  
 13332  		if test.expected {
 13333  			if !IsEqual(errs, nil) {
 13334  				t.Fatalf("Index: %d credit_card failed Error: %s", i, errs)
 13335  			}
 13336  		} else {
 13337  			if IsEqual(errs, nil) {
 13338  				t.Fatalf("Index: %d credit_card failed Error: %s", i, errs)
 13339  			} else {
 13340  				val := getError(errs, "", "")
 13341  				if val.Tag() != "credit_card" {
 13342  					t.Fatalf("Index: %d credit_card failed Error: %s", i, errs)
 13343  				}
 13344  			}
 13345  		}
 13346  	}
 13347  }
 13348  
 13349  func TestLuhnChecksumValidation(t *testing.T) {
 13350  	testsUint := []struct {
 13351  		value    interface{} `validate:"luhn_checksum"` // the type is interface{} because the luhn_checksum works on both strings and numbers
 13352  		tag      string
 13353  		expected bool
 13354  	}{
 13355  		{uint64(586824160825533338), "luhn_checksum", true}, // credit card numbers are just special cases of numbers with luhn checksum
 13356  		{586824160825533338, "luhn_checksum", true},
 13357  		{"586824160825533338", "luhn_checksum", true},
 13358  		{uint64(586824160825533328), "luhn_checksum", false},
 13359  		{586824160825533328, "luhn_checksum", false},
 13360  		{"586824160825533328", "luhn_checksum", false},
 13361  		{10000000116, "luhn_checksum", true}, // but there may be shorter numbers (11 digits)
 13362  		{"10000000116", "luhn_checksum", true},
 13363  		{10000000117, "luhn_checksum", false},
 13364  		{"10000000117", "luhn_checksum", false},
 13365  		{uint64(12345678123456789011), "luhn_checksum", true}, // or longer numbers (19 digits)
 13366  		{"12345678123456789011", "luhn_checksum", true},
 13367  		{1, "luhn_checksum", false}, // single digits (checksum only) are not allowed
 13368  		{"1", "luhn_checksum", false},
 13369  		{-10, "luhn_checksum", false}, // negative ints are not allowed
 13370  		{"abcdefghijklmnop", "luhn_checksum", false},
 13371  	}
 13372  
 13373  	validate := New()
 13374  
 13375  	for i, test := range testsUint {
 13376  		errs := validate.Var(test.value, test.tag)
 13377  		if test.expected {
 13378  			if !IsEqual(errs, nil) {
 13379  				t.Fatalf("Index: %d luhn_checksum failed Error: %s", i, errs)
 13380  			}
 13381  		} else {
 13382  			if IsEqual(errs, nil) {
 13383  				t.Fatalf("Index: %d luhn_checksum failed Error: %s", i, errs)
 13384  			} else {
 13385  				val := getError(errs, "", "")
 13386  				if val.Tag() != "luhn_checksum" {
 13387  					t.Fatalf("Index: %d luhn_checksum failed Error: %s", i, errs)
 13388  				}
 13389  			}
 13390  		}
 13391  	}
 13392  }
 13393  
 13394  func TestMultiOrOperatorGroup(t *testing.T) {
 13395  	tests := []struct {
 13396  		Value    int `validate:"eq=1|gte=5,eq=1|lt=7"`
 13397  		expected bool
 13398  	}{
 13399  		{1, true}, {2, false}, {5, true}, {6, true}, {8, false},
 13400  	}
 13401  
 13402  	validate := New()
 13403  
 13404  	for i, test := range tests {
 13405  		errs := validate.Struct(test)
 13406  		if test.expected {
 13407  			if !IsEqual(errs, nil) {
 13408  				t.Fatalf("Index: %d multi_group_of_OR_operators failed Error: %s", i, errs)
 13409  			}
 13410  		} else {
 13411  			if IsEqual(errs, nil) {
 13412  				t.Fatalf("Index: %d multi_group_of_OR_operators should have errs", i)
 13413  			}
 13414  		}
 13415  	}
 13416  }
 13417  
 13418  func TestCronExpressionValidation(t *testing.T) {
 13419  	tests := []struct {
 13420  		value    string `validate:"cron"`
 13421  		tag      string
 13422  		expected bool
 13423  	}{
 13424  		{"0 0 12 * * ?", "cron", true},
 13425  		{"0 15 10 ? * *", "cron", true},
 13426  		{"0 15 10 * * ?", "cron", true},
 13427  		{"0 15 10 * * ? 2005", "cron", true},
 13428  		{"0 15 10 ? * 6L", "cron", true},
 13429  		{"0 15 10 ? * 6L 2002-2005", "cron", true},
 13430  		{"*/20 * * * *", "cron", true},
 13431  		{"0 15 10 ? * MON-FRI", "cron", true},
 13432  		{"0 15 10 ? * 6#3", "cron", true},
 13433  		{"wrong", "cron", false},
 13434  	}
 13435  
 13436  	validate := New()
 13437  
 13438  	for i, test := range tests {
 13439  		errs := validate.Var(test.value, test.tag)
 13440  		if test.expected {
 13441  			if !IsEqual(errs, nil) {
 13442  				t.Fatalf(`Index: %d cron "%s" failed Error: %s`, i, test.value, errs)
 13443  			}
 13444  		} else {
 13445  			if IsEqual(errs, nil) {
 13446  				t.Fatalf(`Index: %d cron "%s" should have errs`, i, test.value)
 13447  			}
 13448  		}
 13449  	}
 13450  }
 13451  
 13452  func TestNestedStructValidation(t *testing.T) {
 13453  	validator := New(WithRequiredStructEnabled())
 13454  
 13455  	t.Run("required", func(t *testing.T) {
 13456  		type (
 13457  			value struct {
 13458  				Field string
 13459  			}
 13460  			topLevel struct {
 13461  				Nested value `validate:"required"`
 13462  			}
 13463  		)
 13464  
 13465  		var validationErrs ValidationErrors
 13466  		if errs := validator.Struct(topLevel{}); errs != nil {
 13467  			validationErrs = errs.(ValidationErrors)
 13468  		}
 13469  
 13470  		Equal(t, 1, len(validationErrs))
 13471  		AssertError(t, validationErrs, "topLevel.Nested", "topLevel.Nested", "Nested", "Nested", "required")
 13472  
 13473  		Equal(t, validator.Struct(topLevel{value{"potato"}}), nil)
 13474  	})
 13475  
 13476  	t.Run("omitempty", func(t *testing.T) {
 13477  		type (
 13478  			value struct {
 13479  				Field string
 13480  			}
 13481  			topLevel struct {
 13482  				Nested value `validate:"omitempty,required"`
 13483  			}
 13484  		)
 13485  
 13486  		errs := validator.Struct(topLevel{})
 13487  		Equal(t, errs, nil)
 13488  	})
 13489  
 13490  	t.Run("excluded_if", func(t *testing.T) {
 13491  		type (
 13492  			value struct {
 13493  				Field string
 13494  			}
 13495  			topLevel struct {
 13496  				Field  string
 13497  				Nested value `validate:"excluded_if=Field potato"`
 13498  			}
 13499  		)
 13500  
 13501  		errs := validator.Struct(topLevel{Field: "test", Nested: value{"potato"}})
 13502  		Equal(t, errs, nil)
 13503  
 13504  		errs = validator.Struct(topLevel{Field: "potato"})
 13505  		Equal(t, errs, nil)
 13506  
 13507  		errs = validator.Struct(topLevel{Field: "potato", Nested: value{"potato"}})
 13508  		AssertError(t, errs, "topLevel.Nested", "topLevel.Nested", "Nested", "Nested", "excluded_if")
 13509  	})
 13510  
 13511  	t.Run("excluded_unless", func(t *testing.T) {
 13512  		type (
 13513  			value struct {
 13514  				Field string
 13515  			}
 13516  			topLevel struct {
 13517  				Field  string
 13518  				Nested value `validate:"excluded_unless=Field potato"`
 13519  			}
 13520  		)
 13521  
 13522  		errs := validator.Struct(topLevel{Field: "test"})
 13523  		Equal(t, errs, nil)
 13524  
 13525  		errs = validator.Struct(topLevel{Field: "potato", Nested: value{"potato"}})
 13526  		Equal(t, errs, nil)
 13527  
 13528  		errs = validator.Struct(topLevel{Field: "test", Nested: value{"potato"}})
 13529  		AssertError(t, errs, "topLevel.Nested", "topLevel.Nested", "Nested", "Nested", "excluded_unless")
 13530  	})
 13531  
 13532  	t.Run("nonComparableField", func(t *testing.T) {
 13533  		type (
 13534  			value struct {
 13535  				Field []string
 13536  			}
 13537  			topLevel struct {
 13538  				Nested value `validate:"required"`
 13539  			}
 13540  		)
 13541  
 13542  		errs := validator.Struct(topLevel{value{[]string{}}})
 13543  		Equal(t, errs, nil)
 13544  	})
 13545  
 13546  	type (
 13547  		veggyBasket struct {
 13548  			Root   string
 13549  			Squash string `validate:"required"`
 13550  		}
 13551  		testErr struct {
 13552  			path string
 13553  			tag  string
 13554  		}
 13555  		test struct {
 13556  			name  string
 13557  			err   testErr
 13558  			value veggyBasket
 13559  		}
 13560  	)
 13561  
 13562  	if err := validator.RegisterValidation("veggy", func(f FieldLevel) bool {
 13563  		v, ok := f.Field().Interface().(veggyBasket)
 13564  		if !ok || v.Root != "potato" {
 13565  			return false
 13566  		}
 13567  		return true
 13568  	}); err != nil {
 13569  		t.Fatal(fmt.Errorf("failed to register potato tag: %w", err))
 13570  	}
 13571  
 13572  	tests := []test{
 13573  		{
 13574  			name:  "valid",
 13575  			value: veggyBasket{"potato", "zucchini"},
 13576  		}, {
 13577  			name:  "failedCustomTag",
 13578  			value: veggyBasket{"zucchini", "potato"},
 13579  			err:   testErr{"topLevel.VeggyBasket", "veggy"},
 13580  		}, {
 13581  			name:  "failedInnerField",
 13582  			value: veggyBasket{"potato", ""},
 13583  			err:   testErr{"topLevel.VeggyBasket.Squash", "required"},
 13584  		}, {
 13585  			name:  "customTagFailurePriorityCheck",
 13586  			value: veggyBasket{"zucchini", ""},
 13587  			err:   testErr{"topLevel.VeggyBasket", "veggy"},
 13588  		},
 13589  	}
 13590  
 13591  	var evaluateTest = func(tt test, errs error) {
 13592  		if tt.err != (testErr{}) && errs != nil {
 13593  			Equal(t, len(errs.(ValidationErrors)), 1)
 13594  
 13595  			segments := strings.Split(tt.err.path, ".")
 13596  			fieldName := segments[len(segments)-1]
 13597  			AssertError(t, errs, tt.err.path, tt.err.path, fieldName, fieldName, tt.err.tag)
 13598  		}
 13599  
 13600  		shouldFail := tt.err != (testErr{})
 13601  		hasFailed := errs != nil
 13602  		if shouldFail != hasFailed {
 13603  			t.Fatalf("expected failure %v, got: %v with errs: %v", shouldFail, hasFailed, errs)
 13604  		}
 13605  	}
 13606  
 13607  	for _, tt := range tests {
 13608  		type topLevel struct {
 13609  			VeggyBasket veggyBasket `validate:"veggy"`
 13610  		}
 13611  
 13612  		t.Run(tt.name, func(t *testing.T) {
 13613  			evaluateTest(tt, validator.Struct(topLevel{tt.value}))
 13614  		})
 13615  	}
 13616  
 13617  	// Also test on struct pointers
 13618  	for _, tt := range tests {
 13619  		type topLevel struct {
 13620  			VeggyBasket *veggyBasket `validate:"veggy"`
 13621  		}
 13622  
 13623  		t.Run(tt.name+"Ptr", func(t *testing.T) {
 13624  			evaluateTest(tt, validator.Struct(topLevel{&tt.value}))
 13625  		})
 13626  	}
 13627  }
 13628  
 13629  func TestTimeRequired(t *testing.T) {
 13630  	validate := New()
 13631  	validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
 13632  		name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
 13633  
 13634  		if name == "-" {
 13635  			return ""
 13636  		}
 13637  
 13638  		return name
 13639  	})
 13640  
 13641  	type TestTime struct {
 13642  		Time time.Time `validate:"required"`
 13643  	}
 13644  
 13645  	var testTime TestTime
 13646  
 13647  	err := validate.Struct(&testTime)
 13648  	NotEqual(t, err, nil)
 13649  	AssertError(t, err.(ValidationErrors), "TestTime.Time", "TestTime.Time", "Time", "Time", "required")
 13650  }
 13651  
 13652  func TestOmitNilAndRequired(t *testing.T) {
 13653  	type (
 13654  		OmitEmpty struct {
 13655  			Str    string  `validate:"omitempty,required,min=10"`
 13656  			StrPtr *string `validate:"omitempty,required,min=10"`
 13657  			Inner  *OmitEmpty
 13658  		}
 13659  		OmitNil struct {
 13660  			Str    string  `validate:"omitnil,required,min=10"`
 13661  			StrPtr *string `validate:"omitnil,required,min=10"`
 13662  			Inner  *OmitNil
 13663  		}
 13664  	)
 13665  
 13666  	var (
 13667  		validate = New(WithRequiredStructEnabled())
 13668  		valid    = "this is the long string to pass the validation rule"
 13669  	)
 13670  
 13671  	t.Run("compare using valid data", func(t *testing.T) {
 13672  		err1 := validate.Struct(OmitEmpty{Str: valid, StrPtr: &valid, Inner: &OmitEmpty{Str: valid, StrPtr: &valid}})
 13673  		err2 := validate.Struct(OmitNil{Str: valid, StrPtr: &valid, Inner: &OmitNil{Str: valid, StrPtr: &valid}})
 13674  
 13675  		Equal(t, err1, nil)
 13676  		Equal(t, err2, nil)
 13677  	})
 13678  
 13679  	t.Run("compare fully empty omitempty and omitnil", func(t *testing.T) {
 13680  		err1 := validate.Struct(OmitEmpty{})
 13681  		err2 := validate.Struct(OmitNil{})
 13682  
 13683  		Equal(t, err1, nil)
 13684  		AssertError(t, err2, "OmitNil.Str", "OmitNil.Str", "Str", "Str", "required")
 13685  	})
 13686  
 13687  	t.Run("validate in deep", func(t *testing.T) {
 13688  		err1 := validate.Struct(OmitEmpty{Str: valid, Inner: &OmitEmpty{}})
 13689  		err2 := validate.Struct(OmitNil{Str: valid, Inner: &OmitNil{}})
 13690  
 13691  		Equal(t, err1, nil)
 13692  		AssertError(t, err2, "OmitNil.Inner.Str", "OmitNil.Inner.Str", "Str", "Str", "required")
 13693  	})
 13694  }
 13695  

View as plain text