add func ghttp.Group.Common for common http methods(GET/PUT/POST/DELETE) binding; fix issue #IRHB3,#IRHSJ; add more unit test cases for gvalid

This commit is contained in:
John
2019-01-29 23:01:14 +08:00
parent 0d315218dd
commit f4773ef1e4
13 changed files with 1275 additions and 473 deletions

View File

@ -16,7 +16,7 @@ func (r Result) ToJson() string {
return string(content)
}
// 将结果集转换为JSON字符串
// 将结果集转换为XML字符串
func (r Result) ToXml(rootTag...string) string {
content, _ := gparser.VarToXml(r.ToList(), rootTag...)
return string(content)

View File

@ -111,7 +111,11 @@ func (s *Server)handleRequest(w http.ResponseWriter, r *http.Request) {
// 静态目录
s.serveFile(request, staticFile)
} else {
request.Response.WriteStatus(http.StatusNotFound)
if len(request.Response.Header()) == 0 &&
request.Response.Status == 0 &&
request.Response.BufferLength() == 0 {
request.Response.WriteStatus(http.StatusNotFound)
}
}
}
}

View File

@ -69,6 +69,14 @@ func (g *RouterGroup) ALL(pattern string, object interface{}, params...interface
g.bind("HANDLER", gDEFAULT_METHOD + ":" + pattern, object, params...)
}
// 绑定常用方法: GET/PUT/POST/DELETE
func (g *RouterGroup) COMMON(pattern string, object interface{}, params...interface{}) {
g.GET(pattern, object, params...)
g.PUT(pattern, object, params...)
g.POST(pattern, object, params...)
g.DELETE(pattern, object, params...)
}
func (g *RouterGroup) GET(pattern string, object interface{}, params...interface{}) {
g.bind("HANDLER", "GET:" + pattern, object, params...)
}

View File

@ -50,7 +50,7 @@ min 格式min:min 说明:参
max 格式max:max 说明参数最大为max(支持整形和浮点类型参数)
json 格式json 说明判断数据格式为JSON
integer 格式integer 说明:整数
float 格式float 说明:浮点数
float 格式float 说明:浮点数(整数也是浮点数)
boolean 格式boolean 说明:布尔值(1,true,on,yes:true | 0,false,off,no,"":false)
same 格式same:field 说明参数值必需与field参数的值相同
different 格式different:field 说明参数值不能与field参数的值相同

View File

