...

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

View as plain text