Postcode validator for value and field (#759)

* Postcode validator for value and field

* Add translation for postcode rules

Co-authored-by: Dean Karn <Dean.Karn@gmail.com>
pull/767/head
ѵµσɳɠ 4 years ago committed by GitHub
parent c2066206fe
commit a53d64fc35
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 45
      baked_in.go
  2. 173
      postcode_regexes.go
  3. 80
      translations/en/en.go
  4. 13
      translations/en/en_test.go
  5. 223
      validator_test.go

@ -190,6 +190,8 @@ var (
"iso3166_1_alpha3": isIso3166Alpha3, "iso3166_1_alpha3": isIso3166Alpha3,
"iso3166_1_alpha_numeric": isIso3166AlphaNumeric, "iso3166_1_alpha_numeric": isIso3166AlphaNumeric,
"bcp47_language_tag": isBCP47LanguageTag, "bcp47_language_tag": isBCP47LanguageTag,
"postcode_iso3166_alpha2": isPostcodeByIso3166Alpha2,
"postcode_iso3166_alpha2_field": isPostcodeByIso3166Alpha2Field,
"bic": isIsoBicFormat, "bic": isIsoBicFormat,
} }
) )
@ -1205,6 +1207,49 @@ func isEq(fl FieldLevel) bool {
panic(fmt.Sprintf("Bad field type %T", field.Interface())) panic(fmt.Sprintf("Bad field type %T", field.Interface()))
} }
// isPostcodeByIso3166Alpha2 validates by value which is country code in iso 3166 alpha 2
// example: `postcode_iso3166_alpha2=US`
func isPostcodeByIso3166Alpha2(fl FieldLevel) bool {
field := fl.Field()
param := fl.Param()
reg, found := postCodeRegexDict[param]
if !found {
return false
}
return reg.MatchString(field.String())
}
// isPostcodeByIso3166Alpha2 validates by field which represents for a value of country code in iso 3166 alpha 2
// example: `postcode_iso3166_alpha2_field=CountryCode`
func isPostcodeByIso3166Alpha2Field(fl FieldLevel) bool {
field := fl.Field()
kind := field.Kind()
params := parseOneOfParam2(fl.Param())
if len(params) != 1 {
return false
}
currentField, kind, _, found := fl.GetStructFieldOKAdvanced2(fl.Parent(), params[0])
if !found {
return false
}
if kind != reflect.String {
panic(fmt.Sprintf("Bad field type %T", currentField.Interface()))
}
reg, found := postCodeRegexDict[currentField.String()]
if !found {
return false
}
return reg.MatchString(field.String())
}
// IsBase64 is the validation function for validating if the current field's value is a valid base 64. // IsBase64 is the validation function for validating if the current field's value is a valid base 64.
func isBase64(fl FieldLevel) bool { func isBase64(fl FieldLevel) bool {
return base64Regex.MatchString(fl.Field().String()) return base64Regex.MatchString(fl.Field().String())

@ -0,0 +1,173 @@
package validator
import "regexp"
var postCodePatternDict = map[string]string{
"GB": `^GIR[ ]?0AA|((AB|AL|B|BA|BB|BD|BH|BL|BN|BR|BS|BT|CA|CB|CF|CH|CM|CO|CR|CT|CV|CW|DA|DD|DE|DG|DH|DL|DN|DT|DY|E|EC|EH|EN|EX|FK|FY|G|GL|GY|GU|HA|HD|HG|HP|HR|HS|HU|HX|IG|IM|IP|IV|JE|KA|KT|KW|KY|L|LA|LD|LE|LL|LN|LS|LU|M|ME|MK|ML|N|NE|NG|NN|NP|NR|NW|OL|OX|PA|PE|PH|PL|PO|PR|RG|RH|RM|S|SA|SE|SG|SK|SL|SM|SN|SO|SP|SR|SS|ST|SW|SY|TA|TD|TF|TN|TQ|TR|TS|TW|UB|W|WA|WC|WD|WF|WN|WR|WS|WV|YO|ZE)(\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}))|BFPO[ ]?\d{1,4}$`,
"JE": `^JE\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}$`,
"GG": `^GY\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}$`,
"IM": `^IM\d[\dA-Z]?[ ]?\d[ABD-HJLN-UW-Z]{2}$`,
"US": `^\d{5}([ \-]\d{4})?$`,
"CA": `^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJ-NPRSTV-Z][ ]?\d[ABCEGHJ-NPRSTV-Z]\d$`,
"DE": `^\d{5}$`,
"JP": `^\d{3}-\d{4}$`,
"FR": `^\d{2}[ ]?\d{3}$`,
"AU": `^\d{4}$`,
"IT": `^\d{5}$`,
"CH": `^\d{4}$`,
"AT": `^\d{4}$`,
"ES": `^\d{5}$`,
"NL": `^\d{4}[ ]?[A-Z]{2}$`,
"BE": `^\d{4}$`,
"DK": `^\d{4}$`,
"SE": `^\d{3}[ ]?\d{2}$`,
"NO": `^\d{4}$`,
"BR": `^\d{5}[\-]?\d{3}$`,
"PT": `^\d{4}([\-]\d{3})?$`,
"FI": `^\d{5}$`,
"AX": `^22\d{3}$`,
"KR": `^\d{3}[\-]\d{3}$`,
"CN": `^\d{6}$`,
"TW": `^\d{3}(\d{2})?$`,
"SG": `^\d{6}$`,
"DZ": `^\d{5}$`,
"AD": `^AD\d{3}$`,
"AR": `^([A-HJ-NP-Z])?\d{4}([A-Z]{3})?$`,
"AM": `^(37)?\d{4}$`,
"AZ": `^\d{4}$`,
"BH": `^((1[0-2]|[2-9])\d{2})?$`,
"BD": `^\d{4}$`,
"BB": `^(BB\d{5})?$`,
"BY": `^\d{6}$`,
"BM": `^[A-Z]{2}[ ]?[A-Z0-9]{2}$`,
"BA": `^\d{5}$`,
"IO": `^BBND 1ZZ$`,
"BN": `^[A-Z]{2}[ ]?\d{4}$`,
"BG": `^\d{4}$`,
"KH": `^\d{5}$`,
"CV": `^\d{4}$`,
"CL": `^\d{7}$`,
"CR": `^\d{4,5}|\d{3}-\d{4}$`,
"HR": `^\d{5}$`,
"CY": `^\d{4}$`,
"CZ": `^\d{3}[ ]?\d{2}$`,
"DO": `^\d{5}$`,
"EC": `^([A-Z]\d{4}[A-Z]|(?:[A-Z]{2})?\d{6})?$`,
"EG": `^\d{5}$`,
"EE": `^\d{5}$`,
"FO": `^\d{3}$`,
"GE": `^\d{4}$`,
"GR": `^\d{3}[ ]?\d{2}$`,
"GL": `^39\d{2}$`,
"GT": `^\d{5}$`,
"HT": `^\d{4}$`,
"HN": `^(?:\d{5})?$`,
"HU": `^\d{4}$`,
"IS": `^\d{3}$`,
"IN": `^\d{6}$`,
"ID": `^\d{5}$`,
"IL": `^\d{5}$`,
"JO": `^\d{5}$`,
"KZ": `^\d{6}$`,
"KE": `^\d{5}$`,
"KW": `^\d{5}$`,
"LA": `^\d{5}$`,
"LV": `^\d{4}$`,
"LB": `^(\d{4}([ ]?\d{4})?)?$`,
"LI": `^(948[5-9])|(949[0-7])$`,
"LT": `^\d{5}$`,
"LU": `^\d{4}$`,
"MK": `^\d{4}$`,
"MY": `^\d{5}$`,
"MV": `^\d{5}$`,
"MT": `^[A-Z]{3}[ ]?\d{2,4}$`,
"MU": `^(\d{3}[A-Z]{2}\d{3})?$`,
"MX": `^\d{5}$`,
"MD": `^\d{4}$`,
"MC": `^980\d{2}$`,
"MA": `^\d{5}$`,
"NP": `^\d{5}$`,
"NZ": `^\d{4}$`,
"NI": `^((\d{4}-)?\d{3}-\d{3}(-\d{1})?)?$`,
"NG": `^(\d{6})?$`,
"OM": `^(PC )?\d{3}$`,
"PK": `^\d{5}$`,
"PY": `^\d{4}$`,
"PH": `^\d{4}$`,
"PL": `^\d{2}-\d{3}$`,
"PR": `^00[679]\d{2}([ \-]\d{4})?$`,
"RO": `^\d{6}$`,
"RU": `^\d{6}$`,
"SM": `^4789\d$`,
"SA": `^\d{5}$`,
"SN": `^\d{5}$`,
"SK": `^\d{3}[ ]?\d{2}$`,
"SI": `^\d{4}$`,
"ZA": `^\d{4}$`,
"LK": `^\d{5}$`,
"TJ": `^\d{6}$`,
"TH": `^\d{5}$`,
"TN": `^\d{4}$`,
"TR": `^\d{5}$`,
"TM": `^\d{6}$`,
"UA": `^\d{5}$`,
"UY": `^\d{5}$`,
"UZ": `^\d{6}$`,
"VA": `^00120$`,
"VE": `^\d{4}$`,
"ZM": `^\d{5}$`,
"AS": `^96799$`,
"CC": `^6799$`,
"CK": `^\d{4}$`,
"RS": `^\d{6}$`,
"ME": `^8\d{4}$`,
"CS": `^\d{5}$`,
"YU": `^\d{5}$`,
"CX": `^6798$`,
"ET": `^\d{4}$`,
"FK": `^FIQQ 1ZZ$`,
"NF": `^2899$`,
"FM": `^(9694[1-4])([ \-]\d{4})?$`,
"GF": `^9[78]3\d{2}$`,
"GN": `^\d{3}$`,
"GP": `^9[78][01]\d{2}$`,
"GS": `^SIQQ 1ZZ$`,
"GU": `^969[123]\d([ \-]\d{4})?$`,
"GW": `^\d{4}$`,
"HM": `^\d{4}$`,
"IQ": `^\d{5}$`,
"KG": `^\d{6}$`,
"LR": `^\d{4}$`,
"LS": `^\d{3}$`,
"MG": `^\d{3}$`,
"MH": `^969[67]\d([ \-]\d{4})?$`,
"MN": `^\d{6}$`,
"MP": `^9695[012]([ \-]\d{4})?$`,
"MQ": `^9[78]2\d{2}$`,
"NC": `^988\d{2}$`,
"NE": `^\d{4}$`,
"VI": `^008(([0-4]\d)|(5[01]))([ \-]\d{4})?$`,
"VN": `^[0-9]{1,6}$`,
"PF": `^987\d{2}$`,
"PG": `^\d{3}$`,
"PM": `^9[78]5\d{2}$`,
"PN": `^PCRN 1ZZ$`,
"PW": `^96940$`,
"RE": `^9[78]4\d{2}$`,
"SH": `^(ASCN|STHL) 1ZZ$`,
"SJ": `^\d{4}$`,
"SO": `^\d{5}$`,
"SZ": `^[HLMS]\d{3}$`,
"TC": `^TKCA 1ZZ$`,
"WF": `^986\d{2}$`,
"XK": `^\d{5}$`,
"YT": `^976\d{2}$`,
}
var postCodeRegexDict = map[string]*regexp.Regexp{}
func init() {
for countryCode, pattern := range postCodePatternDict {
postCodeRegexDict[countryCode] = regexp.MustCompile(pattern)
}
}

@ -16,7 +16,6 @@ import (
// RegisterDefaultTranslations registers a set of default translations // RegisterDefaultTranslations registers a set of default translations
// for all built in tag's in validator; you may add your own as desired. // for all built in tag's in validator; you may add your own as desired.
func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (err error) { func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (err error) {
translations := []struct { translations := []struct {
tag string tag string
translation string translation string
@ -32,7 +31,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{ {
tag: "len", tag: "len",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("len-string", "{0} must be {1} in length", false); err != nil { if err = ut.Add("len-string", "{0} must be {1} in length", false); err != nil {
return return
} }
@ -61,10 +59,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
} }
return return
}, },
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
var err error var err error
var t string var t string
@ -123,7 +119,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{ {
tag: "min", tag: "min",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("min-string", "{0} must be at least {1} in length", false); err != nil { if err = ut.Add("min-string", "{0} must be at least {1} in length", false); err != nil {
return return
} }
@ -152,10 +147,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
} }
return return
}, },
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
var err error var err error
var t string var t string
@ -214,7 +207,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{ {
tag: "max", tag: "max",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("max-string", "{0} must be a maximum of {1} in length", false); err != nil { if err = ut.Add("max-string", "{0} must be a maximum of {1} in length", false); err != nil {
return return
} }
@ -243,10 +235,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
} }
return return
}, },
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
var err error var err error
var t string var t string
@ -307,7 +297,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} is not equal to {1}", translation: "{0} is not equal to {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
fmt.Printf("warning: error translating FieldError: %#v", fe) fmt.Printf("warning: error translating FieldError: %#v", fe)
@ -322,7 +311,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} should not be equal to {1}", translation: "{0} should not be equal to {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
fmt.Printf("warning: error translating FieldError: %#v", fe) fmt.Printf("warning: error translating FieldError: %#v", fe)
@ -335,7 +323,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{ {
tag: "lt", tag: "lt",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("lt-string", "{0} must be less than {1} in length", false); err != nil { if err = ut.Add("lt-string", "{0} must be less than {1} in length", false); err != nil {
return return
} }
@ -369,10 +356,8 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
} }
return return
}, },
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
var err error var err error
var t string var t string
var f64 float64 var f64 float64
@ -380,7 +365,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var kind reflect.Kind var kind reflect.Kind
fn := func() (err error) { fn := func() (err error) {
if idx := strings.Index(fe.Param(), "."); idx != -1 { if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:])) digits = uint64(len(fe.Param()[idx+1:]))
} }
@ -456,7 +440,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{ {
tag: "lte", tag: "lte",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("lte-string", "{0} must be at maximum {1} in length", false); err != nil { if err = ut.Add("lte-string", "{0} must be at maximum {1} in length", false); err != nil {
return return
} }
@ -492,7 +475,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
}, },
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
var err error var err error
var t string var t string
var f64 float64 var f64 float64
@ -500,7 +482,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var kind reflect.Kind var kind reflect.Kind
fn := func() (err error) { fn := func() (err error) {
if idx := strings.Index(fe.Param(), "."); idx != -1 { if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:])) digits = uint64(len(fe.Param()[idx+1:]))
} }
@ -576,7 +557,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{ {
tag: "gt", tag: "gt",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("gt-string", "{0} must be greater than {1} in length", false); err != nil { if err = ut.Add("gt-string", "{0} must be greater than {1} in length", false); err != nil {
return return
} }
@ -612,7 +592,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
}, },
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
var err error var err error
var t string var t string
var f64 float64 var f64 float64
@ -620,7 +599,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var kind reflect.Kind var kind reflect.Kind
fn := func() (err error) { fn := func() (err error) {
if idx := strings.Index(fe.Param(), "."); idx != -1 { if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:])) digits = uint64(len(fe.Param()[idx+1:]))
} }
@ -696,7 +674,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
{ {
tag: "gte", tag: "gte",
customRegisFunc: func(ut ut.Translator) (err error) { customRegisFunc: func(ut ut.Translator) (err error) {
if err = ut.Add("gte-string", "{0} must be at least {1} in length", false); err != nil { if err = ut.Add("gte-string", "{0} must be at least {1} in length", false); err != nil {
return return
} }
@ -732,7 +709,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
return return
}, },
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
var err error var err error
var t string var t string
var f64 float64 var f64 float64
@ -740,7 +716,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var kind reflect.Kind var kind reflect.Kind
fn := func() (err error) { fn := func() (err error) {
if idx := strings.Index(fe.Param(), "."); idx != -1 { if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:])) digits = uint64(len(fe.Param()[idx+1:]))
} }
@ -818,7 +793,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be equal to {1}", translation: "{0} must be equal to {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -833,7 +807,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be equal to {1}", translation: "{0} must be equal to {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -848,7 +821,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} cannot be equal to {1}", translation: "{0} cannot be equal to {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -863,7 +835,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be greater than {1}", translation: "{0} must be greater than {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -878,7 +849,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be greater than or equal to {1}", translation: "{0} must be greater than or equal to {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -893,7 +863,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be less than {1}", translation: "{0} must be less than {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -908,7 +877,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be less than or equal to {1}", translation: "{0} must be less than or equal to {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -923,7 +891,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} cannot be equal to {1}", translation: "{0} cannot be equal to {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -938,7 +905,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be greater than {1}", translation: "{0} must be greater than {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -953,7 +919,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be greater than or equal to {1}", translation: "{0} must be greater than or equal to {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -968,7 +933,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be less than {1}", translation: "{0} must be less than {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -983,7 +947,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must be less than or equal to {1}", translation: "{0} must be less than or equal to {1}",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1073,7 +1036,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must contain the text '{1}'", translation: "{0} must contain the text '{1}'",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1088,7 +1050,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} must contain at least one of the following characters '{1}'", translation: "{0} must contain at least one of the following characters '{1}'",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1103,7 +1064,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} cannot contain the text '{1}'", translation: "{0} cannot contain the text '{1}'",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1118,7 +1078,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} cannot contain any of the following characters '{1}'", translation: "{0} cannot contain any of the following characters '{1}'",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1133,7 +1092,6 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} cannot contain the following '{1}'", translation: "{0} cannot contain the following '{1}'",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1341,7 +1299,34 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
translation: "{0} does not match the {1} format", translation: "{0} does not match the {1} format",
override: false, override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string { customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
return fe.(error).Error()
}
return t
},
},
{
tag: "postcode_iso3166_alpha2",
translation: "{0} does not match postcode format of {1} country",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe)
return fe.(error).Error()
}
return t
},
},
{
tag: "postcode_iso3166_alpha2_field",
translation: "{0} does not match postcode format of country in {1} field",
override: false,
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field(), fe.Param()) t, err := ut.T(fe.Tag(), fe.Field(), fe.Param())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)
@ -1356,17 +1341,11 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
for _, t := range translations { for _, t := range translations {
if t.customTransFunc != nil && t.customRegisFunc != nil { if t.customTransFunc != nil && t.customRegisFunc != nil {
err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, t.customTransFunc) err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, t.customTransFunc)
} else if t.customTransFunc != nil && t.customRegisFunc == nil { } else if t.customTransFunc != nil && t.customRegisFunc == nil {
err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), t.customTransFunc) err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), t.customTransFunc)
} else if t.customTransFunc == nil && t.customRegisFunc != nil { } else if t.customTransFunc == nil && t.customRegisFunc != nil {
err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, translateFunc) err = v.RegisterTranslation(t.tag, trans, t.customRegisFunc, translateFunc)
} else { } else {
err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), translateFunc) err = v.RegisterTranslation(t.tag, trans, registrationFunc(t.tag, t.translation, t.override), translateFunc)
} }
@ -1380,21 +1359,16 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
} }
func registrationFunc(tag string, translation string, override bool) validator.RegisterTranslationsFunc { func registrationFunc(tag string, translation string, override bool) validator.RegisterTranslationsFunc {
return func(ut ut.Translator) (err error) { return func(ut ut.Translator) (err error) {
if err = ut.Add(tag, translation, override); err != nil { if err = ut.Add(tag, translation, override); err != nil {
return return
} }
return return
} }
} }
func translateFunc(ut ut.Translator, fe validator.FieldError) string { func translateFunc(ut ut.Translator, fe validator.FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field()) t, err := ut.T(fe.Tag(), fe.Field())
if err != nil { if err != nil {
log.Printf("warning: error translating FieldError: %#v", fe) log.Printf("warning: error translating FieldError: %#v", fe)

@ -11,7 +11,6 @@ import (
) )
func TestTranslations(t *testing.T) { func TestTranslations(t *testing.T) {
eng := english.New() eng := english.New()
uni := ut.New(eng, eng) uni := ut.New(eng, eng)
trans, _ := uni.GetTranslator("en") trans, _ := uni.GetTranslator("en")
@ -145,6 +144,9 @@ func TestTranslations(t *testing.T) {
LowercaseString string `validate:"lowercase"` LowercaseString string `validate:"lowercase"`
UppercaseString string `validate:"uppercase"` UppercaseString string `validate:"uppercase"`
Datetime string `validate:"datetime=2006-01-02"` Datetime string `validate:"datetime=2006-01-02"`
PostCode string `validate:"postcode_iso3166_alpha2=SG"`
PostCodeCountry string
PostCodeByField string `validate:"postcode_iso3166_alpha2_field=PostCodeCountry"`
} }
var test Test var test Test
@ -656,6 +658,14 @@ func TestTranslations(t *testing.T) {
ns: "Test.Datetime", ns: "Test.Datetime",
expected: "Datetime does not match the 2006-01-02 format", expected: "Datetime does not match the 2006-01-02 format",
}, },
{
ns: "Test.PostCode",
expected: "PostCode does not match postcode format of SG country",
},
{
ns: "Test.PostCodeByField",
expected: "PostCodeByField does not match postcode format of country in PostCodeCountry field",
},
} }
for _, tt := range tests { for _, tt := range tests {
@ -672,5 +682,4 @@ func TestTranslations(t *testing.T) {
NotEqual(t, fe, nil) NotEqual(t, fe, nil)
Equal(t, tt.expected, fe.Translate(trans)) Equal(t, tt.expected, fe.Translate(trans))
} }
} }

