diff --git a/validator.go b/validator.go index 27d8a63..5312c4e 100644 --- a/validator.go +++ b/validator.go @@ -10,10 +10,12 @@ package validator import ( "bytes" + "errors" "fmt" "reflect" "strings" "time" + "unicode" ) const ( @@ -27,7 +29,7 @@ const ( skipValidationTag = "-" diveTag = "dive" fieldErrMsg = "Key: \"%s\" Error:Field validation for \"%s\" failed on the \"%s\" tag" - invaldField = "Invalid field passed to traverseField" + invalidField = "Invalid field passed to traverseField" arrayIndexFieldName = "%s[%d]" mapIndexFieldName = "%s[%v]" ) @@ -103,6 +105,24 @@ func New(config Config) *Validate { return &Validate{config: config} } +// RegisterValidation adds a validation Func to a Validate's map of validators denoted by the key +// NOTE: if the key already exists, it will get replaced. +// NOTE: this method is not thread-safe +func (v *Validate) RegisterValidation(key string, f Func) error { + + if len(key) == 0 { + return errors.New("Function Key cannot be empty") + } + + if f == nil { + return errors.New("Function cannot be empty") + } + + v.config.ValidationFuncs[key] = f + + return nil +} + // Field allows validation of a single field, still using tag style validation to check multiple errors func (v *Validate) Field(field interface{}, tag string) ValidationErrors { @@ -173,6 +193,11 @@ func (v *Validate) tranverseStruct(topStruct reflect.Value, currentStruct reflec for i := 0; i < numFields; i++ { fld = typ.Field(i) + + if !unicode.IsUpper(rune(fld.Name[0])) { + continue + } + v.traverseField(topStruct, currentStruct, current.Field(i), errPrefix, errs, true, fld.Tag.Get(v.config.TagName), fld.Name) } } @@ -228,7 +253,7 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect. switch kind { case reflect.Invalid: - panic(invaldField) + panic(invalidField) case reflect.Struct, reflect.Interface: if kind == reflect.Interface { @@ -251,7 +276,7 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect. if typ != timeType && typ != timePtrType { - if isStructField { + if isStructField || kind == reflect.Struct { // required passed validationa above so stop here // if only validating the structs existance. @@ -262,8 +287,7 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect. v.tranverseStruct(topStruct, current, current, errPrefix+name+".", errs, false) return } - - panic(invaldField) + panic(invalidField) } FALLTHROUGH: fallthrough @@ -345,7 +369,7 @@ func (v *Validate) traverseSlice(topStruct reflect.Value, currentStruct reflect. idxField = idxField.Elem() } - v.traverseField(topStruct, currentStruct, current, errPrefix, errs, false, tag, fmt.Sprintf(arrayIndexFieldName, name, i)) + v.traverseField(topStruct, currentStruct, idxField, errPrefix, errs, false, tag, fmt.Sprintf(arrayIndexFieldName, name, i)) } } @@ -359,7 +383,7 @@ func (v *Validate) traverseMap(topStruct reflect.Value, currentStruct reflect.Va idxField = idxField.Elem() } - v.traverseField(topStruct, currentStruct, current, errPrefix, errs, false, tag, fmt.Sprintf(mapIndexFieldName, name, key.Interface())) + v.traverseField(topStruct, currentStruct, idxField, errPrefix, errs, false, tag, fmt.Sprintf(mapIndexFieldName, name, key.Interface())) } } diff --git a/validator_test.go b/validator_test.go index ea4656e..5103f38 100644 --- a/validator_test.go +++ b/validator_test.go @@ -6,6 +6,7 @@ import ( "reflect" "runtime" "testing" + "time" ) // NOTES: @@ -228,2775 +229,2399 @@ func AssertError(t *testing.T, errs ValidationErrors, key, field, expectedTag st EqualSkip(t, 2, val.Tag, expectedTag) } -func TestValidation(t *testing.T) { +func TestBadKeyValidation(t *testing.T) { + type Test struct { + Name string `validate:"required, "` + } + + tst := &Test{ + Name: "test", + } + + PanicMatches(t, func() { validate.Struct(tst) }, "Undefined validation function on field Name") +} + +func TestInterfaceErrValidation(t *testing.T) { + + var v1 interface{} + var v2 interface{} + + v2 = 1 + v1 = v2 + + errs := validate.Field(v1, "len=1") + Equal(t, errs, nil) + + errs = validate.Field(v2, "len=1") + Equal(t, errs, nil) + + type ExternalCMD struct { + Userid string `json:"userid"` + Action uint32 `json:"action"` + Data interface{} `json:"data,omitempty" validate:"required"` + } + + s := &ExternalCMD{ + Userid: "123456", + Action: 10000, + // Data: 1, + } + + errs = validate.Struct(s) + NotEqual(t, errs, nil) + Equal(t, len(errs), 1) + AssertError(t, errs, "ExternalCMD.Data", "Data", "required") + + type ExternalCMD2 struct { + Userid string `json:"userid"` + Action uint32 `json:"action"` + Data interface{} `json:"data,omitempty" validate:"len=1"` + } + + s2 := &ExternalCMD2{ + Userid: "123456", + Action: 10000, + // Data: 1, + } + + errs = validate.Struct(s2) + NotEqual(t, errs, nil) + Equal(t, len(errs), 1) + AssertError(t, errs, "ExternalCMD2.Data", "Data", "len") + + s3 := &ExternalCMD2{ + Userid: "123456", + Action: 10000, + Data: 2, + } + + errs = validate.Struct(s3) + NotEqual(t, errs, nil) + Equal(t, len(errs), 1) + AssertError(t, errs, "ExternalCMD2.Data", "Data", "len") + + type Inner struct { + Name string `validate:"required"` + } + + inner := &Inner{ + Name: "", + } + + s4 := &ExternalCMD{ + Userid: "123456", + Action: 10000, + Data: inner, + } + + errs = validate.Struct(s4) + NotEqual(t, errs, nil) + Equal(t, len(errs), 1) + AssertError(t, errs, "ExternalCMD.Data.Name", "Name", "required") + + type TestMapStructPtr struct { + Errs map[int]interface{} `validate:"gt=0,dive,len=2"` + } + + mip := map[int]interface{}{0: &Inner{"ok"}, 3: nil, 4: &Inner{"ok"}} + + msp := &TestMapStructPtr{ + Errs: mip, + } + + errs = validate.Struct(msp) + NotEqual(t, errs, nil) + Equal(t, len(errs), 1) + AssertError(t, errs, "TestMapStructPtr.Errs[3]", "Errs[3]", "len") + + type TestMultiDimensionalStructs struct { + Errs [][]interface{} `validate:"gt=0,dive,dive"` + } + + var errStructArray [][]interface{} + + errStructArray = append(errStructArray, []interface{}{&Inner{"ok"}, &Inner{""}, &Inner{""}}) + errStructArray = append(errStructArray, []interface{}{&Inner{"ok"}, &Inner{""}, &Inner{""}}) + + tms := &TestMultiDimensionalStructs{ + Errs: errStructArray, + } + + errs = validate.Struct(tms) + NotEqual(t, errs, nil) + Equal(t, len(errs), 4) + AssertError(t, errs, "TestMultiDimensionalStructs.Errs[0][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructs.Errs[0][2].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructs.Errs[1][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructs.Errs[1][2].Name", "Name", "required") + + type TestMultiDimensionalStructsPtr2 struct { + Errs [][]*Inner `validate:"gt=0,dive,dive,required"` + } + + var errStructPtr2Array [][]*Inner + + errStructPtr2Array = append(errStructPtr2Array, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}}) + errStructPtr2Array = append(errStructPtr2Array, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}}) + errStructPtr2Array = append(errStructPtr2Array, []*Inner{&Inner{"ok"}, &Inner{""}, nil}) + + tmsp2 := &TestMultiDimensionalStructsPtr2{ + Errs: errStructPtr2Array, + } + + errs = validate.Struct(tmsp2) + NotEqual(t, errs, nil) + Equal(t, len(errs), 6) + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[0][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[0][2].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[1][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[1][2].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[2][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[2][2]", "Errs[2][2]", "required") + + m := map[int]interface{}{0: "ok", 3: "", 4: "ok"} + + errs = validate.Field(m, "len=3,dive,len=2") + NotEqual(t, errs, nil) + Equal(t, len(errs), 1) + AssertError(t, errs, "[3]", "[3]", "len") + + errs = validate.Field(m, "len=2,dive,required") + NotEqual(t, errs, nil) + Equal(t, len(errs), 1) + AssertError(t, errs, "", "", "len") + + arr := []interface{}{"ok", "", "ok"} + + errs = validate.Field(arr, "len=3,dive,len=2") + NotEqual(t, errs, nil) + Equal(t, len(errs), 1) + AssertError(t, errs, "[1]", "[1]", "len") + + errs = validate.Field(arr, "len=2,dive,required") + NotEqual(t, errs, nil) + Equal(t, len(errs), 1) + AssertError(t, errs, "", "", "len") + + type MyStruct struct { + A, B string + C interface{} + } + + var a MyStruct + + a.A = "value" + a.C = "nu" + + errs = validate.Struct(a) + Equal(t, errs, nil) +} + +func TestMapDiveValidation(t *testing.T) { + + n := map[int]interface{}{0: nil} + errs := validate.Field(n, "omitempty,required") + Equal(t, errs, nil) + + m := map[int]string{0: "ok", 3: "", 4: "ok"} + + errs = validate.Field(m, "len=3,dive,required") + NotEqual(t, errs, nil) + Equal(t, len(errs), 1) + AssertError(t, errs, "[3]", "[3]", "required") + + errs = validate.Field(m, "len=2,dive,required") + NotEqual(t, errs, nil) + Equal(t, len(errs), 1) + AssertError(t, errs, "", "", "len") + + type Inner struct { + Name string `validate:"required"` + } + + type TestMapStruct struct { + Errs map[int]Inner `validate:"gt=0,dive"` + } + + mi := map[int]Inner{0: Inner{"ok"}, 3: Inner{""}, 4: Inner{"ok"}} + + ms := &TestMapStruct{ + Errs: mi, + } + + errs = validate.Struct(ms) + NotEqual(t, errs, nil) + Equal(t, len(errs), 1) + AssertError(t, errs, "TestMapStruct.Errs[3].Name", "Name", "required") + + // for full test coverage + fmt.Sprint(errs.Error()) + + type TestMapTimeStruct struct { + Errs map[int]*time.Time `validate:"gt=0,dive,required"` + } + + t1 := time.Now().UTC() + + mta := map[int]*time.Time{0: &t1, 3: nil, 4: nil} + + mt := &TestMapTimeStruct{ + Errs: mta, + } + + errs = validate.Struct(mt) + NotEqual(t, errs, nil) + Equal(t, len(errs), 2) + AssertError(t, errs, "TestMapTimeStruct.Errs[3]", "Errs[3]", "required") + AssertError(t, errs, "TestMapTimeStruct.Errs[4]", "Errs[4]", "required") + + type TestMapStructPtr struct { + Errs map[int]*Inner `validate:"gt=0,dive,required"` + } + + mip := map[int]*Inner{0: &Inner{"ok"}, 3: nil, 4: &Inner{"ok"}} + + msp := &TestMapStructPtr{ + Errs: mip, + } + + errs = validate.Struct(msp) + NotEqual(t, errs, nil) + Equal(t, len(errs), 1) + AssertError(t, errs, "TestMapStructPtr.Errs[3]", "Errs[3]", "required") + + type TestMapStructPtr2 struct { + Errs map[int]*Inner `validate:"gt=0,dive,omitempty,required"` + } + + mip2 := map[int]*Inner{0: &Inner{"ok"}, 3: nil, 4: &Inner{"ok"}} + + msp2 := &TestMapStructPtr2{ + Errs: mip2, + } + + errs = validate.Struct(msp2) + Equal(t, errs, nil) +} + +func TestArrayDiveValidation(t *testing.T) { + + arr := []string{"ok", "", "ok"} + + errs := validate.Field(arr, "len=3,dive,required") + NotEqual(t, errs, nil) + Equal(t, len(errs), 1) + AssertError(t, errs, "[1]", "[1]", "required") + + errs = validate.Field(arr, "len=2,dive,required") + NotEqual(t, errs, nil) + Equal(t, len(errs), 1) + AssertError(t, errs, "", "", "len") + + type BadDive struct { + Name string `validate:"dive"` + } + + bd := &BadDive{ + Name: "TEST", + } + + PanicMatches(t, func() { validate.Struct(bd) }, "dive error! can't dive on a non slice or map") + + type Test struct { + Errs []string `validate:"gt=0,dive,required"` + } + + test := &Test{ + Errs: []string{"ok", "", "ok"}, + } + + errs = validate.Struct(test) + NotEqual(t, errs, nil) + Equal(t, len(errs), 1) + AssertError(t, errs, "Test.Errs[1]", "Errs[1]", "required") + + test = &Test{ + Errs: []string{"ok", "ok", ""}, + } + + errs = validate.Struct(test) + NotEqual(t, errs, nil) + Equal(t, len(errs), 1) + AssertError(t, errs, "Test.Errs[2]", "Errs[2]", "required") + + type TestMultiDimensional struct { + Errs [][]string `validate:"gt=0,dive,dive,required"` + } + + var errArray [][]string + + errArray = append(errArray, []string{"ok", "", ""}) + errArray = append(errArray, []string{"ok", "", ""}) + + tm := &TestMultiDimensional{ + Errs: errArray, + } + + errs = validate.Struct(tm) + NotEqual(t, errs, nil) + Equal(t, len(errs), 4) + AssertError(t, errs, "TestMultiDimensional.Errs[0][1]", "Errs[0][1]", "required") + AssertError(t, errs, "TestMultiDimensional.Errs[0][2]", "Errs[0][2]", "required") + AssertError(t, errs, "TestMultiDimensional.Errs[1][1]", "Errs[1][1]", "required") + AssertError(t, errs, "TestMultiDimensional.Errs[1][2]", "Errs[1][2]", "required") + + type Inner struct { + Name string `validate:"required"` + } + + type TestMultiDimensionalStructs struct { + Errs [][]Inner `validate:"gt=0,dive,dive"` + } + + var errStructArray [][]Inner + + errStructArray = append(errStructArray, []Inner{Inner{"ok"}, Inner{""}, Inner{""}}) + errStructArray = append(errStructArray, []Inner{Inner{"ok"}, Inner{""}, Inner{""}}) + + tms := &TestMultiDimensionalStructs{ + Errs: errStructArray, + } + + errs = validate.Struct(tms) + NotEqual(t, errs, nil) + Equal(t, len(errs), 4) + AssertError(t, errs, "TestMultiDimensionalStructs.Errs[0][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructs.Errs[0][2].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructs.Errs[1][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructs.Errs[1][2].Name", "Name", "required") + + type TestMultiDimensionalStructsPtr struct { + Errs [][]*Inner `validate:"gt=0,dive,dive"` + } + + var errStructPtrArray [][]*Inner + + errStructPtrArray = append(errStructPtrArray, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}}) + errStructPtrArray = append(errStructPtrArray, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}}) + errStructPtrArray = append(errStructPtrArray, []*Inner{&Inner{"ok"}, &Inner{""}, nil}) + + tmsp := &TestMultiDimensionalStructsPtr{ + Errs: errStructPtrArray, + } + + errs = validate.Struct(tmsp) + NotEqual(t, errs, nil) + Equal(t, len(errs), 6) + AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[0][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[0][2].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[1][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[1][2].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[2][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[2][2]", "Errs[2][2]", "") + // for full test coverage + fmt.Sprint(errs.Error()) + + type TestMultiDimensionalStructsPtr2 struct { + Errs [][]*Inner `validate:"gt=0,dive,dive,required"` + } + + var errStructPtr2Array [][]*Inner + + errStructPtr2Array = append(errStructPtr2Array, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}}) + errStructPtr2Array = append(errStructPtr2Array, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}}) + errStructPtr2Array = append(errStructPtr2Array, []*Inner{&Inner{"ok"}, &Inner{""}, nil}) + + tmsp2 := &TestMultiDimensionalStructsPtr2{ + Errs: errStructPtr2Array, + } + + errs = validate.Struct(tmsp2) + NotEqual(t, errs, nil) + Equal(t, len(errs), 6) + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[0][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[0][2].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[1][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[1][2].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[2][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[2][2]", "Errs[2][2]", "required") + + type TestMultiDimensionalStructsPtr3 struct { + Errs [][]*Inner `validate:"gt=0,dive,dive,omitempty"` + } + + var errStructPtr3Array [][]*Inner + + errStructPtr3Array = append(errStructPtr3Array, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}}) + errStructPtr3Array = append(errStructPtr3Array, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}}) + errStructPtr3Array = append(errStructPtr3Array, []*Inner{&Inner{"ok"}, &Inner{""}, nil}) + + tmsp3 := &TestMultiDimensionalStructsPtr3{ + Errs: errStructPtr3Array, + } + + errs = validate.Struct(tmsp3) + NotEqual(t, errs, nil) + Equal(t, len(errs), 5) + AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[0][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[0][2].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[1][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[1][2].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[2][1].Name", "Name", "required") + + type TestMultiDimensionalTimeTime struct { + Errs [][]*time.Time `validate:"gt=0,dive,dive,required"` + } + + var errTimePtr3Array [][]*time.Time + + t1 := time.Now().UTC() + t2 := time.Now().UTC() + t3 := time.Now().UTC().Add(time.Hour * 24) + + errTimePtr3Array = append(errTimePtr3Array, []*time.Time{&t1, &t2, &t3}) + errTimePtr3Array = append(errTimePtr3Array, []*time.Time{&t1, &t2, nil}) + errTimePtr3Array = append(errTimePtr3Array, []*time.Time{&t1, nil, nil}) + + tmtp3 := &TestMultiDimensionalTimeTime{ + Errs: errTimePtr3Array, + } + + errs = validate.Struct(tmtp3) + NotEqual(t, errs, nil) + Equal(t, len(errs), 3) + AssertError(t, errs, "TestMultiDimensionalTimeTime.Errs[1][2]", "Errs[1][2]", "required") + AssertError(t, errs, "TestMultiDimensionalTimeTime.Errs[2][1]", "Errs[2][1]", "required") + AssertError(t, errs, "TestMultiDimensionalTimeTime.Errs[2][2]", "Errs[2][2]", "required") + + type TestMultiDimensionalTimeTime2 struct { + Errs [][]*time.Time `validate:"gt=0,dive,dive,required"` + } + + var errTimeArray [][]*time.Time + + t1 = time.Now().UTC() + t2 = time.Now().UTC() + t3 = time.Now().UTC().Add(time.Hour * 24) + + errTimeArray = append(errTimeArray, []*time.Time{&t1, &t2, &t3}) + errTimeArray = append(errTimeArray, []*time.Time{&t1, &t2, nil}) + errTimeArray = append(errTimeArray, []*time.Time{&t1, nil, nil}) + + tmtp := &TestMultiDimensionalTimeTime2{ + Errs: errTimeArray, + } + + errs = validate.Struct(tmtp) + NotEqual(t, errs, nil) + Equal(t, len(errs), 3) + AssertError(t, errs, "TestMultiDimensionalTimeTime2.Errs[1][2]", "Errs[1][2]", "required") + AssertError(t, errs, "TestMultiDimensionalTimeTime2.Errs[2][1]", "Errs[2][1]", "required") + AssertError(t, errs, "TestMultiDimensionalTimeTime2.Errs[2][2]", "Errs[2][2]", "required") +} + +func TestNilStructPointerValidation(t *testing.T) { + type Inner struct { + Data string + } + + type Outer struct { + Inner *Inner `validate:"omitempty"` + } + + inner := &Inner{ + Data: "test", + } + + outer := &Outer{ + Inner: inner, + } + + errs := validate.Struct(outer) + Equal(t, errs, nil) + + outer = &Outer{ + Inner: nil, + } + + errs = validate.Struct(outer) + Equal(t, errs, nil) + + type Inner2 struct { + Data string + } + + type Outer2 struct { + Inner2 *Inner2 `validate:"required"` + } + + inner2 := &Inner2{ + Data: "test", + } + + outer2 := &Outer2{ + Inner2: inner2, + } + + errs = validate.Struct(outer2) + Equal(t, errs, nil) + + outer2 = &Outer2{ + Inner2: nil, + } + + errs = validate.Struct(outer2) + NotEqual(t, errs, nil) + AssertError(t, errs, "Outer2.Inner2", "Inner2", "required") + + type Inner3 struct { + Data string + } + + type Outer3 struct { + Inner3 *Inner3 + } + + inner3 := &Inner3{ + Data: "test", + } + + outer3 := &Outer3{ + Inner3: inner3, + } + + errs = validate.Struct(outer3) + Equal(t, errs, nil) + + type Inner4 struct { + Data string + } + + type Outer4 struct { + Inner4 *Inner4 `validate:"-"` + } + + inner4 := &Inner4{ + Data: "test", + } + + outer4 := &Outer4{ + Inner4: inner4, + } + + errs = validate.Struct(outer4) + Equal(t, errs, nil) +} + +func TestSSNValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"00-90-8787", false}, + {"66690-76", false}, + {"191 60 2869", true}, + {"191-60-2869", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "ssn") + + if test.expected == true { + if !IsEqual(t, errs, nil) { + t.Fatalf("Index: %d SSN failed Error: %s", i, errs) + } + } else { + if IsEqual(t, errs, nil) { + t.Fatalf("Index: %d SSN failed Error: %s", i, errs) + } else { + val := errs[""] + if val.Tag != "ssn" { + t.Fatalf("Index: %d Latitude failed Error: %s", i, errs) + } + } + } + } +} + +func TestLongitudeValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"-180.000", true}, + {"180.1", false}, + {"+73.234", true}, + {"+382.3811", false}, + {"23.11111111", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "longitude") + + if test.expected == true { + if !IsEqual(t, errs, nil) { + t.Fatalf("Index: %d Longitude failed Error: %s", i, errs) + } + } else { + if IsEqual(t, errs, nil) { + t.Fatalf("Index: %d Longitude failed Error: %s", i, errs) + } else { + val := errs[""] + if val.Tag != "longitude" { + t.Fatalf("Index: %d Latitude failed Error: %s", i, errs) + } + } + } + } +} + +func TestLatitudeValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"-90.000", true}, + {"+90", true}, + {"47.1231231", true}, + {"+99.9", false}, + {"108", false}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "latitude") + + if test.expected == true { + if !IsEqual(t, errs, nil) { + t.Fatalf("Index: %d Latitude failed Error: %s", i, errs) + } + } else { + if IsEqual(t, errs, nil) { + t.Fatalf("Index: %d Latitude failed Error: %s", i, errs) + } else { + val := errs[""] + if val.Tag != "latitude" { + t.Fatalf("Index: %d Latitude failed Error: %s", i, errs) + } + } + } + } +} + +func TestDataURIValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"data:image/png;base64,TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4=", true}, + {"data:text/plain;base64,Vml2YW11cyBmZXJtZW50dW0gc2VtcGVyIHBvcnRhLg==", true}, + {"image/gif;base64,U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", false}, + {"data:image/gif;base64,MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuMPNS1Ufof9EW/M98FNw" + + "UAKrwflsqVxaxQjBQnHQmiI7Vac40t8x7pIb8gLGV6wL7sBTJiPovJ0V7y7oc0Ye" + + "rhKh0Rm4skP2z/jHwwZICgGzBvA0rH8xlhUiTvcwDCJ0kc+fh35hNt8srZQM4619" + + "FTgB66Xmp4EtVyhpQV+t02g6NzK72oZI0vnAvqhpkxLeLiMCyrI416wHm5Tkukhx" + + "QmcL2a6hNOyu0ixX/x2kSFXApEnVrJ+/IxGyfyw8kf4N2IZpW5nEP847lpfj0SZZ" + + "Fwrd1mnfnDbYohX2zRptLy2ZUn06Qo9pkG5ntvFEPo9bfZeULtjYzIl6K8gJ2uGZ" + "HQIDAQAB", true}, + {"data:image/png;base64,12345", false}, + {"", false}, + {"data:text,:;base85,U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", false}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "datauri") + + if test.expected == true { + if !IsEqual(t, errs, nil) { + t.Fatalf("Index: %d DataURI failed Error: %s", i, errs) + } + } else { + if IsEqual(t, errs, nil) { + t.Fatalf("Index: %d DataURI failed Error: %s", i, errs) + } else { + val := errs[""] + if val.Tag != "datauri" { + t.Fatalf("Index: %d DataURI failed Error: %s", i, errs) + } + } + } + } +} + +func TestMultibyteValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", true}, + {"abc", false}, + {"123", false}, + {"<>@;.-=", false}, + {"ひらがな・カタカナ、.漢字", true}, + {"あいうえお foobar", true}, + {"test@example.com", true}, + {"test@example.com", true}, + {"1234abcDExyz", true}, + {"カタカナ", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "multibyte") + + if test.expected == true { + if !IsEqual(t, errs, nil) { + t.Fatalf("Index: %d Multibyte failed Error: %s", i, errs) + } + } else { + if IsEqual(t, errs, nil) { + t.Fatalf("Index: %d Multibyte failed Error: %s", i, errs) + } else { + val := errs[""] + if val.Tag != "multibyte" { + t.Fatalf("Index: %d Multibyte failed Error: %s", i, errs) + } + } + } + } +} + +func TestPrintableASCIIValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", true}, + {"foobar", false}, + {"xyz098", false}, + {"123456", false}, + {"カタカナ", false}, + {"foobar", true}, + {"0987654321", true}, + {"test@example.com", true}, + {"1234abcDEF", true}, + {"newline\n", false}, + {"\x19test\x7F", false}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "printascii") + + if test.expected == true { + if !IsEqual(t, errs, nil) { + t.Fatalf("Index: %d Printable ASCII failed Error: %s", i, errs) + } + } else { + if IsEqual(t, errs, nil) { + t.Fatalf("Index: %d Printable ASCII failed Error: %s", i, errs) + } else { + val := errs[""] + if val.Tag != "printascii" { + t.Fatalf("Index: %d Printable ASCII failed Error: %s", i, errs) + } + } + } + } +} + +func TestASCIIValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", true}, + {"foobar", false}, + {"xyz098", false}, + {"123456", false}, + {"カタカナ", false}, + {"foobar", true}, + {"0987654321", true}, + {"test@example.com", true}, + {"1234abcDEF", true}, + {"", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "ascii") + + if test.expected == true { + if !IsEqual(t, errs, nil) { + t.Fatalf("Index: %d ASCII failed Error: %s", i, errs) + } + } else { + if IsEqual(t, errs, nil) { + t.Fatalf("Index: %d ASCII failed Error: %s", i, errs) + } else { + val := errs[""] + if val.Tag != "ascii" { + t.Fatalf("Index: %d ASCII failed Error: %s", i, errs) + } + } + } + } +} + +func TestUUID5Validation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + + {"", false}, + {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, + {"9c858901-8a57-4791-81fe-4c455b099bc9", false}, + {"a987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, + {"987fbc97-4bed-5078-af07-9141ba07c9f3", true}, + {"987fbc97-4bed-5078-9f07-9141ba07c9f3", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "uuid5") + + if test.expected == true { + if !IsEqual(t, errs, nil) { + t.Fatalf("Index: %d UUID5 failed Error: %s", i, errs) + } + } else { + if IsEqual(t, errs, nil) { + t.Fatalf("Index: %d UUID5 failed Error: %s", i, errs) + } else { + val := errs[""] + if val.Tag != "uuid5" { + t.Fatalf("Index: %d UUID5 failed Error: %s", i, errs) + } + } + } + } +} + +func TestUUID4Validation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, + {"a987fbc9-4bed-5078-af07-9141ba07c9f3", false}, + {"934859", false}, + {"57b73598-8764-4ad0-a76a-679bb6640eb1", true}, + {"625e63f3-58f5-40b7-83a1-a72ad31acffb", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "uuid4") + + if test.expected == true { + if !IsEqual(t, errs, nil) { + t.Fatalf("Index: %d UUID4 failed Error: %s", i, errs) + } + } else { + if IsEqual(t, errs, nil) { + t.Fatalf("Index: %d UUID4 failed Error: %s", i, errs) + } else { + val := errs[""] + if val.Tag != "uuid4" { + t.Fatalf("Index: %d UUID4 failed Error: %s", i, errs) + } + } + } + } +} + +func TestUUID3Validation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"412452646", false}, + {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, + {"a987fbc9-4bed-4078-8f07-9141ba07c9f3", false}, + {"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "uuid3") + + if test.expected == true { + if !IsEqual(t, errs, nil) { + t.Fatalf("Index: %d UUID3 failed Error: %s", i, errs) + } + } else { + if IsEqual(t, errs, nil) { + t.Fatalf("Index: %d UUID3 failed Error: %s", i, errs) + } else { + val := errs[""] + if val.Tag != "uuid3" { + t.Fatalf("Index: %d UUID3 failed Error: %s", i, errs) + } + } + } + } +} + +func TestUUIDValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, + {"a987fbc9-4bed-3078-cf07-9141ba07c9f3xxx", false}, + {"a987fbc94bed3078cf079141ba07c9f3", false}, + {"934859", false}, + {"987fbc9-4bed-3078-cf07a-9141ba07c9f3", false}, + {"aaaaaaaa-1111-1111-aaag-111111111111", false}, + {"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "uuid") + + if test.expected == true { + if !IsEqual(t, errs, nil) { + t.Fatalf("Index: %d UUID failed Error: %s", i, errs) + } + } else { + if IsEqual(t, errs, nil) { + t.Fatalf("Index: %d UUID failed Error: %s", i, errs) + } else { + val := errs[""] + if val.Tag != "uuid" { + t.Fatalf("Index: %d UUID failed Error: %s", i, errs) + } + } + } + } +} + +func TestISBNValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"foo", false}, + {"3836221195", true}, + {"1-61729-085-8", true}, + {"3 423 21412 0", true}, + {"3 401 01319 X", true}, + {"9784873113685", true}, + {"978-4-87311-368-5", true}, + {"978 3401013190", true}, + {"978-3-8362-2119-1", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "isbn") + + if test.expected == true { + if !IsEqual(t, errs, nil) { + t.Fatalf("Index: %d ISBN failed Error: %s", i, errs) + } + } else { + if IsEqual(t, errs, nil) { + t.Fatalf("Index: %d ISBN failed Error: %s", i, errs) + } else { + val := errs[""] + if val.Tag != "isbn" { + t.Fatalf("Index: %d ISBN failed Error: %s", i, errs) + } + } + } + } +} + +func TestISBN13Validation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"foo", false}, + {"3-8362-2119-5", false}, + {"01234567890ab", false}, + {"978 3 8362 2119 0", false}, + {"9784873113685", true}, + {"978-4-87311-368-5", true}, + {"978 3401013190", true}, + {"978-3-8362-2119-1", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "isbn13") + + if test.expected == true { + if !IsEqual(t, errs, nil) { + t.Fatalf("Index: %d ISBN13 failed Error: %s", i, errs) + } + } else { + if IsEqual(t, errs, nil) { + t.Fatalf("Index: %d ISBN13 failed Error: %s", i, errs) + } else { + val := errs[""] + if val.Tag != "isbn13" { + t.Fatalf("Index: %d ISBN13 failed Error: %s", i, errs) + } + } + } + } +} + +func TestISBN10Validation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"foo", false}, + {"3423214121", false}, + {"978-3836221191", false}, + {"3-423-21412-1", false}, + {"3 423 21412 1", false}, + {"3836221195", true}, + {"1-61729-085-8", true}, + {"3 423 21412 0", true}, + {"3 401 01319 X", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "isbn10") + + if test.expected == true { + if !IsEqual(t, errs, nil) { + t.Fatalf("Index: %d ISBN10 failed Error: %s", i, errs) + } + } else { + if IsEqual(t, errs, nil) { + t.Fatalf("Index: %d ISBN10 failed Error: %s", i, errs) + } else { + val := errs[""] + if val.Tag != "isbn10" { + t.Fatalf("Index: %d ISBN10 failed Error: %s", i, errs) + } + } + } + } +} + +func TestExcludesRuneValidation(t *testing.T) { + + tests := []struct { + Value string `validate:"excludesrune=☻"` + Tag string + ExpectedNil bool + }{ + {Value: "a☺b☻c☹d", Tag: "excludesrune=☻", ExpectedNil: false}, + {Value: "abcd", Tag: "excludesrune=☻", ExpectedNil: true}, + } + + for i, s := range tests { + errs := validate.Field(s.Value, s.Tag) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + + errs = validate.Struct(s) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + } +} + +func TestExcludesAllValidation(t *testing.T) { + + tests := []struct { + Value string `validate:"excludesall=@!{}[]"` + Tag string + ExpectedNil bool + }{ + {Value: "abcd@!jfk", Tag: "excludesall=@!{}[]", ExpectedNil: false}, + {Value: "abcdefg", Tag: "excludesall=@!{}[]", ExpectedNil: true}, + } + + for i, s := range tests { + errs := validate.Field(s.Value, s.Tag) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + + errs = validate.Struct(s) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + } + + username := "joeybloggs " + + errs := validate.Field(username, "excludesall=@ ") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "excludesall") + + excluded := "," + + errs = validate.Field(excluded, "excludesall=!@#$%^&*()_+.0x2C?") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "excludesall") + + excluded = "=" + + errs = validate.Field(excluded, "excludesall=!@#$%^&*()_+.0x2C=?") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "excludesall") +} + +func TestExcludesValidation(t *testing.T) { + + tests := []struct { + Value string `validate:"excludes=@"` + Tag string + ExpectedNil bool + }{ + {Value: "abcd@!jfk", Tag: "excludes=@", ExpectedNil: false}, + {Value: "abcdq!jfk", Tag: "excludes=@", ExpectedNil: true}, + } + + for i, s := range tests { + errs := validate.Field(s.Value, s.Tag) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + + errs = validate.Struct(s) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + } +} + +func TestContainsRuneValidation(t *testing.T) { + + tests := []struct { + Value string `validate:"containsrune=☻"` + Tag string + ExpectedNil bool + }{ + {Value: "a☺b☻c☹d", Tag: "containsrune=☻", ExpectedNil: true}, + {Value: "abcd", Tag: "containsrune=☻", ExpectedNil: false}, + } + + for i, s := range tests { + errs := validate.Field(s.Value, s.Tag) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + + errs = validate.Struct(s) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + } +} + +func TestContainsAnyValidation(t *testing.T) { + + tests := []struct { + Value string `validate:"containsany=@!{}[]"` + Tag string + ExpectedNil bool + }{ + {Value: "abcd@!jfk", Tag: "containsany=@!{}[]", ExpectedNil: true}, + {Value: "abcdefg", Tag: "containsany=@!{}[]", ExpectedNil: false}, + } + + for i, s := range tests { + errs := validate.Field(s.Value, s.Tag) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + + errs = validate.Struct(s) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + } +} + +func TestContainsValidation(t *testing.T) { + + tests := []struct { + Value string `validate:"contains=@"` + Tag string + ExpectedNil bool + }{ + {Value: "abcd@!jfk", Tag: "contains=@", ExpectedNil: true}, + {Value: "abcdq!jfk", Tag: "contains=@", ExpectedNil: false}, + } + + for i, s := range tests { + errs := validate.Field(s.Value, s.Tag) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + + errs = validate.Struct(s) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + } +} + +func TestIsNeFieldValidation(t *testing.T) { + + var j uint64 + var k float64 + s := "abcd" + i := 1 + j = 1 + k = 1.543 + arr := []string{"test"} + now := time.Now().UTC() + + var j2 uint64 + var k2 float64 + s2 := "abcdef" + i2 := 3 + j2 = 2 + k2 = 1.5434456 + arr2 := []string{"test", "test2"} + arr3 := []string{"test"} + now2 := now + + errs := validate.FieldWithValue(s, s2, "nefield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(i2, i, "nefield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(j2, j, "nefield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(k2, k, "nefield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(arr2, arr, "nefield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(now2, now, "nefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "nefield") + + errs = validate.FieldWithValue(arr3, arr, "nefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "nefield") + + type Test struct { + Start *time.Time `validate:"nefield=End"` + End *time.Time + } + + sv := &Test{ + Start: &now, + End: &now, + } + + errs = validate.Struct(sv) + NotEqual(t, errs, nil) + AssertError(t, errs, "Test.Start", "Start", "nefield") + + now3 := time.Now().UTC() + + sv = &Test{ + Start: &now, + End: &now3, + } + + errs = validate.Struct(sv) + Equal(t, errs, nil) + + channel := make(chan string) + + PanicMatches(t, func() { validate.FieldWithValue(nil, 1, "nefield") }, "struct or field value not passed for cross validation") + PanicMatches(t, func() { validate.FieldWithValue(5, channel, "nefield") }, "Bad field type chan string") + PanicMatches(t, func() { validate.FieldWithValue(5, now, "nefield") }, "Bad Top Level field type") + + type Test2 struct { + Start *time.Time `validate:"nefield=NonExistantField"` + End *time.Time + } + + sv2 := &Test2{ + Start: &now, + End: &now, + } + + PanicMatches(t, func() { validate.Struct(sv2) }, "Field \"NonExistantField\" not found in struct") +} + +func TestIsNeValidation(t *testing.T) { + + var j uint64 + var k float64 + s := "abcdef" + i := 3 + j = 2 + k = 1.5434 + arr := []string{"test"} + now := time.Now().UTC() + + errs := validate.Field(s, "ne=abcd") + Equal(t, errs, nil) + + errs = validate.Field(i, "ne=1") + Equal(t, errs, nil) + + errs = validate.Field(j, "ne=1") + Equal(t, errs, nil) + + errs = validate.Field(k, "ne=1.543") + Equal(t, errs, nil) + + errs = validate.Field(arr, "ne=2") + Equal(t, errs, nil) + + errs = validate.Field(arr, "ne=1") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ne") + + PanicMatches(t, func() { validate.Field(now, "ne=now") }, "Bad field type time.Time") +} + +func TestIsEqFieldValidation(t *testing.T) { + + var j uint64 + var k float64 + s := "abcd" + i := 1 + j = 1 + k = 1.543 + arr := []string{"test"} + now := time.Now().UTC() + + var j2 uint64 + var k2 float64 + s2 := "abcd" + i2 := 1 + j2 = 1 + k2 = 1.543 + arr2 := []string{"test"} + arr3 := []string{"test", "test2"} + now2 := now + + errs := validate.FieldWithValue(s, s2, "eqfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(i2, i, "eqfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(j2, j, "eqfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(k2, k, "eqfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(arr2, arr, "eqfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(now2, now, "eqfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(arr3, arr, "eqfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "eqfield") - // type Inner struct { - // Name string - // } + type Test struct { + Start *time.Time `validate:"eqfield=End"` + End *time.Time + } + + sv := &Test{ + Start: &now, + End: &now, + } + + errs = validate.Struct(sv) + Equal(t, errs, nil) + + now3 := time.Now().UTC() + + sv = &Test{ + Start: &now, + End: &now3, + } + + errs = validate.Struct(sv) + NotEqual(t, errs, nil) + AssertError(t, errs, "Test.Start", "Start", "eqfield") + + channel := make(chan string) + + PanicMatches(t, func() { validate.FieldWithValue(nil, 1, "eqfield") }, "struct or field value not passed for cross validation") + PanicMatches(t, func() { validate.FieldWithValue(5, channel, "eqfield") }, "Bad field type chan string") + PanicMatches(t, func() { validate.FieldWithValue(5, now, "eqfield") }, "Bad Top Level field type") + + type Test2 struct { + Start *time.Time `validate:"eqfield=NonExistantField"` + End *time.Time + } + + sv2 := &Test2{ + Start: &now, + End: &now, + } + + PanicMatches(t, func() { validate.Struct(sv2) }, "Field \"NonExistantField\" not found in struct") +} + +func TestIsEqValidation(t *testing.T) { + + var j uint64 + var k float64 + s := "abcd" + i := 1 + j = 1 + k = 1.543 + arr := []string{"test"} + now := time.Now().UTC() + + errs := validate.Field(s, "eq=abcd") + Equal(t, errs, nil) + + errs = validate.Field(i, "eq=1") + Equal(t, errs, nil) + + errs = validate.Field(j, "eq=1") + Equal(t, errs, nil) + + errs = validate.Field(k, "eq=1.543") + Equal(t, errs, nil) + + errs = validate.Field(arr, "eq=1") + Equal(t, errs, nil) - // type Test struct { - // Name string `validate:"required"` - // Arr []string `validate:"required"` - // // Inner *Inner `validate:"required"` - // } + errs = validate.Field(arr, "eq=2") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "eq") + + PanicMatches(t, func() { validate.Field(now, "eq=now") }, "Bad field type time.Time") +} + +func TestBase64Validation(t *testing.T) { + + s := "dW5pY29ybg==" + + errs := validate.Field(s, "base64") + Equal(t, errs, nil) + + s = "dGhpIGlzIGEgdGVzdCBiYXNlNjQ=" + errs = validate.Field(s, "base64") + Equal(t, errs, nil) + + s = "" + errs = validate.Field(s, "base64") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "base64") + + s = "dW5pY29ybg== foo bar" + errs = validate.Field(s, "base64") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "base64") +} + +func TestStructOnlyValidation(t *testing.T) { - // // inner := &Inner{ - // // Name: "", - // // } + type Inner struct { + Test string `validate:"len=5"` + } + + type Outer struct { + InnerStruct *Inner `validate:"required,structonly"` + } + + outer := &Outer{ + InnerStruct: nil, + } + + errs := validate.Struct(outer) + NotEqual(t, errs, nil) - // tst := &Test{Name: "Dean"} - // // tst := &Test{Inner: inner} + inner := &Inner{ + Test: "1234", + } - // errs := validate.Struct(tst) + outer = &Outer{ + InnerStruct: inner, + } - // fmt.Println(errs) - // fmt.Println(errs == nil) + errs = validate.Struct(outer) + Equal(t, errs, nil) } -// func AssertStruct(t *testing.T, s *StructErrors, structFieldName string, expectedStructName string) *StructErrors { +func TestGtField(t *testing.T) { + + type TimeTest struct { + Start *time.Time `validate:"required,gt"` + End *time.Time `validate:"required,gt,gtfield=Start"` + } + + now := time.Now() + start := now.Add(time.Hour * 24) + end := start.Add(time.Hour * 24) + + timeTest := &TimeTest{ + Start: &start, + End: &end, + } -// val, ok := s.StructErrors[structFieldName] -// EqualSkip(t, 2, ok, true) -// NotEqualSkip(t, 2, val, nil) -// EqualSkip(t, 2, val.Struct, expectedStructName) + errs := validate.Struct(timeTest) + Equal(t, errs, nil) -// return val -// } + timeTest = &TimeTest{ + Start: &end, + End: &start, + } -// func AssertFieldError(t *testing.T, s *StructErrors, field string, expectedTag string) { + errs = validate.Struct(timeTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "TimeTest.End", "End", "gtfield") -// val, ok := s.Errors[field] -// EqualSkip(t, 2, ok, true) -// NotEqualSkip(t, 2, val, nil) -// EqualSkip(t, 2, val.Field, field) -// EqualSkip(t, 2, val.Tag, expectedTag) -// } + errs = validate.FieldWithValue(&start, &end, "gtfield") + Equal(t, errs, nil) -// func AssertMapFieldError(t *testing.T, s map[string]*FieldError, field string, expectedTag string) { + errs = validate.FieldWithValue(&end, &start, "gtfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtfield") -// val, ok := s[field] -// EqualSkip(t, 2, ok, true) -// NotEqualSkip(t, 2, val, nil) -// EqualSkip(t, 2, val.Field, field) -// EqualSkip(t, 2, val.Tag, expectedTag) -// } + type IntTest struct { + Val1 int `validate:"required"` + Val2 int `validate:"required,gtfield=Val1"` + } -// func TestBadKeyValidation(t *testing.T) { -// type Test struct { -// Name string `validate:"required, "` -// } + intTest := &IntTest{ + Val1: 1, + Val2: 5, + } -// tst := &Test{ -// Name: "test", -// } + errs = validate.Struct(intTest) + Equal(t, errs, nil) -// PanicMatches(t, func() { validate.Struct(tst) }, "Invalid validation tag on field Name") -// } + intTest = &IntTest{ + Val1: 5, + Val2: 1, + } -// func TestFlattenValidation(t *testing.T) { + errs = validate.Struct(intTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "IntTest.Val2", "Val2", "gtfield") -// type Inner struct { -// Name string `validate:"required"` -// } + errs = validate.FieldWithValue(int(1), int(5), "gtfield") + Equal(t, errs, nil) -// type TestMultiDimensionalStructsPtr struct { -// Errs [][]*Inner `validate:"gt=0,dive,dive,required"` -// } + errs = validate.FieldWithValue(int(5), int(1), "gtfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtfield") -// var errStructPtrArray [][]*Inner + type UIntTest struct { + Val1 uint `validate:"required"` + Val2 uint `validate:"required,gtfield=Val1"` + } -// errStructPtrArray = append(errStructPtrArray, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{"ok"}}) + uIntTest := &UIntTest{ + Val1: 1, + Val2: 5, + } -// tmsp := &TestMultiDimensionalStructsPtr{ -// Errs: errStructPtrArray, -// } + errs = validate.Struct(uIntTest) + Equal(t, errs, nil) -// errs := validate.Struct(tmsp) -// NotEqual(t, errs, nil) -// Equal(t, len(errs.Errors), 1) -// // for full test coverage -// fmt.Sprint(errs.Error()) + uIntTest = &UIntTest{ + Val1: 5, + Val2: 1, + } -// fieldErr := errs.Errors["Errs"] -// Equal(t, fieldErr.IsPlaceholderErr, true) -// Equal(t, fieldErr.IsSliceOrArray, true) -// Equal(t, fieldErr.Field, "Errs") -// Equal(t, len(fieldErr.SliceOrArrayErrs), 1) + errs = validate.Struct(uIntTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "UIntTest.Val2", "Val2", "gtfield") -// innerSlice1, ok := fieldErr.SliceOrArrayErrs[0].(*FieldError) -// Equal(t, ok, true) -// Equal(t, innerSlice1.IsPlaceholderErr, true) -// Equal(t, innerSlice1.Field, "Errs[0]") - -// flatFieldErr, ok := fieldErr.Flatten()["[0][1].Inner.Name"] -// Equal(t, ok, true) -// Equal(t, flatFieldErr.Field, "Name") -// Equal(t, flatFieldErr.Tag, "required") - -// structErrFlatten, ok := errs.Flatten()["Errs[0][1].Inner.Name"] -// Equal(t, ok, true) -// Equal(t, structErrFlatten.Field, "Name") -// Equal(t, structErrFlatten.Tag, "required") - -// errStructPtrArray = [][]*Inner{} -// errStructPtrArray = append(errStructPtrArray, []*Inner{&Inner{"ok"}, nil, &Inner{"ok"}}) - -// tmsp = &TestMultiDimensionalStructsPtr{ -// Errs: errStructPtrArray, -// } - -// errs = validate.Struct(tmsp) -// NotEqual(t, errs, nil) -// Equal(t, len(errs.Errors), 1) -// // for full test coverage -// fmt.Sprint(errs.Error()) - -// fieldErr = errs.Errors["Errs"] -// Equal(t, fieldErr.IsPlaceholderErr, true) -// Equal(t, fieldErr.IsSliceOrArray, true) -// Equal(t, fieldErr.Field, "Errs") -// Equal(t, len(fieldErr.SliceOrArrayErrs), 1) - -// innerSlice1, ok = fieldErr.SliceOrArrayErrs[0].(*FieldError) -// Equal(t, ok, true) -// Equal(t, innerSlice1.IsPlaceholderErr, true) -// Equal(t, innerSlice1.Field, "Errs[0]") - -// flatFieldErr, ok = fieldErr.Flatten()["[0][1]"] -// Equal(t, ok, true) -// Equal(t, flatFieldErr.Field, "Errs[0][1]") -// Equal(t, flatFieldErr.Tag, "required") - -// type TestMapStructPtr struct { -// Errs map[int]*Inner `validate:"gt=0,dive,required"` -// } - -// mip := map[int]*Inner{0: &Inner{"ok"}, 3: &Inner{""}, 4: &Inner{"ok"}} - -// msp := &TestMapStructPtr{ -// Errs: mip, -// } - -// errs = validate.Struct(msp) -// NotEqual(t, errs, nil) -// Equal(t, len(errs.Errors), 1) - -// fieldError := errs.Errors["Errs"] -// Equal(t, fieldError.IsPlaceholderErr, true) -// Equal(t, fieldError.IsMap, true) -// Equal(t, len(fieldError.MapErrs), 1) - -// innerStructError, ok := fieldError.MapErrs[3].(*StructErrors) -// Equal(t, ok, true) -// Equal(t, innerStructError.Struct, "Inner") -// Equal(t, len(innerStructError.Errors), 1) - -// innerInnerFieldError, ok := innerStructError.Errors["Name"] -// Equal(t, ok, true) -// Equal(t, innerInnerFieldError.IsPlaceholderErr, false) -// Equal(t, innerInnerFieldError.IsSliceOrArray, false) -// Equal(t, innerInnerFieldError.Field, "Name") -// Equal(t, innerInnerFieldError.Tag, "required") - -// flatErrs, ok := errs.Flatten()["Errs[3].Inner.Name"] -// Equal(t, ok, true) -// Equal(t, flatErrs.Field, "Name") -// Equal(t, flatErrs.Tag, "required") - -// mip2 := map[int]*Inner{0: &Inner{"ok"}, 3: nil, 4: &Inner{"ok"}} - -// msp2 := &TestMapStructPtr{ -// Errs: mip2, -// } - -// errs = validate.Struct(msp2) -// NotEqual(t, errs, nil) -// Equal(t, len(errs.Errors), 1) - -// fieldError = errs.Errors["Errs"] -// Equal(t, fieldError.IsPlaceholderErr, true) -// Equal(t, fieldError.IsMap, true) -// Equal(t, len(fieldError.MapErrs), 1) - -// innerFieldError, ok := fieldError.MapErrs[3].(*FieldError) -// Equal(t, ok, true) -// Equal(t, innerFieldError.IsPlaceholderErr, false) -// Equal(t, innerFieldError.IsSliceOrArray, false) -// Equal(t, innerFieldError.Field, "Errs[3]") -// Equal(t, innerFieldError.Tag, "required") - -// flatErrs, ok = errs.Flatten()["Errs[3]"] -// Equal(t, ok, true) -// Equal(t, flatErrs.Field, "Errs[3]") -// Equal(t, flatErrs.Tag, "required") - -// type TestMapInnerArrayStruct struct { -// Errs map[int][]string `validate:"gt=0,dive,dive,required"` -// } - -// mias := map[int][]string{0: []string{"ok"}, 3: []string{"ok", ""}, 4: []string{"ok"}} - -// mia := &TestMapInnerArrayStruct{ -// Errs: mias, -// } - -// errs = validate.Struct(mia) -// NotEqual(t, errs, nil) -// Equal(t, len(errs.Errors), 1) - -// flatErrs, ok = errs.Flatten()["Errs[3][1]"] -// Equal(t, ok, true) -// Equal(t, flatErrs.Field, "Errs[3][1]") -// Equal(t, flatErrs.Tag, "required") -// } - -// func TestInterfaceErrValidation(t *testing.T) { - -// var v1 interface{} -// var v2 interface{} - -// v2 = 1 -// v1 = v2 - -// err := validate.Field(v1, "len=1") -// Equal(t, err, nil) -// err = validate.Field(v2, "len=1") -// Equal(t, err, nil) - -// type ExternalCMD struct { -// Userid string `json:"userid"` -// Action uint32 `json:"action"` -// Data interface{} `json:"data,omitempty" validate:"required"` -// } - -// s := &ExternalCMD{ -// Userid: "123456", -// Action: 10000, -// // Data: 1, -// } - -// errs := validate.Struct(s) -// NotEqual(t, errs, nil) -// Equal(t, errs.Errors["Data"].Field, "Data") -// Equal(t, errs.Errors["Data"].Tag, "required") - -// type ExternalCMD2 struct { -// Userid string `json:"userid"` -// Action uint32 `json:"action"` -// Data interface{} `json:"data,omitempty" validate:"len=1"` -// } - -// s2 := &ExternalCMD2{ -// Userid: "123456", -// Action: 10000, -// // Data: 1, -// } - -// errs = validate.Struct(s2) -// NotEqual(t, errs, nil) -// Equal(t, errs.Errors["Data"].Field, "Data") -// Equal(t, errs.Errors["Data"].Tag, "len") -// Equal(t, errs.Errors["Data"].Param, "1") - -// s3 := &ExternalCMD2{ -// Userid: "123456", -// Action: 10000, -// Data: 2, -// } - -// errs = validate.Struct(s3) -// NotEqual(t, errs, nil) -// Equal(t, errs.Errors["Data"].Field, "Data") -// Equal(t, errs.Errors["Data"].Tag, "len") -// Equal(t, errs.Errors["Data"].Param, "1") - -// type Inner struct { -// Name string `validate:"required"` -// } - -// inner := &Inner{ -// Name: "", -// } - -// s4 := &ExternalCMD{ -// Userid: "123456", -// Action: 10000, -// Data: inner, -// } - -// errs = validate.Struct(s4) -// NotEqual(t, errs, nil) -// Equal(t, errs.StructErrors["Data"].Struct, "Inner") -// Equal(t, errs.StructErrors["Data"].Errors["Name"].Field, "Name") -// Equal(t, errs.StructErrors["Data"].Errors["Name"].Tag, "required") - -// type TestMapStructPtr struct { -// Errs map[int]interface{} `validate:"gt=0,dive,len=2"` -// } - -// mip := map[int]interface{}{0: &Inner{"ok"}, 3: nil, 4: &Inner{"ok"}} - -// msp := &TestMapStructPtr{ -// Errs: mip, -// } - -// errs = validate.Struct(msp) -// NotEqual(t, errs, nil) -// Equal(t, len(errs.Errors), 1) - -// fieldError := errs.Errors["Errs"] -// Equal(t, fieldError.IsPlaceholderErr, true) -// Equal(t, fieldError.IsMap, true) -// Equal(t, len(fieldError.MapErrs), 1) - -// innerFieldError, ok := fieldError.MapErrs[3].(*FieldError) -// Equal(t, ok, true) -// Equal(t, innerFieldError.IsPlaceholderErr, false) -// Equal(t, innerFieldError.IsMap, false) -// Equal(t, len(innerFieldError.MapErrs), 0) -// Equal(t, innerFieldError.Field, "Errs[3]") -// Equal(t, innerFieldError.Tag, "len") - -// type TestMultiDimensionalStructs struct { -// Errs [][]interface{} `validate:"gt=0,dive,dive,len=2"` -// } - -// var errStructArray [][]interface{} - -// errStructArray = append(errStructArray, []interface{}{&Inner{"ok"}, &Inner{""}, &Inner{""}}) -// errStructArray = append(errStructArray, []interface{}{&Inner{"ok"}, &Inner{""}, &Inner{""}}) - -// tms := &TestMultiDimensionalStructs{ -// Errs: errStructArray, -// } - -// errs = validate.Struct(tms) -// NotEqual(t, errs, nil) -// Equal(t, len(errs.Errors), 1) - -// fieldErr, ok := errs.Errors["Errs"] -// Equal(t, ok, true) -// Equal(t, fieldErr.IsPlaceholderErr, true) -// Equal(t, fieldErr.IsSliceOrArray, true) -// Equal(t, len(fieldErr.SliceOrArrayErrs), 2) - -// sliceError1, ok := fieldErr.SliceOrArrayErrs[0].(*FieldError) -// Equal(t, ok, true) -// Equal(t, sliceError1.IsPlaceholderErr, true) -// Equal(t, sliceError1.IsSliceOrArray, true) -// Equal(t, len(sliceError1.SliceOrArrayErrs), 2) - -// innerSliceStructError1, ok := sliceError1.SliceOrArrayErrs[1].(*StructErrors) -// Equal(t, ok, true) -// Equal(t, len(innerSliceStructError1.Errors), 1) - -// innerInnersliceError1 := innerSliceStructError1.Errors["Name"] -// Equal(t, innerInnersliceError1.IsPlaceholderErr, false) -// Equal(t, innerInnersliceError1.IsSliceOrArray, false) -// Equal(t, len(innerInnersliceError1.SliceOrArrayErrs), 0) - -// type TestMultiDimensionalStructsPtr2 struct { -// Errs [][]*Inner `validate:"gt=0,dive,dive,len=2"` -// } - -// var errStructPtr2Array [][]*Inner - -// errStructPtr2Array = append(errStructPtr2Array, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}}) -// errStructPtr2Array = append(errStructPtr2Array, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}}) -// errStructPtr2Array = append(errStructPtr2Array, []*Inner{&Inner{"ok"}, &Inner{""}, nil}) - -// tmsp2 := &TestMultiDimensionalStructsPtr2{ -// Errs: errStructPtr2Array, -// } - -// errs = validate.Struct(tmsp2) -// NotEqual(t, errs, nil) -// Equal(t, len(errs.Errors), 1) - -// fieldErr, ok = errs.Errors["Errs"] -// Equal(t, ok, true) -// Equal(t, fieldErr.IsPlaceholderErr, true) -// Equal(t, fieldErr.IsSliceOrArray, true) -// Equal(t, len(fieldErr.SliceOrArrayErrs), 3) - -// sliceError1, ok = fieldErr.SliceOrArrayErrs[2].(*FieldError) -// Equal(t, ok, true) -// Equal(t, sliceError1.IsPlaceholderErr, true) -// Equal(t, sliceError1.IsSliceOrArray, true) -// Equal(t, len(sliceError1.SliceOrArrayErrs), 2) - -// innerSliceStructError1, ok = sliceError1.SliceOrArrayErrs[1].(*StructErrors) -// Equal(t, ok, true) -// Equal(t, len(innerSliceStructError1.Errors), 1) - -// innerSliceStructError2, ok := sliceError1.SliceOrArrayErrs[2].(*FieldError) -// Equal(t, ok, true) -// Equal(t, innerSliceStructError2.IsPlaceholderErr, false) -// Equal(t, innerSliceStructError2.IsSliceOrArray, false) -// Equal(t, len(innerSliceStructError2.SliceOrArrayErrs), 0) -// Equal(t, innerSliceStructError2.Field, "Errs[2][2]") - -// innerInnersliceError1 = innerSliceStructError1.Errors["Name"] -// Equal(t, innerInnersliceError1.IsPlaceholderErr, false) -// Equal(t, innerInnersliceError1.IsSliceOrArray, false) -// Equal(t, len(innerInnersliceError1.SliceOrArrayErrs), 0) - -// m := map[int]interface{}{0: "ok", 3: "", 4: "ok"} - -// err = validate.Field(m, "len=3,dive,len=2") -// NotEqual(t, err, nil) -// Equal(t, err.IsPlaceholderErr, true) -// Equal(t, err.IsMap, true) -// Equal(t, len(err.MapErrs), 1) - -// err = validate.Field(m, "len=2,dive,required") -// NotEqual(t, err, nil) -// Equal(t, err.IsPlaceholderErr, false) -// Equal(t, err.IsMap, false) -// Equal(t, len(err.MapErrs), 0) - -// arr := []interface{}{"ok", "", "ok"} - -// err = validate.Field(arr, "len=3,dive,len=2") -// NotEqual(t, err, nil) -// Equal(t, err.IsPlaceholderErr, true) -// Equal(t, err.IsSliceOrArray, true) -// Equal(t, len(err.SliceOrArrayErrs), 1) - -// err = validate.Field(arr, "len=2,dive,required") -// NotEqual(t, err, nil) -// Equal(t, err.IsPlaceholderErr, false) -// Equal(t, err.IsSliceOrArray, false) -// Equal(t, len(err.SliceOrArrayErrs), 0) - -// type MyStruct struct { -// A, B string -// C interface{} -// } - -// var a MyStruct - -// a.A = "value" -// a.C = "nu" - -// errs = validate.Struct(a) -// Equal(t, errs, nil) -// } - -// func TestMapDiveValidation(t *testing.T) { - -// n := map[int]interface{}{0: nil} -// err := validate.Field(n, "omitempty,required") - -// m := map[int]string{0: "ok", 3: "", 4: "ok"} - -// err = validate.Field(m, "len=3,dive,required") -// NotEqual(t, err, nil) -// Equal(t, err.IsPlaceholderErr, true) -// Equal(t, err.IsMap, true) -// Equal(t, len(err.MapErrs), 1) - -// err = validate.Field(m, "len=2,dive,required") -// NotEqual(t, err, nil) -// Equal(t, err.IsPlaceholderErr, false) -// Equal(t, err.IsMap, false) -// Equal(t, len(err.MapErrs), 0) - -// type Inner struct { -// Name string `validate:"required"` -// } - -// type TestMapStruct struct { -// Errs map[int]Inner `validate:"gt=0,dive"` -// } - -// mi := map[int]Inner{0: Inner{"ok"}, 3: Inner{""}, 4: Inner{"ok"}} - -// ms := &TestMapStruct{ -// Errs: mi, -// } - -// errs := validate.Struct(ms) -// NotEqual(t, errs, nil) -// Equal(t, len(errs.Errors), 1) -// // for full test coverage -// fmt.Sprint(errs.Error()) - -// fieldError := errs.Errors["Errs"] -// Equal(t, fieldError.IsPlaceholderErr, true) -// Equal(t, fieldError.IsMap, true) -// Equal(t, len(fieldError.MapErrs), 1) - -// structErr, ok := fieldError.MapErrs[3].(*StructErrors) -// Equal(t, ok, true) -// Equal(t, len(structErr.Errors), 1) - -// innerErr := structErr.Errors["Name"] -// Equal(t, innerErr.IsPlaceholderErr, false) -// Equal(t, innerErr.IsMap, false) -// Equal(t, len(innerErr.MapErrs), 0) -// Equal(t, innerErr.Field, "Name") -// Equal(t, innerErr.Tag, "required") - -// type TestMapTimeStruct struct { -// Errs map[int]*time.Time `validate:"gt=0,dive,required"` -// } - -// t1 := time.Now().UTC() - -// mta := map[int]*time.Time{0: &t1, 3: nil, 4: nil} - -// mt := &TestMapTimeStruct{ -// Errs: mta, -// } - -// errs = validate.Struct(mt) -// NotEqual(t, errs, nil) -// Equal(t, len(errs.Errors), 1) - -// fieldError = errs.Errors["Errs"] -// Equal(t, fieldError.IsPlaceholderErr, true) -// Equal(t, fieldError.IsMap, true) -// Equal(t, len(fieldError.MapErrs), 2) - -// innerErr, ok = fieldError.MapErrs[3].(*FieldError) -// Equal(t, ok, true) -// Equal(t, innerErr.IsPlaceholderErr, false) -// Equal(t, innerErr.IsMap, false) -// Equal(t, len(innerErr.MapErrs), 0) -// Equal(t, innerErr.Field, "Errs[3]") -// Equal(t, innerErr.Tag, "required") - -// type TestMapStructPtr struct { -// Errs map[int]*Inner `validate:"gt=0,dive,required"` -// } - -// mip := map[int]*Inner{0: &Inner{"ok"}, 3: nil, 4: &Inner{"ok"}} - -// msp := &TestMapStructPtr{ -// Errs: mip, -// } - -// errs = validate.Struct(msp) -// NotEqual(t, errs, nil) -// Equal(t, len(errs.Errors), 1) - -// fieldError = errs.Errors["Errs"] -// Equal(t, fieldError.IsPlaceholderErr, true) -// Equal(t, fieldError.IsMap, true) -// Equal(t, len(fieldError.MapErrs), 1) - -// innerFieldError, ok := fieldError.MapErrs[3].(*FieldError) -// Equal(t, ok, true) -// Equal(t, innerFieldError.IsPlaceholderErr, false) -// Equal(t, innerFieldError.IsMap, false) -// Equal(t, len(innerFieldError.MapErrs), 0) -// Equal(t, innerFieldError.Field, "Errs[3]") -// Equal(t, innerFieldError.Tag, "required") - -// type TestMapStructPtr2 struct { -// Errs map[int]*Inner `validate:"gt=0,dive,omitempty,required"` -// } - -// mip2 := map[int]*Inner{0: &Inner{"ok"}, 3: nil, 4: &Inner{"ok"}} - -// msp2 := &TestMapStructPtr2{ -// Errs: mip2, -// } - -// errs = validate.Struct(msp2) -// Equal(t, errs, nil) -// } - -// func TestArrayDiveValidation(t *testing.T) { - -// arr := []string{"ok", "", "ok"} - -// err := validate.Field(arr, "len=3,dive,required") -// NotEqual(t, err, nil) -// Equal(t, err.IsPlaceholderErr, true) -// Equal(t, err.IsSliceOrArray, true) -// Equal(t, len(err.SliceOrArrayErrs), 1) - -// // flat := err.Flatten() -// // fe, ok := flat["[1]"] -// // Equal(t, ok, true) -// // Equal(t, fe.Tag, "required") - -// err = validate.Field(arr, "len=2,dive,required") -// NotEqual(t, err, nil) -// Equal(t, err.IsPlaceholderErr, false) -// Equal(t, err.IsSliceOrArray, false) -// Equal(t, len(err.SliceOrArrayErrs), 0) - -// type BadDive struct { -// Name string `validate:"dive"` -// } - -// bd := &BadDive{ -// Name: "TEST", -// } - -// PanicMatches(t, func() { validate.Struct(bd) }, "dive error! can't dive on a non slice or map") - -// type Test struct { -// Errs []string `validate:"gt=0,dive,required"` -// } - -// test := &Test{ -// Errs: []string{"ok", "", "ok"}, -// } - -// errs := validate.Struct(test) -// NotEqual(t, errs, nil) -// Equal(t, len(errs.Errors), 1) - -// // flat = errs.Flatten() -// // me, ok := flat["Errs[1]"] -// // Equal(t, ok, true) -// // Equal(t, me.Field, "Errs[1]") -// // Equal(t, me.Tag, "required") - -// fieldErr, ok := errs.Errors["Errs"] -// Equal(t, ok, true) -// Equal(t, fieldErr.IsPlaceholderErr, true) -// Equal(t, fieldErr.IsSliceOrArray, true) -// Equal(t, len(fieldErr.SliceOrArrayErrs), 1) - -// innerErr, ok := fieldErr.SliceOrArrayErrs[1].(*FieldError) -// Equal(t, ok, true) -// Equal(t, innerErr.Tag, required) -// Equal(t, innerErr.IsPlaceholderErr, false) -// Equal(t, innerErr.Field, "Errs[1]") - -// test = &Test{ -// Errs: []string{"ok", "ok", ""}, -// } - -// errs = validate.Struct(test) -// NotEqual(t, errs, nil) -// Equal(t, len(errs.Errors), 1) - -// fieldErr, ok = errs.Errors["Errs"] -// Equal(t, ok, true) -// Equal(t, fieldErr.IsPlaceholderErr, true) -// Equal(t, fieldErr.IsSliceOrArray, true) -// Equal(t, len(fieldErr.SliceOrArrayErrs), 1) - -// innerErr, ok = fieldErr.SliceOrArrayErrs[2].(*FieldError) -// Equal(t, ok, true) -// Equal(t, innerErr.Tag, required) -// Equal(t, innerErr.IsPlaceholderErr, false) -// Equal(t, innerErr.Field, "Errs[2]") - -// type TestMultiDimensional struct { -// Errs [][]string `validate:"gt=0,dive,dive,required"` -// } - -// var errArray [][]string - -// errArray = append(errArray, []string{"ok", "", ""}) -// errArray = append(errArray, []string{"ok", "", ""}) - -// tm := &TestMultiDimensional{ -// Errs: errArray, -// } - -// errs = validate.Struct(tm) -// NotEqual(t, errs, nil) -// Equal(t, len(errs.Errors), 1) - -// fieldErr, ok = errs.Errors["Errs"] -// Equal(t, ok, true) -// Equal(t, fieldErr.IsPlaceholderErr, true) -// Equal(t, fieldErr.IsSliceOrArray, true) -// Equal(t, len(fieldErr.SliceOrArrayErrs), 2) - -// sliceError1, ok := fieldErr.SliceOrArrayErrs[0].(*FieldError) -// Equal(t, ok, true) -// Equal(t, sliceError1.IsPlaceholderErr, true) -// Equal(t, sliceError1.IsSliceOrArray, true) -// Equal(t, len(sliceError1.SliceOrArrayErrs), 2) -// Equal(t, sliceError1.Field, "Errs[0]") - -// innerSliceError1, ok := sliceError1.SliceOrArrayErrs[1].(*FieldError) -// Equal(t, ok, true) -// Equal(t, innerSliceError1.IsPlaceholderErr, false) -// Equal(t, innerSliceError1.Tag, required) -// Equal(t, innerSliceError1.IsSliceOrArray, false) -// Equal(t, len(innerSliceError1.SliceOrArrayErrs), 0) -// Equal(t, innerSliceError1.Field, "Errs[0][1]") - -// type Inner struct { -// Name string `validate:"required"` -// } - -// type TestMultiDimensionalStructs struct { -// Errs [][]Inner `validate:"gt=0,dive,dive"` -// } - -// var errStructArray [][]Inner - -// errStructArray = append(errStructArray, []Inner{Inner{"ok"}, Inner{""}, Inner{""}}) -// errStructArray = append(errStructArray, []Inner{Inner{"ok"}, Inner{""}, Inner{""}}) - -// tms := &TestMultiDimensionalStructs{ -// Errs: errStructArray, -// } - -// errs = validate.Struct(tms) -// NotEqual(t, errs, nil) -// Equal(t, len(errs.Errors), 1) - -// fieldErr, ok = errs.Errors["Errs"] -// Equal(t, ok, true) -// Equal(t, fieldErr.IsPlaceholderErr, true) -// Equal(t, fieldErr.IsSliceOrArray, true) -// Equal(t, len(fieldErr.SliceOrArrayErrs), 2) - -// sliceError1, ok = fieldErr.SliceOrArrayErrs[0].(*FieldError) -// Equal(t, ok, true) -// Equal(t, sliceError1.IsPlaceholderErr, true) -// Equal(t, sliceError1.IsSliceOrArray, true) -// Equal(t, len(sliceError1.SliceOrArrayErrs), 2) - -// innerSliceStructError1, ok := sliceError1.SliceOrArrayErrs[1].(*StructErrors) -// Equal(t, ok, true) -// Equal(t, len(innerSliceStructError1.Errors), 1) - -// innerInnersliceError1 := innerSliceStructError1.Errors["Name"] -// Equal(t, innerInnersliceError1.IsPlaceholderErr, false) -// Equal(t, innerInnersliceError1.IsSliceOrArray, false) -// Equal(t, len(innerInnersliceError1.SliceOrArrayErrs), 0) - -// type TestMultiDimensionalStructsPtr struct { -// Errs [][]*Inner `validate:"gt=0,dive,dive"` -// } - -// var errStructPtrArray [][]*Inner - -// errStructPtrArray = append(errStructPtrArray, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}}) -// errStructPtrArray = append(errStructPtrArray, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}}) -// errStructPtrArray = append(errStructPtrArray, []*Inner{&Inner{"ok"}, &Inner{""}, nil}) - -// tmsp := &TestMultiDimensionalStructsPtr{ -// Errs: errStructPtrArray, -// } - -// errs = validate.Struct(tmsp) -// NotEqual(t, errs, nil) -// Equal(t, len(errs.Errors), 1) -// // for full test coverage -// fmt.Sprint(errs.Error()) - -// // flat := errs.Flatten() -// // // fmt.Println(errs) -// // fmt.Println(flat) -// // expect Errs[0][1].Inner.Name -// // me, ok := flat["Errs[1]"] -// // Equal(t, ok, true) -// // Equal(t, me.Field, "Errs[1]") -// // Equal(t, me.Tag, "required") - -// fieldErr, ok = errs.Errors["Errs"] -// Equal(t, ok, true) -// Equal(t, fieldErr.IsPlaceholderErr, true) -// Equal(t, fieldErr.IsSliceOrArray, true) -// Equal(t, len(fieldErr.SliceOrArrayErrs), 3) - -// // flat := fieldErr.Flatten() -// // fmt.Println(errs) -// // fmt.Println(flat) - -// sliceError1, ok = fieldErr.SliceOrArrayErrs[0].(*FieldError) -// Equal(t, ok, true) -// Equal(t, sliceError1.IsPlaceholderErr, true) -// Equal(t, sliceError1.IsSliceOrArray, true) -// Equal(t, len(sliceError1.SliceOrArrayErrs), 2) - -// innerSliceStructError1, ok = sliceError1.SliceOrArrayErrs[1].(*StructErrors) -// Equal(t, ok, true) -// Equal(t, len(innerSliceStructError1.Errors), 1) - -// innerInnersliceError1 = innerSliceStructError1.Errors["Name"] -// Equal(t, innerInnersliceError1.IsPlaceholderErr, false) -// Equal(t, innerInnersliceError1.IsSliceOrArray, false) -// Equal(t, len(innerInnersliceError1.SliceOrArrayErrs), 0) - -// type TestMultiDimensionalStructsPtr2 struct { -// Errs [][]*Inner `validate:"gt=0,dive,dive,required"` -// } - -// var errStructPtr2Array [][]*Inner - -// errStructPtr2Array = append(errStructPtr2Array, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}}) -// errStructPtr2Array = append(errStructPtr2Array, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}}) -// errStructPtr2Array = append(errStructPtr2Array, []*Inner{&Inner{"ok"}, &Inner{""}, nil}) - -// tmsp2 := &TestMultiDimensionalStructsPtr2{ -// Errs: errStructPtr2Array, -// } - -// errs = validate.Struct(tmsp2) -// NotEqual(t, errs, nil) -// Equal(t, len(errs.Errors), 1) - -// fieldErr, ok = errs.Errors["Errs"] -// Equal(t, ok, true) -// Equal(t, fieldErr.IsPlaceholderErr, true) -// Equal(t, fieldErr.IsSliceOrArray, true) -// Equal(t, len(fieldErr.SliceOrArrayErrs), 3) - -// sliceError1, ok = fieldErr.SliceOrArrayErrs[2].(*FieldError) -// Equal(t, ok, true) -// Equal(t, sliceError1.IsPlaceholderErr, true) -// Equal(t, sliceError1.IsSliceOrArray, true) -// Equal(t, len(sliceError1.SliceOrArrayErrs), 2) - -// innerSliceStructError1, ok = sliceError1.SliceOrArrayErrs[1].(*StructErrors) -// Equal(t, ok, true) -// Equal(t, len(innerSliceStructError1.Errors), 1) - -// innerSliceStructError2, ok := sliceError1.SliceOrArrayErrs[2].(*FieldError) -// Equal(t, ok, true) -// Equal(t, innerSliceStructError2.IsPlaceholderErr, false) -// Equal(t, innerSliceStructError2.IsSliceOrArray, false) -// Equal(t, len(innerSliceStructError2.SliceOrArrayErrs), 0) -// Equal(t, innerSliceStructError2.Field, "Errs[2][2]") - -// innerInnersliceError1 = innerSliceStructError1.Errors["Name"] -// Equal(t, innerInnersliceError1.IsPlaceholderErr, false) -// Equal(t, innerInnersliceError1.IsSliceOrArray, false) -// Equal(t, len(innerInnersliceError1.SliceOrArrayErrs), 0) - -// type TestMultiDimensionalStructsPtr3 struct { -// Errs [][]*Inner `validate:"gt=0,dive,dive,omitempty"` -// } - -// var errStructPtr3Array [][]*Inner - -// errStructPtr3Array = append(errStructPtr3Array, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}}) -// errStructPtr3Array = append(errStructPtr3Array, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}}) -// errStructPtr3Array = append(errStructPtr3Array, []*Inner{&Inner{"ok"}, &Inner{""}, nil}) - -// tmsp3 := &TestMultiDimensionalStructsPtr3{ -// Errs: errStructPtr3Array, -// } - -// errs = validate.Struct(tmsp3) -// NotEqual(t, errs, nil) -// Equal(t, len(errs.Errors), 1) - -// fieldErr, ok = errs.Errors["Errs"] -// Equal(t, ok, true) -// Equal(t, fieldErr.IsPlaceholderErr, true) -// Equal(t, fieldErr.IsSliceOrArray, true) -// Equal(t, len(fieldErr.SliceOrArrayErrs), 3) - -// sliceError1, ok = fieldErr.SliceOrArrayErrs[0].(*FieldError) -// Equal(t, ok, true) -// Equal(t, sliceError1.IsPlaceholderErr, true) -// Equal(t, sliceError1.IsSliceOrArray, true) -// Equal(t, len(sliceError1.SliceOrArrayErrs), 2) - -// innerSliceStructError1, ok = sliceError1.SliceOrArrayErrs[1].(*StructErrors) -// Equal(t, ok, true) -// Equal(t, len(innerSliceStructError1.Errors), 1) - -// innerInnersliceError1 = innerSliceStructError1.Errors["Name"] -// Equal(t, innerInnersliceError1.IsPlaceholderErr, false) -// Equal(t, innerInnersliceError1.IsSliceOrArray, false) -// Equal(t, len(innerInnersliceError1.SliceOrArrayErrs), 0) - -// type TestMultiDimensionalTimeTime struct { -// Errs [][]*time.Time `validate:"gt=0,dive,dive,required"` -// } - -// var errTimePtr3Array [][]*time.Time - -// t1 := time.Now().UTC() -// t2 := time.Now().UTC() -// t3 := time.Now().UTC().Add(time.Hour * 24) - -// errTimePtr3Array = append(errTimePtr3Array, []*time.Time{&t1, &t2, &t3}) -// errTimePtr3Array = append(errTimePtr3Array, []*time.Time{&t1, &t2, nil}) -// errTimePtr3Array = append(errTimePtr3Array, []*time.Time{&t1, nil, nil}) - -// tmtp3 := &TestMultiDimensionalTimeTime{ -// Errs: errTimePtr3Array, -// } - -// errs = validate.Struct(tmtp3) -// NotEqual(t, errs, nil) -// Equal(t, len(errs.Errors), 1) - -// fieldErr, ok = errs.Errors["Errs"] -// Equal(t, ok, true) -// Equal(t, fieldErr.IsPlaceholderErr, true) -// Equal(t, fieldErr.IsSliceOrArray, true) -// Equal(t, len(fieldErr.SliceOrArrayErrs), 2) - -// sliceError1, ok = fieldErr.SliceOrArrayErrs[2].(*FieldError) -// Equal(t, ok, true) -// Equal(t, sliceError1.IsPlaceholderErr, true) -// Equal(t, sliceError1.IsSliceOrArray, true) -// Equal(t, len(sliceError1.SliceOrArrayErrs), 2) - -// innerSliceError1, ok = sliceError1.SliceOrArrayErrs[1].(*FieldError) -// Equal(t, ok, true) -// Equal(t, innerSliceError1.IsPlaceholderErr, false) -// Equal(t, innerSliceError1.IsSliceOrArray, false) -// Equal(t, len(innerSliceError1.SliceOrArrayErrs), 0) -// Equal(t, innerSliceError1.Field, "Errs[2][1]") -// Equal(t, innerSliceError1.Tag, required) - -// type TestMultiDimensionalTimeTime2 struct { -// Errs [][]*time.Time `validate:"gt=0,dive,dive,required"` -// } - -// var errTimeArray [][]*time.Time - -// t1 = time.Now().UTC() -// t2 = time.Now().UTC() -// t3 = time.Now().UTC().Add(time.Hour * 24) - -// errTimeArray = append(errTimeArray, []*time.Time{&t1, &t2, &t3}) -// errTimeArray = append(errTimeArray, []*time.Time{&t1, &t2, nil}) -// errTimeArray = append(errTimeArray, []*time.Time{&t1, nil, nil}) - -// tmtp := &TestMultiDimensionalTimeTime2{ -// Errs: errTimeArray, -// } - -// errs = validate.Struct(tmtp) -// NotEqual(t, errs, nil) -// Equal(t, len(errs.Errors), 1) - -// fieldErr, ok = errs.Errors["Errs"] -// Equal(t, ok, true) -// Equal(t, fieldErr.IsPlaceholderErr, true) -// Equal(t, fieldErr.IsSliceOrArray, true) -// Equal(t, len(fieldErr.SliceOrArrayErrs), 2) - -// sliceError1, ok = fieldErr.SliceOrArrayErrs[2].(*FieldError) -// Equal(t, ok, true) -// Equal(t, sliceError1.IsPlaceholderErr, true) -// Equal(t, sliceError1.IsSliceOrArray, true) -// Equal(t, len(sliceError1.SliceOrArrayErrs), 2) - -// innerSliceError1, ok = sliceError1.SliceOrArrayErrs[1].(*FieldError) -// Equal(t, ok, true) -// Equal(t, innerSliceError1.IsPlaceholderErr, false) -// Equal(t, innerSliceError1.IsSliceOrArray, false) -// Equal(t, len(innerSliceError1.SliceOrArrayErrs), 0) -// Equal(t, innerSliceError1.Field, "Errs[2][1]") -// Equal(t, innerSliceError1.Tag, required) -// } - -// func TestNilStructPointerValidation(t *testing.T) { -// type Inner struct { -// Data string -// } - -// type Outer struct { -// Inner *Inner `validate:"omitempty"` -// } - -// inner := &Inner{ -// Data: "test", -// } - -// outer := &Outer{ -// Inner: inner, -// } - -// errs := validate.Struct(outer) -// Equal(t, errs, nil) - -// outer = &Outer{ -// Inner: nil, -// } - -// errs = validate.Struct(outer) -// Equal(t, errs, nil) - -// type Inner2 struct { -// Data string -// } - -// type Outer2 struct { -// Inner2 *Inner2 `validate:"required"` -// } - -// inner2 := &Inner2{ -// Data: "test", -// } - -// outer2 := &Outer2{ -// Inner2: inner2, -// } - -// errs = validate.Struct(outer2) -// Equal(t, errs, nil) - -// outer2 = &Outer2{ -// Inner2: nil, -// } - -// errs = validate.Struct(outer2) -// NotEqual(t, errs, nil) - -// type Inner3 struct { -// Data string -// } - -// type Outer3 struct { -// Inner3 *Inner3 -// } - -// inner3 := &Inner3{ -// Data: "test", -// } - -// outer3 := &Outer3{ -// Inner3: inner3, -// } - -// errs = validate.Struct(outer3) -// Equal(t, errs, nil) - -// type Inner4 struct { -// Data string -// } - -// type Outer4 struct { -// Inner4 *Inner4 `validate:"-"` -// } - -// inner4 := &Inner4{ -// Data: "test", -// } - -// outer4 := &Outer4{ -// Inner4: inner4, -// } - -// errs = validate.Struct(outer4) -// Equal(t, errs, nil) -// } - -// func TestSSNValidation(t *testing.T) { -// tests := []struct { -// param string -// expected bool -// }{ -// {"", false}, -// {"00-90-8787", false}, -// {"66690-76", false}, -// {"191 60 2869", true}, -// {"191-60-2869", true}, -// } - -// for i, test := range tests { - -// err := validate.Field(test.param, "ssn") - -// if test.expected == true { -// if !IsEqual(t, err, nil) { -// t.Fatalf("Index: %d SSN failed Error: %s", i, err) -// } -// } else { -// if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "ssn") { -// t.Fatalf("Index: %d SSN failed Error: %s", i, err) -// } -// } -// } -// } - -// func TestLongitudeValidation(t *testing.T) { -// tests := []struct { -// param string -// expected bool -// }{ -// {"", false}, -// {"-180.000", true}, -// {"180.1", false}, -// {"+73.234", true}, -// {"+382.3811", false}, -// {"23.11111111", true}, -// } - -// for i, test := range tests { - -// err := validate.Field(test.param, "longitude") - -// if test.expected == true { -// if !IsEqual(t, err, nil) { -// t.Fatalf("Index: %d Longitude failed Error: %s", i, err) -// } -// } else { -// if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "longitude") { -// t.Fatalf("Index: %d Longitude failed Error: %s", i, err) -// } -// } -// } -// } - -// func TestLatitudeValidation(t *testing.T) { -// tests := []struct { -// param string -// expected bool -// }{ -// {"", false}, -// {"-90.000", true}, -// {"+90", true}, -// {"47.1231231", true}, -// {"+99.9", false}, -// {"108", false}, -// } - -// for i, test := range tests { - -// err := validate.Field(test.param, "latitude") - -// if test.expected == true { -// if !IsEqual(t, err, nil) { -// t.Fatalf("Index: %d Latitude failed Error: %s", i, err) -// } -// } else { -// if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "latitude") { -// t.Fatalf("Index: %d Latitude failed Error: %s", i, err) -// } -// } -// } -// } - -// func TestDataURIValidation(t *testing.T) { -// tests := []struct { -// param string -// expected bool -// }{ -// {"data:image/png;base64,TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4=", true}, -// {"data:text/plain;base64,Vml2YW11cyBmZXJtZW50dW0gc2VtcGVyIHBvcnRhLg==", true}, -// {"image/gif;base64,U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", false}, -// {"data:image/gif;base64,MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuMPNS1Ufof9EW/M98FNw" + -// "UAKrwflsqVxaxQjBQnHQmiI7Vac40t8x7pIb8gLGV6wL7sBTJiPovJ0V7y7oc0Ye" + -// "rhKh0Rm4skP2z/jHwwZICgGzBvA0rH8xlhUiTvcwDCJ0kc+fh35hNt8srZQM4619" + -// "FTgB66Xmp4EtVyhpQV+t02g6NzK72oZI0vnAvqhpkxLeLiMCyrI416wHm5Tkukhx" + -// "QmcL2a6hNOyu0ixX/x2kSFXApEnVrJ+/IxGyfyw8kf4N2IZpW5nEP847lpfj0SZZ" + -// "Fwrd1mnfnDbYohX2zRptLy2ZUn06Qo9pkG5ntvFEPo9bfZeULtjYzIl6K8gJ2uGZ" + "HQIDAQAB", true}, -// {"data:image/png;base64,12345", false}, -// {"", false}, -// {"data:text,:;base85,U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", false}, -// } - -// for i, test := range tests { - -// err := validate.Field(test.param, "datauri") - -// if test.expected == true { -// if !IsEqual(t, err, nil) { -// t.Fatalf("Index: %d DataURI failed Error: %s", i, err) -// } -// } else { -// if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "datauri") { -// t.Fatalf("Index: %d DataURI failed Error: %s", i, err) -// } -// } -// } -// } - -// func TestMultibyteValidation(t *testing.T) { -// tests := []struct { -// param string -// expected bool -// }{ -// {"", true}, -// {"abc", false}, -// {"123", false}, -// {"<>@;.-=", false}, -// {"ひらがな・カタカナ、.漢字", true}, -// {"あいうえお foobar", true}, -// {"test@example.com", true}, -// {"test@example.com", true}, -// {"1234abcDExyz", true}, -// {"カタカナ", true}, -// } - -// for i, test := range tests { - -// err := validate.Field(test.param, "multibyte") - -// if test.expected == true { -// if !IsEqual(t, err, nil) { -// t.Fatalf("Index: %d Multibyte failed Error: %s", i, err) -// } -// } else { -// if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "multibyte") { -// t.Fatalf("Index: %d Multibyte failed Error: %s", i, err) -// } -// } -// } -// } - -// func TestPrintableASCIIValidation(t *testing.T) { -// tests := []struct { -// param string -// expected bool -// }{ -// {"", true}, -// {"foobar", false}, -// {"xyz098", false}, -// {"123456", false}, -// {"カタカナ", false}, -// {"foobar", true}, -// {"0987654321", true}, -// {"test@example.com", true}, -// {"1234abcDEF", true}, -// {"newline\n", false}, -// {"\x19test\x7F", false}, -// } - -// for i, test := range tests { - -// err := validate.Field(test.param, "printascii") - -// if test.expected == true { -// if !IsEqual(t, err, nil) { -// t.Fatalf("Index: %d Printable ASCII failed Error: %s", i, err) -// } -// } else { -// if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "printascii") { -// t.Fatalf("Index: %d Printable ASCII failed Error: %s", i, err) -// } -// } -// } -// } - -// func TestASCIIValidation(t *testing.T) { -// tests := []struct { -// param string -// expected bool -// }{ -// {"", true}, -// {"foobar", false}, -// {"xyz098", false}, -// {"123456", false}, -// {"カタカナ", false}, -// {"foobar", true}, -// {"0987654321", true}, -// {"test@example.com", true}, -// {"1234abcDEF", true}, -// {"", true}, -// } - -// for i, test := range tests { - -// err := validate.Field(test.param, "ascii") - -// if test.expected == true { -// if !IsEqual(t, err, nil) { -// t.Fatalf("Index: %d ASCII failed Error: %s", i, err) -// } -// } else { -// if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "ascii") { -// t.Fatalf("Index: %d ASCII failed Error: %s", i, err) -// } -// } -// } -// } - -// func TestUUID5Validation(t *testing.T) { -// tests := []struct { -// param string -// expected bool -// }{ - -// {"", false}, -// {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, -// {"9c858901-8a57-4791-81fe-4c455b099bc9", false}, -// {"a987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, -// {"987fbc97-4bed-5078-af07-9141ba07c9f3", true}, -// {"987fbc97-4bed-5078-9f07-9141ba07c9f3", true}, -// } - -// for i, test := range tests { - -// err := validate.Field(test.param, "uuid5") - -// if test.expected == true { -// if !IsEqual(t, err, nil) { -// t.Fatalf("Index: %d UUID5 failed Error: %s", i, err) -// } -// } else { -// if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "uuid5") { -// t.Fatalf("Index: %d UUID5 failed Error: %s", i, err) -// } -// } -// } -// } - -// func TestUUID4Validation(t *testing.T) { -// tests := []struct { -// param string -// expected bool -// }{ -// {"", false}, -// {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, -// {"a987fbc9-4bed-5078-af07-9141ba07c9f3", false}, -// {"934859", false}, -// {"57b73598-8764-4ad0-a76a-679bb6640eb1", true}, -// {"625e63f3-58f5-40b7-83a1-a72ad31acffb", true}, -// } - -// for i, test := range tests { - -// err := validate.Field(test.param, "uuid4") - -// if test.expected == true { -// if !IsEqual(t, err, nil) { -// t.Fatalf("Index: %d UUID4 failed Error: %s", i, err) -// } -// } else { -// if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "uuid4") { -// t.Fatalf("Index: %d UUID4 failed Error: %s", i, err) -// } -// } -// } -// } - -// func TestUUID3Validation(t *testing.T) { -// tests := []struct { -// param string -// expected bool -// }{ -// {"", false}, -// {"412452646", false}, -// {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, -// {"a987fbc9-4bed-4078-8f07-9141ba07c9f3", false}, -// {"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true}, -// } - -// for i, test := range tests { - -// err := validate.Field(test.param, "uuid3") - -// if test.expected == true { -// if !IsEqual(t, err, nil) { -// t.Fatalf("Index: %d UUID3 failed Error: %s", i, err) -// } -// } else { -// if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "uuid3") { -// t.Fatalf("Index: %d UUID3 failed Error: %s", i, err) -// } -// } -// } -// } - -// func TestUUIDValidation(t *testing.T) { -// tests := []struct { -// param string -// expected bool -// }{ -// {"", false}, -// {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, -// {"a987fbc9-4bed-3078-cf07-9141ba07c9f3xxx", false}, -// {"a987fbc94bed3078cf079141ba07c9f3", false}, -// {"934859", false}, -// {"987fbc9-4bed-3078-cf07a-9141ba07c9f3", false}, -// {"aaaaaaaa-1111-1111-aaag-111111111111", false}, -// {"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true}, -// } - -// for i, test := range tests { - -// err := validate.Field(test.param, "uuid") - -// if test.expected == true { -// if !IsEqual(t, err, nil) { -// t.Fatalf("Index: %d UUID failed Error: %s", i, err) -// } -// } else { -// if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "uuid") { -// t.Fatalf("Index: %d UUID failed Error: %s", i, err) -// } -// } -// } -// } - -// func TestISBNValidation(t *testing.T) { -// tests := []struct { -// param string -// expected bool -// }{ -// {"", false}, -// {"foo", false}, -// {"3836221195", true}, -// {"1-61729-085-8", true}, -// {"3 423 21412 0", true}, -// {"3 401 01319 X", true}, -// {"9784873113685", true}, -// {"978-4-87311-368-5", true}, -// {"978 3401013190", true}, -// {"978-3-8362-2119-1", true}, -// } - -// for i, test := range tests { - -// err := validate.Field(test.param, "isbn") - -// if test.expected == true { -// if !IsEqual(t, err, nil) { -// t.Fatalf("Index: %d ISBN failed Error: %s", i, err) -// } -// } else { -// if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "isbn") { -// t.Fatalf("Index: %d ISBN failed Error: %s", i, err) -// } -// } -// } -// } - -// func TestISBN13Validation(t *testing.T) { -// tests := []struct { -// param string -// expected bool -// }{ -// {"", false}, -// {"foo", false}, -// {"3-8362-2119-5", false}, -// {"01234567890ab", false}, -// {"978 3 8362 2119 0", false}, -// {"9784873113685", true}, -// {"978-4-87311-368-5", true}, -// {"978 3401013190", true}, -// {"978-3-8362-2119-1", true}, -// } - -// for i, test := range tests { - -// err := validate.Field(test.param, "isbn13") - -// if test.expected == true { -// if !IsEqual(t, err, nil) { -// t.Fatalf("Index: %d ISBN13 failed Error: %s", i, err) -// } -// } else { -// if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "isbn13") { -// t.Fatalf("Index: %d ISBN13 failed Error: %s", i, err) -// } -// } -// } -// } - -// func TestISBN10Validation(t *testing.T) { -// tests := []struct { -// param string -// expected bool -// }{ -// {"", false}, -// {"foo", false}, -// {"3423214121", false}, -// {"978-3836221191", false}, -// {"3-423-21412-1", false}, -// {"3 423 21412 1", false}, -// {"3836221195", true}, -// {"1-61729-085-8", true}, -// {"3 423 21412 0", true}, -// {"3 401 01319 X", true}, -// } - -// for i, test := range tests { - -// err := validate.Field(test.param, "isbn10") - -// if test.expected == true { -// if !IsEqual(t, err, nil) { -// t.Fatalf("Index: %d ISBN10 failed Error: %s", i, err) -// } -// } else { -// if IsEqual(t, err, nil) || !IsEqual(t, err.Tag, "isbn10") { -// t.Fatalf("Index: %d ISBN10 failed Error: %s", i, err) -// } -// } -// } -// } - -// func TestExcludesRuneValidation(t *testing.T) { - -// tests := []struct { -// Value string `validate:"excludesrune=☻"` -// Tag string -// ExpectedNil bool -// }{ -// {Value: "a☺b☻c☹d", Tag: "excludesrune=☻", ExpectedNil: false}, -// {Value: "abcd", Tag: "excludesrune=☻", ExpectedNil: true}, -// } - -// for i, s := range tests { -// err := validate.Field(s.Value, s.Tag) - -// if (s.ExpectedNil && err != nil) || (!s.ExpectedNil && err == nil) { -// t.Fatalf("Index: %d failed Error: %s", i, err) -// } - -// errs := validate.Struct(s) - -// if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { -// t.Fatalf("Index: %d failed Error: %s", i, errs) -// } -// } -// } - -// func TestExcludesAllValidation(t *testing.T) { - -// tests := []struct { -// Value string `validate:"excludesall=@!{}[]"` -// Tag string -// ExpectedNil bool -// }{ -// {Value: "abcd@!jfk", Tag: "excludesall=@!{}[]", ExpectedNil: false}, -// {Value: "abcdefg", Tag: "excludesall=@!{}[]", ExpectedNil: true}, -// } - -// for i, s := range tests { -// err := validate.Field(s.Value, s.Tag) - -// if (s.ExpectedNil && err != nil) || (!s.ExpectedNil && err == nil) { -// t.Fatalf("Index: %d failed Error: %s", i, err) -// } - -// errs := validate.Struct(s) - -// if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { -// t.Fatalf("Index: %d failed Error: %s", i, errs) -// } -// } - -// username := "joeybloggs " - -// err := validate.Field(username, "excludesall=@ ") -// NotEqual(t, err, nil) - -// excluded := "," - -// err = validate.Field(excluded, "excludesall=!@#$%^&*()_+.0x2C?") -// NotEqual(t, err, nil) - -// excluded = "=" - -// err = validate.Field(excluded, "excludesall=!@#$%^&*()_+.0x2C=?") -// NotEqual(t, err, nil) -// } - -// func TestExcludesValidation(t *testing.T) { - -// tests := []struct { -// Value string `validate:"excludes=@"` -// Tag string -// ExpectedNil bool -// }{ -// {Value: "abcd@!jfk", Tag: "excludes=@", ExpectedNil: false}, -// {Value: "abcdq!jfk", Tag: "excludes=@", ExpectedNil: true}, -// } - -// for i, s := range tests { -// err := validate.Field(s.Value, s.Tag) - -// if (s.ExpectedNil && err != nil) || (!s.ExpectedNil && err == nil) { -// t.Fatalf("Index: %d failed Error: %s", i, err) -// } - -// errs := validate.Struct(s) - -// if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { -// t.Fatalf("Index: %d failed Error: %s", i, errs) -// } -// } -// } - -// func TestContainsRuneValidation(t *testing.T) { - -// tests := []struct { -// Value string `validate:"containsrune=☻"` -// Tag string -// ExpectedNil bool -// }{ -// {Value: "a☺b☻c☹d", Tag: "containsrune=☻", ExpectedNil: true}, -// {Value: "abcd", Tag: "containsrune=☻", ExpectedNil: false}, -// } - -// for i, s := range tests { -// err := validate.Field(s.Value, s.Tag) - -// if (s.ExpectedNil && err != nil) || (!s.ExpectedNil && err == nil) { -// t.Fatalf("Index: %d failed Error: %s", i, err) -// } + errs = validate.FieldWithValue(uint(1), uint(5), "gtfield") + Equal(t, errs, nil) -// errs := validate.Struct(s) + errs = validate.FieldWithValue(uint(5), uint(1), "gtfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtfield") -// if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { -// t.Fatalf("Index: %d failed Error: %s", i, errs) -// } -// } -// } - -// func TestContainsAnyValidation(t *testing.T) { - -// tests := []struct { -// Value string `validate:"containsany=@!{}[]"` -// Tag string -// ExpectedNil bool -// }{ -// {Value: "abcd@!jfk", Tag: "containsany=@!{}[]", ExpectedNil: true}, -// {Value: "abcdefg", Tag: "containsany=@!{}[]", ExpectedNil: false}, -// } - -// for i, s := range tests { -// err := validate.Field(s.Value, s.Tag) + type FloatTest struct { + Val1 float64 `validate:"required"` + Val2 float64 `validate:"required,gtfield=Val1"` + } -// if (s.ExpectedNil && err != nil) || (!s.ExpectedNil && err == nil) { -// t.Fatalf("Index: %d failed Error: %s", i, err) -// } + floatTest := &FloatTest{ + Val1: 1, + Val2: 5, + } -// errs := validate.Struct(s) + errs = validate.Struct(floatTest) + Equal(t, errs, nil) -// if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { -// t.Fatalf("Index: %d failed Error: %s", i, errs) -// } -// } -// } + floatTest = &FloatTest{ + Val1: 5, + Val2: 1, + } -// func TestContainsValidation(t *testing.T) { + errs = validate.Struct(floatTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "FloatTest.Val2", "Val2", "gtfield") -// tests := []struct { -// Value string `validate:"contains=@"` -// Tag string -// ExpectedNil bool -// }{ -// {Value: "abcd@!jfk", Tag: "contains=@", ExpectedNil: true}, -// {Value: "abcdq!jfk", Tag: "contains=@", ExpectedNil: false}, -// } + errs = validate.FieldWithValue(float32(1), float32(5), "gtfield") + Equal(t, errs, nil) -// for i, s := range tests { -// err := validate.Field(s.Value, s.Tag) - -// if (s.ExpectedNil && err != nil) || (!s.ExpectedNil && err == nil) { -// t.Fatalf("Index: %d failed Error: %s", i, err) -// } - -// errs := validate.Struct(s) - -// if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { -// t.Fatalf("Index: %d failed Error: %s", i, errs) -// } -// } -// } - -// func TestIsNeFieldValidation(t *testing.T) { - -// var j uint64 -// var k float64 -// s := "abcd" -// i := 1 -// j = 1 -// k = 1.543 -// arr := []string{"test"} -// now := time.Now().UTC() - -// var j2 uint64 -// var k2 float64 -// s2 := "abcdef" -// i2 := 3 -// j2 = 2 -// k2 = 1.5434456 -// arr2 := []string{"test", "test2"} -// arr3 := []string{"test"} -// now2 := now + errs = validate.FieldWithValue(float32(5), float32(1), "gtfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtfield") -// err := validate.FieldWithValue(s, s2, "nefield") -// Equal(t, err, nil) - -// err = validate.FieldWithValue(i2, i, "nefield") -// Equal(t, err, nil) - -// err = validate.FieldWithValue(j2, j, "nefield") -// Equal(t, err, nil) - -// err = validate.FieldWithValue(k2, k, "nefield") -// Equal(t, err, nil) - -// err = validate.FieldWithValue(arr2, arr, "nefield") -// Equal(t, err, nil) - -// err = validate.FieldWithValue(now2, now, "nefield") -// NotEqual(t, err, nil) - -// err = validate.FieldWithValue(arr3, arr, "nefield") -// NotEqual(t, err, nil) - -// type Test struct { -// Start *time.Time `validate:"nefield=End"` -// End *time.Time -// } - -// sv := &Test{ -// Start: &now, -// End: &now, -// } - -// errs := validate.Struct(sv) -// NotEqual(t, errs, nil) + PanicMatches(t, func() { validate.FieldWithValue(nil, 1, "gtfield") }, "struct not passed for cross validation") + PanicMatches(t, func() { validate.FieldWithValue(5, "T", "gtfield") }, "Bad field type string") + PanicMatches(t, func() { validate.FieldWithValue(5, start, "gtfield") }, "Bad Top Level field type") -// now3 := time.Now().UTC() + type TimeTest2 struct { + Start *time.Time `validate:"required"` + End *time.Time `validate:"required,gtfield=NonExistantField"` + } -// sv = &Test{ -// Start: &now, -// End: &now3, -// } + timeTest2 := &TimeTest2{ + Start: &start, + End: &end, + } -// errs = validate.Struct(sv) -// Equal(t, errs, nil) + PanicMatches(t, func() { validate.Struct(timeTest2) }, "Field \"NonExistantField\" not found in struct") +} -// channel := make(chan string) - -// PanicMatches(t, func() { validate.FieldWithValue(nil, 1, "nefield") }, "struct not passed for cross validation") -// PanicMatches(t, func() { validate.FieldWithValue(5, channel, "nefield") }, "Bad field type chan string") -// PanicMatches(t, func() { validate.FieldWithValue(5, now, "nefield") }, "Bad Top Level field type") +func TestLtField(t *testing.T) { -// type Test2 struct { -// Start *time.Time `validate:"nefield=NonExistantField"` -// End *time.Time -// } + type TimeTest struct { + Start *time.Time `validate:"required,lt,ltfield=End"` + End *time.Time `validate:"required,lt"` + } -// sv2 := &Test2{ -// Start: &now, -// End: &now, -// } + now := time.Now() + start := now.Add(time.Hour * 24 * -1 * 2) + end := start.Add(time.Hour * 24) -// PanicMatches(t, func() { validate.Struct(sv2) }, "Field \"NonExistantField\" not found in struct") -// } + timeTest := &TimeTest{ + Start: &start, + End: &end, + } -// func TestIsNeValidation(t *testing.T) { + errs := validate.Struct(timeTest) + Equal(t, errs, nil) -// var j uint64 -// var k float64 -// s := "abcdef" -// i := 3 -// j = 2 -// k = 1.5434 -// arr := []string{"test"} -// now := time.Now().UTC() + timeTest = &TimeTest{ + Start: &end, + End: &start, + } -// err := validate.Field(s, "ne=abcd") -// Equal(t, err, nil) + errs = validate.Struct(timeTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "TimeTest.Start", "Start", "ltfield") -// err = validate.Field(i, "ne=1") -// Equal(t, err, nil) + errs = validate.FieldWithValue(&end, &start, "ltfield") + Equal(t, errs, nil) -// err = validate.Field(j, "ne=1") -// Equal(t, err, nil) + errs = validate.FieldWithValue(&start, &end, "ltfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltfield") -// err = validate.Field(k, "ne=1.543") -// Equal(t, err, nil) + type IntTest struct { + Val1 int `validate:"required"` + Val2 int `validate:"required,ltfield=Val1"` + } -// err = validate.Field(arr, "ne=2") -// Equal(t, err, nil) + intTest := &IntTest{ + Val1: 5, + Val2: 1, + } -// err = validate.Field(arr, "ne=1") -// NotEqual(t, err, nil) + errs = validate.Struct(intTest) + Equal(t, errs, nil) -// PanicMatches(t, func() { validate.Field(now, "ne=now") }, "Bad field type time.Time") -// } + intTest = &IntTest{ + Val1: 1, + Val2: 5, + } -// func TestIsEqFieldValidation(t *testing.T) { + errs = validate.Struct(intTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "IntTest.Val2", "Val2", "ltfield") -// var j uint64 -// var k float64 -// s := "abcd" -// i := 1 -// j = 1 -// k = 1.543 -// arr := []string{"test"} -// now := time.Now().UTC() + errs = validate.FieldWithValue(int(5), int(1), "ltfield") + Equal(t, errs, nil) -// var j2 uint64 -// var k2 float64 -// s2 := "abcd" -// i2 := 1 -// j2 = 1 -// k2 = 1.543 -// arr2 := []string{"test"} -// arr3 := []string{"test", "test2"} -// now2 := now + errs = validate.FieldWithValue(int(1), int(5), "ltfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltfield") -// err := validate.FieldWithValue(s, s2, "eqfield") -// Equal(t, err, nil) + type UIntTest struct { + Val1 uint `validate:"required"` + Val2 uint `validate:"required,ltfield=Val1"` + } -// err = validate.FieldWithValue(i2, i, "eqfield") -// Equal(t, err, nil) + uIntTest := &UIntTest{ + Val1: 5, + Val2: 1, + } -// err = validate.FieldWithValue(j2, j, "eqfield") -// Equal(t, err, nil) + errs = validate.Struct(uIntTest) + Equal(t, errs, nil) -// err = validate.FieldWithValue(k2, k, "eqfield") -// Equal(t, err, nil) + uIntTest = &UIntTest{ + Val1: 1, + Val2: 5, + } -// err = validate.FieldWithValue(arr2, arr, "eqfield") -// Equal(t, err, nil) + errs = validate.Struct(uIntTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "UIntTest.Val2", "Val2", "ltfield") -// err = validate.FieldWithValue(now2, now, "eqfield") -// Equal(t, err, nil) + errs = validate.FieldWithValue(uint(5), uint(1), "ltfield") + Equal(t, errs, nil) -// err = validate.FieldWithValue(arr3, arr, "eqfield") -// NotEqual(t, err, nil) + errs = validate.FieldWithValue(uint(1), uint(5), "ltfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltfield") -// type Test struct { -// Start *time.Time `validate:"eqfield=End"` -// End *time.Time -// } + type FloatTest struct { + Val1 float64 `validate:"required"` + Val2 float64 `validate:"required,ltfield=Val1"` + } -// sv := &Test{ -// Start: &now, -// End: &now, -// } + floatTest := &FloatTest{ + Val1: 5, + Val2: 1, + } -// errs := validate.Struct(sv) -// Equal(t, errs, nil) + errs = validate.Struct(floatTest) + Equal(t, errs, nil) -// now3 := time.Now().UTC() + floatTest = &FloatTest{ + Val1: 1, + Val2: 5, + } -// sv = &Test{ -// Start: &now, -// End: &now3, -// } + errs = validate.Struct(floatTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "FloatTest.Val2", "Val2", "ltfield") -// errs = validate.Struct(sv) -// NotEqual(t, errs, nil) + errs = validate.FieldWithValue(float32(5), float32(1), "ltfield") + Equal(t, errs, nil) -// channel := make(chan string) + errs = validate.FieldWithValue(float32(1), float32(5), "ltfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltfield") -// PanicMatches(t, func() { validate.FieldWithValue(nil, 1, "eqfield") }, "struct not passed for cross validation") -// PanicMatches(t, func() { validate.FieldWithValue(5, channel, "eqfield") }, "Bad field type chan string") -// PanicMatches(t, func() { validate.FieldWithValue(5, now, "eqfield") }, "Bad Top Level field type") + PanicMatches(t, func() { validate.FieldWithValue(nil, 5, "ltfield") }, "struct not passed for cross validation") + PanicMatches(t, func() { validate.FieldWithValue(1, "T", "ltfield") }, "Bad field type string") + PanicMatches(t, func() { validate.FieldWithValue(1, end, "ltfield") }, "Bad Top Level field type") -// type Test2 struct { -// Start *time.Time `validate:"eqfield=NonExistantField"` -// End *time.Time -// } + type TimeTest2 struct { + Start *time.Time `validate:"required"` + End *time.Time `validate:"required,ltfield=NonExistantField"` + } -// sv2 := &Test2{ -// Start: &now, -// End: &now, -// } + timeTest2 := &TimeTest2{ + Start: &end, + End: &start, + } -// PanicMatches(t, func() { validate.Struct(sv2) }, "Field \"NonExistantField\" not found in struct") -// } + PanicMatches(t, func() { validate.Struct(timeTest2) }, "Field \"NonExistantField\" not found in struct") +} -// func TestIsEqValidation(t *testing.T) { +func TestLteField(t *testing.T) { -// var j uint64 -// var k float64 -// s := "abcd" -// i := 1 -// j = 1 -// k = 1.543 -// arr := []string{"test"} -// now := time.Now().UTC() + type TimeTest struct { + Start *time.Time `validate:"required,lte,ltefield=End"` + End *time.Time `validate:"required,lte"` + } -// err := validate.Field(s, "eq=abcd") -// Equal(t, err, nil) + now := time.Now() + start := now.Add(time.Hour * 24 * -1 * 2) + end := start.Add(time.Hour * 24) -// err = validate.Field(i, "eq=1") -// Equal(t, err, nil) + timeTest := &TimeTest{ + Start: &start, + End: &end, + } -// err = validate.Field(j, "eq=1") -// Equal(t, err, nil) + errs := validate.Struct(timeTest) + Equal(t, errs, nil) -// err = validate.Field(k, "eq=1.543") -// Equal(t, err, nil) + timeTest = &TimeTest{ + Start: &end, + End: &start, + } -// err = validate.Field(arr, "eq=1") -// Equal(t, err, nil) + errs = validate.Struct(timeTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "TimeTest.Start", "Start", "ltefield") -// err = validate.Field(arr, "eq=2") -// NotEqual(t, err, nil) + errs = validate.FieldWithValue(&end, &start, "ltefield") + Equal(t, errs, nil) -// PanicMatches(t, func() { validate.Field(now, "eq=now") }, "Bad field type time.Time") -// } + errs = validate.FieldWithValue(&start, &end, "ltefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltefield") -// func TestBase64Validation(t *testing.T) { + type IntTest struct { + Val1 int `validate:"required"` + Val2 int `validate:"required,ltefield=Val1"` + } -// s := "dW5pY29ybg==" + intTest := &IntTest{ + Val1: 5, + Val2: 1, + } -// err := validate.Field(s, "base64") -// Equal(t, err, nil) + errs = validate.Struct(intTest) + Equal(t, errs, nil) -// s = "dGhpIGlzIGEgdGVzdCBiYXNlNjQ=" -// err = validate.Field(s, "base64") -// Equal(t, err, nil) + intTest = &IntTest{ + Val1: 1, + Val2: 5, + } -// s = "" -// err = validate.Field(s, "base64") -// NotEqual(t, err, nil) + errs = validate.Struct(intTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "IntTest.Val2", "Val2", "ltefield") -// s = "dW5pY29ybg== foo bar" -// err = validate.Field(s, "base64") -// NotEqual(t, err, nil) -// } + errs = validate.FieldWithValue(int(5), int(1), "ltefield") + Equal(t, errs, nil) -// func TestStructOnlyValidation(t *testing.T) { + errs = validate.FieldWithValue(int(1), int(5), "ltefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltefield") -// type Inner struct { -// Test string `validate:"len=5"` -// } + type UIntTest struct { + Val1 uint `validate:"required"` + Val2 uint `validate:"required,ltefield=Val1"` + } -// type Outer struct { -// InnerStruct *Inner `validate:"required,structonly"` -// } + uIntTest := &UIntTest{ + Val1: 5, + Val2: 1, + } -// outer := &Outer{ -// InnerStruct: nil, -// } + errs = validate.Struct(uIntTest) + Equal(t, errs, nil) -// errs := validate.Struct(outer) -// NotEqual(t, errs, nil) + uIntTest = &UIntTest{ + Val1: 1, + Val2: 5, + } -// inner := &Inner{ -// Test: "1234", -// } + errs = validate.Struct(uIntTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "UIntTest.Val2", "Val2", "ltefield") -// outer = &Outer{ -// InnerStruct: inner, -// } + errs = validate.FieldWithValue(uint(5), uint(1), "ltefield") + Equal(t, errs, nil) -// errs = validate.Struct(outer) -// Equal(t, errs, nil) -// } + errs = validate.FieldWithValue(uint(1), uint(5), "ltefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltefield") -// func TestGtField(t *testing.T) { + type FloatTest struct { + Val1 float64 `validate:"required"` + Val2 float64 `validate:"required,ltefield=Val1"` + } -// type TimeTest struct { -// Start *time.Time `validate:"required,gt"` -// End *time.Time `validate:"required,gt,gtfield=Start"` -// } + floatTest := &FloatTest{ + Val1: 5, + Val2: 1, + } -// now := time.Now() -// start := now.Add(time.Hour * 24) -// end := start.Add(time.Hour * 24) + errs = validate.Struct(floatTest) + Equal(t, errs, nil) -// timeTest := &TimeTest{ -// Start: &start, -// End: &end, -// } + floatTest = &FloatTest{ + Val1: 1, + Val2: 5, + } -// errs := validate.Struct(timeTest) -// Equal(t, errs, nil) + errs = validate.Struct(floatTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "FloatTest.Val2", "Val2", "ltefield") -// timeTest = &TimeTest{ -// Start: &end, -// End: &start, -// } + errs = validate.FieldWithValue(float32(5), float32(1), "ltefield") + Equal(t, errs, nil) -// errs2 := validate.Struct(timeTest).Flatten() -// NotEqual(t, errs2, nil) -// AssertMapFieldError(t, errs2, "End", "gtfield") + errs = validate.FieldWithValue(float32(1), float32(5), "ltefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltefield") -// err3 := validate.FieldWithValue(&start, &end, "gtfield") -// Equal(t, err3, nil) + PanicMatches(t, func() { validate.FieldWithValue(nil, 5, "ltefield") }, "struct not passed for cross validation") + PanicMatches(t, func() { validate.FieldWithValue(1, "T", "ltefield") }, "Bad field type string") + PanicMatches(t, func() { validate.FieldWithValue(1, end, "ltefield") }, "Bad Top Level field type") -// err3 = validate.FieldWithValue(&end, &start, "gtfield") -// NotEqual(t, err3, nil) -// Equal(t, err3.Tag, "gtfield") + type TimeTest2 struct { + Start *time.Time `validate:"required"` + End *time.Time `validate:"required,ltefield=NonExistantField"` + } -// type IntTest struct { -// Val1 int `validate:"required"` -// Val2 int `validate:"required,gtfield=Val1"` -// } + timeTest2 := &TimeTest2{ + Start: &end, + End: &start, + } -// intTest := &IntTest{ -// Val1: 1, -// Val2: 5, -// } + PanicMatches(t, func() { validate.Struct(timeTest2) }, "Field \"NonExistantField\" not found in struct") +} -// errs = validate.Struct(intTest) -// Equal(t, errs, nil) +func TestGteField(t *testing.T) { -// intTest = &IntTest{ -// Val1: 5, -// Val2: 1, -// } + type TimeTest struct { + Start *time.Time `validate:"required,gte"` + End *time.Time `validate:"required,gte,gtefield=Start"` + } -// errs2 = validate.Struct(intTest).Flatten() -// NotEqual(t, errs2, nil) -// AssertMapFieldError(t, errs2, "Val2", "gtfield") + now := time.Now() + start := now.Add(time.Hour * 24) + end := start.Add(time.Hour * 24) -// err3 = validate.FieldWithValue(int(1), int(5), "gtfield") -// Equal(t, err3, nil) + timeTest := &TimeTest{ + Start: &start, + End: &end, + } -// err3 = validate.FieldWithValue(int(5), int(1), "gtfield") -// NotEqual(t, err3, nil) -// Equal(t, err3.Tag, "gtfield") + errs := validate.Struct(timeTest) + Equal(t, errs, nil) -// type UIntTest struct { -// Val1 uint `validate:"required"` -// Val2 uint `validate:"required,gtfield=Val1"` -// } + timeTest = &TimeTest{ + Start: &end, + End: &start, + } -// uIntTest := &UIntTest{ -// Val1: 1, -// Val2: 5, -// } + errs = validate.Struct(timeTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "TimeTest.End", "End", "gtefield") -// errs = validate.Struct(uIntTest) -// Equal(t, errs, nil) + errs = validate.FieldWithValue(&start, &end, "gtefield") + Equal(t, errs, nil) -// uIntTest = &UIntTest{ -// Val1: 5, -// Val2: 1, -// } - -// errs2 = validate.Struct(uIntTest).Flatten() -// NotEqual(t, errs2, nil) -// AssertMapFieldError(t, errs2, "Val2", "gtfield") - -// err3 = validate.FieldWithValue(uint(1), uint(5), "gtfield") -// Equal(t, err3, nil) - -// err3 = validate.FieldWithValue(uint(5), uint(1), "gtfield") -// NotEqual(t, err3, nil) -// Equal(t, err3.Tag, "gtfield") - -// type FloatTest struct { -// Val1 float64 `validate:"required"` -// Val2 float64 `validate:"required,gtfield=Val1"` -// } - -// floatTest := &FloatTest{ -// Val1: 1, -// Val2: 5, -// } - -// errs = validate.Struct(floatTest) -// Equal(t, errs, nil) - -// floatTest = &FloatTest{ -// Val1: 5, -// Val2: 1, -// } - -// errs2 = validate.Struct(floatTest).Flatten() -// NotEqual(t, errs2, nil) -// AssertMapFieldError(t, errs2, "Val2", "gtfield") - -// err3 = validate.FieldWithValue(float32(1), float32(5), "gtfield") -// Equal(t, err3, nil) - -// err3 = validate.FieldWithValue(float32(5), float32(1), "gtfield") -// NotEqual(t, err3, nil) -// Equal(t, err3.Tag, "gtfield") - -// PanicMatches(t, func() { validate.FieldWithValue(nil, 1, "gtfield") }, "struct not passed for cross validation") -// PanicMatches(t, func() { validate.FieldWithValue(5, "T", "gtfield") }, "Bad field type string") -// PanicMatches(t, func() { validate.FieldWithValue(5, start, "gtfield") }, "Bad Top Level field type") - -// type TimeTest2 struct { -// Start *time.Time `validate:"required"` -// End *time.Time `validate:"required,gtfield=NonExistantField"` -// } - -// timeTest2 := &TimeTest2{ -// Start: &start, -// End: &end, -// } - -// PanicMatches(t, func() { validate.Struct(timeTest2) }, "Field \"NonExistantField\" not found in struct") -// } - -// func TestLtField(t *testing.T) { - -// type TimeTest struct { -// Start *time.Time `validate:"required,lt,ltfield=End"` -// End *time.Time `validate:"required,lt"` -// } - -// now := time.Now() -// start := now.Add(time.Hour * 24 * -1 * 2) -// end := start.Add(time.Hour * 24) - -// timeTest := &TimeTest{ -// Start: &start, -// End: &end, -// } - -// errs := validate.Struct(timeTest) -// Equal(t, errs, nil) - -// timeTest = &TimeTest{ -// Start: &end, -// End: &start, -// } - -// errs2 := validate.Struct(timeTest).Flatten() -// NotEqual(t, errs2, nil) -// AssertMapFieldError(t, errs2, "Start", "ltfield") - -// err3 := validate.FieldWithValue(&end, &start, "ltfield") -// Equal(t, err3, nil) - -// err3 = validate.FieldWithValue(&start, &end, "ltfield") -// NotEqual(t, err3, nil) -// Equal(t, err3.Tag, "ltfield") - -// type IntTest struct { -// Val1 int `validate:"required"` -// Val2 int `validate:"required,ltfield=Val1"` -// } - -// intTest := &IntTest{ -// Val1: 5, -// Val2: 1, -// } - -// errs = validate.Struct(intTest) -// Equal(t, errs, nil) - -// intTest = &IntTest{ -// Val1: 1, -// Val2: 5, -// } - -// errs2 = validate.Struct(intTest).Flatten() -// NotEqual(t, errs2, nil) -// AssertMapFieldError(t, errs2, "Val2", "ltfield") - -// err3 = validate.FieldWithValue(int(5), int(1), "ltfield") -// Equal(t, err3, nil) - -// err3 = validate.FieldWithValue(int(1), int(5), "ltfield") -// NotEqual(t, err3, nil) -// Equal(t, err3.Tag, "ltfield") + errs = validate.FieldWithValue(&end, &start, "gtefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtefield") -// type UIntTest struct { -// Val1 uint `validate:"required"` -// Val2 uint `validate:"required,ltfield=Val1"` -// } - -// uIntTest := &UIntTest{ -// Val1: 5, -// Val2: 1, -// } + type IntTest struct { + Val1 int `validate:"required"` + Val2 int `validate:"required,gtefield=Val1"` + } -// errs = validate.Struct(uIntTest) -// Equal(t, errs, nil) - -// uIntTest = &UIntTest{ -// Val1: 1, -// Val2: 5, -// } - -// errs2 = validate.Struct(uIntTest).Flatten() -// NotEqual(t, errs2, nil) -// AssertMapFieldError(t, errs2, "Val2", "ltfield") - -// err3 = validate.FieldWithValue(uint(5), uint(1), "ltfield") -// Equal(t, err3, nil) - -// err3 = validate.FieldWithValue(uint(1), uint(5), "ltfield") -// NotEqual(t, err3, nil) -// Equal(t, err3.Tag, "ltfield") - -// type FloatTest struct { -// Val1 float64 `validate:"required"` -// Val2 float64 `validate:"required,ltfield=Val1"` -// } - -// floatTest := &FloatTest{ -// Val1: 5, -// Val2: 1, -// } - -// errs = validate.Struct(floatTest) -// Equal(t, errs, nil) - -// floatTest = &FloatTest{ -// Val1: 1, -// Val2: 5, -// } - -// errs2 = validate.Struct(floatTest).Flatten() -// NotEqual(t, errs2, nil) -// AssertMapFieldError(t, errs2, "Val2", "ltfield") - -// err3 = validate.FieldWithValue(float32(5), float32(1), "ltfield") -// Equal(t, err3, nil) - -// err3 = validate.FieldWithValue(float32(1), float32(5), "ltfield") -// NotEqual(t, err3, nil) -// Equal(t, err3.Tag, "ltfield") - -// PanicMatches(t, func() { validate.FieldWithValue(nil, 5, "ltfield") }, "struct not passed for cross validation") -// PanicMatches(t, func() { validate.FieldWithValue(1, "T", "ltfield") }, "Bad field type string") -// PanicMatches(t, func() { validate.FieldWithValue(1, end, "ltfield") }, "Bad Top Level field type") - -// type TimeTest2 struct { -// Start *time.Time `validate:"required"` -// End *time.Time `validate:"required,ltfield=NonExistantField"` -// } - -// timeTest2 := &TimeTest2{ -// Start: &end, -// End: &start, -// } - -// PanicMatches(t, func() { validate.Struct(timeTest2) }, "Field \"NonExistantField\" not found in struct") -// } - -// func TestLteField(t *testing.T) { - -// type TimeTest struct { -// Start *time.Time `validate:"required,lte,ltefield=End"` -// End *time.Time `validate:"required,lte"` -// } - -// now := time.Now() -// start := now.Add(time.Hour * 24 * -1 * 2) -// end := start.Add(time.Hour * 24) - -// timeTest := &TimeTest{ -// Start: &start, -// End: &end, -// } - -// errs := validate.Struct(timeTest) -// Equal(t, errs, nil) - -// timeTest = &TimeTest{ -// Start: &end, -// End: &start, -// } - -// errs2 := validate.Struct(timeTest).Flatten() -// NotEqual(t, errs2, nil) -// AssertMapFieldError(t, errs2, "Start", "ltefield") - -// err3 := validate.FieldWithValue(&end, &start, "ltefield") -// Equal(t, err3, nil) - -// err3 = validate.FieldWithValue(&start, &end, "ltefield") -// NotEqual(t, err3, nil) -// Equal(t, err3.Tag, "ltefield") - -// type IntTest struct { -// Val1 int `validate:"required"` -// Val2 int `validate:"required,ltefield=Val1"` -// } - -// intTest := &IntTest{ -// Val1: 5, -// Val2: 1, -// } - -// errs = validate.Struct(intTest) -// Equal(t, errs, nil) - -// intTest = &IntTest{ -// Val1: 1, -// Val2: 5, -// } - -// errs2 = validate.Struct(intTest).Flatten() -// NotEqual(t, errs2, nil) -// AssertMapFieldError(t, errs2, "Val2", "ltefield") - -// err3 = validate.FieldWithValue(int(5), int(1), "ltefield") -// Equal(t, err3, nil) - -// err3 = validate.FieldWithValue(int(1), int(5), "ltefield") -// NotEqual(t, err3, nil) -// Equal(t, err3.Tag, "ltefield") + intTest := &IntTest{ + Val1: 1, + Val2: 5, + } -// type UIntTest struct { -// Val1 uint `validate:"required"` -// Val2 uint `validate:"required,ltefield=Val1"` -// } - -// uIntTest := &UIntTest{ -// Val1: 5, -// Val2: 1, -// } + errs = validate.Struct(intTest) + Equal(t, errs, nil) -// errs = validate.Struct(uIntTest) -// Equal(t, errs, nil) - -// uIntTest = &UIntTest{ -// Val1: 1, -// Val2: 5, -// } - -// errs2 = validate.Struct(uIntTest).Flatten() -// NotEqual(t, errs2, nil) -// AssertMapFieldError(t, errs2, "Val2", "ltefield") - -// err3 = validate.FieldWithValue(uint(5), uint(1), "ltefield") -// Equal(t, err3, nil) - -// err3 = validate.FieldWithValue(uint(1), uint(5), "ltefield") -// NotEqual(t, err3, nil) -// Equal(t, err3.Tag, "ltefield") - -// type FloatTest struct { -// Val1 float64 `validate:"required"` -// Val2 float64 `validate:"required,ltefield=Val1"` -// } - -// floatTest := &FloatTest{ -// Val1: 5, -// Val2: 1, -// } - -// errs = validate.Struct(floatTest) -// Equal(t, errs, nil) - -// floatTest = &FloatTest{ -// Val1: 1, -// Val2: 5, -// } - -// errs2 = validate.Struct(floatTest).Flatten() -// NotEqual(t, errs2, nil) -// AssertMapFieldError(t, errs2, "Val2", "ltefield") - -// err3 = validate.FieldWithValue(float32(5), float32(1), "ltefield") -// Equal(t, err3, nil) - -// err3 = validate.FieldWithValue(float32(1), float32(5), "ltefield") -// NotEqual(t, err3, nil) -// Equal(t, err3.Tag, "ltefield") - -// PanicMatches(t, func() { validate.FieldWithValue(nil, 5, "ltefield") }, "struct not passed for cross validation") -// PanicMatches(t, func() { validate.FieldWithValue(1, "T", "ltefield") }, "Bad field type string") -// PanicMatches(t, func() { validate.FieldWithValue(1, end, "ltefield") }, "Bad Top Level field type") - -// type TimeTest2 struct { -// Start *time.Time `validate:"required"` -// End *time.Time `validate:"required,ltefield=NonExistantField"` -// } - -// timeTest2 := &TimeTest2{ -// Start: &end, -// End: &start, -// } - -// PanicMatches(t, func() { validate.Struct(timeTest2) }, "Field \"NonExistantField\" not found in struct") -// } - -// func TestGteField(t *testing.T) { - -// type TimeTest struct { -// Start *time.Time `validate:"required,gte"` -// End *time.Time `validate:"required,gte,gtefield=Start"` -// } - -// now := time.Now() -// start := now.Add(time.Hour * 24) -// end := start.Add(time.Hour * 24) - -// timeTest := &TimeTest{ -// Start: &start, -// End: &end, -// } - -// errs := validate.Struct(timeTest) -// Equal(t, errs, nil) - -// timeTest = &TimeTest{ -// Start: &end, -// End: &start, -// } - -// errs2 := validate.Struct(timeTest).Flatten() -// NotEqual(t, errs2, nil) -// AssertMapFieldError(t, errs2, "End", "gtefield") - -// err3 := validate.FieldWithValue(&start, &end, "gtefield") -// Equal(t, err3, nil) - -// err3 = validate.FieldWithValue(&end, &start, "gtefield") -// NotEqual(t, err3, nil) -// Equal(t, err3.Tag, "gtefield") - -// type IntTest struct { -// Val1 int `validate:"required"` -// Val2 int `validate:"required,gtefield=Val1"` -// } - -// intTest := &IntTest{ -// Val1: 1, -// Val2: 5, -// } - -// errs = validate.Struct(intTest) -// Equal(t, errs, nil) + intTest = &IntTest{ + Val1: 5, + Val2: 1, + } -// intTest = &IntTest{ -// Val1: 5, -// Val2: 1, -// } + errs = validate.Struct(intTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "IntTest.Val2", "Val2", "gtefield") -// errs2 = validate.Struct(intTest).Flatten() -// NotEqual(t, errs2, nil) -// AssertMapFieldError(t, errs2, "Val2", "gtefield") + errs = validate.FieldWithValue(int(1), int(5), "gtefield") + Equal(t, errs, nil) -// err3 = validate.FieldWithValue(int(1), int(5), "gtefield") -// Equal(t, err3, nil) + errs = validate.FieldWithValue(int(5), int(1), "gtefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtefield") -// err3 = validate.FieldWithValue(int(5), int(1), "gtefield") -// NotEqual(t, err3, nil) -// Equal(t, err3.Tag, "gtefield") + type UIntTest struct { + Val1 uint `validate:"required"` + Val2 uint `validate:"required,gtefield=Val1"` + } -// type UIntTest struct { -// Val1 uint `validate:"required"` -// Val2 uint `validate:"required,gtefield=Val1"` -// } + uIntTest := &UIntTest{ + Val1: 1, + Val2: 5, + } -// uIntTest := &UIntTest{ -// Val1: 1, -// Val2: 5, -// } + errs = validate.Struct(uIntTest) + Equal(t, errs, nil) -// errs = validate.Struct(uIntTest) -// Equal(t, errs, nil) + uIntTest = &UIntTest{ + Val1: 5, + Val2: 1, + } -// uIntTest = &UIntTest{ -// Val1: 5, -// Val2: 1, -// } + errs = validate.Struct(uIntTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "UIntTest.Val2", "Val2", "gtefield") -// errs2 = validate.Struct(uIntTest).Flatten() -// NotEqual(t, errs2, nil) -// AssertMapFieldError(t, errs2, "Val2", "gtefield") + errs = validate.FieldWithValue(uint(1), uint(5), "gtefield") + Equal(t, errs, nil) -// err3 = validate.FieldWithValue(uint(1), uint(5), "gtefield") -// Equal(t, err3, nil) + errs = validate.FieldWithValue(uint(5), uint(1), "gtefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtefield") -// err3 = validate.FieldWithValue(uint(5), uint(1), "gtefield") -// NotEqual(t, err3, nil) -// Equal(t, err3.Tag, "gtefield") + type FloatTest struct { + Val1 float64 `validate:"required"` + Val2 float64 `validate:"required,gtefield=Val1"` + } -// type FloatTest struct { -// Val1 float64 `validate:"required"` -// Val2 float64 `validate:"required,gtefield=Val1"` -// } + floatTest := &FloatTest{ + Val1: 1, + Val2: 5, + } -// floatTest := &FloatTest{ -// Val1: 1, -// Val2: 5, -// } + errs = validate.Struct(floatTest) + Equal(t, errs, nil) -// errs = validate.Struct(floatTest) -// Equal(t, errs, nil) + floatTest = &FloatTest{ + Val1: 5, + Val2: 1, + } -// floatTest = &FloatTest{ -// Val1: 5, -// Val2: 1, -// } + errs = validate.Struct(floatTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "FloatTest.Val2", "Val2", "gtefield") -// errs2 = validate.Struct(floatTest).Flatten() -// NotEqual(t, errs2, nil) -// AssertMapFieldError(t, errs2, "Val2", "gtefield") + errs = validate.FieldWithValue(float32(1), float32(5), "gtefield") + Equal(t, errs, nil) -// err3 = validate.FieldWithValue(float32(1), float32(5), "gtefield") -// Equal(t, err3, nil) + errs = validate.FieldWithValue(float32(5), float32(1), "gtefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtefield") -// err3 = validate.FieldWithValue(float32(5), float32(1), "gtefield") -// NotEqual(t, err3, nil) -// Equal(t, err3.Tag, "gtefield") + PanicMatches(t, func() { validate.FieldWithValue(nil, 1, "gtefield") }, "struct not passed for cross validation") + PanicMatches(t, func() { validate.FieldWithValue(5, "T", "gtefield") }, "Bad field type string") + PanicMatches(t, func() { validate.FieldWithValue(5, start, "gtefield") }, "Bad Top Level field type") -// PanicMatches(t, func() { validate.FieldWithValue(nil, 1, "gtefield") }, "struct not passed for cross validation") -// PanicMatches(t, func() { validate.FieldWithValue(5, "T", "gtefield") }, "Bad field type string") -// PanicMatches(t, func() { validate.FieldWithValue(5, start, "gtefield") }, "Bad Top Level field type") + type TimeTest2 struct { + Start *time.Time `validate:"required"` + End *time.Time `validate:"required,gtefield=NonExistantField"` + } -// type TimeTest2 struct { -// Start *time.Time `validate:"required"` -// End *time.Time `validate:"required,gtefield=NonExistantField"` -// } + timeTest2 := &TimeTest2{ + Start: &start, + End: &end, + } -// timeTest2 := &TimeTest2{ -// Start: &start, -// End: &end, -// } + PanicMatches(t, func() { validate.Struct(timeTest2) }, "Field \"NonExistantField\" not found in struct") +} -// PanicMatches(t, func() { validate.Struct(timeTest2) }, "Field \"NonExistantField\" not found in struct") -// } +func TestValidateByTagAndValue(t *testing.T) { -// func TestValidateByTagAndValue(t *testing.T) { + val := "test" + field := "test" + errs := validate.FieldWithValue(val, field, "required") + Equal(t, errs, nil) -// val := "test" -// field := "test" -// err := validate.FieldWithValue(val, field, "required") -// Equal(t, err, nil) + fn := func(topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { -// fn := func(val interface{}, current interface{}, field interface{}, param string) bool { + return current.String() == field.String() + } -// return current.(string) == field.(string) -// } + validate.RegisterValidation("isequaltestfunc", fn) -// validate.AddFunction("isequaltestfunc", fn) + errs = validate.FieldWithValue(val, field, "isequaltestfunc") + Equal(t, errs, nil) -// err = validate.FieldWithValue(val, field, "isequaltestfunc") -// Equal(t, err, nil) + val = "unequal" -// val = "unequal" + errs = validate.FieldWithValue(val, field, "isequaltestfunc") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "isequaltestfunc") +} -// err = validate.FieldWithValue(val, field, "isequaltestfunc") -// NotEqual(t, err, nil) -// Equal(t, err.Tag, "isequaltestfunc") -// } +func TestAddFunctions(t *testing.T) { -// func TestAddFunctions(t *testing.T) { + fn := func(topStruct reflect.Value, currentStruct reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { -// fn := func(val interface{}, current interface{}, field interface{}, param string) bool { + return true + } -// return true -// } + config := Config{ + TagName: "validateme", + ValidationFuncs: BakedInValidators, + } -// validate := New("validateme", BakedInValidators) + validate := New(config) -// err := validate.AddFunction("new", fn) -// Equal(t, err, nil) + errs := validate.RegisterValidation("new", fn) + Equal(t, errs, nil) -// err = validate.AddFunction("", fn) -// NotEqual(t, err, nil) + errs = validate.RegisterValidation("", fn) + NotEqual(t, errs, nil) -// validate.AddFunction("new", nil) -// NotEqual(t, err, nil) + validate.RegisterValidation("new", nil) + NotEqual(t, errs, nil) -// err = validate.AddFunction("new", fn) -// Equal(t, err, nil) -// } + errs = validate.RegisterValidation("new", fn) + Equal(t, errs, nil) +} -// func TestChangeTag(t *testing.T) { +func TestChangeTag(t *testing.T) { -// validate := New("validateme", BakedInValidators) -// validate.SetTag("val") + config := Config{ + TagName: "val", + ValidationFuncs: BakedInValidators, + } + validate := New(config) -// type Test struct { -// Name string `val:"len=4"` -// } -// s := &Test{ -// Name: "TEST", -// } + type Test struct { + Name string `val:"len=4"` + } + s := &Test{ + Name: "TEST", + } -// err := validate.Struct(s) -// Equal(t, err, nil) -// } + errs := validate.Struct(s) + Equal(t, errs, nil) +} -// func TestUnexposedStruct(t *testing.T) { +func TestUnexposedStruct(t *testing.T) { -// type Test struct { -// Name string -// unexposed struct { -// A string `validate:"required"` -// } -// } + type Test struct { + Name string + unexposed struct { + A string `validate:"required"` + } + } -// s := &Test{ -// Name: "TEST", -// } + s := &Test{ + Name: "TEST", + } -// err := validate.Struct(s) -// Equal(t, err, nil) -// } + errs := validate.Struct(s) + Equal(t, errs, nil) +} -// func TestBadParams(t *testing.T) { +func TestBadParams(t *testing.T) { -// i := 1 -// err := validate.Field(i, "-") -// Equal(t, err, nil) + i := 1 + errs := validate.Field(i, "-") + Equal(t, errs, nil) -// PanicMatches(t, func() { validate.Field(i, "len=a") }, "strconv.ParseInt: parsing \"a\": invalid syntax") -// PanicMatches(t, func() { validate.Field(i, "len=a") }, "strconv.ParseInt: parsing \"a\": invalid syntax") + PanicMatches(t, func() { validate.Field(i, "len=a") }, "strconv.ParseInt: parsing \"a\": invalid syntax") + PanicMatches(t, func() { validate.Field(i, "len=a") }, "strconv.ParseInt: parsing \"a\": invalid syntax") -// var ui uint = 1 -// PanicMatches(t, func() { validate.Field(ui, "len=a") }, "strconv.ParseUint: parsing \"a\": invalid syntax") + var ui uint = 1 + PanicMatches(t, func() { validate.Field(ui, "len=a") }, "strconv.ParseUint: parsing \"a\": invalid syntax") -// f := 1.23 -// PanicMatches(t, func() { validate.Field(f, "len=a") }, "strconv.ParseFloat: parsing \"a\": invalid syntax") -// } + f := 1.23 + PanicMatches(t, func() { validate.Field(f, "len=a") }, "strconv.ParseFloat: parsing \"a\": invalid syntax") +} -// func TestLength(t *testing.T) { +func TestLength(t *testing.T) { -// i := true -// PanicMatches(t, func() { validate.Field(i, "len") }, "Bad field type bool") -// } + i := true + PanicMatches(t, func() { validate.Field(i, "len") }, "Bad field type bool") +} -// func TestIsGt(t *testing.T) { +func TestIsGt(t *testing.T) { -// myMap := map[string]string{} -// err := validate.Field(myMap, "gt=0") -// NotEqual(t, err, nil) + myMap := map[string]string{} + errs := validate.Field(myMap, "gt=0") + NotEqual(t, errs, nil) -// f := 1.23 -// err = validate.Field(f, "gt=5") -// NotEqual(t, err, nil) + f := 1.23 + errs = validate.Field(f, "gt=5") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gt") -// var ui uint = 5 -// err = validate.Field(ui, "gt=10") -// NotEqual(t, err, nil) + var ui uint = 5 + errs = validate.Field(ui, "gt=10") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gt") -// i := true -// PanicMatches(t, func() { validate.Field(i, "gt") }, "Bad field type bool") + i := true + PanicMatches(t, func() { validate.Field(i, "gt") }, "Bad field type bool") -// tm := time.Now().UTC() -// tm = tm.Add(time.Hour * 24) + tm := time.Now().UTC() + tm = tm.Add(time.Hour * 24) -// err = validate.Field(tm, "gt") -// Equal(t, err, nil) + errs = validate.Field(tm, "gt") + Equal(t, errs, nil) -// t2 := time.Now().UTC() + t2 := time.Now().UTC() -// err = validate.Field(t2, "gt") -// NotEqual(t, err, nil) -// Equal(t, err.Tag, "gt") + errs = validate.Field(t2, "gt") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gt") -// type Test struct { -// Now *time.Time `validate:"gt"` -// } -// s := &Test{ -// Now: &tm, -// } + type Test struct { + Now *time.Time `validate:"gt"` + } + s := &Test{ + Now: &tm, + } -// errs := validate.Struct(s) -// Equal(t, errs, nil) + errs = validate.Struct(s) + Equal(t, errs, nil) -// s = &Test{ -// Now: &t2, -// } + s = &Test{ + Now: &t2, + } -// errs = validate.Struct(s) -// NotEqual(t, errs, nil) -// } + errs = validate.Struct(s) + NotEqual(t, errs, nil) + AssertError(t, errs, "Test.Now", "Now", "gt") +} -// func TestIsGte(t *testing.T) { +func TestIsGte(t *testing.T) { -// i := true -// PanicMatches(t, func() { validate.Field(i, "gte") }, "Bad field type bool") + i := true + PanicMatches(t, func() { validate.Field(i, "gte") }, "Bad field type bool") -// t1 := time.Now().UTC() -// t1 = t1.Add(time.Hour * 24) + t1 := time.Now().UTC() + t1 = t1.Add(time.Hour * 24) -// err := validate.Field(t1, "gte") -// Equal(t, err, nil) + errs := validate.Field(t1, "gte") + Equal(t, errs, nil) -// t2 := time.Now().UTC() + t2 := time.Now().UTC() -// err = validate.Field(t2, "gte") -// NotEqual(t, err, nil) -// Equal(t, err.Tag, "gte") -// Equal(t, err.Type, reflect.TypeOf(time.Time{})) + errs = validate.Field(t2, "gte") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gte") -// type Test struct { -// Now *time.Time `validate:"gte"` -// } -// s := &Test{ -// Now: &t1, -// } + type Test struct { + Now *time.Time `validate:"gte"` + } + s := &Test{ + Now: &t1, + } -// errs := validate.Struct(s) -// Equal(t, errs, nil) + errs = validate.Struct(s) + Equal(t, errs, nil) -// s = &Test{ -// Now: &t2, -// } + s = &Test{ + Now: &t2, + } -// errs = validate.Struct(s) -// NotEqual(t, errs, nil) -// } + errs = validate.Struct(s) + NotEqual(t, errs, nil) + AssertError(t, errs, "Test.Now", "Now", "gte") +} -// func TestIsLt(t *testing.T) { +func TestIsLt(t *testing.T) { -// myMap := map[string]string{} -// err := validate.Field(myMap, "lt=0") -// NotEqual(t, err, nil) + myMap := map[string]string{} + errs := validate.Field(myMap, "lt=0") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "lt") -// f := 1.23 -// err = validate.Field(f, "lt=0") -// NotEqual(t, err, nil) + f := 1.23 + errs = validate.Field(f, "lt=0") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "lt") -// var ui uint = 5 -// err = validate.Field(ui, "lt=0") -// NotEqual(t, err, nil) + var ui uint = 5 + errs = validate.Field(ui, "lt=0") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "lt") -// i := true -// PanicMatches(t, func() { validate.Field(i, "lt") }, "Bad field type bool") + i := true + PanicMatches(t, func() { validate.Field(i, "lt") }, "Bad field type bool") -// t1 := time.Now().UTC() + t1 := time.Now().UTC() -// err = validate.Field(t1, "lt") -// Equal(t, err, nil) + errs = validate.Field(t1, "lt") + Equal(t, errs, nil) -// t2 := time.Now().UTC() -// t2 = t2.Add(time.Hour * 24) + t2 := time.Now().UTC() + t2 = t2.Add(time.Hour * 24) -// err = validate.Field(t2, "lt") -// NotEqual(t, err, nil) -// Equal(t, err.Tag, "lt") + errs = validate.Field(t2, "lt") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "lt") -// type Test struct { -// Now *time.Time `validate:"lt"` -// } + type Test struct { + Now *time.Time `validate:"lt"` + } -// s := &Test{ -// Now: &t1, -// } + s := &Test{ + Now: &t1, + } -// errs := validate.Struct(s) -// Equal(t, errs, nil) + errs = validate.Struct(s) + Equal(t, errs, nil) -// s = &Test{ -// Now: &t2, -// } + s = &Test{ + Now: &t2, + } -// errs = validate.Struct(s) -// NotEqual(t, errs, nil) -// } + errs = validate.Struct(s) + NotEqual(t, errs, nil) + AssertError(t, errs, "Test.Now", "Now", "lt") +} -// func TestIsLte(t *testing.T) { +func TestIsLte(t *testing.T) { -// i := true -// PanicMatches(t, func() { validate.Field(i, "lte") }, "Bad field type bool") + i := true + PanicMatches(t, func() { validate.Field(i, "lte") }, "Bad field type bool") -// t1 := time.Now().UTC() + t1 := time.Now().UTC() -// err := validate.Field(t1, "lte") -// Equal(t, err, nil) + errs := validate.Field(t1, "lte") + Equal(t, errs, nil) -// t2 := time.Now().UTC() -// t2 = t2.Add(time.Hour * 24) + t2 := time.Now().UTC() + t2 = t2.Add(time.Hour * 24) -// err = validate.Field(t2, "lte") -// NotEqual(t, err, nil) -// Equal(t, err.Tag, "lte") + errs = validate.Field(t2, "lte") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "lte") -// type Test struct { -// Now *time.Time `validate:"lte"` -// } + type Test struct { + Now *time.Time `validate:"lte"` + } -// s := &Test{ -// Now: &t1, -// } + s := &Test{ + Now: &t1, + } -// errs := validate.Struct(s) -// Equal(t, errs, nil) + errs = validate.Struct(s) + Equal(t, errs, nil) -// s = &Test{ -// Now: &t2, -// } + s = &Test{ + Now: &t2, + } -// errs = validate.Struct(s) -// NotEqual(t, errs, nil) -// } + errs = validate.Struct(s) + NotEqual(t, errs, nil) +} func TestUrl(t *testing.T) { @@ -3138,13 +2763,11 @@ func TestOrTag(t *testing.T) { s = "this ain't right" errs = validate.Field(s, "rgb|rgba") NotEqual(t, errs, nil) - // Equal(t, err.Tag, "rgb|rgba") AssertError(t, errs, "", "", "rgb|rgba") s = "this ain't right" errs = validate.Field(s, "rgb|rgba|len=10") NotEqual(t, errs, nil) - // Equal(t, err.Tag, "rgb|rgba|len") AssertError(t, errs, "", "", "rgb|rgba|len") s = "this is right"