|
|
@ -5,53 +5,340 @@ import ( |
|
|
|
"testing" |
|
|
|
"testing" |
|
|
|
|
|
|
|
|
|
|
|
"github.com/joeybloggs/go-validate-yourself" |
|
|
|
"github.com/joeybloggs/go-validate-yourself" |
|
|
|
|
|
|
|
. "gopkg.in/check.v1" |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
type UserDetails struct { |
|
|
|
type SubTest struct { |
|
|
|
Address string `validate:"omitempty,length=6"` |
|
|
|
Test string `validate:"required"` |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
type User struct { |
|
|
|
type TestString struct { |
|
|
|
FirstName string `validate:"required"` |
|
|
|
Required string `validate:"required"` |
|
|
|
Details *UserDetails |
|
|
|
Len string `validate:"len=10"` |
|
|
|
|
|
|
|
Min string `validate:"min=1"` |
|
|
|
|
|
|
|
Max string `validate:"max=10"` |
|
|
|
|
|
|
|
MinMax string `validate:"min=1,max=10"` |
|
|
|
|
|
|
|
OmitEmpty string `validate:"omitempty,min=1,max=10"` |
|
|
|
|
|
|
|
Sub *SubTest |
|
|
|
|
|
|
|
SubIgnore *SubTest `validate:"-"` |
|
|
|
|
|
|
|
Anonymous struct { |
|
|
|
|
|
|
|
A string `validate:"required"` |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type TestInt32 struct { |
|
|
|
|
|
|
|
Required int `validate:"required"` |
|
|
|
|
|
|
|
Len int `validate:"len=10"` |
|
|
|
|
|
|
|
Min int `validate:"min=1"` |
|
|
|
|
|
|
|
Max int `validate:"max=10"` |
|
|
|
|
|
|
|
MinMax int `validate:"min=1,max=10"` |
|
|
|
|
|
|
|
OmitEmpty int `validate:"omitempty,min=1,max=10"` |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type TestUint64 struct { |
|
|
|
|
|
|
|
Required uint64 `validate:"required"` |
|
|
|
|
|
|
|
Len uint64 `validate:"len=10"` |
|
|
|
|
|
|
|
Min uint64 `validate:"min=1"` |
|
|
|
|
|
|
|
Max uint64 `validate:"max=10"` |
|
|
|
|
|
|
|
MinMax uint64 `validate:"min=1,max=10"` |
|
|
|
|
|
|
|
OmitEmpty uint64 `validate:"omitempty,min=1,max=10"` |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type TestFloat64 struct { |
|
|
|
|
|
|
|
Required int64 `validate:"required"` |
|
|
|
|
|
|
|
Len int64 `validate:"len=10"` |
|
|
|
|
|
|
|
Min int64 `validate:"min=1"` |
|
|
|
|
|
|
|
Max int64 `validate:"max=10"` |
|
|
|
|
|
|
|
MinMax int64 `validate:"min=1,max=10"` |
|
|
|
|
|
|
|
OmitEmpty int64 `validate:"omitempty,min=1,max=10"` |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type TestSlice struct { |
|
|
|
|
|
|
|
Required []int `validate:"required"` |
|
|
|
|
|
|
|
Len []int `validate:"len=10"` |
|
|
|
|
|
|
|
Min []int `validate:"min=1"` |
|
|
|
|
|
|
|
Max []int `validate:"max=10"` |
|
|
|
|
|
|
|
MinMax []int `validate:"min=1,max=10"` |
|
|
|
|
|
|
|
OmitEmpty []int `validate:"omitempty,min=1,max=10"` |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func Test(t *testing.T) { TestingT(t) } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
type MySuite struct{} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var _ = Suite(&MySuite{}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func AssetStruct(s *validator.StructValidationErrors, structFieldName string, expectedStructName string, c *C) *validator.StructValidationErrors { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val, ok := s.StructErrors[structFieldName] |
|
|
|
|
|
|
|
c.Assert(ok, Equals, true) |
|
|
|
|
|
|
|
c.Assert(val, NotNil) |
|
|
|
|
|
|
|
c.Assert(val.Struct, Equals, expectedStructName) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return val |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func TestValidateStruct(t *testing.T) { |
|
|
|
func AssertFieldError(s *validator.StructValidationErrors, field string, expectedTag string, c *C) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val, ok := s.Errors[field] |
|
|
|
|
|
|
|
c.Assert(ok, Equals, true) |
|
|
|
|
|
|
|
c.Assert(val, NotNil) |
|
|
|
|
|
|
|
c.Assert(val.Field, Equals, field) |
|
|
|
|
|
|
|
c.Assert(val.ErrorTag, Equals, expectedTag) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (ms *MySuite) TestStructStringValidation(c *C) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tSuccess := &TestString{ |
|
|
|
|
|
|
|
Required: "Required", |
|
|
|
|
|
|
|
Len: "length==10", |
|
|
|
|
|
|
|
Min: "min=1", |
|
|
|
|
|
|
|
Max: "1234567890", |
|
|
|
|
|
|
|
MinMax: "12345", |
|
|
|
|
|
|
|
OmitEmpty: "", |
|
|
|
|
|
|
|
Sub: &SubTest{ |
|
|
|
|
|
|
|
Test: "1", |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
SubIgnore: &SubTest{ |
|
|
|
|
|
|
|
Test: "", |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
Anonymous: struct { |
|
|
|
|
|
|
|
A string `validate:"required"` |
|
|
|
|
|
|
|
}{ |
|
|
|
|
|
|
|
A: "1", |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
err := validator.ValidateStruct(tSuccess) |
|
|
|
|
|
|
|
c.Assert(err, IsNil) |
|
|
|
|
|
|
|
|
|
|
|
u := &User{ |
|
|
|
tFail := &TestString{ |
|
|
|
FirstName: "", |
|
|
|
Required: "", |
|
|
|
Details: &UserDetails{ |
|
|
|
Len: "", |
|
|
|
"", |
|
|
|
Min: "", |
|
|
|
|
|
|
|
Max: "12345678901", |
|
|
|
|
|
|
|
MinMax: "", |
|
|
|
|
|
|
|
OmitEmpty: "12345678901", |
|
|
|
|
|
|
|
Sub: &SubTest{ |
|
|
|
|
|
|
|
Test: "", |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
Anonymous: struct { |
|
|
|
|
|
|
|
A string `validate:"required"` |
|
|
|
|
|
|
|
}{ |
|
|
|
|
|
|
|
A: "", |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
err = validator.ValidateStruct(tFail) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Assert Top Level
|
|
|
|
|
|
|
|
c.Assert(err.Struct, Equals, "TestString") |
|
|
|
|
|
|
|
c.Assert(len(err.Errors), Equals, 6) |
|
|
|
|
|
|
|
c.Assert(len(err.StructErrors), Equals, 2) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Assert Fields
|
|
|
|
|
|
|
|
AssertFieldError(err, "Required", "required", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "Len", "len", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "Min", "min", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "Max", "max", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "MinMax", "min", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "OmitEmpty", "max", c) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Assert Anonymous embedded struct
|
|
|
|
|
|
|
|
AssetStruct(err, "Anonymous", "", c) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Assert SubTest embedded struct
|
|
|
|
|
|
|
|
val := AssetStruct(err, "Sub", "SubTest", c) |
|
|
|
|
|
|
|
c.Assert(len(val.Errors), Equals, 1) |
|
|
|
|
|
|
|
c.Assert(len(val.StructErrors), Equals, 0) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AssertFieldError(val, "Test", "required", c) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (ms *MySuite) TestStructInt32Validation(c *C) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tSuccess := &TestInt32{ |
|
|
|
|
|
|
|
Required: 1, |
|
|
|
|
|
|
|
Len: 10, |
|
|
|
|
|
|
|
Min: 1, |
|
|
|
|
|
|
|
Max: 10, |
|
|
|
|
|
|
|
MinMax: 5, |
|
|
|
|
|
|
|
OmitEmpty: 0, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
err := validator.ValidateStruct(tSuccess) |
|
|
|
|
|
|
|
c.Assert(err, IsNil) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tFail := &TestInt32{ |
|
|
|
|
|
|
|
Required: 0, |
|
|
|
|
|
|
|
Len: 11, |
|
|
|
|
|
|
|
Min: -1, |
|
|
|
|
|
|
|
Max: 11, |
|
|
|
|
|
|
|
MinMax: -1, |
|
|
|
|
|
|
|
OmitEmpty: 11, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
err = validator.ValidateStruct(tFail) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Assert Top Level
|
|
|
|
|
|
|
|
c.Assert(err.Struct, Equals, "TestInt32") |
|
|
|
|
|
|
|
c.Assert(len(err.Errors), Equals, 6) |
|
|
|
|
|
|
|
c.Assert(len(err.StructErrors), Equals, 0) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Assert Fields
|
|
|
|
|
|
|
|
AssertFieldError(err, "Required", "required", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "Len", "len", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "Min", "min", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "Max", "max", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "MinMax", "min", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "OmitEmpty", "max", c) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (ms *MySuite) TestStructUint64Validation(c *C) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tSuccess := &TestUint64{ |
|
|
|
|
|
|
|
Required: 1, |
|
|
|
|
|
|
|
Len: 10, |
|
|
|
|
|
|
|
Min: 1, |
|
|
|
|
|
|
|
Max: 10, |
|
|
|
|
|
|
|
MinMax: 5, |
|
|
|
|
|
|
|
OmitEmpty: 0, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
err := validator.ValidateStruct(tSuccess) |
|
|
|
|
|
|
|
c.Assert(err, IsNil) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tFail := &TestUint64{ |
|
|
|
|
|
|
|
Required: 0, |
|
|
|
|
|
|
|
Len: 11, |
|
|
|
|
|
|
|
Min: 0, |
|
|
|
|
|
|
|
Max: 11, |
|
|
|
|
|
|
|
MinMax: 0, |
|
|
|
|
|
|
|
OmitEmpty: 11, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
err = validator.ValidateStruct(tFail) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Assert Top Level
|
|
|
|
|
|
|
|
c.Assert(err.Struct, Equals, "TestUint64") |
|
|
|
|
|
|
|
c.Assert(len(err.Errors), Equals, 6) |
|
|
|
|
|
|
|
c.Assert(len(err.StructErrors), Equals, 0) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Assert Fields
|
|
|
|
|
|
|
|
AssertFieldError(err, "Required", "required", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "Len", "len", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "Min", "min", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "Max", "max", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "MinMax", "min", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "OmitEmpty", "max", c) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (ms *MySuite) TestStructFloat64Validation(c *C) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tSuccess := &TestFloat64{ |
|
|
|
|
|
|
|
Required: 1, |
|
|
|
|
|
|
|
Len: 10, |
|
|
|
|
|
|
|
Min: 1, |
|
|
|
|
|
|
|
Max: 10, |
|
|
|
|
|
|
|
MinMax: 5, |
|
|
|
|
|
|
|
OmitEmpty: 0, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
err := validator.ValidateStruct(tSuccess) |
|
|
|
|
|
|
|
c.Assert(err, IsNil) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tFail := &TestFloat64{ |
|
|
|
|
|
|
|
Required: 0, |
|
|
|
|
|
|
|
Len: 11, |
|
|
|
|
|
|
|
Min: 0, |
|
|
|
|
|
|
|
Max: 11, |
|
|
|
|
|
|
|
MinMax: 0, |
|
|
|
|
|
|
|
OmitEmpty: 11, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
err = validator.ValidateStruct(tFail) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Assert Top Level
|
|
|
|
|
|
|
|
c.Assert(err.Struct, Equals, "TestFloat64") |
|
|
|
|
|
|
|
c.Assert(len(err.Errors), Equals, 6) |
|
|
|
|
|
|
|
c.Assert(len(err.StructErrors), Equals, 0) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Assert Fields
|
|
|
|
|
|
|
|
AssertFieldError(err, "Required", "required", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "Len", "len", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "Min", "min", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "Max", "max", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "MinMax", "min", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "OmitEmpty", "max", c) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (ms *MySuite) TestStructSliceValidation(c *C) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tSuccess := &TestSlice{ |
|
|
|
|
|
|
|
Required: []int{1}, |
|
|
|
|
|
|
|
Len: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, |
|
|
|
|
|
|
|
Min: []int{1, 2}, |
|
|
|
|
|
|
|
Max: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, |
|
|
|
|
|
|
|
MinMax: []int{1, 2, 3, 4, 5}, |
|
|
|
|
|
|
|
OmitEmpty: []int{}, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
errors := validator.ValidateStruct(u) |
|
|
|
err := validator.ValidateStruct(tSuccess) |
|
|
|
|
|
|
|
c.Assert(err, IsNil) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tFail := &TestSlice{ |
|
|
|
|
|
|
|
Required: []int{}, |
|
|
|
|
|
|
|
Len: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1}, |
|
|
|
|
|
|
|
Min: []int{}, |
|
|
|
|
|
|
|
Max: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1}, |
|
|
|
|
|
|
|
MinMax: []int{}, |
|
|
|
|
|
|
|
OmitEmpty: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1}, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
err = validator.ValidateStruct(tFail) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Assert Top Level
|
|
|
|
|
|
|
|
c.Assert(err.Struct, Equals, "TestSlice") |
|
|
|
|
|
|
|
c.Assert(len(err.Errors), Equals, 6) |
|
|
|
|
|
|
|
c.Assert(len(err.StructErrors), Equals, 0) |
|
|
|
|
|
|
|
|
|
|
|
fmt.Println(errors == nil) |
|
|
|
// Assert Fields
|
|
|
|
|
|
|
|
AssertFieldError(err, "Required", "required", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "Len", "len", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "Min", "min", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "Max", "max", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "MinMax", "min", c) |
|
|
|
|
|
|
|
AssertFieldError(err, "OmitEmpty", "max", c) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (ms *MySuite) TestInvalidStruct(c *C) { |
|
|
|
|
|
|
|
s := &SubTest{ |
|
|
|
|
|
|
|
Test: "1", |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
c.Assert(func() { validator.ValidateStruct(s.Test) }, PanicMatches, "interface passed for validation is not a struct") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for _, i := range errors { |
|
|
|
func (ms *MySuite) TestInvalidField(c *C) { |
|
|
|
fmt.Printf("Error Struct:%s\n", i.Struct) |
|
|
|
s := &SubTest{ |
|
|
|
|
|
|
|
Test: "1", |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for _, j := range i.Errors { |
|
|
|
c.Assert(func() { validator.ValidateFieldByTag(s, "required") }, PanicMatches, "Invalid field passed to ValidateFieldWithTag") |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fmt.Printf("Error Field:%s Error Tag:%s\n", j.Field, j.ErrorTag) |
|
|
|
func (ms *MySuite) TestInvalidTagField(c *C) { |
|
|
|
fmt.Println(j.Error()) |
|
|
|
s := &SubTest{ |
|
|
|
} |
|
|
|
Test: "1", |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
c.Assert(func() { validator.ValidateFieldByTag(s.Test, "") }, PanicMatches, fmt.Sprintf("Invalid validation tag on field %s", "")) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// func TestValidateField(t *testing.T) {
|
|
|
|
func (ms *MySuite) TestInvalidValidatorFunction(c *C) { |
|
|
|
//
|
|
|
|
s := &SubTest{ |
|
|
|
// u := &User{
|
|
|
|
Test: "1", |
|
|
|
// FirstName: "Dean Karn",
|
|
|
|
} |
|
|
|
// Details: &UserDetails{
|
|
|
|
|
|
|
|
// "26 Here Blvd.",
|
|
|
|
c.Assert(func() { validator.ValidateFieldByTag(s.Test, "zzxxBadFunction") }, PanicMatches, fmt.Sprintf("Undefined validation function on field %s", "")) |
|
|
|
// },
|
|
|
|
} |
|
|
|
// }
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// err := validator.ValidateFieldByTag(u.FirstName, "required")
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// fmt.Println(err == nil)
|
|
|
|
|
|
|
|
// fmt.Println(err)
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|