@ -14,6 +14,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/go-playground/assert/v2"
. "github.com/go-playground/assert/v2" . "github.com/go-playground/assert/v2"
"github.com/go-playground/locales/en" "github.com/go-playground/locales/en"
"github.com/go-playground/locales/fr" "github.com/go-playground/locales/fr"
@ -108,7 +109,6 @@ type TestSlice struct {
} }
func AssertError(t *testing.T, err error, nsKey, structNsKey, field, structField, expectedTag string) { func AssertError(t *testing.T, err error, nsKey, structNsKey, field, structField, expectedTag string) {
errs := err.(ValidationErrors) errs := err.(ValidationErrors)
found := false found := false
@ -150,7 +150,6 @@ func AssertDeepError(t *testing.T, err error, nsKey, structNsKey, field, structF
} }
func getError(err error, nsKey, structNsKey string) FieldError { func getError(err error, nsKey, structNsKey string) FieldError {
errs := err.(ValidationErrors) errs := err.(ValidationErrors)
var fe FieldError var fe FieldError
@ -170,7 +169,6 @@ type valuer struct {
} }
func (v valuer) Value() (driver.Value, error) { func (v valuer) Value() (driver.Value, error) {
if v.Name == "errorme" { if v.Name == "errorme" {
panic("SQL Driver Valuer error: some kind of error") panic("SQL Driver Valuer error: some kind of error")
// return nil, errors.New("some kind of error") // return nil, errors.New("some kind of error")
@ -189,7 +187,6 @@ type MadeUpCustomType struct {
} }
func ValidateCustomType(field reflect.Value) interface{} { func ValidateCustomType(field reflect.Value) interface{} {
if cust, ok := field.Interface().(MadeUpCustomType); ok { if cust, ok := field.Interface().(MadeUpCustomType); ok {
if len(cust.FirstName) == 0 || len(cust.LastName) == 0 { if len(cust.FirstName) == 0 || len(cust.LastName) == 0 {
@ -203,7 +200,6 @@ func ValidateCustomType(field reflect.Value) interface{} {
} }
func OverrideIntTypeForSomeReason(field reflect.Value) interface{} { func OverrideIntTypeForSomeReason(field reflect.Value) interface{} {
if i, ok := field.Interface().(int); ok { if i, ok := field.Interface().(int); ok {
if i == 1 { if i == 1 {
return "1" return "1"
@ -223,7 +219,6 @@ type CustomMadeUpStruct struct {
} }
func ValidateValuerType(field reflect.Value) interface{} { func ValidateValuerType(field reflect.Value) interface{} {
if valuer, ok := field.Interface().(driver.Valuer); ok { if valuer, ok := field.Interface().(driver.Valuer); ok {
val, err := valuer.Value() val, err := valuer.Value()
@ -261,7 +256,6 @@ type TestStruct struct {
} }
func StructValidationTestStructSuccess(sl StructLevel) { func StructValidationTestStructSuccess(sl StructLevel) {
st := sl.Current().Interface().(TestStruct) st := sl.Current().Interface().(TestStruct)
if st.String != "good value" { if st.String != "good value" {
@ -270,7 +264,6 @@ func StructValidationTestStructSuccess(sl StructLevel) {
} }
func StructValidationTestStruct(sl StructLevel) { func StructValidationTestStruct(sl StructLevel) {
st := sl.Current().Interface().(TestStruct) st := sl.Current().Interface().(TestStruct)
if st.String != "bad value" { if st.String != "bad value" {
@ -279,7 +272,6 @@ func StructValidationTestStruct(sl StructLevel) {
} }
func StructValidationNoTestStructCustomName(sl StructLevel) { func StructValidationNoTestStructCustomName(sl StructLevel) {
st := sl.Current().Interface().(TestStruct) st := sl.Current().Interface().(TestStruct)
if st.String != "bad value" { if st.String != "bad value" {
@ -288,7 +280,6 @@ func StructValidationNoTestStructCustomName(sl StructLevel) {
} }
func StructValidationTestStructInvalid(sl StructLevel) { func StructValidationTestStructInvalid(sl StructLevel) {
st := sl.Current().Interface().(TestStruct) st := sl.Current().Interface().(TestStruct)
if st.String != "bad value" { if st.String != "bad value" {
@ -297,7 +288,6 @@ func StructValidationTestStructInvalid(sl StructLevel) {
} }
func StructValidationTestStructReturnValidationErrors(sl StructLevel) { func StructValidationTestStructReturnValidationErrors(sl StructLevel) {
s := sl.Current().Interface().(TestStructReturnValidationErrors) s := sl.Current().Interface().(TestStructReturnValidationErrors)
errs := sl.Validator().Struct(s.Inner1.Inner2) errs := sl.Validator().Struct(s.Inner1.Inner2)
@ -309,7 +299,6 @@ func StructValidationTestStructReturnValidationErrors(sl StructLevel) {
} }
func StructValidationTestStructReturnValidationErrors2(sl StructLevel) { func StructValidationTestStructReturnValidationErrors2(sl StructLevel) {
s := sl.Current().Interface().(TestStructReturnValidationErrors) s := sl.Current().Interface().(TestStructReturnValidationErrors)
errs := sl.Validator().Struct(s.Inner1.Inner2) errs := sl.Validator().Struct(s.Inner1.Inner2)
@ -337,7 +326,6 @@ type StructLevelInvalidErr struct {
} }
func StructLevelInvalidError(sl StructLevel) { func StructLevelInvalidError(sl StructLevel) {
top := sl.Top().Interface().(StructLevelInvalidErr) top := sl.Top().Interface().(StructLevelInvalidErr)
s := sl.Current().Interface().(StructLevelInvalidErr) s := sl.Current().Interface().(StructLevelInvalidErr)
@ -359,7 +347,6 @@ func float64Ptr(v float64) *float64 {
} }
func TestStructLevelInvalidError(t *testing.T) { func TestStructLevelInvalidError(t *testing.T) {
validate := New() validate := New()
validate.RegisterStructValidation(StructLevelInvalidError, StructLevelInvalidErr{}) validate.RegisterStructValidation(StructLevelInvalidError, StructLevelInvalidErr{})
@ -383,7 +370,6 @@ func TestStructLevelInvalidError(t *testing.T) {
} }
func TestNameNamespace(t *testing.T) { func TestNameNamespace(t *testing.T) {
type Inner2Namespace struct { type Inner2Namespace struct {
String []string `validate:"dive,required" json:"JSONString"` String []string `validate:"dive,required" json:"JSONString"`
} }
@ -432,7 +418,6 @@ func TestNameNamespace(t *testing.T) {
} }
func TestAnonymous(t *testing.T) { func TestAnonymous(t *testing.T) {
validate := New() validate := New()
validate.RegisterTagNameFunc(func(fld reflect.StructField) string { validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
@ -500,7 +485,6 @@ func TestAnonymous(t *testing.T) {
} }
func TestAnonymousSameStructDifferentTags(t *testing.T) { func TestAnonymousSameStructDifferentTags(t *testing.T) {
validate := New() validate := New()
validate.RegisterTagNameFunc(func(fld reflect.StructField) string { validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
@ -545,7 +529,6 @@ func TestAnonymousSameStructDifferentTags(t *testing.T) {
} }
func TestStructLevelReturnValidationErrors(t *testing.T) { func TestStructLevelReturnValidationErrors(t *testing.T) {
validate := New() validate := New()
validate.RegisterStructValidation(StructValidationTestStructReturnValidationErrors, TestStructReturnValidationErrors{}) validate.RegisterStructValidation(StructValidationTestStructReturnValidationErrors, TestStructReturnValidationErrors{})
@ -575,7 +558,6 @@ func TestStructLevelReturnValidationErrors(t *testing.T) {
} }
func TestStructLevelReturnValidationErrorsWithJSON(t *testing.T) { func TestStructLevelReturnValidationErrorsWithJSON(t *testing.T) {
validate := New() validate := New()
validate.RegisterTagNameFunc(func(fld reflect.StructField) string { validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
@ -632,7 +614,6 @@ func TestStructLevelReturnValidationErrorsWithJSON(t *testing.T) {
} }
func TestStructLevelValidations(t *testing.T) { func TestStructLevelValidations(t *testing.T) {
v1 := New() v1 := New()
v1.RegisterStructValidation(StructValidationTestStruct, TestStruct{}) v1.RegisterStructValidation(StructValidationTestStruct, TestStruct{})
@ -666,7 +647,6 @@ func TestStructLevelValidations(t *testing.T) {
} }
func TestAliasTags(t *testing.T) { func TestAliasTags(t *testing.T) {
validate := New() validate := New()
validate.RegisterAlias("iscoloralias", "hexcolor|rgb|rgba|hsl|hsla") validate.RegisterAlias("iscoloralias", "hexcolor|rgb|rgba|hsl|hsla")
@ -714,7 +694,6 @@ func TestAliasTags(t *testing.T) {
} }
func TestNilValidator(t *testing.T) { func TestNilValidator(t *testing.T) {
type TestStruct struct { type TestStruct struct {
Test string `validate:"required"` Test string `validate:"required"`
} }
@ -724,7 +703,6 @@ func TestNilValidator(t *testing.T) {
var val *Validate var val *Validate
fn := func(fl FieldLevel) bool { fn := func(fl FieldLevel) bool {
return fl.Parent().String() == fl.Field().String() return fl.Parent().String() == fl.Field().String()
} }
@ -1971,7 +1949,6 @@ func TestCrossStructEqFieldValidation(t *testing.T) {
} }
func TestCrossNamespaceFieldValidation(t *testing.T) { func TestCrossNamespaceFieldValidation(t *testing.T) {
type SliceStruct struct { type SliceStruct struct {
Name string Name string
} }
@ -2209,7 +2186,6 @@ func TestCrossNamespaceFieldValidation(t *testing.T) {
} }
func TestExistsValidation(t *testing.T) { func TestExistsValidation(t *testing.T) {
jsonText := "{ \"truthiness2\": true }" jsonText := "{ \"truthiness2\": true }"
type Thing struct { type Thing struct {
@ -2240,7 +2216,6 @@ func TestExistsValidation(t *testing.T) {
} }
func TestSQLValue2Validation(t *testing.T) { func TestSQLValue2Validation(t *testing.T) {
validate := New() validate := New()
validate.RegisterCustomTypeFunc(ValidateValuerType, valuer{}, (*driver.Valuer)(nil), sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{}) validate.RegisterCustomTypeFunc(ValidateValuerType, valuer{}, (*driver.Valuer)(nil), sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{})
validate.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{}) validate.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{})
@ -2291,7 +2266,6 @@ func TestSQLValue2Validation(t *testing.T) {
} }
func TestSQLValueValidation(t *testing.T) { func TestSQLValueValidation(t *testing.T) {
validate := New() validate := New()
validate.RegisterCustomTypeFunc(ValidateValuerType, (*driver.Valuer)(nil), valuer{}) validate.RegisterCustomTypeFunc(ValidateValuerType, (*driver.Valuer)(nil), valuer{})
validate.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{}) validate.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{})
@ -2969,7 +2943,6 @@ func TestUnixAddrValidation(t *testing.T) {
} }
func TestSliceMapArrayChanFuncPtrInterfaceRequiredValidation(t *testing.T) { func TestSliceMapArrayChanFuncPtrInterfaceRequiredValidation(t *testing.T) {
validate := New() validate := New()
var m map[string]string var m map[string]string
@ -3047,7 +3020,6 @@ func TestSliceMapArrayChanFuncPtrInterfaceRequiredValidation(t *testing.T) {
} }
func TestDatePtrValidationIssueValidation(t *testing.T) { func TestDatePtrValidationIssueValidation(t *testing.T) {
type Test struct { type Test struct {
LastViewed *time.Time LastViewed *time.Time
Reminder *time.Time Reminder *time.Time
@ -3099,7 +3071,6 @@ func TestBadKeyValidation(t *testing.T) {
} }
func TestInterfaceErrValidation(t *testing.T) { func TestInterfaceErrValidation(t *testing.T) {
var v2 interface{} = 1 var v2 interface{} = 1
var v1 interface{} = v2 var v1 interface{} = v2
@ -3273,7 +3244,6 @@ func TestInterfaceErrValidation(t *testing.T) {
} }
func TestMapDiveValidation(t *testing.T) { func TestMapDiveValidation(t *testing.T) {
validate := New() validate := New()
n := map[int]interface{}{0: nil} n := map[int]interface{}{0: nil}
@ -3396,7 +3366,6 @@ func TestMapDiveValidation(t *testing.T) {
} }
func TestArrayDiveValidation(t *testing.T) { func TestArrayDiveValidation(t *testing.T) {
validate := New() validate := New()
arr := []string{"ok", "", "ok"} arr := []string{"ok", "", "ok"}
@ -4405,7 +4374,6 @@ func TestISBN10Validation(t *testing.T) {
} }
func TestExcludesRuneValidation(t *testing.T) { func TestExcludesRuneValidation(t *testing.T) {
tests := []struct { tests := []struct {
Value string `validate:"excludesrune=☻"` Value string `validate:"excludesrune=☻"`
Tag string Tag string
@ -4433,7 +4401,6 @@ func TestExcludesRuneValidation(t *testing.T) {
} }
func TestExcludesAllValidation(t *testing.T) { func TestExcludesAllValidation(t *testing.T) {
tests := []struct { tests := []struct {
Value string `validate:"excludesall=@!{}[]"` Value string `validate:"excludesall=@!{}[]"`
Tag string Tag string
@ -4479,7 +4446,6 @@ func TestExcludesAllValidation(t *testing.T) {
} }
func TestExcludesValidation(t *testing.T) { func TestExcludesValidation(t *testing.T) {
tests := []struct { tests := []struct {
Value string `validate:"excludes=@"` Value string `validate:"excludes=@"`
Tag string Tag string
@ -4507,7 +4473,6 @@ func TestExcludesValidation(t *testing.T) {
} }
func TestContainsRuneValidation(t *testing.T) { func TestContainsRuneValidation(t *testing.T) {
tests := []struct { tests := []struct {
Value string `validate:"containsrune=☻"` Value string `validate:"containsrune=☻"`
Tag string Tag string
@ -4535,7 +4500,6 @@ func TestContainsRuneValidation(t *testing.T) {
} }
func TestContainsAnyValidation(t *testing.T) { func TestContainsAnyValidation(t *testing.T) {
tests := []struct { tests := []struct {
Value string `validate:"containsany=@!{}[]"` Value string `validate:"containsany=@!{}[]"`
Tag string Tag string
@ -4563,7 +4527,6 @@ func TestContainsAnyValidation(t *testing.T) {
} }
func TestContainsValidation(t *testing.T) { func TestContainsValidation(t *testing.T) {
tests := []struct { tests := []struct {
Value string `validate:"contains=@"` Value string `validate:"contains=@"`
Tag string Tag string
@ -5149,7 +5112,6 @@ func TestOneOfValidation(t *testing.T) {
} }
func TestBase64Validation(t *testing.T) { func TestBase64Validation(t *testing.T) {
validate := New() validate := New()
s := "dW5pY29ybg==" s := "dW5pY29ybg=="
@ -5253,7 +5215,6 @@ func TestFileValidation(t *testing.T) {
} }
func TestEthereumAddressValidation(t *testing.T) { func TestEthereumAddressValidation(t *testing.T) {
validate := New() validate := New()
tests := []struct { tests := []struct {
@ -5307,7 +5268,6 @@ func TestEthereumAddressValidation(t *testing.T) {
} }
func TestBitcoinAddressValidation(t *testing.T) { func TestBitcoinAddressValidation(t *testing.T) {
validate := New() validate := New()
tests := []struct { tests := []struct {
@ -5417,7 +5377,6 @@ func TestBitcoinAddressValidation(t *testing.T) {
} }
func TestBitcoinBech32AddressValidation(t *testing.T) { func TestBitcoinBech32AddressValidation(t *testing.T) {
validate := New() validate := New()
tests := []struct { tests := []struct {
@ -5468,7 +5427,6 @@ func TestBitcoinBech32AddressValidation(t *testing.T) {
} }
func TestNoStructLevelValidation(t *testing.T) { func TestNoStructLevelValidation(t *testing.T) {
type Inner struct { type Inner struct {
Test string `validate:"len=5"` Test string `validate:"len=5"`
} }
@ -5500,7 +5458,6 @@ func TestNoStructLevelValidation(t *testing.T) {
} }
func TestStructOnlyValidation(t *testing.T) { func TestStructOnlyValidation(t *testing.T) {
type Inner struct { type Inner struct {
Test string `validate:"len=5"` Test string `validate:"len=5"`
} }
@ -6566,7 +6523,6 @@ func TestValidateByTagAndValue(t *testing.T) {
Equal(t, errs, nil) Equal(t, errs, nil)
fn := func(fl FieldLevel) bool { fn := func(fl FieldLevel) bool {
return fl.Parent().String() == fl.Field().String() return fl.Parent().String() == fl.Field().String()
} }
@ -6584,9 +6540,7 @@ func TestValidateByTagAndValue(t *testing.T) {
} }
func TestAddFunctions(t *testing.T) { func TestAddFunctions(t *testing.T) {
fn := func(fl FieldLevel) bool { fn := func(fl FieldLevel) bool {
return true return true
} }
@ -6615,7 +6569,6 @@ func TestAddFunctions(t *testing.T) {
} }
func TestChangeTag(t *testing.T) { func TestChangeTag(t *testing.T) {
validate := New() validate := New()
validate.SetTagName("val") validate.SetTagName("val")
@ -7262,8 +7215,7 @@ func TestIsLte(t *testing.T) {
} }
func TestUrnRFC2141(t *testing.T) { func TestUrnRFC2141(t *testing.T) {
tests := []struct {
var tests = []struct {
param string param string
expected bool expected bool
}{ }{
@ -7339,8 +7291,7 @@ func TestUrnRFC2141(t *testing.T) {
} }
func TestUrl(t *testing.T) { func TestUrl(t *testing.T) {
tests := []struct {
var tests = []struct {
param string param string
expected bool expected bool
}{ }{
@ -7407,8 +7358,7 @@ func TestUrl(t *testing.T) {
} }
func TestUri(t *testing.T) { func TestUri(t *testing.T) {
tests := []struct {
var tests = []struct {
param string param string
expected bool expected bool
}{ }{
@ -7474,7 +7424,6 @@ func TestUri(t *testing.T) {
} }
func TestOrTag(t *testing.T) { func TestOrTag(t *testing.T) {
validate := New() validate := New()
s := "rgba(0,31,255,0.5)" s := "rgba(0,31,255,0.5)"
@ -7504,7 +7453,7 @@ func TestOrTag(t *testing.T) {
Equal(t, errs, nil) Equal(t, errs, nil)
s = "green" s = "green"
errs = validate.Var(s, "eq=|eq=blue,rgb|rgba") //should fail on first validation block errs = validate.Var(s, "eq=|eq=blue,rgb|rgba") // should fail on first validation block
NotEqual(t, errs, nil) NotEqual(t, errs, nil)
ve := errs.(ValidationErrors) ve := errs.(ValidationErrors)
Equal(t, len(ve), 1) Equal(t, len(ve), 1)
@ -7517,7 +7466,6 @@ func TestOrTag(t *testing.T) {
v2 := New() v2 := New()
v2.RegisterTagNameFunc(func(fld reflect.StructField) string { v2.RegisterTagNameFunc(func(fld reflect.StructField) string {
name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
if name == "-" { if name == "-" {
@ -7542,7 +7490,6 @@ func TestOrTag(t *testing.T) {
} }
func TestHsla(t *testing.T) { func TestHsla(t *testing.T) {
validate := New() validate := New()
s := "hsla(360,100%,100%,1)" s := "hsla(360,100%,100%,1)"
@ -7589,7 +7536,6 @@ func TestHsla(t *testing.T) {
} }
func TestHsl(t *testing.T) { func TestHsl(t *testing.T) {
validate := New() validate := New()
s := "hsl(360,100%,50%)" s := "hsl(360,100%,50%)"
@ -7627,7 +7573,6 @@ func TestHsl(t *testing.T) {
} }
func TestRgba(t *testing.T) { func TestRgba(t *testing.T) {
validate := New() validate := New()
s := "rgba(0,31,255,0.5)" s := "rgba(0,31,255,0.5)"
@ -7673,7 +7618,6 @@ func TestRgba(t *testing.T) {
} }
func TestRgb(t *testing.T) { func TestRgb(t *testing.T) {
validate := New() validate := New()
s := "rgb(0,31,255)" s := "rgb(0,31,255)"
@ -7715,7 +7659,6 @@ func TestRgb(t *testing.T) {
} }
func TestEmail(t *testing.T) { func TestEmail(t *testing.T) {
validate := New() validate := New()
s := "test@mail.com" s := "test@mail.com"
@ -7783,7 +7726,6 @@ func TestEmail(t *testing.T) {
} }
func TestHexColor(t *testing.T) { func TestHexColor(t *testing.T) {
validate := New() validate := New()
s := "#fff" s := "#fff"
@ -7811,7 +7753,6 @@ func TestHexColor(t *testing.T) {
} }
func TestHexadecimal(t *testing.T) { func TestHexadecimal(t *testing.T) {
validate := New() validate := New()
s := "ff0044" s := "ff0044"
@ -7838,7 +7779,6 @@ func TestHexadecimal(t *testing.T) {
} }
func TestNumber(t *testing.T) { func TestNumber(t *testing.T) {
validate := New() validate := New()
s := "1" s := "1"
@ -7886,7 +7826,6 @@ func TestNumber(t *testing.T) {
} }
func TestNumeric(t *testing.T) { func TestNumeric(t *testing.T) {
validate := New() validate := New()
s := "1" s := "1"
@ -7929,7 +7868,6 @@ func TestNumeric(t *testing.T) {
} }
func TestAlphaNumeric(t *testing.T) { func TestAlphaNumeric(t *testing.T) {
validate := New() validate := New()
s := "abcd123" s := "abcd123"
@ -7947,7 +7885,6 @@ func TestAlphaNumeric(t *testing.T) {
} }
func TestAlpha(t *testing.T) { func TestAlpha(t *testing.T) {
validate := New() validate := New()
s := "abcd" s := "abcd"
@ -7977,11 +7914,9 @@ func TestAlpha(t *testing.T) {
errs = validate.Var(1, "alpha") errs = validate.Var(1, "alpha")
NotEqual(t, errs, nil) NotEqual(t, errs, nil)
AssertError(t, errs, "", "", "", "", "alpha") AssertError(t, errs, "", "", "", "", "alpha")
} }
func TestStructStringValidation(t *testing.T) { func TestStructStringValidation(t *testing.T) {
validate := New() validate := New()
tSuccess := &TestString{ tSuccess := &TestString{
@ -8063,7 +7998,6 @@ func TestStructStringValidation(t *testing.T) {
} }
func TestStructInt32Validation(t *testing.T) { func TestStructInt32Validation(t *testing.T) {
type TestInt32 struct { type TestInt32 struct {
Required int `validate:"required"` Required int `validate:"required"`
Len int `validate:"len=10"` Len int `validate:"len=10"`
@ -8127,7 +8061,6 @@ func TestStructInt32Validation(t *testing.T) {
} }
func TestStructUint64Validation(t *testing.T) { func TestStructUint64Validation(t *testing.T) {
validate := New() validate := New()
tSuccess := &TestUint64{ tSuccess := &TestUint64{
@ -8167,7 +8100,6 @@ func TestStructUint64Validation(t *testing.T) {
} }
func TestStructFloat64Validation(t *testing.T) { func TestStructFloat64Validation(t *testing.T) {
validate := New() validate := New()
tSuccess := &TestFloat64{ tSuccess := &TestFloat64{
@ -8207,7 +8139,6 @@ func TestStructFloat64Validation(t *testing.T) {
} }
func TestStructSliceValidation(t *testing.T) { func TestStructSliceValidation(t *testing.T) {
validate := New() validate := New()
tSuccess := &TestSlice{ tSuccess := &TestSlice{
@ -8257,11 +8188,9 @@ func TestStructSliceValidation(t *testing.T) {
_, ok := fe.Value().([]int) _, ok := fe.Value().([]int)
Equal(t, ok, true) Equal(t, ok, true)
} }
func TestInvalidStruct(t *testing.T) { func TestInvalidStruct(t *testing.T) {
validate := New() validate := New()
s := &SubTest{ s := &SubTest{
@ -8286,7 +8215,6 @@ func TestInvalidStruct(t *testing.T) {
} }
func TestInvalidValidatorFunction(t *testing.T) { func TestInvalidValidatorFunction(t *testing.T) {
validate := New() validate := New()
s := &SubTest{ s := &SubTest{
@ -8297,7 +8225,6 @@ func TestInvalidValidatorFunction(t *testing.T) {
} }
func TestCustomFieldName(t *testing.T) { func TestCustomFieldName(t *testing.T) {
validate := New() validate := New()
validate.RegisterTagNameFunc(func(fld reflect.StructField) string { validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
name := strings.SplitN(fld.Tag.Get("schema"), ",", 2)[0] name := strings.SplitN(fld.Tag.Get("schema"), ",", 2)[0]
@ -8341,7 +8268,6 @@ func TestCustomFieldName(t *testing.T) {
} }
func TestMutipleRecursiveExtractStructCache(t *testing.T) { func TestMutipleRecursiveExtractStructCache(t *testing.T) {
validate := New() validate := New()
type Recursive struct { type Recursive struct {
@ -8358,7 +8284,6 @@ func TestMutipleRecursiveExtractStructCache(t *testing.T) {
ptr := fmt.Sprintf("%p", sc) ptr := fmt.Sprintf("%p", sc)
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
go func() { go func() {
<-proceed <-proceed
sc := validate.extractStructCache(current, name) sc := validate.extractStructCache(current, name)
@ -8371,7 +8296,6 @@ func TestMutipleRecursiveExtractStructCache(t *testing.T) {
// Thanks @robbrockbank, see https://github.com/go-playground/validator/issues/249 // Thanks @robbrockbank, see https://github.com/go-playground/validator/issues/249
func TestPointerAndOmitEmpty(t *testing.T) { func TestPointerAndOmitEmpty(t *testing.T) {
validate := New() validate := New()
type Test struct { type Test struct {
@ -8417,7 +8341,6 @@ func TestPointerAndOmitEmpty(t *testing.T) {
} }
func TestRequired(t *testing.T) { func TestRequired(t *testing.T) {
validate := New() validate := New()
validate.RegisterTagNameFunc(func(fld reflect.StructField) string { validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
@ -8441,7 +8364,6 @@ func TestRequired(t *testing.T) {
} }
func TestBoolEqual(t *testing.T) { func TestBoolEqual(t *testing.T) {
validate := New() validate := New()
type Test struct { type Test struct {
@ -8469,16 +8391,13 @@ func TestTranslations(t *testing.T) {
validate := New() validate := New()
err := validate.RegisterTranslation("required", trans, err := validate.RegisterTranslation("required", trans,
func(ut ut.Translator) (err error) { func(ut ut.Translator) (err error) {
// using this stype because multiple translation may have to be added for the full translation // using this stype because multiple translation may have to be added for the full translation
if err = ut.Add("required", "{0} is a required field", false); err != nil { if err = ut.Add("required", "{0} is a required field", false); err != nil {
return return
} }
return return
}, func(ut ut.Translator, fe FieldError) string { }, func(ut ut.Translator, fe FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field()) t, err := ut.T(fe.Tag(), fe.Field())
if err != nil { if err != nil {
fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError)) fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError))
@ -8491,16 +8410,13 @@ func TestTranslations(t *testing.T) {
err = validate.RegisterTranslation("required", fr, err = validate.RegisterTranslation("required", fr,
func(ut ut.Translator) (err error) { func(ut ut.Translator) (err error) {
// using this stype because multiple translation may have to be added for the full translation // using this stype because multiple translation may have to be added for the full translation
if err = ut.Add("required", "{0} est un champ obligatoire", false); err != nil { if err = ut.Add("required", "{0} est un champ obligatoire", false); err != nil {
return return
} }
return return
}, func(ut ut.Translator, fe FieldError) string { }, func(ut ut.Translator, fe FieldError) string {
t, transErr := ut.T(fe.Tag(), fe.Field()) t, transErr := ut.T(fe.Tag(), fe.Field())
if transErr != nil { if transErr != nil {
fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError)) fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError))
@ -8578,16 +8494,13 @@ func TestTranslationErrors(t *testing.T) {
validate := New() validate := New()
err = validate.RegisterTranslation("required", trans, err = validate.RegisterTranslation("required", trans,
func(ut ut.Translator) (err error) { func(ut ut.Translator) (err error) {
// using this stype because multiple translation may have to be added for the full translation // using this stype because multiple translation may have to be added for the full translation
if err = ut.Add("required", "{0} is a required field", false); err != nil { if err = ut.Add("required", "{0} is a required field", false); err != nil {
return return
} }
return return
}, func(ut ut.Translator, fe FieldError) string { }, func(ut ut.Translator, fe FieldError) string {
t, err := ut.T(fe.Tag(), fe.Field()) t, err := ut.T(fe.Tag(), fe.Field())
if err != nil { if err != nil {
fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError)) fmt.Printf("warning: error translating FieldError: %#v", fe.(*fieldError))
@ -8602,7 +8515,6 @@ func TestTranslationErrors(t *testing.T) {
} }
func TestStructFiltered(t *testing.T) { func TestStructFiltered(t *testing.T) {
p1 := func(ns []byte) bool { p1 := func(ns []byte) bool {
if bytes.HasSuffix(ns, []byte("NoTag")) || bytes.HasSuffix(ns, []byte("Required")) { if bytes.HasSuffix(ns, []byte("NoTag")) || bytes.HasSuffix(ns, []byte("Required")) {
return false return false
@ -8768,7 +8680,6 @@ func TestStructFiltered(t *testing.T) {
} }
func TestRequiredPtr(t *testing.T) { func TestRequiredPtr(t *testing.T) {
type Test struct { type Test struct {
Bool *bool `validate:"required"` Bool *bool `validate:"required"`
} }
@ -8902,7 +8813,6 @@ func TestAlphaUnicodeValidation(t *testing.T) {
} }
func TestAlphanumericUnicodeValidation(t *testing.T) { func TestAlphanumericUnicodeValidation(t *testing.T) {
tests := []struct { tests := []struct {
param string param string
expected bool expected bool
@ -8945,7 +8855,6 @@ func TestAlphanumericUnicodeValidation(t *testing.T) {
} }
func TestArrayStructNamespace(t *testing.T) { func TestArrayStructNamespace(t *testing.T) {
validate := New() validate := New()
validate.RegisterTagNameFunc(func(fld reflect.StructField) string { validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
@ -8974,7 +8883,6 @@ func TestArrayStructNamespace(t *testing.T) {
} }
func TestMapStructNamespace(t *testing.T) { func TestMapStructNamespace(t *testing.T) {
validate := New() validate := New()
validate.RegisterTagNameFunc(func(fld reflect.StructField) string { validate.RegisterTagNameFunc(func(fld reflect.StructField) string {
name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0] name := strings.SplitN(fld.Tag.Get("json"), ",", 2)[0]
@ -9655,7 +9563,6 @@ func TestURLEncodedValidation(t *testing.T) {
} }
func TestKeys(t *testing.T) { func TestKeys(t *testing.T) {
type Test struct { type Test struct {
Test1 map[string]string `validate:"gt=0,dive,keys,eq=testkey,endkeys,eq=testval" json:"test1"` Test1 map[string]string `validate:"gt=0,dive,keys,eq=testkey,endkeys,eq=testval" json:"test1"`
Test2 map[int]int `validate:"gt=0,dive,keys,eq=3,endkeys,eq=4" json:"test2"` Test2 map[int]int `validate:"gt=0,dive,keys,eq=3,endkeys,eq=4" json:"test2"`
@ -9824,7 +9731,6 @@ func TestKeysCustomValidation(t *testing.T) {
} }
func TestKeyOrs(t *testing.T) { func TestKeyOrs(t *testing.T) {
type Test struct { type Test struct {
Test1 map[string]string `validate:"gt=0,dive,keys,eq=testkey|eq=testkeyok,endkeys,eq=testval" json:"test1"` Test1 map[string]string `validate:"gt=0,dive,keys,eq=testkey|eq=testkeyok,endkeys,eq=testval" json:"test1"`
} }
@ -10602,7 +10508,6 @@ func TestRequiredWithAll(t *testing.T) {
} }
func TestRequiredWithout(t *testing.T) { func TestRequiredWithout(t *testing.T) {
type Inner struct { type Inner struct {
Field *string Field *string
} }
@ -10668,7 +10573,6 @@ func TestRequiredWithout(t *testing.T) {
} }
func TestRequiredWithoutAll(t *testing.T) { func TestRequiredWithoutAll(t *testing.T) {
fieldVal := "test" fieldVal := "test"
test := struct { test := struct {
Field1 string `validate:"omitempty" json:"field_1"` Field1 string `validate:"omitempty" json:"field_1"`
@ -10725,7 +10629,6 @@ func TestLookup(t *testing.T) {
} }
func TestAbilityToValidateNils(t *testing.T) { func TestAbilityToValidateNils(t *testing.T) {
type TestStruct struct { type TestStruct struct {
Test *string `validate:"nil"` Test *string `validate:"nil"`
} }
@ -10867,7 +10770,6 @@ func TestJSONValidation(t *testing.T) {
} }
func Test_hostnameport_validator(t *testing.T) { func Test_hostnameport_validator(t *testing.T) {
type Host struct { type Host struct {
Addr string `validate:"hostname_port"` Addr string `validate:"hostname_port"`
} }
@ -10969,7 +10871,6 @@ func TestUppercaseValidation(t *testing.T) {
PanicMatches(t, func() { PanicMatches(t, func() {
_ = validate.Var(2, "uppercase") _ = validate.Var(2, "uppercase")
}, "Bad field type int") }, "Bad field type int")
} }
func TestDatetimeValidation(t *testing.T) { func TestDatetimeValidation(t *testing.T) {
@ -11263,4 +11164,116 @@ func TestBicIsoFormatValidation(t *testing.T) {
} }
} }
} }
} }
func TestPostCodeByIso3166Alpha2(t *testing.T) {
tests := map[string][]struct {
value string
expected bool
}{
"VN": {
{"ABC", false},
{"700000", true},
{"A1", false},
},
"GB": {
{"EC1A 1BB", true},
{"CF10 1B1H", false},
},
"VI": {
{"00803", true},
{"1234567", false},
},
"LC": { // not support regexp for post code
{"123456", false},
},
"XX": { // not support country
{"123456", false},
},
}
validate := New()
for cc, ccTests := range tests {
for i, test := range ccTests {
errs := validate.Var(test.value, fmt.Sprintf("postcode_iso3166_alpha2=%s", cc))
if test.expected {
if !IsEqual(errs, nil) {
t.Fatalf("Index: %d postcode_iso3166_alpha2=%s failed Error: %s", i, cc, errs)
}
} else {
if IsEqual(errs, nil) {
t.Fatalf("Index: %d postcode_iso3166_alpha2=%s failed Error: %s", i, cc, errs)
}
}
}
}
}
func TestPostCodeByIso3166Alpha2Field(t *testing.T) {
tests := []struct {
Value string `validate:"postcode_iso3166_alpha2_field=CountryCode"`
CountryCode interface{}
expected bool
}{
{"ABC", "VN", false},
{"700000", "VN", true},
{"A1", "VN", false},
{"EC1A 1BB", "GB", true},
{"CF10 1B1H", "GB", false},
{"00803", "VI", true},
{"1234567", "VI", false},
{"123456", "LC", false}, // not support regexp for post code
{"123456", "XX", false}, // not support country
}
validate := New()
for i, test := range tests {
errs := validate.Struct(test)
if test.expected {
if !IsEqual(errs, nil) {
t.Fatalf("Index: %d postcode_iso3166_alpha2_field=CountryCode failed Error: %s", i, errs)
}
} else {
if IsEqual(errs, nil) {
t.Fatalf("Index: %d postcode_iso3166_alpha2_field=CountryCode failed Error: %s", i, errs)
}
}
}
}
func TestPostCodeByIso3166Alpha2Field_WrongField(t *testing.T) {
type test struct {
Value string `validate:"postcode_iso3166_alpha2_field=CountryCode"`
CountryCode1 interface{}
expected bool
}
errs := New().Struct(test{"ABC", "VN", false})
assert.NotEqual(t, nil, errs)
}
func TestPostCodeByIso3166Alpha2Field_MissingParam(t *testing.T) {
type test struct {
Value string `validate:"postcode_iso3166_alpha2_field="`
CountryCode1 interface{}
expected bool
}
errs := New().Struct(test{"ABC", "VN", false})
assert.NotEqual(t, nil, errs)
}
func TestPostCodeByIso3166Alpha2Field_InvalidKind(t *testing.T) {
type test struct {
Value string `validate:"postcode_iso3166_alpha2_field=CountryCode"`
CountryCode interface{}
expected bool
}
defer func() { recover() }()
_ = New().Struct(test{"ABC", 123, false})
t.Errorf("Didn't panic as expected")
}

Loading…
Cancel
Save