Finished converting baked in functions & some updates

completed all validations function conversion.
updated omitempty check to continue if all ok instead of
passing tag to be validated.
pull/114/head
joeybloggs 10 years ago
parent 68ba87af24
commit 019c5fc4ac
  1. 1071
      baked_in.go
  2. 238
      benchmarks_test.go
  3. 6
      regexes.go
  4. 58
      validator.go

File diff suppressed because it is too large Load Diff

@ -42,122 +42,122 @@ func BenchmarkTemplateParallelSimple(b *testing.B) {
})
}
// func BenchmarkValidateStructLarge(b *testing.B) {
// tFail := &TestString{
// Required: "",
// Len: "",
// Min: "",
// Max: "12345678901",
// MinMax: "",
// Lt: "0123456789",
// Lte: "01234567890",
// Gt: "1",
// Gte: "1",
// OmitEmpty: "12345678901",
// Sub: &SubTest{
// Test: "",
// },
// Anonymous: struct {
// A string `validate:"required"`
// }{
// A: "",
// },
// Iface: &Impl{
// F: "12",
// },
// }
// tSuccess := &TestString{
// Required: "Required",
// Len: "length==10",
// Min: "min=1",
// Max: "1234567890",
// MinMax: "12345",
// Lt: "012345678",
// Lte: "0123456789",
// Gt: "01234567890",
// Gte: "0123456789",
// OmitEmpty: "",
// Sub: &SubTest{
// Test: "1",
// },
// SubIgnore: &SubTest{
// Test: "",
// },
// Anonymous: struct {
// A string `validate:"required"`
// }{
// A: "1",
// },
// Iface: &Impl{
// F: "123",
// },
// }
// for n := 0; n < b.N; n++ {
// validate.Struct(tSuccess)
// validate.Struct(tFail)
// }
// }
// func BenchmarkTemplateParallelLarge(b *testing.B) {
// tFail := &TestString{
// Required: "",
// Len: "",
// Min: "",
// Max: "12345678901",
// MinMax: "",
// Lt: "0123456789",
// Lte: "01234567890",
// Gt: "1",
// Gte: "1",
// OmitEmpty: "12345678901",
// Sub: &SubTest{
// Test: "",
// },
// Anonymous: struct {
// A string `validate:"required"`
// }{
// A: "",
// },
// Iface: &Impl{
// F: "12",
// },
// }
// tSuccess := &TestString{
// Required: "Required",
// Len: "length==10",
// Min: "min=1",
// Max: "1234567890",
// MinMax: "12345",
// Lt: "012345678",
// Lte: "0123456789",
// Gt: "01234567890",
// Gte: "0123456789",
// OmitEmpty: "",
// Sub: &SubTest{
// Test: "1",
// },
// SubIgnore: &SubTest{
// Test: "",
// },
// Anonymous: struct {
// A string `validate:"required"`
// }{
// A: "1",
// },
// Iface: &Impl{
// F: "123",
// },
// }
// b.RunParallel(func(pb *testing.PB) {
// for pb.Next() {
// validate.Struct(tSuccess)
// validate.Struct(tFail)
// }
// })
// }
func BenchmarkValidateStructLarge(b *testing.B) {
tFail := &TestString{
Required: "",
Len: "",
Min: "",
Max: "12345678901",
MinMax: "",
Lt: "0123456789",
Lte: "01234567890",
Gt: "1",
Gte: "1",
OmitEmpty: "12345678901",
Sub: &SubTest{
Test: "",
},
Anonymous: struct {
A string `validate:"required"`
}{
A: "",
},
Iface: &Impl{
F: "12",
},
}
tSuccess := &TestString{
Required: "Required",
Len: "length==10",
Min: "min=1",
Max: "1234567890",
MinMax: "12345",
Lt: "012345678",
Lte: "0123456789",
Gt: "01234567890",
Gte: "0123456789",
OmitEmpty: "",
Sub: &SubTest{
Test: "1",
},
SubIgnore: &SubTest{
Test: "",
},
Anonymous: struct {
A string `validate:"required"`
}{
A: "1",
},
Iface: &Impl{
F: "123",
},
}
for n := 0; n < b.N; n++ {
validate.Struct(tSuccess)
validate.Struct(tFail)
}
}
func BenchmarkTemplateParallelLarge(b *testing.B) {
tFail := &TestString{
Required: "",
Len: "",
Min: "",
Max: "12345678901",
MinMax: "",
Lt: "0123456789",
Lte: "01234567890",
Gt: "1",
Gte: "1",
OmitEmpty: "12345678901",
Sub: &SubTest{
Test: "",
},
Anonymous: struct {
A string `validate:"required"`
}{
A: "",
},
Iface: &Impl{
F: "12",
},
}
tSuccess := &TestString{
Required: "Required",
Len: "length==10",
Min: "min=1",
Max: "1234567890",
MinMax: "12345",
Lt: "012345678",
Lte: "0123456789",
Gt: "01234567890",
Gte: "0123456789",
OmitEmpty: "",
Sub: &SubTest{
Test: "1",
},
SubIgnore: &SubTest{
Test: "",
},
Anonymous: struct {
A string `validate:"required"`
}{
A: "1",
},
Iface: &Impl{
F: "123",
},
}
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
validate.Struct(tSuccess)
validate.Struct(tFail)
}
})
}

