add more tests

correct pointer issue is traverseArray

for #78
pull/82/head
joeybloggs 10 years ago
parent 689d3e9989
commit a0f6d14ada
  1. 21
      validator.go
  2. 81
      validator_test.go

@ -97,6 +97,7 @@ type cachedField struct {
mapSubtype reflect.Type mapSubtype reflect.Type
sliceSubKind reflect.Kind sliceSubKind reflect.Kind
mapSubKind reflect.Kind mapSubKind reflect.Kind
dive bool
diveTag string diveTag string
} }
@ -174,6 +175,7 @@ func (e *FieldError) Error() string {
if e.IsSliceOrArray { if e.IsSliceOrArray {
for j, err := range e.SliceOrArrayErrs { for j, err := range e.SliceOrArrayErrs {
buff.WriteString("\n")
buff.WriteString(fmt.Sprintf(sliceErrMsg, e.Field, j, "\n"+err.Error())) buff.WriteString(fmt.Sprintf(sliceErrMsg, e.Field, j, "\n"+err.Error()))
} }
@ -184,7 +186,7 @@ func (e *FieldError) Error() string {
} }
} }
return buff.String() return strings.TrimSpace(buff.String())
} }
return fmt.Sprintf(fieldErrMsg, e.Field, e.Tag) return fmt.Sprintf(fieldErrMsg, e.Field, e.Tag)
@ -553,6 +555,8 @@ func (v *Validate) fieldWithNameAndValue(val interface{}, current interface{}, f
case reflect.Struct, reflect.Interface, reflect.Invalid: case reflect.Struct, reflect.Interface, reflect.Invalid:
if cField.typ != reflect.TypeOf(time.Time{}) { if cField.typ != reflect.TypeOf(time.Time{}) {
fmt.Println(cField.typ)
panic("Invalid field passed to ValidateFieldWithTag") panic("Invalid field passed to ValidateFieldWithTag")
} }
} }
@ -569,8 +573,14 @@ func (v *Validate) fieldWithNameAndValue(val interface{}, current interface{}, f
if t == diveTag { if t == diveTag {
cField.dive = true
if k == 0 { if k == 0 {
if len(tag) == 4 {
cField.diveTag = ""
} else {
cField.diveTag = tag[5:] cField.diveTag = tag[5:]
}
} else { } else {
cField.diveTag = strings.SplitN(tag, diveSplit, 2)[1][1:] cField.diveTag = strings.SplitN(tag, diveSplit, 2)[1][1:]
} }
@ -644,7 +654,7 @@ func (v *Validate) fieldWithNameAndValue(val interface{}, current interface{}, f
} }
} }
if len(cField.diveTag) > 0 { if cField.dive {
if cField.isSliceOrArray { if cField.isSliceOrArray {
@ -680,12 +690,17 @@ func (v *Validate) traverseSliceOrArray(val interface{}, current interface{}, va
idxField := valueField.Index(i) idxField := valueField.Index(i)
if cField.sliceSubKind == reflect.Ptr && !idxField.IsNil() {
idxField = idxField.Elem()
cField.sliceSubKind = idxField.Kind()
}
switch cField.sliceSubKind { switch cField.sliceSubKind {
case reflect.Struct, reflect.Interface: case reflect.Struct, reflect.Interface:
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, false, nil); fieldError != nil {
errs[i] = fieldError errs[i] = fieldError
} }

@ -289,7 +289,6 @@ func TestArrayDiveValidation(t *testing.T) {
} }
errs = validate.Struct(tm) errs = validate.Struct(tm)
NotEqual(t, errs, nil) NotEqual(t, errs, nil)
Equal(t, len(errs.Errors), 1) Equal(t, len(errs.Errors), 1)
@ -311,6 +310,86 @@ func TestArrayDiveValidation(t *testing.T) {
Equal(t, innerSliceError1.Tag, required) Equal(t, innerSliceError1.Tag, required)
Equal(t, innerSliceError1.IsSliceOrArray, false) Equal(t, innerSliceError1.IsSliceOrArray, false)
Equal(t, len(innerSliceError1.SliceOrArrayErrs), 0) Equal(t, len(innerSliceError1.SliceOrArrayErrs), 0)
type Inner struct {
Name string `validate:"required"`
}
type TestMultiDimensionalStructs struct {
Errs [][]Inner `validate:"gt=0,dive,dive"`
}
var errStructArray [][]Inner
errStructArray = append(errStructArray, []Inner{Inner{"ok"}, Inner{""}, Inner{""}})
errStructArray = append(errStructArray, []Inner{Inner{"ok"}, Inner{""}, Inner{""}})
tms := &TestMultiDimensionalStructs{
Errs: errStructArray,
}
errs = validate.Struct(tms)
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), 2)
sliceError1, ok = fieldErr.SliceOrArrayErrs[0].(*FieldError)
Equal(t, ok, true)
Equal(t, sliceError1.IsPlaceholderErr, true)
Equal(t, sliceError1.IsSliceOrArray, true)
Equal(t, len(sliceError1.SliceOrArrayErrs), 2)
innerSliceStructError1, ok := sliceError1.SliceOrArrayErrs[1].(*StructErrors)
Equal(t, ok, true)
Equal(t, len(innerSliceStructError1.Errors), 1)
innerInnersliceError1 := innerSliceStructError1.Errors["Name"]
Equal(t, innerInnersliceError1.IsPlaceholderErr, false)
Equal(t, innerInnersliceError1.IsSliceOrArray, false)
Equal(t, len(innerInnersliceError1.SliceOrArrayErrs), 0)
type TestMultiDimensionalStructsPtr struct {
Errs [][]*Inner `validate:"gt=0,dive,dive"`
}
var errStructPtrArray [][]*Inner
errStructPtrArray = append(errStructPtrArray, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}})
errStructPtrArray = append(errStructPtrArray, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}})
tmsp := &TestMultiDimensionalStructsPtr{
Errs: errStructPtrArray,
}
errs = validate.Struct(tmsp)
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), 2)
sliceError1, ok = fieldErr.SliceOrArrayErrs[0].(*FieldError)
Equal(t, ok, true)
Equal(t, sliceError1.IsPlaceholderErr, true)
Equal(t, sliceError1.IsSliceOrArray, true)
Equal(t, len(sliceError1.SliceOrArrayErrs), 2)
innerSliceStructError1, ok = sliceError1.SliceOrArrayErrs[1].(*StructErrors)
Equal(t, ok, true)
Equal(t, len(innerSliceStructError1.Errors), 1)
innerInnersliceError1 = innerSliceStructError1.Errors["Name"]
Equal(t, innerInnersliceError1.IsPlaceholderErr, false)
Equal(t, innerInnersliceError1.IsSliceOrArray, false)
Equal(t, len(innerInnersliceError1.SliceOrArrayErrs), 0)
} }
func TestNilStructPointerValidation(t *testing.T) { func TestNilStructPointerValidation(t *testing.T) {

Loading…
Cancel
Save