Merge branch 'v5-development' of https://gopkg.in/bluesuncorp/validator.v5 into v5-development
commit
3bece518fa
@ -0,0 +1,163 @@ |
|||||||
|
package validator |
||||||
|
|
||||||
|
import "testing" |
||||||
|
|
||||||
|
func BenchmarkValidateField(b *testing.B) { |
||||||
|
for n := 0; n < b.N; n++ { |
||||||
|
validate.Field("1", "len=1") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func BenchmarkValidateStructSimple(b *testing.B) { |
||||||
|
|
||||||
|
type Foo struct { |
||||||
|
StringValue string `validate:"min=5,max=10"` |
||||||
|
IntValue int `validate:"min=5,max=10"` |
||||||
|
} |
||||||
|
|
||||||
|
validFoo := &Foo{StringValue: "Foobar", IntValue: 7} |
||||||
|
invalidFoo := &Foo{StringValue: "Fo", IntValue: 3} |
||||||
|
|
||||||
|
for n := 0; n < b.N; n++ { |
||||||
|
validate.Struct(validFoo) |
||||||
|
validate.Struct(invalidFoo) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
func BenchmarkTemplateParallelSimple(b *testing.B) { |
||||||
|
|
||||||
|
type Foo struct { |
||||||
|
StringValue string `validate:"min=5,max=10"` |
||||||
|
IntValue int `validate:"min=5,max=10"` |
||||||
|
} |
||||||
|
|
||||||
|
validFoo := &Foo{StringValue: "Foobar", IntValue: 7} |
||||||
|
invalidFoo := &Foo{StringValue: "Fo", IntValue: 3} |
||||||
|
|
||||||
|
b.RunParallel(func(pb *testing.PB) { |
||||||
|
for pb.Next() { |
||||||
|
validate.Struct(validFoo) |
||||||
|
validate.Struct(invalidFoo) |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
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) |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
@ -0,0 +1,85 @@ |
|||||||
|
package main |
||||||
|
|
||||||
|
import ( |
||||||
|
"fmt" |
||||||
|
|
||||||
|
"gopkg.in/bluesuncorp/validator.v5" |
||||||
|
) |
||||||
|
|
||||||
|
// User contains user information
|
||||||
|
type User struct { |
||||||
|
FirstName string `validate:"required"` |
||||||
|
LastName string `validate:"required"` |
||||||
|
Age uint8 `validate:"gte=0,lte=130"` |
||||||
|
Email string `validate:"required,email"` |
||||||
|
FavouriteColor string `validate:"hexcolor|rgb|rgba"` |
||||||
|
Addresses []*Address `validate:"required,dive,required"` // a person can have a home and cottage...
|
||||||
|
} |
||||||
|
|
||||||
|
// Address houses a users address information
|
||||||
|
type Address struct { |
||||||
|
Street string `validate:"required"` |
||||||
|
City string `validate:"required"` |
||||||
|
Planet string `validate:"required"` |
||||||
|
Phone string `validate:"required"` |
||||||
|
} |
||||||
|
|
||||||
|
var validate *validator.Validate |
||||||
|
|
||||||
|
func main() { |
||||||
|
|
||||||
|
validate = validator.New("validate", validator.BakedInValidators) |
||||||
|
|
||||||
|
address := &Address{ |
||||||
|
Street: "Eavesdown Docks", |
||||||
|
Planet: "Persphone", |
||||||
|
Phone: "none", |
||||||
|
} |
||||||
|
|
||||||
|
user := &User{ |
||||||
|
FirstName: "Badger", |
||||||
|
LastName: "Smith", |
||||||
|
Age: 135, |
||||||
|
Email: "Badger.Smith@gmail.com", |
||||||
|
FavouriteColor: "#000", |
||||||
|
Addresses: []*Address{address}, |
||||||
|
} |
||||||
|
|
||||||
|
// returns nil or *StructErrors
|
||||||
|
errs := validate.Struct(user) |
||||||
|
|
||||||
|
if errs != nil { |
||||||
|
|
||||||
|
// err will be of type *FieldError
|
||||||
|
err := errs.Errors["Age"] |
||||||
|
fmt.Println(err.Error()) // output: Field validation for "Age" failed on the "lte" tag
|
||||||
|
fmt.Println(err.Field) // output: Age
|
||||||
|
fmt.Println(err.Tag) // output: lte
|
||||||
|
fmt.Println(err.Kind) // output: uint8
|
||||||
|
fmt.Println(err.Type) // output: uint8
|
||||||
|
fmt.Println(err.Param) // output: 130
|
||||||
|
fmt.Println(err.Value) // output: 135
|
||||||
|
|
||||||
|
// or if you prefer you can use the Flatten function
|
||||||
|
// NOTE: I find this usefull when using a more hard static approach of checking field errors.
|
||||||
|
// The above, is best for passing to some generic code to say parse the errors. i.e. I pass errs
|
||||||
|
// to a routine which loops through the errors, creates and translates the error message into the
|
||||||
|
// users locale and returns a map of map[string]string // field and error which I then use
|
||||||
|
// within the HTML rendering.
|
||||||
|
|
||||||
|
flat := errs.Flatten() |
||||||
|
fmt.Println(flat) // output: map[Age:Field validation for "Age" failed on the "lte" tag Addresses[0].Address.City:Field validation for "City" failed on the "required" tag]
|
||||||
|
err = flat["Addresses[0].Address.City"] |
||||||
|
fmt.Println(err.Field) // output: City
|
||||||
|
fmt.Println(err.Tag) // output: required
|
||||||
|
fmt.Println(err.Kind) // output: string
|
||||||
|
fmt.Println(err.Type) // output: string
|
||||||
|
fmt.Println(err.Param) // output:
|
||||||
|
fmt.Println(err.Value) // output:
|
||||||
|
|
||||||
|
// from here you can create your own error messages in whatever language you wish
|
||||||
|
return |
||||||
|
} |
||||||
|
|
||||||
|
// save user to database
|
||||||
|
} |
@ -0,0 +1,95 @@ |
|||||||
|
package validator_test |
||||||
|
|
||||||
|
import ( |
||||||
|
"fmt" |
||||||
|
|
||||||
|
"../validator" |
||||||
|
) |
||||||
|
|
||||||
|
func ExampleValidate_new() { |
||||||
|
validator.New("validate", validator.BakedInValidators) |
||||||
|
} |
||||||
|
|
||||||
|
func ExampleValidate_addFunction() { |
||||||
|
// This should be stored somewhere globally
|
||||||
|
var validate *validator.Validate |
||||||
|
|
||||||
|
validate = validator.New("validate", validator.BakedInValidators) |
||||||
|
|
||||||
|
fn := func(top interface{}, current interface{}, field interface{}, param string) bool { |
||||||
|
return field.(string) == "hello" |
||||||
|
} |
||||||
|
|
||||||
|
validate.AddFunction("valueishello", fn) |
||||||
|
|
||||||
|
message := "hello" |
||||||
|
err := validate.Field(message, "valueishello") |
||||||
|
fmt.Println(err) |
||||||
|
//Output:
|
||||||
|
//<nil>
|
||||||
|
} |
||||||
|
|
||||||
|
func ExampleValidate_field() { |
||||||
|
// This should be stored somewhere globally
|
||||||
|
var validate *validator.Validate |
||||||
|
|
||||||
|
validate = validator.New("validate", validator.BakedInValidators) |
||||||
|
|
||||||
|
i := 0 |
||||||
|
err := validate.Field(i, "gt=1,lte=10") |
||||||
|
fmt.Println(err.Field) |
||||||
|
fmt.Println(err.Tag) |
||||||
|
fmt.Println(err.Kind) // NOTE: Kind and Type can be different i.e. time Kind=struct and Type=time.Time
|
||||||
|
fmt.Println(err.Type) |
||||||
|
fmt.Println(err.Param) |
||||||
|
fmt.Println(err.Value) |
||||||
|
//Output:
|
||||||
|
//
|
||||||
|
//gt
|
||||||
|
//int
|
||||||
|
//int
|
||||||
|
//1
|
||||||
|
//0
|
||||||
|
} |
||||||
|
|
||||||
|
func ExampleValidate_struct() { |
||||||
|
// This should be stored somewhere globally
|
||||||
|
var validate *validator.Validate |
||||||
|
|
||||||
|
validate = validator.New("validate", validator.BakedInValidators) |
||||||
|
|
||||||
|
type ContactInformation struct { |
||||||
|
Phone string `validate:"required"` |
||||||
|
Street string `validate:"required"` |
||||||
|
City string `validate:"required"` |
||||||
|
} |
||||||
|
|
||||||
|
type User struct { |
||||||
|
Name string `validate:"required,excludesall=!@#$%^&*()_+-=:;?/0x2C"` // 0x2C = comma (,)
|
||||||
|
Age int8 `validate:"required,gt=0,lt=150"` |
||||||
|
Email string `validate:"email"` |
||||||
|
ContactInformation []*ContactInformation |
||||||
|
} |
||||||
|
|
||||||
|
contactInfo := &ContactInformation{ |
||||||
|
Street: "26 Here Blvd.", |
||||||
|
City: "Paradeso", |
||||||
|
} |
||||||
|
|
||||||
|
user := &User{ |
||||||
|
Name: "Joey Bloggs", |
||||||
|
Age: 31, |
||||||
|
Email: "joeybloggs@gmail.com", |
||||||
|
ContactInformation: []*ContactInformation{contactInfo}, |
||||||
|
} |
||||||
|
|
||||||
|
structError := validate.Struct(user) |
||||||
|
for _, fieldError := range structError.Errors { |
||||||
|
fmt.Println(fieldError.Field) // Phone
|
||||||
|
fmt.Println(fieldError.Tag) // required
|
||||||
|
//... and so forth
|
||||||
|
//Output:
|
||||||
|
//Phone
|
||||||
|
//required
|
||||||
|
} |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue