Completed 100% test coverage for alis registration

pull/169/head
joeybloggs 9 years ago
parent 407aac458f
commit a964f5384a
  1. 4
      baked_in.go
  2. 27
      util.go
  3. 10
      validator.go
  4. 10
      validator_test.go

@ -14,7 +14,9 @@ import (
// defines a common or complex set of validation(s) to simplify // defines a common or complex set of validation(s) to simplify
// adding validation to structs. i.e. set key "_ageok" and the tags // adding validation to structs. i.e. set key "_ageok" and the tags
// are "gt=0,lte=130" or key "_preferredname" and tags "omitempty,gt=0,lte=60" // are "gt=0,lte=130" or key "_preferredname" and tags "omitempty,gt=0,lte=60"
var BakedInAliasValidators = map[string]string{} var BakedInAliasValidators = map[string]string{
"iscolor": "hexcolor|rgb|rgba|hsl|hsla",
}
// BakedInValidators is the default map of ValidationFunc // BakedInValidators is the default map of ValidationFunc
// you can add, remove or even replace items to suite your needs, // you can add, remove or even replace items to suite your needs,

@ -13,8 +13,8 @@ const (
leftBracket = "[" leftBracket = "["
rightBracket = "]" rightBracket = "]"
restrictedTagChars = ".[],|=+()`~!@#$%^&*\\\"/?<>{}" restrictedTagChars = ".[],|=+()`~!@#$%^&*\\\"/?<>{}"
restrictedAliasErr = "Alias \"%s\" either contains restricted characters or is the same as a restricted tag needed for normal operation\n" restrictedAliasErr = "Alias \"%s\" either contains restricted characters or is the same as a restricted tag needed for normal operation"
restrictedTagErr = "Tag \"%s\" either contains restricted characters or is the same as a restricted tag needed for normal operation\n" restrictedTagErr = "Tag \"%s\" either contains restricted characters or is the same as a restricted tag needed for normal operation"
) )
var ( var (
@ -234,15 +234,16 @@ func panicIf(err error) {
func (v *Validate) parseTags(tag, fieldName string) []*tagCache { func (v *Validate) parseTags(tag, fieldName string) []*tagCache {
return v.parseTagsRecursive(tag, fieldName, blank, false) tags, _ := v.parseTagsRecursive(tag, fieldName, blank, false)
return tags
} }
func (v *Validate) parseTagsRecursive(tag, fieldName, alias string, isAlias bool) []*tagCache { func (v *Validate) parseTagsRecursive(tag, fieldName, alias string, isAlias bool) ([]*tagCache, bool) {
tags := []*tagCache{} tags := []*tagCache{}
if len(tag) == 0 { if len(tag) == 0 {
return tags return tags, true
} }
for _, t := range strings.Split(tag, tagSeparator) { for _, t := range strings.Split(tag, tagSeparator) {
@ -250,14 +251,22 @@ func (v *Validate) parseTagsRecursive(tag, fieldName, alias string, isAlias bool
if v.config.hasAliasValidators { if v.config.hasAliasValidators {
// check map for alias and process new tags, otherwise process as usual // check map for alias and process new tags, otherwise process as usual
if tagsVal, ok := v.config.aliasValidators[t]; ok { if tagsVal, ok := v.config.aliasValidators[t]; ok {
tags = append(tags, v.parseTagsRecursive(tagsVal, fieldName, t, true)...)
aliasTags, leave := v.parseTagsRecursive(tagsVal, fieldName, t, true)
tags = append(tags, aliasTags...)
if leave {
return tags, leave
}
continue continue
} }
} }
if t == diveTag { if t == diveTag {
tags = append(tags, &tagCache{tagVals: [][]string{{t}}}) tVals := &tagCache{diveTag: tag, tagVals: [][]string{{t}}}
break tags = append(tags, tVals)
return tags, true
} }
// if a pipe character is needed within the param you must use the utf8Pipe representation "0x7C" // if a pipe character is needed within the param you must use the utf8Pipe representation "0x7C"
@ -291,5 +300,5 @@ func (v *Validate) parseTagsRecursive(tag, fieldName, alias string, isAlias bool
} }
} }
return tags return tags, false
} }

@ -55,6 +55,7 @@ type tagCache struct {
isOrVal bool isOrVal bool
isAlias bool isAlias bool
tag string tag string
diveTag string
// actualTag string // actualTag string
} }
@ -191,8 +192,12 @@ func (v *Validate) RegisterCustomTypeFunc(fn CustomTypeFunc, types ...interface{
// to structs. // to structs.
func (v *Validate) RegisterAliasValidation(alias, tags string) { func (v *Validate) RegisterAliasValidation(alias, tags string) {
if v.config.aliasValidators == nil { if len(v.config.aliasValidators) == 0 {
// must copy validators for separate validations to be used in each
v.config.aliasValidators = map[string]string{} v.config.aliasValidators = map[string]string{}
for k, val := range BakedInAliasValidators {
v.config.aliasValidators[k] = val
}
} }
_, ok := restrictedTags[alias] _, ok := restrictedTags[alias]
@ -471,7 +476,8 @@ func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect.
if cTag.tagVals[0][0] == diveTag { if cTag.tagVals[0][0] == diveTag {
dive = true dive = true
diveSubTag = strings.TrimLeft(strings.SplitN(tag, diveTag, 2)[1], ",") // fmt.Println(cTag.diveTag)
diveSubTag = strings.TrimLeft(strings.SplitN(cTag.diveTag, diveTag, 2)[1], ",")
break break
} }

@ -243,6 +243,14 @@ func TestAliasTags(t *testing.T) {
NotEqual(t, errs, nil) NotEqual(t, errs, nil)
AssertError(t, errs, "Test.Color", "Color", "iscolor") AssertError(t, errs, "Test.Color", "Color", "iscolor")
Equal(t, errs["Test.Color"].ActualTag, "hexcolor|rgb|rgba|hsl|hsla") Equal(t, errs["Test.Color"].ActualTag, "hexcolor|rgb|rgba|hsl|hsla")
validate.RegisterAliasValidation("req", "required,dive,iscolor")
arr := []string{"val1", "#fff", "#000"}
errs = validate.Field(arr, "req")
NotEqual(t, errs, nil)
AssertError(t, errs, "[0]", "[0]", "iscolor")
PanicMatches(t, func() { validate.RegisterAliasValidation("exists", "gt=5,lt=10") }, "Alias \"exists\" either contains restricted characters or is the same as a restricted tag needed for normal operation")
} }
func TestStructPartial(t *testing.T) { func TestStructPartial(t *testing.T) {
@ -3881,6 +3889,8 @@ func TestAddFunctions(t *testing.T) {
errs = validate.RegisterValidation("new", fn) errs = validate.RegisterValidation("new", fn)
Equal(t, errs, nil) Equal(t, errs, nil)
PanicMatches(t, func() { validate.RegisterValidation("dive", fn) }, "Tag \"dive\" either contains restricted characters or is the same as a restricted tag needed for normal operation")
} }
func TestChangeTag(t *testing.T) { func TestChangeTag(t *testing.T) {

Loading…
Cancel
Save