@ -58,7 +58,7 @@ var (
sSNRegex = regexp.MustCompile(sSNRegexString)
)
func matchesRegex(regex *regexp.Regexp, field interface{}) bool {
fieldAsString := field.(string) //this will panic inherently
return regex.MatchString(fieldAsString)
func matchesRegex(regex *regexp.Regexp, value string) bool {
// fieldAsString := field.(string) //this will panic inherently
return regex.MatchString(value)
}

@ -101,6 +101,28 @@ func New(config Config) *Validate {
return &Validate{config: config}
}
// 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 {
errs := map[string]*FieldError{}
fieldVal := reflect.ValueOf(field)
v.traverseField(fieldVal, fieldVal, fieldVal, "", errs, false, tag, "")
return errs
}
// FieldWithValue allows validation of a single field, possibly even against another fields value, still using tag style validation to check multiple errors
func (v *Validate) FieldWithValue(val interface{}, field interface{}, tag string) ValidationErrors {
errs := map[string]*FieldError{}
topVal := reflect.ValueOf(val)
v.traverseField(topVal, topVal, reflect.ValueOf(field), "", errs, false, tag, "")
return errs
}
// Struct validates a struct, even it's nested structs, and returns a struct containing the errors
// NOTE: Nested Arrays, or Maps of structs do not get validated only the Array or Map itself; the reason is that there is no good
// way to represent or report which struct within the array has the error, besides can validate the struct prior to adding it to
@ -141,30 +163,6 @@ func (v *Validate) tranverseStruct(topStruct reflect.Value, currentStruct reflec
}
}
// 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 {
errs := map[string]*FieldError{}
fieldVal := reflect.ValueOf(field)
v.traverseField(fieldVal, fieldVal, fieldVal, "", errs, false, tag, "")
return errs
// return v.FieldWithValue(nil, field, tag)
}
// FieldWithValue allows validation of a single field, possibly even against another fields value, still using tag style validation to check multiple errors
func (v *Validate) FieldWithValue(val interface{}, field interface{}, tag string) ValidationErrors {
errs := map[string]*FieldError{}
topVal := reflect.ValueOf(val)
v.traverseField(topVal, topVal, reflect.ValueOf(field), "", errs, false, tag, "")
return errs
}
func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect.Value, current reflect.Value, errPrefix string, errs ValidationErrors, isStructField bool, tag string, name string) {
if tag == skipValidationTag {
@ -275,13 +273,13 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect.
// no use in checking tags if it's empty and is ok to be
// omitempty needs to be the first tag if you wish to use it
if t == omitempty && !hasValue(topStruct, currentStruct, current, typ, kind, "") {
return
}
if t == omitempty {
// if strings.Contains(tag, omitempty) && !hasValue(topStruct, currentStruct, current, "") {
// return
// }
if !hasValue(topStruct, currentStruct, current, typ, kind, "") {
return
}
continue
}
var key string
var param string

Loading…
Cancel
Save