mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
add context for validation functions of package gvalid
This commit is contained in:
@ -4,11 +4,126 @@
|
||||
// If a copy of the MIT was not distributed with this file,
|
||||
// You can obtain one at https://github.com/gogf/gf.
|
||||
|
||||
// Package guid provides simple and high performance unique id generation functionality.
|
||||
//
|
||||
// Unique String ID:
|
||||
// PLEASE VERY NOTE:
|
||||
// This package only provides unique number generation for simple, convenient and most common
|
||||
// usage purpose, but does not provide strict global unique number generation. Please refer
|
||||
// to UUID algorithm for global unique number generation if necessary.
|
||||
package guid
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/container/gtype"
|
||||
"github.com/gogf/gf/encoding/ghash"
|
||||
"github.com/gogf/gf/net/gipv4"
|
||||
"github.com/gogf/gf/util/grand"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
sequenceMax = uint32(46655) // Sequence max("zzz").
|
||||
randomStrBase = "0123456789abcdefghijklmnopqrstuvwxyz" // Random chars string(36 bytes).
|
||||
)
|
||||
|
||||
var (
|
||||
sequence gtype.Uint32 // Sequence for unique purpose of current process.
|
||||
macAddrStr = "0000000" // MAC addresses hash result in 7 bytes.
|
||||
processIdStr = "0000" // Process id in 4 bytes.
|
||||
)
|
||||
|
||||
// init initializes several fixed local variable.
|
||||
func init() {
|
||||
// MAC addresses hash result in 7 bytes.
|
||||
macs, _ := gipv4.GetMacArray()
|
||||
if len(macs) > 0 {
|
||||
var macAddrBytes []byte
|
||||
for _, mac := range macs {
|
||||
macAddrBytes = append(macAddrBytes, []byte(mac)...)
|
||||
}
|
||||
b := []byte{'0', '0', '0', '0', '0', '0', '0'}
|
||||
s := strconv.FormatUint(uint64(ghash.DJBHash(macAddrBytes)), 36)
|
||||
copy(b, s)
|
||||
macAddrStr = string(b)
|
||||
}
|
||||
// Process id in 4 bytes.
|
||||
{
|
||||
b := []byte{'0', '0', '0', '0'}
|
||||
s := strconv.FormatInt(int64(os.Getpid()), 36)
|
||||
copy(b, s)
|
||||
processIdStr = string(b)
|
||||
}
|
||||
}
|
||||
|
||||
// S creates and returns a global unique string in 32 bytes that meets most common
|
||||
// usages without strict UUID algorithm. It returns a unique string using default
|
||||
// unique algorithm if no `data` is given.
|
||||
//
|
||||
// The specified `data` can be no more than 2 parts. No matter how long each of the
|
||||
// `data` size is, each of them will be hashed into 7 bytes as part of the result.
|
||||
// If given `data` parts is less than 2, the leftover size of the result bytes will
|
||||
// be token by random string.
|
||||
//
|
||||
// The returned string is composed with:
|
||||
// 1. Default: MAC(7) + PID(4) + TimestampNano(12) + Sequence(3) + RandomString(6)
|
||||
// 2. CustomData: Data(7/14) + TimestampNano(12) + Sequence(3) + RandomString(3/10)
|
||||
//
|
||||
// Note that:
|
||||
// 1. The returned length is fixed to 32 bytes for performance purpose.
|
||||
// 2. The custom parameter `data` composed should have unique attribute in your
|
||||
// business situation.
|
||||
func S(data ...[]byte) string {
|
||||
var (
|
||||
b = make([]byte, 32)
|
||||
nanoStr = strconv.FormatInt(time.Now().UnixNano(), 36)
|
||||
)
|
||||
if len(data) == 0 {
|
||||
copy(b, macAddrStr)
|
||||
copy(b[7:], processIdStr)
|
||||
copy(b[11:], nanoStr)
|
||||
copy(b[23:], getSequence())
|
||||
copy(b[26:], getRandomStr(6))
|
||||
} else if len(data) <= 2 {
|
||||
n := 0
|
||||
for i, v := range data {
|
||||
// Ignore empty data item bytes.
|
||||
if len(v) > 0 {
|
||||
copy(b[i*7:], getDataHashStr(v))
|
||||
n += 7
|
||||
}
|
||||
}
|
||||
copy(b[n:], nanoStr)
|
||||
copy(b[n+12:], getSequence())
|
||||
copy(b[n+12+3:], getRandomStr(32-n-12-3))
|
||||
} else {
|
||||
panic("too many data parts, it should be no more than 2 parts")
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// getSequence increases and returns the sequence string in 3 bytes.
|
||||
// The sequence is less than "zzz"(46655).
|
||||
func getSequence() []byte {
|
||||
b := []byte{'0', '0', '0'}
|
||||
s := strconv.FormatUint(uint64(sequence.Add(1)%sequenceMax), 36)
|
||||
copy(b, s)
|
||||
return b
|
||||
}
|
||||
|
||||
// getRandomStr randomly picks and returns `n` count of chars from randomStrBase.
|
||||
func getRandomStr(n int) []byte {
|
||||
if n <= 0 {
|
||||
return []byte{}
|
||||
}
|
||||
var (
|
||||
b = make([]byte, n)
|
||||
numberBytes = grand.B(n)
|
||||
)
|
||||
for i := range b {
|
||||
b[i] = randomStrBase[numberBytes[i]%36]
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// getDataHashStr creates and returns hash bytes in 7 bytes with given data bytes.
|
||||
func getDataHashStr(data []byte) []byte {
|
||||
b := []byte{'0', '0', '0', '0', '0', '0', '0'}
|
||||
s := strconv.FormatUint(uint64(ghash.DJBHash(data)), 36)
|
||||
copy(b, s)
|
||||
return b
|
||||
}
|
||||
|
||||
@ -1,129 +0,0 @@
|
||||
// Copyright GoFrame Author(https://goframe.org). 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://github.com/gogf/gf.
|
||||
|
||||
package guid
|
||||
|
||||
import (
|
||||
"github.com/gogf/gf/container/gtype"
|
||||
"github.com/gogf/gf/encoding/ghash"
|
||||
"github.com/gogf/gf/net/gipv4"
|
||||
"github.com/gogf/gf/util/grand"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
sequenceMax = uint32(46655) // Sequence max("zzz").
|
||||
randomStrBase = "0123456789abcdefghijklmnopqrstuvwxyz" // Random chars string(36 bytes).
|
||||
)
|
||||
|
||||
var (
|
||||
sequence gtype.Uint32 // Sequence for unique purpose of current process.
|
||||
macAddrStr = "0000000" // MAC addresses hash result in 7 bytes.
|
||||
processIdStr = "0000" // Process id in 4 bytes.
|
||||
)
|
||||
|
||||
// init initializes several fixed local variable.
|
||||
func init() {
|
||||
// MAC addresses hash result in 7 bytes.
|
||||
macs, _ := gipv4.GetMacArray()
|
||||
if len(macs) > 0 {
|
||||
var macAddrBytes []byte
|
||||
for _, mac := range macs {
|
||||
macAddrBytes = append(macAddrBytes, []byte(mac)...)
|
||||
}
|
||||
b := []byte{'0', '0', '0', '0', '0', '0', '0'}
|
||||
s := strconv.FormatUint(uint64(ghash.DJBHash(macAddrBytes)), 36)
|
||||
copy(b, s)
|
||||
macAddrStr = string(b)
|
||||
}
|
||||
// Process id in 4 bytes.
|
||||
{
|
||||
b := []byte{'0', '0', '0', '0'}
|
||||
s := strconv.FormatInt(int64(os.Getpid()), 36)
|
||||
copy(b, s)
|
||||
processIdStr = string(b)
|
||||
}
|
||||
}
|
||||
|
||||
// S creates and returns a global unique string in 32 bytes that meets most common
|
||||
// usages without strict UUID algorithm. It returns an unique string using default
|
||||
// unique algorithm if no `data` is given.
|
||||
//
|
||||
// The specified `data` can be no more than 2 parts. No matter how long each of the
|
||||
// `data` size is, each of them will be hashed into 7 bytes as part of the result.
|
||||
// If given `data` parts is less than 2, the leftover size of the result bytes will
|
||||
// be token by random string.
|
||||
//
|
||||
// The returned string is composed with:
|
||||
// 1. Default: MAC(7) + PID(4) + TimestampNano(12) + Sequence(3) + RandomString(6)
|
||||
// 2. CustomData: Data(7/14) + TimestampNano(12) + Sequence(3) + RandomString(3/10)
|
||||
//
|
||||
// Note that:
|
||||
// 1. The returned length is fixed to 32 bytes for performance purpose.
|
||||
// 2. The custom parameter `data` composed should have unique attribute in your
|
||||
// business situation.
|
||||
func S(data ...[]byte) string {
|
||||
var (
|
||||
b = make([]byte, 32)
|
||||
nanoStr = strconv.FormatInt(time.Now().UnixNano(), 36)
|
||||
)
|
||||
if len(data) == 0 {
|
||||
copy(b, macAddrStr)
|
||||
copy(b[7:], processIdStr)
|
||||
copy(b[11:], nanoStr)
|
||||
copy(b[23:], getSequence())
|
||||
copy(b[26:], getRandomStr(6))
|
||||
} else if len(data) <= 2 {
|
||||
n := 0
|
||||
for i, v := range data {
|
||||
// Ignore empty data item bytes.
|
||||
if len(v) > 0 {
|
||||
copy(b[i*7:], getDataHashStr(v))
|
||||
n += 7
|
||||
}
|
||||
}
|
||||
copy(b[n:], nanoStr)
|
||||
copy(b[n+12:], getSequence())
|
||||
copy(b[n+12+3:], getRandomStr(32-n-12-3))
|
||||
} else {
|
||||
panic("too many data parts, it should be no more than 2 parts")
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// getSequence increases and returns the sequence string in 3 bytes.
|
||||
// The sequence is less than "zzz"(46655).
|
||||
func getSequence() []byte {
|
||||
b := []byte{'0', '0', '0'}
|
||||
s := strconv.FormatUint(uint64(sequence.Add(1)%sequenceMax), 36)
|
||||
copy(b, s)
|
||||
return b
|
||||
}
|
||||
|
||||
// getRandomStr randomly picks and returns `n` count of chars from randomStrBase.
|
||||
func getRandomStr(n int) []byte {
|
||||
if n <= 0 {
|
||||
return []byte{}
|
||||
}
|
||||
var (
|
||||
b = make([]byte, n)
|
||||
numberBytes = grand.B(n)
|
||||
)
|
||||
for i := range b {
|
||||
b[i] = randomStrBase[numberBytes[i]%36]
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// getDataHashStr creates and returns hash bytes in 7 bytes with given data bytes.
|
||||
func getDataHashStr(data []byte) []byte {
|
||||
b := []byte{'0', '0', '0', '0', '0', '0', '0'}
|
||||
s := strconv.FormatUint(uint64(ghash.DJBHash(data)), 36)
|
||||
copy(b, s)
|
||||
return b
|
||||
}
|
||||
@ -253,7 +253,7 @@ func CheckValue(ctx context.Context, value interface{}, rules string, messages i
|
||||
if len(params) > 0 {
|
||||
data = params[0]
|
||||
}
|
||||
return defaultValidator.Ctx(ctx).Rules(rules).Data(data).Messages(messages).CheckValue(value)
|
||||
return defaultValidator.Rules(rules).Data(data).Messages(messages).CheckValue(ctx, value)
|
||||
}
|
||||
|
||||
// CheckMap validates map and returns the error result. It returns nil if with successful validation.
|
||||
@ -266,7 +266,7 @@ func CheckMap(ctx context.Context, params interface{}, rules interface{}, messag
|
||||
if len(messages) > 0 {
|
||||
customErrorMessages = messages[0]
|
||||
}
|
||||
return defaultValidator.Ctx(ctx).Rules(rules).Messages(customErrorMessages).CheckMap(params)
|
||||
return defaultValidator.Rules(rules).Messages(customErrorMessages).CheckMap(ctx, params)
|
||||
}
|
||||
|
||||
// CheckStruct validates struct and returns the error result.
|
||||
@ -280,7 +280,7 @@ func CheckStruct(ctx context.Context, object interface{}, rules interface{}, mes
|
||||
if len(messages) > 0 {
|
||||
customErrorMessages = messages[0]
|
||||
}
|
||||
return defaultValidator.Ctx(ctx).Rules(rules).Messages(customErrorMessages).CheckStruct(object)
|
||||
return defaultValidator.Rules(rules).Messages(customErrorMessages).CheckStruct(ctx, object)
|
||||
}
|
||||
|
||||
// CheckStructWithData validates struct with given parameter map and returns the error result.
|
||||
@ -294,7 +294,7 @@ func CheckStructWithData(ctx context.Context, object interface{}, data interface
|
||||
if len(messages) > 0 {
|
||||
customErrorMessages = messages[0]
|
||||
}
|
||||
return defaultValidator.Ctx(ctx).Data(data).Rules(rules).Messages(customErrorMessages).CheckStruct(object)
|
||||
return defaultValidator.Data(data).Rules(rules).Messages(customErrorMessages).CheckStruct(ctx, object)
|
||||
}
|
||||
|
||||
// parseSequenceTag parses one sequence tag to field, rule and error message.
|
||||
|
||||
@ -9,6 +9,7 @@ package gvalid
|
||||
import "context"
|
||||
|
||||
// RuleFunc is the custom function for data validation.
|
||||
//
|
||||
// The parameter `rule` specifies the validation rule string, like "required", "between:1,100", etc.
|
||||
// The parameter `value` specifies the value for this rule to validate.
|
||||
// The parameter `message` specifies the custom error message or configured i18n message for this rule.
|
||||
|
||||
@ -182,7 +182,7 @@ func (e *validationError) FirstString() (err string) {
|
||||
return
|
||||
}
|
||||
|
||||
// Current is alis of FirstString, which implements interface gerror.ApiCurrent.
|
||||
// Current is alis of FirstString, which implements interface gerror.iCurrent.
|
||||
func (e *validationError) Current() error {
|
||||
if e == nil {
|
||||
return nil
|
||||
|
||||
@ -7,13 +7,11 @@
|
||||
package gvalid
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/i18n/gi18n"
|
||||
)
|
||||
|
||||
// Validator is the validation manager for chaining operations.
|
||||
type Validator struct {
|
||||
ctx context.Context // Context containing custom context variables.
|
||||
i18nManager *gi18n.Manager // I18n manager for error message translation.
|
||||
key string // Single validation key.
|
||||
value interface{} // Single validation value.
|
||||
@ -28,7 +26,6 @@ type Validator struct {
|
||||
// New creates and returns a new Validator.
|
||||
func New() *Validator {
|
||||
return &Validator{
|
||||
ctx: context.TODO(), // Initialize an empty context.
|
||||
i18nManager: gi18n.Instance(), // Use default i18n manager.
|
||||
ruleFuncMap: make(map[string]RuleFunc), // Custom rule function storing map.
|
||||
}
|
||||
@ -48,13 +45,6 @@ func (v *Validator) I18n(i18nManager *gi18n.Manager) *Validator {
|
||||
return newValidator
|
||||
}
|
||||
|
||||
// Ctx is a chaining operation function, which sets the context for next validation.
|
||||
func (v *Validator) Ctx(ctx context.Context) *Validator {
|
||||
newValidator := v.Clone()
|
||||
newValidator.ctx = ctx
|
||||
return newValidator
|
||||
}
|
||||
|
||||
// Bail sets the mark for stopping validation after the first validation error.
|
||||
func (v *Validator) Bail() *Validator {
|
||||
newValidator := v.Clone()
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
package gvalid
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/errors/gcode"
|
||||
"github.com/gogf/gf/util/gconv"
|
||||
"strings"
|
||||
@ -14,11 +15,11 @@ import (
|
||||
|
||||
// CheckMap validates map and returns the error result. It returns nil if with successful validation.
|
||||
// The parameter `params` should be type of map.
|
||||
func (v *Validator) CheckMap(params interface{}) Error {
|
||||
return v.doCheckMap(params)
|
||||
func (v *Validator) CheckMap(ctx context.Context, params interface{}) Error {
|
||||
return v.doCheckMap(ctx, params)
|
||||
}
|
||||
|
||||
func (v *Validator) doCheckMap(params interface{}) Error {
|
||||
func (v *Validator) doCheckMap(ctx context.Context, params interface{}) Error {
|
||||
// If there's no validation rules, it does nothing and returns quickly.
|
||||
if params == nil || v.rules == nil {
|
||||
return nil
|
||||
@ -105,7 +106,7 @@ func (v *Validator) doCheckMap(params interface{}) Error {
|
||||
value = valueItem
|
||||
}
|
||||
// It checks each rule and its value in loop.
|
||||
if validatedError := v.doCheckValue(doCheckValueInput{
|
||||
if validatedError := v.doCheckValue(ctx, doCheckValueInput{
|
||||
Name: checkRuleItem.Name,
|
||||
Value: value,
|
||||
Rule: checkRuleItem.Rule,
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
package gvalid
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/errors/gcode"
|
||||
"github.com/gogf/gf/internal/structs"
|
||||
"github.com/gogf/gf/util/gconv"
|
||||
@ -16,14 +17,14 @@ import (
|
||||
|
||||
// CheckStruct validates struct and returns the error result.
|
||||
// The parameter `object` should be type of struct/*struct.
|
||||
func (v *Validator) CheckStruct(object interface{}) Error {
|
||||
return v.doCheckStruct(object)
|
||||
func (v *Validator) CheckStruct(ctx context.Context, object interface{}) Error {
|
||||
return v.doCheckStruct(ctx, object)
|
||||
}
|
||||
|
||||
func (v *Validator) doCheckStruct(object interface{}) Error {
|
||||
func (v *Validator) doCheckStruct(ctx context.Context, object interface{}) Error {
|
||||
var (
|
||||
errorMaps = make(map[string]map[string]string) // Returning error.
|
||||
fieldToAliasNameMap = make(map[string]string) // Field name to alias name map.
|
||||
fieldToAliasNameMap = make(map[string]string) // Field names to alias name map.
|
||||
)
|
||||
fieldMap, err := structs.FieldMap(structs.FieldMapInput{
|
||||
Pointer: object,
|
||||
@ -33,7 +34,7 @@ func (v *Validator) doCheckStruct(object interface{}) Error {
|
||||
if err != nil {
|
||||
return newErrorStr(internalObjectErrRuleName, err.Error())
|
||||
}
|
||||
// It checks the struct recursively the its attribute is an embedded struct.
|
||||
// It checks the struct recursively if its attribute is an embedded struct.
|
||||
for _, field := range fieldMap {
|
||||
if field.IsEmbedded() {
|
||||
// No validation interface implements check.
|
||||
@ -43,7 +44,7 @@ func (v *Validator) doCheckStruct(object interface{}) Error {
|
||||
if _, ok := field.TagLookup(noValidationTagName); ok {
|
||||
continue
|
||||
}
|
||||
if err := v.doCheckStruct(field.Value); err != nil {
|
||||
if err := v.doCheckStruct(ctx, field.Value); err != nil {
|
||||
// It merges the errors into single error map.
|
||||
for k, m := range err.(*validationError).errors {
|
||||
errorMaps[k] = m
|
||||
@ -244,7 +245,7 @@ func (v *Validator) doCheckStruct(object interface{}) Error {
|
||||
for _, checkRuleItem := range checkRules {
|
||||
_, value = gutil.MapPossibleItemByKey(inputParamMap, checkRuleItem.Name)
|
||||
// It checks each rule and its value in loop.
|
||||
if validatedError := v.doCheckValue(doCheckValueInput{
|
||||
if validatedError := v.doCheckValue(ctx, doCheckValueInput{
|
||||
Name: checkRuleItem.Name,
|
||||
Value: value,
|
||||
Rule: checkRuleItem.Rule,
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
package gvalid
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/errors/gcode"
|
||||
"github.com/gogf/gf/errors/gerror"
|
||||
"github.com/gogf/gf/text/gstr"
|
||||
@ -30,8 +31,8 @@ type iTime interface {
|
||||
|
||||
// CheckValue checks single value with specified rules.
|
||||
// It returns nil if successful validation.
|
||||
func (v *Validator) CheckValue(value interface{}) Error {
|
||||
return v.doCheckValue(doCheckValueInput{
|
||||
func (v *Validator) CheckValue(ctx context.Context, value interface{}) Error {
|
||||
return v.doCheckValue(ctx, doCheckValueInput{
|
||||
Name: "",
|
||||
Value: value,
|
||||
Rule: gconv.String(v.rules),
|
||||
@ -51,7 +52,7 @@ type doCheckValueInput struct {
|
||||
}
|
||||
|
||||
// doCheckSingleValue does the really rules validation for single key-value.
|
||||
func (v *Validator) doCheckValue(input doCheckValueInput) Error {
|
||||
func (v *Validator) doCheckValue(ctx context.Context, input doCheckValueInput) Error {
|
||||
// If there's no validation rules, it does nothing and returns quickly.
|
||||
if input.Rule == "" {
|
||||
return nil
|
||||
@ -131,8 +132,8 @@ func (v *Validator) doCheckValue(input doCheckValueInput) Error {
|
||||
customRuleFunc = v.getRuleFunc(ruleKey)
|
||||
if customRuleFunc != nil {
|
||||
// It checks custom validation rules with most priority.
|
||||
message := v.getErrorMessageByRule(ruleKey, customMsgMap)
|
||||
if err := customRuleFunc(v.ctx, ruleItems[index], input.Value, message, input.DataRaw); err != nil {
|
||||
message := v.getErrorMessageByRule(ctx, ruleKey, customMsgMap)
|
||||
if err := customRuleFunc(ctx, ruleItems[index], input.Value, message, input.DataRaw); err != nil {
|
||||
match = false
|
||||
errorMsgArray[ruleKey] = err.Error()
|
||||
} else {
|
||||
@ -140,15 +141,18 @@ func (v *Validator) doCheckValue(input doCheckValueInput) Error {
|
||||
}
|
||||
} else {
|
||||
// It checks build-in validation rules if there's no custom rule.
|
||||
match, err = v.doCheckBuildInRules(doCheckBuildInRulesInput{
|
||||
Index: index,
|
||||
Value: input.Value,
|
||||
RuleKey: ruleKey,
|
||||
RulePattern: rulePattern,
|
||||
RuleItems: ruleItems,
|
||||
DataMap: input.DataMap,
|
||||
CustomMsgMap: customMsgMap,
|
||||
})
|
||||
match, err = v.doCheckBuildInRules(
|
||||
ctx,
|
||||
doCheckBuildInRulesInput{
|
||||
Index: index,
|
||||
Value: input.Value,
|
||||
RuleKey: ruleKey,
|
||||
RulePattern: rulePattern,
|
||||
RuleItems: ruleItems,
|
||||
DataMap: input.DataMap,
|
||||
CustomMsgMap: customMsgMap,
|
||||
},
|
||||
)
|
||||
if !match && err != nil {
|
||||
errorMsgArray[ruleKey] = err.Error()
|
||||
}
|
||||
@ -159,7 +163,7 @@ func (v *Validator) doCheckValue(input doCheckValueInput) Error {
|
||||
// It does nothing if the error message for this rule
|
||||
// is already set in previous validation.
|
||||
if _, ok := errorMsgArray[ruleKey]; !ok {
|
||||
errorMsgArray[ruleKey] = v.getErrorMessageByRule(ruleKey, customMsgMap)
|
||||
errorMsgArray[ruleKey] = v.getErrorMessageByRule(ctx, ruleKey, customMsgMap)
|
||||
}
|
||||
// If it is with error and there's bail rule,
|
||||
// it then does not continue validating for left rules.
|
||||
@ -170,9 +174,13 @@ func (v *Validator) doCheckValue(input doCheckValueInput) Error {
|
||||
index++
|
||||
}
|
||||
if len(errorMsgArray) > 0 {
|
||||
return newError(gcode.CodeValidationFailed, []fieldRule{{Name: input.Name, Rule: input.Rule}}, map[string]map[string]string{
|
||||
input.Name: errorMsgArray,
|
||||
})
|
||||
return newError(
|
||||
gcode.CodeValidationFailed,
|
||||
[]fieldRule{{Name: input.Name, Rule: input.Rule}},
|
||||
map[string]map[string]string{
|
||||
input.Name: errorMsgArray,
|
||||
},
|
||||
)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -187,7 +195,7 @@ type doCheckBuildInRulesInput struct {
|
||||
CustomMsgMap map[string]string
|
||||
}
|
||||
|
||||
func (v *Validator) doCheckBuildInRules(input doCheckBuildInRulesInput) (match bool, err error) {
|
||||
func (v *Validator) doCheckBuildInRules(ctx context.Context, input doCheckBuildInRulesInput) (match bool, err error) {
|
||||
valueStr := gconv.String(input.Value)
|
||||
switch input.RuleKey {
|
||||
// Required rules.
|
||||
@ -208,7 +216,7 @@ func (v *Validator) doCheckBuildInRules(input doCheckBuildInRulesInput) (match b
|
||||
"min-length",
|
||||
"max-length",
|
||||
"size":
|
||||
if msg := v.checkLength(valueStr, input.RuleKey, input.RulePattern, input.CustomMsgMap); msg != "" {
|
||||
if msg := v.checkLength(ctx, valueStr, input.RuleKey, input.RulePattern, input.CustomMsgMap); msg != "" {
|
||||
return match, gerror.NewOption(gerror.Option{
|
||||
Text: msg,
|
||||
Code: gcode.CodeValidationFailed,
|
||||
@ -222,7 +230,7 @@ func (v *Validator) doCheckBuildInRules(input doCheckBuildInRulesInput) (match b
|
||||
"min",
|
||||
"max",
|
||||
"between":
|
||||
if msg := v.checkRange(valueStr, input.RuleKey, input.RulePattern, input.CustomMsgMap); msg != "" {
|
||||
if msg := v.checkRange(ctx, valueStr, input.RuleKey, input.RulePattern, input.CustomMsgMap); msg != "" {
|
||||
return match, gerror.NewOption(gerror.Option{
|
||||
Text: msg,
|
||||
Code: gcode.CodeValidationFailed,
|
||||
@ -260,7 +268,7 @@ func (v *Validator) doCheckBuildInRules(input doCheckBuildInRulesInput) (match b
|
||||
match = true
|
||||
} else {
|
||||
var msg string
|
||||
msg = v.getErrorMessageByRule(input.RuleKey, input.CustomMsgMap)
|
||||
msg = v.getErrorMessageByRule(ctx, input.RuleKey, input.CustomMsgMap)
|
||||
msg = strings.Replace(msg, ":format", input.RulePattern, -1)
|
||||
return match, gerror.NewOption(gerror.Option{
|
||||
Text: msg,
|
||||
@ -278,7 +286,7 @@ func (v *Validator) doCheckBuildInRules(input doCheckBuildInRulesInput) (match b
|
||||
}
|
||||
if !match {
|
||||
var msg string
|
||||
msg = v.getErrorMessageByRule(input.RuleKey, input.CustomMsgMap)
|
||||
msg = v.getErrorMessageByRule(ctx, input.RuleKey, input.CustomMsgMap)
|
||||
msg = strings.Replace(msg, ":field", input.RulePattern, -1)
|
||||
return match, gerror.NewOption(gerror.Option{
|
||||
Text: msg,
|
||||
@ -297,7 +305,7 @@ func (v *Validator) doCheckBuildInRules(input doCheckBuildInRulesInput) (match b
|
||||
}
|
||||
if !match {
|
||||
var msg string
|
||||
msg = v.getErrorMessageByRule(input.RuleKey, input.CustomMsgMap)
|
||||
msg = v.getErrorMessageByRule(ctx, input.RuleKey, input.CustomMsgMap)
|
||||
msg = strings.Replace(msg, ":field", input.RulePattern, -1)
|
||||
return match, gerror.NewOption(gerror.Option{
|
||||
Text: msg,
|
||||
|
||||
@ -6,27 +6,29 @@
|
||||
|
||||
package gvalid
|
||||
|
||||
import "context"
|
||||
|
||||
// getErrorMessageByRule retrieves and returns the error message for specified rule.
|
||||
// It firstly retrieves the message from custom message map, and then checks i18n manager,
|
||||
// it returns the default error message if it's not found in custom message map or i18n manager.
|
||||
func (v *Validator) getErrorMessageByRule(ruleKey string, customMsgMap map[string]string) string {
|
||||
func (v *Validator) getErrorMessageByRule(ctx context.Context, ruleKey string, customMsgMap map[string]string) string {
|
||||
content := customMsgMap[ruleKey]
|
||||
if content != "" {
|
||||
// I18n translation.
|
||||
i18nContent := v.i18nManager.GetContent(v.ctx, content)
|
||||
i18nContent := v.i18nManager.GetContent(ctx, content)
|
||||
if i18nContent != "" {
|
||||
return i18nContent
|
||||
}
|
||||
return content
|
||||
}
|
||||
// Retrieve default message according to certain rule.
|
||||
content = v.i18nManager.GetContent(v.ctx, ruleMessagePrefixForI18n+ruleKey)
|
||||
content = v.i18nManager.GetContent(ctx, ruleMessagePrefixForI18n+ruleKey)
|
||||
if content == "" {
|
||||
content = defaultMessages[ruleKey]
|
||||
}
|
||||
// If there's no configured rule message, it uses default one.
|
||||
if content == "" {
|
||||
content = v.i18nManager.GetContent(v.ctx, ruleMessagePrefixForI18n+internalDefaultRuleName)
|
||||
content = v.i18nManager.GetContent(ctx, ruleMessagePrefixForI18n+internalDefaultRuleName)
|
||||
if content == "" {
|
||||
content = defaultMessages[internalDefaultRuleName]
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
package gvalid
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/gogf/gf/util/gconv"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -15,7 +16,7 @@ import (
|
||||
// checkLength checks `value` using length rules.
|
||||
// The length is calculated using unicode string, which means one chinese character or letter
|
||||
// both has the length of 1.
|
||||
func (v *Validator) checkLength(value, ruleKey, ruleVal string, customMsgMap map[string]string) string {
|
||||
func (v *Validator) checkLength(ctx context.Context, value, ruleKey, ruleVal string, customMsgMap map[string]string) string {
|
||||
var (
|
||||
msg = ""
|
||||
runeArray = gconv.Runes(value)
|
||||
@ -39,7 +40,7 @@ func (v *Validator) checkLength(value, ruleKey, ruleVal string, customMsgMap map
|
||||
}
|
||||
}
|
||||
if valueLen < min || valueLen > max {
|
||||
msg = v.getErrorMessageByRule(ruleKey, customMsgMap)
|
||||
msg = v.getErrorMessageByRule(ctx, ruleKey, customMsgMap)
|
||||
msg = strings.Replace(msg, ":min", strconv.Itoa(min), -1)
|
||||
msg = strings.Replace(msg, ":max", strconv.Itoa(max), -1)
|
||||
return msg
|
||||
@ -48,21 +49,21 @@ func (v *Validator) checkLength(value, ruleKey, ruleVal string, customMsgMap map
|
||||
case "min-length":
|
||||
min, err := strconv.Atoi(ruleVal)
|
||||
if valueLen < min || err != nil {
|
||||
msg = v.getErrorMessageByRule(ruleKey, customMsgMap)
|
||||
msg = v.getErrorMessageByRule(ctx, ruleKey, customMsgMap)
|
||||
msg = strings.Replace(msg, ":min", strconv.Itoa(min), -1)
|
||||
}
|
||||
|
||||
case "max-length":
|
||||
max, err := strconv.Atoi(ruleVal)
|
||||
if valueLen > max || err != nil {
|
||||
msg = v.getErrorMessageByRule(ruleKey, customMsgMap)
|
||||
msg = v.getErrorMessageByRule(ctx, ruleKey, customMsgMap)
|
||||
msg = strings.Replace(msg, ":max", strconv.Itoa(max), -1)
|
||||
}
|
||||
|
||||
case "size":
|
||||
size, err := strconv.Atoi(ruleVal)
|
||||
if valueLen != size || err != nil {
|
||||
msg = v.getErrorMessageByRule(ruleKey, customMsgMap)
|
||||
msg = v.getErrorMessageByRule(ctx, ruleKey, customMsgMap)
|
||||
msg = strings.Replace(msg, ":size", strconv.Itoa(size), -1)
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,12 +7,13 @@
|
||||
package gvalid
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// checkRange checks `value` using range rules.
|
||||
func (v *Validator) checkRange(value, ruleKey, ruleVal string, customMsgMap map[string]string) string {
|
||||
func (v *Validator) checkRange(ctx context.Context, value, ruleKey, ruleVal string, customMsgMap map[string]string) string {
|
||||
msg := ""
|
||||
switch ruleKey {
|
||||
// Value range.
|
||||
@ -32,7 +33,7 @@ func (v *Validator) checkRange(value, ruleKey, ruleVal string, customMsgMap map[
|
||||
}
|
||||
valueF, err := strconv.ParseFloat(value, 10)
|
||||
if valueF < min || valueF > max || err != nil {
|
||||
msg = v.getErrorMessageByRule(ruleKey, customMsgMap)
|
||||
msg = v.getErrorMessageByRule(ctx, ruleKey, customMsgMap)
|
||||
msg = strings.Replace(msg, ":min", strconv.FormatFloat(min, 'f', -1, 64), -1)
|
||||
msg = strings.Replace(msg, ":max", strconv.FormatFloat(max, 'f', -1, 64), -1)
|
||||
}
|
||||
@ -44,7 +45,7 @@ func (v *Validator) checkRange(value, ruleKey, ruleVal string, customMsgMap map[
|
||||
valueN, err2 = strconv.ParseFloat(value, 10)
|
||||
)
|
||||
if valueN < min || err1 != nil || err2 != nil {
|
||||
msg = v.getErrorMessageByRule(ruleKey, customMsgMap)
|
||||
msg = v.getErrorMessageByRule(ctx, ruleKey, customMsgMap)
|
||||
msg = strings.Replace(msg, ":min", strconv.FormatFloat(min, 'f', -1, 64), -1)
|
||||
}
|
||||
|
||||
@ -55,7 +56,7 @@ func (v *Validator) checkRange(value, ruleKey, ruleVal string, customMsgMap map[
|
||||
valueN, err2 = strconv.ParseFloat(value, 10)
|
||||
)
|
||||
if valueN > max || err1 != nil || err2 != nil {
|
||||
msg = v.getErrorMessageByRule(ruleKey, customMsgMap)
|
||||
msg = v.getErrorMessageByRule(ctx, ruleKey, customMsgMap)
|
||||
msg = strings.Replace(msg, ":max", strconv.FormatFloat(max, 'f', -1, 64), -1)
|
||||
}
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/gogf/gf/os/gctx"
|
||||
"math"
|
||||
"reflect"
|
||||
|
||||
@ -30,7 +31,7 @@ func ExampleCheckMap() {
|
||||
"password@required|length:6,16|same:password2#密码不能为空|密码长度应当在:min到:max之间|两次密码输入不相等",
|
||||
"password2@required|length:6,16#",
|
||||
}
|
||||
if e := gvalid.CheckMap(context.TODO(), params, rules); e != nil {
|
||||
if e := gvalid.CheckMap(gctx.New(), params, rules); e != nil {
|
||||
fmt.Println(e.Map())
|
||||
fmt.Println(e.FirstItem())
|
||||
fmt.Println(e.FirstString())
|
||||
@ -52,7 +53,7 @@ func ExampleCheckMap2() {
|
||||
"password@required|length:6,16|same:password2#密码不能为空|密码长度应当在:min到:max之间|两次密码输入不相等",
|
||||
"password2@required|length:6,16#",
|
||||
}
|
||||
if e := gvalid.CheckMap(context.TODO(), params, rules); e != nil {
|
||||
if e := gvalid.CheckMap(gctx.New(), params, rules); e != nil {
|
||||
fmt.Println(e.Map())
|
||||
fmt.Println(e.FirstItem())
|
||||
fmt.Println(e.FirstString())
|
||||
@ -74,7 +75,7 @@ func ExampleCheckStruct() {
|
||||
Page: 1,
|
||||
Size: 10,
|
||||
}
|
||||
err := gvalid.CheckStruct(context.TODO(), obj, nil)
|
||||
err := gvalid.CheckStruct(gctx.New(), obj, nil)
|
||||
fmt.Println(err == nil)
|
||||
// Output:
|
||||
// true
|
||||
@ -91,7 +92,7 @@ func ExampleCheckStruct2() {
|
||||
Page: 1,
|
||||
Size: 10,
|
||||
}
|
||||
err := gvalid.CheckStruct(context.TODO(), obj, nil)
|
||||
err := gvalid.CheckStruct(gctx.New(), obj, nil)
|
||||
fmt.Println(err == nil)
|
||||
// Output:
|
||||
// true
|
||||
@ -108,7 +109,7 @@ func ExampleCheckStruct3() {
|
||||
Page: 1,
|
||||
Size: 10,
|
||||
}
|
||||
err := gvalid.CheckStruct(context.TODO(), obj, nil)
|
||||
err := gvalid.CheckStruct(gctx.New(), obj, nil)
|
||||
fmt.Println(err)
|
||||
// Output:
|
||||
// project id must between 1, 10000
|
||||
@ -141,7 +142,7 @@ func ExampleRegisterRule() {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
err := gvalid.CheckStruct(context.TODO(), user, nil)
|
||||
err := gvalid.CheckStruct(gctx.New(), user, nil)
|
||||
fmt.Println(err.Error())
|
||||
// May Output:
|
||||
// 用户名称已被占用
|
||||
@ -175,14 +176,14 @@ func ExampleRegisterRule_OverwriteRequired() {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
fmt.Println(gvalid.CheckValue(context.TODO(), "", "required", "It's required"))
|
||||
fmt.Println(gvalid.CheckValue(context.TODO(), 0, "required", "It's required"))
|
||||
fmt.Println(gvalid.CheckValue(context.TODO(), false, "required", "It's required"))
|
||||
fmt.Println(gvalid.CheckValue(gctx.New(), "", "required", "It's required"))
|
||||
fmt.Println(gvalid.CheckValue(gctx.New(), 0, "required", "It's required"))
|
||||
fmt.Println(gvalid.CheckValue(gctx.New(), false, "required", "It's required"))
|
||||
gvalid.DeleteRule(rule)
|
||||
fmt.Println("rule deleted")
|
||||
fmt.Println(gvalid.CheckValue(context.TODO(), "", "required", "It's required"))
|
||||
fmt.Println(gvalid.CheckValue(context.TODO(), 0, "required", "It's required"))
|
||||
fmt.Println(gvalid.CheckValue(context.TODO(), false, "required", "It's required"))
|
||||
fmt.Println(gvalid.CheckValue(gctx.New(), "", "required", "It's required"))
|
||||
fmt.Println(gvalid.CheckValue(gctx.New(), 0, "required", "It's required"))
|
||||
fmt.Println(gvalid.CheckValue(gctx.New(), false, "required", "It's required"))
|
||||
// Output:
|
||||
// It's required
|
||||
// It's required
|
||||
@ -197,7 +198,10 @@ func ExampleValidator_Rules() {
|
||||
data := g.Map{
|
||||
"password": "123",
|
||||
}
|
||||
err := g.Validator().Data(data).Rules("required-with:password").Messages("请输入确认密码").CheckValue("")
|
||||
err := g.Validator().Data(data).
|
||||
Rules("required-with:password").
|
||||
Messages("请输入确认密码").
|
||||
CheckValue(gctx.New(), "")
|
||||
fmt.Println(err.String())
|
||||
|
||||
// Output:
|
||||
@ -205,7 +209,9 @@ func ExampleValidator_Rules() {
|
||||
}
|
||||
|
||||
func ExampleValidator_CheckValue() {
|
||||
err := g.Validator().Rules("min:18").Messages("未成年人不允许注册哟").CheckValue(16)
|
||||
err := g.Validator().Rules("min:18").
|
||||
Messages("未成年人不允许注册哟").
|
||||
CheckValue(gctx.New(), 16)
|
||||
fmt.Println(err.String())
|
||||
|
||||
// Output:
|
||||
@ -230,7 +236,10 @@ func ExampleValidator_CheckMap() {
|
||||
"same": "两次密码输入不相等",
|
||||
},
|
||||
}
|
||||
err := g.Validator().Messages(messages).Rules(rules).CheckMap(params)
|
||||
err := g.Validator().
|
||||
Messages(messages).
|
||||
Rules(rules).
|
||||
CheckMap(gctx.New(), params)
|
||||
if err != nil {
|
||||
g.Dump(err.Maps())
|
||||
}
|
||||
@ -259,7 +268,7 @@ func ExampleValidator_CheckStruct() {
|
||||
if err := gconv.Scan(data, &user); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err := g.Validator().Data(data).CheckStruct(user)
|
||||
err := g.Validator().Data(data).CheckStruct(gctx.New(), user)
|
||||
if err != nil {
|
||||
fmt.Println(err.Items())
|
||||
}
|
||||
|
||||
@ -10,6 +10,7 @@ import (
|
||||
"context"
|
||||
"github.com/gogf/gf/errors/gcode"
|
||||
"github.com/gogf/gf/errors/gerror"
|
||||
"github.com/gogf/gf/os/gctx"
|
||||
"github.com/gogf/gf/os/gtime"
|
||||
"testing"
|
||||
"time"
|
||||
@ -19,6 +20,10 @@ import (
|
||||
"github.com/gogf/gf/util/gvalid"
|
||||
)
|
||||
|
||||
var (
|
||||
ctx = gctx.New()
|
||||
)
|
||||
|
||||
func Test_Check(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
rule := "abc:6,16"
|
||||
@ -1018,13 +1023,13 @@ func Test_InternalError_String(t *testing.T) {
|
||||
|
||||
func Test_Code(t *testing.T) {
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
err := g.Validator().Rules("required").CheckValue("")
|
||||
err := g.Validator().Rules("required").CheckValue(ctx, "")
|
||||
t.AssertNE(err, nil)
|
||||
t.Assert(gerror.Code(err), gcode.CodeValidationFailed)
|
||||
})
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
err := g.Validator().Rules("none-exist-rule").CheckValue("")
|
||||
err := g.Validator().Rules("none-exist-rule").CheckValue(ctx, "")
|
||||
t.AssertNE(err, nil)
|
||||
t.Assert(gerror.Code(err), gcode.CodeInternalError)
|
||||
})
|
||||
@ -1036,7 +1041,7 @@ func Test_Bail(t *testing.T) {
|
||||
err := g.Validator().
|
||||
Rules("required|min:1|between:1,100").
|
||||
Messages("|min number is 1|size is between 1 and 100").
|
||||
CheckValue(-1)
|
||||
CheckValue(ctx, -1)
|
||||
t.AssertNE(err, nil)
|
||||
t.Assert(err.Error(), "min number is 1; size is between 1 and 100")
|
||||
})
|
||||
@ -1046,7 +1051,7 @@ func Test_Bail(t *testing.T) {
|
||||
err := g.Validator().
|
||||
Rules("bail|required|min:1|between:1,100").
|
||||
Messages("||min number is 1|size is between 1 and 100").
|
||||
CheckValue(-1)
|
||||
CheckValue(ctx, -1)
|
||||
t.AssertNE(err, nil)
|
||||
t.Assert(err.Error(), "min number is 1")
|
||||
})
|
||||
@ -1061,7 +1066,7 @@ func Test_Bail(t *testing.T) {
|
||||
Page: 1,
|
||||
Size: -1,
|
||||
}
|
||||
err := g.Validator().CheckStruct(obj)
|
||||
err := g.Validator().CheckStruct(ctx, obj)
|
||||
t.AssertNE(err, nil)
|
||||
t.Assert(err.Error(), "min number is 1; size is between 1 and 100")
|
||||
})
|
||||
@ -1075,7 +1080,7 @@ func Test_Bail(t *testing.T) {
|
||||
Page: 1,
|
||||
Size: -1,
|
||||
}
|
||||
err := g.Validator().CheckStruct(obj)
|
||||
err := g.Validator().CheckStruct(ctx, obj)
|
||||
t.AssertNE(err, nil)
|
||||
t.Assert(err.Error(), "min number is 1")
|
||||
})
|
||||
|
||||
@ -225,7 +225,7 @@ func Test_Map_Bail(t *testing.T) {
|
||||
"password@required|length:6,16|same:password2#密码不能为空|密码长度应当在:min到:max之间|两次密码输入不相等",
|
||||
"password2@required|length:6,16#",
|
||||
}
|
||||
err := g.Validator().Bail().Rules(rules).CheckMap(params)
|
||||
err := g.Validator().Bail().Rules(rules).CheckMap(ctx, params)
|
||||
t.AssertNE(err, nil)
|
||||
t.Assert(err.String(), "账号不能为空; 账号长度应当在6到16之间")
|
||||
})
|
||||
@ -241,7 +241,7 @@ func Test_Map_Bail(t *testing.T) {
|
||||
"password@required|length:6,16|same:password2#密码不能为空|密码长度应当在:min到:max之间|两次密码输入不相等",
|
||||
"password2@required|length:6,16#",
|
||||
}
|
||||
err := g.Validator().Bail().Rules(rules).CheckMap(params)
|
||||
err := g.Validator().Bail().Rules(rules).CheckMap(ctx, params)
|
||||
t.AssertNE(err, nil)
|
||||
t.Assert(err.String(), "账号不能为空")
|
||||
})
|
||||
|
||||
@ -171,14 +171,17 @@ func TestValidator_RuleFunc(t *testing.T) {
|
||||
return nil
|
||||
}
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
err := g.Validator().Rules(ruleName).Messages("custom message").RuleFunc(ruleName, ruleFunc).CheckValue("123456")
|
||||
err := g.Validator().Rules(ruleName).
|
||||
Messages("custom message").
|
||||
RuleFunc(ruleName, ruleFunc).
|
||||
CheckValue(ctx, "123456")
|
||||
t.Assert(err.String(), "custom message")
|
||||
err = g.Validator().
|
||||
Rules(ruleName).
|
||||
Messages("custom message").
|
||||
Data(g.Map{"data": "123456"}).
|
||||
RuleFunc(ruleName, ruleFunc).
|
||||
CheckValue("123456")
|
||||
CheckValue(ctx, "123456")
|
||||
t.AssertNil(err)
|
||||
})
|
||||
// Error with struct validation.
|
||||
@ -191,7 +194,7 @@ func TestValidator_RuleFunc(t *testing.T) {
|
||||
Value: "123",
|
||||
Data: "123456",
|
||||
}
|
||||
err := g.Validator().RuleFunc(ruleName, ruleFunc).CheckStruct(st)
|
||||
err := g.Validator().RuleFunc(ruleName, ruleFunc).CheckStruct(ctx, st)
|
||||
t.Assert(err.String(), "自定义错误")
|
||||
})
|
||||
// No error with struct validation.
|
||||
@ -204,7 +207,7 @@ func TestValidator_RuleFunc(t *testing.T) {
|
||||
Value: "123456",
|
||||
Data: "123456",
|
||||
}
|
||||
err := g.Validator().RuleFunc(ruleName, ruleFunc).CheckStruct(st)
|
||||
err := g.Validator().RuleFunc(ruleName, ruleFunc).CheckStruct(ctx, st)
|
||||
t.AssertNil(err)
|
||||
})
|
||||
}
|
||||
@ -227,7 +230,7 @@ func TestValidator_RuleFuncMap(t *testing.T) {
|
||||
Messages("custom message").
|
||||
RuleFuncMap(map[string]gvalid.RuleFunc{
|
||||
ruleName: ruleFunc,
|
||||
}).CheckValue("123456")
|
||||
}).CheckValue(ctx, "123456")
|
||||
t.Assert(err.String(), "custom message")
|
||||
err = g.Validator().
|
||||
Rules(ruleName).
|
||||
@ -236,7 +239,7 @@ func TestValidator_RuleFuncMap(t *testing.T) {
|
||||
RuleFuncMap(map[string]gvalid.RuleFunc{
|
||||
ruleName: ruleFunc,
|
||||
}).
|
||||
CheckValue("123456")
|
||||
CheckValue(ctx, "123456")
|
||||
t.AssertNil(err)
|
||||
})
|
||||
// Error with struct validation.
|
||||
@ -252,7 +255,7 @@ func TestValidator_RuleFuncMap(t *testing.T) {
|
||||
err := g.Validator().
|
||||
RuleFuncMap(map[string]gvalid.RuleFunc{
|
||||
ruleName: ruleFunc,
|
||||
}).CheckStruct(st)
|
||||
}).CheckStruct(ctx, st)
|
||||
t.Assert(err.String(), "自定义错误")
|
||||
})
|
||||
// No error with struct validation.
|
||||
@ -268,7 +271,7 @@ func TestValidator_RuleFuncMap(t *testing.T) {
|
||||
err := g.Validator().
|
||||
RuleFuncMap(map[string]gvalid.RuleFunc{
|
||||
ruleName: ruleFunc,
|
||||
}).CheckStruct(st)
|
||||
}).CheckStruct(ctx, st)
|
||||
t.AssertNil(err)
|
||||
})
|
||||
}
|
||||
|
||||
@ -24,14 +24,14 @@ func TestValidator_I18n(t *testing.T) {
|
||||
validator = gvalid.New().I18n(i18nManager)
|
||||
)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
err = validator.Rules("required").CheckValue("")
|
||||
err = validator.Rules("required").CheckValue(ctx, "")
|
||||
t.Assert(err.String(), "The field is required")
|
||||
|
||||
err = validator.Ctx(ctxCn).Rules("required").CheckValue("")
|
||||
err = validator.Rules("required").CheckValue(ctxCn, "")
|
||||
t.Assert(err.String(), "字段不能为空")
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
err = validator.Ctx(ctxCn).Rules("required").Messages("CustomMessage").CheckValue("")
|
||||
err = validator.Rules("required").Messages("CustomMessage").CheckValue(ctxCn, "")
|
||||
t.Assert(err.String(), "自定义错误")
|
||||
})
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
@ -44,7 +44,7 @@ func TestValidator_I18n(t *testing.T) {
|
||||
Page: 1,
|
||||
Size: 10,
|
||||
}
|
||||
err := validator.Ctx(ctxCn).CheckStruct(obj)
|
||||
err = validator.CheckStruct(ctxCn, obj)
|
||||
t.Assert(err.String(), "项目ID必须大于等于1并且要小于等于10000")
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user