Skip to content

Commit a0f6d14

Browse files
joeybloggsjoeybloggs
authored andcommitted
add more tests
correct pointer issue is traverseArray for #78
1 parent 689d3e9 commit a0f6d14

File tree

2 files changed

+99
-5
lines changed

2 files changed

+99
-5
lines changed

validator.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ type cachedField struct {
9797
mapSubtype reflect.Type
9898
sliceSubKind reflect.Kind
9999
mapSubKind reflect.Kind
100+
dive bool
100101
diveTag string
101102
}
102103

@@ -174,6 +175,7 @@ func (e *FieldError) Error() string {
174175
if e.IsSliceOrArray {
175176

176177
for j, err := range e.SliceOrArrayErrs {
178+
buff.WriteString("\n")
177179
buff.WriteString(fmt.Sprintf(sliceErrMsg, e.Field, j, "\n"+err.Error()))
178180
}
179181

@@ -184,7 +186,7 @@ func (e *FieldError) Error() string {
184186
}
185187
}
186188

187-
return buff.String()
189+
return strings.TrimSpace(buff.String())
188190
}
189191

190192
return fmt.Sprintf(fieldErrMsg, e.Field, e.Tag)
@@ -553,6 +555,8 @@ func (v *Validate) fieldWithNameAndValue(val interface{}, current interface{}, f
553555
case reflect.Struct, reflect.Interface, reflect.Invalid:
554556

555557
if cField.typ != reflect.TypeOf(time.Time{}) {
558+
559+
fmt.Println(cField.typ)
556560
panic("Invalid field passed to ValidateFieldWithTag")
557561
}
558562
}
@@ -569,8 +573,14 @@ func (v *Validate) fieldWithNameAndValue(val interface{}, current interface{}, f
569573

570574
if t == diveTag {
571575

576+
cField.dive = true
577+
572578
if k == 0 {
573-
cField.diveTag = tag[5:]
579+
if len(tag) == 4 {
580+
cField.diveTag = ""
581+
} else {
582+
cField.diveTag = tag[5:]
583+
}
574584
} else {
575585
cField.diveTag = strings.SplitN(tag, diveSplit, 2)[1][1:]
576586
}
@@ -644,7 +654,7 @@ func (v *Validate) fieldWithNameAndValue(val interface{}, current interface{}, f
644654
}
645655
}
646656

647-
if len(cField.diveTag) > 0 {
657+
if cField.dive {
648658

649659
if cField.isSliceOrArray {
650660

@@ -680,12 +690,17 @@ func (v *Validate) traverseSliceOrArray(val interface{}, current interface{}, va
680690

681691
idxField := valueField.Index(i)
682692

693+
if cField.sliceSubKind == reflect.Ptr && !idxField.IsNil() {
694+
idxField = idxField.Elem()
695+
cField.sliceSubKind = idxField.Kind()
696+
}
697+
683698
switch cField.sliceSubKind {
684699
case reflect.Struct, reflect.Interface:
685700

686701
if cField.isTimeSubtype || idxField.Type() == reflect.TypeOf(time.Time{}) {
687702

688-
if fieldError := v.fieldWithNameAndValue(val, current, idxField.Interface(), cField.diveTag, cField.name, true, nil); fieldError != nil {
703+
if fieldError := v.fieldWithNameAndValue(val, current, idxField.Interface(), cField.diveTag, cField.name, false, nil); fieldError != nil {
689704
errs[i] = fieldError
690705
}
691706

validator_test.go

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,6 @@ func TestArrayDiveValidation(t *testing.T) {
289289
}
290290

291291
errs = validate.Struct(tm)
292-
293292
NotEqual(t, errs, nil)
294293
Equal(t, len(errs.Errors), 1)
295294

@@ -311,6 +310,86 @@ func TestArrayDiveValidation(t *testing.T) {
311310
Equal(t, innerSliceError1.Tag, required)
312311
Equal(t, innerSliceError1.IsSliceOrArray, false)
313312
Equal(t, len(innerSliceError1.SliceOrArrayErrs), 0)
313+
314+
type Inner struct {
315+
Name string `validate:"required"`
316+
}
317+
318+
type TestMultiDimensionalStructs struct {
319+
Errs [][]Inner `validate:"gt=0,dive,dive"`
320+
}
321+
322+
var errStructArray [][]Inner
323+
324+
errStructArray = append(errStructArray, []Inner{Inner{"ok"}, Inner{""}, Inner{""}})
325+
errStructArray = append(errStructArray, []Inner{Inner{"ok"}, Inner{""}, Inner{""}})
326+
327+
tms := &TestMultiDimensionalStructs{
328+
Errs: errStructArray,
329+
}
330+
331+
errs = validate.Struct(tms)
332+
NotEqual(t, errs, nil)
333+
Equal(t, len(errs.Errors), 1)
334+
335+
fieldErr, ok = errs.Errors["Errs"]
336+
Equal(t, ok, true)
337+
Equal(t, fieldErr.IsPlaceholderErr, true)
338+
Equal(t, fieldErr.IsSliceOrArray, true)
339+
Equal(t, len(fieldErr.SliceOrArrayErrs), 2)
340+
341+
sliceError1, ok = fieldErr.SliceOrArrayErrs[0].(*FieldError)
342+
Equal(t, ok, true)
343+
Equal(t, sliceError1.IsPlaceholderErr, true)
344+
Equal(t, sliceError1.IsSliceOrArray, true)
345+
Equal(t, len(sliceError1.SliceOrArrayErrs), 2)
346+
347+
innerSliceStructError1, ok := sliceError1.SliceOrArrayErrs[1].(*StructErrors)
348+
Equal(t, ok, true)
349+
Equal(t, len(innerSliceStructError1.Errors), 1)
350+
351+
innerInnersliceError1 := innerSliceStructError1.Errors["Name"]
352+
Equal(t, innerInnersliceError1.IsPlaceholderErr, false)
353+
Equal(t, innerInnersliceError1.IsSliceOrArray, false)
354+
Equal(t, len(innerInnersliceError1.SliceOrArrayErrs), 0)
355+
356+
type TestMultiDimensionalStructsPtr struct {
357+
Errs [][]*Inner `validate:"gt=0,dive,dive"`
358+
}
359+
360+
var errStructPtrArray [][]*Inner
361+
362+
errStructPtrArray = append(errStructPtrArray, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}})
363+
errStructPtrArray = append(errStructPtrArray, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}})
364+
365+
tmsp := &TestMultiDimensionalStructsPtr{
366+
Errs: errStructPtrArray,
367+
}
368+
369+
errs = validate.Struct(tmsp)
370+
NotEqual(t, errs, nil)
371+
Equal(t, len(errs.Errors), 1)
372+
373+
fieldErr, ok = errs.Errors["Errs"]
374+
Equal(t, ok, true)
375+
Equal(t, fieldErr.IsPlaceholderErr, true)
376+
Equal(t, fieldErr.IsSliceOrArray, true)
377+
Equal(t, len(fieldErr.SliceOrArrayErrs), 2)
378+
379+
sliceError1, ok = fieldErr.SliceOrArrayErrs[0].(*FieldError)
380+
Equal(t, ok, true)
381+
Equal(t, sliceError1.IsPlaceholderErr, true)
382+
Equal(t, sliceError1.IsSliceOrArray, true)
383+
Equal(t, len(sliceError1.SliceOrArrayErrs), 2)
384+
385+
innerSliceStructError1, ok = sliceError1.SliceOrArrayErrs[1].(*StructErrors)
386+
Equal(t, ok, true)
387+
Equal(t, len(innerSliceStructError1.Errors), 1)
388+
389+
innerInnersliceError1 = innerSliceStructError1.Errors["Name"]
390+
Equal(t, innerInnersliceError1.IsPlaceholderErr, false)
391+
Equal(t, innerInnersliceError1.IsSliceOrArray, false)
392+
Equal(t, len(innerInnersliceError1.SliceOrArrayErrs), 0)
314393
}
315394

316395
func TestNilStructPointerValidation(t *testing.T) {

0 commit comments

Comments
 (0)