@ -45,6 +45,63 @@ var (
"not-in" : struct{}{},
"regex" : struct{}{},
}
// 所有支持的校验规则
allSupportedRules = map[string]struct{} {
"required" : struct{}{},
"required-if" : struct{}{},
"required-unless" : struct{}{},
"required-with" : struct{}{},
"required-with-all" : struct{}{},
"required-without" : struct{}{},
"required-without-all" : struct{}{},
"date" : struct{}{},
"date-format" : struct{}{},
"email" : struct{}{},
"phone" : struct{}{},
"telephone" : struct{}{},
"passport" : struct{}{},
"password" : struct{}{},
"password2" : struct{}{},
"password3" : struct{}{},
"postcode" : struct{}{},
"id-number" : struct{}{},
"qq" : struct{}{},
"ip" : struct{}{},
"ipv4" : struct{}{},
"ipv6" : struct{}{},
"mac" : struct{}{},
"url" : struct{}{},
"domain" : struct{}{},
"length" : struct{}{},
"min-length" : struct{}{},
"max-length" : struct{}{},
"between" : struct{}{},
"min" : struct{}{},
"max" : struct{}{},
"json" : struct{}{},
"integer" : struct{}{},
"float" : struct{}{},
"boolean" : struct{}{},
"same" : struct{}{},
"different" : struct{}{},
"in" : struct{}{},
"not-in" : struct{}{},
"regex" : struct{}{},
}
// 布尔Map
boolMap = map[string]struct{} {
// true
"1" : struct{}{},
"true" : struct{}{},
"on" : struct{}{},
"yes" : struct{}{},
// false
"" : struct{}{},
"0" : struct{}{},
"false" : struct{}{},
"off" : struct{}{},
"no" : struct{}{},
}
)
// 检测单条数据的规则:
@ -62,24 +119,41 @@ func Check(value interface{}, rules string, msgs interface{}, params...map[strin
}
}
// 自定义错误消息处理
list := make([]string, 0)
customMsgs := make(map[string]string)
msgArray := make([]string, 0)
customMsgMap := make(map[string]string)
switch v := msgs.(type) {
case map[string]string:
customMsgs = v
customMsgMap = v
case string:
list = strings.Split(v, "|")
msgArray = strings.Split(v, "|")
}
items := strings.Split(strings.TrimSpace(rules), "|")
for index := 0; index < len(items); {
item := items[index]
ruleItems := strings.Split(strings.TrimSpace(rules), "|")
// 规则项预处理, 主要解决规则中存在的"|"关键字符号
for i := 0; ; {
array := strings.Split(ruleItems[i], ":")
if _, ok := allSupportedRules[array[0]]; !ok {
if i > 0 {
ruleItems[i - 1] += "|" + ruleItems[i]
ruleItems = append(ruleItems[ : i], ruleItems[i + 1 : ]...)
} else {
return newErrorStr("invalid_rules", "invalid rules:" + rules)
}
} else {
i++
}
if i == len(ruleItems) {
break
}
}
for index := 0; index < len(ruleItems); {
item := ruleItems[index]
results := ruleRegex.FindStringSubmatch(item)
ruleKey := strings.TrimSpace(results[1])
ruleVal := strings.TrimSpace(results[2])
match := false
if len(list) > index {
customMsgs[ruleKey] = strings.TrimSpace(list[index])
if len(msgArray) > index {
customMsgMap[ruleKey] = strings.TrimSpace(msgArray[index])
}
switch ruleKey {
// 必须字段
@ -96,7 +170,7 @@ func Check(value interface{}, rules string, msgs interface{}, params...map[strin
case "length": fallthrough
case "min-length": fallthrough
case "max-length":
if msg := checkLength(val, ruleKey, ruleVal, customMsgs); msg != "" {
if msg := checkLength(val, ruleKey, ruleVal, customMsgMap); msg != "" {
errorMsgs[ruleKey] = msg
} else {
match = true
@ -106,7 +180,7 @@ func Check(value interface{}, rules string, msgs interface{}, params...map[strin
case "min": fallthrough
case "max": fallthrough
case "between":
if msg := checkSize(val, ruleKey, ruleVal, customMsgs); msg != "" {
if msg := checkSize(val, ruleKey, ruleVal, customMsgMap); msg != "" {
errorMsgs[ruleKey] = msg
} else {
match = true
@ -115,10 +189,10 @@ func Check(value interface{}, rules string, msgs interface{}, params...map[strin
// 自定义正则判断
case "regex":
// 需要判断是否被|符号截断,如果是,那么需要进行整合
for i := index + 1; i < len(items); i++ {
for i := index + 1; i < len(ruleItems); i++ {
// 判断下一个规则是否合法,不合法那么和当前正则规则进行整合
if !gregex.IsMatchString(gSINGLE_RULE_PATTERN, items[i]) {
ruleVal += "|" + items[i]
if !gregex.IsMatchString(gSINGLE_RULE_PATTERN, ruleItems[i]) {
ruleVal += "|" + ruleItems[i]
index++
}
}
@ -201,9 +275,9 @@ func Check(value interface{}, rules string, msgs interface{}, params...map[strin
case "qq":
match = gregex.IsMatchString(`^[1-9][0-9]{4,}$`, val)
// 中国邮政编码
// 中国邮政编码
case "postcode":
match = gregex.IsMatchString(`^[1-9]\d{5}$`, val)
match = gregex.IsMatchString(`^\d{6}$`, val)
/*
公民身份证号
@ -221,13 +295,13 @@ func Check(value interface{}, rules string, msgs interface{}, params...map[strin
校验码: [0-9Xx]
十八位:^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$
十五位:^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}$
十五位:^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}$
总:
(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}$)
(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}$)
*/
case "id-number":
match = gregex.IsMatchString(`(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{2}$)`, val)
match = gregex.IsMatchString(`(^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$)|(^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}$)`, val)
// 通用帐号规则(字母开头只能包含字母、数字和下划线长度在6~18之间)
case "passport":
@ -245,7 +319,7 @@ func Check(value interface{}, rules string, msgs interface{}, params...map[strin
// 强等强度密码(在弱密码的基础上,必须包含大小写字母、数字和特殊字符)
case "password3":
if gregex.IsMatchString(`^[\w\S]{6,18}$`, val) && gregex.IsMatchString(`[a-z]+`, val) && gregex.IsMatchString(`[A-Z]+`, val) && gregex.IsMatchString(`\d+`, val) && gregex.IsMatchString(`\S+`, val) {
if gregex.IsMatchString(`^[\w\S]{6,18}$`, val) && gregex.IsMatchString(`[a-z]+`, val) && gregex.IsMatchString(`[A-Z]+`, val) && gregex.IsMatchString(`\d+`, val) && gregex.IsMatchString(`[^a-zA-Z0-9]+`, val) {
match = true
}
@ -269,17 +343,18 @@ func Check(value interface{}, rules string, msgs interface{}, params...map[strin
// 布尔值(1,true,on,yes:true | 0,false,off,no,"":false)
case "boolean":
if val != "" && val != "0" && val != "false" && val != "off" && val != "no" {
match = false
if _, ok := boolMap[strings.ToLower(val)]; ok {
match = true
}
// 邮件
case "email":
match = gregex.IsMatchString(`^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$`, val)
match = gregex.IsMatchString(`^[a-zA-Z0-9_\-\.]+@[a-zA-Z0-9_\-]+(\.[a-zA-Z0-9_\-]+)+$`, val)
// URL
case "url":
match = gregex.IsMatchString(`^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$`, val)
match = gregex.IsMatchString(`(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]`, val)
// domain
case "domain":
@ -299,7 +374,7 @@ func Check(value interface{}, rules string, msgs interface{}, params...map[strin
// MAC地址
case "mac":
match = gregex.IsMatchString(`^([0-9A-Fa-f]{2}-){5}[0-9A-Fa-f]{2}$`, val)
match = gregex.IsMatchString(`^([0-9A-Fa-f]{2}[\-:]){5}[0-9A-Fa-f]{2}$`, val)
default:
errorMsgs[ruleKey] = "Invalid rule name:" + ruleKey
@ -310,7 +385,7 @@ func Check(value interface{}, rules string, msgs interface{}, params...map[strin
// 不存在则使用默认的错误信息,
// 如果在校验过程中已经设置了错误信息,那么这里便不作处理
if _, ok := errorMsgs[ruleKey]; !ok {
if msg, ok := customMsgs[ruleKey]; ok {
if msg, ok := customMsgMap[ruleKey]; ok {
errorMsgs[ruleKey] = msg
} else {
errorMsgs[ruleKey] = errorMsgMap.Get(ruleKey)
@ -333,99 +408,91 @@ func Check(value interface{}, rules string, msgs interface{}, params...map[strin
func checkRequired(value, ruleKey, ruleVal string, params map[string]string) bool {
required := false
switch ruleKey {
// 必须字段
case "required":
required = true
// 必须字段
case "required":
required = true
// 必须字段(当任意所给定字段值与所给值相等时)
case "required-if":
required = false
array := strings.Split(ruleVal, ",")
// 必须为偶数,才能是键值对匹配
if len(array)%2 == 0 {
for i := 0; i < len(array); {
tk := array[i]
tv := array[i+1]
if v, ok := params[tk]; ok {
if strings.Compare(tv, v) == 0 {
required = true
break
case "required-if":
required = false
array := strings.Split(ruleVal, ",")
// 必须为偶数,才能是键值对匹配
if len(array)%2 == 0 {
for i := 0; i < len(array); {
tk := array[i]
tv := array[i+1]
if v, ok := params[tk]; ok {
if strings.Compare(tv, v) == 0 {
required = true
break
}
}
i += 2
}
i += 2
}
}
// 必须字段(当所给定字段值与所给值都不相等时)
case "required-unless":
required = true
array := strings.Split(ruleVal, ",")
// 必须为偶数,才能是键值对匹配
if len(array)%2 == 0 {
for i := 0; i < len(array); {
tk := array[i]
tv := array[i+1]
if v, ok := params[tk]; ok {
if strings.Compare(tv, v) == 0 {
required = false
break
case "required-unless":
required = true
array := strings.Split(ruleVal, ",")
// 必须为偶数,才能是键值对匹配
if len(array)%2 == 0 {
for i := 0; i < len(array); {
tk := array[i]
tv := array[i+1]
if v, ok := params[tk]; ok {
if strings.Compare(tv, v) == 0 {
required = false
break
}
}
i += 2
}
i += 2
}
}
// 必须字段(当所给定任意字段值不为空时)
case "required-with":
required = false
array := strings.Split(ruleVal, ",")
for i := 0; i < len(array); i++ {
if v, ok := params[array[i]]; ok {
if v != "" {
case "required-with":
required = false
array := strings.Split(ruleVal, ",")
for i := 0; i < len(array); i++ {
if params[array[i]] != "" {
required = true
break
}
}
}
// 必须字段(当所给定所有字段值都不为空时)
case "required-with-all":
required = true
array := strings.Split(ruleVal, ",")
for i := 0; i < len(array); i++ {
if v, ok := params[array[i]]; ok {
if v == "" {
case "required-with-all":
required = true
array := strings.Split(ruleVal, ",")
for i := 0; i < len(array); i++ {
if params[array[i]] == "" {
required = false
break
}
}
}
// 必须字段(当所给定任意字段值为空时)
case "required-without":
required = false
array := strings.Split(ruleVal, ",")
for i := 0; i < len(array); i++ {
if v, ok := params[array[i]]; ok {
if v == "" {
case "required-without":
required = false
array := strings.Split(ruleVal, ",")
for i := 0; i < len(array); i++ {
if params[array[i]] == "" {
required = true
break
}
}
}
// 必须字段(当所给定所有字段值都为空时)
case "required-without-all":
required = true
array := strings.Split(ruleVal, ",")
for i := 0; i < len(array); i++ {
if v, ok := params[array[i]]; ok {
if v != "" {
case "required-without-all":
required = true
array := strings.Split(ruleVal, ",")
for i := 0; i < len(array); i++ {
if params[array[i]] != "" {
required = false
break
}
}
}
}
if required {
return !(value == "")
@ -435,138 +502,138 @@ func checkRequired(value, ruleKey, ruleVal string, params map[string]string) boo
}
// 对字段值长度进行检测
func checkLength(value, ruleKey, ruleVal string, custonMsgs map[string]string) string {
func checkLength(value, ruleKey, ruleVal string, customMsgMap map[string]string) string {
msg := ""
switch ruleKey {
// 长度范围
case "length":
array := strings.Split(ruleVal, ",")
min := 0
max := 0
if len(array) > 0 {
if v, err := strconv.Atoi(strings.TrimSpace(array[0])); err == nil {
min = v
// 长度范围
case "length":
array := strings.Split(ruleVal, ",")
min := 0
max := 0
if len(array) > 0 {
if v, err := strconv.Atoi(strings.TrimSpace(array[0])); err == nil {
min = v
}
}
}
if len(array) > 1 {
if v, err := strconv.Atoi(strings.TrimSpace(array[1])); err == nil {
max = v
if len(array) > 1 {
if v, err := strconv.Atoi(strings.TrimSpace(array[1])); err == nil {
max = v
}
}
}
if len(value) < min || len(value) > max {
if v, ok := custonMsgs[ruleKey]; !ok {
msg = errorMsgMap.Get(ruleKey)
} else {
msg = v
}
msg = strings.Replace(msg, ":min", strconv.Itoa(min), -1)
msg = strings.Replace(msg, ":max", strconv.Itoa(max), -1)
return msg
}
// 最小长度
case "min-length":
if min, err := strconv.Atoi(ruleVal); err == nil {
if len(value) < min {
if v, ok := custonMsgs[ruleKey]; !ok {
if len(value) < min || len(value) > max {
if v, ok := customMsgMap[ruleKey]; !ok {
msg = errorMsgMap.Get(ruleKey)
} else {
msg = v
}
msg = strings.Replace(msg, ":min", strconv.Itoa(min), -1)
msg = strings.Replace(msg, ":max", strconv.Itoa(max), -1)
return msg
}
// 最小长度
case "min-length":
if min, err := strconv.Atoi(ruleVal); err == nil {
if len(value) < min {
if v, ok := customMsgMap[ruleKey]; !ok {
msg = errorMsgMap.Get(ruleKey)
} else {
msg = v
}
msg = strings.Replace(msg, ":min", strconv.Itoa(min), -1)
}
} else {
msg = "校验参数[" + ruleVal + "]应当为整数类型"
}
} else {
msg = "校验参数[" + ruleVal + "]应当为整数类型"
}
// 最大长度
case "max-length":
if max, err := strconv.Atoi(ruleVal); err == nil {
if len(value) > max {
if v, ok := custonMsgs[ruleKey]; !ok {
msg = errorMsgMap.Get(ruleKey)
} else {
msg = v
case "max-length":
if max, err := strconv.Atoi(ruleVal); err == nil {
if len(value) > max {
if v, ok := customMsgMap[ruleKey]; !ok {
msg = errorMsgMap.Get(ruleKey)
} else {
msg = v
}
msg = strings.Replace(msg, ":max", strconv.Itoa(max), -1)
}
msg = strings.Replace(msg, ":max", strconv.Itoa(max), -1)
} else {
msg = "校验参数[" + ruleVal + "]应当为整数类型"
}
} else {
msg = "校验参数[" + ruleVal + "]应当为整数类型"
}
}
return msg
}
// 对字段值大小进行检测
func checkSize(value, ruleKey, ruleVal string, custonMsgs map[string]string) string {
func checkSize(value, ruleKey, ruleVal string, customMsgMap map[string]string) string {
msg := ""
switch ruleKey {
// 大小范围
case "between":
array := strings.Split(ruleVal, ",")
min := float64(0)
max := float64(0)
if len(array) > 0 {
if v, err := strconv.ParseFloat(strings.TrimSpace(array[0]), 10); err == nil {
min = v
}
}
if len(array) > 1 {
if v, err := strconv.ParseFloat(strings.TrimSpace(array[1]), 10); err == nil {
max = v
}
}
if v, err := strconv.ParseFloat(value, 10); err == nil {
if v < min || v > max {
if v, ok := custonMsgs[ruleKey]; !ok {
msg = errorMsgMap.Get(ruleKey)
} else {
msg = v
// 大小范围
case "between":
array := strings.Split(ruleVal, ",")
min := float64(0)
max := float64(0)
if len(array) > 0 {
if v, err := strconv.ParseFloat(strings.TrimSpace(array[0]), 10); err == nil {
min = v
}
}
if len(array) > 1 {
if v, err := strconv.ParseFloat(strings.TrimSpace(array[1]), 10); err == nil {
max = v
}
msg = strings.Replace(msg, ":min", strconv.FormatFloat(min, 'f', -1, 64), -1)
msg = strings.Replace(msg, ":max", strconv.FormatFloat(max, 'f', -1, 64), -1)
}
} else {
msg = "输入参数[" + value + "]应当为数字类型"
}
// 最小值
case "min":
if min, err := strconv.ParseFloat(ruleVal, 10); err == nil {
if v, err := strconv.ParseFloat(value, 10); err == nil {
if v < min {
if v, ok := custonMsgs[ruleKey]; !ok {
if v < min || v > max {
if v, ok := customMsgMap[ruleKey]; !ok {
msg = errorMsgMap.Get(ruleKey)
} else {
msg = v
}
msg = strings.Replace(msg, ":min", strconv.FormatFloat(min, 'f', -1, 64), -1)
}
} else {
msg = "输入参数[" + value + "]应当为数字类型"
}
} else {
msg = "校验参数[" + ruleVal + "]应当为数字类型"
}
// 最大值
case "max":
if max, err := strconv.ParseFloat(ruleVal, 10); err == nil {
if v, err := strconv.ParseFloat(value, 10); err == nil {
if v > max {
if v, ok := custonMsgs[ruleKey]; !ok {
msg = errorMsgMap.Get(ruleKey)
} else {
msg = v
}
msg = strings.Replace(msg, ":max", strconv.FormatFloat(max, 'f', -1, 64), -1)
}
} else {
msg = "输入参数[" + value + "]应当为数字类型"
}
} else {
msg = "校验参数[" + ruleVal + "]应当为数字类型"
}
// 最小值
case "min":
if min, err := strconv.ParseFloat(ruleVal, 10); err == nil {
if v, err := strconv.ParseFloat(value, 10); err == nil {
if v < min {
if v, ok := customMsgMap[ruleKey]; !ok {
msg = errorMsgMap.Get(ruleKey)
} else {
msg = v
}
msg = strings.Replace(msg, ":min", strconv.FormatFloat(min, 'f', -1, 64), -1)
}
} else {
msg = "输入参数[" + value + "]应当为数字类型"
}
} else {
msg = "校验参数[" + ruleVal + "]应当为数字类型"
}
// 最大值
case "max":
if max, err := strconv.ParseFloat(ruleVal, 10); err == nil {
if v, err := strconv.ParseFloat(value, 10); err == nil {
if v > max {
if v, ok := customMsgMap[ruleKey]; !ok {
msg = errorMsgMap.Get(ruleKey)
} else {
msg = v
}
msg = strings.Replace(msg, ":max", strconv.FormatFloat(max, 'f', -1, 64), -1)
}
} else {
msg = "输入参数[" + value + "]应当为数字类型"
}
} else {
msg = "校验参数[" + ruleVal + "]应当为数字类型"
}
}
return msg
}

View File

@ -0,0 +1,800 @@
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.
package gvalid_test
import (
"gitee.com/johng/gf/g"
"gitee.com/johng/gf/g/util/gtest"
"gitee.com/johng/gf/g/util/gvalid"
"testing"
)
func Test_Required(t *testing.T) {
if m := gvalid.Check("1", "required", nil); m != nil {
t.Error(m)
}
if m := gvalid.Check("", "required", nil); m == nil {
t.Error(m)
}
if m := gvalid.Check("", "required-if:id,1,age,18", nil, map[string]interface{}{"id" : 1, "age" : 19}); m == nil {
t.Error("Required校验失败")
}
if m := gvalid.Check("", "required-if:id,1,age,18", nil, map[string]interface{}{"id" : 2, "age" : 19}); m != nil {
t.Error("Required校验失败")
}
}
func Test_RequiredIf(t *testing.T) {
gtest.Case(t, func() {
rule := "required-if:100,200"
val1 := ""
val2 := "100"
val3 := "200"
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(err3, nil)
})
}
func Test_RequiredUnless(t *testing.T) {
gtest.Case(t, func() {
rule := "required-unless:100,200"
val1 := ""
val2 := "100"
val3 := "200"
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
gtest.AssertNE(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(err3, nil)
})
}
func Test_RequiredWith(t *testing.T) {
gtest.Case(t, func() {
rule := "required-with:id,name"
val1 := ""
params1 := g.Map{
"age" : 18,
}
params2 := g.Map{
"id" : 100,
}
params3 := g.Map{
"id" : 100,
"name" : "john",
}
err1 := gvalid.Check(val1, rule, nil, params1)
err2 := gvalid.Check(val1, rule, nil, params2)
err3 := gvalid.Check(val1, rule, nil, params3)
gtest.Assert(err1, nil)
gtest.AssertNE(err2, nil)
gtest.AssertNE(err3, nil)
})
}
func Test_RequiredWithAll(t *testing.T) {
gtest.Case(t, func() {
rule := "required-with-all:id,name"
val1 := ""
params1 := g.Map{
"age" : 18,
}
params2 := g.Map{
"id" : 100,
}
params3 := g.Map{
"id" : 100,
"name" : "john",
}
err1 := gvalid.Check(val1, rule, nil, params1)
err2 := gvalid.Check(val1, rule, nil, params2)
err3 := gvalid.Check(val1, rule, nil, params3)
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.AssertNE(err3, nil)
})
}
func Test_RequiredWithOut(t *testing.T) {
gtest.Case(t, func() {
rule := "required-without:id,name"
val1 := ""
params1 := g.Map{
"age" : 18,
}
params2 := g.Map{
"id" : 100,
}
params3 := g.Map{
"id" : 100,
"name" : "john",
}
err1 := gvalid.Check(val1, rule, nil, params1)
err2 := gvalid.Check(val1, rule, nil, params2)
err3 := gvalid.Check(val1, rule, nil, params3)
gtest.AssertNE(err1, nil)
gtest.AssertNE(err2, nil)
gtest.Assert(err3, nil)
})
}
func Test_RequiredWithOutAll(t *testing.T) {
gtest.Case(t, func() {
rule := "required-without-all:id,name"
val1 := ""
params1 := g.Map{
"age" : 18,
}
params2 := g.Map{
"id" : 100,
}
params3 := g.Map{
"id" : 100,
"name" : "john",
}
err1 := gvalid.Check(val1, rule, nil, params1)
err2 := gvalid.Check(val1, rule, nil, params2)
err3 := gvalid.Check(val1, rule, nil, params3)
gtest.AssertNE(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(err3, nil)
})
}
func Test_Date(t *testing.T) {
gtest.Case(t, func() {
rule := "date"
val1 := "2010"
val2 := "201011"
val3 := "20101101"
val4 := "2010-11-01"
val5 := "2010.11.01"
val6 := "2010/11/01"
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
err4 := gvalid.Check(val4, rule, nil)
err5 := gvalid.Check(val5, rule, nil)
err6 := gvalid.Check(val6, rule, nil)
gtest.AssertNE(err1, nil)
gtest.AssertNE(err2, nil)
gtest.Assert(err3, nil)
gtest.Assert(err4, nil)
gtest.Assert(err5, nil)
gtest.Assert(err6, nil)
})
}
func Test_DateFormat(t *testing.T) {
gtest.Case(t, func() {
val1 := "2010"
val2 := "201011"
val3 := "2010.11"
val4 := "201011-01"
val5 := "2010~11~01"
val6 := "2010-11~01"
err1 := gvalid.Check(val1, "date-format:Y", nil)
err2 := gvalid.Check(val2, "date-format:Ym", nil)
err3 := gvalid.Check(val3, "date-format:Y.m", nil)
err4 := gvalid.Check(val4, "date-format:Ym-d", nil)
err5 := gvalid.Check(val5, "date-format:Y~m~d", nil)
err6 := gvalid.Check(val6, "date-format:Y~m~d", nil)
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(err3, nil)
gtest.Assert(err4, nil)
gtest.Assert(err5, nil)
gtest.AssertNE(err6, nil)
})
}
func Test_Email(t *testing.T) {
gtest.Case(t, func() {
rule := "email"
value1 := "m@johngcn"
value2 := "m@www@johngcn"
value3 := "m-m_m@mail.johng.cn"
value4 := "m.m-m@johng.cn"
err1 := gvalid.Check(value1, rule, nil)
err2 := gvalid.Check(value2, rule, nil)
err3 := gvalid.Check(value3, rule, nil)
err4 := gvalid.Check(value4, rule, nil)
gtest.AssertNE(err1, nil)
gtest.AssertNE(err2, nil)
gtest.Assert(err3, nil)
gtest.Assert(err4, nil)
})
}
func Test_Phone(t *testing.T) {
gtest.Case(t, func() {
err1 := gvalid.Check("1361990897", "phone", nil)
err2 := gvalid.Check("13619908979", "phone", nil)
err3 := gvalid.Check("16719908979", "phone", nil)
err4 := gvalid.Check("19719908989", "phone", nil)
gtest.AssertNE(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(err3, nil)
gtest.Assert(err4, nil)
})
}
func Test_Telephone(t *testing.T) {
gtest.Case(t, func() {
rule := "telephone"
val1 := "869265"
val2 := "028-869265"
val3 := "86292651"
val4 := "028-8692651"
val5 := "0830-8692651"
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
err4 := gvalid.Check(val4, rule, nil)
err5 := gvalid.Check(val5, rule, nil)
gtest.AssertNE(err1, nil)
gtest.AssertNE(err2, nil)
gtest.Assert(err3, nil)
gtest.Assert(err4, nil)
gtest.Assert(err5, nil)
})
}
func Test_Passport(t *testing.T) {
gtest.Case(t, func() {
rule := "passport"
val1 := "123456"
val2 := "a12345-6"
val3 := "aaaaa"
val4 := "aaaaaa"
val5 := "a123_456"
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
err4 := gvalid.Check(val4, rule, nil)
err5 := gvalid.Check(val5, rule, nil)
gtest.AssertNE(err1, nil)
gtest.AssertNE(err2, nil)
gtest.AssertNE(err3, nil)
gtest.Assert(err4, nil)
gtest.Assert(err5, nil)
})
}
func Test_Password(t *testing.T) {
gtest.Case(t, func() {
rule := "password"
val1 := "12345"
val2 := "aaaaa"
val3 := "a12345-6"
val4 := ">,/;'[09-"
val5 := "a123_456"
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
err4 := gvalid.Check(val4, rule, nil)
err5 := gvalid.Check(val5, rule, nil)
gtest.AssertNE(err1, nil)
gtest.AssertNE(err2, nil)
gtest.Assert(err3, nil)
gtest.Assert(err4, nil)
gtest.Assert(err5, nil)
})
}
func Test_Password2(t *testing.T) {
gtest.Case(t, func() {
rule := "password2"
val1 := "12345"
val2 := "Naaaa"
val3 := "a12345-6"
val4 := ">,/;'[09-"
val5 := "a123_456"
val6 := "Nant1986"
val7 := "Nant1986!"
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
err4 := gvalid.Check(val4, rule, nil)
err5 := gvalid.Check(val5, rule, nil)
err6 := gvalid.Check(val6, rule, nil)
err7 := gvalid.Check(val7, rule, nil)
gtest.AssertNE(err1, nil)
gtest.AssertNE(err2, nil)
gtest.AssertNE(err3, nil)
gtest.AssertNE(err4, nil)
gtest.AssertNE(err5, nil)
gtest.Assert(err6, nil)
gtest.Assert(err7, nil)
})
}
func Test_Password3(t *testing.T) {
gtest.Case(t, func() {
rule := "password3"
val1 := "12345"
val2 := "Naaaa"
val3 := "a12345-6"
val4 := ">,/;'[09-"
val5 := "a123_456"
val6 := "Nant1986"
val7 := "Nant1986!"
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
err4 := gvalid.Check(val4, rule, nil)
err5 := gvalid.Check(val5, rule, nil)
err6 := gvalid.Check(val6, rule, nil)
err7 := gvalid.Check(val7, rule, nil)
gtest.AssertNE(err1, nil)
gtest.AssertNE(err2, nil)
gtest.AssertNE(err3, nil)
gtest.AssertNE(err4, nil)
gtest.AssertNE(err5, nil)
gtest.AssertNE(err6, nil)
gtest.Assert(err7, nil)
})
}
func Test_Postcode(t *testing.T) {
gtest.Case(t, func() {
rule := "postcode"
val1 := "12345"
val2 := "610036"
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
gtest.AssertNE(err1, nil)
gtest.Assert(err2, nil)
})
}
func Test_IDNumber(t *testing.T) {
gtest.Case(t, func() {
rule := "id-number"
val1 := "11111111111111"
val2 := "1111111111111111"
val3 := "311128500121201"
val4 := "510521198607185367"
val5 := "51052119860718536x"
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
err4 := gvalid.Check(val4, rule, nil)
err5 := gvalid.Check(val5, rule, nil)
gtest.AssertNE(err1, nil)
gtest.AssertNE(err2, nil)
gtest.Assert(err3, nil)
gtest.Assert(err4, nil)
gtest.Assert(err5, nil)
})
}
func Test_QQ(t *testing.T) {
gtest.Case(t, func() {
rule := "qq"
val1 := "100"
val2 := "1"
val3 := "10000"
val4 := "38996181"
val5 := "389961817"
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
err4 := gvalid.Check(val4, rule, nil)
err5 := gvalid.Check(val5, rule, nil)
gtest.AssertNE(err1, nil)
gtest.AssertNE(err2, nil)
gtest.Assert(err3, nil)
gtest.Assert(err4, nil)
gtest.Assert(err5, nil)
})
}
func Test_Ip(t *testing.T) {
if m := gvalid.Check("10.0.0.1", "ipv4", nil); m != nil {
t.Error(m)
}
if m := gvalid.Check("0.0.0.0", "ipv4", nil); m != nil {
t.Error(m)
}
if m := gvalid.Check("1920.0.0.0", "ipv4", nil); m == nil {
t.Error("ipv4校验失败")
}
if m := gvalid.Check("fe80::5484:7aff:fefe:9799", "ipv6", nil); m != nil {
t.Error(m)
}
if m := gvalid.Check("fe80::5484:7aff:fefe:9799123", "ipv6", nil); m == nil {
t.Error(m)
}
}
func Test_IPv4(t *testing.T) {
gtest.Case(t, func() {
rule := "ipv4"
val1 := "0.0.0"
val2 := "0.0.0.0"
val3 := "1.1.1.1"
val4 := "255.255.255.0"
val5 := "127.0.0.1"
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
err4 := gvalid.Check(val4, rule, nil)
err5 := gvalid.Check(val5, rule, nil)
gtest.AssertNE(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(err3, nil)
gtest.Assert(err4, nil)
gtest.Assert(err5, nil)
})
}
func Test_IPv6(t *testing.T) {
gtest.Case(t, func() {
rule := "ipv6"
val1 := "192.168.1.1"
val2 := "CDCD:910A:2222:5498:8475:1111:3900:2020"
val3 := "1030::C9B4:FF12:48AA:1A2B"
val4 := "2000:0:0:0:0:0:0:1"
val5 := "0000:0000:0000:0000:0000:ffff:c0a8:5909"
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
err4 := gvalid.Check(val4, rule, nil)
err5 := gvalid.Check(val5, rule, nil)
gtest.AssertNE(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(err3, nil)
gtest.Assert(err4, nil)
gtest.Assert(err5, nil)
})
}
func Test_MAC(t *testing.T) {
gtest.Case(t, func() {
rule := "mac"
val1 := "192.168.1.1"
val2 := "44-45-53-54-00-00"
val3 := "01:00:5e:00:00:00"
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
gtest.AssertNE(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(err3, nil)
})
}
func Test_URL(t *testing.T) {
gtest.Case(t, func() {
rule := "url"
val1 := "127.0.0.1"
val2 := "https://www.baidu.com"
val3 := "http://127.0.0.1"
val4 := "file:///tmp/test.txt"
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
err4 := gvalid.Check(val4, rule, nil)
gtest.AssertNE(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(err3, nil)
gtest.Assert(err4, nil)
})
}
func Test_Domain(t *testing.T) {
gtest.Case(t, func() {
rule := "domain"
val1 := "localhost"
val2 := "baidu.com"
val3 := "www.baidu.com"
val4 := "jn.np"
val5 := "www.jn.np"
val6 := "w.www.jn.np"
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
err4 := gvalid.Check(val4, rule, nil)
err5 := gvalid.Check(val5, rule, nil)
err6 := gvalid.Check(val6, rule, nil)
gtest.AssertNE(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(err3, nil)
gtest.Assert(err4, nil)
gtest.Assert(err5, nil)
gtest.Assert(err6, nil)
})
}
func Test_Length(t *testing.T) {
rule := "length:6,16"
if m := gvalid.Check("123456", rule, nil); m != nil {
t.Error(m)
}
if m := gvalid.Check("12345", rule, nil); m == nil {
t.Error("长度校验失败")
}
}
func Test_MinLength(t *testing.T) {
rule := "min-length:6"
if m := gvalid.Check("123456", rule, nil); m != nil {
t.Error(m)
}
if m := gvalid.Check("12345", rule, nil); m == nil {
t.Error("长度校验失败")
}
}
func Test_MaxLength(t *testing.T) {
rule := "max-length:6"
if m := gvalid.Check("12345", rule, nil); m != nil {
t.Error(m)
}
if m := gvalid.Check("1234567", rule, nil); m == nil {
t.Error("长度校验失败")
}
}
func Test_Between(t *testing.T) {
rule := "between:6.01, 10.01"
if m := gvalid.Check(10, rule, nil); m != nil {
t.Error(m)
}
if m := gvalid.Check(10.02, rule, nil); m == nil {
t.Error("大小范围校验失败")
}
}
func Test_Min(t *testing.T) {
gtest.Case(t, func() {
rule := "min:100"
val1 := "1"
val2 := "99"
val3 := "100"
val4 := "1000"
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
err4 := gvalid.Check(val4, rule, nil)
gtest.AssertNE(err1, nil)
gtest.AssertNE(err2, nil)
gtest.Assert(err3, nil)
gtest.Assert(err4, nil)
})
}
func Test_Max(t *testing.T) {
gtest.Case(t, func() {
rule := "max:100"
val1 := "1"
val2 := "99"
val3 := "100"
val4 := "1000"
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
err4 := gvalid.Check(val4, rule, nil)
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(err3, nil)
gtest.AssertNE(err4, nil)
})
}
func Test_Json(t *testing.T) {
gtest.Case(t, func() {
rule := "json"
val1 := ""
val2 := "."
val3 := "{}"
val4 := "[]"
val5 := "[1,2,3,4]"
val6 := `{"list":[1,2,3,4]}`
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
err4 := gvalid.Check(val4, rule, nil)
err5 := gvalid.Check(val5, rule, nil)
err6 := gvalid.Check(val6, rule, nil)
gtest.AssertNE(err1, nil)
gtest.AssertNE(err2, nil)
gtest.Assert(err3, nil)
gtest.Assert(err4, nil)
gtest.Assert(err5, nil)
gtest.Assert(err6, nil)
})
}
func Test_Integer(t *testing.T) {
gtest.Case(t, func() {
rule := "integer"
val1 := ""
val2 := "1.0"
val3 := "001"
val4 := "1"
val5 := "100"
val6 := `999999999`
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
err4 := gvalid.Check(val4, rule, nil)
err5 := gvalid.Check(val5, rule, nil)
err6 := gvalid.Check(val6, rule, nil)
gtest.AssertNE(err1, nil)
gtest.AssertNE(err2, nil)
gtest.Assert(err3, nil)
gtest.Assert(err4, nil)
gtest.Assert(err5, nil)
gtest.Assert(err6, nil)
})
}
func Test_Float(t *testing.T) {
gtest.Case(t, func() {
rule := "float"
val1 := ""
val2 := "a"
val3 := "1"
val4 := "1.0"
val5 := "1.1"
val6 := `0.1`
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
err4 := gvalid.Check(val4, rule, nil)
err5 := gvalid.Check(val5, rule, nil)
err6 := gvalid.Check(val6, rule, nil)
gtest.AssertNE(err1, nil)
gtest.AssertNE(err2, nil)
gtest.Assert(err3, nil)
gtest.Assert(err4, nil)
gtest.Assert(err5, nil)
gtest.Assert(err6, nil)
})
}
func Test_Boolean(t *testing.T) {
gtest.Case(t, func() {
rule := "boolean"
val1 := "a"
val2 := "-"
val3 := ""
val4 := "1"
val5 := "true"
val6 := `off`
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
err4 := gvalid.Check(val4, rule, nil)
err5 := gvalid.Check(val5, rule, nil)
err6 := gvalid.Check(val6, rule, nil)
gtest.AssertNE(err1, nil)
gtest.AssertNE(err2, nil)
gtest.Assert(err3, nil)
gtest.Assert(err4, nil)
gtest.Assert(err5, nil)
gtest.Assert(err6, nil)
})
}
func Test_Same(t *testing.T) {
gtest.Case(t, func() {
rule := "same:id"
val1 := "100"
params1 := g.Map{
"age" : 18,
}
params2 := g.Map{
"id" : 100,
}
params3 := g.Map{
"id" : 100,
"name" : "john",
}
err1 := gvalid.Check(val1, rule, nil, params1)
err2 := gvalid.Check(val1, rule, nil, params2)
err3 := gvalid.Check(val1, rule, nil, params3)
gtest.AssertNE(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(err3, nil)
})
}
func Test_Different(t *testing.T) {
gtest.Case(t, func() {
rule := "different:id"
val1 := "100"
params1 := g.Map{
"age" : 18,
}
params2 := g.Map{
"id" : 100,
}
params3 := g.Map{
"id" : 100,
"name" : "john",
}
err1 := gvalid.Check(val1, rule, nil, params1)
err2 := gvalid.Check(val1, rule, nil, params2)
err3 := gvalid.Check(val1, rule, nil, params3)
gtest.Assert(err1, nil)
gtest.AssertNE(err2, nil)
gtest.AssertNE(err3, nil)
})
}
func Test_In(t *testing.T) {
gtest.Case(t, func() {
rule := "in:100,200"
val1 := ""
val2 := "1"
val3 := "100"
val4 := "200"
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
err4 := gvalid.Check(val4, rule, nil)
gtest.AssertNE(err1, nil)
gtest.AssertNE(err2, nil)
gtest.Assert(err3, nil)
gtest.Assert(err4, nil)
})
}
func Test_NotIn(t *testing.T) {
gtest.Case(t, func() {
rule := "not-in:100,200"
val1 := ""
val2 := "1"
val3 := "100"
val4 := "200"
err1 := gvalid.Check(val1, rule, nil)
err2 := gvalid.Check(val2, rule, nil)
err3 := gvalid.Check(val3, rule, nil)
err4 := gvalid.Check(val4, rule, nil)
gtest.Assert(err1, nil)
gtest.Assert(err2, nil)
gtest.AssertNE(err3, nil)
gtest.AssertNE(err4, nil)
})
}
func Test_Regex1(t *testing.T) {
rule := `regex:\d{6}|\D{6}|length:6,16`
if m := gvalid.Check("123456", rule, nil); m != nil {
t.Error(m)
}
if m := gvalid.Check("abcde6", rule, nil); m == nil {
t.Error("校验失败")
}
}
func Test_Regex2(t *testing.T) {
gtest.Case(t, func() {
rule := `required|min-length:6|regex:^data:image\/(jpeg|png);base64,`
str1 := ""
str2 := "data"
str3 := "data:image/jpeg;base64,/9jrbattq22r"
err1 := gvalid.Check(str1, rule, nil)
err2 := gvalid.Check(str2, rule, nil)
err3 := gvalid.Check(str3, rule, nil)
gtest.AssertNE(err1, nil)
gtest.AssertNE(err2, nil)
gtest.Assert(err3, nil)
gtest.AssertNE(err1.Map()["required"], nil)
gtest.AssertNE(err2.Map()["min-length"], nil)
})
}

View File

@ -0,0 +1,67 @@
// Copyright 2019 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.
package gvalid_test
import (
"gitee.com/johng/gf/g/util/gvalid"
"testing"
)
func Test_CheckMap(t *testing.T) {
kvmap := map[string]interface{} {
"id" : "0",
"name" : "john",
}
rules := map[string]string {
"id" : "required|between:1,100",
"name" : "required|length:6,16",
}
msgs := gvalid.CustomMsg {
"id" : "ID不能为空|ID范围应当为:min到:max",
"name" : map[string]string {
"required" : "名称不能为空",
"length" : "名称长度为:min到:max个字符",
},
}
if m := gvalid.CheckMap(kvmap, rules, msgs); m == nil {
t.Error("CheckMap校验失败")
}
kvmap = map[string]interface{} {
"id" : "1",
"name" : "john",
}
rules = map[string]string {
"id" : "required|between:1,100",
"name" : "required|length:4,16",
}
msgs = map[string]interface{} {
"id" : "ID不能为空|ID范围应当为:min到:max",
"name" : map[string]string {
"required" : "名称不能为空",
"length" : "名称长度为:min到:max个字符",
},
}
if m := gvalid.CheckMap(kvmap, rules, msgs); m != nil {
t.Error(m)
}
}
// 如果值为nil并且不需要require*验证时,其他验证失效
func Test_CheckMapWithNilAndNotRequiredField(t *testing.T) {
data := map[string]interface{} {
"id" : "1",
}
rules := map[string]string {
"id" : "required",
"name" : "length:4,16",
}
if m := gvalid.CheckMap(data, rules); m != nil {
t.Error(m)
}
}

View File

@ -0,0 +1,34 @@
// Copyright 2019 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.
package gvalid_test
import (
"gitee.com/johng/gf/g/util/gvalid"
"testing"
)
func Test_CheckStruct(t *testing.T) {
type Object struct {
Name string
Age int
}
rules := map[string]string {
"Name" : "required|length:6,16",
"Age" : "between:18,30",
}
msgs := map[string]interface{} {
"Name" : map[string]string {
"required" : "名称不能为空",
"length" : "名称长度为:min到:max个字符",
},
"Age" : "年龄为18到30周岁",
}
obj := &Object{"john", 16}
if m := gvalid.CheckStruct(obj, rules, msgs); m == nil {
t.Error("CheckObject校验失败")
}
}

View File

@ -0,0 +1,80 @@
// Copyright 2019 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.
package gvalid_test
import (
"gitee.com/johng/gf/g/util/gvalid"
"strings"
"testing"
)
func Test_SetDefaultErrorMsgs(t *testing.T) {
rule := "integer|length:6,16"
msgs := map[string]string {
"integer" : "请输入一个整数",
"length" : "参数长度不对啊老铁",
}
gvalid.SetDefaultErrorMsgs(msgs)
e := gvalid.Check("6.66", rule, nil)
if e == nil || len(e.Map()) != 2 {
t.Error("规则校验失败")
} else {
if v, ok := e.Map()["integer"]; ok {
if strings.Compare(v, msgs["integer"]) != 0 {
t.Error("错误信息不匹配")
}
}
if v, ok := e.Map()["length"]; ok {
if strings.Compare(v, msgs["length"]) != 0 {
t.Error("错误信息不匹配")
}
}
}
}
func Test_CustomError1(t *testing.T) {
rule := "integer|length:6,16"
msgs := map[string]string {
"integer" : "请输入一个整数",
"length" : "参数长度不对啊老铁",
}
e := gvalid.Check("6.66", rule, msgs)
if e == nil || len(e.Map()) != 2 {
t.Error("规则校验失败")
} else {
if v, ok := e.Map()["integer"]; ok {
if strings.Compare(v, msgs["integer"]) != 0 {
t.Error("错误信息不匹配")
}
}
if v, ok := e.Map()["length"]; ok {
if strings.Compare(v, msgs["length"]) != 0 {
t.Error("错误信息不匹配")
}
}
}
}
func Test_CustomError2(t *testing.T) {
rule := "integer|length:6,16"
msgs := "请输入一个整数|参数长度不对啊老铁"
e := gvalid.Check("6.66", rule, msgs)
if e == nil || len(e.Map()) != 2 {
t.Error("规则校验失败")
} else {
if v, ok := e.Map()["integer"]; ok {
if strings.Compare(v, "请输入一个整数") != 0 {
t.Error("错误信息不匹配")
}
}
if v, ok := e.Map()["length"]; ok {
if strings.Compare(v, "参数长度不对啊老铁") != 0 {
t.Error("错误信息不匹配")
}
}
}
}

View File

@ -1,238 +0,0 @@
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.
package gvalid
import (
"strings"
"testing"
)
func Test_Regex(t *testing.T) {
rule := `regex:\d{6}|\D{6}|length:6,16`
if m := Check("123456", rule, nil); m != nil {
t.Error(m)
}
if m := Check("abcde6", rule, nil); m == nil {
t.Error("校验失败")
}
}
func Test_CheckMap(t *testing.T) {
kvmap := map[string]interface{} {
"id" : "0",
"name" : "john",
}
rules := map[string]string {
"id" : "required|between:1,100",
"name" : "required|length:6,16",
}
msgs := CustomMsg {
"id" : "ID不能为空|ID范围应当为:min到:max",
"name" : map[string]string {
"required" : "名称不能为空",
"length" : "名称长度为:min到:max个字符",
},
}
if m := CheckMap(kvmap, rules, msgs); m == nil {
t.Error("CheckMap校验失败")
}
kvmap = map[string]interface{} {
"id" : "1",
"name" : "john",
}
rules = map[string]string {
"id" : "required|between:1,100",
"name" : "required|length:4,16",
}
msgs = map[string]interface{} {
"id" : "ID不能为空|ID范围应当为:min到:max",
"name" : map[string]string {
"required" : "名称不能为空",
"length" : "名称长度为:min到:max个字符",
},
}
if m := CheckMap(kvmap, rules, msgs); m != nil {
t.Error(m)
}
}
func Test_CheckObject(t *testing.T) {
type Object struct {
Name string
Age int
}
rules := map[string]string {
"Name" : "required|length:6,16",
"Age" : "between:18,30",
}
msgs := map[string]interface{} {
"Name" : map[string]string {
"required" : "名称不能为空",
"length" : "名称长度为:min到:max个字符",
},
"Age" : "年龄为18到30周岁",
}
obj := &Object{"john", 16}
if m := CheckStruct(obj, rules, msgs); m == nil {
t.Error("CheckObject校验失败")
}
}
func Test_Required(t *testing.T) {
if m := Check("1", "required", nil); m != nil {
t.Error(m)
}
if m := Check("", "required", nil); m == nil {
t.Error(m)
}
if m := Check("", "required-if:id,1,age,18", nil, map[string]interface{}{"id" : 1, "age" : 19}); m == nil {
t.Error("Required校验失败")
}
if m := Check("", "required-if:id,1,age,18", nil, map[string]interface{}{"id" : 2, "age" : 19}); m != nil {
t.Error("Required校验失败")
}
}
func Test_Ip(t *testing.T) {
if m := Check("10.0.0.1", "ipv4", nil); m != nil {
t.Error(m)
}
if m := Check("0.0.0.0", "ipv4", nil); m != nil {
t.Error(m)
}
if m := Check("1920.0.0.0", "ipv4", nil); m == nil {
t.Error("ipv4校验失败")
}
if m := Check("fe80::5484:7aff:fefe:9799", "ipv6", nil); m != nil {
t.Error(m)
}
if m := Check("fe80::5484:7aff:fefe:9799123", "ipv6", nil); m == nil {
t.Error(m)
}
}
func Test_Length(t *testing.T) {
rule := "length:6,16"
if m := Check("123456", rule, nil); m != nil {
t.Error(m)
}
if m := Check("12345", rule, nil); m == nil {
t.Error("长度校验失败")
}
}
func Test_MinLength(t *testing.T) {
rule := "min-length:6"
if m := Check("123456", rule, nil); m != nil {
t.Error(m)
}
if m := Check("12345", rule, nil); m == nil {
t.Error("长度校验失败")
}
}
func Test_MaxLength(t *testing.T) {
rule := "max-length:6"
if m := Check("12345", rule, nil); m != nil {
t.Error(m)
}
if m := Check("1234567", rule, nil); m == nil {
t.Error("长度校验失败")
}
}
func Test_Between(t *testing.T) {
rule := "between:6.01, 10.01"
if m := Check(10, rule, nil); m != nil {
t.Error(m)
}
if m := Check(10.02, rule, nil); m == nil {
t.Error("大小范围校验失败")
}
}
func Test_SetDefaultErrorMsgs(t *testing.T) {
rule := "integer|length:6,16"
msgs := map[string]string {
"integer" : "请输入一个整数",
"length" : "参数长度不对啊老铁",
}
SetDefaultErrorMsgs(msgs)
e := Check("6.66", rule, nil)
if e == nil || len(e.Map()) != 2 {
t.Error("规则校验失败")
} else {
if v, ok := e.Map()["integer"]; ok {
if strings.Compare(v, msgs["integer"]) != 0 {
t.Error("错误信息不匹配")
}
}
if v, ok := e.Map()["length"]; ok {
if strings.Compare(v, msgs["length"]) != 0 {
t.Error("错误信息不匹配")
}
}
}
}
func Test_CustomError1(t *testing.T) {
rule := "integer|length:6,16"
msgs := map[string]string {
"integer" : "请输入一个整数",
"length" : "参数长度不对啊老铁",
}
e := Check("6.66", rule, msgs)
if e == nil || len(e.Map()) != 2 {
t.Error("规则校验失败")
} else {
if v, ok := e.Map()["integer"]; ok {
if strings.Compare(v, msgs["integer"]) != 0 {
t.Error("错误信息不匹配")
}
}
if v, ok := e.Map()["length"]; ok {
if strings.Compare(v, msgs["length"]) != 0 {
t.Error("错误信息不匹配")
}
}
}
}
func Test_CustomError2(t *testing.T) {
rule := "integer|length:6,16"
msgs := "请输入一个整数|参数长度不对啊老铁"
e := Check("6.66", rule, msgs)
if e == nil || len(e.Map()) != 2 {
t.Error("规则校验失败")
} else {
if v, ok := e.Map()["integer"]; ok {
if strings.Compare(v, "请输入一个整数") != 0 {
t.Error("错误信息不匹配")
}
}
if v, ok := e.Map()["length"]; ok {
if strings.Compare(v, "参数长度不对啊老铁") != 0 {
t.Error("错误信息不匹配")
}
}
}
}
// 如果值为nil并且不需要require*验证时,其他验证失效
func Test_CheckMapWithNilAndNotRequiredField(t *testing.T) {
data := map[string]interface{} {
"id" : "1",
}
rules := map[string]string {
"id" : "required",
"name" : "length:4,16",
}
if m := CheckMap(data, rules); m != nil {
t.Error(m)
}
}

View File

@ -1,25 +0,0 @@
// Copyright 2019 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://gitee.com/johng/gf.
package gvalid
import (
"gitee.com/johng/gf/g/util/gtest"
"testing"
)
func Test_Phone(t *testing.T) {
gtest.Case(t, func() {
err1 := Check("1361990897", "phone", nil)
err2 := Check("13619908979", "phone", nil)
err3 := Check("16719908979", "phone", nil)
err4 := Check("19719908989", "phone", nil)
gtest.AssertNE(err1, nil)
gtest.Assert(err2, nil)
gtest.Assert(err3, nil)
gtest.Assert(err4, nil)
})
}

View File

@ -1,31 +1,25 @@
package main
import (
"fmt"
"gitee.com/johng/gf/g"
"gitee.com/johng/gf/g/net/ghttp"
"sync"
)
func main() {
g := sync.WaitGroup{}
c := ghttp.NewClient()
for s1 := 97; s1 <= 122; s1++ {
g.Add(1)
go func(s1 int) {
for s2 := 97; s2 <= 122; s2++ {
for s3 := 97; s3 <= 122; s3++ {
for s4 := 97; s4 <= 122; s4++ {
url := "https://github.com/" + string(s1) + string(s2) + string(s3) + string(s4)
if r, _ := c.Get(url); r != nil {
if r.StatusCode != 200 {
fmt.Println(url, r.StatusCode)
r.Close()
}
}
}
}
}
}(s1)
func Handler(r *ghttp.Request) {
if r.Request.Method == "OPTIONS" {
return
}
g.Wait()
r.Response.WriteJson(g.Map{"name" : "john"})
}
func main() {
s := g.Server()
s.BindHookHandler("/*any", ghttp.HOOK_BEFORE_SERVE, func(r *ghttp.Request) {
r.Response.SetAllowCrossDomainRequest("*", "PUT,GET,POST,DELETE,OPTIONS")
r.Response.Header().Set("Access-Control-Allow-Credentials", "true")
r.Response.Header().Set("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, token")
})
s.Group("/v1").ALL("*", Handler, ghttp.HOOK_BEFORE_SERVE)
s.SetPort(6789)
s.Run()
}

View File

@ -1,9 +1,20 @@
package main
import (
"fmt"
"gitee.com/johng/gf/g"
"gitee.com/johng/gf/g/net/ghttp"
)
func main() {
fmt.Println(float32(10)/3)
s := g.Server()
s.BindHookHandler("/*any", ghttp.HOOK_BEFORE_SERVE, func(r *ghttp.Request) {
r.Response.SetAllowCrossDomainRequest("*", "PUT,GET,POST,DELETE,OPTIONS")
r.Response.Header().Set("Access-Control-Allow-Credentials", "true")
r.Response.Header().Set("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, token")
})
s.Group("/v1").COMMON("*", func(r *ghttp.Request) {
r.Response.WriteJson(g.Map{"name" : "john"})
})
s.SetPort(6789)
s.Run()
}