Updates + Benchmarks

update documentation.
add benchmarks for StructPartial, dive tag, cross field and cross struct cross field.
pull/161/head
joeybloggs 9 years ago
parent 4f46e02133
commit 883731a774
  1. 194
      benchmarks_test.go
  2. 4
      validator.go

@ -4,6 +4,7 @@ import (
sql "database/sql/driver"
"reflect"
"testing"
"time"
)
func BenchmarkFieldSuccess(b *testing.B) {
@ -18,6 +19,18 @@ func BenchmarkFieldFailure(b *testing.B) {
}
}
func BenchmarkFieldDiveSuccess(b *testing.B) {
for n := 0; n < b.N; n++ {
validate.Field([]string{"val1", "val2", "val3"}, "required,dive,required")
}
}
func BenchmarkFieldDiveFailure(b *testing.B) {
for n := 0; n < b.N; n++ {
validate.Field([]string{"val1", "", "val3"}, "required,dive,required")
}
}
func BenchmarkFieldCustomTypeSuccess(b *testing.B) {
customTypes := map[reflect.Type]CustomTypeFunc{}
@ -62,35 +75,31 @@ func BenchmarkFieldOrTagFailure(b *testing.B) {
}
}
func BenchmarkStructSimpleSuccess(b *testing.B) {
func BenchmarkStructSimpleCustomTypeSuccess(b *testing.B) {
type Foo struct {
StringValue string `validate:"min=5,max=10"`
IntValue int `validate:"min=5,max=10"`
}
customTypes := map[reflect.Type]CustomTypeFunc{}
customTypes[reflect.TypeOf((*sql.Valuer)(nil))] = ValidateValuerType
customTypes[reflect.TypeOf(valuer{})] = ValidateValuerType
validFoo := &Foo{StringValue: "Foobar", IntValue: 7}
validate := New(Config{TagName: "validate", ValidationFuncs: BakedInValidators, CustomTypeFuncs: customTypes})
for n := 0; n < b.N; n++ {
validate.Struct(validFoo)
val := valuer{
Name: "1",
}
}
func BenchmarkStructSimpleFailure(b *testing.B) {
type Foo struct {
StringValue string `validate:"min=5,max=10"`
Valuer valuer `validate:"len=1"`
IntValue int `validate:"min=5,max=10"`
}
invalidFoo := &Foo{StringValue: "Fo", IntValue: 3}
validFoo := &Foo{Valuer: val, IntValue: 7}
for n := 0; n < b.N; n++ {
validate.Struct(invalidFoo)
validate.Struct(validFoo)
}
}
func BenchmarkStructSimpleCustomTypeSuccess(b *testing.B) {
func BenchmarkStructSimpleCustomTypeFailure(b *testing.B) {
customTypes := map[reflect.Type]CustomTypeFunc{}
customTypes[reflect.TypeOf((*sql.Valuer)(nil))] = ValidateValuerType
@ -98,44 +107,175 @@ func BenchmarkStructSimpleCustomTypeSuccess(b *testing.B) {
validate := New(Config{TagName: "validate", ValidationFuncs: BakedInValidators, CustomTypeFuncs: customTypes})
val := valuer{
Name: "1",
}
val := valuer{}
type Foo struct {
Valuer valuer `validate:"len=1"`
IntValue int `validate:"min=5,max=10"`
}
validFoo := &Foo{Valuer: val, IntValue: 7}
validFoo := &Foo{Valuer: val, IntValue: 3}
for n := 0; n < b.N; n++ {
validate.Struct(validFoo)
}
}
func BenchmarkStructSimpleCustomTypeFailure(b *testing.B) {
func BenchmarkStructPartialSuccess(b *testing.B) {
customTypes := map[reflect.Type]CustomTypeFunc{}
customTypes[reflect.TypeOf((*sql.Valuer)(nil))] = ValidateValuerType
customTypes[reflect.TypeOf(valuer{})] = ValidateValuerType
type Test struct {
Name string `validate:"required"`
NickName string `validate:"required"`
}
validate := New(Config{TagName: "validate", ValidationFuncs: BakedInValidators, CustomTypeFuncs: customTypes})
test := &Test{
Name: "Joey Bloggs",
}
val := valuer{}
for n := 0; n < b.N; n++ {
validate.StructPartial(test, "Name")
}
}
func BenchmarkStructPartialFailure(b *testing.B) {
type Test struct {
Name string `validate:"required"`
NickName string `validate:"required"`
}
test := &Test{
Name: "Joey Bloggs",
}
for n := 0; n < b.N; n++ {
validate.StructPartial(test, "NickName")
}
}
func BenchmarkStructSimpleCrossFieldSuccess(b *testing.B) {
type Test struct {
Start time.Time
End time.Time `validate:"gtfield=Start"`
}
now := time.Now().UTC()
then := now.Add(time.Hour * 5)
test := &Test{
Start: now,
End: then,
}
for n := 0; n < b.N; n++ {
validate.Struct(test)
}
}
func BenchmarkStructSimpleCrossFieldFailure(b *testing.B) {
type Test struct {
Start time.Time
End time.Time `validate:"gtfield=Start"`
}
now := time.Now().UTC()
then := now.Add(time.Hour * -5)
test := &Test{
Start: now,
End: then,
}
for n := 0; n < b.N; n++ {
validate.Struct(test)
}
}
func BenchmarkStructSimpleCrossStructCrossFieldSuccess(b *testing.B) {
type Inner struct {
Start time.Time
}
type Outer struct {
Inner *Inner
CreatedAt time.Time `validate:"eqcsfield=Inner.Start"`
}
now := time.Now().UTC()
inner := &Inner{
Start: now,
}
outer := &Outer{
Inner: inner,
CreatedAt: now,
}
for n := 0; n < b.N; n++ {
validate.Struct(outer)
}
}
func BenchmarkStructSimpleCrossStructCrossFieldFailure(b *testing.B) {
type Inner struct {
Start time.Time
}
type Outer struct {
Inner *Inner
CreatedAt time.Time `validate:"eqcsfield=Inner.Start"`
}
now := time.Now().UTC()
then := now.Add(time.Hour * 5)
inner := &Inner{
Start: then,
}
outer := &Outer{
Inner: inner,
CreatedAt: now,
}
for n := 0; n < b.N; n++ {
validate.Struct(outer)
}
}
func BenchmarkStructSimpleSuccess(b *testing.B) {
type Foo struct {
Valuer valuer `validate:"len=1"`
StringValue string `validate:"min=5,max=10"`
IntValue int `validate:"min=5,max=10"`
}
validFoo := &Foo{Valuer: val, IntValue: 3}
validFoo := &Foo{StringValue: "Foobar", IntValue: 7}
for n := 0; n < b.N; n++ {
validate.Struct(validFoo)
}
}
func BenchmarkStructSimpleFailure(b *testing.B) {
type Foo struct {
StringValue string `validate:"min=5,max=10"`
IntValue int `validate:"min=5,max=10"`
}
invalidFoo := &Foo{StringValue: "Fo", IntValue: 3}
for n := 0; n < b.N; n++ {
validate.Struct(invalidFoo)
}
}
func BenchmarkStructSimpleSuccessParallel(b *testing.B) {
type Foo struct {

@ -213,6 +213,8 @@ func (v *Validate) FieldWithValue(val interface{}, field interface{}, tag string
// StructPartial validates the fields passed in only, ignoring all others.
// Fields may be provided in a namespaced fashion relative to the struct provided
// i.e. NestedStruct.Field or NestedArrayField[0].Struct.Name
// NOTE: This is normally not needed, however in some specific cases such as: tied to a
// legacy data structure, it will be useful
func (v *Validate) StructPartial(current interface{}, fields ...string) ValidationErrors {
sv, _ := v.extractType(reflect.ValueOf(current))
@ -269,6 +271,8 @@ func (v *Validate) StructPartial(current interface{}, fields ...string) Validati
// StructExcept validates all fields except the ones passed in.
// Fields may be provided in a namespaced fashion relative to the struct provided
// i.e. NestedStruct.Field or NestedArrayField[0].Struct.Name
// NOTE: This is normally not needed, however in some specific cases such as: tied to a
// legacy data structure, it will be useful
func (v *Validate) StructExcept(current interface{}, fields ...string) ValidationErrors {
sv, _ := v.extractType(reflect.ValueOf(current))

Loading…
Cancel
Save