|
|
@ -4,6 +4,7 @@ import ( |
|
|
|
sql "database/sql/driver" |
|
|
|
sql "database/sql/driver" |
|
|
|
"reflect" |
|
|
|
"reflect" |
|
|
|
"testing" |
|
|
|
"testing" |
|
|
|
|
|
|
|
"time" |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
func BenchmarkFieldSuccess(b *testing.B) { |
|
|
|
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) { |
|
|
|
func BenchmarkFieldCustomTypeSuccess(b *testing.B) { |
|
|
|
|
|
|
|
|
|
|
|
customTypes := map[reflect.Type]CustomTypeFunc{} |
|
|
|
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 { |
|
|
|
customTypes := map[reflect.Type]CustomTypeFunc{} |
|
|
|
StringValue string `validate:"min=5,max=10"` |
|
|
|
customTypes[reflect.TypeOf((*sql.Valuer)(nil))] = ValidateValuerType |
|
|
|
IntValue int `validate:"min=5,max=10"` |
|
|
|
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++ { |
|
|
|
val := valuer{ |
|
|
|
validate.Struct(validFoo) |
|
|
|
Name: "1", |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func BenchmarkStructSimpleFailure(b *testing.B) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type Foo struct { |
|
|
|
type Foo struct { |
|
|
|
StringValue string `validate:"min=5,max=10"` |
|
|
|
Valuer valuer `validate:"len=1"` |
|
|
|
IntValue int `validate:"min=5,max=10"` |
|
|
|
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++ { |
|
|
|
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 := map[reflect.Type]CustomTypeFunc{} |
|
|
|
customTypes[reflect.TypeOf((*sql.Valuer)(nil))] = ValidateValuerType |
|
|
|
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}) |
|
|
|
validate := New(Config{TagName: "validate", ValidationFuncs: BakedInValidators, CustomTypeFuncs: customTypes}) |
|
|
|
|
|
|
|
|
|
|
|
val := valuer{ |
|
|
|
val := valuer{} |
|
|
|
Name: "1", |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type Foo struct { |
|
|
|
type Foo struct { |
|
|
|
Valuer valuer `validate:"len=1"` |
|
|
|
Valuer valuer `validate:"len=1"` |
|
|
|
IntValue int `validate:"min=5,max=10"` |
|
|
|
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++ { |
|
|
|
for n := 0; n < b.N; n++ { |
|
|
|
validate.Struct(validFoo) |
|
|
|
validate.Struct(validFoo) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func BenchmarkStructSimpleCustomTypeFailure(b *testing.B) { |
|
|
|
func BenchmarkStructPartialSuccess(b *testing.B) { |
|
|
|
|
|
|
|
|
|
|
|
customTypes := map[reflect.Type]CustomTypeFunc{} |
|
|
|
type Test struct { |
|
|
|
customTypes[reflect.TypeOf((*sql.Valuer)(nil))] = ValidateValuerType |
|
|
|
Name string `validate:"required"` |
|
|
|
customTypes[reflect.TypeOf(valuer{})] = ValidateValuerType |
|
|
|
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 { |
|
|
|
type Foo struct { |
|
|
|
Valuer valuer `validate:"len=1"` |
|
|
|
StringValue string `validate:"min=5,max=10"` |
|
|
|
IntValue int `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++ { |
|
|
|
for n := 0; n < b.N; n++ { |
|
|
|
validate.Struct(validFoo) |
|
|
|
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) { |
|
|
|
func BenchmarkStructSimpleSuccessParallel(b *testing.B) { |
|
|
|
|
|
|
|
|
|
|
|
type Foo struct { |
|
|
|
type Foo struct { |
|
|
|