Skip to content

Commit

Permalink
Merge pull request #191 from OscarVanL/fix/188/validate-embedded-structs
Browse files Browse the repository at this point in the history
fixes #188
  • Loading branch information
inhere committed Dec 28, 2022
2 parents 97f1366 + 1d3b06e commit 0d4b817
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 5 deletions.
8 changes: 3 additions & 5 deletions data_source.go
Expand Up @@ -297,7 +297,6 @@ func (d *StructData) parseRulesFromTag(v *Validation) {
// preStrName - the parent field name.
recursiveFunc = func(vv reflect.Value, vt reflect.Type, parentFName string, parentIsAnonymous bool) {
for i := 0; i < vt.NumField(); i++ {
fValue := removeValuePtr(vv).Field(i)
fv := vt.Field(i)
// skip don't exported field
name := fv.Name
Expand Down Expand Up @@ -365,16 +364,15 @@ func (d *StructData) parseRulesFromTag(v *Validation) {
ft := removeTypePtr(vt.Field(i).Type)

// collect rules from sub-struct and from arrays/slices elements
if ft != timeType {
if fValue.Type().Kind() == reflect.Ptr && fValue.IsNil() {
continue
}
if ft != timeType && removeValuePtr(vv).IsValid() {

// feat: only collect sub-struct rule on current field has rule.
if vRule == "" && gOpt.CheckSubOnParentMarked {
continue
}

fValue := removeValuePtr(vv).Field(i)

switch ft.Kind() {
case reflect.Struct:
recursiveFunc(fValue, ft, name, fv.Anonymous)
Expand Down
95 changes: 95 additions & 0 deletions issues_test.go
@@ -1,6 +1,7 @@
package validate_test

import (
"encoding/json"
"fmt"
"testing"
"time"
Expand Down Expand Up @@ -297,6 +298,100 @@ func TestPtrFieldValidation(t *testing.T) {
assert.False(t, valid.Validate())
}

type Pet struct {
Breed string `json:"breed" validate:"min_len:3"`
Color string `json:"color" validate:"in:orange,black,brown"`
}
type Human struct {
Age int `json:"age" validate:"gt:13"`
Name string `json:"name" validate:"min_len:3"`
}
type Settings struct {
*Pet `json:",omitempty"`
*Human `json:",omitempty"`
}

type Entity struct {
ID string `json:"id" validate:"uuid4"`
Kind string `json:"kind" validate:"in:pet,human"`
Settings Settings `json:"settings"`
}

func (Entity) ConfigValidation(v *validate.Validation) {
v.WithScenes(validate.SValues{
"required": []string{"ID", "Kind"},
"pet": []string{"Settings.Pet"},
"human": []string{"Settings.Human"},
})

}

func TestPtrFieldEmbeddedValid(t *testing.T) {
// Valid case :)
input := []byte(`{
"id": "59fcf270-8646-4250-b4ff-d50f6121bc9d",
"kind": "pet",
"settings": {
"breed": "dog",
"color": "brown"
}
}`)
var entity Entity
err := json.Unmarshal(input, &entity)
fmt.Println(entity)
assert.NoError(t, err)

validate.Config(func(opt *validate.GlobalOption) {
opt.SkipOnEmpty = false
opt.StopOnError = false
})

vld := validate.Struct(&entity)
vld.SkipOnEmpty = false
err = vld.ValidateE("required")
assert.Empty(t, err)
vld.ResetResult()
err = vld.ValidateE(entity.Kind)
assert.Empty(t, err)

validate.ResetOption()
}

func TestPtrFieldEmbeddedInvalid(t *testing.T) {
// Invalid case
input := []byte(`{
"id": "59fcf270-8646-4250-b4ff-d50f6121bc9d",
"kind": "pet",
"settings": {
}
}`)
var entity Entity
err := json.Unmarshal(input, &entity)
fmt.Println(entity)
assert.NoError(t, err)

validate.Config(func(opt *validate.GlobalOption) {
opt.SkipOnEmpty = false
opt.StopOnError = false
})
vld := validate.Struct(&entity)
err = vld.ValidateE("required")
assert.Empty(t, err)
vld.ResetResult()
err = vld.ValidateE(entity.Kind)
expected := validate.Errors{
"breed": validate.MS{
"min_len": "breed min length is 3",
},
"color": validate.MS{
"in": "color value must be in the enum [orange black brown]",
},
}

assert.Equal(t, expected, err)
validate.ResetOption()
}

// ----- test case structs

type Org struct {
Expand Down
8 changes: 8 additions & 0 deletions validation.go
Expand Up @@ -591,6 +591,14 @@ func (v *Validation) isNotNeedToCheck(field string) bool {
return false
}

fields := strings.Split(field, ".")
for i := 0; i < len(fields); i++ {
_, ok := v.sceneFields[strings.Join(fields[0:i], ".")]
if ok {
return false
}
}

_, ok := v.sceneFields[field]
return !ok
}

0 comments on commit 0d4b817

Please sign in to comment.