Merge pull request #130 from joeybloggs/v5-development

Porting Back fixes from v6
pull/132/head
Dean Karn 9 years ago
commit ec0b27fac6
  1. 10
      baked_in.go
  2. 5
      doc.go
  3. 14
      validator.go
  4. 82
      validator_test.go

@ -424,10 +424,12 @@ func hasValue(top interface{}, current interface{}, field interface{}, param str
st := reflect.ValueOf(field) st := reflect.ValueOf(field)
switch st.Kind() { switch st.Kind() {
case reflect.Invalid:
case reflect.Slice, reflect.Map, reflect.Array: return false
return field != nil && int64(st.Len()) > 0 case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func:
return !st.IsNil()
case reflect.Array:
return field != reflect.Zero(reflect.TypeOf(field)).Interface()
default: default:
return field != nil && field != reflect.Zero(reflect.TypeOf(field)).Interface() return field != nil && field != reflect.Zero(reflect.TypeOf(field)).Interface()
} }

@ -193,9 +193,10 @@ Here is a list of the current built in validators:
within its SliceOrArrayErrs or MapErrs fields. within its SliceOrArrayErrs or MapErrs fields.
required required
This validates that the value is not the data types default value. This validates that the value is not the data types default zero value.
For numbers ensures value is not zero. For strings ensures value is For numbers ensures value is not zero. For strings ensures value is
not "". For slices, arrays, and maps, ensures the length is not zero. not "". For slices, maps, pointers, interfaces, channels and functions
ensures the value is not nil.
(Usage: required) (Usage: required)
len len

@ -627,7 +627,11 @@ func (v *Validate) fieldWithNameAndValue(val interface{}, current interface{}, f
f = valueField.Interface() f = valueField.Interface()
} }
cField = &cachedField{name: name, kind: valueField.Kind(), tag: tag, typ: valueField.Type()} cField = &cachedField{name: name, kind: valueField.Kind(), tag: tag}
if cField.kind != reflect.Invalid {
cField.typ = valueField.Type()
}
switch cField.kind { switch cField.kind {
case reflect.Slice, reflect.Array: case reflect.Slice, reflect.Array:
@ -648,8 +652,14 @@ func (v *Validate) fieldWithNameAndValue(val interface{}, current interface{}, f
} }
switch cField.kind { switch cField.kind {
case reflect.Invalid:
return &FieldError{
Field: cField.name,
Tag: cField.tag,
Kind: cField.kind,
}
case reflect.Struct, reflect.Interface, reflect.Invalid: case reflect.Struct, reflect.Interface:
if cField.typ != reflect.TypeOf(time.Time{}) { if cField.typ != reflect.TypeOf(time.Time{}) {
panic("Invalid field passed to fieldWithNameAndValue") panic("Invalid field passed to fieldWithNameAndValue")

@ -231,6 +231,82 @@ func AssertMapFieldError(t *testing.T, s map[string]*FieldError, field string, e
EqualSkip(t, 2, val.Tag, expectedTag) EqualSkip(t, 2, val.Tag, expectedTag)
} }
func TestSliceMapArrayChanFuncPtrInterfaceRequiredValidation(t *testing.T) {
var m map[string]string
errs := validate.Field(m, "required")
NotEqual(t, errs, nil)
// AssertError(t, errs, "", "", "required")
m = map[string]string{}
errs = validate.Field(m, "required")
Equal(t, errs, nil)
var arr [5]string
errs = validate.Field(arr, "required")
NotEqual(t, errs, nil)
// AssertError(t, errs, "", "", "required")
arr[0] = "ok"
errs = validate.Field(arr, "required")
Equal(t, errs, nil)
var s []string
errs = validate.Field(s, "required")
NotEqual(t, errs, nil)
// AssertError(t, errs, "", "", "required")
s = []string{}
errs = validate.Field(s, "required")
Equal(t, errs, nil)
var c chan string
errs = validate.Field(c, "required")
NotEqual(t, errs, nil)
// AssertError(t, errs, "", "", "required")
c = make(chan string)
errs = validate.Field(c, "required")
Equal(t, errs, nil)
var tst *int
errs = validate.Field(tst, "required")
NotEqual(t, errs, nil)
// AssertError(t, errs, "", "", "required")
one := 1
tst = &one
errs = validate.Field(tst, "required")
Equal(t, errs, nil)
var iface interface{}
errs = validate.Field(iface, "required")
NotEqual(t, errs, nil)
// AssertError(t, errs, "", "", "required")
errs = validate.Field(iface, "omitempty,required")
Equal(t, errs, nil)
errs = validate.Field(iface, "")
Equal(t, errs, nil)
errs = validate.Field(iface, "len=1")
NotEqual(t, errs, nil)
var f func(string)
errs = validate.Field(f, "required")
NotEqual(t, errs, nil)
// AssertError(t, errs, "", "", "required")
f = func(name string) {}
errs = validate.Field(f, "required")
Equal(t, errs, nil)
}
func TestBadKeyValidation(t *testing.T) { func TestBadKeyValidation(t *testing.T) {
type Test struct { type Test struct {
Name string `validate:"required, "` Name string `validate:"required, "`
@ -3735,14 +3811,14 @@ func TestStructSliceValidation(t *testing.T) {
Min: []int{1, 2}, Min: []int{1, 2},
Max: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, Max: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0},
MinMax: []int{1, 2, 3, 4, 5}, MinMax: []int{1, 2, 3, 4, 5},
OmitEmpty: []int{}, OmitEmpty: nil,
} }
err := validate.Struct(tSuccess) err := validate.Struct(tSuccess)
Equal(t, err, nil) Equal(t, err, nil)
tFail := &TestSlice{ tFail := &TestSlice{
Required: []int{}, Required: nil,
Len: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1}, Len: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1},
Min: []int{}, Min: []int{},
Max: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1}, Max: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1},
@ -3810,7 +3886,7 @@ func TestPoolObjectMaxSizeValidation(t *testing.T) {
Min: []int{1, 2}, Min: []int{1, 2},
Max: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, Max: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0},
MinMax: []int{1, 2, 3, 4, 5}, MinMax: []int{1, 2, 3, 4, 5},
OmitEmpty: []int{}, OmitEmpty: nil,
} }
for i := 0; i < 2; i++ { for i := 0; i < 2; i++ {

Loading…
Cancel
Save