diff --git a/validation/validation.go b/validation/validation.go index 465a006f..2781a72e 100644 --- a/validation/validation.go +++ b/validation/validation.go @@ -245,14 +245,13 @@ func (v *Validation) ZipCode(obj interface{}, key string) *Result { } func (v *Validation) apply(chk Validator, obj interface{}) *Result { - validatorName := reflect.TypeOf(chk).Name() if nil == obj { if chk.IsSatisfied(obj) { return &Result{Ok: true} } } else if reflect.TypeOf(obj).Kind() == reflect.Ptr { if reflect.ValueOf(obj).IsNil() { - if "Required" != validatorName { + if chk.IsSatisfied(nil) { return &Result{Ok: true} } } else { @@ -372,7 +371,18 @@ func (v *Validation) Valid(obj interface{}) (b bool, err error) { hasReuired = true } - if !hasReuired && v.RequiredFirst && len(objV.Field(i).String()) == 0 { + currentField := objV.Field(i).Interface() + if objV.Field(i).Kind() == reflect.Ptr { + if objV.Field(i).IsNil() { + currentField = "" + } else { + currentField = objV.Field(i).Elem().Interface() + } + } + + + chk := Required{""}.IsSatisfied(currentField) + if !hasReuired && v.RequiredFirst && !chk { if _, ok := CanSkipFuncs[vf.Name]; ok { continue } @@ -429,3 +439,9 @@ func (v *Validation) RecursiveValid(objc interface{}) (bool, error) { } return pass, err } + +func (v *Validation) CanSkipAlso(skipFunc string) { + if _, ok := CanSkipFuncs[skipFunc]; !ok { + CanSkipFuncs[skipFunc] = struct{}{} + } +} diff --git a/validation/validation_test.go b/validation/validation_test.go index c9f7c2df..f97105fd 100644 --- a/validation/validation_test.go +++ b/validation/validation_test.go @@ -490,8 +490,8 @@ func TestPointer(t *testing.T) { if err != nil { t.Fatal(err) } - if !b { - t.Fatal("validation should be passed") + if b { + t.Fatal("validation should not be passed") } invalidEmail := "a@a" @@ -523,3 +523,41 @@ func TestPointer(t *testing.T) { t.Fatal("validation should not be passed") } } + + +func TestCanSkipAlso(t *testing.T) { + type User struct { + ID int + + Email string `valid:"Email"` + ReqEmail string `valid:"Required;Email"` + MatchRange int `valid:"Range(10, 20)"` + } + + u := User{ + ReqEmail: "a@a.com", + Email: "", + MatchRange: 0, + } + + valid := Validation{RequiredFirst: true} + b, err := valid.Valid(u) + if err != nil { + t.Fatal(err) + } + if b { + t.Fatal("validation should not be passed") + } + + valid = Validation{RequiredFirst: true} + valid.CanSkipAlso("Range") + b, err = valid.Valid(u) + if err != nil { + t.Fatal(err) + } + if !b { + t.Fatal("validation should be passed") + } + +} +