Fix support for aliased time.Duration types

pull/937/head
tom twinkle 3 years ago
parent 9e2ea40380
commit 8e94f1ae3a
  1. 5
      util.go
  2. 320
      validator_test.go

@ -243,10 +243,9 @@ func asIntFromTimeDuration(param string) int64 {
// asIntFromType calls the proper function to parse param as int64, // asIntFromType calls the proper function to parse param as int64,
// given a field's Type t. // given a field's Type t.
func asIntFromType(t reflect.Type, param string) int64 { func asIntFromType(t reflect.Type, param string) int64 {
switch t { if t.ConvertibleTo(timeDurationType) {
case timeDurationType:
return asIntFromTimeDuration(param) return asIntFromTimeDuration(param)
default: } else {
return asInt(param) return asInt(param)
} }
} }

@ -1126,6 +1126,47 @@ func TestCrossStructLteFieldValidation(t *testing.T) {
timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)} timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)}
errs = validate.Struct(timeDurationOmitemptyTest) errs = validate.Struct(timeDurationOmitemptyTest)
Equal(t, errs, nil) Equal(t, errs, nil)
// -- Validations for a struct and an inner struct with time.Duration alias type fields.
type DurationAlias time.Duration
type TimeDurationAliasInner struct {
Duration DurationAlias
}
var timeDurationAliasInner *TimeDurationAliasInner
type TimeDurationAliasTest struct {
Inner *TimeDurationAliasInner
Duration DurationAlias `validate:"ltecsfield=Inner.Duration"`
}
var timeDurationAliasTest *TimeDurationAliasTest
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(time.Hour + time.Minute)}
timeDurationAliasTest = &TimeDurationAliasTest{timeDurationAliasInner, DurationAlias(time.Hour)}
errs = validate.Struct(timeDurationAliasTest)
Equal(t, errs, nil)
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(time.Hour)}
timeDurationAliasTest = &TimeDurationAliasTest{timeDurationAliasInner, DurationAlias(time.Hour)}
errs = validate.Struct(timeDurationAliasTest)
Equal(t, errs, nil)
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(time.Hour - time.Minute)}
timeDurationAliasTest = &TimeDurationAliasTest{timeDurationAliasInner, DurationAlias(time.Hour)}
errs = validate.Struct(timeDurationAliasTest)
NotEqual(t, errs, nil)
AssertError(t, errs, "TimeDurationAliasTest.Duration", "TimeDurationAliasTest.Duration", "Duration", "Duration", "ltecsfield")
type TimeDurationAliasOmitemptyTest struct {
Inner *TimeDurationAliasInner
Duration DurationAlias `validate:"omitempty,ltecsfield=Inner.Duration"`
}
var timeDurationAliasOmitemptyTest *TimeDurationAliasOmitemptyTest
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(-time.Minute)}
timeDurationAliasOmitemptyTest = &TimeDurationAliasOmitemptyTest{timeDurationAliasInner, DurationAlias(0)}
errs = validate.Struct(timeDurationAliasOmitemptyTest)
Equal(t, errs, nil)
} }
func TestCrossStructLtFieldValidation(t *testing.T) { func TestCrossStructLtFieldValidation(t *testing.T) {
@ -1282,6 +1323,48 @@ func TestCrossStructLtFieldValidation(t *testing.T) {
timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)} timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)}
errs = validate.Struct(timeDurationOmitemptyTest) errs = validate.Struct(timeDurationOmitemptyTest)
Equal(t, errs, nil) Equal(t, errs, nil)
// -- Validations for a struct and an inner struct with time.Duration alias type fields.
type DurationAlias time.Duration
type TimeDurationAliasInner struct {
Duration DurationAlias
}
var timeDurationAliasInner *TimeDurationAliasInner
type TimeDurationAliasTest struct {
Inner *TimeDurationAliasInner
Duration DurationAlias `validate:"ltcsfield=Inner.Duration"`
}
var timeDurationAliasTest *TimeDurationAliasTest
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(time.Hour + time.Minute)}
timeDurationAliasTest = &TimeDurationAliasTest{timeDurationAliasInner, DurationAlias(time.Hour)}
errs = validate.Struct(timeDurationAliasTest)
Equal(t, errs, nil)
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(time.Hour)}
timeDurationAliasTest = &TimeDurationAliasTest{timeDurationAliasInner, DurationAlias(time.Hour)}
errs = validate.Struct(timeDurationAliasTest)
NotEqual(t, errs, nil)
AssertError(t, errs, "TimeDurationAliasTest.Duration", "TimeDurationAliasTest.Duration", "Duration", "Duration", "ltcsfield")
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(time.Hour - time.Minute)}
timeDurationAliasTest = &TimeDurationAliasTest{timeDurationAliasInner, DurationAlias(time.Hour)}
errs = validate.Struct(timeDurationAliasTest)
NotEqual(t, errs, nil)
AssertError(t, errs, "TimeDurationAliasTest.Duration", "TimeDurationAliasTest.Duration", "Duration", "Duration", "ltcsfield")
type TimeDurationAliasOmitemptyTest struct {
Inner *TimeDurationAliasInner
Duration DurationAlias `validate:"omitempty,ltcsfield=Inner.Duration"`
}
var timeDurationAliasOmitemptyTest *TimeDurationAliasOmitemptyTest
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(-time.Minute)}
timeDurationAliasOmitemptyTest = &TimeDurationAliasOmitemptyTest{timeDurationAliasInner, DurationAlias(0)}
errs = validate.Struct(timeDurationAliasOmitemptyTest)
Equal(t, errs, nil)
} }
func TestCrossStructGteFieldValidation(t *testing.T) { func TestCrossStructGteFieldValidation(t *testing.T) {
@ -1448,6 +1531,47 @@ func TestCrossStructGteFieldValidation(t *testing.T) {
timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)} timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)}
errs = validate.Struct(timeDurationOmitemptyTest) errs = validate.Struct(timeDurationOmitemptyTest)
Equal(t, errs, nil) Equal(t, errs, nil)
// -- Validations for a struct and an inner struct with time.Duration alias type fields.
type DurationAlias time.Duration
type TimeDurationAliasInner struct {
Duration DurationAlias
}
var timeDurationAliasInner *TimeDurationAliasInner
type TimeDurationAliasTest struct {
Inner *TimeDurationAliasInner
Duration DurationAlias `validate:"gtecsfield=Inner.Duration"`
}
var timeDurationAliasTest *TimeDurationAliasTest
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(time.Hour - time.Minute)}
timeDurationAliasTest = &TimeDurationAliasTest{timeDurationAliasInner, DurationAlias(time.Hour)}
errs = validate.Struct(timeDurationAliasTest)
Equal(t, errs, nil)
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(time.Hour)}
timeDurationAliasTest = &TimeDurationAliasTest{timeDurationAliasInner, DurationAlias(time.Hour)}
errs = validate.Struct(timeDurationAliasTest)
Equal(t, errs, nil)
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(time.Hour + time.Minute)}
timeDurationAliasTest = &TimeDurationAliasTest{timeDurationAliasInner, DurationAlias(time.Hour)}
errs = validate.Struct(timeDurationAliasTest)
NotEqual(t, errs, nil)
AssertError(t, errs, "TimeDurationAliasTest.Duration", "TimeDurationAliasTest.Duration", "Duration", "Duration", "gtecsfield")
type TimeDurationAliasOmitemptyTest struct {
Inner *TimeDurationAliasInner
Duration DurationAlias `validate:"omitempty,gtecsfield=Inner.Duration"`
}
var timeDurationAliasOmitemptyTest *TimeDurationAliasOmitemptyTest
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(time.Hour)}
timeDurationAliasOmitemptyTest = &TimeDurationAliasOmitemptyTest{timeDurationAliasInner, DurationAlias(0)}
errs = validate.Struct(timeDurationAliasOmitemptyTest)
Equal(t, errs, nil)
} }
func TestCrossStructGtFieldValidation(t *testing.T) { func TestCrossStructGtFieldValidation(t *testing.T) {
@ -1604,6 +1728,48 @@ func TestCrossStructGtFieldValidation(t *testing.T) {
timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)} timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)}
errs = validate.Struct(timeDurationOmitemptyTest) errs = validate.Struct(timeDurationOmitemptyTest)
Equal(t, errs, nil) Equal(t, errs, nil)
// -- Validations for a struct and an inner struct with time.Duration alias type fields.
type DurationAlias time.Duration
type TimeDurationAliasInner struct {
Duration DurationAlias
}
var timeDurationAliasInner *TimeDurationAliasInner
type TimeDurationAliasTest struct {
Inner *TimeDurationAliasInner
Duration DurationAlias `validate:"gtcsfield=Inner.Duration"`
}
var timeDurationAliasTest *TimeDurationAliasTest
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(time.Hour - time.Minute)}
timeDurationAliasTest = &TimeDurationAliasTest{timeDurationAliasInner, DurationAlias(time.Hour)}
errs = validate.Struct(timeDurationAliasTest)
Equal(t, errs, nil)
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(time.Hour)}
timeDurationAliasTest = &TimeDurationAliasTest{timeDurationAliasInner, DurationAlias(time.Hour)}
errs = validate.Struct(timeDurationAliasTest)
NotEqual(t, errs, nil)
AssertError(t, errs, "TimeDurationAliasTest.Duration", "TimeDurationAliasTest.Duration", "Duration", "Duration", "gtcsfield")
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(time.Hour + time.Minute)}
timeDurationAliasTest = &TimeDurationAliasTest{timeDurationAliasInner, DurationAlias(time.Hour)}
errs = validate.Struct(timeDurationAliasTest)
NotEqual(t, errs, nil)
AssertError(t, errs, "TimeDurationAliasTest.Duration", "TimeDurationAliasTest.Duration", "Duration", "Duration", "gtcsfield")
type TimeDurationAliasOmitemptyTest struct {
Inner *TimeDurationAliasInner
Duration DurationAlias `validate:"omitempty,gtcsfield=Inner.Duration"`
}
var timeDurationAliasOmitemptyTest *TimeDurationAliasOmitemptyTest
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(time.Hour)}
timeDurationAliasOmitemptyTest = &TimeDurationAliasOmitemptyTest{timeDurationAliasInner, DurationAlias(0)}
errs = validate.Struct(timeDurationAliasOmitemptyTest)
Equal(t, errs, nil)
} }
func TestCrossStructNeFieldValidation(t *testing.T) { func TestCrossStructNeFieldValidation(t *testing.T) {
@ -1776,6 +1942,47 @@ func TestCrossStructNeFieldValidation(t *testing.T) {
timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)} timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)}
errs = validate.Struct(timeDurationOmitemptyTest) errs = validate.Struct(timeDurationOmitemptyTest)
Equal(t, errs, nil) Equal(t, errs, nil)
// -- Validations for a struct and an inner struct with time.Duration alias type fields.
type DurationAlias time.Duration
type TimeDurationAliasInner struct {
Duration DurationAlias
}
var timeDurationAliasInner *TimeDurationAliasInner
type TimeDurationAliasTest struct {
Inner *TimeDurationAliasInner
Duration DurationAlias `validate:"necsfield=Inner.Duration"`
}
var timeDurationAliasTest *TimeDurationAliasTest
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(time.Hour - time.Minute)}
timeDurationAliasTest = &TimeDurationAliasTest{timeDurationAliasInner, DurationAlias(time.Hour)}
errs = validate.Struct(timeDurationAliasTest)
Equal(t, errs, nil)
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(time.Hour + time.Minute)}
timeDurationAliasTest = &TimeDurationAliasTest{timeDurationAliasInner, DurationAlias(time.Hour)}
errs = validate.Struct(timeDurationAliasTest)
Equal(t, errs, nil)
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(time.Hour)}
timeDurationAliasTest = &TimeDurationAliasTest{timeDurationAliasInner, DurationAlias(time.Hour)}
errs = validate.Struct(timeDurationAliasTest)
NotEqual(t, errs, nil)
AssertError(t, errs, "TimeDurationAliasTest.Duration", "TimeDurationAliasTest.Duration", "Duration", "Duration", "necsfield")
type TimeDurationAliasOmitemptyTest struct {
Inner *TimeDurationAliasInner
Duration DurationAlias `validate:"omitempty,necsfield=Inner.Duration"`
}
var timeDurationAliasOmitemptyTest *TimeDurationAliasOmitemptyTest
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(0)}
timeDurationAliasOmitemptyTest = &TimeDurationAliasOmitemptyTest{timeDurationAliasInner, DurationAlias(0)}
errs = validate.Struct(timeDurationAliasOmitemptyTest)
Equal(t, errs, nil)
} }
func TestCrossStructEqFieldValidation(t *testing.T) { func TestCrossStructEqFieldValidation(t *testing.T) {
@ -1946,6 +2153,48 @@ func TestCrossStructEqFieldValidation(t *testing.T) {
timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)} timeDurationOmitemptyTest = &TimeDurationOmitemptyTest{timeDurationInner, time.Duration(0)}
errs = validate.Struct(timeDurationOmitemptyTest) errs = validate.Struct(timeDurationOmitemptyTest)
Equal(t, errs, nil) Equal(t, errs, nil)
// -- Validations for a struct and an inner struct with time.Duration alias type fields.
type DurationAlias time.Duration
type TimeDurationAliasInner struct {
Duration DurationAlias
}
var timeDurationAliasInner *TimeDurationAliasInner
type TimeDurationAliasTest struct {
Inner *TimeDurationAliasInner
Duration DurationAlias `validate:"eqcsfield=Inner.Duration"`
}
var timeDurationAliasTest *TimeDurationAliasTest
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(time.Hour)}
timeDurationAliasTest = &TimeDurationAliasTest{timeDurationAliasInner, DurationAlias(time.Hour)}
errs = validate.Struct(timeDurationAliasTest)
Equal(t, errs, nil)
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(time.Hour - time.Minute)}
timeDurationAliasTest = &TimeDurationAliasTest{timeDurationAliasInner, DurationAlias(time.Hour)}
errs = validate.Struct(timeDurationAliasTest)
NotEqual(t, errs, nil)
AssertError(t, errs, "TimeDurationAliasTest.Duration", "TimeDurationAliasTest.Duration", "Duration", "Duration", "eqcsfield")
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(time.Hour + time.Minute)}
timeDurationAliasTest = &TimeDurationAliasTest{timeDurationAliasInner, DurationAlias(time.Hour)}
errs = validate.Struct(timeDurationAliasTest)
NotEqual(t, errs, nil)
AssertError(t, errs, "TimeDurationAliasTest.Duration", "TimeDurationAliasTest.Duration", "Duration", "Duration", "eqcsfield")
type TimeDurationAliasOmitemptyTest struct {
Inner *TimeDurationAliasInner
Duration DurationAlias `validate:"omitempty,eqcsfield=Inner.Duration"`
}
var timeDurationAliasOmitemptyTest *TimeDurationAliasOmitemptyTest
timeDurationAliasInner = &TimeDurationAliasInner{DurationAlias(time.Hour)}
timeDurationAliasOmitemptyTest = &TimeDurationAliasOmitemptyTest{timeDurationAliasInner, DurationAlias(0)}
errs = validate.Struct(timeDurationAliasOmitemptyTest)
Equal(t, errs, nil)
} }
func TestCrossNamespaceFieldValidation(t *testing.T) { func TestCrossNamespaceFieldValidation(t *testing.T) {
@ -5402,6 +5651,33 @@ func TestIsEqFieldValidationWithAliasTime(t *testing.T) {
Equal(t, errs, nil) Equal(t, errs, nil)
} }
func TestMaxValidationWithAliasTimeDuration(t *testing.T) {
var errs error
validate := New()
type CustomDuration time.Duration
type Test struct {
ParamInt CustomDuration `validate:"max=1000000000"`
ParamDurationString CustomDuration `validate:"max=1s"`
ParamIntP *CustomDuration `validate:"max=1000000000"`
ParamDurationStringP *CustomDuration `validate:"max=1s"`
}
duration := time.Second
customDuration := CustomDuration(duration)
sv := &Test{
ParamInt: customDuration,
ParamDurationString: customDuration,
ParamIntP: &customDuration,
ParamDurationStringP: &customDuration,
}
errs = validate.Struct(sv)
Equal(t, errs, nil)
}
func TestIsEqValidation(t *testing.T) { func TestIsEqValidation(t *testing.T) {
var errs error var errs error
validate := New() validate := New()
@ -12264,25 +12540,25 @@ func TestCreditCardFormatValidation(t *testing.T) {
} }
func TestMultiOrOperatorGroup(t *testing.T) { func TestMultiOrOperatorGroup(t *testing.T) {
tests := []struct { tests := []struct {
Value int `validate:"eq=1|gte=5,eq=1|lt=7"` Value int `validate:"eq=1|gte=5,eq=1|lt=7"`
expected bool expected bool
}{ }{
{1, true}, {2, false}, {5, true}, {6, true}, {8, false}, {1, true}, {2, false}, {5, true}, {6, true}, {8, false},
} }
validate := New() validate := New()
for i, test := range tests { for i, test := range tests {
errs := validate.Struct(test) errs := validate.Struct(test)
if test.expected { if test.expected {
if !IsEqual(errs, nil) { if !IsEqual(errs, nil) {
t.Fatalf("Index: %d multi_group_of_OR_operators failed Error: %s", i, errs) t.Fatalf("Index: %d multi_group_of_OR_operators failed Error: %s", i, errs)
} }
} else { } else {
if IsEqual(errs, nil) { if IsEqual(errs, nil) {
t.Fatalf("Index: %d multi_group_of_OR_operators should have errs", i) t.Fatalf("Index: %d multi_group_of_OR_operators should have errs", i)
} }
} }
} }
} }

Loading…
Cancel
Save