unexpose baked in validators map for safety.

pull/169/head
joeybloggs 9 years ago
parent c293315337
commit 4807bf93bb
  1. 37
      benchmarks_test.go
  2. 2
      util.go
  3. 50
      validator.go
  4. 20
      validator_test.go

@ -2,7 +2,6 @@ package validator
import ( import (
sql "database/sql/driver" sql "database/sql/driver"
"reflect"
"testing" "testing"
"time" "time"
) )
@ -33,11 +32,12 @@ func BenchmarkFieldDiveFailure(b *testing.B) {
func BenchmarkFieldCustomTypeSuccess(b *testing.B) { func BenchmarkFieldCustomTypeSuccess(b *testing.B) {
customTypes := map[reflect.Type]CustomTypeFunc{} // customTypes := map[reflect.Type]CustomTypeFunc{}
customTypes[reflect.TypeOf((*sql.Valuer)(nil))] = ValidateValuerType // customTypes[reflect.TypeOf((*sql.Valuer)(nil))] = ValidateValuerType
customTypes[reflect.TypeOf(valuer{})] = ValidateValuerType // customTypes[reflect.TypeOf(valuer{})] = ValidateValuerType
validate := New(Config{TagName: "validate", ValidationFuncs: BakedInValidators, CustomTypeFuncs: customTypes}) validate := New(Config{TagName: "validate"})
validate.RegisterCustomTypeFunc(ValidateValuerType, (*sql.Valuer)(nil), valuer{})
val := valuer{ val := valuer{
Name: "1", Name: "1",
@ -50,11 +50,12 @@ func BenchmarkFieldCustomTypeSuccess(b *testing.B) {
func BenchmarkFieldCustomTypeFailure(b *testing.B) { func BenchmarkFieldCustomTypeFailure(b *testing.B) {
customTypes := map[reflect.Type]CustomTypeFunc{} // customTypes := map[reflect.Type]CustomTypeFunc{}
customTypes[reflect.TypeOf((*sql.Valuer)(nil))] = ValidateValuerType // customTypes[reflect.TypeOf((*sql.Valuer)(nil))] = ValidateValuerType
customTypes[reflect.TypeOf(valuer{})] = ValidateValuerType // customTypes[reflect.TypeOf(valuer{})] = ValidateValuerType
validate := New(Config{TagName: "validate", ValidationFuncs: BakedInValidators, CustomTypeFuncs: customTypes}) validate := New(Config{TagName: "validate"})
validate.RegisterCustomTypeFunc(ValidateValuerType, (*sql.Valuer)(nil), valuer{})
val := valuer{} val := valuer{}
@ -77,11 +78,12 @@ func BenchmarkFieldOrTagFailure(b *testing.B) {
func BenchmarkStructSimpleCustomTypeSuccess(b *testing.B) { func BenchmarkStructSimpleCustomTypeSuccess(b *testing.B) {
customTypes := map[reflect.Type]CustomTypeFunc{} // customTypes := map[reflect.Type]CustomTypeFunc{}
customTypes[reflect.TypeOf((*sql.Valuer)(nil))] = ValidateValuerType // customTypes[reflect.TypeOf((*sql.Valuer)(nil))] = ValidateValuerType
customTypes[reflect.TypeOf(valuer{})] = ValidateValuerType // customTypes[reflect.TypeOf(valuer{})] = ValidateValuerType
validate := New(Config{TagName: "validate", ValidationFuncs: BakedInValidators, CustomTypeFuncs: customTypes}) validate := New(Config{TagName: "validate"})
validate.RegisterCustomTypeFunc(ValidateValuerType, (*sql.Valuer)(nil), valuer{})
val := valuer{ val := valuer{
Name: "1", Name: "1",
@ -101,11 +103,12 @@ func BenchmarkStructSimpleCustomTypeSuccess(b *testing.B) {
func BenchmarkStructSimpleCustomTypeFailure(b *testing.B) { func BenchmarkStructSimpleCustomTypeFailure(b *testing.B) {
customTypes := map[reflect.Type]CustomTypeFunc{} // customTypes := map[reflect.Type]CustomTypeFunc{}
customTypes[reflect.TypeOf((*sql.Valuer)(nil))] = ValidateValuerType // customTypes[reflect.TypeOf((*sql.Valuer)(nil))] = ValidateValuerType
customTypes[reflect.TypeOf(valuer{})] = ValidateValuerType // customTypes[reflect.TypeOf(valuer{})] = ValidateValuerType
validate := New(Config{TagName: "validate", ValidationFuncs: BakedInValidators, CustomTypeFuncs: customTypes}) validate := New(Config{TagName: "validate"})
validate.RegisterCustomTypeFunc(ValidateValuerType, (*sql.Valuer)(nil), valuer{})
val := valuer{} val := valuer{}

@ -54,7 +54,7 @@ func (v *Validate) extractType(current reflect.Value) (reflect.Value, reflect.Ki
default: default:
if v.config.hasCustomFuncs { if v.config.hasCustomFuncs {
if fn, ok := v.config.CustomTypeFuncs[current.Type()]; ok { if fn, ok := v.config.customTypeFuncs[current.Type()]; ok {
return v.extractType(reflect.ValueOf(fn(current))) return v.extractType(reflect.ValueOf(fn(current)))
} }
} }

@ -90,8 +90,8 @@ type Validate struct {
// It is passed to the New() function // It is passed to the New() function
type Config struct { type Config struct {
TagName string TagName string
ValidationFuncs map[string]Func validationFuncs map[string]Func
CustomTypeFuncs map[reflect.Type]CustomTypeFunc customTypeFuncs map[reflect.Type]CustomTypeFunc
aliasValidators map[string]string aliasValidators map[string]string
hasCustomFuncs bool hasCustomFuncs bool
hasAliasValidators bool hasAliasValidators bool
@ -146,8 +146,24 @@ type FieldError struct {
// New creates a new Validate instance for use. // New creates a new Validate instance for use.
func New(config Config) *Validate { func New(config Config) *Validate {
if config.CustomTypeFuncs != nil && len(config.CustomTypeFuncs) > 0 { // if config.CustomTypeFuncs != nil && len(config.CustomTypeFuncs) > 0 {
config.hasCustomFuncs = true // config.hasCustomFuncs = true
// }
if len(config.aliasValidators) == 0 {
// must copy validators for separate validations to be used in each
config.aliasValidators = map[string]string{}
for k, val := range BakedInAliasValidators {
config.aliasValidators[k] = val
}
}
if len(config.validationFuncs) == 0 {
// must copy validators for separate validations to be used in each
config.validationFuncs = map[string]Func{}
for k, val := range BakedInValidators {
config.validationFuncs[k] = val
}
} }
return &Validate{config: config} return &Validate{config: config}
@ -172,7 +188,7 @@ func (v *Validate) RegisterValidation(key string, f Func) error {
panic(fmt.Sprintf(restrictedTagErr, key)) panic(fmt.Sprintf(restrictedTagErr, key))
} }
v.config.ValidationFuncs[key] = f v.config.validationFuncs[key] = f
return nil return nil
} }
@ -180,12 +196,12 @@ func (v *Validate) RegisterValidation(key string, f Func) error {
// RegisterCustomTypeFunc registers a CustomTypeFunc against a number of types // RegisterCustomTypeFunc registers a CustomTypeFunc against a number of types
func (v *Validate) RegisterCustomTypeFunc(fn CustomTypeFunc, types ...interface{}) { func (v *Validate) RegisterCustomTypeFunc(fn CustomTypeFunc, types ...interface{}) {
if v.config.CustomTypeFuncs == nil { if v.config.customTypeFuncs == nil {
v.config.CustomTypeFuncs = map[reflect.Type]CustomTypeFunc{} v.config.customTypeFuncs = map[reflect.Type]CustomTypeFunc{}
} }
for _, t := range types { for _, t := range types {
v.config.CustomTypeFuncs[reflect.TypeOf(t)] = fn v.config.customTypeFuncs[reflect.TypeOf(t)] = fn
} }
v.config.hasCustomFuncs = true v.config.hasCustomFuncs = true
@ -199,13 +215,13 @@ func (v *Validate) RegisterCustomTypeFunc(fn CustomTypeFunc, types ...interface{
// will be the actual tag within the alias that failed. // will be the actual tag within the alias that failed.
func (v *Validate) RegisterAliasValidation(alias, tags string) { func (v *Validate) RegisterAliasValidation(alias, tags string) {
if len(v.config.aliasValidators) == 0 { // if len(v.config.aliasValidators) == 0 {
// must copy validators for separate validations to be used in each // // 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 { // for k, val := range BakedInAliasValidators {
v.config.aliasValidators[k] = val // v.config.aliasValidators[k] = val
} // }
} // }
_, ok := restrictedTags[alias] _, ok := restrictedTags[alias]
@ -544,7 +560,7 @@ func (v *Validate) validateField(topStruct reflect.Value, currentStruct reflect.
for _, val := range valTag.tagVals { for _, val := range valTag.tagVals {
valFunc, ok = v.config.ValidationFuncs[val[0]] valFunc, ok = v.config.validationFuncs[val[0]]
if !ok { if !ok {
panic(strings.TrimSpace(fmt.Sprintf(undefinedValidation, name))) panic(strings.TrimSpace(fmt.Sprintf(undefinedValidation, name)))
} }
@ -579,7 +595,7 @@ func (v *Validate) validateField(topStruct reflect.Value, currentStruct reflect.
return true return true
} }
valFunc, ok = v.config.ValidationFuncs[valTag.tagVals[0][0]] valFunc, ok = v.config.validationFuncs[valTag.tagVals[0][0]]
if !ok { if !ok {
panic(strings.TrimSpace(fmt.Sprintf(undefinedValidation, name))) panic(strings.TrimSpace(fmt.Sprintf(undefinedValidation, name)))
} }

@ -111,7 +111,7 @@ type TestSlice struct {
OmitEmpty []int `validate:"omitempty,min=1,max=10"` OmitEmpty []int `validate:"omitempty,min=1,max=10"`
} }
var validate = New(Config{TagName: "validate", ValidationFuncs: BakedInValidators}) var validate = New(Config{TagName: "validate"})
func AssertError(t *testing.T, errs ValidationErrors, key, field, expectedTag string) { func AssertError(t *testing.T, errs ValidationErrors, key, field, expectedTag string) {
@ -1255,7 +1255,6 @@ func TestSQLValue2Validation(t *testing.T) {
config := Config{ config := Config{
TagName: "validate", TagName: "validate",
ValidationFuncs: BakedInValidators,
} }
validate := New(config) validate := New(config)
@ -1311,13 +1310,16 @@ func TestSQLValue2Validation(t *testing.T) {
func TestSQLValueValidation(t *testing.T) { func TestSQLValueValidation(t *testing.T) {
customTypes := map[reflect.Type]CustomTypeFunc{} // customTypes := map[reflect.Type]CustomTypeFunc{}
customTypes[reflect.TypeOf((*driver.Valuer)(nil))] = ValidateValuerType // customTypes[reflect.TypeOf((*driver.Valuer)(nil))] = ValidateValuerType
customTypes[reflect.TypeOf(valuer{})] = ValidateValuerType // customTypes[reflect.TypeOf(valuer{})] = ValidateValuerType
customTypes[reflect.TypeOf(MadeUpCustomType{})] = ValidateCustomType // customTypes[reflect.TypeOf(MadeUpCustomType{})] = ValidateCustomType
customTypes[reflect.TypeOf(1)] = OverrideIntTypeForSomeReason // customTypes[reflect.TypeOf(1)] = OverrideIntTypeForSomeReason
validate := New(Config{TagName: "validate", ValidationFuncs: BakedInValidators, CustomTypeFuncs: customTypes}) validate := New(Config{TagName: "validate"})
validate.RegisterCustomTypeFunc(ValidateValuerType, (*driver.Valuer)(nil), valuer{})
validate.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{})
validate.RegisterCustomTypeFunc(OverrideIntTypeForSomeReason, 1)
val := valuer{ val := valuer{
Name: "", Name: "",
@ -3873,7 +3875,6 @@ func TestAddFunctions(t *testing.T) {
config := Config{ config := Config{
TagName: "validateme", TagName: "validateme",
ValidationFuncs: BakedInValidators,
} }
validate := New(config) validate := New(config)
@ -3897,7 +3898,6 @@ func TestChangeTag(t *testing.T) {
config := Config{ config := Config{
TagName: "val", TagName: "val",
ValidationFuncs: BakedInValidators,
} }
validate := New(config) validate := New(config)

Loading…
Cancel
Save