add default translations for "en"

- need help creating more.
pull/256/head
Dean Karn 8 years ago
parent 532878b008
commit a7ca4a1d32
  1. 98
      README.md
  2. 22
      errors.go
  3. 101
      examples/translations/main.go
  4. 1301
      translations/en/en.go
  5. 580
      translations/en/en_test.go
  6. 16
      util.go
  7. 4
      validator.go
  8. 21
      validator_instance.go

@ -2,7 +2,7 @@ Package validator
================
<img align="right" src="https://raw.githubusercontent.com/go-playground/validator/v9/logo.png">
[![Join the chat at https://gitter.im/go-playground/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
![Project status](https://img.shields.io/badge/version-9.0.0-green.svg)
![Project status](https://img.shields.io/badge/version-9.1.0-green.svg)
[![Build Status](https://semaphoreci.com/api/v1/joeybloggs/validator/branches/v9/badge.svg)](https://semaphoreci.com/joeybloggs/validator)
[![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=v9&service=github)](https://coveralls.io/github/go-playground/validator?branch=v9)
[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator)
@ -333,54 +333,54 @@ Benchmarks
------
###### Run on MacBook Pro (Retina, 15-inch, Late 2013) 2.6 GHz Intel Core i7 16 GB 1600 MHz DDR3 using Go version go1.7 darwin/amd64
```go
BenchmarkFieldSuccess-8 20000000 108 ns/op 0 B/op 0 allocs/op
BenchmarkFieldSuccessParallel-8 50000000 35.7 ns/op 0 B/op 0 allocs/op
BenchmarkFieldFailure-8 5000000 320 ns/op 192 B/op 4 allocs/op
BenchmarkFieldFailureParallel-8 20000000 113 ns/op 192 B/op 4 allocs/op
BenchmarkFieldDiveSuccess-8 2000000 726 ns/op 201 B/op 11 allocs/op
BenchmarkFieldDiveSuccessParallel-8 10000000 263 ns/op 201 B/op 11 allocs/op
BenchmarkFieldDiveFailure-8 2000000 939 ns/op 396 B/op 16 allocs/op
BenchmarkFieldDiveFailureParallel-8 5000000 382 ns/op 397 B/op 16 allocs/op
BenchmarkFieldCustomTypeSuccess-8 5000000 268 ns/op 32 B/op 2 allocs/op
BenchmarkFieldCustomTypeSuccessParallel-8 20000000 87.8 ns/op 32 B/op 2 allocs/op
BenchmarkFieldCustomTypeFailure-8 5000000 310 ns/op 192 B/op 4 allocs/op
BenchmarkFieldCustomTypeFailureParallel-8 20000000 131 ns/op 192 B/op 4 allocs/op
BenchmarkFieldOrTagSuccess-8 2000000 889 ns/op 16 B/op 1 allocs/op
BenchmarkFieldOrTagSuccessParallel-8 5000000 418 ns/op 16 B/op 1 allocs/op
BenchmarkFieldOrTagFailure-8 3000000 546 ns/op 208 B/op 5 allocs/op
BenchmarkFieldOrTagFailureParallel-8 3000000 450 ns/op 208 B/op 5 allocs/op
BenchmarkStructLevelValidationSuccess-8 5000000 336 ns/op 32 B/op 2 allocs/op
BenchmarkStructLevelValidationSuccessParallel-8 20000000 123 ns/op 32 B/op 2 allocs/op
BenchmarkStructLevelValidationFailure-8 2000000 611 ns/op 288 B/op 8 allocs/op
BenchmarkStructLevelValidationFailureParallel-8 5000000 298 ns/op 288 B/op 8 allocs/op
BenchmarkStructSimpleCustomTypeSuccess-8 2000000 555 ns/op 32 B/op 2 allocs/op
BenchmarkStructSimpleCustomTypeSuccessParallel-8 10000000 197 ns/op 32 B/op 2 allocs/op
BenchmarkStructSimpleCustomTypeFailure-8 2000000 811 ns/op 392 B/op 9 allocs/op
BenchmarkStructSimpleCustomTypeFailureParallel-8 5000000 370 ns/op 408 B/op 10 allocs/op
BenchmarkStructPartialSuccess-8 2000000 676 ns/op 256 B/op 6 allocs/op
BenchmarkStructPartialSuccessParallel-8 5000000 301 ns/op 256 B/op 6 allocs/op
BenchmarkStructPartialFailure-8 1000000 1001 ns/op 464 B/op 11 allocs/op
BenchmarkStructPartialFailureParallel-8 3000000 436 ns/op 464 B/op 11 allocs/op
BenchmarkStructExceptSuccess-8 1000000 1038 ns/op 480 B/op 12 allocs/op
BenchmarkStructExceptSuccessParallel-8 10000000 281 ns/op 240 B/op 5 allocs/op
BenchmarkStructExceptFailure-8 2000000 863 ns/op 448 B/op 10 allocs/op
BenchmarkStructExceptFailureParallel-8 3000000 379 ns/op 448 B/op 10 allocs/op
BenchmarkStructSimpleCrossFieldSuccess-8 3000000 549 ns/op 72 B/op 3 allocs/op
BenchmarkStructSimpleCrossFieldSuccessParallel-8 10000000 192 ns/op 72 B/op 3 allocs/op
BenchmarkStructSimpleCrossFieldFailure-8 2000000 783 ns/op 288 B/op 8 allocs/op
BenchmarkStructSimpleCrossFieldFailureParallel-8 5000000 296 ns/op 288 B/op 8 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 2000000 837 ns/op 80 B/op 4 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8 5000000 284 ns/op 80 B/op 4 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldFailure-8 1000000 1110 ns/op 304 B/op 9 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8 3000000 416 ns/op 304 B/op 9 allocs/op
BenchmarkStructSimpleSuccess-8 5000000 380 ns/op 0 B/op 0 allocs/op
BenchmarkStructSimpleSuccessParallel-8 20000000 114 ns/op 0 B/op 0 allocs/op
BenchmarkStructSimpleFailure-8 2000000 760 ns/op 392 B/op 9 allocs/op
BenchmarkStructSimpleFailureParallel-8 5000000 353 ns/op 392 B/op 9 allocs/op
BenchmarkStructComplexSuccess-8 1000000 2100 ns/op 128 B/op 8 allocs/op
BenchmarkStructComplexSuccessParallel-8 2000000 662 ns/op 128 B/op 8 allocs/op
BenchmarkStructComplexFailure-8 200000 5080 ns/op 2833 B/op 53 allocs/op
BenchmarkStructComplexFailureParallel-8 1000000 2159 ns/op 2833 B/op 53 allocs/op
BenchmarkFieldSuccess-8 20000000 105 ns/op 0 B/op 0 allocs/op
BenchmarkFieldSuccessParallel-8 50000000 35.1 ns/op 0 B/op 0 allocs/op
BenchmarkFieldFailure-8 5000000 337 ns/op 208 B/op 4 allocs/op
BenchmarkFieldFailureParallel-8 20000000 120 ns/op 208 B/op 4 allocs/op
BenchmarkFieldDiveSuccess-8 2000000 716 ns/op 201 B/op 11 allocs/op
BenchmarkFieldDiveSuccessParallel-8 10000000 253 ns/op 201 B/op 11 allocs/op
BenchmarkFieldDiveFailure-8 1000000 1060 ns/op 412 B/op 16 allocs/op
BenchmarkFieldDiveFailureParallel-8 5000000 360 ns/op 413 B/op 16 allocs/op
BenchmarkFieldCustomTypeSuccess-8 5000000 299 ns/op 32 B/op 2 allocs/op
BenchmarkFieldCustomTypeSuccessParallel-8 20000000 86.0 ns/op 32 B/op 2 allocs/op
BenchmarkFieldCustomTypeFailure-8 5000000 341 ns/op 208 B/op 4 allocs/op
BenchmarkFieldCustomTypeFailureParallel-8 20000000 140 ns/op 208 B/op 4 allocs/op
BenchmarkFieldOrTagSuccess-8 2000000 893 ns/op 16 B/op 1 allocs/op
BenchmarkFieldOrTagSuccessParallel-8 5000000 431 ns/op 16 B/op 1 allocs/op
BenchmarkFieldOrTagFailure-8 2000000 563 ns/op 224 B/op 5 allocs/op
BenchmarkFieldOrTagFailureParallel-8 5000000 417 ns/op 224 B/op 5 allocs/op
BenchmarkStructLevelValidationSuccess-8 5000000 339 ns/op 32 B/op 2 allocs/op
BenchmarkStructLevelValidationSuccessParallel-8 20000000 114 ns/op 32 B/op 2 allocs/op
BenchmarkStructLevelValidationFailure-8 2000000 630 ns/op 304 B/op 8 allocs/op
BenchmarkStructLevelValidationFailureParallel-8 5000000 291 ns/op 304 B/op 8 allocs/op
BenchmarkStructSimpleCustomTypeSuccess-8 3000000 540 ns/op 32 B/op 2 allocs/op
BenchmarkStructSimpleCustomTypeSuccessParallel-8 10000000 176 ns/op 32 B/op 2 allocs/op
BenchmarkStructSimpleCustomTypeFailure-8 2000000 821 ns/op 424 B/op 9 allocs/op
BenchmarkStructSimpleCustomTypeFailureParallel-8 5000000 336 ns/op 440 B/op 10 allocs/op
BenchmarkStructPartialSuccess-8 2000000 686 ns/op 256 B/op 6 allocs/op
BenchmarkStructPartialSuccessParallel-8 5000000 282 ns/op 256 B/op 6 allocs/op
BenchmarkStructPartialFailure-8 2000000 931 ns/op 480 B/op 11 allocs/op
BenchmarkStructPartialFailureParallel-8 5000000 394 ns/op 480 B/op 11 allocs/op
BenchmarkStructExceptSuccess-8 1000000 1017 ns/op 496 B/op 12 allocs/op
BenchmarkStructExceptSuccessParallel-8 10000000 233 ns/op 240 B/op 5 allocs/op
BenchmarkStructExceptFailure-8 2000000 864 ns/op 464 B/op 10 allocs/op
BenchmarkStructExceptFailureParallel-8 5000000 393 ns/op 464 B/op 10 allocs/op
BenchmarkStructSimpleCrossFieldSuccess-8 3000000 552 ns/op 72 B/op 3 allocs/op
BenchmarkStructSimpleCrossFieldSuccessParallel-8 10000000 202 ns/op 72 B/op 3 allocs/op
BenchmarkStructSimpleCrossFieldFailure-8 2000000 798 ns/op 304 B/op 8 allocs/op
BenchmarkStructSimpleCrossFieldFailureParallel-8 5000000 356 ns/op 304 B/op 8 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldSuccess-8 2000000 825 ns/op 80 B/op 4 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldSuccessParallel-8 5000000 300 ns/op 80 B/op 4 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldFailure-8 2000000 1103 ns/op 320 B/op 9 allocs/op
BenchmarkStructSimpleCrossStructCrossFieldFailureParallel-8 3000000 433 ns/op 320 B/op 9 allocs/op
BenchmarkStructSimpleSuccess-8 5000000 360 ns/op 0 B/op 0 allocs/op
BenchmarkStructSimpleSuccessParallel-8 20000000 110 ns/op 0 B/op 0 allocs/op
BenchmarkStructSimpleFailure-8 2000000 783 ns/op 424 B/op 9 allocs/op
BenchmarkStructSimpleFailureParallel-8 5000000 358 ns/op 424 B/op 9 allocs/op
BenchmarkStructComplexSuccess-8 1000000 2120 ns/op 128 B/op 8 allocs/op
BenchmarkStructComplexSuccessParallel-8 2000000 659 ns/op 128 B/op 8 allocs/op
BenchmarkStructComplexFailure-8 300000 5126 ns/op 3041 B/op 53 allocs/op
BenchmarkStructComplexFailureParallel-8 1000000 2261 ns/op 3041 B/op 53 allocs/op
```
Complimentary Software

@ -63,6 +63,14 @@ func (ve ValidationErrors) Translate(ut ut.Translator) ValidationErrorsTranslati
for i := 0; i < len(ve); i++ {
fe = ve[i].(*fieldError)
// // in case an Anonymous struct was used, ensure that the key
// // would be 'Username' instead of ".Username"
// if len(fe.ns) > 0 && fe.ns[:1] == "." {
// trans[fe.ns[1:]] = fe.Translate(ut)
// continue
// }
trans[fe.ns] = fe.Translate(ut)
}
@ -192,8 +200,18 @@ func (fe *fieldError) StructNamespace() string {
// Field returns the fields name with the tag name taking precedence over the
// fields actual name.
func (fe *fieldError) Field() string {
// return fe.field
return fe.ns[len(fe.ns)-int(fe.fieldLen):]
// // return fe.field
// fld := fe.ns[len(fe.ns)-int(fe.fieldLen):]
// log.Println("FLD:", fld)
// if len(fld) > 0 && fld[:1] == "." {
// return fld[1:]
// }
// return fld
}
// returns the fields actual name from the struct, when able to determine.
@ -236,7 +254,7 @@ func (fe *fieldError) Error() string {
// as calling fe.Error()
func (fe *fieldError) Translate(ut ut.Translator) string {
m, ok := fe.v.transTagFunc[ut.Locale()]
m, ok := fe.v.transTagFunc[ut]
if !ok {
return fe.Error()
}

@ -0,0 +1,101 @@
package main
import (
"fmt"
"gopkg.in/go-playground/validator.v9"
)
// User contains user information
type User struct {
FirstName string `validate:"required"`
LastName string `validate:"required"`
Age uint8 `validate:"gte=0,lte=130"`
Email string `validate:"required,email"`
FavouriteColor string `validate:"iscolor"` // alias for 'hexcolor|rgb|rgba|hsl|hsla'
Addresses []*Address `validate:"required,dive,required"` // a person can have a home and cottage...
}
// Address houses a users address information
type Address struct {
Street string `validate:"required"`
City string `validate:"required"`
Planet string `validate:"required"`
Phone string `validate:"required"`
}
// use a single instance of Validate, it caches struct info
var validate *validator.Validate
func main() {
validate = validator.New()
validateStruct()
validateVariable()
}
func validateStruct() {
address := &Address{
Street: "Eavesdown Docks",
Planet: "Persphone",
Phone: "none",
}
user := &User{
FirstName: "Badger",
LastName: "Smith",
Age: 135,
Email: "Badger.Smith@gmail.com",
FavouriteColor: "#000-",
Addresses: []*Address{address},
}
// returns nil or ValidationErrors ( map[string]*FieldError )
err := validate.Struct(user)
if err != nil {
// this check is only needed when your code could produce
// an invalid value for validation such as interface with nil
// value most including myself do not usually have code like this.
if _, ok := err.(*validator.InvalidValidationError); ok {
fmt.Println(err)
return
}
for _, err := range err.(validator.ValidationErrors) {
fmt.Println(err.Namespace())
fmt.Println(err.Field())
fmt.Println(err.StructNamespace()) // can differ when a custom TagNameFunc is registered or
fmt.Println(err.StructField()) // by passing alt name to ReportError like below
fmt.Println(err.Tag())
fmt.Println(err.ActualTag())
fmt.Println(err.Kind())
fmt.Println(err.Type())
fmt.Println(err.Value())
fmt.Println(err.Param())
fmt.Println()
}
// from here you can create your own error messages in whatever language you wish
return
}
// save user to database
}
func validateVariable() {
myEmail := "joeybloggs.gmail.com"
errs := validate.Var(myEmail, "required,email")
if errs != nil {
fmt.Println(errs) // output: Key: "" Error:Field validation for "" failed on the "email" tag
return
}
// email ok, move on
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,580 @@
package en
import (
"testing"
"time"
english "github.com/go-playground/locales/en"
"github.com/go-playground/universal-translator"
. "gopkg.in/go-playground/assert.v1"
"gopkg.in/go-playground/validator.v9"
)
func TestTranslations(t *testing.T) {
eng := english.New()
uni := ut.New(eng, eng)
trans, _ := uni.GetTranslator("en")
validate := validator.New()
err := RegisterDefaultTranslations(validate, trans)
Equal(t, err, nil)
type Inner struct {
EqCSFieldString string
NeCSFieldString string
GtCSFieldString string
GteCSFieldString string
LtCSFieldString string
LteCSFieldString string
}
type Test struct {
Inner Inner
RequiredString string `validate:"required"`
RequiredNumber int `validate:"required"`
RequiredMultiple []string `validate:"required"`
LenString string `validate:"len=1"`
LenNumber float64 `validate:"len=1113.00"`
LenMultiple []string `validate:"len=7"`
MinString string `validate:"min=1"`
MinNumber float64 `validate:"min=1113.00"`
MinMultiple []string `validate:"min=7"`
MaxString string `validate:"max=3"`
MaxNumber float64 `validate:"max=1113.00"`
MaxMultiple []string `validate:"max=7"`
EqString string `validate:"eq=3"`
EqNumber float64 `validate:"eq=2.33"`
EqMultiple []string `validate:"eq=7"`
NeString string `validate:"ne="`
NeNumber float64 `validate:"ne=0.00"`
NeMultiple []string `validate:"ne=0"`
LtString string `validate:"lt=3"`
LtNumber float64 `validate:"lt=5.56"`
LtMultiple []string `validate:"lt=2"`
LtTime time.Time `validate:"lt"`
LteString string `validate:"lte=3"`
LteNumber float64 `validate:"lte=5.56"`
LteMultiple []string `validate:"lte=2"`
LteTime time.Time `validate:"lte"`
GtString string `validate:"gt=3"`
GtNumber float64 `validate:"gt=5.56"`
GtMultiple []string `validate:"gt=2"`
GtTime time.Time `validate:"gt"`
GteString string `validate:"gte=3"`
GteNumber float64 `validate:"gte=5.56"`
GteMultiple []string `validate:"gte=2"`
GteTime time.Time `validate:"gte"`
EqFieldString string `validate:"eqfield=MaxString"`
EqCSFieldString string `validate:"eqcsfield=Inner.EqCSFieldString"`
NeCSFieldString string `validate:"necsfield=Inner.NeCSFieldString"`
GtCSFieldString string `validate:"gtcsfield=Inner.GtCSFieldString"`
GteCSFieldString string `validate:"gtecsfield=Inner.GteCSFieldString"`
LtCSFieldString string `validate:"ltcsfield=Inner.LtCSFieldString"`
LteCSFieldString string `validate:"ltecsfield=Inner.LteCSFieldString"`
NeFieldString string `validate:"nefield=EqFieldString"`
GtFieldString string `validate:"gtfield=MaxString"`
GteFieldString string `validate:"gtefield=MaxString"`
LtFieldString string `validate:"ltfield=MaxString"`
LteFieldString string `validate:"ltefield=MaxString"`
AlphaString string `validate:"alpha"`
AlphanumString string `validate:"alphanum"`
NumericString string `validate:"numeric"`
NumberString string `validate:"number"`
HexadecimalString string `validate:"hexadecimal"`
HexColorString string `validate:"hexcolor"`
RGBColorString string `validate:"rgb"`
RGBAColorString string `validate:"rgba"`
HSLColorString string `validate:"hsl"`
HSLAColorString string `validate:"hsla"`
Email string `validate:"email"`
URL string `validate:"url"`
URI string `validate:"uri"`
Base64 string `validate:"base64"`
Contains string `validate:"contains=purpose"`
ContainsAny string `validate:"containsany=!@#$"`
Excludes string `validate:"excludes=text"`
ExcludesAll string `validate:"excludesall=!@#$"`
ExcludesRune string `validate:"excludesrune=☻"`
ISBN string `validate:"isbn"`
ISBN10 string `validate:"isbn10"`
ISBN13 string `validate:"isbn13"`
UUID string `validate:"uuid"`
UUID3 string `validate:"uuid3"`
UUID4 string `validate:"uuid4"`
UUID5 string `validate:"uuid5"`
ASCII string `validate:"ascii"`
PrintableASCII string `validate:"printascii"`
MultiByte string `validate:"multibyte"`
DataURI string `validate:"datauri"`
Latitude string `validate:"latitude"`
Longitude string `validate:"longitude"`
SSN string `validate:"ssn"`
IP string `validate:"ip"`
IPv4 string `validate:"ipv4"`
IPv6 string `validate:"ipv6"`
CIDR string `validate:"cidr"`
CIDRv4 string `validate:"cidrv4"`
CIDRv6 string `validate:"cidrv6"`
TCPAddr string `validate:"tcp_addr"`
TCPAddrv4 string `validate:"tcp4_addr"`
TCPAddrv6 string `validate:"tcp6_addr"`
UDPAddr string `validate:"udp_addr"`
UDPAddrv4 string `validate:"udp4_addr"`
UDPAddrv6 string `validate:"udp6_addr"`
IPAddr string `validate:"ip_addr"`
IPAddrv4 string `validate:"ip4_addr"`
IPAddrv6 string `validate:"ip6_addr"`
UinxAddr string `validate:"unix_addr"` // can't fail from within Go's net package currently, but maybe in the future
MAC string `validate:"mac"`
}
var test Test
test.Inner.EqCSFieldString = "1234"
test.Inner.GtCSFieldString = "1234"
test.Inner.GteCSFieldString = "1234"
test.MaxString = "1234"
test.MaxNumber = 2000
test.MaxMultiple = make([]string, 9)
test.LtString = "1234"
test.LtNumber = 6
test.LtMultiple = make([]string, 3)
test.LtTime = time.Now().Add(time.Hour * 24)
test.LteString = "1234"
test.LteNumber = 6
test.LteMultiple = make([]string, 3)
test.LteTime = time.Now().Add(time.Hour * 24)
test.LtFieldString = "12345"
test.LteFieldString = "12345"
test.LtCSFieldString = "1234"
test.LteCSFieldString = "1234"
test.AlphaString = "abc3"
test.AlphanumString = "abc3!"
test.NumericString = "12E.00"
test.NumberString = "12E"
test.Excludes = "this is some test text"
test.ExcludesAll = "This is Great!"
test.ExcludesRune = "Love it ☻"
test.ASCII = "カタカナ"
test.PrintableASCII = "カタカナ"
test.MultiByte = "1234feerf"
err = validate.Struct(test)
NotEqual(t, err, nil)
errs, ok := err.(validator.ValidationErrors)
Equal(t, ok, true)
tests := []struct {
ns string
expected string
}{
{
ns: "Test.MAC",
expected: "MAC must contain a valid MAC address",
},
{
ns: "Test.IPAddr",
expected: "IPAddr must be a resolvable IP address",
},
{
ns: "Test.IPAddrv4",
expected: "IPAddrv4 must be a resolvable IPv4 address",
},
{
ns: "Test.IPAddrv6",
expected: "IPAddrv6 must be a resolvable IPv6 address",
},
{
ns: "Test.UDPAddr",
expected: "UDPAddr must be a valid UDP address",
},
{
ns: "Test.UDPAddrv4",
expected: "UDPAddrv4 must be a valid IPv4 UDP address",
},
{
ns: "Test.UDPAddrv6",
expected: "UDPAddrv6 must be a valid IPv6 UDP address",
},
{
ns: "Test.TCPAddr",
expected: "TCPAddr must be a valid TCP address",
},
{
ns: "Test.TCPAddrv4",
expected: "TCPAddrv4 must be a valid IPv4 TCP address",
},
{
ns: "Test.TCPAddrv6",
expected: "TCPAddrv6 must be a valid IPv6 TCP address",
},
{
ns: "Test.CIDR",
expected: "CIDR must contain a valid CIDR notation",
},
{
ns: "Test.CIDRv4",
expected: "CIDRv4 must contain a valid CIDR notation for an IPv4 address",
},
{
ns: "Test.CIDRv6",
expected: "CIDRv6 must contain a valid CIDR notation for an IPv6 address",
},
{
ns: "Test.SSN",
expected: "SSN must be a valid SSN number",
},
{
ns: "Test.IP",
expected: "IP must be a valid IP address",
},
{
ns: "Test.IPv4",
expected: "IPv4 must be a valid IPv4 address",
},
{
ns: "Test.IPv6",
expected: "IPv6 must be a valid IPv6 address",
},
{
ns: "Test.DataURI",
expected: "DataURI must contain a valid Data URI",
},
{
ns: "Test.Latitude",
expected: "Latitude must contain valid latitude coordinates",
},
{
ns: "Test.Longitude",
expected: "Longitude must contain a valid longitude coordinates",
},
{
ns: "Test.MultiByte",
expected: "MultiByte must contain multibyte characters",
},
{
ns: "Test.ASCII",
expected: "ASCII must contain only ascii characters",
},
{
ns: "Test.PrintableASCII",
expected: "PrintableASCII must contain only printable ascii characters",
},
{
ns: "Test.UUID",
expected: "UUID must be a valid UUID",
},
{
ns: "Test.UUID3",
expected: "UUID3 must be a valid version 3 UUID",
},
{
ns: "Test.UUID4",
expected: "UUID4 must be a valid version 4 UUID",
},
{
ns: "Test.UUID5",
expected: "UUID5 must be a valid version 5 UUID",
},
{
ns: "Test.ISBN",
expected: "ISBN must be a valid ISBN number",
},
{
ns: "Test.ISBN10",
expected: "ISBN10 must be a valid ISBN-10 number",
},
{
ns: "Test.ISBN13",
expected: "ISBN13 must be a valid ISBN-13 number",
},
{
ns: "Test.Excludes",
expected: "Excludes cannot contain the text 'text'",
},
{
ns: "Test.ExcludesAll",
expected: "ExcludesAll cannot contain any of the following characters '!@#$'",
},
{
ns: "Test.ExcludesRune",
expected: "ExcludesRune cannot contain the following '☻'",
},
{
ns: "Test.ContainsAny",
expected: "ContainsAny must contain at least one of the following characters '!@#$'",
},
{
ns: "Test.Contains",
expected: "Contains must contain the text 'purpose'",
},
{
ns: "Test.Base64",
expected: "Base64 must be a valid Base64 string",
},
{
ns: "Test.Email",
expected: "Email must be a valid email address",
},
{
ns: "Test.URL",
expected: "URL must be a valid URL",
},
{
ns: "Test.URI",
expected: "URI must be a valid URI",
},
{
ns: "Test.RGBColorString",
expected: "RGBColorString must be a valid RGB color",
},
{
ns: "Test.RGBAColorString",
expected: "RGBAColorString must be a valid RGBA color",
},
{
ns: "Test.HSLColorString",
expected: "HSLColorString must be a valid HSL color",
},
{
ns: "Test.HSLAColorString",
expected: "HSLAColorString must be a valid HSLA color",
},
{
ns: "Test.HexadecimalString",
expected: "HexadecimalString must be a valid hexadecimal",
},
{
ns: "Test.HexColorString",
expected: "HexColorString must be a valid HEX color",
},
{
ns: "Test.NumberString",
expected: "NumberString must be a valid number",
},
{
ns: "Test.NumericString",
expected: "NumericString must be a valid numeric value",
},
{
ns: "Test.AlphanumString",
expected: "AlphanumString can only contain alphanumeric characters",
},
{
ns: "Test.AlphaString",
expected: "AlphaString can only contain alphabetic characters",
},
{
ns: "Test.LtFieldString",
expected: "LtFieldString must be less than MaxString",
},
{
ns: "Test.LteFieldString",
expected: "LteFieldString must be less than or equal to MaxString",
},
{
ns: "Test.GtFieldString",
expected: "GtFieldString must be greater than MaxString",
},
{
ns: "Test.GteFieldString",
expected: "GteFieldString must be greater than or equal to MaxString",
},
{
ns: "Test.NeFieldString",
expected: "NeFieldString cannot be equal to EqFieldString",
},
{
ns: "Test.LtCSFieldString",
expected: "LtCSFieldString must be less than Inner.LtCSFieldString",
},
{
ns: "Test.LteCSFieldString",
expected: "LteCSFieldString must be less than or equal to Inner.LteCSFieldString",
},
{
ns: "Test.GtCSFieldString",
expected: "GtCSFieldString must be greater than Inner.GtCSFieldString",
},
{
ns: "Test.GteCSFieldString",
expected: "GteCSFieldString must be greater than or equal to Inner.GteCSFieldString",
},
{
ns: "Test.NeCSFieldString",
expected: "NeCSFieldString cannot be equal to Inner.NeCSFieldString",
},
{
ns: "Test.EqCSFieldString",
expected: "EqCSFieldString must be equal to Inner.EqCSFieldString",
},
{
ns: "Test.EqFieldString",
expected: "EqFieldString must be equal to MaxString",
},
{
ns: "Test.GteString",
expected: "GteString must be at least 3 characters in length",
},
{
ns: "Test.GteNumber",
expected: "GteNumber must be 5.56 or greater",
},
{
ns: "Test.GteMultiple",
expected: "GteMultiple must contain at least 2 items",
},
{
ns: "Test.GteTime",
expected: "GteTime must be greater than or equal to the current Date & Time",
},
{
ns: "Test.GtString",
expected: "GtString must be greater than 3 characters in length",
},
{
ns: "Test.GtNumber",
expected: "GtNumber must be greater than 5.56",
},
{
ns: "Test.GtMultiple",
expected: "GtMultiple must contain more than 2 items",
},
{
ns: "Test.GtTime",
expected: "GtTime must be greater than the current Date & Time",
},
{
ns: "Test.LteString",
expected: "LteString must be at maximum 3 characters in length",
},
{
ns: "Test.LteNumber",
expected: "LteNumber must be 5.56 or less",
},
{
ns: "Test.LteMultiple",
expected: "LteMultiple must contain at maximum 2 items",
},
{
ns: "Test.LteTime",
expected: "LteTime must be less than or equal to the current Date & Time",
},
{
ns: "Test.LtString",
expected: "LtString must be less than 3 characters in length",
},
{
ns: "Test.LtNumber",
expected: "LtNumber must be less than 5.56",
},
{
ns: "Test.LtMultiple",
expected: "LtMultiple must contain less than 2 items",
},
{
ns: "Test.LtTime",
expected: "LtTime must be less than the current Date & Time",
},
{
ns: "Test.NeString",
expected: "NeString should not be equal to ",
},
{
ns: "Test.NeNumber",
expected: "NeNumber should not be equal to 0.00",
},
{
ns: "Test.NeMultiple",
expected: "NeMultiple should not be equal to 0",
},
{
ns: "Test.EqString",
expected: "EqString is not equal to 3",
},
{
ns: "Test.EqNumber",
expected: "EqNumber is not equal to 2.33",
},
{
ns: "Test.EqMultiple",
expected: "EqMultiple is not equal to 7",
},
{
ns: "Test.MaxString",
expected: "MaxString must be a maximum of 3 characters in length",
},
{
ns: "Test.MaxNumber",
expected: "MaxNumber must be 1,113.00 or less",
},
{
ns: "Test.MaxMultiple",
expected: "MaxMultiple must contain at maximum 7 items",
},
{
ns: "Test.MinString",
expected: "MinString must be at least 1 character in length",
},
{
ns: "Test.MinNumber",
expected: "MinNumber must be 1,113.00 or greater",
},
{
ns: "Test.MinMultiple",
expected: "MinMultiple must contain at least 7 items",
},
{
ns: "Test.LenString",
expected: "LenString must be 1 character in length",
},
{
ns: "Test.LenNumber",
expected: "LenNumber must be equal to 1,113.00",
},
{
ns: "Test.LenMultiple",
expected: "LenMultiple must contain 7 items",
},
{
ns: "Test.RequiredString",
expected: "RequiredString is a required field",
},
{
ns: "Test.RequiredNumber",
expected: "RequiredNumber is a required field",
},
{
ns: "Test.RequiredMultiple",
expected: "RequiredMultiple is a required field",
},
}
for _, tt := range tests {
var fe validator.FieldError
for _, e := range errs {
if tt.ns == e.Namespace() {
fe = e
break
}
}
NotEqual(t, fe, nil)
Equal(t, tt.expected, fe.Translate(trans))
}
}

@ -6,22 +6,6 @@ import (
"strings"
)
// import (
// "reflect"
// "strconv"
// "strings"
// )
// const (
// blank = ""
// namespaceSeparator = "."
// leftBracket = "["
// rightBracket = "]"
// restrictedTagChars = ".[],|=+()`~!@#$%^&*\\\"/?<>{}"
// 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"
// )
// extractTypeInternal gets the actual underlying type of field value.
// It will dive into pointers, customTypes and return you the
// underlying value and it's kind.

@ -37,7 +37,7 @@ func (v *validate) validateStruct(parent reflect.Value, current reflect.Value, t
cs = v.v.extractStructCache(current, typ.Name())
}
if len(ns) == 0 {
if len(ns) == 0 && len(cs.name) != 0 {
ns = append(ns, cs.name...)
ns = append(ns, '.')
@ -310,7 +310,7 @@ OUTER:
v.misc = append(v.misc, '|')
v.misc = append(v.misc, ct.tag...)
if ct.next == nil {
if ct.next == nil || ct.next.typeof != typeOr { // ct.typeof != typeOr
// if we get here, no valid 'or' value and no more tags
v.str1 = string(append(ns, cf.altName...))

@ -55,7 +55,7 @@ type Validate struct {
customFuncs map[reflect.Type]CustomTypeFunc
aliases map[string]string
validations map[string]Func
transTagFunc map[string]map[string]TranslationFunc // map[<locale>]map[<tag>]TranslationFunc
transTagFunc map[ut.Translator]map[string]TranslationFunc // map[<locale>]map[<tag>]TranslationFunc
tagCache *tagCache
structCache *structCache
}
@ -192,20 +192,20 @@ func (v *Validate) RegisterCustomTypeFunc(fn CustomTypeFunc, types ...interface{
v.hasCustomFuncs = true
}
func (v *Validate) RegisterTranslation(tag string, ut ut.Translator, registerFn RegisterTranslationsFunc, translationFn TranslationFunc) (err error) {
func (v *Validate) RegisterTranslation(tag string, trans ut.Translator, registerFn RegisterTranslationsFunc, translationFn TranslationFunc) (err error) {
if v.transTagFunc == nil {
v.transTagFunc = make(map[string]map[string]TranslationFunc)
v.transTagFunc = make(map[ut.Translator]map[string]TranslationFunc)
}
if err = registerFn(ut); err != nil {
if err = registerFn(trans); err != nil {
return
}
m, ok := v.transTagFunc[ut.Locale()]
m, ok := v.transTagFunc[trans]
if !ok {
m = make(map[string]TranslationFunc)
v.transTagFunc[ut.Locale()] = m
v.transTagFunc[trans] = m
}
m[tag] = translationFn
@ -357,8 +357,13 @@ func (v *Validate) StructExcept(s interface{}, fields ...string) (err error) {
for _, key := range fields {
vd.misc = append(vd.misc[0:0], name...)
vd.misc = append(vd.misc, '.')
vd.misc = vd.misc[0:0]
if len(name) > 0 {
vd.misc = append(vd.misc, name...)
vd.misc = append(vd.misc, '.')
}
vd.misc = append(vd.misc, key...)
vd.includeExclude[string(vd.misc)] = struct{}{}
}

Loading…
Cancel
Save