Merge branch 'issue-#1' into v1-development

pull/16/head
Dean Karn 10 years ago
commit 6c26ed7bba
  1. 122
      baked_in.go
  2. 8
      doc.go
  3. 2
      regexes.go
  4. 2
      validator.go
  5. 106
      validator_test.go

@ -2,6 +2,7 @@ package validator
import (
"fmt"
"net/url"
"reflect"
"strconv"
)
@ -9,28 +10,69 @@ import (
// BakedInValidators is the map of ValidationFunc used internally
// but can be used with any new Validator if desired
var BakedInValidators = map[string]ValidationFunc{
"required": required,
"len": length,
"min": min,
"max": max,
"lt": lt,
"lte": lte,
"gt": gt,
"gte": gte,
"alpha": alpha,
"alphanum": alphanum,
"numeric": numeric,
"number": number,
"hexadecimal": hexadecimal,
"hexcolor": hexcolor,
"rgb": rgb,
"rgba": rgba,
"hsl": hsl,
"hsla": hsla,
"email": email,
"required": hasValue,
"len": hasLengthOf,
"min": hasMinOf,
"max": hasMaxOf,
"lt": isLt,
"lte": isLte,
"gt": isGt,
"gte": isGte,
"alpha": isAlpha,
"alphanum": isAlphanum,
"numeric": isNumeric,
"number": isNumber,
"hexadecimal": isHexadecimal,
"hexcolor": isHexcolor,
"rgb": isRgb,
"rgba": isRgba,
"hsl": isHsl,
"hsla": isHsla,
"email": isEmail,
"url": isURL,
"uri": isURI,
}
func email(field interface{}, param string) bool {
func isURI(field interface{}, param string) bool {
st := reflect.ValueOf(field)
switch st.Kind() {
case reflect.String:
_, err := url.ParseRequestURI(field.(string))
return err == nil
default:
panic(fmt.Sprintf("Bad field type %T", field))
}
}
func isURL(field interface{}, param string) bool {
st := reflect.ValueOf(field)
switch st.Kind() {
case reflect.String:
url, err := url.ParseRequestURI(field.(string))
if err != nil {
return false
}
if len(url.Scheme) == 0 {
return false
}
return err == nil
default:
panic(fmt.Sprintf("Bad field type %T", field))
}
}
func isEmail(field interface{}, param string) bool {
st := reflect.ValueOf(field)
@ -43,7 +85,7 @@ func email(field interface{}, param string) bool {
}
}
func hsla(field interface{}, param string) bool {
func isHsla(field interface{}, param string) bool {
st := reflect.ValueOf(field)
@ -56,7 +98,7 @@ func hsla(field interface{}, param string) bool {
}
}
func hsl(field interface{}, param string) bool {
func isHsl(field interface{}, param string) bool {
st := reflect.ValueOf(field)
@ -69,7 +111,7 @@ func hsl(field interface{}, param string) bool {
}
}
func rgba(field interface{}, param string) bool {
func isRgba(field interface{}, param string) bool {
st := reflect.ValueOf(field)
@ -82,7 +124,7 @@ func rgba(field interface{}, param string) bool {
}
}
func rgb(field interface{}, param string) bool {
func isRgb(field interface{}, param string) bool {
st := reflect.ValueOf(field)
@ -95,7 +137,7 @@ func rgb(field interface{}, param string) bool {
}
}
func hexcolor(field interface{}, param string) bool {
func isHexcolor(field interface{}, param string) bool {
st := reflect.ValueOf(field)
@ -108,7 +150,7 @@ func hexcolor(field interface{}, param string) bool {
}
}
func hexadecimal(field interface{}, param string) bool {
func isHexadecimal(field interface{}, param string) bool {
st := reflect.ValueOf(field)
@ -121,7 +163,7 @@ func hexadecimal(field interface{}, param string) bool {
}
}
func number(field interface{}, param string) bool {
func isNumber(field interface{}, param string) bool {
st := reflect.ValueOf(field)
@ -134,7 +176,7 @@ func number(field interface{}, param string) bool {
}
}
func numeric(field interface{}, param string) bool {
func isNumeric(field interface{}, param string) bool {
st := reflect.ValueOf(field)
@ -147,7 +189,7 @@ func numeric(field interface{}, param string) bool {
}
}
func alphanum(field interface{}, param string) bool {
func isAlphanum(field interface{}, param string) bool {
st := reflect.ValueOf(field)
@ -160,7 +202,7 @@ func alphanum(field interface{}, param string) bool {
}
}
func alpha(field interface{}, param string) bool {
func isAlpha(field interface{}, param string) bool {
st := reflect.ValueOf(field)
@ -173,7 +215,7 @@ func alpha(field interface{}, param string) bool {
}
}
func required(field interface{}, param string) bool {
func hasValue(field interface{}, param string) bool {
st := reflect.ValueOf(field)
@ -187,7 +229,7 @@ func required(field interface{}, param string) bool {
}
}
func gte(field interface{}, param string) bool {
func isGte(field interface{}, param string) bool {
st := reflect.ValueOf(field)
@ -223,7 +265,7 @@ func gte(field interface{}, param string) bool {
}
}
func gt(field interface{}, param string) bool {
func isGt(field interface{}, param string) bool {
st := reflect.ValueOf(field)
@ -262,7 +304,7 @@ func gt(field interface{}, param string) bool {
// 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.
func length(field interface{}, param string) bool {
func hasLengthOf(field interface{}, param string) bool {
st := reflect.ValueOf(field)
@ -302,12 +344,12 @@ func length(field interface{}, param string) bool {
// number. For number types, 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 min(field interface{}, param string) bool {
func hasMinOf(field interface{}, param string) bool {
return gte(field, param)
return isGte(field, param)
}
func lte(field interface{}, param string) bool {
func isLte(field interface{}, param string) bool {
st := reflect.ValueOf(field)
@ -343,7 +385,7 @@ func lte(field interface{}, param string) bool {
}
}
func lt(field interface{}, param string) bool {
func isLt(field interface{}, param string) bool {
st := reflect.ValueOf(field)
@ -383,9 +425,9 @@ func lt(field interface{}, param string) bool {
// 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 hasMaxOf(field interface{}, param string) bool {
return lte(field, param)
return isLte(field, param)
}
// asInt retuns the parameter as a int64

@ -227,6 +227,14 @@ Here is a list of the current built in validators:
This may not conform to all possibilities of any rfc standard, but neither
does any email provider accept all posibilities...
(Usage: email)
url
This validates that a strings value contains a valid url
This will accept any url the golang request uri accepts but must contain
a schema for example http:// or rtmp://
(Usage: url)
uri
This validates that a strings value contains a valid uri
This will accept any uri the golang request uri accepts (Usage: uri)
Validator notes:

@ -14,6 +14,8 @@ const (
hslRegexString = "^hsl\\(\\s*(0|[1-9]\\d?|[12]\\d\\d|3[0-5]\\d|360)\\s*,\\s*((0|[1-9]\\d?|100)%)\\s*,\\s*((0|[1-9]\\d?|100)%)\\s*\\)$"
hslaRegexString = "^hsla\\(\\s*(0|[1-9]\\d?|[12]\\d\\d|3[0-5]\\d|360)\\s*,\\s*((0|[1-9]\\d?|100)%)\\s*,\\s*((0|[1-9]\\d?|100)%)\\s*,\\s*((0.[1-9]*)|[01])\\s*\\)$"
emailRegexString = "^(((([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|((\\x22)((((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(([\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(\\([\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(((\\x20|\\x09)*(\\x0d\\x0a))?(\\x20|\\x09)+)?(\\x22)))@((([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])([a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*([a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$"
// urlRegexString = `^((ftp|http|https):\/\/)?(\S+(:\S*)?@)?((([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|((www\.)?)?(([a-z\x{00a1}-\x{ffff}0-9]+-?-?_?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-z\x{00a1}-\x{ffff}]{2,}))?)|localhost)(:(\d{1,5}))?((\/|\?|#)[^\s]*)?$`
// urlRegexString = "^(?:(?:https?|ftp):\\/\\/)(?:\\S+(?::\\S*)?@)?(?:(?!10(?:\\.\\d{1,3}){3})(?!127(?:\\.\\d{1,3}){3})(?!169\\.254(?:\\.\\d{1,3}){2})(?!192\\.168(?:\\.\\d{1,3}){2})(?!172\\.(?:1[6-9]|2\\d|3[0-1])(?:\\.\\d{1,3}){2})(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[1-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)*(?:\\.(?:[a-z\u00a1-\uffff]{2,})))(?::\\d{2,5})?(?:\\/[^\\s]*)?$"
)
var (

@ -267,7 +267,7 @@ func (v *Validator) validateFieldByNameAndTag(f interface{}, name string, tag st
return nil
}
if strings.Contains(tag, omitempty) && !required(f, "") {
if strings.Contains(tag, omitempty) && !hasValue(f, "") {
return nil
}

@ -121,6 +121,112 @@ func AssertMapFieldError(s map[string]*validator.FieldValidationError, field str
c.Assert(val.ErrorTag, Equals, expectedTag)
}
func (ms *MySuite) TestUrl(c *C) {
var tests = []struct {
param string
expected bool
}{
{"http://foo.bar#com", true},
{"http://foobar.com", true},
{"https://foobar.com", true},
{"foobar.com", false},
{"http://foobar.coffee/", true},
{"http://foobar.中文网/", true},
{"http://foobar.org/", true},
{"http://foobar.org:8080/", true},
{"ftp://foobar.ru/", true},
{"http://user:pass@www.foobar.com/", true},
{"http://127.0.0.1/", true},
{"http://duckduckgo.com/?q=%2F", true},
{"http://localhost:3000/", true},
{"http://foobar.com/?foo=bar#baz=qux", true},
{"http://foobar.com?foo=bar", true},
{"http://www.xn--froschgrn-x9a.net/", true},
{"", false},
{"xyz://foobar.com", true},
{"invalid.", false},
{".com", false},
{"rtmp://foobar.com", true},
{"http://www.foo_bar.com/", true},
{"http://localhost:3000/", true},
{"http://foobar.com#baz=qux", true},
{"http://foobar.com/t$-_.+!*\\'(),", true},
{"http://www.foobar.com/~foobar", true},
{"http://www.-foobar.com/", true},
{"http://www.foo---bar.com/", true},
{"mailto:someone@example.com", true},
{"irc://irc.server.org/channel", true},
{"irc://#channel@network", true},
{"/abs/test/dir", false},
{"./rel/test/dir", false},
}
for _, test := range tests {
err := validator.ValidateFieldByTag(test.param, "url")
if test.expected == true {
c.Assert(err, IsNil)
} else {
c.Assert(err, NotNil)
c.Assert(err.Error(), Equals, "url")
}
}
}
func (ms *MySuite) TestUri(c *C) {
var tests = []struct {
param string
expected bool
}{
{"http://foo.bar#com", true},
{"http://foobar.com", true},
{"https://foobar.com", true},
{"foobar.com", false},
{"http://foobar.coffee/", true},
{"http://foobar.中文网/", true},
{"http://foobar.org/", true},
{"http://foobar.org:8080/", true},
{"ftp://foobar.ru/", true},
{"http://user:pass@www.foobar.com/", true},
{"http://127.0.0.1/", true},
{"http://duckduckgo.com/?q=%2F", true},
{"http://localhost:3000/", true},
{"http://foobar.com/?foo=bar#baz=qux", true},
{"http://foobar.com?foo=bar", true},
{"http://www.xn--froschgrn-x9a.net/", true},
{"", false},
{"xyz://foobar.com", true},
{"invalid.", false},
{".com", false},
{"rtmp://foobar.com", true},
{"http://www.foo_bar.com/", true},
{"http://localhost:3000/", true},
{"http://foobar.com#baz=qux", true},
{"http://foobar.com/t$-_.+!*\\'(),", true},
{"http://www.foobar.com/~foobar", true},
{"http://www.-foobar.com/", true},
{"http://www.foo---bar.com/", true},
{"mailto:someone@example.com", true},
{"irc://irc.server.org/channel", true},
{"irc://#channel@network", true},
{"/abs/test/dir", true},
{"./rel/test/dir", false},
}
for _, test := range tests {
err := validator.ValidateFieldByTag(test.param, "uri")
if test.expected == true {
c.Assert(err, IsNil)
} else {
c.Assert(err, NotNil)
c.Assert(err.Error(), Equals, "uri")
}
}
}
func (ms *MySuite) TestOrTag(c *C) {
s := "rgba(0,31,255,0.5)"
err := validator.ValidateFieldByTag(s, "rgb|rgba")

Loading…
Cancel
Save