├── .gitignore ├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── doc.go ├── errors.go ├── formats.go ├── formats_test.go ├── go.mod ├── go.sum ├── regexes.go ├── testdata └── a.go ├── validate.go ├── validate_test.go └── validators.go /.gitignore: -------------------------------------------------------------------------------- 1 | coverage.txt 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.11.x 4 | - 1.12.x 5 | - tip 6 | 7 | before_install: 8 | - go get -t -v ./... 9 | 10 | script: 11 | - make 12 | 13 | after_success: 14 | - bash <(curl -s https://codecov.io/bash) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Vadym Myrgorod 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | test: 2 | @echo > coverage.txt 3 | go test -race -coverprofile=coverage.txt -covermode=atomic 4 | 5 | .PHONY: test 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # validate 2 | [![Build Status](https://travis-ci.org/dealancer/validate.svg?branch=v2)](https://travis-ci.org/dealancer/validate) 3 | [![codecov](https://codecov.io/gh/dealancer/validate/branch/v2/graph/badge.svg)](https://codecov.io/gh/dealancer/validate) 4 | [![Go Report Card](https://goreportcard.com/badge/gopkg.in/dealancer/validate.v2)](https://goreportcard.com/report/gopkg.in/dealancer/validate.v2) 5 | [![GoDoc](https://godoc.org/gopkg.in/dealancer/validate.v2?status.svg)](https://godoc.org/gopkg.in/dealancer/validate.v2) 6 | [![GitHub release](https://img.shields.io/github/release/dealancer/validate.svg)](https://github.com/dealancer/validate/releases) 7 | [![License](https://img.shields.io/github/license/dealancer/validate.svg)](./LICENSE) 8 | 9 | Package **validate** validates Go struct and types recursively based on tags. 10 | It provides powerful syntax to perform validation for substructs, maps, slices, arrays, and pointers. Package also allows to run custom validation methods. 11 | 12 | Use this package to make sure that the content of the struct is in the format you need. 13 | For example, **validate** package is useful when unmarshalling YAML or JSON. 14 | 15 | ## Installation 16 | 17 | 1. Use `go get` to download validate package. 18 | ``` 19 | go get gopkg.in/dealancer/validate.v2 20 | ``` 21 | 2. Import validate package into your project. 22 | ```go 23 | import "gopkg.in/dealancer/validate.v2" 24 | ``` 25 | 26 | 27 | ## Types 28 | 29 | This package supports a wide variety of types. 30 | 31 | * Most of the built-in types: 32 | * `int`, `int8` `int16`, `int32`, `int64` 33 | * `uint`, `uint8`, `uint16`, `uint32`, `uint64` 34 | * `float32`, `float64` 35 | * `uintptr` 36 | * `string` 37 | * Aliased types: 38 | * `time.Duration` 39 | * `byte` (`uint8`) 40 | * `rune` (`int32`) 41 | * e.g. `type Enum string` 42 | * Complex types: 43 | * Struct 44 | * Map 45 | * Slice 46 | * Array 47 | * Pointer 48 | 49 | ## Validators 50 | 51 | This package provides the following validators. 52 | 53 | * `eq` (equals), `ne` (not equals), `gt` (greater than), `lt` (less than), `gte` (greater than or equal to), `lte` (less than or equal to) validators compare a numeric value of a number or compare a count of elements in a string, a map, a slice, or an array. 54 | * `empty` validator checks if a string, a map, a slice, or an array is (not) empty. 55 | * `nil` validator checks if a pointer is (not) nil. 56 | * `one_of` validator checks if a number or a string contains any of the given elements. 57 | * `format` validator checks if a string in one of the following formats: `alpha`, `alnum`, `alpha_unicode`, `alnum_unicode`, `numeric`, `number`, `hexadecimal`, `hexcolor`, `rgb`, `rgba`, `hsl`, `hsla`, `email`, `url`, `uri`, `urn_rfc2141`, `file`, `base64`, `base64url`, `isbn`, `isbn10`, `isbn13`, `eth_addr`, `btc_addr`, `btc_addr_bech32`, `uuid`, `uuid3`, `uuid4`, `uuid5`, `ascii`, `ascii_print`, `datauri`, `latitude`, `longitude`, `ssn`, `ipv4`, `ipv6`, `ip`, `cidrv4`, `cidrv6`, `cidr`, `mac`, `hostname`, `hostname_rfc1123`, `fqdn`, `url_encoded`, `dir`, `postcode`. 58 | 59 | ## Operators 60 | 61 | Following operators are used. There are listed in the descending order of their precedence. 62 | 63 | * `[]` (brackets) are used to validate map keys. 64 | * `>` (greater-than sign) is used to validate values of maps, slices, arrays or to dereference a pointer. 65 | * `&` (ampersand) is used to perform multiple validators using AND logic. 66 | * `|` (vertical bar) is used to perform multiple validators using OR logic. 67 | * `=` (equal sign) is used to separate validator type from value. 68 | * `,` (comma) is used to specify multiple tokens for a validator (e.g. `one_of`). 69 | 70 | ## Usage 71 | 72 | ```go 73 | type Registration struct { 74 | // Username should be between 3 and 25 characters and in alphanumeric unicode format 75 | Username string `validate:"gte=3 & lte=25 & format=alnum_unicode"` 76 | 77 | // Email should be empty or in the email format 78 | Email string `validate:"empty=true | format=email"` 79 | 80 | // Password is validated using a custom validation method 81 | Password string 82 | 83 | // Role should be one of "admin", "publisher", or "author" 84 | Role string `validate:"one_of=admin,publisher,author"` 85 | 86 | // URLs should not be empty, URLs values should be in the url format 87 | URLs []string `validate:"empty=false > format=url"` 88 | 89 | // Retired (pointer) should not be nil 90 | Retired *bool `validate:"nil=false"` 91 | 92 | // Some complex field with validation 93 | Complex []map[*string]int `validate:"gte=1 & lte=2 | eq=4 > empty=false [nil=false > empty=false] > ne=0"` 94 | } 95 | 96 | // Custom validation 97 | func (r Registration) Validate() error { 98 | if !StrongPass(r.Password) { 99 | return errors.New("Password should be strong!") 100 | } 101 | 102 | return nil 103 | } 104 | 105 | type Registrations struct { 106 | r []Registration `validate:"gte=2"` // There should be at least two registrations 107 | } 108 | ``` 109 | 110 | ```go 111 | registrations := Registrations{ 112 | r: []Registration{ 113 | Registration{ 114 | Username: "admin", 115 | }, 116 | }, 117 | } 118 | 119 | if err := validate.Validate(®istrations); err != nil { 120 | panic(err) 121 | } 122 | ``` 123 | 124 | See [GoDoc](https://godoc.org/gopkg.in/dealancer/validate.v2) for the complete reference. 125 | 126 | ## Credits 127 | 128 | This project is written by Vadym Myrgorod. Insipred by [go-playground/validator](https://github.com/go-playground/validator). 129 | -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package validate validates Go structs and types recursively based on tags. 3 | It provides powerful syntax to perform validation for substructs, maps, slices, arrays, and pointers. 4 | Package also allows to run custom validation methods. 5 | 6 | Use this package to make sure that the content of the struct is in the format you need. 7 | For example, **validate** package is useful when unmarshalling YAML or JSON. 8 | 9 | This package supports most of the built-in types: int8, uint8, int16, uint16, int32, 10 | uint32, int64, uint64, int, uint, uintptr, float32, float64 and aliased types: 11 | time.Duration, byte (uint8), rune (int32). 12 | 13 | Following validators are available: gt, lt, gte, lte, empty, nil, one_of, format. 14 | 15 | Basic usage 16 | 17 | Use validate tag to specify validators for fields of a struct. 18 | If any of validators fail, validate.Validate returns an error. 19 | 20 | type S struct { 21 | i int `validate:"gte=0"` // Should be greater than or equal to 0 22 | s string `validate:"format=email"` // Should be in the email format 23 | b *bool `validate:"nil=false"` // Should not be nil 24 | } 25 | 26 | err := validate.Validate(S{ 27 | i: -1, 28 | s: "", 29 | b: nil, 30 | }) 31 | 32 | // err contains an error because n is less than 0, s is empty, and b is nil 33 | 34 | Multiple validators 35 | 36 | It is possible to specify multiple validators using & (ampersand) or | (vertical bar) operator. 37 | & operator is used for logical AND, while | is used for logical OR. 38 | & operator has a priority over | operator. 39 | 40 | type S struct { 41 | // Check that the value is in the range of -20...-10 or 10...20 42 | field int `validate:"gte=-20 & lte=-10 | gte=10 & lte=20"` 43 | } 44 | 45 | Slice and array validation 46 | 47 | You can use a regular syntax to validate a slice/array. To validate slice/array values, specify validators after an arrow character. 48 | 49 | type S struct { 50 | // Check that the slice is not empty and slice values are either 1 or -1 51 | field []int `validate:"empty=false > one_of=1,-1"` 52 | } 53 | 54 | Map validation 55 | 56 | You can use a regular syntax to validate a map. To validate map keys, specify validators inside brackets. 57 | To validate map values, specify validators after an arrow character. 58 | 59 | type S struct { 60 | // Check that the map contains at least two elements, map keys are not empty, and map values are between 0 and 10 61 | field map[string]int `validate:"gte=2 [empty=false] > gte=0 & lte=10"` 62 | } 63 | 64 | Pointer validation 65 | 66 | You can use a regular syntax to validate a pointer. To dereference a pointer, specify validators after an arrow character. 67 | 68 | type S struct { 69 | // Check that the pointer is not nil and the number is between 0 and 10 70 | field *int `validate:"nil=false > gte=0 & lte=10"` 71 | } 72 | 73 | Nested struct validation 74 | 75 | You can validate a nested struct with regular syntax. 76 | 77 | type A struct { 78 | // Check that the number is greater than or equal to 0 79 | a int `validate:"gte=0"` 80 | } 81 | 82 | type B struct { 83 | A 84 | // Check that the number is greater than or equal to 0 85 | b int `validate:"gte=0"` 86 | } 87 | 88 | Substruct validation 89 | 90 | You can validate a substruct with regular syntax. 91 | 92 | type A struct { 93 | // Check that the number is greater than or equal to 0 94 | field int `validate:"gte=0"` 95 | } 96 | 97 | type B struct { 98 | a A 99 | // Check that the number is greater than or equal to 0 100 | field int `validate:"gte=0"` 101 | } 102 | 103 | Deep validation 104 | 105 | You can use brackets and arrow syntax to deep to as many levels as you need. 106 | 107 | type A struct { 108 | field int `validate:"gte=0 & lte=10"` 109 | } 110 | 111 | type B struct { 112 | field []map[*string]*A `validate:"gte=1 & lte=2 | eq=4 > empty=false [nil=false > empty=false] > nil=false"` 113 | } 114 | 115 | // gte=1 & lte=2 | eq=4 will be applied to the array 116 | // empty=false will be applied to the map 117 | // nil=false > empty=false will be applied to the map key (pointer and string) 118 | // nil=false will be applied to the map value 119 | // gte=0 & lte=10 will be applied to the A.field 120 | 121 | Custom validation 122 | 123 | You can specify custom validation method. 124 | Custom validation also works for a substuct, if a substruct is defined in an exported field. 125 | 126 | type S struct { 127 | field int 128 | } 129 | 130 | func (s S) Validate() error { 131 | if s.field <= 0 { 132 | return errors.New("field should be positive") 133 | } 134 | return nil 135 | } 136 | 137 | Handling errors 138 | 139 | Validate method returns two types of errors: ErrorSyntax and ErrorValidation. 140 | You can handle an error type using switch syntax. 141 | 142 | type S struct { 143 | field *string `validate:"empty=false"` 144 | } 145 | 146 | var err error 147 | 148 | if err = validate.Validate(S{nil}); err != nil { 149 | switch err.(type) { 150 | case validate.ErrorSyntax: 151 | // Handle syntax error 152 | case validate.ErrorValidation: 153 | // Handle validation error 154 | default: 155 | // Handle other errors 156 | } 157 | } 158 | */ 159 | package validate 160 | -------------------------------------------------------------------------------- /errors.go: -------------------------------------------------------------------------------- 1 | package validate 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | // ErrorField is an error interface for field/value error. 9 | type ErrorField interface { 10 | error 11 | FieldName() string 12 | } 13 | 14 | // errorField is a setter interface 15 | type errorField interface { 16 | setFieldName(string) 17 | } 18 | 19 | // ErrorValidation occurs when validator does not validate. 20 | type ErrorValidation struct { 21 | fieldName string 22 | fieldValue reflect.Value 23 | validatorType ValidatorType 24 | validatorValue string 25 | } 26 | 27 | // FieldName gets a field name. 28 | func (e ErrorValidation) FieldName() string { 29 | return e.fieldName 30 | } 31 | 32 | // setFieldName sets a field name. 33 | func (e *ErrorValidation) setFieldName(fieldName string) { 34 | e.fieldName = fieldName 35 | } 36 | 37 | // Error returns an error. 38 | func (e ErrorValidation) Error() string { 39 | validator := string(e.validatorType) 40 | if len(e.validatorValue) > 0 { 41 | validator += "=" + e.validatorValue 42 | } 43 | 44 | if len(e.fieldName) > 0 { 45 | return fmt.Sprintf("Validation error in field \"%v\" of type \"%v\" using validator \"%v\"", e.fieldName, e.fieldValue.Type(), validator) 46 | } 47 | 48 | return fmt.Sprintf("Validation error in value of type \"%v\" using validator \"%v\"", e.fieldValue.Type(), validator) 49 | } 50 | 51 | // ErrorSyntax occurs when there is a syntax error. 52 | type ErrorSyntax struct { 53 | fieldName string 54 | expression string 55 | near string 56 | comment string 57 | } 58 | 59 | // FieldName gets a field name. 60 | func (e ErrorSyntax) FieldName() string { 61 | return e.fieldName 62 | } 63 | 64 | // setFieldName sets a field name. 65 | func (e *ErrorSyntax) setFieldName(fieldName string) { 66 | e.fieldName = fieldName 67 | } 68 | 69 | // Error returns an error. 70 | func (e ErrorSyntax) Error() string { 71 | if len(e.fieldName) > 0 { 72 | return fmt.Sprintf("Syntax error when validating field \"%v\", expression \"%v\" near \"%v\": %v", e.fieldName, e.expression, e.near, e.comment) 73 | } 74 | 75 | return fmt.Sprintf("Syntax error when validating value, expression \"%v\" near \"%v\": %v", e.expression, e.near, e.comment) 76 | } 77 | 78 | // Set field name 79 | func setFieldName(err ErrorField, fieldName string) ErrorField { 80 | switch (err).(type) { 81 | case ErrorValidation: 82 | e := err.(ErrorValidation) 83 | var i interface{} = &e 84 | (i).(errorField).setFieldName(fieldName) 85 | return e 86 | case ErrorSyntax: 87 | e := err.(ErrorSyntax) 88 | var i interface{} = &e 89 | (i).(errorField).setFieldName(fieldName) 90 | return e 91 | } 92 | 93 | return err 94 | } 95 | -------------------------------------------------------------------------------- /formats.go: -------------------------------------------------------------------------------- 1 | package validate 2 | 3 | import ( 4 | "bytes" 5 | "crypto/sha256" 6 | "net" 7 | "net/url" 8 | "os" 9 | "strings" 10 | 11 | urn "github.com/leodido/go-urn" 12 | ) 13 | 14 | // FormatType is used for format validator type definitions. 15 | type FormatType string 16 | 17 | // Following string formats are available. 18 | // E.g. `validate:"format=email"` 19 | const ( 20 | FormatAlpha FormatType = "alpha" 21 | FormatAlnum FormatType = "alnum" 22 | FormatAlphaUnicode FormatType = "alpha_unicode" 23 | FormatAlnumUnicode FormatType = "alnum_unicode" 24 | FormatNumeric FormatType = "numeric" 25 | FormatNumber FormatType = "number" 26 | FormatHexadecimal FormatType = "hexadecimal" 27 | FormatHEXColor FormatType = "hexcolor" 28 | FormatRGB FormatType = "rgb" 29 | FormatRGBA FormatType = "rgba" 30 | FormatHSL FormatType = "hsl" 31 | FormatHSLA FormatType = "hsla" 32 | FormatEmail FormatType = "email" 33 | FormatURL FormatType = "url" 34 | FormatURI FormatType = "uri" 35 | FormatUrnRFC2141 FormatType = "urn_rfc2141" // RFC 2141 36 | FormatFile FormatType = "file" 37 | FormatBase64 FormatType = "base64" 38 | FormatBase64URL FormatType = "base64url" 39 | FormatISBN FormatType = "isbn" 40 | FormatISBN10 FormatType = "isbn10" 41 | FormatISBN13 FormatType = "isbn13" 42 | FormatEthereumAddress FormatType = "eth_addr" 43 | FormatBitcoinAddress FormatType = "btc_addr" 44 | FormatBitcoinBech32Address FormatType = "btc_addr_bech32" 45 | FormatUUID FormatType = "uuid" 46 | FormatUUID3 FormatType = "uuid3" 47 | FormatUUID4 FormatType = "uuid4" 48 | FormatUUID5 FormatType = "uuid5" 49 | FormatASCII FormatType = "ascii" 50 | FormatPrintableASCII FormatType = "ascii_print" 51 | FormatDataURI FormatType = "datauri" 52 | FormatLatitude FormatType = "latitude" 53 | FormatLongitude FormatType = "longitude" 54 | FormatSSN FormatType = "ssn" 55 | FormatIPv4 FormatType = "ipv4" 56 | FormatIPv6 FormatType = "ipv6" 57 | FormatIP FormatType = "ip" 58 | FormatCIDRv4 FormatType = "cidrv4" 59 | FormatCIDRv6 FormatType = "cidrv6" 60 | FormatCIDR FormatType = "cidr" 61 | FormatMAC FormatType = "mac" 62 | FormatHostnameRFC952 FormatType = "hostname" // RFC 952 63 | FormatHostnameRFC1123 FormatType = "hostname_rfc1123" // RFC 1123 64 | FormatFQDN FormatType = "fqdn" 65 | FormatURLEncoded FormatType = "url_encoded" 66 | FormatDir FormatType = "dir" 67 | FormatPostcode FormatType = "postcode" 68 | ) 69 | 70 | // formatFunc is an interface for format validator func 71 | type formatFunc func(value string) bool 72 | 73 | func getFormatTypeMap() map[FormatType]formatFunc { 74 | return map[FormatType]formatFunc{ 75 | FormatAlpha: formatAlpha, 76 | FormatAlnum: formatAlnum, 77 | FormatAlphaUnicode: formatAlphaUnicode, 78 | FormatAlnumUnicode: formatAlnumUnicode, 79 | FormatNumeric: formatNumeric, 80 | FormatNumber: formatNumber, 81 | FormatHexadecimal: formatHexadecimal, 82 | FormatHEXColor: formatHEXColor, 83 | FormatRGB: formatRGB, 84 | FormatRGBA: formatRGBA, 85 | FormatHSL: formatHSL, 86 | FormatHSLA: formatHSLA, 87 | FormatEmail: formatEmail, 88 | FormatURL: formatURL, 89 | FormatURI: formatURI, 90 | FormatUrnRFC2141: formatUrnRFC2141, 91 | FormatFile: formatFile, 92 | FormatBase64: formatBase64, 93 | FormatBase64URL: formatBase64URL, 94 | FormatISBN: formatISBN, 95 | FormatISBN10: formatISBN10, 96 | FormatISBN13: formatISBN13, 97 | FormatEthereumAddress: formatEthereumAddress, 98 | FormatBitcoinAddress: formatBitcoinAddress, 99 | FormatBitcoinBech32Address: formatBitcoinBech32Address, 100 | FormatUUID: formatUUID, 101 | FormatUUID3: formatUUID3, 102 | FormatUUID4: formatUUID4, 103 | FormatUUID5: formatUUID5, 104 | FormatASCII: formatASCII, 105 | FormatPrintableASCII: formatPrintableASCII, 106 | FormatDataURI: formatDataURI, 107 | FormatLatitude: formatLatitude, 108 | FormatLongitude: formatLongitude, 109 | FormatSSN: formatSSN, 110 | FormatIPv4: formatIPv4, 111 | FormatIPv6: formatIPv6, 112 | FormatIP: formatIP, 113 | FormatCIDRv4: formatCIDRv4, 114 | FormatCIDRv6: formatCIDRv6, 115 | FormatCIDR: formatCIDR, 116 | FormatMAC: formatMAC, 117 | FormatHostnameRFC952: formatHostnameRFC952, 118 | FormatHostnameRFC1123: formatHostnameRFC1123, 119 | FormatFQDN: formatFQDN, 120 | FormatURLEncoded: formatURLEncoded, 121 | FormatDir: formatDir, 122 | FormatPostcode: formatPostcode, 123 | } 124 | } 125 | 126 | func formatURLEncoded(value string) bool { 127 | return uRLEncodedRegex.MatchString(value) 128 | } 129 | 130 | // formatMAC is the validation function for validating if the field's value is a valid MAC address. 131 | func formatMAC(value string) bool { 132 | _, err := net.ParseMAC(value) 133 | 134 | return err == nil 135 | } 136 | 137 | // formatCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address. 138 | func formatCIDRv4(value string) bool { 139 | ip, _, err := net.ParseCIDR(value) 140 | 141 | return err == nil && ip.To4() != nil 142 | } 143 | 144 | // formatCIDRv6 is the validation function for validating if the field's value is a valid v6 CIDR address. 145 | func formatCIDRv6(value string) bool { 146 | 147 | ip, _, err := net.ParseCIDR(value) 148 | 149 | return err == nil && ip.To4() == nil 150 | } 151 | 152 | // formatCIDR is the validation function for validating if the field's value is a valid v4 or v6 CIDR address. 153 | func formatCIDR(value string) bool { 154 | _, _, err := net.ParseCIDR(value) 155 | 156 | return err == nil 157 | } 158 | 159 | // formatIPv4 is the validation function for validating if a value is a valid v4 IP address. 160 | func formatIPv4(value string) bool { 161 | ip := net.ParseIP(value) 162 | 163 | return ip != nil && ip.To4() != nil 164 | } 165 | 166 | // formatIPv6 is the validation function for validating if the field's value is a valid v6 IP address. 167 | func formatIPv6(value string) bool { 168 | ip := net.ParseIP(value) 169 | 170 | return ip != nil && ip.To4() == nil 171 | } 172 | 173 | // formatIP is the validation function for validating if the field's value is a valid v4 or v6 IP address. 174 | func formatIP(value string) bool { 175 | ip := net.ParseIP(value) 176 | 177 | return ip != nil 178 | } 179 | 180 | // formatSSN is the validation function for validating if the field's value is a valid SSN. 181 | func formatSSN(value string) bool { 182 | if len(value) != 11 { 183 | return false 184 | } 185 | 186 | return sSNRegex.MatchString(value) 187 | } 188 | 189 | // formatLongitude is the validation function for validating if the field's value is a valid longitude coordinate. 190 | func formatLongitude(value string) bool { 191 | return longitudeRegex.MatchString(value) 192 | } 193 | 194 | // formatLatitude is the validation function for validating if the field's value is a valid latitude coordinate. 195 | func formatLatitude(value string) bool { 196 | return latitudeRegex.MatchString(value) 197 | } 198 | 199 | // formatDataURI is the validation function for validating if the field's value is a valid data URI. 200 | func formatDataURI(value string) bool { 201 | uri := strings.SplitN(value, ",", 2) 202 | 203 | if len(uri) != 2 { 204 | return false 205 | } 206 | 207 | if !dataURIRegex.MatchString(uri[0]) { 208 | return false 209 | } 210 | 211 | return base64Regex.MatchString(uri[1]) 212 | } 213 | 214 | // formatPrintableASCII is the validation function for validating if the field's value is a valid printable ASCII character. 215 | func formatPrintableASCII(value string) bool { 216 | return printableASCIIRegex.MatchString(value) 217 | } 218 | 219 | // formatASCII is the validation function for validating if the field's value is a valid ASCII character. 220 | func formatASCII(value string) bool { 221 | return aSCIIRegex.MatchString(value) 222 | } 223 | 224 | // formatUUID5 is the validation function for validating if the field's value is a valid v5 UUID. 225 | func formatUUID5(value string) bool { 226 | return uUID5Regex.MatchString(value) 227 | } 228 | 229 | // formatUUID4 is the validation function for validating if the field's value is a valid v4 UUID. 230 | func formatUUID4(value string) bool { 231 | return uUID4Regex.MatchString(value) 232 | } 233 | 234 | // formatUUID3 is the validation function for validating if the field's value is a valid v3 UUID. 235 | func formatUUID3(value string) bool { 236 | return uUID3Regex.MatchString(value) 237 | } 238 | 239 | // formatUUID is the validation function for validating if the field's value is a valid UUID of any version. 240 | func formatUUID(value string) bool { 241 | return uUIDRegex.MatchString(value) 242 | } 243 | 244 | // formatISBN is the validation function for validating if the field's value is a valid v10 or v13 ISBN. 245 | func formatISBN(value string) bool { 246 | return formatISBN10(value) || formatISBN13(value) 247 | } 248 | 249 | // formatISBN13 is the validation function for validating if the field's value is a valid v13 ISBN. 250 | func formatISBN13(value string) bool { 251 | s := strings.Replace(strings.Replace(value, "-", "", 4), " ", "", 4) 252 | 253 | if !iSBN13Regex.MatchString(s) { 254 | return false 255 | } 256 | 257 | var checksum int32 258 | var i int32 259 | 260 | factor := []int32{1, 3} 261 | 262 | for i = 0; i < 12; i++ { 263 | checksum += factor[i%2] * int32(s[i]-'0') 264 | } 265 | 266 | return (int32(s[12]-'0'))-((10-(checksum%10))%10) == 0 267 | } 268 | 269 | // formatISBN10 is the validation function for validating if the field's value is a valid v10 ISBN. 270 | func formatISBN10(value string) bool { 271 | s := strings.Replace(strings.Replace(value, "-", "", 3), " ", "", 3) 272 | 273 | if !iSBN10Regex.MatchString(s) { 274 | return false 275 | } 276 | 277 | var checksum int32 278 | var i int32 279 | 280 | for i = 0; i < 9; i++ { 281 | checksum += (i + 1) * int32(s[i]-'0') 282 | } 283 | 284 | if s[9] == 'X' { 285 | checksum += 10 * 10 286 | } else { 287 | checksum += 10 * int32(s[9]-'0') 288 | } 289 | 290 | return checksum%11 == 0 291 | } 292 | 293 | // formatEthereumAddress is the validation function for validating if the field's value is a valid ethereum address based currently only on the format 294 | func formatEthereumAddress(value string) bool { 295 | address := value 296 | 297 | if !ethAddressRegex.MatchString(address) { 298 | return false 299 | } 300 | 301 | if ethAddressRegexUpper.MatchString(address) || ethAddressRegexLower.MatchString(address) { 302 | return true 303 | } 304 | 305 | // checksum validation is blocked by https://github.com/golang/crypto/pull/28 306 | 307 | return true 308 | } 309 | 310 | // formatBitcoinAddress is the validation function for validating if the field's value is a valid btc address 311 | func formatBitcoinAddress(value string) bool { 312 | address := value 313 | 314 | if !btcAddressRegex.MatchString(address) { 315 | return false 316 | } 317 | 318 | alphabet := []byte("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz") 319 | 320 | decode := [25]byte{} 321 | 322 | for _, n := range []byte(address) { 323 | d := bytes.IndexByte(alphabet, n) 324 | 325 | for i := 24; i >= 0; i-- { 326 | d += 58 * int(decode[i]) 327 | decode[i] = byte(d % 256) 328 | d /= 256 329 | } 330 | } 331 | 332 | h := sha256.New() 333 | _, _ = h.Write(decode[:21]) 334 | d := h.Sum([]byte{}) 335 | h = sha256.New() 336 | _, _ = h.Write(d) 337 | 338 | validchecksum := [4]byte{} 339 | computedchecksum := [4]byte{} 340 | 341 | copy(computedchecksum[:], h.Sum(d[:0])) 342 | copy(validchecksum[:], decode[21:]) 343 | 344 | return validchecksum == computedchecksum 345 | } 346 | 347 | // formatBitcoinBech32Address is the validation function for validating if the field's value is a valid bech32 btc address 348 | func formatBitcoinBech32Address(value string) bool { 349 | address := value 350 | 351 | if !btcLowerAddressRegexBech32.MatchString(address) && !btcUpperAddressRegexBech32.MatchString(address) { 352 | return false 353 | } 354 | 355 | am := len(address) % 8 356 | 357 | if am == 0 || am == 3 || am == 5 { 358 | return false 359 | } 360 | 361 | address = strings.ToLower(address) 362 | 363 | alphabet := "qpzry9x8gf2tvdw0s3jn54khce6mua7l" 364 | 365 | hr := []int{3, 3, 0, 2, 3} // the human readable part will always be bc 366 | addr := address[3:] 367 | dp := make([]int, 0, len(addr)) 368 | 369 | for _, c := range addr { 370 | dp = append(dp, strings.IndexRune(alphabet, c)) 371 | } 372 | 373 | ver := dp[0] 374 | 375 | if ver < 0 || ver > 16 { 376 | return false 377 | } 378 | 379 | if ver == 0 { 380 | if len(address) != 42 && len(address) != 62 { 381 | return false 382 | } 383 | } 384 | 385 | values := append(hr, dp...) 386 | 387 | GEN := []int{0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3} 388 | 389 | p := 1 390 | 391 | for _, v := range values { 392 | b := p >> 25 393 | p = (p&0x1ffffff)<<5 ^ v 394 | 395 | for i := 0; i < 5; i++ { 396 | if (b>>uint(i))&1 == 1 { 397 | p ^= GEN[i] 398 | } 399 | } 400 | } 401 | 402 | if p != 1 { 403 | return false 404 | } 405 | 406 | b := uint(0) 407 | acc := 0 408 | mv := (1 << 5) - 1 409 | var sw []int 410 | 411 | for _, v := range dp[1 : len(dp)-6] { 412 | acc = (acc << 5) | v 413 | b += 5 414 | for b >= 8 { 415 | b -= 8 416 | sw = append(sw, (acc>>b)&mv) 417 | } 418 | } 419 | 420 | if len(sw) < 2 || len(sw) > 40 { 421 | return false 422 | } 423 | 424 | return true 425 | } 426 | 427 | // formatBase64 is the validation function for validating if the current field's value is a valid base 64. 428 | func formatBase64(value string) bool { 429 | return base64Regex.MatchString(value) 430 | } 431 | 432 | // formatBase64URL is the validation function for validating if the current field's value is a valid base64 URL safe string. 433 | func formatBase64URL(value string) bool { 434 | return base64URLRegex.MatchString(value) 435 | } 436 | 437 | // formatURI is the validation function for validating if the current field's value is a valid URI. 438 | func formatURI(value string) bool { 439 | // checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195 440 | // emulate browser and strip the '#' suffix prior to validation. see issue-#237 441 | if i := strings.Index(value, "#"); i > -1 { 442 | value = value[:i] 443 | } 444 | 445 | if len(value) == 0 { 446 | return false 447 | } 448 | 449 | _, err := url.ParseRequestURI(value) 450 | 451 | return err == nil 452 | } 453 | 454 | // formatURL is the validation function for validating if the current field's value is a valid URL. 455 | func formatURL(value string) bool { 456 | var i int 457 | 458 | // checks needed as of Go 1.6 because of change https://github.com/golang/go/commit/617c93ce740c3c3cc28cdd1a0d712be183d0b328#diff-6c2d018290e298803c0c9419d8739885L195 459 | // emulate browser and strip the '#' suffix prior to validation. see issue-#237 460 | if i = strings.Index(value, "#"); i > -1 { 461 | value = value[:i] 462 | } 463 | 464 | if len(value) == 0 { 465 | return false 466 | } 467 | 468 | url, err := url.ParseRequestURI(value) 469 | 470 | if err != nil || url.Scheme == "" { 471 | return false 472 | } 473 | 474 | return err == nil 475 | } 476 | 477 | // formatUrnRFC2141 is the validation function for validating if the current field's value is a valid URN as per RFC 2141. 478 | func formatUrnRFC2141(value string) bool { 479 | _, match := urn.Parse([]byte(value)) 480 | 481 | return match 482 | 483 | } 484 | 485 | // formatFile is the validation function for validating if the current field's value is a valid file path. 486 | func formatFile(value string) bool { 487 | fileInfo, err := os.Stat(value) 488 | if err != nil { 489 | return false 490 | } 491 | 492 | return !fileInfo.IsDir() 493 | } 494 | 495 | // formatEmail is the validation function for validating if the current field's value is a valid email address. 496 | func formatEmail(value string) bool { 497 | return emailRegex.MatchString(value) 498 | } 499 | 500 | // formatHSLA is the validation function for validating if the current field's value is a valid HSLA color. 501 | func formatHSLA(value string) bool { 502 | return hslaRegex.MatchString(value) 503 | } 504 | 505 | // formatHSL is the validation function for validating if the current field's value is a valid HSL color. 506 | func formatHSL(value string) bool { 507 | return hslRegex.MatchString(value) 508 | } 509 | 510 | // formatRGBA is the validation function for validating if the current field's value is a valid RGBA color. 511 | func formatRGBA(value string) bool { 512 | return rgbaRegex.MatchString(value) 513 | } 514 | 515 | // formatRGB is the validation function for validating if the current field's value is a valid RGB color. 516 | func formatRGB(value string) bool { 517 | return rgbRegex.MatchString(value) 518 | } 519 | 520 | // formatHEXColor is the validation function for validating if the current field's value is a valid HEX color. 521 | func formatHEXColor(value string) bool { 522 | return hexcolorRegex.MatchString(value) 523 | } 524 | 525 | // formatHexadecimal is the validation function for validating if the current field's value is a valid hexadecimal. 526 | func formatHexadecimal(value string) bool { 527 | return hexadecimalRegex.MatchString(value) 528 | } 529 | 530 | // formatNumber is the validation function for validating if the current field's value is a valid number. 531 | func formatNumber(value string) bool { 532 | return numberRegex.MatchString(value) 533 | } 534 | 535 | // formatNumeric is the validation function for validating if the current field's value is a valid numeric value. 536 | func formatNumeric(value string) bool { 537 | return numericRegex.MatchString(value) 538 | } 539 | 540 | // formatAlnum is the validation function for validating if the current field's value is a valid alphanumeric value. 541 | func formatAlnum(value string) bool { 542 | return alnumRegex.MatchString(value) 543 | } 544 | 545 | // formatAlpha is the validation function for validating if the current field's value is a valid alpha value. 546 | func formatAlpha(value string) bool { 547 | return alphaRegex.MatchString(value) 548 | } 549 | 550 | // formatAlnumUnicode is the validation function for validating if the current field's value is a valid alphanumeric unicode value. 551 | func formatAlnumUnicode(value string) bool { 552 | return alnumUnicodeRegex.MatchString(value) 553 | } 554 | 555 | // formatAlphaUnicode is the validation function for validating if the current field's value is a valid alpha unicode value. 556 | func formatAlphaUnicode(value string) bool { 557 | return alphaUnicodeRegex.MatchString(value) 558 | } 559 | 560 | func formatHostnameRFC952(value string) bool { 561 | return hostnameRegexRFC952.MatchString(value) 562 | } 563 | 564 | func formatHostnameRFC1123(value string) bool { 565 | return hostnameRegexRFC1123.MatchString(value) 566 | } 567 | 568 | func formatFQDN(value string) bool { 569 | val := value 570 | 571 | if val == "" { 572 | return false 573 | } 574 | 575 | if val[len(val)-1] == '.' { 576 | val = val[0 : len(val)-1] 577 | } 578 | 579 | return strings.ContainsAny(val, ".") && 580 | hostnameRegexRFC952.MatchString(val) 581 | } 582 | 583 | // formatDir is the validation function for validating if the current field's value is a valid directory. 584 | func formatDir(value string) bool { 585 | fileInfo, err := os.Stat(value) 586 | if err != nil { 587 | return false 588 | } 589 | 590 | return fileInfo.IsDir() 591 | } 592 | 593 | // formatPostcode is the validation function for validating if the current field's value is a valid postcode. 594 | func formatPostcode(value string) bool { 595 | return postcodeRegex.MatchString(value) 596 | } 597 | -------------------------------------------------------------------------------- /formats_test.go: -------------------------------------------------------------------------------- 1 | package validate 2 | 3 | import ( 4 | "path/filepath" 5 | "testing" 6 | ) 7 | 8 | type FormatTestGroup struct { 9 | Type FormatType 10 | Tests []FormatTest 11 | } 12 | 13 | type FormatTest struct { 14 | Sample string 15 | Result bool 16 | } 17 | 18 | func getFormatTestGroups() []FormatTestGroup { 19 | return []FormatTestGroup{ 20 | FormatTestGroup{ 21 | FormatMAC, []FormatTest{ 22 | {"3D:F2:C9:A6:B3:4F", true}, 23 | {"3D-F2-C9-A6-B3:4F", false}, 24 | {"123", false}, 25 | {"", false}, 26 | {"abacaba", false}, 27 | {"00:25:96:FF:FE:12:34:56", true}, 28 | {"0025:96FF:FE12:3456", false}, 29 | }, 30 | }, 31 | FormatTestGroup{ 32 | FormatIP, []FormatTest{ 33 | {"", false}, 34 | {"10.0.0.1", true}, 35 | {"172.16.0.1", true}, 36 | {"192.168.0.1", true}, 37 | {"192.168.255.254", true}, 38 | {"192.168.255.256", false}, 39 | {"172.16.255.254", true}, 40 | {"172.16.256.255", false}, 41 | {"2001:cdba:0000:0000:0000:0000:3257:9652", true}, 42 | {"2001:cdba:0:0:0:0:3257:9652", true}, 43 | {"2001:cdba::3257:9652", true}, 44 | }, 45 | }, 46 | FormatTestGroup{ 47 | FormatIPv6, []FormatTest{ 48 | {"10.0.0.1", false}, 49 | {"172.16.0.1", false}, 50 | {"192.168.0.1", false}, 51 | {"192.168.255.254", false}, 52 | {"192.168.255.256", false}, 53 | {"172.16.255.254", false}, 54 | {"172.16.256.255", false}, 55 | {"2001:cdba:0000:0000:0000:0000:3257:9652", true}, 56 | {"2001:cdba:0:0:0:0:3257:9652", true}, 57 | {"2001:cdba::3257:9652", true}, 58 | }, 59 | }, 60 | FormatTestGroup{ 61 | FormatIPv4, []FormatTest{ 62 | {"10.0.0.1", true}, 63 | {"172.16.0.1", true}, 64 | {"192.168.0.1", true}, 65 | {"192.168.255.254", true}, 66 | {"192.168.255.256", false}, 67 | {"172.16.255.254", true}, 68 | {"172.16.256.255", false}, 69 | {"2001:cdba:0000:0000:0000:0000:3257:9652", false}, 70 | {"2001:cdba:0:0:0:0:3257:9652", false}, 71 | {"2001:cdba::3257:9652", false}, 72 | }, 73 | }, 74 | FormatTestGroup{ 75 | FormatCIDR, []FormatTest{ 76 | {"10.0.0.0/0", true}, 77 | {"10.0.0.1/8", true}, 78 | {"172.16.0.1/16", true}, 79 | {"192.168.0.1/24", true}, 80 | {"192.168.255.254/24", true}, 81 | {"192.168.255.254/48", false}, 82 | {"192.168.255.256/24", false}, 83 | {"172.16.255.254/16", true}, 84 | {"172.16.256.255/16", false}, 85 | {"2001:cdba:0000:0000:0000:0000:3257:9652/64", true}, 86 | {"2001:cdba:0000:0000:0000:0000:3257:9652/256", false}, 87 | {"2001:cdba:0:0:0:0:3257:9652/32", true}, 88 | {"2001:cdba::3257:9652/16", true}, 89 | }, 90 | }, 91 | FormatTestGroup{ 92 | FormatCIDRv6, []FormatTest{ 93 | {"10.0.0.0/0", false}, 94 | {"10.0.0.1/8", false}, 95 | {"172.16.0.1/16", false}, 96 | {"192.168.0.1/24", false}, 97 | {"192.168.255.254/24", false}, 98 | {"192.168.255.254/48", false}, 99 | {"192.168.255.256/24", false}, 100 | {"172.16.255.254/16", false}, 101 | {"172.16.256.255/16", false}, 102 | {"2001:cdba:0000:0000:0000:0000:3257:9652/64", true}, 103 | {"2001:cdba:0000:0000:0000:0000:3257:9652/256", false}, 104 | {"2001:cdba:0:0:0:0:3257:9652/32", true}, 105 | {"2001:cdba::3257:9652/16", true}, 106 | }, 107 | }, 108 | FormatTestGroup{ 109 | FormatCIDRv4, []FormatTest{ 110 | {"10.0.0.0/0", true}, 111 | {"10.0.0.1/8", true}, 112 | {"172.16.0.1/16", true}, 113 | {"192.168.0.1/24", true}, 114 | {"192.168.255.254/24", true}, 115 | {"192.168.255.254/48", false}, 116 | {"192.168.255.256/24", false}, 117 | {"172.16.255.254/16", true}, 118 | {"172.16.256.255/16", false}, 119 | {"2001:cdba:0000:0000:0000:0000:3257:9652/64", false}, 120 | {"2001:cdba:0000:0000:0000:0000:3257:9652/256", false}, 121 | {"2001:cdba:0:0:0:0:3257:9652/32", false}, 122 | {"2001:cdba::3257:9652/16", false}, 123 | }, 124 | }, 125 | FormatTestGroup{ 126 | FormatSSN, []FormatTest{ 127 | {"", false}, 128 | {"00-90-8787", false}, 129 | {"66690-76", false}, 130 | {"191 60 2869", true}, 131 | {"191-60-2869", true}, 132 | }, 133 | }, 134 | FormatTestGroup{ 135 | FormatLongitude, []FormatTest{ 136 | {"", false}, 137 | {"-180.000", true}, 138 | {"180.1", false}, 139 | {"+73.234", true}, 140 | {"+382.3811", false}, 141 | {"23.11111111", true}, 142 | }, 143 | }, 144 | FormatTestGroup{ 145 | FormatLatitude, []FormatTest{ 146 | {"", false}, 147 | {"-90.000", true}, 148 | {"+90", true}, 149 | {"47.1231231", true}, 150 | {"+99.9", false}, 151 | {"108", false}, 152 | }, 153 | }, 154 | FormatTestGroup{ 155 | FormatDataURI, []FormatTest{ 156 | {"data:image/png;base64,TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4=", true}, 157 | {"data:text/plain;base64,Vml2YW11cyBmZXJtZW50dW0gc2VtcGVyIHBvcnRhLg==", true}, 158 | {"image/gif;base64,U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", false}, 159 | {"data:image/gif;base64,MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuMPNS1Ufof9EW/M98FNw" + 160 | "UAKrwflsqVxaxQjBQnHQmiI7Vac40t8x7pIb8gLGV6wL7sBTJiPovJ0V7y7oc0Ye" + 161 | "rhKh0Rm4skP2z/jHwwZICgGzBvA0rH8xlhUiTvcwDCJ0kc+fh35hNt8srZQM4619" + 162 | "FTgB66Xmp4EtVyhpQV+t02g6NzK72oZI0vnAvqhpkxLeLiMCyrI416wHm5Tkukhx" + 163 | "QmcL2a6hNOyu0ixX/x2kSFXApEnVrJ+/IxGyfyw8kf4N2IZpW5nEP847lpfj0SZZ" + 164 | "Fwrd1mnfnDbYohX2zRptLy2ZUn06Qo9pkG5ntvFEPo9bfZeULtjYzIl6K8gJ2uGZ" + "HQIDAQAB", true}, 165 | {"data:image/png;base64,12345", false}, 166 | {"", false}, 167 | {"data:text,:;base85,U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", false}, 168 | }, 169 | }, 170 | FormatTestGroup{ 171 | FormatPrintableASCII, []FormatTest{ 172 | {"", true}, 173 | {"foobar", false}, 174 | {"xyz098", false}, 175 | {"123456", false}, 176 | {"カタカナ", false}, 177 | {"foobar", true}, 178 | {"0987654321", true}, 179 | {"test@example.com", true}, 180 | {"1234abcDEF", true}, 181 | {"newline\n", false}, 182 | {"\x19test\x7F", false}, 183 | }, 184 | }, 185 | FormatTestGroup{ 186 | FormatASCII, []FormatTest{ 187 | {"", true}, 188 | {"foobar", false}, 189 | {"xyz098", false}, 190 | {"123456", false}, 191 | {"カタカナ", false}, 192 | {"foobar", true}, 193 | {"0987654321", true}, 194 | {"test@example.com", true}, 195 | {"1234abcDEF", true}, 196 | {"", true}, 197 | }, 198 | }, 199 | FormatTestGroup{ 200 | FormatUUID5, []FormatTest{ 201 | {"", false}, 202 | {"xxxa987Fbc9-4bed-3078-cf07-9141ba07c9f3", false}, 203 | {"9c858901-8a57-4791-81Fe-4c455b099bc9", false}, 204 | {"a987Fbc9-4bed-3078-cf07-9141ba07c9f3", false}, 205 | {"987Fbc97-4bed-5078-af07-9141ba07c9f3", true}, 206 | {"987Fbc97-4bed-5078-9f07-9141ba07c9f3", true}, 207 | }, 208 | }, 209 | FormatTestGroup{ 210 | FormatUUID4, []FormatTest{ 211 | {"", false}, 212 | {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9F3", false}, 213 | {"a987fbc9-4bed-5078-af07-9141ba07c9F3", false}, 214 | {"934859", false}, 215 | {"57b73598-8764-4ad0-a76A-679bb6640eb1", true}, 216 | {"625e63f3-58f5-40b7-83a1-a72ad31acFfb", true}, 217 | }, 218 | }, 219 | FormatTestGroup{ 220 | FormatUUID3, []FormatTest{ 221 | {"", false}, 222 | {"412452646", false}, 223 | {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9F3", false}, 224 | {"a987fbc9-4bed-4078-8f07-9141ba07c9F3", false}, 225 | {"a987fbc9-4bed-3078-cf07-9141ba07c9F3", true}, 226 | }, 227 | }, 228 | FormatTestGroup{ 229 | FormatUUID, []FormatTest{ 230 | {"", false}, 231 | {"xxxa987Fbc9-4bed-3078-cf07-9141ba07c9f3", false}, 232 | {"a987Fbc9-4bed-3078-cf07-9141ba07c9f3xxx", false}, 233 | {"a987Fbc94bed3078cf079141ba07c9f3", false}, 234 | {"934859", false}, 235 | {"987fbc9-4bed-3078-cf07a-9141ba07c9F3", false}, 236 | {"aaaaaaaa-1111-1111-aaaG-111111111111", false}, 237 | {"a987Fbc9-4bed-3078-cf07-9141ba07c9f3", true}, 238 | }, 239 | }, 240 | FormatTestGroup{ 241 | FormatISBN, []FormatTest{ 242 | {"", false}, 243 | {"foo", false}, 244 | {"3836221195", true}, 245 | {"1-61729-085-8", true}, 246 | {"3 423 21412 0", true}, 247 | {"3 401 01319 X", true}, 248 | {"9784873113685", true}, 249 | {"978-4-87311-368-5", true}, 250 | {"978 3401013190", true}, 251 | {"978-3-8362-2119-1", true}, 252 | }, 253 | }, 254 | FormatTestGroup{ 255 | FormatISBN13, []FormatTest{ 256 | {"", false}, 257 | {"foo", false}, 258 | {"3-8362-2119-5", false}, 259 | {"01234567890ab", false}, 260 | {"978 3 8362 2119 0", false}, 261 | {"9784873113685", true}, 262 | {"978-4-87311-368-5", true}, 263 | {"978 3401013190", true}, 264 | {"978-3-8362-2119-1", true}, 265 | }, 266 | }, 267 | FormatTestGroup{ 268 | FormatISBN10, []FormatTest{ 269 | {"", false}, 270 | {"foo", false}, 271 | {"3423214121", false}, 272 | {"978-3836221191", false}, 273 | {"3-423-21412-1", false}, 274 | {"3 423 21412 1", false}, 275 | {"3836221195", true}, 276 | {"1-61729-085-8", true}, 277 | {"3 423 21412 0", true}, 278 | {"3 401 01319 X", true}, 279 | }, 280 | }, 281 | FormatTestGroup{ 282 | FormatBase64, []FormatTest{ 283 | {"dW5pY29ybg==", true}, 284 | {"dGhpIGlzIGEgdGVzdCBiYXNlNjQ=", true}, 285 | {"", false}, 286 | {"dW5pY29ybg== foo bar", false}, 287 | }, 288 | }, 289 | FormatTestGroup{ 290 | FormatBase64URL, []FormatTest{ 291 | // empty string, although a valid base64 string, should fail 292 | {"", false}, 293 | // invalid length 294 | {"a", false}, 295 | // base64 with padding 296 | {"Zg==", true}, 297 | {"Zm8=", true}, 298 | // base64 without padding 299 | {"Zm9v", true}, 300 | {"Zg", false}, 301 | {"Zm8", false}, 302 | // base64 URL safe encoding with invalid, special characters '+' and '/' 303 | {"FPucA9l+", false}, 304 | {"FPucA/lz", false}, 305 | // base64 URL safe encoding with valid, special characters '-' and '_' 306 | {"FPucA9l-", true}, 307 | {"FPucA_lz", true}, 308 | // non base64 characters 309 | {"@mc=", false}, 310 | {"Zm 9", false}, 311 | }, 312 | }, 313 | FormatTestGroup{ 314 | FormatFile, []FormatTest{ 315 | // empty path 316 | {"", false}, 317 | // regular file 318 | {filepath.Join("testdata", "a.go"), true}, 319 | // missing file 320 | {filepath.Join("testdata", "no.go"), false}, 321 | // directory, not a file 322 | {"testdata", false}, 323 | }, 324 | }, 325 | FormatTestGroup{ 326 | FormatDir, []FormatTest{ 327 | // existing dir 328 | {"testdata", true}, 329 | // existing self dir 330 | {".", true}, 331 | // existing parent dir 332 | {"..", true}, 333 | // empty dir 334 | {"", false}, 335 | // missing dir 336 | {"non_existing_testdata", false}, 337 | // a file not a directory 338 | {filepath.Join("testdata", "a.go"), false}, 339 | }, 340 | }, 341 | FormatTestGroup{ 342 | FormatEthereumAddress, []FormatTest{ 343 | {"", false}, 344 | {"0x02F9AE5f22EA3fA88F05780B30385bEC", false}, 345 | {"123f681646d4a755815f9cb19e1acc8565a0c2ac", false}, 346 | {"0x02F9AE5f22EA3fA88F05780B30385bECFacbf130", true}, 347 | {"0x123f681646d4a755815f9cb19e1acc8565a0c2ac", true}, 348 | }, 349 | }, 350 | FormatTestGroup{ 351 | FormatBitcoinAddress, []FormatTest{ 352 | {"", false}, 353 | {"x", false}, 354 | {"0x02F9AE5f22EA3fA88F05780B30385bEC", false}, 355 | {"1A1zP1ePQGefi2DMPTifTL5SLmv7DivfNa", false}, 356 | {"1P9RQEr2XeE3PEb44ZE35sfZRRW1JH8Uqx", false}, 357 | {"3P14159I73E4gFr7JterCCQh9QjiTjiZrG", false}, 358 | {"3P141597f3E4gFr7JterCCQh9QjiTjiZrG", false}, 359 | {"37qgekLpCCHrQuSjvX3fs496FWTGsHFHizjJAs6NPcR47aefnnCWECAhHV6E3g4YN7u7Yuwod5Y", false}, 360 | {"dzb7VV1Ui55BARxv7ATxAtCUeJsANKovDGWFVgpTbhq9gvPqP3yv", false}, 361 | {"MuNu7ZAEDFiHthiunm7dPjwKqrVNCM3mAz6rP9zFveQu14YA8CxExSJTHcVP9DErn6u84E6Ej7S", false}, 362 | {"rPpQpYknyNQ5AEHuY6H8ijJJrYc2nDKKk9jjmKEXsWzyAQcFGpDLU2Zvsmoi8JLR7hAwoy3RQWf", false}, 363 | {"4Uc3FmN6NQ6zLBK5QQBXRBUREaaHwCZYsGCueHauuDmJpZKn6jkEskMB2Zi2CNgtb5r6epWEFfUJq", false}, 364 | {"7aQgR5DFQ25vyXmqZAWmnVCjL3PkBcdVkBUpjrjMTcghHx3E8wb", false}, 365 | {"17QpPprjeg69fW1DV8DcYYCKvWjYhXvWkov6MJ1iTTvMFj6weAqW7wybZeH57WTNxXVCRH4veVs", false}, 366 | {"KxuACDviz8Xvpn1xAh9MfopySZNuyajYMZWz16Dv2mHHryznWUp3", false}, 367 | {"7nK3GSmqdXJQtdohvGfJ7KsSmn3TmGqExug49583bDAL91pVSGq5xS9SHoAYL3Wv3ijKTit65th", false}, 368 | {"cTivdBmq7bay3RFGEBBuNfMh2P1pDCgRYN2Wbxmgwr4ki3jNUL2va", false}, 369 | {"gjMV4vjNjyMrna4fsAr8bWxAbwtmMUBXJS3zL4NJt5qjozpbQLmAfK1uA3CquSqsZQMpoD1g2nk", false}, 370 | {"emXm1naBMoVzPjbk7xpeTVMFy4oDEe25UmoyGgKEB1gGWsK8kRGs", false}, 371 | {"7VThQnNRj1o3Zyvc7XHPRrjDf8j2oivPTeDXnRPYWeYGE4pXeRJDZgf28ppti5hsHWXS2GSobdqyo", false}, 372 | {"1G9u6oCVCPh2o8m3t55ACiYvG1y5BHewUkDSdiQarDcYXXhFHYdzMdYfUAhfxn5vNZBwpgUNpso", false}, 373 | {"31QQ7ZMLkScDiB4VyZjuptr7AEc9j1SjstF7pRoLhHTGkW4Q2y9XELobQmhhWxeRvqcukGd1XCq", false}, 374 | {"DHqKSnpxa8ZdQyH8keAhvLTrfkyBMQxqngcQA5N8LQ9KVt25kmGN", false}, 375 | {"2LUHcJPbwLCy9GLH1qXmfmAwvadWw4bp4PCpDfduLqV17s6iDcy1imUwhQJhAoNoN1XNmweiJP4i", false}, 376 | {"7USRzBXAnmck8fX9HmW7RAb4qt92VFX6soCnts9s74wxm4gguVhtG5of8fZGbNPJA83irHVY6bCos", false}, 377 | {"1DGezo7BfVebZxAbNT3XGujdeHyNNBF3vnficYoTSp4PfK2QaML9bHzAMxke3wdKdHYWmsMTJVu", false}, 378 | {"2D12DqDZKwCxxkzs1ZATJWvgJGhQ4cFi3WrizQ5zLAyhN5HxuAJ1yMYaJp8GuYsTLLxTAz6otCfb", false}, 379 | {"8AFJzuTujXjw1Z6M3fWhQ1ujDW7zsV4ePeVjVo7D1egERqSW9nZ", false}, 380 | {"163Q17qLbTCue8YY3AvjpUhotuaodLm2uqMhpYirsKjVqnxJRWTEoywMVY3NbBAHuhAJ2cF9GAZ", false}, 381 | {"2MnmgiRH4eGLyLc9eAqStzk7dFgBjFtUCtu", false}, 382 | {"461QQ2sYWxU7H2PV4oBwJGNch8XVTYYbZxU", false}, 383 | {"2UCtv53VttmQYkVU4VMtXB31REvQg4ABzs41AEKZ8UcB7DAfVzdkV9JDErwGwyj5AUHLkmgZeobs", false}, 384 | {"cSNjAsnhgtiFMi6MtfvgscMB2Cbhn2v1FUYfviJ1CdjfidvmeW6mn", false}, 385 | {"gmsow2Y6EWAFDFE1CE4Hd3Tpu2BvfmBfG1SXsuRARbnt1WjkZnFh1qGTiptWWbjsq2Q6qvpgJVj", false}, 386 | {"nksUKSkzS76v8EsSgozXGMoQFiCoCHzCVajFKAXqzK5on9ZJYVHMD5CKwgmX3S3c7M1U3xabUny", false}, 387 | {"L3favK1UzFGgdzYBF2oBT5tbayCo4vtVBLJhg2iYuMeePxWG8SQc", false}, 388 | {"7VxLxGGtYT6N99GdEfi6xz56xdQ8nP2dG1CavuXx7Rf2PrvNMTBNevjkfgs9JmkcGm6EXpj8ipyPZ ", false}, 389 | {"2mbZwFXF6cxShaCo2czTRB62WTx9LxhTtpP", false}, 390 | {"dB7cwYdcPSgiyAwKWL3JwCVwSk6epU2txw", false}, 391 | {"HPhFUhUAh8ZQQisH8QQWafAxtQYju3SFTX", false}, 392 | {"4ctAH6AkHzq5ioiM1m9T3E2hiYEev5mTsB", false}, 393 | {"31uEbMgunupShBVTewXjtqbBv5MndwfXhb", false}, 394 | {"175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W", false}, 395 | {"Hn1uFi4dNexWrqARpjMqgT6cX1UsNPuV3cHdGg9ExyXw8HTKadbktRDtdeVmY3M1BxJStiL4vjJ", false}, 396 | {"Sq3fDbvutABmnAHHExJDgPLQn44KnNC7UsXuT7KZecpaYDMU9Txs", false}, 397 | {"6TqWyrqdgUEYDQU1aChMuFMMEimHX44qHFzCUgGfqxGgZNMUVWJ", false}, 398 | {"giqJo7oWqFxNKWyrgcBxAVHXnjJ1t6cGoEffce5Y1y7u649Noj5wJ4mmiUAKEVVrYAGg2KPB3Y4", false}, 399 | {"cNzHY5e8vcmM3QVJUcjCyiKMYfeYvyueq5qCMV3kqcySoLyGLYUK", false}, 400 | {"37uTe568EYc9WLoHEd9jXEvUiWbq5LFLscNyqvAzLU5vBArUJA6eydkLmnMwJDjkL5kXc2VK7ig", false}, 401 | {"EsYbG4tWWWY45G31nox838qNdzksbPySWc", false}, 402 | {"nbuzhfwMoNzA3PaFnyLcRxE9bTJPDkjZ6Rf6Y6o2ckXZfzZzXBT", false}, 403 | {"cQN9PoxZeCWK1x56xnz6QYAsvR11XAce3Ehp3gMUdfSQ53Y2mPzx", false}, 404 | {"1Gm3N3rkef6iMbx4voBzaxtXcmmiMTqZPhcuAepRzYUJQW4qRpEnHvMojzof42hjFRf8PE2jPde", false}, 405 | {"2TAq2tuN6x6m233bpT7yqdYQPELdTDJn1eU", false}, 406 | {"ntEtnnGhqPii4joABvBtSEJG6BxjT2tUZqE8PcVYgk3RHpgxgHDCQxNbLJf7ardf1dDk2oCQ7Cf", false}, 407 | {"Ky1YjoZNgQ196HJV3HpdkecfhRBmRZdMJk89Hi5KGfpfPwS2bUbfd", false}, 408 | {"2A1q1YsMZowabbvta7kTy2Fd6qN4r5ZCeG3qLpvZBMzCixMUdkN2Y4dHB1wPsZAeVXUGD83MfRED", false}, 409 | {"1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", true}, 410 | {"1Ax4gZtb7gAit2TivwejZHYtNNLT18PUXJ", true}, 411 | {"1C5bSj1iEGUgSTbziymG7Cn18ENQuT36vv", true}, 412 | {"1Gqk4Tv79P91Cc1STQtU3s1W6277M2CVWu", true}, 413 | {"1JwMWBVLtiqtscbaRHai4pqHokhFCbtoB4", true}, 414 | {"19dcawoKcZdQz365WpXWMhX6QCUpR9SY4r", true}, 415 | {"13p1ijLwsnrcuyqcTvJXkq2ASdXqcnEBLE", true}, 416 | {"1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2", true}, 417 | {"3P14159f73E4gFr7JterCCQh9QjiTjiZrG", true}, 418 | {"3CMNFxN1oHBc4R1EpboAL5yzHGgE611Xou", true}, 419 | {"3QjYXhTkvuj8qPaXHTTWb5wjXhdsLAAWVy", true}, 420 | {"3AnNxabYGoTxYiTEZwFEnerUoeFXK2Zoks", true}, 421 | {"33vt8ViH5jsr115AGkW6cEmEz9MpvJSwDk", true}, 422 | {"3QCzvfL4ZRvmJFiWWBVwxfdaNBT8EtxB5y", true}, 423 | {"37Sp6Rv3y4kVd1nQ1JV5pfqXccHNyZm1x3", true}, 424 | {"3ALJH9Y951VCGcVZYAdpA3KchoP9McEj1G", true}, 425 | {"12KYrjTdVGjFMtaxERSk3gphreJ5US8aUP", true}, 426 | {"12QeMLzSrB8XH8FvEzPMVoRxVAzTr5XM2y", true}, 427 | {"1oNLrsHnBcR6dpaBpwz3LSwutbUNkNSjs", true}, 428 | {"1SQHtwR5oJRKLfiWQ2APsAd9miUc4k2ez", true}, 429 | {"116CGDLddrZhMrTwhCVJXtXQpxygTT1kHd", true}, 430 | {"3NJZLcZEEYBpxYEUGewU4knsQRn1WM5Fkt", true}, 431 | }, 432 | }, 433 | FormatTestGroup{ 434 | FormatBitcoinBech32Address, []FormatTest{ 435 | {"", false}, 436 | {"bc1rw5uspcuh", false}, 437 | {"bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5", false}, 438 | {"BC13W508D6QEJXTDG4Y5R3ZARVARY0C5XW7KN40WF2", false}, 439 | {"qw508d6qejxtdg4y5r3zarvary0c5xw7kg3g4ty", false}, 440 | {"bc1rw5uspcuh", false}, 441 | {"bc10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90", false}, 442 | {"BC1QW508d6QEJxTDG4y5R3ZArVARY0C5XW7KV8F3T4", false}, 443 | {"BC1QR508D6QEJXTDG4Y5R3ZARVARYV98GJ9P", false}, 444 | {"bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t5", false}, 445 | {"bc10w508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7kw5rljs90", false}, 446 | {"bc1pw508d6qejxtdg4y5r3zarqfsj6c3", false}, 447 | {"bc1zw508d6qejxtdg4y5r3zarvaryvqyzf3du", false}, 448 | {"bc1gmk9yu", false}, 449 | {"bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3pjxtptv", false}, 450 | {"BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4", true}, 451 | {"bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx", true}, 452 | {"bc1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3qccfmv3", true}, 453 | {"BC1SW50QA3JX3S", true}, 454 | {"bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj", true}, 455 | }, 456 | }, 457 | FormatTestGroup{ 458 | FormatUrnRFC2141, []FormatTest{ 459 | {"urn:a:b", true}, 460 | {"urn:a::", true}, 461 | {"urn:a:-", true}, 462 | {"URN:simple:simple", true}, 463 | {"urn:urna:simple", true}, 464 | {"urn:burnout:nss", true}, 465 | {"urn:burn:nss", true}, 466 | {"urn:urnurnurn:x", true}, 467 | {"urn:abcdefghilmnopqrstuvzabcdefghilm:x", true}, 468 | {"URN:123:x", true}, 469 | {"URN:abcd-:x", true}, 470 | {"URN:abcd-abcd:x", true}, 471 | {"urn:urnx:urn", true}, 472 | {"urn:ciao:a:b:c", true}, 473 | {"urn:aaa:x:y:", true}, 474 | {"urn:ciao:-", true}, 475 | {"urn:colon:::::nss", true}, 476 | {"urn:ciao:@!=%2C(xyz)+a,b.*@g=$_'", true}, 477 | {"URN:hexes:%25", true}, 478 | {"URN:x:abc%1Dz%2F%3az", true}, 479 | {"URN:foo:a123,456", true}, 480 | {"urn:foo:a123,456", true}, 481 | {"urn:FOO:a123,456", true}, 482 | {"urn:foo:A123,456", true}, 483 | {"urn:foo:a123%2C456", true}, 484 | {"URN:FOO:a123%2c456", true}, 485 | {"URN:FOO:ABC%FFabc123%2c456", true}, 486 | {"URN:FOO:ABC%FFabc123%2C456%9A", true}, 487 | {"urn:ietf:params:scim:schemas:core:2.0:User", true}, 488 | {"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:meta.lastModified", true}, 489 | {"URN:-xxx:x", false}, 490 | {"urn::colon:nss", false}, 491 | {"urn:abcdefghilmnopqrstuvzabcdefghilmn:specificstring", false}, 492 | {"URN:a!?:x", false}, 493 | {"URN:#,:x", false}, 494 | {"urn:urn:NSS", false}, 495 | {"urn:URN:NSS", false}, 496 | {"urn:white space:NSS", false}, 497 | {"urn:concat:no spaces", false}, 498 | {"urn:a:%", false}, 499 | {"urn:", false}, 500 | }, 501 | }, 502 | FormatTestGroup{ 503 | FormatURL, []FormatTest{ 504 | {"http://foo.bar#com", true}, 505 | {"http://foobar.com", true}, 506 | {"https://foobar.com", true}, 507 | {"foobar.com", false}, 508 | {"http://foobar.coffee/", true}, 509 | {"http://foobar.中文网/", true}, 510 | {"http://foobar.org/", true}, 511 | {"http://foobar.org:8080/", true}, 512 | {"ftp://foobar.ru/", true}, 513 | {"http://user:pass@www.foobar.com/", true}, 514 | {"http://127.0.0.1/", true}, 515 | {"http://duckduckgo.com/?q=%2F", true}, 516 | {"http://localhost:3000/", true}, 517 | {"http://foobar.com/?foo=bar#baz=qux", true}, 518 | {"http://foobar.com?foo=bar", true}, 519 | {"http://www.xn--froschgrn-x9a.net/", true}, 520 | {"", false}, 521 | {"xyz://foobar.com", true}, 522 | {"invalid.", false}, 523 | {".com", false}, 524 | {"rtmp://foobar.com", true}, 525 | {"http://www.foo_bar.com/", true}, 526 | {"http://localhost:3000/", true}, 527 | {"http://foobar.com/#baz", true}, 528 | {"http://foobar.com#baz=qux", true}, 529 | {"http://foobar.com/t$-_.+!*\\'(),", true}, 530 | {"http://www.foobar.com/~foobar", true}, 531 | {"http://www.-foobar.com/", true}, 532 | {"http://www.foo---bar.com/", true}, 533 | {"mailto:someone@example.com", true}, 534 | {"irc://irc.server.org/channel", true}, 535 | {"irc://#channel@network", true}, 536 | {"/abs/test/dir", false}, 537 | {"./rel/test/dir", false}, 538 | }, 539 | }, 540 | FormatTestGroup{ 541 | FormatURI, []FormatTest{ 542 | {"http://foo.bar#com", true}, 543 | {"http://foobar.com", true}, 544 | {"https://foobar.com", true}, 545 | {"foobar.com", false}, 546 | {"http://foobar.coffee/", true}, 547 | {"http://foobar.中文网/", true}, 548 | {"http://foobar.org/", true}, 549 | {"http://foobar.org:8080/", true}, 550 | {"ftp://foobar.ru/", true}, 551 | {"http://user:pass@www.foobar.com/", true}, 552 | {"http://127.0.0.1/", true}, 553 | {"http://duckduckgo.com/?q=%2F", true}, 554 | {"http://localhost:3000/", true}, 555 | {"http://foobar.com/?foo=bar#baz=qux", true}, 556 | {"http://foobar.com?foo=bar", true}, 557 | {"http://www.xn--froschgrn-x9a.net/", true}, 558 | {"", false}, 559 | {"xyz://foobar.com", true}, 560 | {"invalid.", false}, 561 | {".com", false}, 562 | {"rtmp://foobar.com", true}, 563 | {"http://www.foo_bar.com/", true}, 564 | {"http://localhost:3000/", true}, 565 | {"http://foobar.com#baz=qux", true}, 566 | {"http://foobar.com/t$-_.+!*\\'(),", true}, 567 | {"http://www.foobar.com/~foobar", true}, 568 | {"http://www.-foobar.com/", true}, 569 | {"http://www.foo---bar.com/", true}, 570 | {"mailto:someone@example.com", true}, 571 | {"irc://irc.server.org/channel", true}, 572 | {"irc://#channel@network", true}, 573 | {"/abs/test/dir", true}, 574 | {"./rel/test/dir", false}, 575 | }, 576 | }, 577 | FormatTestGroup{ 578 | FormatHSLA, []FormatTest{ 579 | {"hsla(360,100%,100%,1)", true}, 580 | {"hsla(360,100%,100%,0.5)", true}, 581 | {"hsla(0,0%,0%, 0)", true}, 582 | {"hsl(361,100%,50%,1)", false}, 583 | {"hsl(361,100%,50%)", false}, 584 | {"hsla(361,100%,50%)", false}, 585 | {"hsla(360,101%,50%)", false}, 586 | {"hsla(360,100%,101%)", false}, 587 | }, 588 | }, 589 | FormatTestGroup{ 590 | FormatHSL, []FormatTest{ 591 | {"hsl(360,100%,50%)", true}, 592 | {"hsl(0,0%,0%)", true}, 593 | {"hsl(361,100%,50%)", false}, 594 | {"hsl(361,101%,50%)", false}, 595 | {"hsl(361,100%,101%)", false}, 596 | {"hsl(-10,100%,100%)", false}, 597 | }, 598 | }, 599 | FormatTestGroup{ 600 | FormatRGBA, []FormatTest{ 601 | {"rgba(0,31,255,0.5)", true}, 602 | {"rgba(0,31,255,0.12)", true}, 603 | {"rgba(12%,55%,100%,0.12)", true}, 604 | {"rgba( 0, 31, 255, 0.5)", true}, 605 | {"rgba(12%,55,100%,0.12)", false}, 606 | {"rgb(0, 31, 255)", false}, 607 | {"rgb(1,349,275,0.5)", false}, 608 | {"rgb(01,31,255,0.5)", false}, 609 | }, 610 | }, 611 | FormatTestGroup{ 612 | FormatRGB, []FormatTest{ 613 | {"rgb(0,31,255)", true}, 614 | {"rgb(0, 31, 255)", true}, 615 | {"rgb(10%, 50%, 100%)", true}, 616 | {"rgb(10%, 50%, 55)", false}, 617 | {"rgb(1,349,275)", false}, 618 | {"rgb(01,31,255)", false}, 619 | {"rgba(0,31,255)", false}, 620 | }, 621 | }, 622 | FormatTestGroup{ 623 | FormatEmail, []FormatTest{ 624 | {"test@mail.com", true}, 625 | {"Dörte@Sörensen.example.com", true}, 626 | {"θσερ@εχαμπλε.ψομ", true}, 627 | {"юзер@екзампл.ком", true}, 628 | {"उपयोगकर्ता@उदाहरण.कॉम", true}, 629 | {"用户@例子.广告", true}, 630 | {"mail@domain_with_underscores.org", false}, 631 | {"", false}, 632 | {"test@email", false}, 633 | {"test@email.", false}, 634 | {"@email.com", false}, 635 | {`"test test"@email.com`, true}, 636 | {`"@email.com`, false}, 637 | }, 638 | }, 639 | FormatTestGroup{ 640 | FormatHEXColor, []FormatTest{ 641 | {"#fff", true}, 642 | {"#c2c2c2", true}, 643 | {"fff", false}, 644 | {"fffFF", false}, 645 | {"", false}, 646 | }, 647 | }, 648 | FormatTestGroup{ 649 | FormatHexadecimal, []FormatTest{ 650 | {"ff0044", true}, 651 | {"abcdefg", false}, 652 | }, 653 | }, 654 | FormatTestGroup{ 655 | FormatNumber, []FormatTest{ 656 | {"1", true}, 657 | {"+1", true}, 658 | {"-1", true}, 659 | {"1.12", true}, 660 | {"+1.12", true}, 661 | {"-1.12", true}, 662 | {"1.", false}, 663 | {"1.o", false}, 664 | {"", false}, 665 | }, 666 | }, 667 | FormatTestGroup{ 668 | FormatNumeric, []FormatTest{ 669 | {"1", true}, 670 | {"+1", false}, 671 | {"-1", false}, 672 | {"1.12", false}, 673 | {"+1.12", false}, 674 | {"-1.12", false}, 675 | {"1.", false}, 676 | {"1.o", false}, 677 | {"", false}, 678 | }, 679 | }, 680 | FormatTestGroup{ 681 | FormatAlnum, []FormatTest{ 682 | {"abcd123", true}, 683 | {"abc!23", false}, 684 | {"", false}, 685 | }, 686 | }, 687 | FormatTestGroup{ 688 | FormatAlpha, []FormatTest{ 689 | {"abcd", true}, 690 | {"abc®", false}, 691 | {"abc÷", false}, 692 | {"abc1", false}, 693 | {"this is a test string", false}, 694 | {"", false}, 695 | }, 696 | }, 697 | FormatTestGroup{ 698 | FormatAlnumUnicode, []FormatTest{ 699 | {"", false}, 700 | {"abc", true}, 701 | {"this is a test string", false}, 702 | {"这是一个测试字符串", true}, 703 | {"\u0031\u0032\u0033", true}, // unicode 5 704 | {"123", true}, 705 | {"<>@;.-=", false}, 706 | {"ひらがな・カタカナ、.漢字", false}, 707 | {"あいうえおfoobar", true}, 708 | {"test@example.com", false}, 709 | {"1234abcDE", true}, 710 | {"カタカナ", true}, 711 | }, 712 | }, 713 | FormatTestGroup{ 714 | FormatAlphaUnicode, []FormatTest{ 715 | {"", false}, 716 | {"abc", true}, 717 | {"this is a test string", false}, 718 | {"这是一个测试字符串", true}, 719 | {"123", false}, 720 | {"<>@;.-=", false}, 721 | {"ひらがな・カタカナ、.漢字", false}, 722 | {"あいうえおfoobar", true}, 723 | {"test@example.com", false}, 724 | {"1234abcDE", false}, 725 | {"カタカナ", true}, 726 | }, 727 | }, 728 | FormatTestGroup{ 729 | FormatHostnameRFC952, []FormatTest{ 730 | {"test.example.com", true}, 731 | {"example.com", true}, 732 | {"example24.com", true}, 733 | {"test.example24.com", true}, 734 | {"test24.example24.com", true}, 735 | {"example", true}, 736 | {"EXAMPLE", true}, 737 | {"1.foo.com", false}, 738 | {"test.example.com.", false}, 739 | {"example.com.", false}, 740 | {"example24.com.", false}, 741 | {"test.example24.com.", false}, 742 | {"test24.example24.com.", false}, 743 | {"example.", false}, 744 | {"192.168.0.1", false}, 745 | {"email@example.com", false}, 746 | {"2001:cdba:0000:0000:0000:0000:3257:9652", false}, 747 | {"2001:cdba:0:0:0:0:3257:9652", false}, 748 | {"2001:cdba::3257:9652", false}, 749 | }, 750 | }, 751 | FormatTestGroup{ 752 | FormatHostnameRFC1123, []FormatTest{ 753 | {"test.example.com", true}, 754 | {"example.com", true}, 755 | {"example24.com", true}, 756 | {"test.example24.com", true}, 757 | {"test24.example24.com", true}, 758 | {"example", true}, 759 | {"1.foo.com", true}, 760 | {"test.example.com.", false}, 761 | {"example.com.", false}, 762 | {"example24.com.", false}, 763 | {"test.example24.com.", false}, 764 | {"test24.example24.com.", false}, 765 | {"example.", false}, 766 | {"192.168.0.1", true}, 767 | {"email@example.com", false}, 768 | {"2001:cdba:0000:0000:0000:0000:3257:9652", false}, 769 | {"2001:cdba:0:0:0:0:3257:9652", false}, 770 | {"2001:cdba::3257:9652", false}, 771 | }, 772 | }, 773 | FormatTestGroup{ 774 | FormatFQDN, []FormatTest{ 775 | {"test.example.com", true}, 776 | {"example.com", true}, 777 | {"example24.com", true}, 778 | {"test.example24.com", true}, 779 | {"test24.example24.com", true}, 780 | {"test.example.com.", true}, 781 | {"example.com.", true}, 782 | {"example24.com.", true}, 783 | {"test.example24.com.", true}, 784 | {"test24.example24.com.", true}, 785 | {"test24.example24.com..", false}, 786 | {"example", false}, 787 | {"192.168.0.1", false}, 788 | {"email@example.com", false}, 789 | {"2001:cdba:0000:0000:0000:0000:3257:9652", false}, 790 | {"2001:cdba:0:0:0:0:3257:9652", false}, 791 | {"2001:cdba::3257:9652", false}, 792 | {"", false}, 793 | }, 794 | }, 795 | FormatTestGroup{ 796 | FormatURLEncoded, []FormatTest{ 797 | {"%20", true}, 798 | {"%af", true}, 799 | {"%ff", true}, 800 | {"<%az", false}, 801 | {"%test%", false}, 802 | {"a%b", false}, 803 | {"1%2", false}, 804 | {"%%a%%", false}, 805 | }, 806 | }, 807 | FormatTestGroup{ 808 | FormatPostcode, []FormatTest{ 809 | {"PO32 6QN", true}, 810 | {"PO30 1JQ", true}, 811 | {"WC2H", false}, 812 | {"WC2H 7LTa", false}, 813 | }, 814 | }, 815 | } 816 | } 817 | 818 | func Test(t *testing.T) { 819 | groups := getFormatTestGroups() 820 | formatTypeMap := getFormatTypeMap() 821 | 822 | for _, group := range groups { 823 | for _, test := range group.Tests { 824 | if result := formatTypeMap[group.Type](test.Sample); result != test.Result { 825 | t.Errorf("%v format validator does not validate sample \"%v\", exected %v.", group.Type, test.Sample, test.Result) 826 | } 827 | } 828 | } 829 | } 830 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module gopkg.in/dealancer/validate.v2 2 | 3 | go 1.11 4 | 5 | require ( 6 | github.com/leodido/go-urn v1.1.0 7 | github.com/stretchr/testify v1.3.0 // indirect 8 | ) 9 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8= 4 | github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= 5 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 6 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 7 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 8 | github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= 9 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 10 | -------------------------------------------------------------------------------- /regexes.go: -------------------------------------------------------------------------------- 1 | package validate 2 | 3 | import "regexp" 4 | 5 | const ( 6 | alphaRegexString = "^[a-zA-Z]+$" 7 | alnumRegexString = "^[a-zA-Z0-9]+$" 8 | alphaUnicodeRegexString = "^[\\p{L}]+$" 9 | alnumUnicodeRegexString = "^[\\p{L}\\p{N}]+$" 10 | numericRegexString = "^[0-9]+$" 11 | numberRegexString = "^[-+]?[0-9]+(?:\\.[0-9]+)?$" 12 | hexadecimalRegexString = "^[0-9a-fA-F]+$" 13 | hexcolorRegexString = "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$" 14 | rgbRegexString = "^rgb\\(\\s*(?:(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])|(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%)\\s*\\)$" 15 | rgbaRegexString = "^rgba\\(\\s*(?:(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])|(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%)\\s*,\\s*(?:(?:0.[1-9]*)|[01])\\s*\\)$" 16 | hslRegexString = "^hsl\\(\\s*(?:0|[1-9]\\d?|[12]\\d\\d|3[0-5]\\d|360)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*\\)$" 17 | hslaRegexString = "^hsla\\(\\s*(?:0|[1-9]\\d?|[12]\\d\\d|3[0-5]\\d|360)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0.[1-9]*)|[01])\\s*\\)$" 18 | emailRegexString = "^(?:(?:(?:(?:[a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(?:\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|(?:(?:\\x22)(?:(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(?:\\x20|\\x09)+)?(?:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(\\x20|\\x09)+)?(?:\\x22))))@(?:(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$" 19 | base64RegexString = "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$" 20 | base64URLRegexString = "^(?:[A-Za-z0-9-_]{4})*(?:[A-Za-z0-9-_]{2}==|[A-Za-z0-9-_]{3}=|[A-Za-z0-9-_]{4})$" 21 | iSBN10RegexString = "^(?:[0-9]{9}X|[0-9]{10})$" 22 | iSBN13RegexString = "^(?:(?:97(?:8|9))[0-9]{10})$" 23 | uUID3RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-3[0-9a-fA-F]{3}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" 24 | uUID4RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" 25 | uUID5RegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-5[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$" 26 | uUIDRegexString = "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" 27 | aSCIIRegexString = "^[\x00-\x7F]*$" 28 | printableASCIIRegexString = "^[\x20-\x7E]*$" 29 | dataURIRegexString = "^data:.+\\/(.+);base64$" 30 | latitudeRegexString = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$" 31 | longitudeRegexString = "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$" 32 | sSNRegexString = `^[0-9]{3}[ -]?(0[1-9]|[1-9][0-9])[ -]?([1-9][0-9]{3}|[0-9][1-9][0-9]{2}|[0-9]{2}[1-9][0-9]|[0-9]{3}[1-9])$` 33 | hostnameRegexStringRFC952 = `^[a-zA-Z][a-zA-Z0-9\-\.]+[a-zA-Z0-9]$` // https://tools.ietf.org/html/rfc952 34 | hostnameRegexStringRFC1123 = `^[a-zA-Z0-9][a-zA-Z0-9\-\.]+[a-zA-Z0-9]$` // accepts hostname starting with a digit https://tools.ietf.org/html/rfc1123 35 | btcAddressRegexString = `^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$` // bitcoin address 36 | btcAddressUpperRegexStringBech32 = `^BC1[02-9AC-HJ-NP-Z]{7,76}$` // bitcoin bech32 address https://en.bitcoin.it/wiki/Bech32 37 | btcAddressLowerRegexStringBech32 = `^bc1[02-9ac-hj-np-z]{7,76}$` // bitcoin bech32 address https://en.bitcoin.it/wiki/Bech32 38 | ethAddressRegexString = `^0x[0-9a-fA-F]{40}$` 39 | ethAddressUpperRegexString = `^0x[0-9A-F]{40}$` 40 | ethAddressLowerRegexString = `^0x[0-9a-f]{40}$` 41 | uRLEncodedRegexString = `(%[A-Fa-f0-9]{2})` 42 | postcodeRegexString = `^([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9]?[A-Za-z])))) [0-9][A-Za-z]{2})$` //https://stackoverflow.com/questions/164979/regex-for-matching-uk-postcodes/51885364#51885364 43 | ) 44 | 45 | var ( 46 | alphaRegex = regexp.MustCompile(alphaRegexString) 47 | alnumRegex = regexp.MustCompile(alnumRegexString) 48 | alphaUnicodeRegex = regexp.MustCompile(alphaUnicodeRegexString) 49 | alnumUnicodeRegex = regexp.MustCompile(alnumUnicodeRegexString) 50 | numericRegex = regexp.MustCompile(numericRegexString) 51 | numberRegex = regexp.MustCompile(numberRegexString) 52 | hexadecimalRegex = regexp.MustCompile(hexadecimalRegexString) 53 | hexcolorRegex = regexp.MustCompile(hexcolorRegexString) 54 | rgbRegex = regexp.MustCompile(rgbRegexString) 55 | rgbaRegex = regexp.MustCompile(rgbaRegexString) 56 | hslRegex = regexp.MustCompile(hslRegexString) 57 | hslaRegex = regexp.MustCompile(hslaRegexString) 58 | emailRegex = regexp.MustCompile(emailRegexString) 59 | base64Regex = regexp.MustCompile(base64RegexString) 60 | base64URLRegex = regexp.MustCompile(base64URLRegexString) 61 | iSBN10Regex = regexp.MustCompile(iSBN10RegexString) 62 | iSBN13Regex = regexp.MustCompile(iSBN13RegexString) 63 | uUID3Regex = regexp.MustCompile(uUID3RegexString) 64 | uUID4Regex = regexp.MustCompile(uUID4RegexString) 65 | uUID5Regex = regexp.MustCompile(uUID5RegexString) 66 | uUIDRegex = regexp.MustCompile(uUIDRegexString) 67 | aSCIIRegex = regexp.MustCompile(aSCIIRegexString) 68 | printableASCIIRegex = regexp.MustCompile(printableASCIIRegexString) 69 | dataURIRegex = regexp.MustCompile(dataURIRegexString) 70 | latitudeRegex = regexp.MustCompile(latitudeRegexString) 71 | longitudeRegex = regexp.MustCompile(longitudeRegexString) 72 | sSNRegex = regexp.MustCompile(sSNRegexString) 73 | hostnameRegexRFC952 = regexp.MustCompile(hostnameRegexStringRFC952) 74 | hostnameRegexRFC1123 = regexp.MustCompile(hostnameRegexStringRFC1123) 75 | btcAddressRegex = regexp.MustCompile(btcAddressRegexString) 76 | btcUpperAddressRegexBech32 = regexp.MustCompile(btcAddressUpperRegexStringBech32) 77 | btcLowerAddressRegexBech32 = regexp.MustCompile(btcAddressLowerRegexStringBech32) 78 | ethAddressRegex = regexp.MustCompile(ethAddressRegexString) 79 | ethAddressRegexUpper = regexp.MustCompile(ethAddressUpperRegexString) 80 | ethAddressRegexLower = regexp.MustCompile(ethAddressLowerRegexString) 81 | uRLEncodedRegex = regexp.MustCompile(uRLEncodedRegexString) 82 | postcodeRegex = regexp.MustCompile(postcodeRegexString) 83 | ) 84 | -------------------------------------------------------------------------------- /testdata/a.go: -------------------------------------------------------------------------------- 1 | package testdata 2 | -------------------------------------------------------------------------------- /validate.go: -------------------------------------------------------------------------------- 1 | package validate 2 | 3 | import ( 4 | "reflect" 5 | "regexp" 6 | "strings" 7 | ) 8 | 9 | // MasterTag is the main validation tag. 10 | const MasterTag = "validate" 11 | 12 | // CustomValidator is an interface for a validated struct. 13 | type CustomValidator interface { 14 | 15 | // Validate is a custom validation function. 16 | // Validate does not work when the receiver is a reference. 17 | // Validate does not work for nested types obtained from unexported field. 18 | Validate() error 19 | } 20 | 21 | // Validate validates fields of a struct. 22 | // It accepts a struct or a struct pointer as a parameter. 23 | // It returns an error if a struct does not validate or nil if there are no validation errors. 24 | // 25 | // err := validate.Validate(struct { 26 | // field time.Duration `validate:"gte=0s"` 27 | // }{ 28 | // field: -time.Second, 29 | // }) 30 | // 31 | // // err contains an error 32 | func Validate(element interface{}) error { 33 | value := reflect.ValueOf(element) 34 | 35 | return validateField(value, "", "") 36 | } 37 | 38 | // validateField validates a struct field 39 | func validateField(value reflect.Value, fieldName string, validators string) error { 40 | kind := value.Kind() 41 | 42 | // Get validator type Map 43 | validatorTypeMap := getValidatorTypeMap() 44 | 45 | // Get validators 46 | keyValidators, valueValidators, validators, err := splitValidators(validators) 47 | if err != nil { 48 | err = setFieldName(err, fieldName) 49 | return err 50 | } 51 | 52 | // Call a custom validator 53 | if err := callCustomValidator(value); err != nil { 54 | return err 55 | } 56 | 57 | // Parse validators 58 | validatorsOr, err := parseValidators(valueValidators) 59 | if err != nil { 60 | err = setFieldName(err, fieldName) 61 | return err 62 | } 63 | 64 | // Perform validators 65 | for _, validatorsAnd := range validatorsOr { 66 | for _, validator := range validatorsAnd { 67 | if validatorFunc, ok := validatorTypeMap[validator.Type]; ok { 68 | if err = validatorFunc(value, validator.Value); err != nil { 69 | err = setFieldName(err, fieldName) 70 | break 71 | } 72 | } else { 73 | return ErrorSyntax{ 74 | fieldName: fieldName, 75 | expression: string(validator.Type), 76 | near: valueValidators, 77 | comment: "could not find a validator", 78 | } 79 | } 80 | } 81 | if err == nil { 82 | break 83 | } 84 | } 85 | if err != nil { 86 | return err 87 | } 88 | 89 | // Dive one level deep into arrays and pointers 90 | switch kind { 91 | case reflect.Struct: 92 | if err := validateStruct(value); err != nil { 93 | return err 94 | } 95 | case reflect.Map: 96 | for _, key := range value.MapKeys() { 97 | if err := validateField(key, fieldName, keyValidators); err != nil { 98 | return err 99 | } 100 | if err := validateField(value.MapIndex(key), fieldName, validators); err != nil { 101 | return err 102 | } 103 | } 104 | case reflect.Slice, reflect.Array: 105 | for i := 0; i < value.Len(); i++ { 106 | if err := validateField(value.Index(i), fieldName, validators); err != nil { 107 | return err 108 | } 109 | } 110 | case reflect.Ptr: 111 | if !value.IsNil() { 112 | if err := validateField(value.Elem(), fieldName, validators); err != nil { 113 | return err 114 | } 115 | } 116 | } 117 | 118 | if kind != reflect.Map { 119 | if len(keyValidators) > 0 { 120 | return ErrorSyntax{ 121 | fieldName: fieldName, 122 | expression: validators, 123 | near: "", 124 | comment: "unexpexted expression", 125 | } 126 | } 127 | } 128 | 129 | if kind != reflect.Map && kind != reflect.Slice && kind != reflect.Array && kind != reflect.Ptr { 130 | if len(validators) > 0 { 131 | return ErrorSyntax{ 132 | fieldName: fieldName, 133 | expression: validators, 134 | near: "", 135 | comment: "unexpexted expression", 136 | } 137 | } 138 | } 139 | 140 | return nil 141 | } 142 | 143 | // validateStruct validates a struct 144 | func validateStruct(value reflect.Value) error { 145 | typ := value.Type() 146 | 147 | // Iterate over struct fields 148 | for i := 0; i < typ.NumField(); i++ { 149 | validators := getValidators(typ.Field(i).Tag) 150 | fieldName := typ.Field(i).Name 151 | if err := validateField(value.Field(i), fieldName, validators); err != nil { 152 | return err 153 | } 154 | } 155 | 156 | return nil 157 | } 158 | 159 | // getValidators gets validators 160 | func getValidators(tag reflect.StructTag) string { 161 | return tag.Get(MasterTag) 162 | } 163 | 164 | // splitValidators splits validators into key validators, value validators and remaning validators of the next level 165 | func splitValidators(validators string) (keyValidators string, valValidators string, remaningValidators string, err ErrorField) { 166 | gt := 0 167 | bracket := 0 168 | bracketStart := 0 169 | bracketEnd := -1 170 | 171 | i := 0 172 | loop: 173 | for ; i < len(validators); i++ { 174 | switch validators[i] { 175 | case '>': 176 | if bracket == 0 { 177 | gt++ 178 | break loop 179 | } 180 | case '[': 181 | if bracket == 0 { 182 | bracketStart = i 183 | } 184 | bracket++ 185 | case ']': 186 | bracket-- 187 | if bracket == 0 { 188 | bracketEnd = i 189 | } 190 | } 191 | } 192 | 193 | if bracket > 0 { 194 | err = ErrorSyntax{ 195 | expression: "", 196 | near: validators, 197 | comment: "expected \"]\"", 198 | } 199 | return 200 | } else if bracket < 0 { 201 | err = ErrorSyntax{ 202 | expression: "", 203 | near: validators, 204 | comment: "unexpected \"]\"", 205 | } 206 | return 207 | } 208 | 209 | if bracketStart <= len(validators) { 210 | valValidators += validators[:bracketStart] 211 | } 212 | if bracketEnd+1 <= len(validators) { 213 | if valValidators != "" { 214 | valValidators += " " 215 | } 216 | valValidators += validators[bracketEnd+1 : i] 217 | } 218 | if bracketStart+1 <= len(validators) && bracketEnd >= 0 && bracketStart+1 <= bracketEnd { 219 | keyValidators = validators[bracketStart+1 : bracketEnd] 220 | } 221 | if i+1 <= len(validators) { 222 | remaningValidators = validators[i+1:] 223 | } 224 | 225 | if gt > 0 && len(remaningValidators) == 0 { 226 | err = ErrorSyntax{ 227 | expression: "", 228 | near: validators, 229 | comment: "expected expression", 230 | } 231 | return 232 | } 233 | 234 | return 235 | } 236 | 237 | // parseValidator parses validators into the slice of slices. 238 | // First slice acts as AND logic, second array acts as OR logic. 239 | func parseValidators(validators string) (validatorsOr [][]validator, err ErrorField) { 240 | regexpType := regexp.MustCompile(`[[:alnum:]_]+`) 241 | regexpValue := regexp.MustCompile(`[^=\s]+[^=]*[^=\s]+|[^=\s]+`) 242 | 243 | if len(validators) == 0 { 244 | return 245 | } 246 | 247 | entriesOr := strings.Split(validators, "|") 248 | validatorsOr = make([][]validator, 0, len(entriesOr)) 249 | for _, entryOr := range entriesOr { 250 | entriesAnd := strings.Split(entryOr, "&") 251 | validatorsAnd := make([]validator, 0, len(entriesAnd)) 252 | for _, entryOr := range entriesAnd { 253 | entries := strings.Split(entryOr, "=") 254 | if len(entries) == 0 || len(entries) > 2 { 255 | err = ErrorSyntax{ 256 | expression: validators, 257 | comment: "could not parse", 258 | } 259 | return 260 | } 261 | t := regexpType.FindString(entries[0]) 262 | if len(t) == 0 { 263 | err = ErrorSyntax{ 264 | expression: entries[0], 265 | near: validators, 266 | comment: "could not parse", 267 | } 268 | return 269 | } 270 | v := "" 271 | if len(entries) == 2 { 272 | v = regexpValue.FindString(entries[1]) 273 | } 274 | validatorsAnd = append(validatorsAnd, validator{ValidatorType(t), v}) 275 | } 276 | if len(validatorsAnd) > 0 { 277 | validatorsOr = append(validatorsOr, validatorsAnd) 278 | } 279 | } 280 | 281 | return 282 | } 283 | 284 | // parseTokens parses tokens into array 285 | func parseTokens(str string) []interface{} { 286 | tokenStrings := strings.Split(str, ",") 287 | tokens := make([]interface{}, 0, len(tokenStrings)) 288 | 289 | for i := range tokenStrings { 290 | token := strings.TrimSpace(tokenStrings[i]) 291 | if token != "" { 292 | tokens = append(tokens, token) 293 | } 294 | } 295 | 296 | return tokens 297 | } 298 | 299 | // tokenOneOf check if a token is one of tokens 300 | func tokenOneOf(token interface{}, tokens []interface{}) bool { 301 | for _, t := range tokens { 302 | if t == token { 303 | return true 304 | } 305 | } 306 | 307 | return false 308 | } 309 | 310 | // Call a custom validator 311 | func callCustomValidator(value reflect.Value) error { 312 | if !value.CanInterface() { 313 | return nil 314 | } 315 | 316 | // Following code won't work in case if Validate is implemented by reference and value is passed by value 317 | if customValidator, ok := value.Interface().(CustomValidator); ok { 318 | return customValidator.Validate() 319 | } 320 | 321 | // Following code is a fallbak if value is passed by value 322 | valueCopyPointer := reflect.New(value.Type()) 323 | valueCopyPointer.Elem().Set(value) 324 | if customValidator, ok := valueCopyPointer.Interface().(CustomValidator); ok { 325 | return customValidator.Validate() 326 | } 327 | 328 | return nil 329 | } 330 | -------------------------------------------------------------------------------- /validate_test.go: -------------------------------------------------------------------------------- 1 | package validate 2 | 3 | import ( 4 | "errors" 5 | "reflect" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestSplitValidators(t *testing.T) { 11 | key, val, validators := "", "", "" 12 | 13 | key, val, validators, _ = splitValidators("") 14 | if key != "" || val != "" || validators != "" { 15 | t.Errorf("splitValidators incorrectly splits validators") 16 | } 17 | 18 | key, val, validators, _ = splitValidators("[]>") 19 | if key != "" || val != "" || validators != "" { 20 | t.Errorf("splitValidators incorrectly splits validators") 21 | } 22 | 23 | key, val, validators, _ = splitValidators(" [ ] > ") 24 | if key != " " || val != " " || validators != " " { 25 | t.Errorf("splitValidators incorrectly splits validators") 26 | } 27 | 28 | key, val, validators, _ = splitValidators("[[>]]>>") 29 | if key != "[>]" || val != "" || validators != ">" { 30 | t.Errorf("splitValidators incorrectly splits validators") 31 | } 32 | 33 | key, val, validators, _ = splitValidators("val_a=a val_b=b") 34 | if key != "" || val != "val_a=a val_b=b" || validators != "" { 35 | t.Errorf("splitValidators incorrectly splits validators") 36 | } 37 | 38 | key, val, validators, _ = splitValidators("val_a=a val_b=b [[val_c=c] > val_d=d] val_e=e > val_f=f [val_g=g] > val_h=h") 39 | if key != "[val_c=c] > val_d=d" || val != "val_a=a val_b=b val_e=e " || validators != " val_f=f [val_g=g] > val_h=h" { 40 | t.Errorf("splitValidators incorrectly splits validators") 41 | } 42 | } 43 | 44 | func TestParseValidators(t *testing.T) { 45 | var validatorsOr [][]validator 46 | 47 | validatorsOr, _ = parseValidators("") 48 | if len(validatorsOr) > 0 { 49 | t.Errorf("parseValidators incorrectly parses validators") 50 | } 51 | 52 | validatorsOr, _ = parseValidators("&|&,&") 53 | if len(validatorsOr) > 0 { 54 | t.Errorf("parseValidators incorrectly parses validators") 55 | } 56 | 57 | validatorsOr, _ = parseValidators("val_a=a") 58 | if !reflect.DeepEqual(validatorsOr, [][]validator{ 59 | []validator{ 60 | validator{ 61 | ValidatorType("val_a"), 62 | "a", 63 | }, 64 | }, 65 | }) { 66 | t.Errorf("parseValidators incorrectly parses validators") 67 | } 68 | 69 | validatorsOr, _ = parseValidators(" val |val_a=a|val_1 = 1 | val_b = b , c_d_ , 1.0 |VAL = V A L U E ¶ ") 70 | if !reflect.DeepEqual(validatorsOr, [][]validator{ 71 | []validator{ 72 | validator{ 73 | ValidatorType("val"), 74 | "", 75 | }, 76 | }, 77 | []validator{ 78 | validator{ 79 | ValidatorType("val_a"), 80 | "a", 81 | }, 82 | }, 83 | []validator{ 84 | validator{ 85 | ValidatorType("val_1"), 86 | "1", 87 | }, 88 | }, 89 | []validator{ 90 | validator{ 91 | ValidatorType("val_b"), 92 | "b , c_d_ , 1.0", 93 | }, 94 | }, 95 | []validator{ 96 | validator{ 97 | ValidatorType("VAL"), 98 | "V A L U E ¶", 99 | }, 100 | }, 101 | }) { 102 | t.Errorf("parseValidators incorrectly parses validators") 103 | } 104 | 105 | validatorsOr, _ = parseValidators(" val &val_a=a|val_1 = 1 & val_b = b , c_d_ , 1.0 &VAL = V A L U E ¶ ") 106 | if !reflect.DeepEqual(validatorsOr, [][]validator{ 107 | []validator{ 108 | validator{ 109 | ValidatorType("val"), 110 | "", 111 | }, 112 | validator{ 113 | ValidatorType("val_a"), 114 | "a", 115 | }, 116 | }, 117 | []validator{ 118 | validator{ 119 | ValidatorType("val_1"), 120 | "1", 121 | }, 122 | validator{ 123 | ValidatorType("val_b"), 124 | "b , c_d_ , 1.0", 125 | }, 126 | validator{ 127 | ValidatorType("VAL"), 128 | "V A L U E ¶", 129 | }, 130 | }, 131 | }) { 132 | t.Errorf("parseValidators incorrectly parses validators") 133 | } 134 | } 135 | 136 | func TestParseTokens(t *testing.T) { 137 | var tokens, res []interface{} 138 | 139 | tokens = parseTokens("") 140 | if !reflect.DeepEqual(tokens, make([]interface{}, 0)) { 141 | t.Errorf("parseTokens incorrectly parses validators") 142 | } 143 | 144 | tokens = parseTokens(" ,, , ") 145 | if !reflect.DeepEqual(tokens, make([]interface{}, 0)) { 146 | t.Errorf("parseTokens incorrectly parses validators") 147 | } 148 | 149 | tokens = parseTokens("a, b, c") 150 | res = make([]interface{}, 3) 151 | res[0] = "a" 152 | res[1] = "b" 153 | res[2] = "c" 154 | if !reflect.DeepEqual(tokens, res) { 155 | t.Errorf("parseTokens incorrectly parses validators") 156 | } 157 | } 158 | 159 | func TestBasic(t *testing.T) { 160 | type St struct { 161 | field int 162 | } 163 | st := St{ 164 | field: 1, 165 | } 166 | if nil != Validate(st) { 167 | t.Errorf("validate does not validate struct type") 168 | } 169 | if nil != Validate(&st) { 170 | t.Errorf("validate does not validate struct pointer type") 171 | } 172 | if nil != Validate(map[int]St{ 173 | 0: st, 174 | }) { 175 | t.Errorf("validate does not validate map of struct type") 176 | } 177 | if nil != Validate(map[St]int{ 178 | st: 0, 179 | }) { 180 | t.Errorf("validate does not validate map of struct type") 181 | } 182 | if nil != Validate([]St{ 183 | st, 184 | }) { 185 | t.Errorf("validate does not validate slice of struct type") 186 | } 187 | if nil != Validate([1]St{ 188 | st, 189 | }) { 190 | t.Errorf("validate does not validate slice of struct type") 191 | } 192 | 193 | type StFail struct { 194 | field int `validate:"lte=0"` 195 | } 196 | stFail := StFail{ 197 | field: 1, 198 | } 199 | if nil == Validate(stFail) { 200 | t.Errorf("validate does not validate struct type") 201 | } 202 | if nil == Validate(&stFail) { 203 | t.Errorf("validate does not validate struct pointer type") 204 | } 205 | if nil == Validate(map[int]StFail{ 206 | 0: stFail, 207 | }) { 208 | t.Errorf("validate does not validate map of struct type") 209 | } 210 | if nil == Validate(map[StFail]int{ 211 | stFail: 0, 212 | }) { 213 | t.Errorf("validate does not validate map of struct type") 214 | } 215 | if nil == Validate([]StFail{ 216 | stFail, 217 | }) { 218 | t.Errorf("validate does not validate slice of struct type") 219 | } 220 | if nil == Validate([1]StFail{ 221 | stFail, 222 | }) { 223 | t.Errorf("validate does not validate slice of struct type") 224 | } 225 | 226 | type StAnotherFail struct { 227 | a int 228 | b int 229 | field int `validate:"lte=0"` 230 | c int 231 | d int 232 | } 233 | stAnotherFail := StAnotherFail{ 234 | field: 1, 235 | } 236 | if nil == Validate(stAnotherFail) { 237 | t.Errorf("validate does not validate struct type") 238 | } 239 | if nil == Validate(&stAnotherFail) { 240 | t.Errorf("validate does not validate struct pointer type") 241 | } 242 | if nil == Validate(map[int]StAnotherFail{ 243 | 0: stAnotherFail, 244 | }) { 245 | t.Errorf("validate does not validate map of struct type") 246 | } 247 | if nil == Validate(map[StAnotherFail]int{ 248 | stAnotherFail: 0, 249 | }) { 250 | t.Errorf("validate does not validate map of struct type") 251 | } 252 | if nil == Validate([]StAnotherFail{ 253 | stAnotherFail, 254 | }) { 255 | t.Errorf("validate does not validate slice of struct type") 256 | } 257 | if nil == Validate([1]StAnotherFail{ 258 | stAnotherFail, 259 | }) { 260 | t.Errorf("validate does not validate slice of struct type") 261 | } 262 | } 263 | 264 | func TestErrors(t *testing.T) { 265 | var err error 266 | zero := 0 267 | 268 | err = Validate(struct { 269 | field map[time.Duration]int `validate:"gte=2 [eq=0s]"` 270 | }{ 271 | field: map[time.Duration]int{-time.Second: 1}, 272 | }) 273 | 274 | switch err.(type) { 275 | case ErrorValidation: 276 | default: 277 | t.Errorf("error of the wrong type") 278 | } 279 | 280 | err = Validate(struct { 281 | field map[time.Duration]int `validate:"gte=2 [eq=0s"` 282 | }{ 283 | field: map[time.Duration]int{-time.Second: 0}, 284 | }) 285 | 286 | switch err.(type) { 287 | case ErrorSyntax: 288 | default: 289 | t.Errorf("error of the wrong type") 290 | } 291 | 292 | err = Validate(struct { 293 | field map[time.Duration]int `validate:"gte=2 [eq=0s]]"` 294 | }{ 295 | field: map[time.Duration]int{-time.Second: 0}, 296 | }) 297 | 298 | switch err.(type) { 299 | case ErrorSyntax: 300 | default: 301 | t.Errorf("error of the wrong type") 302 | } 303 | 304 | err = Validate(struct { 305 | field map[time.Duration]int `validate:"&&"` 306 | }{ 307 | field: map[time.Duration]int{-time.Second: 0}, 308 | }) 309 | 310 | switch err.(type) { 311 | case ErrorSyntax: 312 | default: 313 | t.Errorf("error of the wrong type") 314 | } 315 | 316 | err = Validate(struct { 317 | field map[time.Duration]int `validate:"||"` 318 | }{ 319 | field: map[time.Duration]int{-time.Second: 0}, 320 | }) 321 | 322 | switch err.(type) { 323 | case ErrorSyntax: 324 | default: 325 | t.Errorf("error of the wrong type") 326 | } 327 | 328 | err = Validate(struct { 329 | field map[time.Duration]int `validate:">"` 330 | }{ 331 | field: map[time.Duration]int{-time.Second: 0}, 332 | }) 333 | 334 | switch err.(type) { 335 | case ErrorSyntax: 336 | default: 337 | t.Errorf("error of the wrong type") 338 | } 339 | 340 | err = Validate(struct { 341 | field map[time.Duration]int `validate:">>gte=0"` 342 | }{ 343 | field: map[time.Duration]int{-time.Second: -1}, 344 | }) 345 | 346 | switch err.(type) { 347 | case ErrorSyntax: 348 | default: 349 | t.Errorf("error of the wrong type") 350 | } 351 | 352 | err = Validate(struct { 353 | field map[time.Duration]int `validate:">[gte=0]"` 354 | }{ 355 | field: map[time.Duration]int{-time.Second: -1}, 356 | }) 357 | 358 | switch err.(type) { 359 | case ErrorSyntax: 360 | default: 361 | t.Errorf("error of the wrong type") 362 | } 363 | 364 | err = Validate(struct { 365 | field map[time.Duration]int `validate:"abc"` 366 | }{ 367 | field: map[time.Duration]int{-time.Second: 0}, 368 | }) 369 | 370 | switch err.(type) { 371 | case ErrorSyntax: 372 | default: 373 | t.Errorf("error of the wrong type") 374 | } 375 | 376 | err = Validate(struct { 377 | field map[time.Duration]int `validate:"gte"` 378 | }{ 379 | field: map[time.Duration]int{-time.Second: 0}, 380 | }) 381 | 382 | switch err.(type) { 383 | case ErrorSyntax: 384 | default: 385 | t.Errorf("error of the wrong type") 386 | } 387 | 388 | err = Validate(struct { 389 | field map[time.Duration]int `validate:"gte=0=0"` 390 | }{ 391 | field: map[time.Duration]int{-time.Second: 0}, 392 | }) 393 | 394 | switch err.(type) { 395 | case ErrorSyntax: 396 | default: 397 | t.Errorf("error of the wrong type") 398 | } 399 | 400 | err = Validate(struct { 401 | field int `validate:"empty=true"` 402 | }{ 403 | field: 0, 404 | }) 405 | 406 | switch err.(type) { 407 | case ErrorSyntax: 408 | default: 409 | t.Errorf("error of the wrong type") 410 | } 411 | 412 | err = Validate(struct { 413 | field int `validate:"nil=true"` 414 | }{ 415 | field: 0, 416 | }) 417 | 418 | switch err.(type) { 419 | case ErrorSyntax: 420 | default: 421 | t.Errorf("error of the wrong type") 422 | } 423 | 424 | err = Validate(struct { 425 | field *int `validate:"eq=0"` 426 | }{ 427 | field: &zero, 428 | }) 429 | 430 | switch err.(type) { 431 | case ErrorSyntax: 432 | default: 433 | t.Errorf("error of the wrong type") 434 | } 435 | 436 | err = Validate(struct { 437 | field *int `validate:"ne=0"` 438 | }{ 439 | field: &zero, 440 | }) 441 | 442 | switch err.(type) { 443 | case ErrorSyntax: 444 | default: 445 | t.Errorf("error of the wrong type") 446 | } 447 | 448 | err = Validate(struct { 449 | field *int `validate:"gt=0"` 450 | }{ 451 | field: &zero, 452 | }) 453 | 454 | switch err.(type) { 455 | case ErrorSyntax: 456 | default: 457 | t.Errorf("error of the wrong type") 458 | } 459 | 460 | err = Validate(struct { 461 | field *int `validate:"lt=0"` 462 | }{ 463 | field: &zero, 464 | }) 465 | 466 | switch err.(type) { 467 | case ErrorSyntax: 468 | default: 469 | t.Errorf("error of the wrong type") 470 | } 471 | 472 | err = Validate(struct { 473 | field *int `validate:"gte=0"` 474 | }{ 475 | field: &zero, 476 | }) 477 | 478 | switch err.(type) { 479 | case ErrorSyntax: 480 | default: 481 | t.Errorf("error of the wrong type") 482 | } 483 | 484 | err = Validate(struct { 485 | field *int `validate:"lte=0"` 486 | }{ 487 | field: &zero, 488 | }) 489 | 490 | switch err.(type) { 491 | case ErrorSyntax: 492 | default: 493 | t.Errorf("error of the wrong type") 494 | } 495 | 496 | err = Validate(struct { 497 | field *int `validate:"format=email"` 498 | }{ 499 | field: &zero, 500 | }) 501 | 502 | switch err.(type) { 503 | case ErrorSyntax: 504 | default: 505 | t.Errorf("error of the wrong type") 506 | } 507 | } 508 | 509 | type StCustomValidator struct { 510 | field int 511 | anotherField int `validate:"eq=0"` 512 | } 513 | 514 | func (st StCustomValidator) Validate() error { 515 | if st.field <= 0 { 516 | return errors.New("field should be positive") 517 | } 518 | 519 | return nil 520 | } 521 | 522 | type StCustomValidator2 struct { 523 | field int 524 | anotherField int `validate:"eq=0"` 525 | } 526 | 527 | func (st *StCustomValidator2) Validate() error { 528 | if st.field <= 0 { 529 | return errors.New("field should be positive") 530 | } 531 | 532 | return nil 533 | } 534 | 535 | type IntCustomValidator int 536 | 537 | func (i IntCustomValidator) Validate() error { 538 | if i <= 0 { 539 | return errors.New("field should be positive") 540 | } 541 | 542 | return nil 543 | } 544 | 545 | func TestCustomValidator(t *testing.T) { 546 | // Test a custom validtor wiht a value reciever by value, then by reference 547 | if nil != Validate(StCustomValidator{ 548 | field: 1, 549 | }) { 550 | t.Errorf("custom validator does not validate") 551 | } 552 | 553 | if nil == Validate(StCustomValidator{ 554 | field: 0, 555 | }) { 556 | t.Errorf("custom validator does not validate") 557 | } 558 | 559 | if nil != Validate(&StCustomValidator{ 560 | field: 1, 561 | }) { 562 | t.Errorf("custom validator does not validate") 563 | } 564 | 565 | if nil == Validate(&StCustomValidator{ 566 | field: 0, 567 | }) { 568 | t.Errorf("custom validator does not validate") 569 | } 570 | 571 | // Test a custom validtor with a pointer reciever by value, then by reference 572 | if nil != Validate(StCustomValidator2{ 573 | field: 1, 574 | }) { 575 | t.Errorf("custom validator does not validate") 576 | } 577 | 578 | if nil == Validate(StCustomValidator2{ 579 | field: 0, 580 | }) { 581 | t.Errorf("custom validator does not validate") 582 | } 583 | 584 | if nil != Validate(&StCustomValidator2{ 585 | field: 1, 586 | }) { 587 | t.Errorf("custom validator does not validate") 588 | } 589 | 590 | if nil == Validate(&StCustomValidator2{ 591 | field: 0, 592 | }) { 593 | t.Errorf("custom validator does not validate") 594 | } 595 | 596 | // Test an embedded validator together with a custom validtor with a value reciever by value, then by reference 597 | if nil == Validate(StCustomValidator{ 598 | field: 1, 599 | anotherField: 1, 600 | }) { 601 | t.Errorf("custom validator does not validate") 602 | } 603 | 604 | if nil == Validate(StCustomValidator{ 605 | field: 1, 606 | anotherField: 1, 607 | }) { 608 | t.Errorf("custom validator does not validate") 609 | } 610 | 611 | if nil == Validate(&StCustomValidator{ 612 | field: 1, 613 | anotherField: 1, 614 | }) { 615 | t.Errorf("custom validator does not validate") 616 | } 617 | 618 | if nil == Validate(&StCustomValidator{ 619 | field: 1, 620 | anotherField: 1, 621 | }) { 622 | t.Errorf("custom validator does not validate") 623 | } 624 | 625 | // Test an embedded validator together with a custom validtor with a pointer reciever by value, then by reference 626 | if nil == Validate(StCustomValidator2{ 627 | field: 1, 628 | anotherField: 1, 629 | }) { 630 | t.Errorf("custom validator does not validate") 631 | } 632 | 633 | if nil == Validate(StCustomValidator2{ 634 | field: 1, 635 | anotherField: 1, 636 | }) { 637 | t.Errorf("custom validator does not validate") 638 | } 639 | 640 | if nil == Validate(&StCustomValidator2{ 641 | field: 1, 642 | anotherField: 1, 643 | }) { 644 | t.Errorf("custom validator does not validate") 645 | } 646 | 647 | if nil == Validate(&StCustomValidator2{ 648 | field: 1, 649 | anotherField: 1, 650 | }) { 651 | t.Errorf("custom validator does not validate") 652 | } 653 | 654 | // Test a custom validtor of a subtruct (defined in exported field) with a value reciever by value, then by reference 655 | if nil != Validate(struct { 656 | Field StCustomValidator 657 | }{ 658 | Field: StCustomValidator{ 659 | field: 1, 660 | }, 661 | }) { 662 | t.Errorf("custom validator does not validate") 663 | } 664 | 665 | if nil == Validate(struct { 666 | Field StCustomValidator 667 | }{ 668 | Field: StCustomValidator{ 669 | field: 0, 670 | }, 671 | }) { 672 | t.Errorf("custom validator does not validate") 673 | } 674 | 675 | if nil != Validate(struct { 676 | Field *StCustomValidator 677 | }{ 678 | Field: &StCustomValidator{ 679 | field: 1, 680 | }, 681 | }) { 682 | t.Errorf("custom validator does not validate") 683 | } 684 | 685 | if nil == Validate(struct { 686 | Field *StCustomValidator 687 | }{ 688 | Field: &StCustomValidator{ 689 | field: 0, 690 | }, 691 | }) { 692 | t.Errorf("custom validator does not validate") 693 | } 694 | 695 | // Test a custom validtor of a subtruct (defined in exported field) with a pointer reciever by value, then by reference 696 | if nil != Validate(struct { 697 | Field StCustomValidator2 698 | }{ 699 | Field: StCustomValidator2{ 700 | field: 1, 701 | }, 702 | }) { 703 | t.Errorf("custom validator does not validate") 704 | } 705 | 706 | if nil == Validate(struct { 707 | Field StCustomValidator2 708 | }{ 709 | Field: StCustomValidator2{ 710 | field: 0, 711 | }, 712 | }) { 713 | t.Errorf("custom validator does not validate") 714 | } 715 | 716 | if nil != Validate(struct { 717 | Field *StCustomValidator2 718 | }{ 719 | Field: &StCustomValidator2{ 720 | field: 1, 721 | }, 722 | }) { 723 | t.Errorf("custom validator does not validate") 724 | } 725 | 726 | if nil == Validate(struct { 727 | Field *StCustomValidator2 728 | }{ 729 | Field: &StCustomValidator2{ 730 | field: 0, 731 | }, 732 | }) { 733 | t.Errorf("custom validator does not validate") 734 | } 735 | 736 | // Test a custom validtor of a subtruct (defined in unexported field) with a value reciever by value, then by reference 737 | // This will fail, but should not panic 738 | if nil != Validate(struct { 739 | field StCustomValidator 740 | }{ 741 | field: StCustomValidator{ 742 | field: 1, 743 | }, 744 | }) { 745 | t.Errorf("custom validator does not validate") 746 | } 747 | 748 | if nil != Validate(struct { 749 | field StCustomValidator 750 | }{ 751 | field: StCustomValidator{ 752 | field: 0, 753 | }, 754 | }) { 755 | t.Errorf("custom validator does not validate") 756 | } 757 | 758 | if nil != Validate(struct { 759 | field *StCustomValidator 760 | }{ 761 | field: &StCustomValidator{ 762 | field: 1, 763 | }, 764 | }) { 765 | t.Errorf("custom validator does not validate") 766 | } 767 | 768 | if nil != Validate(struct { 769 | field *StCustomValidator 770 | }{ 771 | field: &StCustomValidator{ 772 | field: 0, 773 | }, 774 | }) { 775 | t.Errorf("custom validator does not validate") 776 | } 777 | 778 | // Test a custom validtor of a subtruct (defined in unexported field) with a pointer reciever by value, then by reference 779 | // This will fail, but should not panic 780 | if nil != Validate(struct { 781 | field StCustomValidator2 782 | }{ 783 | field: StCustomValidator2{ 784 | field: 1, 785 | }, 786 | }) { 787 | t.Errorf("custom validator does not validate") 788 | } 789 | 790 | if nil != Validate(struct { 791 | field StCustomValidator2 792 | }{ 793 | field: StCustomValidator2{ 794 | field: 0, 795 | }, 796 | }) { 797 | t.Errorf("custom validator does not validate") 798 | } 799 | 800 | if nil != Validate(struct { 801 | field *StCustomValidator2 802 | }{ 803 | field: &StCustomValidator2{ 804 | field: 1, 805 | }, 806 | }) { 807 | t.Errorf("custom validator does not validate") 808 | } 809 | 810 | if nil != Validate(struct { 811 | field *StCustomValidator2 812 | }{ 813 | field: &StCustomValidator2{ 814 | field: 0, 815 | }, 816 | }) { 817 | t.Errorf("custom validator does not validate") 818 | } 819 | 820 | // Test a custom validtor of an artbitrary type 821 | one := IntCustomValidator(1) 822 | zero := IntCustomValidator(0) 823 | 824 | if nil != Validate(one) { 825 | t.Errorf("custom validator does not validate") 826 | } 827 | 828 | if nil == Validate(zero) { 829 | t.Errorf("custom validator does not validate") 830 | } 831 | 832 | if nil != Validate(&one) { 833 | t.Errorf("custom validator does not validate") 834 | } 835 | 836 | if nil == Validate(&zero) { 837 | t.Errorf("custom validator does not validate") 838 | } 839 | } 840 | 841 | func TestAndVal(t *testing.T) { 842 | if nil == Validate(struct { 843 | field int `validate:"gte=0<e=10"` 844 | }{ 845 | field: -1, 846 | }) { 847 | t.Errorf("& operator does not validate") 848 | } 849 | 850 | if nil == Validate(struct { 851 | field int `validate:"gte=0<e=10"` 852 | }{ 853 | field: 11, 854 | }) { 855 | t.Errorf("& operator does not validate") 856 | } 857 | 858 | if nil != Validate(struct { 859 | field int `validate:"gte=0<e=10"` 860 | }{ 861 | field: 5, 862 | }) { 863 | t.Errorf("& operator does not validate") 864 | } 865 | 866 | if nil == Validate(struct { 867 | field int `validate:"gte=1<e=-1"` 868 | }{ 869 | field: 0, 870 | }) { 871 | t.Errorf("& operator does not validate") 872 | } 873 | } 874 | 875 | func TestOrVal(t *testing.T) { 876 | if nil == Validate(struct { 877 | field int `validate:"lte=0|gte=10"` 878 | }{ 879 | field: 5, 880 | }) { 881 | t.Errorf("| operator does not validate") 882 | } 883 | 884 | if nil != Validate(struct { 885 | field int `validate:"lte=0|gte=10"` 886 | }{ 887 | field: -1, 888 | }) { 889 | t.Errorf("| operator does not validate") 890 | } 891 | 892 | if nil != Validate(struct { 893 | field int `validate:"lte=0|gte=10"` 894 | }{ 895 | field: 11, 896 | }) { 897 | t.Errorf("| operator does not validate") 898 | } 899 | 900 | if nil != Validate(struct { 901 | field int `validate:"gte=0|lte=10"` 902 | }{ 903 | field: 5, 904 | }) { 905 | t.Errorf("| operator does not validate") 906 | } 907 | 908 | if nil != Validate(struct { 909 | field int `validate:"gte=0|lte=10"` 910 | }{ 911 | field: -1, 912 | }) { 913 | t.Errorf("| operator does not validate") 914 | } 915 | 916 | if nil != Validate(struct { 917 | field int `validate:"gte=0|lte=10"` 918 | }{ 919 | field: 11, 920 | }) { 921 | t.Errorf("| operator does not validate") 922 | } 923 | } 924 | 925 | func TestAndOrVal(t *testing.T) { 926 | if nil == Validate(struct { 927 | field int `validate:"gte=0 & lte=5 | gte=10 & lte=15"` 928 | }{ 929 | field: -1, 930 | }) { 931 | t.Errorf("& and | operators does not validate") 932 | } 933 | 934 | if nil == Validate(struct { 935 | field int `validate:"gte=0 & lte=5 | gte=10 & lte=15"` 936 | }{ 937 | field: 6, 938 | }) { 939 | t.Errorf("& and | operators does not validate") 940 | } 941 | 942 | if nil == Validate(struct { 943 | field int `validate:"gte=0 & lte=5 | gte=10 & lte=15"` 944 | }{ 945 | field: 16, 946 | }) { 947 | t.Errorf("& and | operators does not validate") 948 | } 949 | 950 | if nil != Validate(struct { 951 | field int `validate:"gte=0 & lte=5 | gte=10 & lte=15"` 952 | }{ 953 | field: 1, 954 | }) { 955 | t.Errorf("& and | operators does not validate") 956 | } 957 | 958 | if nil != Validate(struct { 959 | field int `validate:"gte=0 & lte=5 | gte=10 & lte=15"` 960 | }{ 961 | field: 11, 962 | }) { 963 | t.Errorf("& and | operators does not validate") 964 | } 965 | } 966 | 967 | func TestFormatVal(t *testing.T) { 968 | if nil == Validate(struct { 969 | field int `validate:" gte = 0 & lte = 10 & bla= "` 970 | }{ 971 | field: -1, 972 | }) { 973 | t.Errorf("validators with spaces does not validate") 974 | } 975 | 976 | if nil != Validate(struct { 977 | field int `validate:" gte = 0 & lte = 10 "` 978 | }{ 979 | field: 5, 980 | }) { 981 | t.Errorf("validators with spaces does not validate") 982 | } 983 | 984 | if nil != Validate(struct { 985 | field int `validate:""` 986 | }{ 987 | field: 5, 988 | }) { 989 | t.Errorf("empty validator must not validate") 990 | } 991 | 992 | if nil == Validate(struct { 993 | field int `validate:" one_of = 1 , 2 , 3 "` 994 | }{ 995 | field: 4, 996 | }) { 997 | t.Errorf("validators with spaces does not validate") 998 | } 999 | 1000 | if nil != Validate(struct { 1001 | field int `validate:" one_of = 1 , 2 , 3 "` 1002 | }{ 1003 | field: 2, 1004 | }) { 1005 | t.Errorf("validators with spaces does not validate") 1006 | } 1007 | 1008 | if nil == Validate(struct { 1009 | field int `validate:"one_of="` 1010 | }{ 1011 | field: 0, 1012 | }) { 1013 | t.Errorf("empty one_of validate should not validate") 1014 | } 1015 | 1016 | if nil == Validate(struct { 1017 | field int `validate:"one_of"` 1018 | }{ 1019 | field: 0, 1020 | }) { 1021 | t.Errorf("empty one_of validate should not validate") 1022 | } 1023 | } 1024 | 1025 | func TestEqValForDuration(t *testing.T) { 1026 | if nil == Validate(struct { 1027 | field time.Duration `validate:"eq=abc"` 1028 | }{ 1029 | field: 0, 1030 | }) { 1031 | t.Errorf("eq validator does not validate for time.Duratuon") 1032 | } 1033 | 1034 | if nil == Validate(struct { 1035 | field time.Duration `validate:"eq=0s"` 1036 | }{ 1037 | field: -time.Second, 1038 | }) { 1039 | t.Errorf("eq validator does not validate for time.Duratuon") 1040 | } 1041 | 1042 | if nil != Validate(struct { 1043 | field time.Duration `validate:"eq=0s"` 1044 | }{ 1045 | field: 0, 1046 | }) { 1047 | t.Errorf("eq validator does not validate for time.Duratuon") 1048 | } 1049 | } 1050 | 1051 | func TestEqValForInt(t *testing.T) { 1052 | if nil == Validate(struct { 1053 | field int `validate:"eq=abc"` 1054 | }{ 1055 | field: 0, 1056 | }) { 1057 | t.Errorf("eq validator does not validate for int") 1058 | } 1059 | 1060 | if nil != Validate(struct { 1061 | field int `validate:"eq=0"` 1062 | }{ 1063 | field: 0, 1064 | }) { 1065 | t.Errorf("eq validator does not validate for int") 1066 | } 1067 | 1068 | if nil != Validate(struct { 1069 | field int8 `validate:"eq=0"` 1070 | }{ 1071 | field: 0, 1072 | }) { 1073 | t.Errorf("eq validator does not validate for int8") 1074 | } 1075 | 1076 | if nil != Validate(struct { 1077 | field int16 `validate:"eq=0"` 1078 | }{ 1079 | field: 0, 1080 | }) { 1081 | t.Errorf("eq validator does not validate for int16") 1082 | } 1083 | 1084 | if nil != Validate(struct { 1085 | field int32 `validate:"eq=0"` 1086 | }{ 1087 | field: 0, 1088 | }) { 1089 | t.Errorf("eq validator does not validate for int32") 1090 | } 1091 | 1092 | if nil != Validate(struct { 1093 | field int64 `validate:"eq=0"` 1094 | }{ 1095 | field: 0, 1096 | }) { 1097 | t.Errorf("eq validator does not validate for int64") 1098 | } 1099 | 1100 | if nil == Validate(struct { 1101 | field int `validate:"eq=0"` 1102 | }{ 1103 | field: 1, 1104 | }) { 1105 | t.Errorf("eq validator does not validate for int") 1106 | } 1107 | 1108 | if nil == Validate(struct { 1109 | field int8 `validate:"eq=0"` 1110 | }{ 1111 | field: 1, 1112 | }) { 1113 | t.Errorf("eq validator does not validate for int8") 1114 | } 1115 | 1116 | if nil == Validate(struct { 1117 | field int16 `validate:"eq=0"` 1118 | }{ 1119 | field: 1, 1120 | }) { 1121 | t.Errorf("eq validator does not validate for int16") 1122 | } 1123 | 1124 | if nil == Validate(struct { 1125 | field int32 `validate:"eq=0"` 1126 | }{ 1127 | field: 1, 1128 | }) { 1129 | t.Errorf("eq validator does not validate for int32") 1130 | } 1131 | 1132 | if nil == Validate(struct { 1133 | field int64 `validate:"eq=0"` 1134 | }{ 1135 | field: 1, 1136 | }) { 1137 | t.Errorf("eq validator does not validate for int64") 1138 | } 1139 | } 1140 | 1141 | func TestEqValForRune(t *testing.T) { 1142 | if nil == Validate(struct { 1143 | field rune `validate:"eq=abc"` 1144 | }{ 1145 | field: 0, 1146 | }) { 1147 | t.Errorf("eq validator does not validate for rune") 1148 | } 1149 | 1150 | if nil != Validate(struct { 1151 | field rune `validate:"eq=0"` 1152 | }{ 1153 | field: 0, 1154 | }) { 1155 | t.Errorf("eq validator does not validate for rune") 1156 | } 1157 | 1158 | if nil == Validate(struct { 1159 | field rune `validate:"eq=0"` 1160 | }{ 1161 | field: 1, 1162 | }) { 1163 | t.Errorf("eq validator does not validate for rune") 1164 | } 1165 | } 1166 | 1167 | func TestEqValForUint(t *testing.T) { 1168 | if nil == Validate(struct { 1169 | field uint `validate:"eq=abc"` 1170 | }{ 1171 | field: 0, 1172 | }) { 1173 | t.Errorf("eq validator does not validate for uint") 1174 | } 1175 | 1176 | if nil != Validate(struct { 1177 | field uint `validate:"eq=10"` 1178 | }{ 1179 | field: 10, 1180 | }) { 1181 | t.Errorf("eq validator does not validate for uint") 1182 | } 1183 | 1184 | if nil != Validate(struct { 1185 | field uint8 `validate:"eq=10"` 1186 | }{ 1187 | field: 10, 1188 | }) { 1189 | t.Errorf("eq validator does not validate for uint8") 1190 | } 1191 | 1192 | if nil != Validate(struct { 1193 | field uint16 `validate:"eq=10"` 1194 | }{ 1195 | field: 10, 1196 | }) { 1197 | t.Errorf("eq validator does not validate for uint16") 1198 | } 1199 | 1200 | if nil != Validate(struct { 1201 | field uint32 `validate:"eq=10"` 1202 | }{ 1203 | field: 10, 1204 | }) { 1205 | t.Errorf("eq validator does not validate for uint32") 1206 | } 1207 | 1208 | if nil != Validate(struct { 1209 | field uint64 `validate:"eq=10"` 1210 | }{ 1211 | field: 10, 1212 | }) { 1213 | t.Errorf("eq validator does not validate for uint64") 1214 | } 1215 | 1216 | if nil != Validate(struct { 1217 | field uintptr `validate:"eq=10"` 1218 | }{ 1219 | field: 10, 1220 | }) { 1221 | t.Errorf("eq validator does not validate for uintptr") 1222 | } 1223 | 1224 | if nil == Validate(struct { 1225 | field uint `validate:"eq=10"` 1226 | }{ 1227 | field: 11, 1228 | }) { 1229 | t.Errorf("eq validator does not validate for uint") 1230 | } 1231 | 1232 | if nil == Validate(struct { 1233 | field uint8 `validate:"eq=10"` 1234 | }{ 1235 | field: 11, 1236 | }) { 1237 | t.Errorf("eq validator does not validate for uint8") 1238 | } 1239 | 1240 | if nil == Validate(struct { 1241 | field uint16 `validate:"eq=10"` 1242 | }{ 1243 | field: 11, 1244 | }) { 1245 | t.Errorf("eq validator does not validate for uint16") 1246 | } 1247 | 1248 | if nil == Validate(struct { 1249 | field uint32 `validate:"eq=10"` 1250 | }{ 1251 | field: 11, 1252 | }) { 1253 | t.Errorf("eq validator does not validate for uint32") 1254 | } 1255 | 1256 | if nil == Validate(struct { 1257 | field uint64 `validate:"eq=10"` 1258 | }{ 1259 | field: 11, 1260 | }) { 1261 | t.Errorf("eq validator does not validate for uint64") 1262 | } 1263 | 1264 | if nil == Validate(struct { 1265 | field uintptr `validate:"eq=10"` 1266 | }{ 1267 | field: 11, 1268 | }) { 1269 | t.Errorf("eq validator does not validate for uintptr") 1270 | } 1271 | } 1272 | 1273 | func TestEqValForFloat(t *testing.T) { 1274 | if nil == Validate(struct { 1275 | field float32 `validate:"eq=abc"` 1276 | }{ 1277 | field: 0, 1278 | }) { 1279 | t.Errorf("eq validator does not validate for flaot32") 1280 | } 1281 | 1282 | if nil != Validate(struct { 1283 | field float32 `validate:"eq=0"` 1284 | }{ 1285 | field: 0, 1286 | }) { 1287 | t.Errorf("eq validator does not validate for flaot32") 1288 | } 1289 | 1290 | if nil != Validate(struct { 1291 | field float64 `validate:"eq=0"` 1292 | }{ 1293 | field: 0, 1294 | }) { 1295 | t.Errorf("eq validator does not validate for flaot64") 1296 | } 1297 | 1298 | if nil == Validate(struct { 1299 | field float32 `validate:"eq=0"` 1300 | }{ 1301 | field: 0.1, 1302 | }) { 1303 | t.Errorf("eq validator does not validate for flaot32") 1304 | } 1305 | 1306 | if nil == Validate(struct { 1307 | field float64 `validate:"eq=0"` 1308 | }{ 1309 | field: 0.1, 1310 | }) { 1311 | t.Errorf("eq validator does not validate for flaot64") 1312 | } 1313 | } 1314 | 1315 | func TestEqValForString(t *testing.T) { 1316 | if nil == Validate(struct { 1317 | field string `validate:"eq=abc"` 1318 | }{ 1319 | field: "aa", 1320 | }) { 1321 | t.Errorf("eq validator does not validate for string") 1322 | } 1323 | 1324 | if nil != Validate(struct { 1325 | field string `validate:"eq=2"` 1326 | }{ 1327 | field: "aa", 1328 | }) { 1329 | t.Errorf("eq validator does not validate for string") 1330 | } 1331 | 1332 | if nil == Validate(struct { 1333 | field string `validate:"eq=2"` 1334 | }{ 1335 | field: "abc", 1336 | }) { 1337 | t.Errorf("eq validator does not validate for string") 1338 | } 1339 | } 1340 | 1341 | func TestEqValForMap(t *testing.T) { 1342 | if nil == Validate(struct { 1343 | field map[string]string `validate:"eq=abc"` 1344 | }{ 1345 | field: map[string]string{ 1346 | "a": "a", 1347 | "b": "b", 1348 | }, 1349 | }) { 1350 | t.Errorf("eq validator does not validate for map") 1351 | } 1352 | 1353 | if nil != Validate(struct { 1354 | field map[string]string `validate:"eq=2"` 1355 | }{ 1356 | field: map[string]string{ 1357 | "a": "a", 1358 | "b": "b", 1359 | }, 1360 | }) { 1361 | t.Errorf("eq validator does not validate for map") 1362 | } 1363 | 1364 | if nil == Validate(struct { 1365 | field map[string]string `validate:"eq=2"` 1366 | }{ 1367 | field: map[string]string{ 1368 | "a": "a", 1369 | "b": "b", 1370 | "c": "c", 1371 | }, 1372 | }) { 1373 | t.Errorf("eq validator does not validate for map") 1374 | } 1375 | } 1376 | 1377 | func TestEqValForSlice(t *testing.T) { 1378 | if nil == Validate(struct { 1379 | field []string `validate:"eq=abc"` 1380 | }{ 1381 | field: []string{"a", "b"}, 1382 | }) { 1383 | t.Errorf("eq validator does not validate for slice") 1384 | } 1385 | 1386 | if nil != Validate(struct { 1387 | field []string `validate:"eq=2"` 1388 | }{ 1389 | field: []string{"a", "b"}, 1390 | }) { 1391 | t.Errorf("eq validator does not validate for slice") 1392 | } 1393 | 1394 | if nil == Validate(struct { 1395 | field []string `validate:"eq=2"` 1396 | }{ 1397 | field: []string{"a", "b", "c"}, 1398 | }) { 1399 | t.Errorf("eq validator does not validate for slice") 1400 | } 1401 | } 1402 | 1403 | func TestEqValForArray(t *testing.T) { 1404 | if nil == Validate(struct { 1405 | field [2]string `validate:"eq=abc"` 1406 | }{ 1407 | field: [2]string{"a", "b"}, 1408 | }) { 1409 | t.Errorf("eq validator does not validate for string") 1410 | } 1411 | 1412 | if nil != Validate(struct { 1413 | field [2]string `validate:"eq=2"` 1414 | }{ 1415 | field: [2]string{"a", "b"}, 1416 | }) { 1417 | t.Errorf("eq validator does not validate for string") 1418 | } 1419 | 1420 | if nil == Validate(struct { 1421 | field [3]string `validate:"eq=2"` 1422 | }{ 1423 | field: [3]string{"a", "b", "c"}, 1424 | }) { 1425 | t.Errorf("eq validator does not validate for string") 1426 | } 1427 | } 1428 | 1429 | func TestNeValForDuration(t *testing.T) { 1430 | if nil == Validate(struct { 1431 | field time.Duration `validate:"ne=abc"` 1432 | }{ 1433 | field: -time.Second, 1434 | }) { 1435 | t.Errorf("ne validator does not validate for time.Duratuon") 1436 | } 1437 | 1438 | if nil != Validate(struct { 1439 | field time.Duration `validate:"ne=0s"` 1440 | }{ 1441 | field: -time.Second, 1442 | }) { 1443 | t.Errorf("ne validator does not validate for time.Duratuon") 1444 | } 1445 | 1446 | if nil == Validate(struct { 1447 | field time.Duration `validate:"ne=0s"` 1448 | }{ 1449 | field: 0, 1450 | }) { 1451 | t.Errorf("ne validator does not validate for time.Duratuon") 1452 | } 1453 | } 1454 | 1455 | func TestNeValForInt(t *testing.T) { 1456 | if nil == Validate(struct { 1457 | field int `validate:"ne=abc"` 1458 | }{ 1459 | field: 0, 1460 | }) { 1461 | t.Errorf("ne validator does not validate for int") 1462 | } 1463 | 1464 | if nil == Validate(struct { 1465 | field int `validate:"ne=0"` 1466 | }{ 1467 | field: 0, 1468 | }) { 1469 | t.Errorf("ne validator does not validate for int") 1470 | } 1471 | 1472 | if nil == Validate(struct { 1473 | field int8 `validate:"ne=0"` 1474 | }{ 1475 | field: 0, 1476 | }) { 1477 | t.Errorf("ne validator does not validate for int8") 1478 | } 1479 | 1480 | if nil == Validate(struct { 1481 | field int16 `validate:"ne=0"` 1482 | }{ 1483 | field: 0, 1484 | }) { 1485 | t.Errorf("ne validator does not validate for int16") 1486 | } 1487 | 1488 | if nil == Validate(struct { 1489 | field int32 `validate:"ne=0"` 1490 | }{ 1491 | field: 0, 1492 | }) { 1493 | t.Errorf("ne validator does not validate for int32") 1494 | } 1495 | 1496 | if nil == Validate(struct { 1497 | field int64 `validate:"ne=0"` 1498 | }{ 1499 | field: 0, 1500 | }) { 1501 | t.Errorf("ne validator does not validate for int64") 1502 | } 1503 | 1504 | if nil != Validate(struct { 1505 | field int `validate:"ne=0"` 1506 | }{ 1507 | field: 1, 1508 | }) { 1509 | t.Errorf("ne validator does not validate for int") 1510 | } 1511 | 1512 | if nil != Validate(struct { 1513 | field int8 `validate:"ne=0"` 1514 | }{ 1515 | field: 1, 1516 | }) { 1517 | t.Errorf("ne validator does not validate for int8") 1518 | } 1519 | 1520 | if nil != Validate(struct { 1521 | field int16 `validate:"ne=0"` 1522 | }{ 1523 | field: 1, 1524 | }) { 1525 | t.Errorf("ne validator does not validate for int16") 1526 | } 1527 | 1528 | if nil != Validate(struct { 1529 | field int32 `validate:"ne=0"` 1530 | }{ 1531 | field: 1, 1532 | }) { 1533 | t.Errorf("ne validator does not validate for int32") 1534 | } 1535 | 1536 | if nil != Validate(struct { 1537 | field int64 `validate:"ne=0"` 1538 | }{ 1539 | field: 1, 1540 | }) { 1541 | t.Errorf("ne validator does not validate for int64") 1542 | } 1543 | } 1544 | 1545 | func TestNeValForRune(t *testing.T) { 1546 | if nil == Validate(struct { 1547 | field rune `validate:"ne=abc"` 1548 | }{ 1549 | field: 0, 1550 | }) { 1551 | t.Errorf("ne validator does not validate for rune") 1552 | } 1553 | 1554 | if nil == Validate(struct { 1555 | field rune `validate:"ne=0"` 1556 | }{ 1557 | field: 0, 1558 | }) { 1559 | t.Errorf("ne validator does not validate for rune") 1560 | } 1561 | 1562 | if nil != Validate(struct { 1563 | field rune `validate:"ne=0"` 1564 | }{ 1565 | field: 1, 1566 | }) { 1567 | t.Errorf("ne validator does not validate for rune") 1568 | } 1569 | } 1570 | 1571 | func TestNeValForUint(t *testing.T) { 1572 | if nil == Validate(struct { 1573 | field uint `validate:"ne=abc"` 1574 | }{ 1575 | field: 10, 1576 | }) { 1577 | t.Errorf("ne validator does not validate for uint") 1578 | } 1579 | 1580 | if nil == Validate(struct { 1581 | field uint `validate:"ne=10"` 1582 | }{ 1583 | field: 10, 1584 | }) { 1585 | t.Errorf("ne validator does not validate for uint") 1586 | } 1587 | 1588 | if nil == Validate(struct { 1589 | field uint8 `validate:"ne=10"` 1590 | }{ 1591 | field: 10, 1592 | }) { 1593 | t.Errorf("ne validator does not validate for uint8") 1594 | } 1595 | 1596 | if nil == Validate(struct { 1597 | field uint16 `validate:"ne=10"` 1598 | }{ 1599 | field: 10, 1600 | }) { 1601 | t.Errorf("ne validator does not validate for uint16") 1602 | } 1603 | 1604 | if nil == Validate(struct { 1605 | field uint32 `validate:"ne=10"` 1606 | }{ 1607 | field: 10, 1608 | }) { 1609 | t.Errorf("ne validator does not validate for uint32") 1610 | } 1611 | 1612 | if nil == Validate(struct { 1613 | field uint64 `validate:"ne=10"` 1614 | }{ 1615 | field: 10, 1616 | }) { 1617 | t.Errorf("ne validator does not validate for uint64") 1618 | } 1619 | 1620 | if nil == Validate(struct { 1621 | field uintptr `validate:"ne=10"` 1622 | }{ 1623 | field: 10, 1624 | }) { 1625 | t.Errorf("ne validator does not validate for uintptr") 1626 | } 1627 | 1628 | if nil != Validate(struct { 1629 | field uint `validate:"ne=10"` 1630 | }{ 1631 | field: 11, 1632 | }) { 1633 | t.Errorf("ne validator does not validate for uint") 1634 | } 1635 | 1636 | if nil != Validate(struct { 1637 | field uint8 `validate:"ne=10"` 1638 | }{ 1639 | field: 11, 1640 | }) { 1641 | t.Errorf("ne validator does not validate for uint8") 1642 | } 1643 | 1644 | if nil != Validate(struct { 1645 | field uint16 `validate:"ne=10"` 1646 | }{ 1647 | field: 11, 1648 | }) { 1649 | t.Errorf("ne validator does not validate for uint16") 1650 | } 1651 | 1652 | if nil != Validate(struct { 1653 | field uint32 `validate:"ne=10"` 1654 | }{ 1655 | field: 11, 1656 | }) { 1657 | t.Errorf("ne validator does not validate for uint32") 1658 | } 1659 | 1660 | if nil != Validate(struct { 1661 | field uint64 `validate:"ne=10"` 1662 | }{ 1663 | field: 11, 1664 | }) { 1665 | t.Errorf("ne validator does not validate for uint64") 1666 | } 1667 | 1668 | if nil != Validate(struct { 1669 | field uintptr `validate:"ne=10"` 1670 | }{ 1671 | field: 11, 1672 | }) { 1673 | t.Errorf("ne validator does not validate for uintptr") 1674 | } 1675 | } 1676 | 1677 | func TestNeValForFloat(t *testing.T) { 1678 | if nil == Validate(struct { 1679 | field float32 `validate:"ne=abc"` 1680 | }{ 1681 | field: 0, 1682 | }) { 1683 | t.Errorf("ne validator does not validate for flaot32") 1684 | } 1685 | 1686 | if nil == Validate(struct { 1687 | field float32 `validate:"ne=0"` 1688 | }{ 1689 | field: 0, 1690 | }) { 1691 | t.Errorf("ne validator does not validate for flaot32") 1692 | } 1693 | 1694 | if nil == Validate(struct { 1695 | field float64 `validate:"ne=0"` 1696 | }{ 1697 | field: 0, 1698 | }) { 1699 | t.Errorf("ne validator does not validate for flaot64") 1700 | } 1701 | 1702 | if nil != Validate(struct { 1703 | field float32 `validate:"ne=0"` 1704 | }{ 1705 | field: 0.1, 1706 | }) { 1707 | t.Errorf("ne validator does not validate for flaot32") 1708 | } 1709 | 1710 | if nil != Validate(struct { 1711 | field float64 `validate:"ne=0"` 1712 | }{ 1713 | field: 0.1, 1714 | }) { 1715 | t.Errorf("ne validator does not validate for flaot64") 1716 | } 1717 | } 1718 | 1719 | func TestNeValForString(t *testing.T) { 1720 | if nil == Validate(struct { 1721 | field string `validate:"ne=abc"` 1722 | }{ 1723 | field: "aa", 1724 | }) { 1725 | t.Errorf("ne validator does not validate for string") 1726 | } 1727 | 1728 | if nil == Validate(struct { 1729 | field string `validate:"ne=2"` 1730 | }{ 1731 | field: "aa", 1732 | }) { 1733 | t.Errorf("ne validator does not validate for string") 1734 | } 1735 | 1736 | if nil != Validate(struct { 1737 | field string `validate:"ne=2"` 1738 | }{ 1739 | field: "abc", 1740 | }) { 1741 | t.Errorf("ne validator does not validate for string") 1742 | } 1743 | } 1744 | 1745 | func TestNeValForMap(t *testing.T) { 1746 | if nil == Validate(struct { 1747 | field map[string]string `validate:"ne=abc"` 1748 | }{ 1749 | field: map[string]string{ 1750 | "a": "a", 1751 | "b": "b", 1752 | }, 1753 | }) { 1754 | t.Errorf("ne validator does not validate for map") 1755 | } 1756 | 1757 | if nil == Validate(struct { 1758 | field map[string]string `validate:"ne=2"` 1759 | }{ 1760 | field: map[string]string{ 1761 | "a": "a", 1762 | "b": "b", 1763 | }, 1764 | }) { 1765 | t.Errorf("ne validator does not validate for map") 1766 | } 1767 | 1768 | if nil != Validate(struct { 1769 | field map[string]string `validate:"ne=2"` 1770 | }{ 1771 | field: map[string]string{ 1772 | "a": "a", 1773 | "b": "b", 1774 | "c": "c", 1775 | }, 1776 | }) { 1777 | t.Errorf("ne validator does not validate for map") 1778 | } 1779 | } 1780 | 1781 | func TestNeValForSlice(t *testing.T) { 1782 | if nil == Validate(struct { 1783 | field []string `validate:"ne=abc"` 1784 | }{ 1785 | field: []string{"a", "b"}, 1786 | }) { 1787 | t.Errorf("ne validator does not validate for slice") 1788 | } 1789 | 1790 | if nil == Validate(struct { 1791 | field []string `validate:"ne=2"` 1792 | }{ 1793 | field: []string{"a", "b"}, 1794 | }) { 1795 | t.Errorf("ne validator does not validate for slice") 1796 | } 1797 | 1798 | if nil != Validate(struct { 1799 | field []string `validate:"ne=2"` 1800 | }{ 1801 | field: []string{"a", "b", "c"}, 1802 | }) { 1803 | t.Errorf("ne validator does not validate for slice") 1804 | } 1805 | } 1806 | 1807 | func TestNeValForArray(t *testing.T) { 1808 | if nil == Validate(struct { 1809 | field [2]string `validate:"ne=abc"` 1810 | }{ 1811 | field: [2]string{"a", "b"}, 1812 | }) { 1813 | t.Errorf("ne validator does not validate for string") 1814 | } 1815 | 1816 | if nil == Validate(struct { 1817 | field [2]string `validate:"ne=2"` 1818 | }{ 1819 | field: [2]string{"a", "b"}, 1820 | }) { 1821 | t.Errorf("ne validator does not validate for string") 1822 | } 1823 | 1824 | if nil != Validate(struct { 1825 | field [3]string `validate:"ne=2"` 1826 | }{ 1827 | field: [3]string{"a", "b", "c"}, 1828 | }) { 1829 | t.Errorf("ne validator does not validate for string") 1830 | } 1831 | } 1832 | 1833 | func TestGtValForDuration(t *testing.T) { 1834 | if nil == Validate(struct { 1835 | field time.Duration `validate:"gt=abc"` 1836 | }{ 1837 | field: -time.Second, 1838 | }) { 1839 | t.Errorf("gt validator does not validate for time.Duratuon") 1840 | } 1841 | 1842 | if nil == Validate(struct { 1843 | field time.Duration `validate:"gt=0s"` 1844 | }{ 1845 | field: -time.Second, 1846 | }) { 1847 | t.Errorf("gt validator does not validate for time.Duratuon") 1848 | } 1849 | 1850 | if nil == Validate(struct { 1851 | field time.Duration `validate:"gt=-1s"` 1852 | }{ 1853 | field: -time.Minute, 1854 | }) { 1855 | t.Errorf("gt validator does not validate for time.Duratuon") 1856 | } 1857 | 1858 | if nil == Validate(struct { 1859 | field time.Duration `validate:"gt=0s"` 1860 | }{ 1861 | field: 0, 1862 | }) { 1863 | t.Errorf("gt validator does not validate for time.Duratuon") 1864 | } 1865 | 1866 | if nil != Validate(struct { 1867 | field time.Duration `validate:"gt=-1s"` 1868 | }{ 1869 | field: -time.Millisecond, 1870 | }) { 1871 | t.Errorf("gt validator does not validate for time.Duratuon") 1872 | } 1873 | } 1874 | 1875 | func TestLtValForDuration(t *testing.T) { 1876 | if nil == Validate(struct { 1877 | field time.Duration `validate:"lt=abc"` 1878 | }{ 1879 | field: time.Second, 1880 | }) { 1881 | t.Errorf("lt validator does not validate for time.Duratuon") 1882 | } 1883 | 1884 | if nil == Validate(struct { 1885 | field time.Duration `validate:"lt=0s"` 1886 | }{ 1887 | field: time.Second, 1888 | }) { 1889 | t.Errorf("lt validator does not validate for time.Duratuon") 1890 | } 1891 | 1892 | if nil == Validate(struct { 1893 | field time.Duration `validate:"lt=1s"` 1894 | }{ 1895 | field: time.Minute, 1896 | }) { 1897 | t.Errorf("lt validator does not validate for time.Duratuon") 1898 | } 1899 | 1900 | if nil == Validate(struct { 1901 | field time.Duration `validate:"lt=0s"` 1902 | }{ 1903 | field: 0, 1904 | }) { 1905 | t.Errorf("lt validator does not validate for time.Duratuon") 1906 | } 1907 | 1908 | if nil != Validate(struct { 1909 | field time.Duration `validate:"lt=1s"` 1910 | }{ 1911 | field: time.Millisecond, 1912 | }) { 1913 | t.Errorf("lt validator does not validate for time.Duratuon") 1914 | } 1915 | } 1916 | 1917 | func TestGtValForInt(t *testing.T) { 1918 | if nil == Validate(struct { 1919 | field int `validate:"gt=abc"` 1920 | }{ 1921 | field: 0, 1922 | }) { 1923 | t.Errorf("gt validator does not validate for int") 1924 | } 1925 | 1926 | if nil == Validate(struct { 1927 | field int `validate:"gt=0"` 1928 | }{ 1929 | field: 0, 1930 | }) { 1931 | t.Errorf("gt validator does not validate for int") 1932 | } 1933 | 1934 | if nil == Validate(struct { 1935 | field int8 `validate:"gt=0"` 1936 | }{ 1937 | field: 0, 1938 | }) { 1939 | t.Errorf("gt validator does not validate for int8") 1940 | } 1941 | 1942 | if nil == Validate(struct { 1943 | field int16 `validate:"gt=0"` 1944 | }{ 1945 | field: 0, 1946 | }) { 1947 | t.Errorf("gt validator does not validate for int16") 1948 | } 1949 | 1950 | if nil == Validate(struct { 1951 | field int32 `validate:"gt=0"` 1952 | }{ 1953 | field: 0, 1954 | }) { 1955 | t.Errorf("gt validator does not validate for int32") 1956 | } 1957 | 1958 | if nil == Validate(struct { 1959 | field int64 `validate:"gt=0"` 1960 | }{ 1961 | field: 0, 1962 | }) { 1963 | t.Errorf("gt validator does not validate for int64") 1964 | } 1965 | 1966 | if nil != Validate(struct { 1967 | field int `validate:"gt=0"` 1968 | }{ 1969 | field: 1, 1970 | }) { 1971 | t.Errorf("gt validator does not validate for int") 1972 | } 1973 | 1974 | if nil != Validate(struct { 1975 | field int8 `validate:"gt=0"` 1976 | }{ 1977 | field: 1, 1978 | }) { 1979 | t.Errorf("gt validator does not validate for int8") 1980 | } 1981 | 1982 | if nil != Validate(struct { 1983 | field int16 `validate:"gt=0"` 1984 | }{ 1985 | field: 1, 1986 | }) { 1987 | t.Errorf("gt validator does not validate for int16") 1988 | } 1989 | 1990 | if nil != Validate(struct { 1991 | field int32 `validate:"gt=0"` 1992 | }{ 1993 | field: 1, 1994 | }) { 1995 | t.Errorf("gt validator does not validate for int32") 1996 | } 1997 | 1998 | if nil != Validate(struct { 1999 | field int64 `validate:"gt=0"` 2000 | }{ 2001 | field: 1, 2002 | }) { 2003 | t.Errorf("gt validator does not validate for int64") 2004 | } 2005 | } 2006 | 2007 | func TestLtValForInt(t *testing.T) { 2008 | if nil == Validate(struct { 2009 | field int `validate:"lt=abc"` 2010 | }{ 2011 | field: 0, 2012 | }) { 2013 | t.Errorf("lt validator does not validate for int") 2014 | } 2015 | 2016 | if nil == Validate(struct { 2017 | field int `validate:"lt=0"` 2018 | }{ 2019 | field: 0, 2020 | }) { 2021 | t.Errorf("lt validator does not validate for int") 2022 | } 2023 | 2024 | if nil == Validate(struct { 2025 | field int8 `validate:"lt=0"` 2026 | }{ 2027 | field: 0, 2028 | }) { 2029 | t.Errorf("lt validator does not validate for int8") 2030 | } 2031 | 2032 | if nil == Validate(struct { 2033 | field int16 `validate:"lt=0"` 2034 | }{ 2035 | field: 0, 2036 | }) { 2037 | t.Errorf("lt validator does not validate for int16") 2038 | } 2039 | 2040 | if nil == Validate(struct { 2041 | field int32 `validate:"lt=0"` 2042 | }{ 2043 | field: 0, 2044 | }) { 2045 | t.Errorf("lt validator does not validate for int32") 2046 | } 2047 | 2048 | if nil == Validate(struct { 2049 | field int64 `validate:"lt=0"` 2050 | }{ 2051 | field: 0, 2052 | }) { 2053 | t.Errorf("lt validator does not validate for int64") 2054 | } 2055 | 2056 | if nil != Validate(struct { 2057 | field int `validate:"lt=0"` 2058 | }{ 2059 | field: -1, 2060 | }) { 2061 | t.Errorf("lt validator does not validate for int") 2062 | } 2063 | 2064 | if nil != Validate(struct { 2065 | field int8 `validate:"lt=0"` 2066 | }{ 2067 | field: -1, 2068 | }) { 2069 | t.Errorf("lt validator does not validate for int8") 2070 | } 2071 | 2072 | if nil != Validate(struct { 2073 | field int16 `validate:"lt=0"` 2074 | }{ 2075 | field: -1, 2076 | }) { 2077 | t.Errorf("lt validator does not validate for int16") 2078 | } 2079 | 2080 | if nil != Validate(struct { 2081 | field int32 `validate:"lt=0"` 2082 | }{ 2083 | field: -1, 2084 | }) { 2085 | t.Errorf("lt validator does not validate for int32") 2086 | } 2087 | 2088 | if nil != Validate(struct { 2089 | field int64 `validate:"lt=0"` 2090 | }{ 2091 | field: -1, 2092 | }) { 2093 | t.Errorf("lt validator does not validate for int64") 2094 | } 2095 | } 2096 | 2097 | func TestGtValForRune(t *testing.T) { 2098 | if nil == Validate(struct { 2099 | field rune `validate:"gt=abc"` 2100 | }{ 2101 | field: 0, 2102 | }) { 2103 | t.Errorf("gt validator does not validate for rune") 2104 | } 2105 | 2106 | if nil == Validate(struct { 2107 | field rune `validate:"gt=0"` 2108 | }{ 2109 | field: 0, 2110 | }) { 2111 | t.Errorf("gt validator does not validate for rune") 2112 | } 2113 | 2114 | if nil != Validate(struct { 2115 | field rune `validate:"gt=0"` 2116 | }{ 2117 | field: 1, 2118 | }) { 2119 | t.Errorf("gt validator does not validate for rune") 2120 | } 2121 | } 2122 | 2123 | func TestLtValForRune(t *testing.T) { 2124 | if nil == Validate(struct { 2125 | field rune `validate:"lt=abc"` 2126 | }{ 2127 | field: 0, 2128 | }) { 2129 | t.Errorf("lt validator does not validate for rune") 2130 | } 2131 | 2132 | if nil == Validate(struct { 2133 | field rune `validate:"lt=0"` 2134 | }{ 2135 | field: 0, 2136 | }) { 2137 | t.Errorf("lt validator does not validate for rune") 2138 | } 2139 | 2140 | if nil != Validate(struct { 2141 | field rune `validate:"lt=0"` 2142 | }{ 2143 | field: -1, 2144 | }) { 2145 | t.Errorf("lt validator does not validate for rune") 2146 | } 2147 | } 2148 | 2149 | func TestGtValForUint(t *testing.T) { 2150 | if nil == Validate(struct { 2151 | field uint `validate:"gt=abc"` 2152 | }{ 2153 | field: 10, 2154 | }) { 2155 | t.Errorf("gt validator does not validate for uint") 2156 | } 2157 | 2158 | if nil == Validate(struct { 2159 | field uint `validate:"gt=10"` 2160 | }{ 2161 | field: 10, 2162 | }) { 2163 | t.Errorf("gt validator does not validate for uint") 2164 | } 2165 | 2166 | if nil == Validate(struct { 2167 | field uint8 `validate:"gt=10"` 2168 | }{ 2169 | field: 10, 2170 | }) { 2171 | t.Errorf("gt validator does not validate for uint8") 2172 | } 2173 | 2174 | if nil == Validate(struct { 2175 | field uint16 `validate:"gt=10"` 2176 | }{ 2177 | field: 10, 2178 | }) { 2179 | t.Errorf("gt validator does not validate for uint16") 2180 | } 2181 | 2182 | if nil == Validate(struct { 2183 | field uint32 `validate:"gt=10"` 2184 | }{ 2185 | field: 10, 2186 | }) { 2187 | t.Errorf("gt validator does not validate for uint32") 2188 | } 2189 | 2190 | if nil == Validate(struct { 2191 | field uint64 `validate:"gt=10"` 2192 | }{ 2193 | field: 10, 2194 | }) { 2195 | t.Errorf("gt validator does not validate for uint64") 2196 | } 2197 | 2198 | if nil == Validate(struct { 2199 | field uintptr `validate:"gt=10"` 2200 | }{ 2201 | field: 10, 2202 | }) { 2203 | t.Errorf("gt validator does not validate for uintptr") 2204 | } 2205 | 2206 | if nil != Validate(struct { 2207 | field uint `validate:"gt=10"` 2208 | }{ 2209 | field: 11, 2210 | }) { 2211 | t.Errorf("gt validator does not validate for uint") 2212 | } 2213 | 2214 | if nil != Validate(struct { 2215 | field uint8 `validate:"gt=10"` 2216 | }{ 2217 | field: 11, 2218 | }) { 2219 | t.Errorf("gt validator does not validate for uint8") 2220 | } 2221 | 2222 | if nil != Validate(struct { 2223 | field uint16 `validate:"gt=10"` 2224 | }{ 2225 | field: 11, 2226 | }) { 2227 | t.Errorf("gt validator does not validate for uint16") 2228 | } 2229 | 2230 | if nil != Validate(struct { 2231 | field uint32 `validate:"gt=10"` 2232 | }{ 2233 | field: 11, 2234 | }) { 2235 | t.Errorf("gt validator does not validate for uint32") 2236 | } 2237 | 2238 | if nil != Validate(struct { 2239 | field uint64 `validate:"gt=10"` 2240 | }{ 2241 | field: 11, 2242 | }) { 2243 | t.Errorf("gt validator does not validate for uint64") 2244 | } 2245 | 2246 | if nil != Validate(struct { 2247 | field uintptr `validate:"gt=10"` 2248 | }{ 2249 | field: 11, 2250 | }) { 2251 | t.Errorf("gt validator does not validate for uintptr") 2252 | } 2253 | } 2254 | 2255 | func TestLtValForUint(t *testing.T) { 2256 | if nil == Validate(struct { 2257 | field uint `validate:"lt=abc"` 2258 | }{ 2259 | field: 0, 2260 | }) { 2261 | t.Errorf("lt validator does not validate for uint") 2262 | } 2263 | 2264 | if nil == Validate(struct { 2265 | field uint `validate:"lt=0"` 2266 | }{ 2267 | field: 0, 2268 | }) { 2269 | t.Errorf("lt validator does not validate for uint") 2270 | } 2271 | 2272 | if nil == Validate(struct { 2273 | field uint8 `validate:"lt=0"` 2274 | }{ 2275 | field: 0, 2276 | }) { 2277 | t.Errorf("lt validator does not validate for uint8") 2278 | } 2279 | 2280 | if nil == Validate(struct { 2281 | field uint16 `validate:"lt=0"` 2282 | }{ 2283 | field: 0, 2284 | }) { 2285 | t.Errorf("lt validator does not validate for uint16") 2286 | } 2287 | 2288 | if nil == Validate(struct { 2289 | field uint32 `validate:"lt=0"` 2290 | }{ 2291 | field: 0, 2292 | }) { 2293 | t.Errorf("lt validator does not validate for uint32") 2294 | } 2295 | 2296 | if nil == Validate(struct { 2297 | field uint64 `validate:"lt=0"` 2298 | }{ 2299 | field: 0, 2300 | }) { 2301 | t.Errorf("lt validator does not validate for uint64") 2302 | } 2303 | 2304 | if nil == Validate(struct { 2305 | field uintptr `validate:"lt=0"` 2306 | }{ 2307 | field: 0, 2308 | }) { 2309 | t.Errorf("lt validator does not validate for uintptr") 2310 | } 2311 | 2312 | if nil != Validate(struct { 2313 | field uint `validate:"lt=1"` 2314 | }{ 2315 | field: 0, 2316 | }) { 2317 | t.Errorf("lt validator does not validate for uint") 2318 | } 2319 | 2320 | if nil != Validate(struct { 2321 | field uint8 `validate:"lt=1"` 2322 | }{ 2323 | field: 0, 2324 | }) { 2325 | t.Errorf("lt validator does not validate for uint8") 2326 | } 2327 | 2328 | if nil != Validate(struct { 2329 | field uint16 `validate:"lt=1"` 2330 | }{ 2331 | field: 0, 2332 | }) { 2333 | t.Errorf("lt validator does not validate for uint16") 2334 | } 2335 | 2336 | if nil != Validate(struct { 2337 | field uint32 `validate:"lt=1"` 2338 | }{ 2339 | field: 0, 2340 | }) { 2341 | t.Errorf("lt validator does not validate for uint32") 2342 | } 2343 | 2344 | if nil != Validate(struct { 2345 | field uint64 `validate:"lt=1"` 2346 | }{ 2347 | field: 0, 2348 | }) { 2349 | t.Errorf("lt validator does not validate for uint64") 2350 | } 2351 | 2352 | if nil != Validate(struct { 2353 | field uint64 `validate:"lt=1"` 2354 | }{ 2355 | field: 0, 2356 | }) { 2357 | t.Errorf("lt validator does not validate for uintptr") 2358 | } 2359 | } 2360 | 2361 | func TestGtValForFloat(t *testing.T) { 2362 | if nil == Validate(struct { 2363 | field float32 `validate:"gt=abc"` 2364 | }{ 2365 | field: 0, 2366 | }) { 2367 | t.Errorf("gt validator does not validate for flaot32") 2368 | } 2369 | 2370 | if nil == Validate(struct { 2371 | field float32 `validate:"gt=0"` 2372 | }{ 2373 | field: 0, 2374 | }) { 2375 | t.Errorf("gt validator does not validate for flaot32") 2376 | } 2377 | 2378 | if nil == Validate(struct { 2379 | field float64 `validate:"gt=0"` 2380 | }{ 2381 | field: 0, 2382 | }) { 2383 | t.Errorf("gt validator does not validate for flaot64") 2384 | } 2385 | 2386 | if nil != Validate(struct { 2387 | field float32 `validate:"gt=0"` 2388 | }{ 2389 | field: 0.1, 2390 | }) { 2391 | t.Errorf("gt validator does not validate for flaot32") 2392 | } 2393 | 2394 | if nil != Validate(struct { 2395 | field float64 `validate:"gt=0"` 2396 | }{ 2397 | field: 0.1, 2398 | }) { 2399 | t.Errorf("gt validator does not validate for flaot64") 2400 | } 2401 | } 2402 | 2403 | func TestLtValForFloat(t *testing.T) { 2404 | if nil == Validate(struct { 2405 | field float32 `validate:"lt=abc"` 2406 | }{ 2407 | field: 0, 2408 | }) { 2409 | t.Errorf("lt validator does not validate for flaot32") 2410 | } 2411 | 2412 | if nil == Validate(struct { 2413 | field float32 `validate:"lt=0"` 2414 | }{ 2415 | field: 0, 2416 | }) { 2417 | t.Errorf("lt validator does not validate for flaot32") 2418 | } 2419 | 2420 | if nil == Validate(struct { 2421 | field float64 `validate:"lt=0"` 2422 | }{ 2423 | field: 0, 2424 | }) { 2425 | t.Errorf("lt validator does not validate for flaot64") 2426 | } 2427 | 2428 | if nil != Validate(struct { 2429 | field float32 `validate:"lt=0"` 2430 | }{ 2431 | field: -0.1, 2432 | }) { 2433 | t.Errorf("lt validator does not validate for flaot32") 2434 | } 2435 | 2436 | if nil != Validate(struct { 2437 | field float64 `validate:"lt=0"` 2438 | }{ 2439 | field: -0.1, 2440 | }) { 2441 | t.Errorf("lt validator does not validate for flaot64") 2442 | } 2443 | } 2444 | 2445 | func TestGtValForString(t *testing.T) { 2446 | if nil == Validate(struct { 2447 | field string `validate:"gt=abc"` 2448 | }{ 2449 | field: "aa", 2450 | }) { 2451 | t.Errorf("gt validator does not validate for string") 2452 | } 2453 | 2454 | if nil == Validate(struct { 2455 | field string `validate:"gt=2"` 2456 | }{ 2457 | field: "aa", 2458 | }) { 2459 | t.Errorf("gt validator does not validate for string") 2460 | } 2461 | 2462 | if nil != Validate(struct { 2463 | field string `validate:"gt=2"` 2464 | }{ 2465 | field: "abc", 2466 | }) { 2467 | t.Errorf("gt validator does not validate for string") 2468 | } 2469 | } 2470 | 2471 | func TestLtValForString(t *testing.T) { 2472 | if nil == Validate(struct { 2473 | field string `validate:"lt=abc"` 2474 | }{ 2475 | field: "ab", 2476 | }) { 2477 | t.Errorf("lt validator does not validate for string") 2478 | } 2479 | 2480 | if nil == Validate(struct { 2481 | field string `validate:"lt=2"` 2482 | }{ 2483 | field: "ab", 2484 | }) { 2485 | t.Errorf("lt validator does not validate for string") 2486 | } 2487 | 2488 | if nil != Validate(struct { 2489 | field string `validate:"lt=2"` 2490 | }{ 2491 | field: "a", 2492 | }) { 2493 | t.Errorf("lt validator does not validate for string") 2494 | } 2495 | } 2496 | 2497 | func TestGtValForMap(t *testing.T) { 2498 | if nil == Validate(struct { 2499 | field map[string]string `validate:"gt=abc"` 2500 | }{ 2501 | field: map[string]string{ 2502 | "a": "a", 2503 | "b": "b", 2504 | }, 2505 | }) { 2506 | t.Errorf("gt validator does not validate for map") 2507 | } 2508 | 2509 | if nil == Validate(struct { 2510 | field map[string]string `validate:"gt=2"` 2511 | }{ 2512 | field: map[string]string{ 2513 | "a": "a", 2514 | "b": "b", 2515 | }, 2516 | }) { 2517 | t.Errorf("gt validator does not validate for map") 2518 | } 2519 | 2520 | if nil != Validate(struct { 2521 | field map[string]string `validate:"gt=2"` 2522 | }{ 2523 | field: map[string]string{ 2524 | "a": "a", 2525 | "b": "b", 2526 | "c": "c", 2527 | }, 2528 | }) { 2529 | t.Errorf("gt validator does not validate for map") 2530 | } 2531 | } 2532 | 2533 | func TestLtForMap(t *testing.T) { 2534 | if nil == Validate(struct { 2535 | field map[string]string `validate:"lt=abc"` 2536 | }{ 2537 | field: map[string]string{ 2538 | "a": "a", 2539 | "b": "b", 2540 | }, 2541 | }) { 2542 | t.Errorf("lt validator does not validate for map") 2543 | } 2544 | 2545 | if nil == Validate(struct { 2546 | field map[string]string `validate:"lt=2"` 2547 | }{ 2548 | field: map[string]string{ 2549 | "a": "a", 2550 | "b": "b", 2551 | }, 2552 | }) { 2553 | t.Errorf("lt validator does not validate for map") 2554 | } 2555 | 2556 | if nil != Validate(struct { 2557 | field map[string]string `validate:"lt=2"` 2558 | }{ 2559 | field: map[string]string{ 2560 | "a": "a", 2561 | }, 2562 | }) { 2563 | t.Errorf("lt validator does not validate for map") 2564 | } 2565 | } 2566 | 2567 | func TestGtValForSlice(t *testing.T) { 2568 | if nil == Validate(struct { 2569 | field []string `validate:"gt=abc"` 2570 | }{ 2571 | field: []string{"a", "b"}, 2572 | }) { 2573 | t.Errorf("gt validator does not validate for slice") 2574 | } 2575 | 2576 | if nil == Validate(struct { 2577 | field []string `validate:"gt=2"` 2578 | }{ 2579 | field: []string{"a", "b"}, 2580 | }) { 2581 | t.Errorf("gt validator does not validate for slice") 2582 | } 2583 | 2584 | if nil != Validate(struct { 2585 | field []string `validate:"gt=2"` 2586 | }{ 2587 | field: []string{"a", "b", "c"}, 2588 | }) { 2589 | t.Errorf("gt validator does not validate for slice") 2590 | } 2591 | } 2592 | 2593 | func TestLtValForSlice(t *testing.T) { 2594 | if nil == Validate(struct { 2595 | field []string `validate:"lt=abc"` 2596 | }{ 2597 | field: []string{"a", "b"}, 2598 | }) { 2599 | t.Errorf("gt validator does not validate for slice") 2600 | } 2601 | 2602 | if nil == Validate(struct { 2603 | field []string `validate:"lt=2"` 2604 | }{ 2605 | field: []string{"a", "b"}, 2606 | }) { 2607 | t.Errorf("gt validator does not validate for slice") 2608 | } 2609 | 2610 | if nil != Validate(struct { 2611 | field []string `validate:"lt=2"` 2612 | }{ 2613 | field: []string{"a"}, 2614 | }) { 2615 | t.Errorf("gt validator does not validate for slice") 2616 | } 2617 | } 2618 | 2619 | func TestGtValForArray(t *testing.T) { 2620 | if nil == Validate(struct { 2621 | field [2]string `validate:"gt=abc"` 2622 | }{ 2623 | field: [2]string{"a", "b"}, 2624 | }) { 2625 | t.Errorf("gt validator does not validate for string") 2626 | } 2627 | 2628 | if nil == Validate(struct { 2629 | field [2]string `validate:"gt=2"` 2630 | }{ 2631 | field: [2]string{"a", "b"}, 2632 | }) { 2633 | t.Errorf("gt validator does not validate for string") 2634 | } 2635 | 2636 | if nil != Validate(struct { 2637 | field [3]string `validate:"gt=2"` 2638 | }{ 2639 | field: [3]string{"a", "b", "c"}, 2640 | }) { 2641 | t.Errorf("gt validator does not validate for string") 2642 | } 2643 | } 2644 | 2645 | func TestLtValForArray(t *testing.T) { 2646 | if nil == Validate(struct { 2647 | field [2]string `validate:"lt=abc"` 2648 | }{ 2649 | field: [2]string{"a", "b"}, 2650 | }) { 2651 | t.Errorf("gt validator does not validate for array") 2652 | } 2653 | 2654 | if nil == Validate(struct { 2655 | field [2]string `validate:"lt=2"` 2656 | }{ 2657 | field: [2]string{"a", "b"}, 2658 | }) { 2659 | t.Errorf("gt validator does not validate for array") 2660 | } 2661 | 2662 | if nil != Validate(struct { 2663 | field [1]string `validate:"lt=2"` 2664 | }{ 2665 | field: [1]string{"a"}, 2666 | }) { 2667 | t.Errorf("gt validator does not validate for array") 2668 | } 2669 | } 2670 | 2671 | func TestGteValForDuration(t *testing.T) { 2672 | if nil == Validate(struct { 2673 | field time.Duration `validate:"gte=abc"` 2674 | }{ 2675 | field: -time.Second, 2676 | }) { 2677 | t.Errorf("gte validator does not validate for time.Duratuon") 2678 | } 2679 | 2680 | if nil == Validate(struct { 2681 | field time.Duration `validate:"gte=0s"` 2682 | }{ 2683 | field: -time.Second, 2684 | }) { 2685 | t.Errorf("gte validator does not validate for time.Duratuon") 2686 | } 2687 | 2688 | if nil == Validate(struct { 2689 | field time.Duration `validate:"gte=-1s"` 2690 | }{ 2691 | field: -time.Minute, 2692 | }) { 2693 | t.Errorf("gte validator does not validate for time.Duratuon") 2694 | } 2695 | 2696 | if nil != Validate(struct { 2697 | field time.Duration `validate:"gte=0s"` 2698 | }{ 2699 | field: 0, 2700 | }) { 2701 | t.Errorf("gte validator does not validate for time.Duratuon") 2702 | } 2703 | 2704 | if nil != Validate(struct { 2705 | field time.Duration `validate:"gte=-1s"` 2706 | }{ 2707 | field: -time.Millisecond, 2708 | }) { 2709 | t.Errorf("gte validator does not validate for time.Duratuon") 2710 | } 2711 | } 2712 | 2713 | func TestLteValForDuration(t *testing.T) { 2714 | if nil == Validate(struct { 2715 | field time.Duration `validate:"lte=abc"` 2716 | }{ 2717 | field: time.Second, 2718 | }) { 2719 | t.Errorf("lte validator does not validate for time.Duratuon") 2720 | } 2721 | 2722 | if nil == Validate(struct { 2723 | field time.Duration `validate:"lte=0s"` 2724 | }{ 2725 | field: time.Second, 2726 | }) { 2727 | t.Errorf("lte validator does not validate for time.Duratuon") 2728 | } 2729 | 2730 | if nil == Validate(struct { 2731 | field time.Duration `validate:"lte=1s"` 2732 | }{ 2733 | field: time.Minute, 2734 | }) { 2735 | t.Errorf("lte validator does not validate for time.Duratuon") 2736 | } 2737 | 2738 | if nil != Validate(struct { 2739 | field time.Duration `validate:"lte=0s"` 2740 | }{ 2741 | field: 0, 2742 | }) { 2743 | t.Errorf("lte validator does not validate for time.Duratuon") 2744 | } 2745 | 2746 | if nil != Validate(struct { 2747 | field time.Duration `validate:"lte=1s"` 2748 | }{ 2749 | field: time.Millisecond, 2750 | }) { 2751 | t.Errorf("lte validator does not validate for time.Duratuon") 2752 | } 2753 | } 2754 | 2755 | func TestGteValForInt(t *testing.T) { 2756 | if nil == Validate(struct { 2757 | field int `validate:"gte=abc"` 2758 | }{ 2759 | field: -1, 2760 | }) { 2761 | t.Errorf("gte validator does not validate for int") 2762 | } 2763 | 2764 | if nil == Validate(struct { 2765 | field int `validate:"gte=0"` 2766 | }{ 2767 | field: -1, 2768 | }) { 2769 | t.Errorf("gte validator does not validate for int") 2770 | } 2771 | 2772 | if nil == Validate(struct { 2773 | field int8 `validate:"gte=0"` 2774 | }{ 2775 | field: -1, 2776 | }) { 2777 | t.Errorf("gte validator does not validate for int8") 2778 | } 2779 | 2780 | if nil == Validate(struct { 2781 | field int16 `validate:"gte=0"` 2782 | }{ 2783 | field: -1, 2784 | }) { 2785 | t.Errorf("gte validator does not validate for int16") 2786 | } 2787 | 2788 | if nil == Validate(struct { 2789 | field int32 `validate:"gte=0"` 2790 | }{ 2791 | field: -1, 2792 | }) { 2793 | t.Errorf("gte validator does not validate for int32") 2794 | } 2795 | 2796 | if nil == Validate(struct { 2797 | field int64 `validate:"gte=0"` 2798 | }{ 2799 | field: -1, 2800 | }) { 2801 | t.Errorf("gte validator does not validate for int64") 2802 | } 2803 | 2804 | if nil != Validate(struct { 2805 | field int `validate:"gte=0"` 2806 | }{ 2807 | field: 0, 2808 | }) { 2809 | t.Errorf("gte validator does not validate for int") 2810 | } 2811 | 2812 | if nil != Validate(struct { 2813 | field int8 `validate:"gte=0"` 2814 | }{ 2815 | field: 0, 2816 | }) { 2817 | t.Errorf("gte validator does not validate for int8") 2818 | } 2819 | 2820 | if nil != Validate(struct { 2821 | field int16 `validate:"gte=0"` 2822 | }{ 2823 | field: 0, 2824 | }) { 2825 | t.Errorf("gte validator does not validate for int16") 2826 | } 2827 | 2828 | if nil != Validate(struct { 2829 | field int32 `validate:"gte=0"` 2830 | }{ 2831 | field: 0, 2832 | }) { 2833 | t.Errorf("gte validator does not validate for int32") 2834 | } 2835 | 2836 | if nil != Validate(struct { 2837 | field int64 `validate:"gte=0"` 2838 | }{ 2839 | field: 0, 2840 | }) { 2841 | t.Errorf("gte validator does not validate for int64") 2842 | } 2843 | } 2844 | 2845 | func TestLteValForInt(t *testing.T) { 2846 | if nil == Validate(struct { 2847 | field int `validate:"lte=abc"` 2848 | }{ 2849 | field: 1, 2850 | }) { 2851 | t.Errorf("lte validator does not validate for int") 2852 | } 2853 | 2854 | if nil == Validate(struct { 2855 | field int `validate:"lte=0"` 2856 | }{ 2857 | field: 1, 2858 | }) { 2859 | t.Errorf("lte validator does not validate for int") 2860 | } 2861 | 2862 | if nil == Validate(struct { 2863 | field int8 `validate:"lte=0"` 2864 | }{ 2865 | field: 1, 2866 | }) { 2867 | t.Errorf("lte validator does not validate for int8") 2868 | } 2869 | 2870 | if nil == Validate(struct { 2871 | field int16 `validate:"lte=0"` 2872 | }{ 2873 | field: 1, 2874 | }) { 2875 | t.Errorf("lte validator does not validate for int16") 2876 | } 2877 | 2878 | if nil == Validate(struct { 2879 | field int32 `validate:"lte=0"` 2880 | }{ 2881 | field: 1, 2882 | }) { 2883 | t.Errorf("lte validator does not validate for int32") 2884 | } 2885 | 2886 | if nil == Validate(struct { 2887 | field int64 `validate:"lte=0"` 2888 | }{ 2889 | field: 1, 2890 | }) { 2891 | t.Errorf("lte validator does not validate for int64") 2892 | } 2893 | 2894 | if nil != Validate(struct { 2895 | field int `validate:"lte=0"` 2896 | }{ 2897 | field: 0, 2898 | }) { 2899 | t.Errorf("lte validator does not validate for int") 2900 | } 2901 | 2902 | if nil != Validate(struct { 2903 | field int8 `validate:"lte=0"` 2904 | }{ 2905 | field: 0, 2906 | }) { 2907 | t.Errorf("lte validator does not validate for int8") 2908 | } 2909 | 2910 | if nil != Validate(struct { 2911 | field int16 `validate:"lte=0"` 2912 | }{ 2913 | field: 0, 2914 | }) { 2915 | t.Errorf("lte validator does not validate for int16") 2916 | } 2917 | 2918 | if nil != Validate(struct { 2919 | field int32 `validate:"lte=0"` 2920 | }{ 2921 | field: 0, 2922 | }) { 2923 | t.Errorf("lte validator does not validate for int32") 2924 | } 2925 | 2926 | if nil != Validate(struct { 2927 | field int64 `validate:"lte=0"` 2928 | }{ 2929 | field: 0, 2930 | }) { 2931 | t.Errorf("lte validator does not validate for int64") 2932 | } 2933 | } 2934 | 2935 | func TestGteValForRune(t *testing.T) { 2936 | if nil == Validate(struct { 2937 | field rune `validate:"gte=abc"` 2938 | }{ 2939 | field: -1, 2940 | }) { 2941 | t.Errorf("gte validator does not validate for rune") 2942 | } 2943 | 2944 | if nil == Validate(struct { 2945 | field rune `validate:"gte=0"` 2946 | }{ 2947 | field: -1, 2948 | }) { 2949 | t.Errorf("gte validator does not validate for rune") 2950 | } 2951 | 2952 | if nil != Validate(struct { 2953 | field rune `validate:"gte=0"` 2954 | }{ 2955 | field: 0, 2956 | }) { 2957 | t.Errorf("gte validator does not validate for rune") 2958 | } 2959 | } 2960 | 2961 | func TestLteValForRune(t *testing.T) { 2962 | if nil == Validate(struct { 2963 | field rune `validate:"lte=abc"` 2964 | }{ 2965 | field: 1, 2966 | }) { 2967 | t.Errorf("lte validator does not validate for rune") 2968 | } 2969 | 2970 | if nil == Validate(struct { 2971 | field rune `validate:"lte=0"` 2972 | }{ 2973 | field: 1, 2974 | }) { 2975 | t.Errorf("lte validator does not validate for rune") 2976 | } 2977 | 2978 | if nil != Validate(struct { 2979 | field rune `validate:"lte=0"` 2980 | }{ 2981 | field: 0, 2982 | }) { 2983 | t.Errorf("lte validator does not validate for rune") 2984 | } 2985 | } 2986 | 2987 | func TestGteValForUint(t *testing.T) { 2988 | if nil == Validate(struct { 2989 | field uint `validate:"gte=abc"` 2990 | }{ 2991 | field: 9, 2992 | }) { 2993 | t.Errorf("gte validator does not validate for uint") 2994 | } 2995 | 2996 | if nil == Validate(struct { 2997 | field uint `validate:"gte=10"` 2998 | }{ 2999 | field: 9, 3000 | }) { 3001 | t.Errorf("gte validator does not validate for uint") 3002 | } 3003 | 3004 | if nil == Validate(struct { 3005 | field uint8 `validate:"gte=10"` 3006 | }{ 3007 | field: 9, 3008 | }) { 3009 | t.Errorf("gte validator does not validate for uint8") 3010 | } 3011 | 3012 | if nil == Validate(struct { 3013 | field uint16 `validate:"gte=10"` 3014 | }{ 3015 | field: 9, 3016 | }) { 3017 | t.Errorf("gte validator does not validate for uint16") 3018 | } 3019 | 3020 | if nil == Validate(struct { 3021 | field uint32 `validate:"gte=10"` 3022 | }{ 3023 | field: 9, 3024 | }) { 3025 | t.Errorf("gte validator does not validate for uint32") 3026 | } 3027 | 3028 | if nil == Validate(struct { 3029 | field uint64 `validate:"gte=10"` 3030 | }{ 3031 | field: 9, 3032 | }) { 3033 | t.Errorf("gte validator does not validate for uint64") 3034 | } 3035 | 3036 | if nil == Validate(struct { 3037 | field uintptr `validate:"gte=10"` 3038 | }{ 3039 | field: 9, 3040 | }) { 3041 | t.Errorf("gte validator does not validate for uintptr") 3042 | } 3043 | 3044 | if nil != Validate(struct { 3045 | field uint `validate:"gte=10"` 3046 | }{ 3047 | field: 10, 3048 | }) { 3049 | t.Errorf("gte validator does not validate for uint") 3050 | } 3051 | 3052 | if nil != Validate(struct { 3053 | field uint8 `validate:"gte=10"` 3054 | }{ 3055 | field: 10, 3056 | }) { 3057 | t.Errorf("gte validator does not validate for uint8") 3058 | } 3059 | 3060 | if nil != Validate(struct { 3061 | field uint16 `validate:"gte=10"` 3062 | }{ 3063 | field: 10, 3064 | }) { 3065 | t.Errorf("gte validator does not validate for uint16") 3066 | } 3067 | 3068 | if nil != Validate(struct { 3069 | field uint32 `validate:"gte=10"` 3070 | }{ 3071 | field: 10, 3072 | }) { 3073 | t.Errorf("gte validator does not validate for uint32") 3074 | } 3075 | 3076 | if nil != Validate(struct { 3077 | field uint64 `validate:"gte=10"` 3078 | }{ 3079 | field: 10, 3080 | }) { 3081 | t.Errorf("gte validator does not validate for uint64") 3082 | } 3083 | 3084 | if nil != Validate(struct { 3085 | field uintptr `validate:"gte=10"` 3086 | }{ 3087 | field: 10, 3088 | }) { 3089 | t.Errorf("gte validator does not validate for uintptr") 3090 | } 3091 | } 3092 | 3093 | func TestLteValForUint(t *testing.T) { 3094 | if nil == Validate(struct { 3095 | field uint `validate:"lte=abc"` 3096 | }{ 3097 | field: 1, 3098 | }) { 3099 | t.Errorf("lte validator does not validate for uint") 3100 | } 3101 | 3102 | if nil == Validate(struct { 3103 | field uint `validate:"lte=0"` 3104 | }{ 3105 | field: 1, 3106 | }) { 3107 | t.Errorf("lte validator does not validate for uint") 3108 | } 3109 | 3110 | if nil == Validate(struct { 3111 | field uint8 `validate:"lte=0"` 3112 | }{ 3113 | field: 1, 3114 | }) { 3115 | t.Errorf("lte validator does not validate for uint8") 3116 | } 3117 | 3118 | if nil == Validate(struct { 3119 | field uint16 `validate:"lte=0"` 3120 | }{ 3121 | field: 1, 3122 | }) { 3123 | t.Errorf("lte validator does not validate for uint16") 3124 | } 3125 | 3126 | if nil == Validate(struct { 3127 | field uint32 `validate:"lte=0"` 3128 | }{ 3129 | field: 1, 3130 | }) { 3131 | t.Errorf("lte validator does not validate for uint32") 3132 | } 3133 | 3134 | if nil == Validate(struct { 3135 | field uint64 `validate:"lte=0"` 3136 | }{ 3137 | field: 1, 3138 | }) { 3139 | t.Errorf("lte validator does not validate for uint64") 3140 | } 3141 | 3142 | if nil == Validate(struct { 3143 | field uintptr `validate:"lte=0"` 3144 | }{ 3145 | field: 1, 3146 | }) { 3147 | t.Errorf("lte validator does not validate for uintptr") 3148 | } 3149 | 3150 | if nil != Validate(struct { 3151 | field uint `validate:"lte=0"` 3152 | }{ 3153 | field: 0, 3154 | }) { 3155 | t.Errorf("lte validator does not validate for uint") 3156 | } 3157 | 3158 | if nil != Validate(struct { 3159 | field uint8 `validate:"lte=0"` 3160 | }{ 3161 | field: 0, 3162 | }) { 3163 | t.Errorf("lte validator does not validate for uint8") 3164 | } 3165 | 3166 | if nil != Validate(struct { 3167 | field uint16 `validate:"lte=0"` 3168 | }{ 3169 | field: 0, 3170 | }) { 3171 | t.Errorf("lte validator does not validate for uint16") 3172 | } 3173 | 3174 | if nil != Validate(struct { 3175 | field uint32 `validate:"lte=0"` 3176 | }{ 3177 | field: 0, 3178 | }) { 3179 | t.Errorf("lte validator does not validate for uint32") 3180 | } 3181 | 3182 | if nil != Validate(struct { 3183 | field uint64 `validate:"lte=0"` 3184 | }{ 3185 | field: 0, 3186 | }) { 3187 | t.Errorf("lte validator does not validate for uint64") 3188 | } 3189 | 3190 | if nil != Validate(struct { 3191 | field uint64 `validate:"lte=0"` 3192 | }{ 3193 | field: 0, 3194 | }) { 3195 | t.Errorf("lte validator does not validate for uintptr") 3196 | } 3197 | } 3198 | 3199 | func TestGteValForFloat(t *testing.T) { 3200 | if nil == Validate(struct { 3201 | field float32 `validate:"gte=abc"` 3202 | }{ 3203 | field: -0.1, 3204 | }) { 3205 | t.Errorf("gte validator does not validate for flaot32") 3206 | } 3207 | 3208 | if nil == Validate(struct { 3209 | field float32 `validate:"gte=0"` 3210 | }{ 3211 | field: -0.1, 3212 | }) { 3213 | t.Errorf("gte validator does not validate for flaot32") 3214 | } 3215 | 3216 | if nil == Validate(struct { 3217 | field float64 `validate:"gte=0"` 3218 | }{ 3219 | field: -0.1, 3220 | }) { 3221 | t.Errorf("gte validator does not validate for flaot64") 3222 | } 3223 | 3224 | if nil != Validate(struct { 3225 | field float32 `validate:"gte=0"` 3226 | }{ 3227 | field: 0, 3228 | }) { 3229 | t.Errorf("gte validator does not validate for flaot32") 3230 | } 3231 | 3232 | if nil != Validate(struct { 3233 | field float64 `validate:"gte=0"` 3234 | }{ 3235 | field: 0, 3236 | }) { 3237 | t.Errorf("gte validator does not validate for flaot64") 3238 | } 3239 | } 3240 | 3241 | func TestLteValForFloat(t *testing.T) { 3242 | if nil == Validate(struct { 3243 | field float32 `validate:"lte=abc"` 3244 | }{ 3245 | field: 0.1, 3246 | }) { 3247 | t.Errorf("lte validator does not validate for flaot32") 3248 | } 3249 | 3250 | if nil == Validate(struct { 3251 | field float32 `validate:"lte=0"` 3252 | }{ 3253 | field: 0.1, 3254 | }) { 3255 | t.Errorf("lte validator does not validate for flaot32") 3256 | } 3257 | 3258 | if nil == Validate(struct { 3259 | field float64 `validate:"lte=0"` 3260 | }{ 3261 | field: 0.1, 3262 | }) { 3263 | t.Errorf("lte validator does not validate for flaot64") 3264 | } 3265 | 3266 | if nil != Validate(struct { 3267 | field float32 `validate:"lte=0"` 3268 | }{ 3269 | field: 0, 3270 | }) { 3271 | t.Errorf("lte validator does not validate for flaot32") 3272 | } 3273 | 3274 | if nil != Validate(struct { 3275 | field float64 `validate:"lte=0"` 3276 | }{ 3277 | field: 0, 3278 | }) { 3279 | t.Errorf("lte validator does not validate for flaot64") 3280 | } 3281 | } 3282 | 3283 | func TestGteValForString(t *testing.T) { 3284 | if nil == Validate(struct { 3285 | field string `validate:"gte=abc"` 3286 | }{ 3287 | field: "a", 3288 | }) { 3289 | t.Errorf("gte validator does not validate for string") 3290 | } 3291 | 3292 | if nil == Validate(struct { 3293 | field string `validate:"gte=2"` 3294 | }{ 3295 | field: "a", 3296 | }) { 3297 | t.Errorf("gte validator does not validate for string") 3298 | } 3299 | 3300 | if nil != Validate(struct { 3301 | field string `validate:"gte=2"` 3302 | }{ 3303 | field: "ab", 3304 | }) { 3305 | t.Errorf("gte validator does not validate for string") 3306 | } 3307 | } 3308 | 3309 | func TestLteValForString(t *testing.T) { 3310 | if nil == Validate(struct { 3311 | field string `validate:"lte=abc"` 3312 | }{ 3313 | field: "abc", 3314 | }) { 3315 | t.Errorf("lte validator does not validate for string") 3316 | } 3317 | 3318 | if nil == Validate(struct { 3319 | field string `validate:"lte=2"` 3320 | }{ 3321 | field: "abc", 3322 | }) { 3323 | t.Errorf("lte validator does not validate for string") 3324 | } 3325 | 3326 | if nil != Validate(struct { 3327 | field string `validate:"lte=2"` 3328 | }{ 3329 | field: "ab", 3330 | }) { 3331 | t.Errorf("lte validator does not validate for string") 3332 | } 3333 | } 3334 | 3335 | func TestGteValForMap(t *testing.T) { 3336 | if nil == Validate(struct { 3337 | field map[string]string `validate:"gte=abc"` 3338 | }{ 3339 | field: map[string]string{ 3340 | "a": "a", 3341 | }, 3342 | }) { 3343 | t.Errorf("gte validator does not validate for map") 3344 | } 3345 | 3346 | if nil == Validate(struct { 3347 | field map[string]string `validate:"gte=2"` 3348 | }{ 3349 | field: map[string]string{ 3350 | "a": "a", 3351 | }, 3352 | }) { 3353 | t.Errorf("gte validator does not validate for map") 3354 | } 3355 | 3356 | if nil != Validate(struct { 3357 | field map[string]string `validate:"gte=2"` 3358 | }{ 3359 | field: map[string]string{ 3360 | "a": "a", 3361 | "b": "b", 3362 | }, 3363 | }) { 3364 | t.Errorf("gte validator does not validate for map") 3365 | } 3366 | } 3367 | 3368 | func TestLteForMap(t *testing.T) { 3369 | if nil == Validate(struct { 3370 | field map[string]string `validate:"lte=abc"` 3371 | }{ 3372 | field: map[string]string{ 3373 | "a": "a", 3374 | "b": "b", 3375 | "c": "c", 3376 | }, 3377 | }) { 3378 | t.Errorf("lte validator does not validate for map") 3379 | } 3380 | 3381 | if nil == Validate(struct { 3382 | field map[string]string `validate:"lte=2"` 3383 | }{ 3384 | field: map[string]string{ 3385 | "a": "a", 3386 | "b": "b", 3387 | "c": "c", 3388 | }, 3389 | }) { 3390 | t.Errorf("lte validator does not validate for map") 3391 | } 3392 | 3393 | if nil != Validate(struct { 3394 | field map[string]string `validate:"lte=2"` 3395 | }{ 3396 | field: map[string]string{ 3397 | "a": "a", 3398 | "b": "b", 3399 | }, 3400 | }) { 3401 | t.Errorf("lte validator does not validate for map") 3402 | } 3403 | } 3404 | 3405 | func TestGteValForSlice(t *testing.T) { 3406 | if nil == Validate(struct { 3407 | field []string `validate:"gte=abc"` 3408 | }{ 3409 | field: []string{"a"}, 3410 | }) { 3411 | t.Errorf("gte validator does not validate for slice") 3412 | } 3413 | 3414 | if nil == Validate(struct { 3415 | field []string `validate:"gte=2"` 3416 | }{ 3417 | field: []string{"a"}, 3418 | }) { 3419 | t.Errorf("gte validator does not validate for slice") 3420 | } 3421 | 3422 | if nil != Validate(struct { 3423 | field []string `validate:"gte=2"` 3424 | }{ 3425 | field: []string{"a", "b"}, 3426 | }) { 3427 | t.Errorf("gte validator does not validate for slice") 3428 | } 3429 | } 3430 | 3431 | func TestLteValForSlice(t *testing.T) { 3432 | if nil == Validate(struct { 3433 | field []string `validate:"lte=abc"` 3434 | }{ 3435 | field: []string{"a", "b", "c"}, 3436 | }) { 3437 | t.Errorf("gte validator does not validate for slice") 3438 | } 3439 | 3440 | if nil == Validate(struct { 3441 | field []string `validate:"lte=2"` 3442 | }{ 3443 | field: []string{"a", "b", "c"}, 3444 | }) { 3445 | t.Errorf("gte validator does not validate for slice") 3446 | } 3447 | 3448 | if nil != Validate(struct { 3449 | field []string `validate:"lte=2"` 3450 | }{ 3451 | field: []string{"a", "b"}, 3452 | }) { 3453 | t.Errorf("gte validator does not validate for slice") 3454 | } 3455 | } 3456 | 3457 | func TestGteValForArray(t *testing.T) { 3458 | if nil == Validate(struct { 3459 | field [1]string `validate:"gte=abc"` 3460 | }{ 3461 | field: [1]string{"a"}, 3462 | }) { 3463 | t.Errorf("gte validator does not validate for string") 3464 | } 3465 | 3466 | if nil == Validate(struct { 3467 | field [1]string `validate:"gte=2"` 3468 | }{ 3469 | field: [1]string{"a"}, 3470 | }) { 3471 | t.Errorf("gte validator does not validate for string") 3472 | } 3473 | 3474 | if nil != Validate(struct { 3475 | field [2]string `validate:"gte=2"` 3476 | }{ 3477 | field: [2]string{"a", "b"}, 3478 | }) { 3479 | t.Errorf("gte validator does not validate for string") 3480 | } 3481 | } 3482 | 3483 | func TestLteValForArray(t *testing.T) { 3484 | if nil == Validate(struct { 3485 | field [3]string `validate:"lte=abc"` 3486 | }{ 3487 | field: [3]string{"a", "b", "c"}, 3488 | }) { 3489 | t.Errorf("gte validator does not validate for array") 3490 | } 3491 | 3492 | if nil == Validate(struct { 3493 | field [3]string `validate:"lte=2"` 3494 | }{ 3495 | field: [3]string{"a", "b", "c"}, 3496 | }) { 3497 | t.Errorf("gte validator does not validate for array") 3498 | } 3499 | 3500 | if nil != Validate(struct { 3501 | field [2]string `validate:"lte=2"` 3502 | }{ 3503 | field: [2]string{"a", "b"}, 3504 | }) { 3505 | t.Errorf("gte validator does not validate for array") 3506 | } 3507 | } 3508 | 3509 | func TestEmptyValForString(t *testing.T) { 3510 | if nil == Validate(struct { 3511 | field string `validate:"empty=abc"` 3512 | }{ 3513 | field: "a", 3514 | }) { 3515 | t.Errorf("empty validator does not validate for string") 3516 | } 3517 | 3518 | if nil == Validate(struct { 3519 | field string `validate:"empty=true"` 3520 | }{ 3521 | field: "a", 3522 | }) { 3523 | t.Errorf("empty validator does not validate for string") 3524 | } 3525 | 3526 | if nil != Validate(struct { 3527 | field string `validate:"empty=true"` 3528 | }{ 3529 | field: "", 3530 | }) { 3531 | t.Errorf("empty validator does not validate for string") 3532 | } 3533 | 3534 | if nil == Validate(struct { 3535 | field string `validate:"empty=false"` 3536 | }{ 3537 | field: "", 3538 | }) { 3539 | t.Errorf("empty validator does not validate for string") 3540 | } 3541 | 3542 | if nil != Validate(struct { 3543 | field string `validate:"empty=false"` 3544 | }{ 3545 | field: "a", 3546 | }) { 3547 | t.Errorf("empty validator does not validate for string") 3548 | } 3549 | } 3550 | 3551 | func TestEmptyValForMap(t *testing.T) { 3552 | if nil == Validate(struct { 3553 | field map[string]string `validate:"empty=abc"` 3554 | }{ 3555 | field: map[string]string{"a": "a"}, 3556 | }) { 3557 | t.Errorf("empty validator does not validate for map") 3558 | } 3559 | 3560 | if nil == Validate(struct { 3561 | field map[string]string `validate:"empty=true"` 3562 | }{ 3563 | field: map[string]string{"a": "a"}, 3564 | }) { 3565 | t.Errorf("empty validator does not validate for map") 3566 | } 3567 | 3568 | if nil != Validate(struct { 3569 | field map[string]string `validate:"empty=true"` 3570 | }{ 3571 | field: map[string]string{}, 3572 | }) { 3573 | t.Errorf("empty validator does not validate for map") 3574 | } 3575 | 3576 | if nil == Validate(struct { 3577 | field map[string]string `validate:"empty=false"` 3578 | }{ 3579 | field: map[string]string{}, 3580 | }) { 3581 | t.Errorf("empty validator does not validate for map") 3582 | } 3583 | 3584 | if nil != Validate(struct { 3585 | field map[string]string `validate:"empty=false"` 3586 | }{ 3587 | field: map[string]string{"a": "a"}, 3588 | }) { 3589 | t.Errorf("empty validator does not validate for map") 3590 | } 3591 | } 3592 | 3593 | func TestEmptyValForSlice(t *testing.T) { 3594 | if nil == Validate(struct { 3595 | field []string `validate:"empty=abc"` 3596 | }{ 3597 | field: []string{ 3598 | "a", 3599 | }, 3600 | }) { 3601 | t.Errorf("empty validator does not validate for slice") 3602 | } 3603 | 3604 | if nil == Validate(struct { 3605 | field []string `validate:"empty=true"` 3606 | }{ 3607 | field: []string{ 3608 | "a", 3609 | }, 3610 | }) { 3611 | t.Errorf("empty validator does not validate for slice") 3612 | } 3613 | 3614 | if nil != Validate(struct { 3615 | field []string `validate:"empty=true"` 3616 | }{ 3617 | field: []string{}, 3618 | }) { 3619 | t.Errorf("empty validator does not validate for slice") 3620 | } 3621 | 3622 | if nil == Validate(struct { 3623 | field []string `validate:"empty=false"` 3624 | }{ 3625 | field: []string{}, 3626 | }) { 3627 | t.Errorf("empty validator does not validate for slice") 3628 | } 3629 | 3630 | if nil != Validate(struct { 3631 | field []string `validate:"empty=false"` 3632 | }{ 3633 | field: []string{"a"}, 3634 | }) { 3635 | t.Errorf("empty validator does not validate for slice") 3636 | } 3637 | } 3638 | 3639 | func TestEmptyValForArray(t *testing.T) { 3640 | if nil == Validate(struct { 3641 | field [1]string `validate:"empty=abc"` 3642 | }{ 3643 | field: [1]string{ 3644 | "a", 3645 | }, 3646 | }) { 3647 | t.Errorf("empty validator does not validate for array") 3648 | } 3649 | 3650 | if nil == Validate(struct { 3651 | field [1]string `validate:"empty=true"` 3652 | }{ 3653 | field: [1]string{ 3654 | "a", 3655 | }, 3656 | }) { 3657 | t.Errorf("empty validator does not validate for array") 3658 | } 3659 | 3660 | if nil != Validate(struct { 3661 | field [0]string `validate:"empty=true"` 3662 | }{ 3663 | field: [0]string{}, 3664 | }) { 3665 | t.Errorf("empty validator does not validate for array") 3666 | } 3667 | 3668 | if nil == Validate(struct { 3669 | field [0]string `validate:"empty=false"` 3670 | }{ 3671 | field: [0]string{}, 3672 | }) { 3673 | t.Errorf("empty validator does not validate for array") 3674 | } 3675 | 3676 | if nil != Validate(struct { 3677 | field [1]string `validate:"empty=false"` 3678 | }{ 3679 | field: [1]string{"a"}, 3680 | }) { 3681 | t.Errorf("empty validator does not validate for array") 3682 | } 3683 | } 3684 | 3685 | func TestNilValForPtr(t *testing.T) { 3686 | if nil == Validate(struct { 3687 | field *int `validate:"nil=abc"` 3688 | }{ 3689 | field: new(int), 3690 | }) { 3691 | t.Errorf("nil validator does not validate for pointer") 3692 | } 3693 | 3694 | if nil == Validate(struct { 3695 | field *int `validate:"nil=true"` 3696 | }{ 3697 | field: new(int), 3698 | }) { 3699 | t.Errorf("nil validator does not validate for pointer") 3700 | } 3701 | 3702 | if nil != Validate(struct { 3703 | field *int `validate:"nil=true"` 3704 | }{ 3705 | field: nil, 3706 | }) { 3707 | t.Errorf("nil validator does not validate for pointer") 3708 | } 3709 | 3710 | if nil == Validate(struct { 3711 | field *int `validate:"nil=false"` 3712 | }{ 3713 | field: nil, 3714 | }) { 3715 | t.Errorf("nil validator does not validate for pointer") 3716 | } 3717 | 3718 | if nil != Validate(struct { 3719 | field *int `validate:"nil=false"` 3720 | }{ 3721 | field: new(int), 3722 | }) { 3723 | t.Errorf("nil validator does not validate for pointer") 3724 | } 3725 | } 3726 | 3727 | func TestOneOfValForDuration(t *testing.T) { 3728 | if nil == Validate(struct { 3729 | field time.Duration `validate:"one_of="` 3730 | }{ 3731 | field: 4 * time.Second, 3732 | }) { 3733 | t.Errorf("one_of validator does not validate for time.Duration") 3734 | } 3735 | 3736 | if nil == Validate(struct { 3737 | field time.Duration `validate:"one_of=abc"` 3738 | }{ 3739 | field: 4 * time.Second, 3740 | }) { 3741 | t.Errorf("one_of validator does not validate for time.Duration") 3742 | } 3743 | 3744 | if nil == Validate(struct { 3745 | field time.Duration `validate:"one_of=1s,2s,3s"` 3746 | }{ 3747 | field: 4 * time.Second, 3748 | }) { 3749 | t.Errorf("one_of validator does not validate for time.Duration") 3750 | } 3751 | 3752 | if nil != Validate(struct { 3753 | field time.Duration `validate:"one_of=1s,2s,3s"` 3754 | }{ 3755 | field: 2 * time.Second, 3756 | }) { 3757 | t.Errorf("one_of validator does not validate for time.Duration") 3758 | } 3759 | } 3760 | 3761 | func TestOneOfValForInt(t *testing.T) { 3762 | if nil == Validate(struct { 3763 | field int `validate:"one_of="` 3764 | }{ 3765 | field: 4, 3766 | }) { 3767 | t.Errorf("one_of validator does not validate for int") 3768 | } 3769 | 3770 | if nil == Validate(struct { 3771 | field int `validate:"one_of=abc"` 3772 | }{ 3773 | field: 4, 3774 | }) { 3775 | t.Errorf("one_of validator does not validate for int") 3776 | } 3777 | 3778 | if nil == Validate(struct { 3779 | field int `validate:"one_of=1,2,3"` 3780 | }{ 3781 | field: 4, 3782 | }) { 3783 | t.Errorf("one_of validator does not validate for int") 3784 | } 3785 | 3786 | if nil != Validate(struct { 3787 | field int `validate:"one_of=1,2,3"` 3788 | }{ 3789 | field: 2, 3790 | }) { 3791 | t.Errorf("one_of validator does not validate for int") 3792 | } 3793 | 3794 | if nil == Validate(struct { 3795 | field int8 `validate:"one_of=1,2,3"` 3796 | }{ 3797 | field: 4, 3798 | }) { 3799 | t.Errorf("one_of validator does not validate for int8") 3800 | } 3801 | 3802 | if nil != Validate(struct { 3803 | field int8 `validate:"one_of=1,2,3"` 3804 | }{ 3805 | field: 2, 3806 | }) { 3807 | t.Errorf("one_of validator does not validate for int8") 3808 | } 3809 | 3810 | if nil == Validate(struct { 3811 | field int16 `validate:"one_of=1,2,3"` 3812 | }{ 3813 | field: 4, 3814 | }) { 3815 | t.Errorf("one_of validator does not validate for int16") 3816 | } 3817 | 3818 | if nil != Validate(struct { 3819 | field int16 `validate:"one_of=1,2,3"` 3820 | }{ 3821 | field: 2, 3822 | }) { 3823 | t.Errorf("one_of validator does not validate for int16") 3824 | } 3825 | 3826 | if nil == Validate(struct { 3827 | field int32 `validate:"one_of=1,2,3"` 3828 | }{ 3829 | field: 4, 3830 | }) { 3831 | t.Errorf("one_of validator does not validate for int32") 3832 | } 3833 | 3834 | if nil != Validate(struct { 3835 | field int32 `validate:"one_of=1,2,3"` 3836 | }{ 3837 | field: 2, 3838 | }) { 3839 | t.Errorf("one_of validator does not validate for int32") 3840 | } 3841 | 3842 | if nil == Validate(struct { 3843 | field int64 `validate:"one_of=1,2,3"` 3844 | }{ 3845 | field: 4, 3846 | }) { 3847 | t.Errorf("one_of validator does not validate for int64") 3848 | } 3849 | 3850 | if nil != Validate(struct { 3851 | field int64 `validate:"one_of=1,2,3"` 3852 | }{ 3853 | field: 2, 3854 | }) { 3855 | t.Errorf("one_of validator does not validate for int64") 3856 | } 3857 | } 3858 | 3859 | func TestOneOfValForUint(t *testing.T) { 3860 | if nil == Validate(struct { 3861 | field uint `validate:"one_of="` 3862 | }{ 3863 | field: 4, 3864 | }) { 3865 | t.Errorf("one_of validator does not validate for uint") 3866 | } 3867 | 3868 | if nil == Validate(struct { 3869 | field uint `validate:"one_of=abc"` 3870 | }{ 3871 | field: 4, 3872 | }) { 3873 | t.Errorf("one_of validator does not validate for uint") 3874 | } 3875 | 3876 | if nil == Validate(struct { 3877 | field uint `validate:"one_of=1,2,3"` 3878 | }{ 3879 | field: 4, 3880 | }) { 3881 | t.Errorf("one_of validator does not validate for uint") 3882 | } 3883 | 3884 | if nil != Validate(struct { 3885 | field uint `validate:"one_of=1,2,3"` 3886 | }{ 3887 | field: 2, 3888 | }) { 3889 | t.Errorf("one_of validator does not validate for uint") 3890 | } 3891 | 3892 | if nil == Validate(struct { 3893 | field uint8 `validate:"one_of=1,2,3"` 3894 | }{ 3895 | field: 4, 3896 | }) { 3897 | t.Errorf("one_of validator does not validate for uint8") 3898 | } 3899 | 3900 | if nil != Validate(struct { 3901 | field uint8 `validate:"one_of=1,2,3"` 3902 | }{ 3903 | field: 2, 3904 | }) { 3905 | t.Errorf("one_of validator does not validate for uint8") 3906 | } 3907 | 3908 | if nil == Validate(struct { 3909 | field uint16 `validate:"one_of=1,2,3"` 3910 | }{ 3911 | field: 4, 3912 | }) { 3913 | t.Errorf("one_of validator does not validate for uint16") 3914 | } 3915 | 3916 | if nil != Validate(struct { 3917 | field uint16 `validate:"one_of=1,2,3"` 3918 | }{ 3919 | field: 2, 3920 | }) { 3921 | t.Errorf("one_of validator does not validate for uint16") 3922 | } 3923 | 3924 | if nil == Validate(struct { 3925 | field uint32 `validate:"one_of=1,2,3"` 3926 | }{ 3927 | field: 4, 3928 | }) { 3929 | t.Errorf("one_of validator does not validate for uint32") 3930 | } 3931 | 3932 | if nil != Validate(struct { 3933 | field uint32 `validate:"one_of=1,2,3"` 3934 | }{ 3935 | field: 2, 3936 | }) { 3937 | t.Errorf("one_of validator does not validate for uint32") 3938 | } 3939 | 3940 | if nil == Validate(struct { 3941 | field uint64 `validate:"one_of=1,2,3"` 3942 | }{ 3943 | field: 4, 3944 | }) { 3945 | t.Errorf("one_of validator does not validate for uint64") 3946 | } 3947 | 3948 | if nil != Validate(struct { 3949 | field uint64 `validate:"one_of=1,2,3"` 3950 | }{ 3951 | field: 2, 3952 | }) { 3953 | t.Errorf("one_of validator does not validate for uint64") 3954 | } 3955 | } 3956 | 3957 | func TestOneOfValForFloat(t *testing.T) { 3958 | if nil == Validate(struct { 3959 | field float32 `validate:"one_of="` 3960 | }{ 3961 | field: 4.0, 3962 | }) { 3963 | t.Errorf("one_of validator does not validate for float32") 3964 | } 3965 | 3966 | if nil == Validate(struct { 3967 | field float32 `validate:"one_of=abc"` 3968 | }{ 3969 | field: 4.0, 3970 | }) { 3971 | t.Errorf("one_of validator does not validate for float32") 3972 | } 3973 | 3974 | if nil == Validate(struct { 3975 | field float32 `validate:"one_of=1.0,2.0,3.0"` 3976 | }{ 3977 | field: 4.0, 3978 | }) { 3979 | t.Errorf("one_of validator does not validate for float32") 3980 | } 3981 | 3982 | if nil != Validate(struct { 3983 | field float32 `validate:"one_of=1.0,2.0,3.0"` 3984 | }{ 3985 | field: 2.0, 3986 | }) { 3987 | t.Errorf("one_of validator does not validate for float32") 3988 | } 3989 | 3990 | if nil == Validate(struct { 3991 | field float64 `validate:"one_of=1.0,2.0,3.0"` 3992 | }{ 3993 | field: 4.0, 3994 | }) { 3995 | t.Errorf("one_of validator does not validate for float64") 3996 | } 3997 | 3998 | if nil != Validate(struct { 3999 | field float64 `validate:"one_of=1.0,2.0,3.0"` 4000 | }{ 4001 | field: 2.0, 4002 | }) { 4003 | t.Errorf("one_of validator does not validate for float64") 4004 | } 4005 | } 4006 | 4007 | func TestOneOfValForString(t *testing.T) { 4008 | if nil == Validate(struct { 4009 | field string `validate:"one_of="` 4010 | }{ 4011 | field: "four", 4012 | }) { 4013 | t.Errorf("one_of validator does not validate for string") 4014 | } 4015 | 4016 | if nil == Validate(struct { 4017 | field string `validate:"one_of=one,two,three"` 4018 | }{ 4019 | field: "four", 4020 | }) { 4021 | t.Errorf("one_of validator does not validate for string") 4022 | } 4023 | 4024 | if nil != Validate(struct { 4025 | field string `validate:"one_of=one,two,three"` 4026 | }{ 4027 | field: "two", 4028 | }) { 4029 | t.Errorf("one_of validator does not validate for string") 4030 | } 4031 | } 4032 | 4033 | func TestFormatValForString(t *testing.T) { 4034 | if nil == Validate(struct { 4035 | field string `validate:"format=abc"` 4036 | }{ 4037 | field: "abc", 4038 | }) { 4039 | t.Errorf("format validator does not validate for string") 4040 | } 4041 | 4042 | if nil == Validate(struct { 4043 | field string `validate:"format=email"` 4044 | }{ 4045 | field: "abc", 4046 | }) { 4047 | t.Errorf("format validator does not validate for string") 4048 | } 4049 | 4050 | if nil != Validate(struct { 4051 | field string `validate:"format=email"` 4052 | }{ 4053 | field: "abc@example.com", 4054 | }) { 4055 | t.Errorf("format validator does not validate for string") 4056 | } 4057 | } 4058 | 4059 | func TestDeepValsForStruct(t *testing.T) { 4060 | s := " " 4061 | 4062 | if nil == Validate(struct { 4063 | field struct { 4064 | field int `validate:"gte=0"` 4065 | } 4066 | }{ 4067 | field: struct { 4068 | field int `validate:"gte=0"` 4069 | }{field: -1}, 4070 | }) { 4071 | t.Errorf("gte validator does not validate for struct field") 4072 | } 4073 | 4074 | if nil != Validate(struct { 4075 | field struct { 4076 | field int `validate:"gte=0"` 4077 | } 4078 | }{ 4079 | field: struct { 4080 | field int `validate:"gte=0"` 4081 | }{field: 0}, 4082 | }) { 4083 | t.Errorf("gte validator does not validate for struct field") 4084 | } 4085 | 4086 | if nil == Validate(struct { 4087 | field struct { 4088 | field int `validate:"lte=0"` 4089 | } 4090 | }{ 4091 | field: struct { 4092 | field int `validate:"lte=0"` 4093 | }{field: 1}, 4094 | }) { 4095 | t.Errorf("lte validator does not validate for struct field") 4096 | } 4097 | 4098 | if nil != Validate(struct { 4099 | field struct { 4100 | field int `validate:"lte=0"` 4101 | } 4102 | }{ 4103 | field: struct { 4104 | field int `validate:"lte=0"` 4105 | }{field: 0}, 4106 | }) { 4107 | t.Errorf("lte validator does not validate for struct field") 4108 | } 4109 | 4110 | if nil == Validate(struct { 4111 | field struct { 4112 | field string `validate:"empty=true"` 4113 | } 4114 | }{ 4115 | field: struct { 4116 | field string `validate:"empty=true"` 4117 | }{field: " "}, 4118 | }) { 4119 | t.Errorf("empty validator does not validate for struct field") 4120 | } 4121 | 4122 | if nil != Validate(struct { 4123 | field struct { 4124 | field string `validate:"empty=true"` 4125 | } 4126 | }{ 4127 | field: struct { 4128 | field string `validate:"empty=true"` 4129 | }{field: ""}, 4130 | }) { 4131 | t.Errorf("empty validator does not validate for struct field") 4132 | } 4133 | 4134 | if nil == Validate(struct { 4135 | field struct { 4136 | field string `validate:"empty=false"` 4137 | } 4138 | }{ 4139 | field: struct { 4140 | field string `validate:"empty=false"` 4141 | }{field: ""}, 4142 | }) { 4143 | t.Errorf("empty validator does not validate for struct field") 4144 | } 4145 | 4146 | if nil != Validate(struct { 4147 | field struct { 4148 | field string `validate:"empty=false"` 4149 | } 4150 | }{ 4151 | field: struct { 4152 | field string `validate:"empty=false"` 4153 | }{field: " "}, 4154 | }) { 4155 | t.Errorf("empty validator does not validate for struct field") 4156 | } 4157 | 4158 | if nil != Validate(struct { 4159 | field struct { 4160 | field int `validate:"lte=0"` 4161 | } 4162 | }{ 4163 | field: struct { 4164 | field int `validate:"lte=0"` 4165 | }{field: 0}, 4166 | }) { 4167 | t.Errorf("lte validator does not validate for struct field") 4168 | } 4169 | 4170 | if nil == Validate(struct { 4171 | field struct { 4172 | field *string `validate:"nil=true"` 4173 | } 4174 | }{ 4175 | field: struct { 4176 | field *string `validate:"nil=true"` 4177 | }{field: &s}, 4178 | }) { 4179 | t.Errorf("nil validator does not validate for struct field") 4180 | } 4181 | 4182 | if nil != Validate(struct { 4183 | field struct { 4184 | field *string `validate:"nil=true"` 4185 | } 4186 | }{ 4187 | field: struct { 4188 | field *string `validate:"nil=true"` 4189 | }{field: nil}, 4190 | }) { 4191 | t.Errorf("nil validator does not validate for struct field") 4192 | } 4193 | 4194 | if nil == Validate(struct { 4195 | field struct { 4196 | field *string `validate:"nil=false"` 4197 | } 4198 | }{ 4199 | field: struct { 4200 | field *string `validate:"nil=false"` 4201 | }{field: nil}, 4202 | }) { 4203 | t.Errorf("nil validator does not validate for struct field") 4204 | } 4205 | 4206 | if nil != Validate(struct { 4207 | field struct { 4208 | field *string `validate:"nil=false"` 4209 | } 4210 | }{ 4211 | field: struct { 4212 | field *string `validate:"nil=false"` 4213 | }{field: &s}, 4214 | }) { 4215 | t.Errorf("nil validator does not validate for struct field") 4216 | } 4217 | 4218 | if nil == Validate(struct { 4219 | field struct { 4220 | field int `validate:"one_of=1,2,3"` 4221 | } 4222 | }{ 4223 | field: struct { 4224 | field int `validate:"one_of=1,2,3"` 4225 | }{field: 4}, 4226 | }) { 4227 | t.Errorf("one_of validator does not validate for struct field") 4228 | } 4229 | 4230 | if nil != Validate(struct { 4231 | field struct { 4232 | field int `validate:"one_of=1,2,3"` 4233 | } 4234 | }{ 4235 | field: struct { 4236 | field int `validate:"one_of=1,2,3"` 4237 | }{field: 1}, 4238 | }) { 4239 | t.Errorf("one_of validator does not validate for struct field") 4240 | } 4241 | 4242 | if nil == Validate(struct { 4243 | field struct { 4244 | field string `validate:"format=email"` 4245 | } 4246 | }{ 4247 | field: struct { 4248 | field string `validate:"format=email"` 4249 | }{field: "abc"}, 4250 | }) { 4251 | t.Errorf("format validator does not validate for struct field") 4252 | } 4253 | 4254 | if nil != Validate(struct { 4255 | field struct { 4256 | field string `validate:"format=email"` 4257 | } 4258 | }{ 4259 | field: struct { 4260 | field string `validate:"format=email"` 4261 | }{field: "abc@example.com"}, 4262 | }) { 4263 | t.Errorf("format validator does not validate for struct field") 4264 | } 4265 | } 4266 | 4267 | func TestDeepValsForNestedStruct(t *testing.T) { 4268 | type A struct { 4269 | field int `validate:"gte=0"` 4270 | } 4271 | 4272 | type B struct { 4273 | A 4274 | field int `validate:"gte=0"` 4275 | } 4276 | 4277 | if nil == Validate(B{ 4278 | A: A{ 4279 | field: -1, 4280 | }, 4281 | field: 0, 4282 | }) { 4283 | t.Errorf("validator does not validate for nested struct") 4284 | } 4285 | 4286 | if nil == Validate(B{ 4287 | A: A{ 4288 | field: 0, 4289 | }, 4290 | field: -1, 4291 | }) { 4292 | t.Errorf("validator does not validate for nested struct") 4293 | } 4294 | 4295 | if nil != Validate(B{ 4296 | A: A{ 4297 | field: 0, 4298 | }, 4299 | field: 0, 4300 | }) { 4301 | t.Errorf("validator does not validate for nested struct") 4302 | } 4303 | } 4304 | 4305 | func TestDeepValsForMapKeys(t *testing.T) { 4306 | s := " " 4307 | 4308 | if nil == Validate(struct { 4309 | field map[int]int `validate:"[gte=0]"` 4310 | }{ 4311 | field: map[int]int{0: 0, -1: 0}, 4312 | }) { 4313 | t.Errorf("[gte] validator does not validate for map key") 4314 | } 4315 | 4316 | if nil != Validate(struct { 4317 | field map[int]int `validate:"[gte=0]"` 4318 | }{ 4319 | field: map[int]int{0: 0}, 4320 | }) { 4321 | t.Errorf("[gte] validator does not validate map key") 4322 | } 4323 | 4324 | if nil == Validate(struct { 4325 | field map[int]int `validate:"[lte=0]"` 4326 | }{ 4327 | field: map[int]int{0: 0, 1: 0}, 4328 | }) { 4329 | t.Errorf("[lte] validator does not validate for map key") 4330 | } 4331 | 4332 | if nil != Validate(struct { 4333 | field map[int]int `validate:"[lte=0]"` 4334 | }{ 4335 | field: map[int]int{0: 0}, 4336 | }) { 4337 | t.Errorf("[lte] validator does not validate for map key") 4338 | } 4339 | 4340 | if nil == Validate(struct { 4341 | field map[string]int `validate:"[empty=true]"` 4342 | }{ 4343 | field: map[string]int{ 4344 | " ": 0, 4345 | }, 4346 | }) { 4347 | t.Errorf("[empty] validator does not validate for map key") 4348 | } 4349 | 4350 | if nil != Validate(struct { 4351 | field map[string]int `validate:"[empty=true]"` 4352 | }{ 4353 | field: map[string]int{ 4354 | "": 0, 4355 | }, 4356 | }) { 4357 | t.Errorf("[empty] validator does not validate for map key") 4358 | } 4359 | 4360 | if nil == Validate(struct { 4361 | field map[string]int `validate:"[empty=false]"` 4362 | }{ 4363 | field: map[string]int{ 4364 | "": 0, 4365 | }, 4366 | }) { 4367 | t.Errorf("[empty] validator does not validate for map key") 4368 | } 4369 | 4370 | if nil != Validate(struct { 4371 | field map[string]int `validate:"[empty=false]"` 4372 | }{ 4373 | field: map[string]int{ 4374 | " ": 0, 4375 | }, 4376 | }) { 4377 | t.Errorf("[empty] validator does not validate for map key") 4378 | } 4379 | 4380 | if nil == Validate(struct { 4381 | field map[*string]int `validate:"[nil=true]"` 4382 | }{ 4383 | field: map[*string]int{ 4384 | &s: 0, 4385 | }, 4386 | }) { 4387 | t.Errorf("[nil] validator does not validate for map key") 4388 | } 4389 | 4390 | if nil != Validate(struct { 4391 | field map[*string]int `validate:"[nil=true]"` 4392 | }{ 4393 | field: map[*string]int{ 4394 | nil: 0, 4395 | }, 4396 | }) { 4397 | t.Errorf("[nil] validator does not validate for map key") 4398 | } 4399 | 4400 | if nil == Validate(struct { 4401 | field map[*string]int `validate:"[nil=false]"` 4402 | }{ 4403 | field: map[*string]int{ 4404 | nil: 0, 4405 | }, 4406 | }) { 4407 | t.Errorf("[nil] validator does not validate for map key") 4408 | } 4409 | 4410 | if nil != Validate(struct { 4411 | field map[*string]int `validate:"[nil=false]"` 4412 | }{ 4413 | field: map[*string]int{ 4414 | &s: 0, 4415 | }, 4416 | }) { 4417 | t.Errorf("[nil] validator does not validate for map key") 4418 | } 4419 | 4420 | if nil == Validate(struct { 4421 | field map[int]int `validate:"[one_of=1,2,3]"` 4422 | }{ 4423 | field: map[int]int{ 4424 | 4: 0, 4425 | }, 4426 | }) { 4427 | t.Errorf("[one_of] validator does not validate for map key") 4428 | } 4429 | 4430 | if nil != Validate(struct { 4431 | field map[int]int `validate:"[one_of=1,2,3]"` 4432 | }{ 4433 | field: map[int]int{ 4434 | 1: 0, 4435 | 2: 0, 4436 | 3: 0, 4437 | }, 4438 | }) { 4439 | t.Errorf("[one_of] validator does not validate for map key") 4440 | } 4441 | 4442 | if nil == Validate(struct { 4443 | field map[string]int `validate:"[format=email]"` 4444 | }{ 4445 | field: map[string]int{ 4446 | "abc": 0, 4447 | }, 4448 | }) { 4449 | t.Errorf("[format] validator does not validate for map key") 4450 | } 4451 | 4452 | if nil != Validate(struct { 4453 | field map[string]int `validate:"[format=email]"` 4454 | }{ 4455 | field: map[string]int{ 4456 | "abc@example.com": 0, 4457 | }, 4458 | }) { 4459 | t.Errorf("[format] validator does not validate for map key") 4460 | } 4461 | } 4462 | 4463 | func TestDeepValsForMapValues(t *testing.T) { 4464 | s := " " 4465 | 4466 | if nil == Validate(struct { 4467 | field map[int]int `validate:"> gte=0"` 4468 | }{ 4469 | field: map[int]int{0: 0, 1: -1}, 4470 | }) { 4471 | t.Errorf(">gte validator does not validate for map values") 4472 | } 4473 | 4474 | if nil != Validate(struct { 4475 | field map[int]int `validate:"> gte=0"` 4476 | }{ 4477 | field: map[int]int{0: 0}, 4478 | }) { 4479 | t.Errorf(">gte validator does not validate map values") 4480 | } 4481 | 4482 | if nil == Validate(struct { 4483 | field map[int]int `validate:"> lte=0"` 4484 | }{ 4485 | field: map[int]int{0: 0, -1: 1}, 4486 | }) { 4487 | t.Errorf(">lte validator does not validate for map values") 4488 | } 4489 | 4490 | if nil != Validate(struct { 4491 | field map[int]int `validate:"> lte=0"` 4492 | }{ 4493 | field: map[int]int{0: 0}, 4494 | }) { 4495 | t.Errorf(">lte validator does not validate for map values") 4496 | } 4497 | 4498 | if nil == Validate(struct { 4499 | field map[int]string `validate:"> empty=true"` 4500 | }{ 4501 | field: map[int]string{ 4502 | 0: " ", 4503 | }, 4504 | }) { 4505 | t.Errorf(">empty validator does not validate for map values") 4506 | } 4507 | 4508 | if nil != Validate(struct { 4509 | field map[int]string `validate:"> empty=true"` 4510 | }{ 4511 | field: map[int]string{ 4512 | 0: "", 4513 | }, 4514 | }) { 4515 | t.Errorf(">empty validator does not validate for map values") 4516 | } 4517 | 4518 | if nil == Validate(struct { 4519 | field map[int]string `validate:"> empty=false"` 4520 | }{ 4521 | field: map[int]string{ 4522 | 0: "", 4523 | }, 4524 | }) { 4525 | t.Errorf(">empty validator does not validate for map values") 4526 | } 4527 | 4528 | if nil != Validate(struct { 4529 | field map[int]string `validate:"> empty=false"` 4530 | }{ 4531 | field: map[int]string{ 4532 | 0: " ", 4533 | }, 4534 | }) { 4535 | t.Errorf(">empty validator does not validate for map values") 4536 | } 4537 | 4538 | if nil == Validate(struct { 4539 | field map[int]*string `validate:"> nil=true"` 4540 | }{ 4541 | field: map[int]*string{ 4542 | 0: &s, 4543 | }, 4544 | }) { 4545 | t.Errorf(">nil validator does not validate for map values") 4546 | } 4547 | 4548 | if nil != Validate(struct { 4549 | field map[int]*string `validate:"> nil=true"` 4550 | }{ 4551 | field: map[int]*string{ 4552 | 0: nil, 4553 | }, 4554 | }) { 4555 | t.Errorf(">nil validator does not validate for map values") 4556 | } 4557 | 4558 | if nil == Validate(struct { 4559 | field map[int]*string `validate:"> nil=false"` 4560 | }{ 4561 | field: map[int]*string{ 4562 | 0: nil, 4563 | }, 4564 | }) { 4565 | t.Errorf(">nil validator does not validate for map values") 4566 | } 4567 | 4568 | if nil != Validate(struct { 4569 | field map[int]*string `validate:"> nil=false"` 4570 | }{ 4571 | field: map[int]*string{ 4572 | 0: &s, 4573 | }, 4574 | }) { 4575 | t.Errorf(">nil validator does not validate for map values") 4576 | } 4577 | 4578 | if nil == Validate(struct { 4579 | field map[int]int `validate:"> one_of=1,2,3"` 4580 | }{ 4581 | field: map[int]int{ 4582 | 0: 4, 4583 | }, 4584 | }) { 4585 | t.Errorf(">one_of validator does not validate for map values") 4586 | } 4587 | 4588 | if nil != Validate(struct { 4589 | field map[int]int `validate:"> one_of=1,2,3"` 4590 | }{ 4591 | field: map[int]int{ 4592 | -1: 1, 4593 | -2: 2, 4594 | -3: 3, 4595 | }, 4596 | }) { 4597 | t.Errorf(">one_of validator does not validate for map values") 4598 | } 4599 | 4600 | if nil == Validate(struct { 4601 | field map[int]string `validate:"> format=email"` 4602 | }{ 4603 | field: map[int]string{ 4604 | 0: "abc", 4605 | }, 4606 | }) { 4607 | t.Errorf(">format validator does not validate for map values") 4608 | } 4609 | 4610 | if nil != Validate(struct { 4611 | field map[int]string `validate:"> format=email"` 4612 | }{ 4613 | field: map[int]string{ 4614 | 0: "abc@example.com", 4615 | }, 4616 | }) { 4617 | t.Errorf(">format validator does not validate for map values") 4618 | } 4619 | } 4620 | 4621 | func TestDeepValsForSlice(t *testing.T) { 4622 | if nil == Validate(struct { 4623 | field []int `validate:">gte=0"` 4624 | }{ 4625 | field: []int{0, -1}, 4626 | }) { 4627 | t.Errorf(">gte validator does not validate for slice") 4628 | } 4629 | 4630 | if nil != Validate(struct { 4631 | field []int `validate:">gte=0"` 4632 | }{ 4633 | field: []int{0, 0}, 4634 | }) { 4635 | t.Errorf(">gte validator does not validate for slice") 4636 | } 4637 | 4638 | if nil == Validate(struct { 4639 | field []int `validate:">lte=0"` 4640 | }{ 4641 | field: []int{0, 1}, 4642 | }) { 4643 | t.Errorf(">lte validator does not validate for slice") 4644 | } 4645 | 4646 | if nil != Validate(struct { 4647 | field []int `validate:">lte=0"` 4648 | }{ 4649 | field: []int{0, 0}, 4650 | }) { 4651 | t.Errorf(">lte validator does not validate for slice") 4652 | } 4653 | 4654 | if nil == Validate(struct { 4655 | field [][]int `validate:">empty=true"` 4656 | }{ 4657 | field: [][]int{ 4658 | []int{0}, 4659 | }, 4660 | }) { 4661 | t.Errorf(">empty validator does not validate for slice") 4662 | } 4663 | 4664 | if nil != Validate(struct { 4665 | field [][]int `validate:">empty=true"` 4666 | }{ 4667 | field: [][]int{ 4668 | []int{}, 4669 | }, 4670 | }) { 4671 | t.Errorf(">empty validator does not validate for slice") 4672 | } 4673 | 4674 | if nil == Validate(struct { 4675 | field [][]int `validate:">empty=false"` 4676 | }{ 4677 | field: [][]int{ 4678 | []int{}, 4679 | }, 4680 | }) { 4681 | t.Errorf(">empty validator does not validate for slice") 4682 | } 4683 | 4684 | if nil != Validate(struct { 4685 | field [][]int `validate:">empty=false"` 4686 | }{ 4687 | field: [][]int{ 4688 | []int{0}, 4689 | }, 4690 | }) { 4691 | t.Errorf(">empty validator does not validate for slice") 4692 | } 4693 | 4694 | if nil == Validate(struct { 4695 | field []*int `validate:">nil=true"` 4696 | }{ 4697 | field: []*int{ 4698 | new(int), 4699 | }, 4700 | }) { 4701 | t.Errorf(">nil validator does not validate for slice") 4702 | } 4703 | 4704 | if nil != Validate(struct { 4705 | field []*int `validate:">nil=true"` 4706 | }{ 4707 | field: []*int{nil}, 4708 | }) { 4709 | t.Errorf(">nil validator does not validate for slice") 4710 | } 4711 | 4712 | if nil == Validate(struct { 4713 | field []*int `validate:">nil=false"` 4714 | }{ 4715 | field: []*int{nil}, 4716 | }) { 4717 | t.Errorf(">nil validator does not validate for slice") 4718 | } 4719 | 4720 | if nil != Validate(struct { 4721 | field []*int `validate:">nil=false"` 4722 | }{ 4723 | field: []*int{new(int)}, 4724 | }) { 4725 | t.Errorf(">nil validator does not validate for slice") 4726 | } 4727 | 4728 | if nil == Validate(struct { 4729 | field []int `validate:">one_of=1,2,3"` 4730 | }{ 4731 | field: []int{4}, 4732 | }) { 4733 | t.Errorf(">one_of validator does not validate for slice") 4734 | } 4735 | 4736 | if nil != Validate(struct { 4737 | field []int `validate:">one_of=1,2,3"` 4738 | }{ 4739 | field: []int{1, 2, 3}, 4740 | }) { 4741 | t.Errorf(">one_of validator does not validate for slice") 4742 | } 4743 | 4744 | if nil == Validate(struct { 4745 | field []string `validate:">format=email"` 4746 | }{ 4747 | field: []string{"abc"}, 4748 | }) { 4749 | t.Errorf(">foormat validator does not validate for slice") 4750 | } 4751 | 4752 | if nil != Validate(struct { 4753 | field []string `validate:">format=email"` 4754 | }{ 4755 | field: []string{"abc@example.com"}, 4756 | }) { 4757 | t.Errorf(">foormat validator does not validate for slice") 4758 | } 4759 | } 4760 | 4761 | func TestDeepValsForArray(t *testing.T) { 4762 | if nil == Validate(struct { 4763 | field [2]int `validate:">gte=0"` 4764 | }{ 4765 | field: [2]int{0, -1}, 4766 | }) { 4767 | t.Errorf(">gte validator does not validate for array") 4768 | } 4769 | 4770 | if nil != Validate(struct { 4771 | field [2]int `validate:">gte=0"` 4772 | }{ 4773 | field: [2]int{0, 0}, 4774 | }) { 4775 | t.Errorf(">gte validator does not validate for array") 4776 | } 4777 | 4778 | if nil == Validate(struct { 4779 | field [2]int `validate:">lte=0"` 4780 | }{ 4781 | field: [2]int{0, 1}, 4782 | }) { 4783 | t.Errorf(">lte validator does not validate for array") 4784 | } 4785 | 4786 | if nil != Validate(struct { 4787 | field [2]int `validate:">lte=0"` 4788 | }{ 4789 | field: [2]int{0, 0}, 4790 | }) { 4791 | t.Errorf(">lte validator does not validate for array") 4792 | } 4793 | 4794 | if nil == Validate(struct { 4795 | field [1][1]int `validate:">empty=true"` 4796 | }{ 4797 | field: [1][1]int{ 4798 | [1]int{0}, 4799 | }, 4800 | }) { 4801 | t.Errorf(">empty validator does not validate for array") 4802 | } 4803 | 4804 | if nil != Validate(struct { 4805 | field [1][0]int `validate:">empty=true"` 4806 | }{ 4807 | field: [1][0]int{ 4808 | [0]int{}, 4809 | }, 4810 | }) { 4811 | t.Errorf(">empty validator does not validate for array") 4812 | } 4813 | 4814 | if nil == Validate(struct { 4815 | field [1][0]int `validate:">empty=false"` 4816 | }{ 4817 | field: [1][0]int{ 4818 | [0]int{}, 4819 | }, 4820 | }) { 4821 | t.Errorf(">empty validator does not validate for array") 4822 | } 4823 | 4824 | if nil != Validate(struct { 4825 | field [1][1]int `validate:">empty=false"` 4826 | }{ 4827 | field: [1][1]int{ 4828 | [1]int{0}, 4829 | }, 4830 | }) { 4831 | t.Errorf(">empty validator does not validate for array") 4832 | } 4833 | 4834 | if nil == Validate(struct { 4835 | field [1]*int `validate:">nil=true"` 4836 | }{ 4837 | field: [1]*int{ 4838 | new(int), 4839 | }, 4840 | }) { 4841 | t.Errorf(">nil validator does not validate for array") 4842 | } 4843 | 4844 | if nil != Validate(struct { 4845 | field [1]*int `validate:">nil=true"` 4846 | }{ 4847 | field: [1]*int{nil}, 4848 | }) { 4849 | t.Errorf(">nil validator does not validate for array") 4850 | } 4851 | 4852 | if nil == Validate(struct { 4853 | field [1]*int `validate:">nil=false"` 4854 | }{ 4855 | field: [1]*int{nil}, 4856 | }) { 4857 | t.Errorf(">nil validator does not validate for array") 4858 | } 4859 | 4860 | if nil != Validate(struct { 4861 | field [1]*int `validate:">nil=false"` 4862 | }{ 4863 | field: [1]*int{new(int)}, 4864 | }) { 4865 | t.Errorf(">nil validator does not validate for array") 4866 | } 4867 | 4868 | if nil == Validate(struct { 4869 | field [1]int `validate:">one_of=1,2,3"` 4870 | }{ 4871 | field: [1]int{4}, 4872 | }) { 4873 | t.Errorf(">one_of validator does not validate for array") 4874 | } 4875 | 4876 | if nil != Validate(struct { 4877 | field [3]int `validate:">one_of=1,2,3"` 4878 | }{ 4879 | field: [3]int{1, 2, 3}, 4880 | }) { 4881 | t.Errorf(">one_of validator does not validate for array") 4882 | } 4883 | 4884 | if nil == Validate(struct { 4885 | field [1]string `validate:">format=email"` 4886 | }{ 4887 | field: [1]string{"abc"}, 4888 | }) { 4889 | t.Errorf(">foormat validator does not validate for array") 4890 | } 4891 | 4892 | if nil != Validate(struct { 4893 | field [1]string `validate:">format=email"` 4894 | }{ 4895 | field: [1]string{"abc@example.com"}, 4896 | }) { 4897 | t.Errorf(">foormat validator does not validate for array") 4898 | } 4899 | } 4900 | 4901 | func TestDeepValsForPtr(t *testing.T) { 4902 | gteusOne := -1 4903 | zero := 0 4904 | one := 1 4905 | four := 4 4906 | empty := "" 4907 | notEmpty := "a" 4908 | abc := "abc" 4909 | email := "abc@example.com" 4910 | onePtr := &one 4911 | var nilPtr *int 4912 | 4913 | if nil == Validate(struct { 4914 | field *int `validate:">gte=0"` 4915 | }{ 4916 | field: >eusOne, 4917 | }) { 4918 | t.Errorf(">gte validator does not validate for pointer") 4919 | } 4920 | 4921 | if nil != Validate(struct { 4922 | field *int `validate:">gte=0"` 4923 | }{ 4924 | field: &zero, 4925 | }) { 4926 | t.Errorf(">gte validator does not validate for pointer") 4927 | } 4928 | 4929 | if nil == Validate(struct { 4930 | field *int `validate:">lte=0"` 4931 | }{ 4932 | field: &one, 4933 | }) { 4934 | t.Errorf(">lte validator does not validate for pointer") 4935 | } 4936 | 4937 | if nil != Validate(struct { 4938 | field *int `validate:">lte=0"` 4939 | }{ 4940 | field: &zero, 4941 | }) { 4942 | t.Errorf(">lte validator does not validate for pointer") 4943 | } 4944 | 4945 | if nil == Validate(struct { 4946 | field *string `validate:">empty=true"` 4947 | }{ 4948 | field: ¬Empty, 4949 | }) { 4950 | t.Errorf(">empty validator does not validate for pointer") 4951 | } 4952 | 4953 | if nil != Validate(struct { 4954 | field *string `validate:">empty=true"` 4955 | }{ 4956 | field: &empty, 4957 | }) { 4958 | t.Errorf(">empty validator does not validate for pointer") 4959 | } 4960 | 4961 | if nil == Validate(struct { 4962 | field *string `validate:">empty=false"` 4963 | }{ 4964 | field: &empty, 4965 | }) { 4966 | t.Errorf(">empty validator does not validate for pointer") 4967 | } 4968 | 4969 | if nil != Validate(struct { 4970 | field *string `validate:">empty=false"` 4971 | }{ 4972 | field: ¬Empty, 4973 | }) { 4974 | t.Errorf(">empty validator does not validate for pointer") 4975 | } 4976 | 4977 | if nil == Validate(struct { 4978 | field **int `validate:">nil=true"` 4979 | }{ 4980 | field: &onePtr, 4981 | }) { 4982 | t.Errorf(">nil validator does not validate for pointer") 4983 | } 4984 | 4985 | if nil != Validate(struct { 4986 | field **int `validate:">nil=true"` 4987 | }{ 4988 | field: &nilPtr, 4989 | }) { 4990 | t.Errorf(">nil validator does not validate for pointer") 4991 | } 4992 | 4993 | if nil == Validate(struct { 4994 | field **int `validate:">nil=false"` 4995 | }{ 4996 | field: &nilPtr, 4997 | }) { 4998 | t.Errorf(">nil validator does not validate for pointer") 4999 | } 5000 | 5001 | if nil != Validate(struct { 5002 | field **int `validate:">nil=false"` 5003 | }{ 5004 | field: &onePtr, 5005 | }) { 5006 | t.Errorf(">nil validator does not validate for pointer") 5007 | } 5008 | 5009 | if nil == Validate(struct { 5010 | field *int `validate:">one_of=1,2,3"` 5011 | }{ 5012 | field: &four, 5013 | }) { 5014 | t.Errorf(">one_of validator does not validate for pointer") 5015 | } 5016 | 5017 | if nil != Validate(struct { 5018 | field *int `validate:">one_of=1,2,3"` 5019 | }{ 5020 | field: &one, 5021 | }) { 5022 | t.Errorf(">one_of validator does not validate for pointer") 5023 | } 5024 | 5025 | if nil == Validate(struct { 5026 | field *string `validate:">format=email"` 5027 | }{ 5028 | field: &abc, 5029 | }) { 5030 | t.Errorf(">format validator does not validate for pointer") 5031 | } 5032 | 5033 | if nil != Validate(struct { 5034 | field *string `validate:">format=email"` 5035 | }{ 5036 | field: &email, 5037 | }) { 5038 | t.Errorf(">format validator does not validate for pointer") 5039 | } 5040 | } 5041 | 5042 | func TestDeepDeepVal(t *testing.T) { 5043 | str := " " 5044 | emptyStr := "" 5045 | zero := 0 5046 | gteusOne := -1 5047 | 5048 | if nil != Validate(struct { 5049 | field []map[*string]*int `validate:"empty=false > empty=false [nil=false > empty=true] > nil=false > gte=0"` 5050 | }{ 5051 | field: []map[*string]*int{ 5052 | map[*string]*int{ 5053 | &emptyStr: &zero, 5054 | }, 5055 | }, 5056 | }) { 5057 | t.Errorf("complex validator does not validate") 5058 | } 5059 | 5060 | if nil == Validate(struct { 5061 | field []map[*string]*int `validate:"empty=false > empty=false [nil=false > empty=true] > nil=false > gte=0"` 5062 | }{ 5063 | field: []map[*string]*int{ 5064 | map[*string]*int{ 5065 | &emptyStr: >eusOne, 5066 | }, 5067 | }, 5068 | }) { 5069 | t.Errorf("complex validator does not validate") 5070 | } 5071 | 5072 | if nil == Validate(struct { 5073 | field []map[*string]*int `validate:"empty=false > empty=false [nil=false > empty=true] > nil=false > gte=0"` 5074 | }{ 5075 | field: []map[*string]*int{ 5076 | map[*string]*int{ 5077 | &emptyStr: nil, 5078 | }, 5079 | }, 5080 | }) { 5081 | t.Errorf("complex validator does not validate") 5082 | } 5083 | 5084 | if nil == Validate(struct { 5085 | field []map[*string]*int `validate:"empty=false > empty=false [nil=false > empty=true] > nil=false > gte=0"` 5086 | }{ 5087 | field: []map[*string]*int{ 5088 | map[*string]*int{ 5089 | &str: &zero, 5090 | }, 5091 | }, 5092 | }) { 5093 | t.Errorf("complex validator does not validate") 5094 | } 5095 | 5096 | if nil == Validate(struct { 5097 | field []map[*string]*int `validate:"empty=false > empty=false [nil=false > empty=true] > nil=false > gte=0"` 5098 | }{ 5099 | field: []map[*string]*int{ 5100 | map[*string]*int{ 5101 | nil: &zero, 5102 | }, 5103 | }, 5104 | }) { 5105 | t.Errorf("complex validator does not validate") 5106 | } 5107 | 5108 | if nil == Validate(struct { 5109 | field []map[*string]*int `validate:"empty=false > empty=false [nil=false > empty=true] > nil=false > gte=0"` 5110 | }{ 5111 | field: []map[*string]*int{ 5112 | map[*string]*int{}, 5113 | }, 5114 | }) { 5115 | t.Errorf("complex validator does not validate") 5116 | } 5117 | 5118 | if nil == Validate(struct { 5119 | field []map[*string]*int `validate:"empty=false > empty=false [nil=false > empty=true] > nil=false > gte=0"` 5120 | }{ 5121 | field: []map[*string]*int{}, 5122 | }) { 5123 | t.Errorf("complex validator does not validate") 5124 | } 5125 | } 5126 | 5127 | func TestDeepDeepStructVal(t *testing.T) { 5128 | emptyStr := "" 5129 | 5130 | type SubStr struct { 5131 | field int `validate:"gte=0"` 5132 | } 5133 | 5134 | if nil != Validate(struct { 5135 | field []map[*string]*SubStr `validate:"empty=false > empty=false [nil=false > empty=true] > nil=false"` 5136 | }{ 5137 | field: []map[*string]*SubStr{ 5138 | map[*string]*SubStr{ 5139 | &emptyStr: &SubStr{field: 0}, 5140 | }, 5141 | }, 5142 | }) { 5143 | t.Errorf("complex validator does not validate") 5144 | } 5145 | 5146 | if nil == Validate(struct { 5147 | field []map[*string]*SubStr `validate:"empty=false > empty=false [nil=false > empty=true] > nil=false"` 5148 | }{ 5149 | field: []map[*string]*SubStr{ 5150 | map[*string]*SubStr{ 5151 | &emptyStr: &SubStr{field: -1}, 5152 | }, 5153 | }, 5154 | }) { 5155 | t.Errorf("complex validator does not validate") 5156 | } 5157 | 5158 | if nil != Validate(struct { 5159 | field []map[*string]*SubStr 5160 | }{ 5161 | field: []map[*string]*SubStr{ 5162 | map[*string]*SubStr{ 5163 | &emptyStr: &SubStr{field: 0}, 5164 | }, 5165 | }, 5166 | }) { 5167 | t.Errorf("complex validator does not validate") 5168 | } 5169 | 5170 | if nil == Validate(struct { 5171 | field []map[*string]*SubStr 5172 | }{ 5173 | field: []map[*string]*SubStr{ 5174 | map[*string]*SubStr{ 5175 | &emptyStr: &SubStr{field: -1}, 5176 | }, 5177 | }, 5178 | }) { 5179 | t.Errorf("complex validator does not validate") 5180 | } 5181 | } 5182 | -------------------------------------------------------------------------------- /validators.go: -------------------------------------------------------------------------------- 1 | package validate 2 | 3 | import ( 4 | "reflect" 5 | "strconv" 6 | "time" 7 | ) 8 | 9 | // ValidatorType is used for validator type definitions. 10 | type ValidatorType string 11 | 12 | // Following validators are available. 13 | const ( 14 | // ValidatorEq (equals) compares a numeric value of a number or compares a count of elements in a string, a map, a slice, or an array. 15 | // E.g. `validate:"eq=1"` 16 | ValidatorEq ValidatorType = "eq" 17 | 18 | // ValidatorNe (not equals) compares a numeric value of a number or compares a count of elements in a string, a map, a slice, or an array. 19 | // E.g. `validate:"ne=0"` 20 | ValidatorNe ValidatorType = "ne" 21 | 22 | // ValidatorGt (greater than) compares a numeric value of a number or compares a count of elements in a string, a map, a slice, or an array. 23 | // E.g. `validate:"gt=-1"` 24 | ValidatorGt ValidatorType = "gt" 25 | 26 | // ValidatorLt (less than) compares a numeric value of a number or compares a count of elements in a string, a map, a slice, or an array. 27 | // E.g. `validate:"lt=11"` 28 | ValidatorLt ValidatorType = "lt" 29 | 30 | // ValidatorGte (greater than or equal to) compares a numeric value of a number or compares a count of elements in a string, a map, a slice, or an array. 31 | // E.g. `validate:"gte=0"` 32 | ValidatorGte ValidatorType = "gte" 33 | 34 | // ValidatorLte (less than or equal to) compares a numeric value of a number or compares a count of elements in a string, a map, a slice, or an array. 35 | // E.g. `validate:"lte=10"` 36 | ValidatorLte ValidatorType = "lte" 37 | 38 | // ValidatorEmpty checks if a string, a map, a slice, or an array is (not) empty. 39 | // E.g. `validate:"empty=false"` 40 | ValidatorEmpty ValidatorType = "empty" 41 | 42 | // ValidatorNil checks if a pointer is (not) nil. 43 | // E.g. `validate:"nil=false"` 44 | ValidatorNil ValidatorType = "nil" 45 | 46 | // ValidatorOneOf checks if a number or a string contains any of the given elements. 47 | // E.g. `validate:"one_of=1,2,3"` 48 | ValidatorOneOf ValidatorType = "one_of" 49 | 50 | // ValidatorFormat checks if a string of a given format. 51 | // E.g. `validate:"format=email"` 52 | ValidatorFormat ValidatorType = "format" 53 | ) 54 | 55 | // validatorFunc is an interface for validator func 56 | type validatorFunc func(value reflect.Value, validator string) ErrorField 57 | 58 | func getValidatorTypeMap() map[ValidatorType]validatorFunc { 59 | return map[ValidatorType]validatorFunc{ 60 | ValidatorEq: validateEq, 61 | ValidatorNe: validateNe, 62 | ValidatorGt: validateGt, 63 | ValidatorLt: validateLt, 64 | ValidatorGte: validateGte, 65 | ValidatorLte: validateLte, 66 | ValidatorEmpty: validateEmpty, 67 | ValidatorNil: validateNil, 68 | ValidatorOneOf: validateOneOf, 69 | ValidatorFormat: validateFormat, 70 | } 71 | } 72 | 73 | type validator struct { 74 | Type ValidatorType 75 | Value string 76 | } 77 | 78 | func validateEq(value reflect.Value, validator string) ErrorField { 79 | kind := value.Kind() 80 | typ := value.Type() 81 | 82 | errorValidation := ErrorValidation{ 83 | fieldValue: value, 84 | validatorType: ValidatorEq, 85 | validatorValue: validator, 86 | } 87 | 88 | errorSyntax := ErrorSyntax{ 89 | expression: validator, 90 | near: string(ValidatorEq), 91 | comment: "could not parse or run", 92 | } 93 | 94 | switch kind { 95 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 96 | if typ == reflect.TypeOf((time.Duration)(0)) { 97 | if token, err := time.ParseDuration(validator); err != nil { 98 | return errorSyntax 99 | } else if time.Duration(value.Int()) != token { 100 | return errorValidation 101 | } 102 | } else { 103 | if token, err := strconv.ParseInt(validator, 10, 64); err != nil { 104 | return errorSyntax 105 | } else if value.Int() != token { 106 | return errorValidation 107 | } 108 | } 109 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 110 | if token, err := strconv.ParseUint(validator, 10, 64); err != nil { 111 | return errorSyntax 112 | } else if value.Uint() != token { 113 | return errorValidation 114 | } 115 | case reflect.Float32, reflect.Float64: 116 | if token, err := strconv.ParseFloat(validator, 64); err != nil { 117 | return errorSyntax 118 | } else if value.Float() != token { 119 | return errorValidation 120 | } 121 | case reflect.String, reflect.Map, reflect.Slice, reflect.Array: 122 | if token, err := strconv.Atoi(validator); err != nil { 123 | return errorSyntax 124 | } else if value.Len() != token { 125 | return errorValidation 126 | } 127 | default: 128 | return errorSyntax 129 | } 130 | 131 | return nil 132 | } 133 | 134 | func validateNe(value reflect.Value, validator string) ErrorField { 135 | kind := value.Kind() 136 | typ := value.Type() 137 | 138 | errorValidation := ErrorValidation{ 139 | fieldValue: value, 140 | validatorType: ValidatorNe, 141 | validatorValue: validator, 142 | } 143 | 144 | errorSyntax := ErrorSyntax{ 145 | expression: validator, 146 | near: string(ValidatorNe), 147 | comment: "could not parse or run", 148 | } 149 | 150 | switch kind { 151 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 152 | if typ == reflect.TypeOf((time.Duration)(0)) { 153 | if token, err := time.ParseDuration(validator); err != nil { 154 | return errorSyntax 155 | } else if time.Duration(value.Int()) == token { 156 | return errorValidation 157 | } 158 | } else { 159 | if token, err := strconv.ParseInt(validator, 10, 64); err != nil { 160 | return errorSyntax 161 | } else if value.Int() == token { 162 | return errorValidation 163 | } 164 | } 165 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 166 | if token, err := strconv.ParseUint(validator, 10, 64); err != nil { 167 | return errorSyntax 168 | } else if value.Uint() == token { 169 | return errorValidation 170 | } 171 | case reflect.Float32, reflect.Float64: 172 | if token, err := strconv.ParseFloat(validator, 64); err != nil { 173 | return errorSyntax 174 | } else if value.Float() == token { 175 | return errorValidation 176 | } 177 | case reflect.String, reflect.Map, reflect.Slice, reflect.Array: 178 | if token, err := strconv.Atoi(validator); err != nil { 179 | return errorSyntax 180 | } else if value.Len() == token { 181 | return errorValidation 182 | } 183 | default: 184 | return errorSyntax 185 | } 186 | 187 | return nil 188 | } 189 | 190 | func validateGt(value reflect.Value, validator string) ErrorField { 191 | kind := value.Kind() 192 | typ := value.Type() 193 | 194 | errorValidation := ErrorValidation{ 195 | fieldValue: value, 196 | validatorType: ValidatorGt, 197 | validatorValue: validator, 198 | } 199 | 200 | errorSyntax := ErrorSyntax{ 201 | expression: validator, 202 | near: string(ValidatorGt), 203 | comment: "could not parse or run", 204 | } 205 | 206 | switch kind { 207 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 208 | if typ == reflect.TypeOf((time.Duration)(0)) { 209 | if token, err := time.ParseDuration(validator); err != nil { 210 | return errorSyntax 211 | } else if time.Duration(value.Int()) <= token { 212 | return errorValidation 213 | } 214 | } else { 215 | if token, err := strconv.ParseInt(validator, 10, 64); err != nil { 216 | return errorSyntax 217 | } else if value.Int() <= token { 218 | return errorValidation 219 | } 220 | } 221 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 222 | if token, err := strconv.ParseUint(validator, 10, 64); err != nil { 223 | return errorSyntax 224 | } else if value.Uint() <= token { 225 | return errorValidation 226 | } 227 | case reflect.Float32, reflect.Float64: 228 | if token, err := strconv.ParseFloat(validator, 64); err != nil { 229 | return errorSyntax 230 | } else if value.Float() <= token { 231 | return errorValidation 232 | } 233 | case reflect.String, reflect.Map, reflect.Slice, reflect.Array: 234 | if token, err := strconv.Atoi(validator); err != nil { 235 | return errorSyntax 236 | } else if value.Len() <= token { 237 | return errorValidation 238 | } 239 | default: 240 | return errorSyntax 241 | } 242 | 243 | return nil 244 | } 245 | 246 | func validateLt(value reflect.Value, validator string) ErrorField { 247 | kind := value.Kind() 248 | typ := value.Type() 249 | 250 | errorValidation := ErrorValidation{ 251 | fieldValue: value, 252 | validatorType: ValidatorLt, 253 | validatorValue: validator, 254 | } 255 | 256 | errorSyntax := ErrorSyntax{ 257 | expression: validator, 258 | near: string(ValidatorLt), 259 | comment: "could not parse or run", 260 | } 261 | 262 | switch kind { 263 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 264 | if typ == reflect.TypeOf((time.Duration)(0)) { 265 | if token, err := time.ParseDuration(validator); err != nil { 266 | return errorSyntax 267 | } else if time.Duration(value.Int()) >= token { 268 | return errorValidation 269 | } 270 | } else { 271 | if token, err := strconv.ParseInt(validator, 10, 64); err != nil { 272 | return errorSyntax 273 | } else if value.Int() >= token { 274 | return errorValidation 275 | } 276 | } 277 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 278 | if token, err := strconv.ParseUint(validator, 10, 64); err != nil { 279 | return errorSyntax 280 | } else if value.Uint() >= token { 281 | return errorValidation 282 | } 283 | case reflect.Float32, reflect.Float64: 284 | if token, err := strconv.ParseFloat(validator, 64); err != nil { 285 | return errorSyntax 286 | } else if value.Float() >= token { 287 | return errorValidation 288 | } 289 | case reflect.String, reflect.Map, reflect.Slice, reflect.Array: 290 | if token, err := strconv.Atoi(validator); err != nil { 291 | return errorSyntax 292 | } else if value.Len() >= token { 293 | return errorValidation 294 | } 295 | default: 296 | return errorSyntax 297 | } 298 | 299 | return nil 300 | } 301 | 302 | func validateGte(value reflect.Value, validator string) ErrorField { 303 | kind := value.Kind() 304 | typ := value.Type() 305 | 306 | errorValidation := ErrorValidation{ 307 | fieldValue: value, 308 | validatorType: ValidatorGte, 309 | validatorValue: validator, 310 | } 311 | 312 | errorSyntax := ErrorSyntax{ 313 | expression: validator, 314 | near: string(ValidatorGte), 315 | comment: "could not parse or run", 316 | } 317 | 318 | switch kind { 319 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 320 | if typ == reflect.TypeOf((time.Duration)(0)) { 321 | if token, err := time.ParseDuration(validator); err != nil { 322 | return errorSyntax 323 | } else if time.Duration(value.Int()) < token { 324 | return errorValidation 325 | } 326 | } else { 327 | if token, err := strconv.ParseInt(validator, 10, 64); err != nil { 328 | return errorSyntax 329 | } else if value.Int() < token { 330 | return errorValidation 331 | } 332 | } 333 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 334 | if token, err := strconv.ParseUint(validator, 10, 64); err != nil { 335 | return errorSyntax 336 | } else if value.Uint() < token { 337 | return errorValidation 338 | } 339 | case reflect.Float32, reflect.Float64: 340 | if token, err := strconv.ParseFloat(validator, 64); err != nil { 341 | return errorSyntax 342 | } else if value.Float() < token { 343 | return errorValidation 344 | } 345 | case reflect.String, reflect.Map, reflect.Slice, reflect.Array: 346 | if token, err := strconv.Atoi(validator); err != nil { 347 | return errorSyntax 348 | } else if value.Len() < token { 349 | return errorValidation 350 | } 351 | default: 352 | return errorSyntax 353 | } 354 | 355 | return nil 356 | } 357 | 358 | func validateLte(value reflect.Value, validator string) ErrorField { 359 | kind := value.Kind() 360 | typ := value.Type() 361 | 362 | errorValidation := ErrorValidation{ 363 | fieldValue: value, 364 | validatorType: ValidatorLte, 365 | validatorValue: validator, 366 | } 367 | 368 | errorSyntax := ErrorSyntax{ 369 | expression: validator, 370 | near: string(ValidatorLte), 371 | comment: "could not parse or run", 372 | } 373 | 374 | switch kind { 375 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 376 | if typ == reflect.TypeOf((time.Duration)(0)) { 377 | if token, err := time.ParseDuration(validator); err != nil { 378 | return errorSyntax 379 | } else if time.Duration(value.Int()) > token { 380 | return errorValidation 381 | } 382 | } else { 383 | if token, err := strconv.ParseInt(validator, 10, 64); err != nil { 384 | return errorSyntax 385 | } else if value.Int() > token { 386 | return errorValidation 387 | } 388 | } 389 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 390 | if token, err := strconv.ParseUint(validator, 10, 64); err != nil { 391 | return errorSyntax 392 | } else if value.Uint() > token { 393 | return errorValidation 394 | } 395 | case reflect.Float32, reflect.Float64: 396 | if token, err := strconv.ParseFloat(validator, 64); err != nil { 397 | return errorSyntax 398 | } else if value.Float() > token { 399 | return errorValidation 400 | } 401 | case reflect.String, reflect.Map, reflect.Slice, reflect.Array: 402 | if token, err := strconv.Atoi(validator); err != nil { 403 | return errorSyntax 404 | } else if value.Len() > token { 405 | return errorValidation 406 | } 407 | default: 408 | return errorSyntax 409 | } 410 | 411 | return nil 412 | } 413 | 414 | func validateEmpty(value reflect.Value, validator string) ErrorField { 415 | kind := value.Kind() 416 | 417 | errorValidation := ErrorValidation{ 418 | fieldValue: value, 419 | validatorType: ValidatorEmpty, 420 | validatorValue: validator, 421 | } 422 | 423 | errorSyntax := ErrorSyntax{ 424 | expression: validator, 425 | near: string(ValidatorEmpty), 426 | comment: "could not parse or run", 427 | } 428 | 429 | switch kind { 430 | case reflect.String, reflect.Map, reflect.Slice, reflect.Array: 431 | if isEmpty, err := strconv.ParseBool(validator); err != nil { 432 | return errorSyntax 433 | } else if isEmpty && value.Len() > 0 { 434 | return errorValidation 435 | } else if !isEmpty && value.Len() == 0 { 436 | return errorValidation 437 | } 438 | default: 439 | return errorSyntax 440 | } 441 | 442 | return nil 443 | } 444 | 445 | func validateNil(value reflect.Value, validator string) ErrorField { 446 | kind := value.Kind() 447 | 448 | errorValidation := ErrorValidation{ 449 | fieldValue: value, 450 | validatorType: ValidatorNil, 451 | validatorValue: validator, 452 | } 453 | 454 | errorSyntax := ErrorSyntax{ 455 | expression: validator, 456 | near: string(ValidatorNil), 457 | comment: "could not parse or run", 458 | } 459 | 460 | switch kind { 461 | case reflect.Ptr: 462 | if isNil, err := strconv.ParseBool(validator); err != nil { 463 | return errorSyntax 464 | } else if isNil && !value.IsNil() { 465 | return errorValidation 466 | } else if !isNil && value.IsNil() { 467 | return errorValidation 468 | } 469 | default: 470 | return errorSyntax 471 | } 472 | 473 | return nil 474 | } 475 | 476 | func validateOneOf(value reflect.Value, validator string) ErrorField { 477 | kind := value.Kind() 478 | typ := value.Type() 479 | 480 | errorValidation := ErrorValidation{ 481 | fieldValue: value, 482 | validatorType: ValidatorOneOf, 483 | validatorValue: validator, 484 | } 485 | 486 | errorSyntax := ErrorSyntax{ 487 | expression: validator, 488 | near: string(ValidatorOneOf), 489 | comment: "could not parse or run", 490 | } 491 | 492 | switch kind { 493 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 494 | if typ == reflect.TypeOf((time.Duration)(0)) { 495 | var tokens []interface{} 496 | if tokens = parseTokens(validator); len(tokens) == 0 { 497 | return errorSyntax 498 | } 499 | for i, token := range tokens { 500 | tokens[i] = nil 501 | if token, err := time.ParseDuration(token.(string)); err != nil { 502 | return errorSyntax 503 | } else { 504 | tokens[i] = token 505 | } 506 | } 507 | if !tokenOneOf(time.Duration(value.Int()), tokens) { 508 | return errorValidation 509 | } 510 | } else { 511 | var tokens []interface{} 512 | if tokens = parseTokens(validator); len(tokens) == 0 { 513 | return errorSyntax 514 | } 515 | for i, token := range tokens { 516 | tokens[i] = nil 517 | if token, err := strconv.ParseInt(token.(string), 10, 64); err != nil { 518 | return errorSyntax 519 | } else { 520 | tokens[i] = token 521 | } 522 | } 523 | if !tokenOneOf(value.Int(), tokens) { 524 | return errorValidation 525 | } 526 | } 527 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: 528 | var tokens []interface{} 529 | if tokens = parseTokens(validator); len(tokens) == 0 { 530 | return errorSyntax 531 | } 532 | for i, token := range tokens { 533 | tokens[i] = nil 534 | if token, err := strconv.ParseUint(token.(string), 10, 64); err != nil { 535 | return errorSyntax 536 | } else { 537 | tokens[i] = token 538 | } 539 | } 540 | if !tokenOneOf(value.Uint(), tokens) { 541 | return errorValidation 542 | } 543 | case reflect.Float32, reflect.Float64: 544 | var tokens []interface{} 545 | if tokens = parseTokens(validator); len(tokens) == 0 { 546 | return errorSyntax 547 | } 548 | for i, token := range tokens { 549 | tokens[i] = nil 550 | if token, err := strconv.ParseFloat(token.(string), 64); err != nil { 551 | return errorSyntax 552 | } else { 553 | tokens[i] = token 554 | } 555 | } 556 | if !tokenOneOf(value.Float(), tokens) { 557 | return errorValidation 558 | } 559 | case reflect.String: 560 | var tokens []interface{} 561 | if tokens = parseTokens(validator); len(tokens) == 0 { 562 | return errorSyntax 563 | } 564 | if !tokenOneOf(value.String(), tokens) { 565 | return errorValidation 566 | } 567 | default: 568 | return errorSyntax 569 | } 570 | 571 | return nil 572 | } 573 | 574 | func validateFormat(value reflect.Value, validator string) ErrorField { 575 | kind := value.Kind() 576 | 577 | errorValidation := ErrorValidation{ 578 | fieldValue: value, 579 | validatorType: ValidatorFormat, 580 | validatorValue: validator, 581 | } 582 | 583 | errorSyntax := ErrorSyntax{ 584 | expression: validator, 585 | near: string(ValidatorFormat), 586 | comment: "could not find format", 587 | } 588 | 589 | switch kind { 590 | case reflect.String: 591 | formatTypeMap := getFormatTypeMap() 592 | if formatFunc, ok := formatTypeMap[FormatType(validator)]; !ok { 593 | return errorSyntax 594 | } else if !formatFunc(value.String()) { 595 | return errorValidation 596 | } 597 | default: 598 | return errorSyntax 599 | } 600 | 601 | return nil 602 | } 603 | --------------------------------------------------------------------------------