diff --git a/g/container/garray/garray_sorted_int.go b/g/container/garray/garray_sorted_int.go index 21082698f..c2723ce76 100644 --- a/g/container/garray/garray_sorted_int.go +++ b/g/container/garray/garray_sorted_int.go @@ -156,10 +156,10 @@ func (a *SortedIntArray) binSearch(value int, lock bool) (index int, result int) for min <= max { mid = int((min + max) / 2) cmp = a.compareFunc(value, a.array[mid]) - switch cmp { - case -1 : max = mid - 1 - case 1 : min = mid + 1 - case 0 : + switch { + case cmp < 0 : max = mid - 1 + case cmp > 0 : min = mid + 1 + default : return mid, cmp } } diff --git a/g/container/garray/garray_sorted_interface.go b/g/container/garray/garray_sorted_interface.go index 27ab6cdcb..b22d55e86 100644 --- a/g/container/garray/garray_sorted_interface.go +++ b/g/container/garray/garray_sorted_interface.go @@ -149,10 +149,10 @@ func (a *SortedArray) binSearch(value interface{}, lock bool)(index int, result for min <= max { mid = int((min + max) / 2) cmp = a.compareFunc(value, a.array[mid]) - switch cmp { - case -1 : max = mid - 1 - case 1 : min = mid + 1 - case 0 : + switch { + case cmp < 0 : max = mid - 1 + case cmp > 0 : min = mid + 1 + default : return mid, cmp } } diff --git a/g/container/garray/garray_sorted_string.go b/g/container/garray/garray_sorted_string.go index 7cae7e73d..969a921df 100644 --- a/g/container/garray/garray_sorted_string.go +++ b/g/container/garray/garray_sorted_string.go @@ -150,10 +150,10 @@ func (a *SortedStringArray) binSearch(value string, lock bool) (index int, resul for min <= max { mid = int((min + max) / 2) cmp = a.compareFunc(value, a.array[mid]) - switch cmp { - case -1 : max = mid - 1 - case 1 : min = mid + 1 - case 0 : + switch { + case cmp < 0 : max = mid - 1 + case cmp > 0 : min = mid + 1 + default : return mid, cmp } } diff --git a/g/database/gdb/gdb_type_result.go b/g/database/gdb/gdb_type_result.go index 20330e94b..b08bdd1ec 100644 --- a/g/database/gdb/gdb_type_result.go +++ b/g/database/gdb/gdb_type_result.go @@ -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) diff --git a/g/net/ghttp/ghttp_server_handler.go b/g/net/ghttp/ghttp_server_handler.go index b22bd5887..27fb7028e 100644 --- a/g/net/ghttp/ghttp_server_handler.go +++ b/g/net/ghttp/ghttp_server_handler.go @@ -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) + } } } } diff --git a/g/net/ghttp/ghttp_server_router_group.go b/g/net/ghttp/ghttp_server_router_group.go index fec8e318a..08e600d7e 100644 --- a/g/net/ghttp/ghttp_server_router_group.go +++ b/g/net/ghttp/ghttp_server_router_group.go @@ -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...) } diff --git a/g/os/gfcache/gfcache.go b/g/os/gfcache/gfcache.go index ffd7891d9..36a429889 100644 --- a/g/os/gfcache/gfcache.go +++ b/g/os/gfcache/gfcache.go @@ -10,14 +10,14 @@ package gfcache import ( + "gitee.com/johng/gf/g/container/gmap" "gitee.com/johng/gf/g/container/gtype" - "gitee.com/johng/gf/g/os/gcache" ) type Cache struct { - cap *gtype.Int // 缓存容量(byte),设置为0表示不限制 - size *gtype.Int // 缓存大小(Byte) - cache *gcache.Cache // 缓存对象 + cap *gtype.Int // 缓存容量(byte),设置为0表示不限制 + size *gtype.Int // 缓存大小(Byte) + cache *gmap.StringInterfaceMap // 缓存对象 } const ( @@ -38,11 +38,10 @@ func New(cap ... int) *Cache { return &Cache { cap : gtype.NewInt(c), size : gtype.NewInt(), - cache : gcache.New(), + cache : gmap.NewStringInterfaceMap(), } } - // 获得已缓存的文件大小(byte) func GetSize() int { return cache.GetSize() diff --git a/g/os/gfcache/gfcache_cache.go b/g/os/gfcache/gfcache_cache.go index 91981fa01..0021150f9 100644 --- a/g/os/gfcache/gfcache_cache.go +++ b/g/os/gfcache/gfcache_cache.go @@ -12,7 +12,7 @@ import ( "gitee.com/johng/gf/g/os/gfsnotify" ) -// 设置容量大小(MB) +// 设置容量大小(byte) func (c *Cache) SetCap(cap int) { c.cap.Set(cap) } @@ -34,15 +34,15 @@ func (c *Cache) GetContents(path string) string { // 获得文件内容 []byte func (c *Cache) GetBinContents(path string) []byte { - v := c.cache.Get(path) - if v != nil { + if v := c.cache.Get(path); v != nil { return v.([]byte) } b := gfile.GetBinContents(path) - if b != nil && (c.cap.Val() == 0 || c.size.Val() < c.cap.Val()) { - c.addMonitor(path) - c.cache.Set(path, b, 0) + // 读取到内容,并且没有超过缓存容量限制时才会执行缓存 + if len(b) > 0 && (c.cap.Val() == 0 || c.size.Val() < c.cap.Val()) { c.size.Add(len(b)) + c.cache.Set(path, b) + c.addMonitor(path) } return b } @@ -55,19 +55,22 @@ func (c *Cache) addMonitor(path string) { } gfsnotify.Add(path, func(event *gfsnotify.Event) { //glog.Debug("gfcache:", event) - r := c.cache.Get(path).([]byte) + length := 0 + if r := c.cache.Get(path); r != nil { + length = len(r.([]byte)) + } // 是否删除 if event.IsRemove() { c.cache.Remove(path) - c.size.Add(-len(r)) + c.size.Add(-length) + return } // 更新缓存内容 if c.cap.Val() == 0 || c.size.Val() < c.cap.Val() { b := gfile.GetBinContents(path) - if b != nil { - dif := len(b) - len(r) - c.cache.Set(path, b, 0) - c.size.Add(dif) + if len(b) > 0 { + c.size.Add(len(b) - length) + c.cache.Set(path, b) } } }) diff --git a/g/util/gvalid/gvalid.go b/g/util/gvalid/gvalid.go index 4e471848c..d94eaf42a 100644 --- a/g/util/gvalid/gvalid.go +++ b/g/util/gvalid/gvalid.go @@ -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参数的值相同 diff --git a/g/util/gvalid/gvalid_check.go b/g/util/gvalid/gvalid_check.go index dede01b58..6e06c779b 100644 --- a/g/util/gvalid/gvalid_check.go +++ b/g/util/gvalid/gvalid_check.go @@ -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 } diff --git a/g/util/gvalid/gvalid_unit_basic_all_test.go b/g/util/gvalid/gvalid_unit_basic_all_test.go new file mode 100644 index 000000000..3627d30a5 --- /dev/null +++ b/g/util/gvalid/gvalid_unit_basic_all_test.go @@ -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) + }) +} \ No newline at end of file diff --git a/g/util/gvalid/gvalid_unit_checkmap_test.go b/g/util/gvalid/gvalid_unit_checkmap_test.go new file mode 100644 index 000000000..c7aed2d0d --- /dev/null +++ b/g/util/gvalid/gvalid_unit_checkmap_test.go @@ -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) + } +} + diff --git a/g/util/gvalid/gvalid_unit_checkstruct_test.go b/g/util/gvalid/gvalid_unit_checkstruct_test.go new file mode 100644 index 000000000..11d339640 --- /dev/null +++ b/g/util/gvalid/gvalid_unit_checkstruct_test.go @@ -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校验失败") + } +} diff --git a/g/util/gvalid/gvalid_unit_customerror_test.go b/g/util/gvalid/gvalid_unit_customerror_test.go new file mode 100644 index 000000000..35c88e83d --- /dev/null +++ b/g/util/gvalid/gvalid_unit_customerror_test.go @@ -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("错误信息不匹配") + } + } + } +} \ No newline at end of file diff --git a/g/util/gvalid/gvalid_unix_basic_test.go b/g/util/gvalid/gvalid_unix_basic_test.go deleted file mode 100644 index 77e6274f1..000000000 --- a/g/util/gvalid/gvalid_unix_basic_test.go +++ /dev/null @@ -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) - } -} \ No newline at end of file diff --git a/g/util/gvalid/gvalid_unix_phone_test.go b/g/util/gvalid/gvalid_unix_phone_test.go deleted file mode 100644 index 8618f17c7..000000000 --- a/g/util/gvalid/gvalid_unix_phone_test.go +++ /dev/null @@ -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) - }) -} diff --git a/geg/other/test.go b/geg/other/test.go index f51d44077..25e66bdb0 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -2,6 +2,7 @@ package main import ( "fmt" +<<<<<<< HEAD "gitee.com/johng/gf/g/net/ghttp" "strings" "time" @@ -12,4 +13,11 @@ func main() { time.Sleep(500*time.Millisecond) fmt.Println(strings.TrimSpace(ghttp.GetContent("http://127.0.0.1:8881"))) } +======= + "gitee.com/johng/gf/g/os/gfile" +) + +func main() { + fmt.Println(gfile.RealPath("config")) +>>>>>>> master } \ No newline at end of file diff --git a/geg/other/test2.go b/geg/other/test2.go index f686389ca..b562a0c86 100644 --- a/geg/other/test2.go +++ b/geg/other/test2.go @@ -1,5 +1,6 @@ package main +<<<<<<< HEAD func main() { //listener, err := reuseport.Listen("tcp", ":8881") //if err != nil { @@ -14,4 +15,23 @@ func main() { //}) // //panic(server.Serve(listener)) +======= +import ( + "gitee.com/johng/gf/g" + "gitee.com/johng/gf/g/net/ghttp" +) + +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").COMMON("*", func(r *ghttp.Request) { + r.Response.WriteJson(g.Map{"name" : "john"}) + }) + s.SetPort(6789) + s.Run() +>>>>>>> master } \ No newline at end of file diff --git a/version.go b/version.go index c02ef9f2e..4a61b91f2 100644 --- a/version.go +++ b/version.go @@ -1,5 +1,5 @@ package gf -const VERSION = "v1.4.6" +const VERSION = "v1.4.7" const AUTHORS = "john"