Skip to content

Commit 200a5b4

Browse files
joeybloggsjoeybloggs
authored andcommitted
finish map error handling & complete test coverage
for #78
1 parent 8bf793a commit 200a5b4

File tree

2 files changed

+97
-14
lines changed

2 files changed

+97
-14
lines changed

validator.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -697,8 +697,6 @@ func (v *Validate) traverseMap(val interface{}, current interface{}, valueField
697697
cField.mapSubKind = idxField.Kind()
698698
}
699699

700-
// fmt.Println(cField.sliceSubKind)
701-
702700
switch cField.mapSubKind {
703701
case reflect.Struct, reflect.Interface:
704702

@@ -720,7 +718,7 @@ func (v *Validate) traverseMap(val interface{}, current interface{}, valueField
720718
if strings.Contains(cField.tag, required) {
721719

722720
errs[key.Interface()] = &FieldError{
723-
Field: cField.name,
721+
Field: fmt.Sprintf(mapIndexFieldName, cField.name, key.Interface()),
724722
Tag: required,
725723
Value: idxField.Interface(),
726724
Kind: reflect.Ptr,
@@ -779,7 +777,7 @@ func (v *Validate) traverseSliceOrArray(val interface{}, current interface{}, va
779777
if strings.Contains(cField.tag, required) {
780778

781779
errs[i] = &FieldError{
782-
Field: cField.name,
780+
Field: fmt.Sprintf(arrayIndexFieldName, cField.name, i),
783781
Tag: required,
784782
Value: idxField.Interface(),
785783
Kind: reflect.Ptr,

validator_test.go

Lines changed: 95 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -257,19 +257,95 @@ func TestMapDiveValidation(t *testing.T) {
257257
}
258258

259259
errs := validate.Struct(ms)
260+
NotEqual(t, errs, nil)
261+
Equal(t, len(errs.Errors), 1)
262+
// for full test coverage
263+
fmt.Sprint(errs.Error())
264+
265+
fieldError := errs.Errors["Errs"]
266+
Equal(t, fieldError.IsPlaceholderErr, true)
267+
Equal(t, fieldError.IsMap, true)
268+
Equal(t, len(fieldError.MapErrs), 1)
269+
270+
structErr, ok := fieldError.MapErrs[3].(*StructErrors)
271+
Equal(t, ok, true)
272+
Equal(t, len(structErr.Errors), 1)
273+
274+
innerErr := structErr.Errors["Name"]
275+
Equal(t, innerErr.IsPlaceholderErr, false)
276+
Equal(t, innerErr.IsMap, false)
277+
Equal(t, len(innerErr.MapErrs), 0)
278+
Equal(t, innerErr.Field, "Name")
279+
Equal(t, innerErr.Tag, "required")
280+
281+
type TestMapTimeStruct struct {
282+
Errs map[int]*time.Time `validate:"gt=0,dive,required"`
283+
}
284+
285+
t1 := time.Now().UTC()
286+
287+
mta := map[int]*time.Time{0: &t1, 3: nil, 4: nil}
288+
289+
mt := &TestMapTimeStruct{
290+
Errs: mta,
291+
}
292+
293+
errs = validate.Struct(mt)
294+
NotEqual(t, errs, nil)
295+
Equal(t, len(errs.Errors), 1)
260296

261-
fmt.Println(errs)
297+
fieldError = errs.Errors["Errs"]
298+
Equal(t, fieldError.IsPlaceholderErr, true)
299+
Equal(t, fieldError.IsMap, true)
300+
Equal(t, len(fieldError.MapErrs), 2)
262301

263-
// type Test struct {
264-
// Errs map[int]string `validate:"gt=0,dive,required"`
265-
// }
302+
innerErr, ok = fieldError.MapErrs[3].(*FieldError)
303+
Equal(t, ok, true)
304+
Equal(t, innerErr.IsPlaceholderErr, false)
305+
Equal(t, innerErr.IsMap, false)
306+
Equal(t, len(innerErr.MapErrs), 0)
307+
Equal(t, innerErr.Field, "Errs[3]")
308+
Equal(t, innerErr.Tag, "required")
266309

267-
// test := &Test{
268-
// Errs: map[int]string{0: "ok", 1: "", 4: "ok"},
269-
// }
310+
type TestMapStructPtr struct {
311+
Errs map[int]*Inner `validate:"gt=0,dive,required"`
312+
}
270313

271-
// errs := validate.Struct(test)
272-
// NotEqual(t, errs, nil)
314+
mip := map[int]*Inner{0: &Inner{"ok"}, 3: nil, 4: &Inner{"ok"}}
315+
316+
msp := &TestMapStructPtr{
317+
Errs: mip,
318+
}
319+
320+
errs = validate.Struct(msp)
321+
NotEqual(t, errs, nil)
322+
Equal(t, len(errs.Errors), 1)
323+
324+
fieldError = errs.Errors["Errs"]
325+
Equal(t, fieldError.IsPlaceholderErr, true)
326+
Equal(t, fieldError.IsMap, true)
327+
Equal(t, len(fieldError.MapErrs), 1)
328+
329+
innerFieldError, ok := fieldError.MapErrs[3].(*FieldError)
330+
Equal(t, ok, true)
331+
Equal(t, innerFieldError.IsPlaceholderErr, false)
332+
Equal(t, innerFieldError.IsMap, false)
333+
Equal(t, len(innerFieldError.MapErrs), 0)
334+
Equal(t, innerFieldError.Field, "Errs[3]")
335+
Equal(t, innerFieldError.Tag, "required")
336+
337+
type TestMapStructPtr2 struct {
338+
Errs map[int]*Inner `validate:"gt=0,dive,omitempty,required"`
339+
}
340+
341+
mip2 := map[int]*Inner{0: &Inner{"ok"}, 3: nil, 4: &Inner{"ok"}}
342+
343+
msp2 := &TestMapStructPtr2{
344+
Errs: mip2,
345+
}
346+
347+
errs = validate.Struct(msp2)
348+
Equal(t, errs, nil)
273349
}
274350

275351
func TestArrayDiveValidation(t *testing.T) {
@@ -437,6 +513,8 @@ func TestArrayDiveValidation(t *testing.T) {
437513
errs = validate.Struct(tmsp)
438514
NotEqual(t, errs, nil)
439515
Equal(t, len(errs.Errors), 1)
516+
// for full test coverage
517+
fmt.Sprint(errs.Error())
440518

441519
fieldErr, ok = errs.Errors["Errs"]
442520
Equal(t, ok, true)
@@ -483,7 +561,7 @@ func TestArrayDiveValidation(t *testing.T) {
483561
Equal(t, fieldErr.IsSliceOrArray, true)
484562
Equal(t, len(fieldErr.SliceOrArrayErrs), 3)
485563

486-
sliceError1, ok = fieldErr.SliceOrArrayErrs[0].(*FieldError)
564+
sliceError1, ok = fieldErr.SliceOrArrayErrs[2].(*FieldError)
487565
Equal(t, ok, true)
488566
Equal(t, sliceError1.IsPlaceholderErr, true)
489567
Equal(t, sliceError1.IsSliceOrArray, true)
@@ -493,6 +571,13 @@ func TestArrayDiveValidation(t *testing.T) {
493571
Equal(t, ok, true)
494572
Equal(t, len(innerSliceStructError1.Errors), 1)
495573

574+
innerSliceStructError2, ok := sliceError1.SliceOrArrayErrs[2].(*FieldError)
575+
Equal(t, ok, true)
576+
Equal(t, innerSliceStructError2.IsPlaceholderErr, false)
577+
Equal(t, innerSliceStructError2.IsSliceOrArray, false)
578+
Equal(t, len(innerSliceStructError2.SliceOrArrayErrs), 0)
579+
Equal(t, innerSliceStructError2.Field, "Errs[2][2]")
580+
496581
innerInnersliceError1 = innerSliceStructError1.Errors["Name"]
497582
Equal(t, innerInnersliceError1.IsPlaceholderErr, false)
498583
Equal(t, innerInnersliceError1.IsSliceOrArray, false)

0 commit comments

Comments
 (0)