add lt validation function + test code
add lte validation function + test code
add gt validation function + test code
add get validation function + test code
pull/16/head
Dean Karn 10 years ago
parent b1ff752828
commit 2073d33609
  1. 116
      baked_in.go
  2. 21
      doc.go
  3. 40
      validator_test.go

@ -13,6 +13,10 @@ var BakedInValidators = map[string]ValidationFunc{
"len": length,
"min": min,
"max": max,
"lt": lt,
"lte": lte,
"gt": gt,
"gte": gte,
"alpha": alpha,
"alphanum": alphanum,
"numeric": numeric,
@ -183,6 +187,78 @@ func required(field interface{}, param string) bool {
}
}
func gte(field interface{}, param string) bool {
st := reflect.ValueOf(field)
switch st.Kind() {
case reflect.String:
p := asInt(param)
return int64(len(st.String())) >= p
case reflect.Slice, reflect.Map, reflect.Array:
p := asInt(param)
return int64(st.Len()) >= p
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
p := asInt(param)
return st.Int() >= p
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
p := asUint(param)
return st.Uint() >= p
case reflect.Float32, reflect.Float64:
p := asFloat(param)
return st.Float() >= p
default:
panic(fmt.Sprintf("Bad field type for Input Param %s for %s\n", param, field))
}
}
func gt(field interface{}, param string) bool {
st := reflect.ValueOf(field)
switch st.Kind() {
case reflect.String:
p := asInt(param)
return int64(len(st.String())) > p
case reflect.Slice, reflect.Map, reflect.Array:
p := asInt(param)
return int64(st.Len()) > p
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
p := asInt(param)
return st.Int() > p
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
p := asUint(param)
return st.Uint() > p
case reflect.Float32, reflect.Float64:
p := asFloat(param)
return st.Float() > p
default:
panic(fmt.Sprintf("Bad field type for Input Param %s for %s\n", param, field))
}
}
// length tests whether a variable's length is equal to a given
// value. For strings it tests the number of characters whereas
// for maps and slices it tests the number of items.
@ -228,6 +304,11 @@ func length(field interface{}, param string) bool {
// and slices it tests the number of items.
func min(field interface{}, param string) bool {
return gte(field, param)
}
func lte(field interface{}, param string) bool {
st := reflect.ValueOf(field)
switch st.Kind() {
@ -235,38 +316,34 @@ func min(field interface{}, param string) bool {
case reflect.String:
p := asInt(param)
return int64(len(st.String())) >= p
return int64(len(st.String())) <= p
case reflect.Slice, reflect.Map, reflect.Array:
p := asInt(param)
return int64(st.Len()) >= p
return int64(st.Len()) <= p
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
p := asInt(param)
return st.Int() >= p
return st.Int() <= p
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
p := asUint(param)
return st.Uint() >= p
return st.Uint() <= p
case reflect.Float32, reflect.Float64:
p := asFloat(param)
return st.Float() >= p
return st.Float() <= p
default:
panic(fmt.Sprintf("Bad field type for Input Param %s for %s\n", param, field))
}
}
// max tests whether a variable value is lesser than a given
// value. For numbers, it's a simple lesser-than test; for
// strings it tests the number of characters whereas for maps
// and slices it tests the number of items.
func max(field interface{}, param string) bool {
func lt(field interface{}, param string) bool {
st := reflect.ValueOf(field)
@ -275,33 +352,42 @@ func max(field interface{}, param string) bool {
case reflect.String:
p := asInt(param)
return int64(len(st.String())) <= p
return int64(len(st.String())) < p
case reflect.Slice, reflect.Map, reflect.Array:
p := asInt(param)
return int64(st.Len()) <= p
return int64(st.Len()) < p
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
p := asInt(param)
return st.Int() <= p
return st.Int() < p
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
p := asUint(param)
return st.Uint() <= p
return st.Uint() < p
case reflect.Float32, reflect.Float64:
p := asFloat(param)
return st.Float() <= p
return st.Float() < p
default:
panic(fmt.Sprintf("Bad field type for Input Param %s for %s\n", param, field))
}
}
// max tests whether a variable value is lesser than a given
// value. For numbers, it's a simple lesser-than test; for
// strings it tests the number of characters whereas for maps
// and slices it tests the number of items.
func max(field interface{}, param string) bool {
return lte(field, param)
}
// asInt retuns the parameter as a int64
// or panics if it can't convert
func asInt(param string) int64 {

@ -163,6 +163,27 @@ Here is a list of the current built in validators:
the string length is at least that number of characters. For slices,
arrays, and maps, validates the number of items. (Usage: min=10)
gt
For numbers, this will ensure that the value is greater than the
parameter given. For strings, it checks that the string length
is greater than that number of characters. For slices, arrays
and maps it validates the number of items. (Usage: gt=10)
gte
Same as 'min' above. Kept both to make terminology with 'len' easier
(Usage: gte=10)
lt
For numbers, this will ensure that the value is
less than the parameter given. For strings, it checks
that the string length is less than that number of characters.
For slices, arrays, and maps it validates the number of items.
(Usage: lt=10)
lte
Same as 'max' above. Kept both to make terminology with 'len' easier
(Usage: lte=10)
alpha
This validates that a strings value contains alpha characters only
(Usage: alpha)

@ -34,6 +34,10 @@ type TestString struct {
Min string `validate:"min=1"`
Max string `validate:"max=10"`
MinMax string `validate:"min=1,max=10"`
Lt string `validate:"lt=10"`
Lte string `validate:"lte=10"`
Gt string `validate:"gt=10"`
Gte string `validate:"gte=10"`
OmitEmpty string `validate:"omitempty,min=1,max=10"`
Sub *SubTest
SubIgnore *SubTest `validate:"-"`
@ -49,6 +53,10 @@ type TestInt32 struct {
Min int `validate:"min=1"`
Max int `validate:"max=10"`
MinMax int `validate:"min=1,max=10"`
Lt int `validate:"lt=10"`
Lte int `validate:"lte=10"`
Gt int `validate:"gt=10"`
Gte int `validate:"gte=10"`
OmitEmpty int `validate:"omitempty,min=1,max=10"`
}
@ -425,6 +433,10 @@ func (ms *MySuite) TestFlattening(c *C) {
Min: "min=1",
Max: "1234567890",
MinMax: "12345",
Lt: "012345678",
Lte: "0123456789",
Gt: "01234567890",
Gte: "0123456789",
OmitEmpty: "",
Sub: &SubTest{
Test: "1",
@ -472,6 +484,8 @@ func (ms *MySuite) TestFlattening(c *C) {
// Assert Fields
AssertMapFieldError(err2, "Len", "len", c)
AssertMapFieldError(err2, "Gt", "gt", c)
AssertMapFieldError(err2, "Gte", "gte", c)
// Assert Struct Field
AssertMapFieldError(err2, "Sub.Test", "required", c)
@ -491,6 +505,10 @@ func (ms *MySuite) TestStructStringValidation(c *C) {
Min: "min=1",
Max: "1234567890",
MinMax: "12345",
Lt: "012345678",
Lte: "0123456789",
Gt: "01234567890",
Gte: "0123456789",
OmitEmpty: "",
Sub: &SubTest{
Test: "1",
@ -517,6 +535,10 @@ func (ms *MySuite) TestStructStringValidation(c *C) {
Min: "",
Max: "12345678901",
MinMax: "",
Lt: "0123456789",
Lte: "01234567890",
Gt: "1",
Gte: "1",
OmitEmpty: "12345678901",
Sub: &SubTest{
Test: "",
@ -536,7 +558,7 @@ func (ms *MySuite) TestStructStringValidation(c *C) {
// Assert Top Level
c.Assert(err, NotNil)
c.Assert(err.Struct, Equals, "TestString")
c.Assert(len(err.Errors), Equals, 6)
c.Assert(len(err.Errors), Equals, 10)
c.Assert(len(err.StructErrors), Equals, 3)
// Assert Fields
@ -545,6 +567,8 @@ func (ms *MySuite) TestStructStringValidation(c *C) {
AssertFieldError(err, "Min", "min", c)
AssertFieldError(err, "Max", "max", c)
AssertFieldError(err, "MinMax", "min", c)
AssertFieldError(err, "Gt", "gt", c)
AssertFieldError(err, "Gte", "gte", c)
AssertFieldError(err, "OmitEmpty", "max", c)
// Assert Anonymous embedded struct
@ -566,6 +590,10 @@ func (ms *MySuite) TestStructInt32Validation(c *C) {
Min: 1,
Max: 10,
MinMax: 5,
Lt: 9,
Lte: 10,
Gt: 11,
Gte: 10,
OmitEmpty: 0,
}
@ -578,6 +606,10 @@ func (ms *MySuite) TestStructInt32Validation(c *C) {
Min: -1,
Max: 11,
MinMax: -1,
Lt: 10,
Lte: 11,
Gt: 10,
Gte: 9,
OmitEmpty: 11,
}
@ -586,7 +618,7 @@ func (ms *MySuite) TestStructInt32Validation(c *C) {
// Assert Top Level
c.Assert(err, NotNil)
c.Assert(err.Struct, Equals, "TestInt32")
c.Assert(len(err.Errors), Equals, 6)
c.Assert(len(err.Errors), Equals, 10)
c.Assert(len(err.StructErrors), Equals, 0)
// Assert Fields
@ -595,6 +627,10 @@ func (ms *MySuite) TestStructInt32Validation(c *C) {
AssertFieldError(err, "Min", "min", c)
AssertFieldError(err, "Max", "max", c)
AssertFieldError(err, "MinMax", "min", c)
AssertFieldError(err, "Lt", "lt", c)
AssertFieldError(err, "Lte", "lte", c)
AssertFieldError(err, "Gt", "gt", c)
AssertFieldError(err, "Gte", "gte", c)
AssertFieldError(err, "OmitEmpty", "max", c)
}

Loading…
Cancel
Save