Skip to content

Commit 98f4165

Browse files
joeybloggsjoeybloggs
authored andcommitted
added time test
fix issue with time.Time data type validation
1 parent a0f6d14 commit 98f4165

File tree

2 files changed

+170
-9
lines changed

2 files changed

+170
-9
lines changed

validator.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ func (v *Validate) structRecursive(top interface{}, current interface{}, s inter
380380

381381
typeField = structType.Field(i)
382382

383-
cField = &cachedField{index: i, tag: typeField.Tag.Get(v.tagName), isTime: valueField.Type() == reflect.TypeOf(time.Time{})}
383+
cField = &cachedField{index: i, tag: typeField.Tag.Get(v.tagName), isTime: (valueField.Type() == reflect.TypeOf(time.Time{}) || valueField.Type() == reflect.TypeOf(&time.Time{}))}
384384

385385
if cField.tag == noValidationTag {
386386
cs.children--
@@ -538,12 +538,12 @@ func (v *Validate) fieldWithNameAndValue(val interface{}, current interface{}, f
538538
case reflect.Slice, reflect.Array:
539539
cField.isSliceOrArray = true
540540
cField.sliceSubtype = cField.typ.Elem()
541-
cField.isTimeSubtype = cField.sliceSubtype == reflect.TypeOf(time.Time{})
541+
cField.isTimeSubtype = (cField.sliceSubtype == reflect.TypeOf(time.Time{}) || cField.sliceSubtype == reflect.TypeOf(&time.Time{}))
542542
cField.sliceSubKind = cField.sliceSubtype.Kind()
543543
case reflect.Map:
544544
cField.isMap = true
545545
cField.mapSubtype = cField.typ.Elem()
546-
cField.isTimeSubtype = cField.mapSubtype == reflect.TypeOf(time.Time{})
546+
cField.isTimeSubtype = (cField.mapSubtype == reflect.TypeOf(time.Time{}) || cField.mapSubtype == reflect.TypeOf(&time.Time{}))
547547
cField.mapSubKind = cField.mapSubtype.Kind()
548548
}
549549
} else {
@@ -555,8 +555,6 @@ func (v *Validate) fieldWithNameAndValue(val interface{}, current interface{}, f
555555
case reflect.Struct, reflect.Interface, reflect.Invalid:
556556

557557
if cField.typ != reflect.TypeOf(time.Time{}) {
558-
559-
fmt.Println(cField.typ)
560558
panic("Invalid field passed to ValidateFieldWithTag")
561559
}
562560
}
@@ -698,7 +696,7 @@ func (v *Validate) traverseSliceOrArray(val interface{}, current interface{}, va
698696
switch cField.sliceSubKind {
699697
case reflect.Struct, reflect.Interface:
700698

701-
if cField.isTimeSubtype || idxField.Type() == reflect.TypeOf(time.Time{}) {
699+
if cField.isTimeSubtype {
702700

703701
if fieldError := v.fieldWithNameAndValue(val, current, idxField.Interface(), cField.diveTag, cField.name, false, nil); fieldError != nil {
704702
errs[i] = fieldError
@@ -722,9 +720,9 @@ func (v *Validate) traverseSliceOrArray(val interface{}, current interface{}, va
722720
Kind: reflect.Ptr,
723721
Type: cField.sliceSubtype,
724722
}
725-
726-
continue
727723
}
724+
725+
continue
728726
}
729727

730728
if structErrors := v.structRecursive(val, current, idxField.Interface()); structErrors != nil {

validator_test.go

Lines changed: 164 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ func TestArrayDiveValidation(t *testing.T) {
361361

362362
errStructPtrArray = append(errStructPtrArray, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}})
363363
errStructPtrArray = append(errStructPtrArray, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}})
364+
errStructPtrArray = append(errStructPtrArray, []*Inner{&Inner{"ok"}, &Inner{""}, nil})
364365

365366
tmsp := &TestMultiDimensionalStructsPtr{
366367
Errs: errStructPtrArray,
@@ -374,7 +375,46 @@ func TestArrayDiveValidation(t *testing.T) {
374375
Equal(t, ok, true)
375376
Equal(t, fieldErr.IsPlaceholderErr, true)
376377
Equal(t, fieldErr.IsSliceOrArray, true)
377-
Equal(t, len(fieldErr.SliceOrArrayErrs), 2)
378+
Equal(t, len(fieldErr.SliceOrArrayErrs), 3)
379+
380+
sliceError1, ok = fieldErr.SliceOrArrayErrs[0].(*FieldError)
381+
Equal(t, ok, true)
382+
Equal(t, sliceError1.IsPlaceholderErr, true)
383+
Equal(t, sliceError1.IsSliceOrArray, true)
384+
Equal(t, len(sliceError1.SliceOrArrayErrs), 2)
385+
386+
innerSliceStructError1, ok = sliceError1.SliceOrArrayErrs[1].(*StructErrors)
387+
Equal(t, ok, true)
388+
Equal(t, len(innerSliceStructError1.Errors), 1)
389+
390+
innerInnersliceError1 = innerSliceStructError1.Errors["Name"]
391+
Equal(t, innerInnersliceError1.IsPlaceholderErr, false)
392+
Equal(t, innerInnersliceError1.IsSliceOrArray, false)
393+
Equal(t, len(innerInnersliceError1.SliceOrArrayErrs), 0)
394+
395+
type TestMultiDimensionalStructsPtr2 struct {
396+
Errs [][]*Inner `validate:"gt=0,dive,dive,required"`
397+
}
398+
399+
var errStructPtr2Array [][]*Inner
400+
401+
errStructPtr2Array = append(errStructPtr2Array, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}})
402+
errStructPtr2Array = append(errStructPtr2Array, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}})
403+
errStructPtr2Array = append(errStructPtr2Array, []*Inner{&Inner{"ok"}, &Inner{""}, nil})
404+
405+
tmsp2 := &TestMultiDimensionalStructsPtr2{
406+
Errs: errStructPtr2Array,
407+
}
408+
409+
errs = validate.Struct(tmsp2)
410+
NotEqual(t, errs, nil)
411+
Equal(t, len(errs.Errors), 1)
412+
413+
fieldErr, ok = errs.Errors["Errs"]
414+
Equal(t, ok, true)
415+
Equal(t, fieldErr.IsPlaceholderErr, true)
416+
Equal(t, fieldErr.IsSliceOrArray, true)
417+
Equal(t, len(fieldErr.SliceOrArrayErrs), 3)
378418

379419
sliceError1, ok = fieldErr.SliceOrArrayErrs[0].(*FieldError)
380420
Equal(t, ok, true)
@@ -390,6 +430,129 @@ func TestArrayDiveValidation(t *testing.T) {
390430
Equal(t, innerInnersliceError1.IsPlaceholderErr, false)
391431
Equal(t, innerInnersliceError1.IsSliceOrArray, false)
392432
Equal(t, len(innerInnersliceError1.SliceOrArrayErrs), 0)
433+
434+
type TestMultiDimensionalStructsPtr3 struct {
435+
Errs [][]*Inner `validate:"gt=0,dive,dive,omitempty"`
436+
}
437+
438+
var errStructPtr3Array [][]*Inner
439+
440+
errStructPtr3Array = append(errStructPtr3Array, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}})
441+
errStructPtr3Array = append(errStructPtr3Array, []*Inner{&Inner{"ok"}, &Inner{""}, &Inner{""}})
442+
errStructPtr3Array = append(errStructPtr3Array, []*Inner{&Inner{"ok"}, &Inner{""}, nil})
443+
444+
tmsp3 := &TestMultiDimensionalStructsPtr3{
445+
Errs: errStructPtr3Array,
446+
}
447+
448+
errs = validate.Struct(tmsp3)
449+
NotEqual(t, errs, nil)
450+
Equal(t, len(errs.Errors), 1)
451+
452+
fieldErr, ok = errs.Errors["Errs"]
453+
Equal(t, ok, true)
454+
Equal(t, fieldErr.IsPlaceholderErr, true)
455+
Equal(t, fieldErr.IsSliceOrArray, true)
456+
Equal(t, len(fieldErr.SliceOrArrayErrs), 3)
457+
458+
sliceError1, ok = fieldErr.SliceOrArrayErrs[0].(*FieldError)
459+
Equal(t, ok, true)
460+
Equal(t, sliceError1.IsPlaceholderErr, true)
461+
Equal(t, sliceError1.IsSliceOrArray, true)
462+
Equal(t, len(sliceError1.SliceOrArrayErrs), 2)
463+
464+
innerSliceStructError1, ok = sliceError1.SliceOrArrayErrs[1].(*StructErrors)
465+
Equal(t, ok, true)
466+
Equal(t, len(innerSliceStructError1.Errors), 1)
467+
468+
innerInnersliceError1 = innerSliceStructError1.Errors["Name"]
469+
Equal(t, innerInnersliceError1.IsPlaceholderErr, false)
470+
Equal(t, innerInnersliceError1.IsSliceOrArray, false)
471+
Equal(t, len(innerInnersliceError1.SliceOrArrayErrs), 0)
472+
473+
type TestMultiDimensionalTimeTime struct {
474+
Errs [][]*time.Time `validate:"gt=0,dive,dive,required"`
475+
}
476+
477+
var errTimePtr3Array [][]*time.Time
478+
479+
t1 := time.Now().UTC()
480+
t2 := time.Now().UTC()
481+
t3 := time.Now().UTC().Add(time.Hour * 24)
482+
483+
errTimePtr3Array = append(errTimePtr3Array, []*time.Time{&t1, &t2, &t3})
484+
errTimePtr3Array = append(errTimePtr3Array, []*time.Time{&t1, &t2, nil})
485+
errTimePtr3Array = append(errTimePtr3Array, []*time.Time{&t1, nil, nil})
486+
487+
tmtp3 := &TestMultiDimensionalTimeTime{
488+
Errs: errTimePtr3Array,
489+
}
490+
491+
errs = validate.Struct(tmtp3)
492+
NotEqual(t, errs, nil)
493+
Equal(t, len(errs.Errors), 1)
494+
495+
fieldErr, ok = errs.Errors["Errs"]
496+
Equal(t, ok, true)
497+
Equal(t, fieldErr.IsPlaceholderErr, true)
498+
Equal(t, fieldErr.IsSliceOrArray, true)
499+
Equal(t, len(fieldErr.SliceOrArrayErrs), 2)
500+
501+
sliceError1, ok = fieldErr.SliceOrArrayErrs[2].(*FieldError)
502+
Equal(t, ok, true)
503+
Equal(t, sliceError1.IsPlaceholderErr, true)
504+
Equal(t, sliceError1.IsSliceOrArray, true)
505+
Equal(t, len(sliceError1.SliceOrArrayErrs), 2)
506+
507+
innerSliceError1, ok = sliceError1.SliceOrArrayErrs[1].(*FieldError)
508+
Equal(t, ok, true)
509+
Equal(t, innerSliceError1.IsPlaceholderErr, false)
510+
Equal(t, innerSliceError1.IsSliceOrArray, false)
511+
Equal(t, len(innerSliceError1.SliceOrArrayErrs), 0)
512+
Equal(t, innerSliceError1.Field, "Errs[2]")
513+
Equal(t, innerSliceError1.Tag, required)
514+
515+
type TestMultiDimensionalTimeTime2 struct {
516+
Errs [][]*time.Time `validate:"gt=0,dive,dive,required"`
517+
}
518+
519+
var errTimeArray [][]*time.Time
520+
521+
t1 = time.Now().UTC()
522+
t2 = time.Now().UTC()
523+
t3 = time.Now().UTC().Add(time.Hour * 24)
524+
525+
errTimeArray = append(errTimeArray, []*time.Time{&t1, &t2, &t3})
526+
errTimeArray = append(errTimeArray, []*time.Time{&t1, &t2, nil})
527+
errTimeArray = append(errTimeArray, []*time.Time{&t1, nil, nil})
528+
529+
tmtp := &TestMultiDimensionalTimeTime2{
530+
Errs: errTimeArray,
531+
}
532+
533+
errs = validate.Struct(tmtp)
534+
NotEqual(t, errs, nil)
535+
Equal(t, len(errs.Errors), 1)
536+
537+
fieldErr, ok = errs.Errors["Errs"]
538+
Equal(t, ok, true)
539+
Equal(t, fieldErr.IsPlaceholderErr, true)
540+
Equal(t, fieldErr.IsSliceOrArray, true)
541+
Equal(t, len(fieldErr.SliceOrArrayErrs), 2)
542+
543+
sliceError1, ok = fieldErr.SliceOrArrayErrs[2].(*FieldError)
544+
Equal(t, ok, true)
545+
Equal(t, sliceError1.IsPlaceholderErr, true)
546+
Equal(t, sliceError1.IsSliceOrArray, true)
547+
Equal(t, len(sliceError1.SliceOrArrayErrs), 2)
548+
549+
innerSliceError1, ok = sliceError1.SliceOrArrayErrs[1].(*FieldError)
550+
Equal(t, ok, true)
551+
Equal(t, innerSliceError1.IsPlaceholderErr, false)
552+
Equal(t, innerSliceError1.IsSliceOrArray, false)
553+
Equal(t, len(innerSliceError1.SliceOrArrayErrs), 0)
554+
Equal(t, innerSliceError1.Field, "Errs[2]")
555+
Equal(t, innerSliceError1.Tag, required)
393556
}
394557

395558
func TestNilStructPointerValidation(t *testing.T) {

0 commit comments

Comments
 (0)