diff --git a/validate_test.go b/validate_test.go index 3108020..64d46b3 100644 --- a/validate_test.go +++ b/validate_test.go @@ -2,6 +2,7 @@ package validate_test import ( "errors" + "fmt" "strings" "testing" @@ -40,6 +41,29 @@ func (s *validatableStruct) Validate() error { return s.f() } +type validatableSlice []validatableStruct + +func (s validatableSlice) Validate() error { + var errs error + + if len(s) < 1 { + errs = validate.AppendError(errs, "must contain at least 1 item") + } + + fooVals := map[string]bool{} + for i, item := range s { + if fooVals[item.Foo] { + errs = validate.Append(errs, &validate.Error{ + Field: fmt.Sprintf("%d.Foo", i), + Msg: "is not unique", + }) + } + fooVals[item.Foo] = true + } + + return errs +} + type nestedStruct struct { OtherField *validatableStruct OtherFieldJSON *validatableStruct `json:"other_field,omitempty"` @@ -122,6 +146,31 @@ func TestValidate(t *testing.T) { &validate.Error{Msg: "must not contain space"}, }, }, + { + name: "valid validatable slice type", + obj: validatableSlice{ + {Foo: "Hello"}, + {Foo: "World"}, + }, + wantErrs: []error{}, + }, + { + name: "invalid validatable slice type", + obj: validatableSlice{}, + wantErrs: []error{ + &validate.Error{Msg: "must contain at least 1 item"}, + }, + }, + { + name: "invalid validatable slice type with custom field error", + obj: validatableSlice{ + {Foo: "Hello"}, + {Foo: "Hello"}, + }, + wantErrs: []error{ + &validate.Error{Field: "1.Foo", Msg: "is not unique"}, + }, + }, { name: "single Go error", obj: &validatableStruct{f: func() error { diff --git a/validator.go b/validator.go index d171925..742fe14 100644 --- a/validator.go +++ b/validator.go @@ -83,7 +83,7 @@ func (s *Validator) validate(path []string, data interface{}) error { e := &Error{} if ok := errors.As(err, &e); ok { field := e.Field - if field != "" { + if field != "" && d.Kind() == reflect.Struct { if sf, ok := d.Type().FieldByName(e.Field); ok { field = s.fieldName(sf) }