Add some initial validation

change slice errors variable type to map[int]error to allow tracking of index of the error i the array

for #78
pull/82/head
joeybloggs 10 years ago
parent 4afdc19aef
commit d019d02290
  1. 21
      validator.go
  2. 36
      validator_test.go

@ -199,12 +199,13 @@ type FieldError struct {
Type reflect.Type Type reflect.Type
Param string Param string
Value interface{} Value interface{}
isPlaceholderErr bool IsPlaceholderErr bool
IsSliceOrArray bool IsSliceOrArray bool
IsMap bool IsMap bool
// Key interface{} // Key interface{}
// Index int // Index int
SliceOrArrayErrs []error // counld be FieldError, StructErrors // SliceOrArrayErrs []error // counld be FieldError, StructErrors
SliceOrArrayErrs map[int]error // counld be FieldError, StructErrors
MapErrs map[interface{}]error // counld be FieldError, StructErrors MapErrs map[interface{}]error // counld be FieldError, StructErrors
} }
@ -707,7 +708,7 @@ func (v *Validate) fieldWithNameAndValue(val interface{}, current interface{}, f
Kind: cField.kind, Kind: cField.kind,
Type: cField.typ, Type: cField.typ,
Value: f, Value: f,
isPlaceholderErr: true, IsPlaceholderErr: true,
IsSliceOrArray: true, IsSliceOrArray: true,
// Index: i, // Index: i,
SliceOrArrayErrs: errs, SliceOrArrayErrs: errs,
@ -750,9 +751,9 @@ func (v *Validate) fieldWithNameAndValue(val interface{}, current interface{}, f
return nil return nil
} }
func (v *Validate) traverseSliceOrArray(val interface{}, current interface{}, valueField reflect.Value, cField *cachedField) []error { func (v *Validate) traverseSliceOrArray(val interface{}, current interface{}, valueField reflect.Value, cField *cachedField) map[int]error {
errs := make([]error, 0) errs := make(map[int]error, 0)
for i := 0; i < valueField.Len(); i++ { for i := 0; i < valueField.Len(); i++ {
@ -764,7 +765,7 @@ func (v *Validate) traverseSliceOrArray(val interface{}, current interface{}, va
if cField.isTimeSubtype || idxField.Type() == reflect.TypeOf(time.Time{}) { if cField.isTimeSubtype || idxField.Type() == reflect.TypeOf(time.Time{}) {
if fieldError := v.fieldWithNameAndValue(val, current, idxField.Interface(), cField.diveTag, cField.name, true, nil); fieldError != nil { if fieldError := v.fieldWithNameAndValue(val, current, idxField.Interface(), cField.diveTag, cField.name, true, nil); fieldError != nil {
errs = append(errs, fieldError) errs[i] = fieldError
} }
continue continue
@ -778,25 +779,25 @@ func (v *Validate) traverseSliceOrArray(val interface{}, current interface{}, va
if strings.Contains(cField.tag, required) { if strings.Contains(cField.tag, required) {
errs = append(errs, &FieldError{ errs[i] = &FieldError{
Field: cField.name, Field: cField.name,
Tag: required, Tag: required,
Value: idxField.Interface(), Value: idxField.Interface(),
Kind: reflect.Ptr, Kind: reflect.Ptr,
Type: cField.sliceSubtype, Type: cField.sliceSubtype,
}) }
continue continue
} }
} }
if structErrors := v.structRecursive(val, current, idxField.Interface()); structErrors != nil { if structErrors := v.structRecursive(val, current, idxField.Interface()); structErrors != nil {
errs = append(errs, structErrors) errs[i] = structErrors
} }
default: default:
if fieldError := v.fieldWithNameAndValue(val, current, idxField.Interface(), cField.diveTag, cField.name, true, nil); fieldError != nil { if fieldError := v.fieldWithNameAndValue(val, current, idxField.Interface(), cField.diveTag, cField.name, true, nil); fieldError != nil {
errs = append(errs, fieldError) errs[i] = fieldError
} }
} }
} }

@ -237,8 +237,42 @@ func TestArrayDiveValidation(t *testing.T) {
} }
errs := validate.Struct(test) errs := validate.Struct(test)
NotEqual(t, errs, nil)
Equal(t, len(errs.Errors), 1)
fieldErr, ok := errs.Errors["Errs"]
Equal(t, ok, true)
Equal(t, fieldErr.IsPlaceholderErr, true)
Equal(t, fieldErr.IsSliceOrArray, true)
Equal(t, len(fieldErr.SliceOrArrayErrs), 1)
innerErr, ok := fieldErr.SliceOrArrayErrs[1].(*FieldError)
Equal(t, ok, true)
Equal(t, innerErr.Tag, required)
Equal(t, innerErr.IsPlaceholderErr, false)
Equal(t, innerErr.Field, "Errs")
test = &Test{
Errs: []string{"ok", "ok", ""},
}
errs = validate.Struct(test)
NotEqual(t, errs, nil)
Equal(t, len(errs.Errors), 1)
fieldErr, ok = errs.Errors["Errs"]
Equal(t, ok, true)
Equal(t, fieldErr.IsPlaceholderErr, true)
Equal(t, fieldErr.IsSliceOrArray, true)
Equal(t, len(fieldErr.SliceOrArrayErrs), 1)
innerErr, ok = fieldErr.SliceOrArrayErrs[2].(*FieldError)
Equal(t, ok, true)
Equal(t, innerErr.Tag, required)
Equal(t, innerErr.IsPlaceholderErr, false)
Equal(t, innerErr.Field, "Errs")
fmt.Println(errs) fmt.Println(errs.Errors["Errs"].IsPlaceholderErr)
// type TestMap struct { // type TestMap struct {
// Errs *map[int]string `validate:"gt=0,dive,required"` // Errs *map[int]string `validate:"gt=0,dive,required"`

Loading…
Cancel
Save