hanayo/vendor/github.com/asaskevich/govalidator/validator_test.go
2019-02-23 13:29:15 +00:00

3041 lines
77 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package govalidator
import (
"fmt"
"strings"
"testing"
"time"
)
func init() {
CustomTypeTagMap.Set("customFalseValidator", CustomTypeValidator(func(i interface{}, o interface{}) bool {
return false
}))
CustomTypeTagMap.Set("customTrueValidator", CustomTypeValidator(func(i interface{}, o interface{}) bool {
return true
}))
}
func TestIsAlpha(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"\n", false},
{"\r", false},
{"Ⅸ", false},
{"", true},
{" fooo ", false},
{"abc!!!", false},
{"abc1", false},
{"abc〩", false},
{"abc", true},
{"소주", false},
{"ABC", true},
{"FoObAr", true},
{"소aBC", false},
{"소", false},
{"달기&Co.", false},
{"〩Hours", false},
{"\ufff0", false},
{"\u0070", true}, //UTF-8(ASCII): p
{"\u0026", false}, //UTF-8(ASCII): &
{"\u0030", false}, //UTF-8(ASCII): 0
{"123", false},
{"0123", false},
{"-00123", false},
{"0", false},
{"-0", false},
{"123.123", false},
{" ", false},
{".", false},
{"-1¾", false},
{"1¾", false},
{"〥〩", false},
{"모자", false},
{"ix", true},
{"۳۵۶۰", false},
{"1--", false},
{"1-1", false},
{"-", false},
{"--", false},
{"1++", false},
{"1+1", false},
{"+", false},
{"++", false},
{"+1", false},
}
for _, test := range tests {
actual := IsAlpha(test.param)
if actual != test.expected {
t.Errorf("Expected IsAlpha(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsUTFLetter(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"\n", false},
{"\r", false},
{"Ⅸ", false},
{"", true},
{" fooo ", false},
{"abc!!!", false},
{"abc1", false},
{"abc〩", false},
{"", true},
{"abc", true},
{"소주", true},
{"ABC", true},
{"FoObAr", true},
{"소aBC", true},
{"소", true},
{"달기&Co.", false},
{"〩Hours", false},
{"\ufff0", false},
{"\u0070", true}, //UTF-8(ASCII): p
{"\u0026", false}, //UTF-8(ASCII): &
{"\u0030", false}, //UTF-8(ASCII): 0
{"123", false},
{"0123", false},
{"-00123", false},
{"0", false},
{"-0", false},
{"123.123", false},
{" ", false},
{".", false},
{"-1¾", false},
{"1¾", false},
{"〥〩", false},
{"모자", true},
{"ix", true},
{"۳۵۶۰", false},
{"1--", false},
{"1-1", false},
{"-", false},
{"--", false},
{"1++", false},
{"1+1", false},
{"+", false},
{"++", false},
{"+1", false},
}
for _, test := range tests {
actual := IsUTFLetter(test.param)
if actual != test.expected {
t.Errorf("Expected IsUTFLetter(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsAlphanumeric(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"\n", false},
{"\r", false},
{"Ⅸ", false},
{"", true},
{" fooo ", false},
{"abc!!!", false},
{"abc123", true},
{"ABC111", true},
{"abc1", true},
{"abc〩", false},
{"abc", true},
{"소주", false},
{"ABC", true},
{"FoObAr", true},
{"소aBC", false},
{"소", false},
{"달기&Co.", false},
{"〩Hours", false},
{"\ufff0", false},
{"\u0070", true}, //UTF-8(ASCII): p
{"\u0026", false}, //UTF-8(ASCII): &
{"\u0030", true}, //UTF-8(ASCII): 0
{"123", true},
{"0123", true},
{"-00123", false},
{"0", true},
{"-0", false},
{"123.123", false},
{" ", false},
{".", false},
{"-1¾", false},
{"1¾", false},
{"〥〩", false},
{"모자", false},
{"ix", true},
{"۳۵۶۰", false},
{"1--", false},
{"1-1", false},
{"-", false},
{"--", false},
{"1++", false},
{"1+1", false},
{"+", false},
{"++", false},
{"+1", false},
}
for _, test := range tests {
actual := IsAlphanumeric(test.param)
if actual != test.expected {
t.Errorf("Expected IsAlphanumeric(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsUTFLetterNumeric(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"\n", false},
{"\r", false},
{"Ⅸ", true},
{"", true},
{" fooo ", false},
{"abc!!!", false},
{"abc1", true},
{"abc〩", true},
{"abc", true},
{"소주", true},
{"ABC", true},
{"FoObAr", true},
{"소aBC", true},
{"소", true},
{"달기&Co.", false},
{"〩Hours", true},
{"\ufff0", false},
{"\u0070", true}, //UTF-8(ASCII): p
{"\u0026", false}, //UTF-8(ASCII): &
{"\u0030", true}, //UTF-8(ASCII): 0
{"123", true},
{"0123", true},
{"-00123", false},
{"0", true},
{"-0", false},
{"123.123", false},
{" ", false},
{".", false},
{"-1¾", false},
{"1¾", true},
{"〥〩", true},
{"모자", true},
{"ix", true},
{"۳۵۶۰", true},
{"1--", false},
{"1-1", false},
{"-", false},
{"--", false},
{"1++", false},
{"1+1", false},
{"+", false},
{"++", false},
{"+1", false},
}
for _, test := range tests {
actual := IsUTFLetterNumeric(test.param)
if actual != test.expected {
t.Errorf("Expected IsUTFLetterNumeric(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsNumeric(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"\n", false},
{"\r", false},
{"Ⅸ", false},
{"", true},
{" fooo ", false},
{"abc!!!", false},
{"abc1", false},
{"abc〩", false},
{"abc", false},
{"소주", false},
{"ABC", false},
{"FoObAr", false},
{"소aBC", false},
{"소", false},
{"달기&Co.", false},
{"〩Hours", false},
{"\ufff0", false},
{"\u0070", false}, //UTF-8(ASCII): p
{"\u0026", false}, //UTF-8(ASCII): &
{"\u0030", true}, //UTF-8(ASCII): 0
{"123", true},
{"0123", true},
{"-00123", false},
{"+00123", false},
{"0", true},
{"-0", false},
{"123.123", false},
{" ", false},
{".", false},
{"12𐅪3", false},
{"-1¾", false},
{"1¾", false},
{"〥〩", false},
{"모자", false},
{"ix", false},
{"۳۵۶۰", false},
{"1--", false},
{"1-1", false},
{"-", false},
{"--", false},
{"1++", false},
{"1+1", false},
{"+", false},
{"++", false},
{"+1", false},
}
for _, test := range tests {
actual := IsNumeric(test.param)
if actual != test.expected {
t.Errorf("Expected IsNumeric(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsUTFNumeric(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"\n", false},
{"\r", false},
{"Ⅸ", true},
{"", true},
{" fooo ", false},
{"abc!!!", false},
{"abc1", false},
{"abc〩", false},
{"abc", false},
{"소주", false},
{"ABC", false},
{"FoObAr", false},
{"소aBC", false},
{"소", false},
{"달기&Co.", false},
{"〩Hours", false},
{"\ufff0", false},
{"\u0070", false}, //UTF-8(ASCII): p
{"\u0026", false}, //UTF-8(ASCII): &
{"\u0030", true}, //UTF-8(ASCII): 0
{"123", true},
{"0123", true},
{"-00123", true},
{"0", true},
{"-0", true},
{"--0", false},
{"-0-", false},
{"123.123", false},
{" ", false},
{".", false},
{"12𐅪3", true},
{"-1¾", true},
{"1¾", true},
{"〥〩", true},
{"모자", false},
{"ix", false},
{"۳۵۶۰", true},
{"1++", false},
{"1+1", false},
{"+", false},
{"++", false},
{"+1", true},
}
for _, test := range tests {
actual := IsUTFNumeric(test.param)
if actual != test.expected {
t.Errorf("Expected IsUTFNumeric(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsUTFDigit(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"\n", false},
{"\r", false},
{"Ⅸ", false},
{"", true},
{" fooo ", false},
{"abc!!!", false},
{"abc1", false},
{"abc〩", false},
{"abc", false},
{"소주", false},
{"ABC", false},
{"FoObAr", false},
{"소aBC", false},
{"소", false},
{"달기&Co.", false},
{"〩Hours", false},
{"\ufff0", false},
{"\u0070", false}, //UTF-8(ASCII): p
{"\u0026", false}, //UTF-8(ASCII): &
{"\u0030", true}, //UTF-8(ASCII): 0
{"123", true},
{"0123", true},
{"-00123", true},
{"0", true},
{"-0", true},
{"--0", false},
{"-0-", false},
{"123.123", false},
{" ", false},
{".", false},
{"12𐅪3", false},
{"1483920", true},
{"", true},
{"۳۵۶۰", true},
{"-29", true},
{"-1¾", false},
{"1¾", false},
{"〥〩", false},
{"모자", false},
{"ix", false},
{"۳۵۶۰", true},
{"1++", false},
{"1+1", false},
{"+", false},
{"++", false},
{"+1", true},
}
for _, test := range tests {
actual := IsUTFDigit(test.param)
if actual != test.expected {
t.Errorf("Expected IsUTFDigit(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsLowerCase(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", true},
{"abc123", true},
{"abc", true},
{"a b c", true},
{"abcß", true},
{"abcẞ", false},
{"ABCẞ", false},
{"tr竪s 端ber", true},
{"fooBar", false},
{"123ABC", false},
{"ABC123", false},
{"ABC", false},
{"S T R", false},
{"fooBar", false},
{"abacaba123", true},
}
for _, test := range tests {
actual := IsLowerCase(test.param)
if actual != test.expected {
t.Errorf("Expected IsLowerCase(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsUpperCase(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", true},
{"abc123", false},
{"abc", false},
{"a b c", false},
{"abcß", false},
{"abcẞ", false},
{"ABCẞ", true},
{"tr竪s 端ber", false},
{"fooBar", false},
{"123ABC", true},
{"ABC123", true},
{"ABC", true},
{"S T R", true},
{"fooBar", false},
{"abacaba123", false},
}
for _, test := range tests {
actual := IsUpperCase(test.param)
if actual != test.expected {
t.Errorf("Expected IsUpperCase(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsInt(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"-2147483648", true}, //Signed 32 Bit Min Int
{"2147483647", true}, //Signed 32 Bit Max Int
{"-2147483649", true}, //Signed 32 Bit Min Int - 1
{"2147483648", true}, //Signed 32 Bit Max Int + 1
{"4294967295", true}, //Unsigned 32 Bit Max Int
{"4294967296", true}, //Unsigned 32 Bit Max Int + 1
{"-9223372036854775808", true}, //Signed 64 Bit Min Int
{"9223372036854775807", true}, //Signed 64 Bit Max Int
{"-9223372036854775809", true}, //Signed 64 Bit Min Int - 1
{"9223372036854775808", true}, //Signed 64 Bit Max Int + 1
{"18446744073709551615", true}, //Unsigned 64 Bit Max Int
{"18446744073709551616", true}, //Unsigned 64 Bit Max Int + 1
{"", true},
{"123", true},
{"0", true},
{"-0", true},
{"+0", true},
{"01", false},
{"123.123", false},
{" ", false},
{"000", false},
}
for _, test := range tests {
actual := IsInt(test.param)
if actual != test.expected {
t.Errorf("Expected IsInt(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsHash(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
algo string
expected bool
}{
{"3ca25ae354e192b26879f651a51d92aa8a34d8d3", "sha1", true},
{"3ca25ae354e192b26879f651a51d34d8d3", "sha1", false},
{"3ca25ae354e192b26879f651a51d92aa8a34d8d3", "Tiger160", true},
{"3ca25ae354e192b26879f651a51d34d8d3", "ripemd160", false},
{"579282cfb65ca1f109b78536effaf621b853c9f7079664a3fbe2b519f435898c", "sha256", true},
{"579282cfb65ca1f109b78536effaf621b853c9f7079664a3fbe2b519f435898casfdsafsadfsdf", "sha256", false},
{"bf547c3fc5841a377eb1519c2890344dbab15c40ae4150b4b34443d2212e5b04aa9d58865bf03d8ae27840fef430b891", "sha384", true},
{"579282cfb65ca1f109b78536effaf621b853c9f7079664a3fbe2b519f435898casfdsafsadfsdf", "sha384", false},
{"45bc5fa8cb45ee408c04b6269e9f1e1c17090c5ce26ffeeda2af097735b29953ce547e40ff3ad0d120e5361cc5f9cee35ea91ecd4077f3f589b4d439168f91b9", "sha512", true},
{"579282cfb65ca1f109b78536effaf621b853c9f7079664a3fbe2b519f435898casfdsafsadfsdf", "sha512", false},
{"46fc0125a148788a3ac1d649566fc04eb84a746f1a6e4fa7", "tiger192", true},
{"46fc0125a148788a3ac1d649566fc04eb84a746f1a6$$%@^", "TIGER192", false},
{"46fc0125a148788a3ac1d649566fc04eb84a746f1a6$$%@^", "SOMEHASH", false},
}
for _, test := range tests {
actual := IsHash(test.param, test.algo)
if actual != test.expected {
t.Errorf("Expected IsHash(%q, %q) to be %v, got %v", test.param, test.algo, test.expected, actual)
}
}
}
func TestIsEmail(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", false},
{"foo@bar.com", true},
{"x@x.x", true},
{"foo@bar.com.au", true},
{"foo+bar@bar.com", true},
{"foo@bar.coffee", true},
{"foo@bar.coffee..coffee", false},
{"foo@bar.bar.coffee", true},
{"foo@bar.中文网", true},
{"invalidemail@", false},
{"invalid.com", false},
{"@invalid.com", false},
{"test|123@m端ller.com", true},
{"hans@m端ller.com", true},
{"hans.m端ller@test.com", true},
{"NathAn.daVIeS@DomaIn.cOM", true},
{"NATHAN.DAVIES@DOMAIN.CO.UK", true},
}
for _, test := range tests {
actual := IsEmail(test.param)
if actual != test.expected {
t.Errorf("Expected IsEmail(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsURL(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", false},
{"http://foo.bar#com", true},
{"http://foobar.com", true},
{"https://foobar.com", true},
{"foobar.com", true},
{"http://foobar.coffee/", true},
{"http://foobar.中文网/", true},
{"http://foobar.org/", true},
{"http://foobar.ORG", true},
{"http://foobar.org:8080/", true},
{"ftp://foobar.ru/", true},
{"ftp.foo.bar", true},
{"http://user:pass@www.foobar.com/", true},
{"http://user:pass@www.foobar.com/path/file", true},
{"http://127.0.0.1/", true},
{"http://duckduckgo.com/?q=%2F", true},
{"http://localhost:3000/", true},
{"http://foobar.com/?foo=bar#baz=qux", true},
{"http://foobar.com?foo=bar", true},
{"http://www.xn--froschgrn-x9a.net/", true},
{"http://foobar.com/a-", true},
{"http://foobar.پاکستان/", true},
{"http://foobar.c_o_m", false},
{"", false},
{"xyz://foobar.com", false},
// {"invalid.", false}, is it false like "localhost."?
{".com", false},
{"rtmp://foobar.com", false},
{"http://www.foo_bar.com/", false},
{"http://localhost:3000/", true},
{"http://foobar.com#baz=qux", true},
{"http://foobar.com/t$-_.+!*\\'(),", true},
{"http://www.foobar.com/~foobar", true},
{"http://www.-foobar.com/", false},
{"http://www.foo---bar.com/", false},
{"http://r6---snnvoxuioq6.googlevideo.com", true},
{"mailto:someone@example.com", true},
{"irc://irc.server.org/channel", false},
{"irc://#channel@network", true},
{"/abs/test/dir", false},
{"./rel/test/dir", false},
{"http://foo^bar.org", false},
{"http://foo&*bar.org", false},
{"http://foo&bar.org", false},
{"http://foo bar.org", false},
{"http://foo.bar.org", true},
{"http://www.foo.bar.org", true},
{"http://www.foo.co.uk", true},
{"foo", false},
{"http://.foo.com", false},
{"http://,foo.com", false},
{",foo.com", false},
{"http://myservice.:9093/", true},
// according to issues #62 #66
{"https://pbs.twimg.com/profile_images/560826135676588032/j8fWrmYY_normal.jpeg", true},
// according to #125
{"http://prometheus-alertmanager.service.q:9093", true},
{"aio1_alertmanager_container-63376c45:9093", true},
{"https://www.logn-123-123.url.with.sigle.letter.d:12345/url/path/foo?bar=zzz#user", true},
{"http://me.example.com", true},
{"http://www.me.example.com", true},
{"https://farm6.static.flickr.com", true},
{"https://zh.wikipedia.org/wiki/Wikipedia:%E9%A6%96%E9%A1%B5", true},
{"google", false},
// According to #87
{"http://hyphenated-host-name.example.co.in", true},
{"http://cant-end-with-hyphen-.example.com", false},
{"http://-cant-start-with-hyphen.example.com", false},
{"http://www.domain-can-have-dashes.com", true},
{"http://m.abcd.com/test.html", true},
{"http://m.abcd.com/a/b/c/d/test.html?args=a&b=c", true},
{"http://[::1]:9093", true},
{"http://[::1]:909388", false},
{"1200::AB00:1234::2552:7777:1313", false},
{"http://[2001:db8:a0b:12f0::1]/index.html", true},
{"http://[1200:0000:AB00:1234:0000:2552:7777:1313]", true},
{"http://user:pass@[::1]:9093/a/b/c/?a=v#abc", true},
{"https://127.0.0.1/a/b/c?a=v&c=11d", true},
{"https://foo_bar.example.com", true},
{"http://foo_bar.example.com", true},
{"http://foo_bar_fizz_buzz.example.com", true},
{"http://_cant_start_with_underescore", false},
{"http://cant_end_with_underescore_", false},
{"foo_bar.example.com", true},
{"foo_bar_fizz_buzz.example.com", true},
{"http://hello_world.example.com", true},
// According to #212
{"foo_bar-fizz-buzz:1313", true},
{"foo_bar-fizz-buzz:13:13", false},
{"foo_bar-fizz-buzz://1313", false},
}
for _, test := range tests {
actual := IsURL(test.param)
if actual != test.expected {
t.Errorf("Expected IsURL(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsRequestURL(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", false},
{"http://foo.bar/#com", true},
{"http://foobar.com", true},
{"https://foobar.com", true},
{"foobar.com", false},
{"http://foobar.coffee/", true},
{"http://foobar.中文网/", true},
{"http://foobar.org/", true},
{"http://foobar.org:8080/", true},
{"ftp://foobar.ru/", true},
{"http://user:pass@www.foobar.com/", true},
{"http://127.0.0.1/", true},
{"http://duckduckgo.com/?q=%2F", true},
{"http://localhost:3000/", true},
{"http://foobar.com/?foo=bar#baz=qux", true},
{"http://foobar.com?foo=bar", true},
{"http://www.xn--froschgrn-x9a.net/", true},
{"", false},
{"xyz://foobar.com", true},
{"invalid.", false},
{".com", false},
{"rtmp://foobar.com", true},
{"http://www.foo_bar.com/", true},
{"http://localhost:3000/", true},
{"http://foobar.com/#baz=qux", true},
{"http://foobar.com/t$-_.+!*\\'(),", true},
{"http://www.foobar.com/~foobar", true},
{"http://www.-foobar.com/", true},
{"http://www.foo---bar.com/", true},
{"mailto:someone@example.com", true},
{"irc://irc.server.org/channel", true},
{"irc://#channel@network", true},
{"/abs/test/dir", false},
{"./rel/test/dir", false},
}
for _, test := range tests {
actual := IsRequestURL(test.param)
if actual != test.expected {
t.Errorf("Expected IsRequestURL(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsRequestURI(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", false},
{"http://foo.bar/#com", true},
{"http://foobar.com", true},
{"https://foobar.com", true},
{"foobar.com", false},
{"http://foobar.coffee/", true},
{"http://foobar.中文网/", true},
{"http://foobar.org/", true},
{"http://foobar.org:8080/", true},
{"ftp://foobar.ru/", true},
{"http://user:pass@www.foobar.com/", true},
{"http://127.0.0.1/", true},
{"http://duckduckgo.com/?q=%2F", true},
{"http://localhost:3000/", true},
{"http://foobar.com/?foo=bar#baz=qux", true},
{"http://foobar.com?foo=bar", true},
{"http://www.xn--froschgrn-x9a.net/", true},
{"xyz://foobar.com", true},
{"invalid.", false},
{".com", false},
{"rtmp://foobar.com", true},
{"http://www.foo_bar.com/", true},
{"http://localhost:3000/", true},
{"http://foobar.com/#baz=qux", true},
{"http://foobar.com/t$-_.+!*\\'(),", true},
{"http://www.foobar.com/~foobar", true},
{"http://www.-foobar.com/", true},
{"http://www.foo---bar.com/", true},
{"mailto:someone@example.com", true},
{"irc://irc.server.org/channel", true},
{"irc://#channel@network", true},
{"/abs/test/dir", true},
{"./rel/test/dir", false},
}
for _, test := range tests {
actual := IsRequestURI(test.param)
if actual != test.expected {
t.Errorf("Expected IsRequestURI(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsFloat(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", false},
{" ", false},
{"-.123", false},
{"abacaba", false},
{"1f", false},
{"-1f", false},
{"+1f", false},
{"123", true},
{"123.", true},
{"123.123", true},
{"-123.123", true},
{"+123.123", true},
{"0.123", true},
{"-0.123", true},
{"+0.123", true},
{".0", true},
{"01.123", true},
{"-0.22250738585072011e-307", true},
{"+0.22250738585072011e-307", true},
}
for _, test := range tests {
actual := IsFloat(test.param)
if actual != test.expected {
t.Errorf("Expected IsFloat(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsHexadecimal(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"abcdefg", false},
{"", false},
{"..", false},
{"deadBEEF", true},
{"ff0044", true},
}
for _, test := range tests {
actual := IsHexadecimal(test.param)
if actual != test.expected {
t.Errorf("Expected IsHexadecimal(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsHexcolor(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", false},
{"#ff", false},
{"fff0", false},
{"#ff12FG", false},
{"CCccCC", true},
{"fff", true},
{"#f00", true},
}
for _, test := range tests {
actual := IsHexcolor(test.param)
if actual != test.expected {
t.Errorf("Expected IsHexcolor(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsRGBcolor(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", false},
{"rgb(0,31,255)", true},
{"rgb(1,349,275)", false},
{"rgb(01,31,255)", false},
{"rgb(0.6,31,255)", false},
{"rgba(0,31,255)", false},
{"rgb(0, 31, 255)", true},
}
for _, test := range tests {
actual := IsRGBcolor(test.param)
if actual != test.expected {
t.Errorf("Expected IsRGBcolor(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsNull(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"abacaba", false},
{"", true},
}
for _, test := range tests {
actual := IsNull(test.param)
if actual != test.expected {
t.Errorf("Expected IsNull(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsDivisibleBy(t *testing.T) {
t.Parallel()
var tests = []struct {
param1 string
param2 string
expected bool
}{
{"4", "2", true},
{"100", "10", true},
{"", "1", true},
{"123", "foo", false},
{"123", "0", false},
}
for _, test := range tests {
actual := IsDivisibleBy(test.param1, test.param2)
if actual != test.expected {
t.Errorf("Expected IsDivisibleBy(%q, %q) to be %v, got %v", test.param1, test.param2, test.expected, actual)
}
}
}
// This small example illustrate how to work with IsDivisibleBy function.
func ExampleIsDivisibleBy() {
println("1024 is divisible by 64: ", IsDivisibleBy("1024", "64"))
}
func TestIsByteLength(t *testing.T) {
t.Parallel()
var tests = []struct {
param1 string
param2 int
param3 int
expected bool
}{
{"abacaba", 100, -1, false},
{"abacaba", 1, 3, false},
{"abacaba", 1, 7, true},
{"abacaba", 0, 8, true},
{"\ufff0", 1, 1, false},
}
for _, test := range tests {
actual := IsByteLength(test.param1, test.param2, test.param3)
if actual != test.expected {
t.Errorf("Expected IsByteLength(%q, %q, %q) to be %v, got %v", test.param1, test.param2, test.param3, test.expected, actual)
}
}
}
func TestIsJSON(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", false},
{"145", true},
{"asdf", false},
{"123:f00", false},
{"{\"Name\":\"Alice\",\"Body\":\"Hello\",\"Time\":1294706395881547000}", true},
{"{}", true},
{"{\"Key\":{\"Key\":{\"Key\":123}}}", true},
{"[]", true},
{"null", true},
}
for _, test := range tests {
actual := IsJSON(test.param)
if actual != test.expected {
t.Errorf("Expected IsJSON(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsMultibyte(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"abc", false},
{"123", false},
{"<>@;.-=", false},
{"ひらがな・カタカナ、.漢字", true},
{"あいうえお foobar", true},
{"testexample.com", true},
{"testexample.com", true},
{"1234abcDE", true},
{"カタカナ", true},
{"", true},
}
for _, test := range tests {
actual := IsMultibyte(test.param)
if actual != test.expected {
t.Errorf("Expected IsMultibyte(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsASCII(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", true},
{"bar", false},
{"", false},
{"456", false},
{"カタカナ", false},
{"foobar", true},
{"0987654321", true},
{"test@example.com", true},
{"1234abcDEF", true},
{"", true},
}
for _, test := range tests {
actual := IsASCII(test.param)
if actual != test.expected {
t.Errorf("Expected IsASCII(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsPrintableASCII(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", true},
{"bar", false},
{"", false},
{"456", false},
{"カタカナ", false},
{"foobar", true},
{"0987654321", true},
{"test@example.com", true},
{"1234abcDEF", true},
{"newline\n", false},
{"\x19test\x7F", false},
}
for _, test := range tests {
actual := IsPrintableASCII(test.param)
if actual != test.expected {
t.Errorf("Expected IsPrintableASCII(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsFullWidth(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", true},
{"abc", false},
{"abc123", false},
{"!\"#$%&()<>/+=-_? ~^|.,@`{}[]", false},
{"ひらがな・カタカナ、.漢字", true},
{"3ー0 a@com", true},
{"Fカタカナ゙ᆲ", true},
{"GoodParts", true},
{"", true},
}
for _, test := range tests {
actual := IsFullWidth(test.param)
if actual != test.expected {
t.Errorf("Expected IsFullWidth(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsHalfWidth(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", true},
{"あいうえお", false},
{"", false},
{"!\"#$%&()<>/+=-_? ~^|.,@`{}[]", true},
{"l-btn_02--active", true},
{"abc123い", true},
{"カタカナ゙ᆲ←", true},
{"", true},
}
for _, test := range tests {
actual := IsHalfWidth(test.param)
if actual != test.expected {
t.Errorf("Expected IsHalfWidth(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsVariableWidth(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", true},
{"ひらがなカタカナ漢字ABCDE", true},
{"123", true},
{"Fカタカナ゙ᆲ", true},
{"", true},
{"GoodParts", true},
{"abc", false},
{"abc123", false},
{"!\"#$%&()<>/+=-_? ~^|.,@`{}[]", false},
{"ひらがな・カタカナ、.漢字", false},
{"", false},
{"カタカナ゙ᆲ", false},
}
for _, test := range tests {
actual := IsVariableWidth(test.param)
if actual != test.expected {
t.Errorf("Expected IsVariableWidth(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsUUID(t *testing.T) {
t.Parallel()
// Tests without version
var tests = []struct {
param string
expected bool
}{
{"", false},
{"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
{"a987fbc9-4bed-3078-cf07-9141ba07c9f3xxx", false},
{"a987fbc94bed3078cf079141ba07c9f3", false},
{"934859", false},
{"987fbc9-4bed-3078-cf07a-9141ba07c9f3", false},
{"aaaaaaaa-1111-1111-aaag-111111111111", false},
{"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true},
}
for _, test := range tests {
actual := IsUUID(test.param)
if actual != test.expected {
t.Errorf("Expected IsUUID(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
// UUID ver. 3
tests = []struct {
param string
expected bool
}{
{"", false},
{"412452646", false},
{"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
{"a987fbc9-4bed-4078-8f07-9141ba07c9f3", false},
{"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true},
}
for _, test := range tests {
actual := IsUUIDv3(test.param)
if actual != test.expected {
t.Errorf("Expected IsUUIDv3(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
// UUID ver. 4
tests = []struct {
param string
expected bool
}{
{"", false},
{"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
{"a987fbc9-4bed-5078-af07-9141ba07c9f3", false},
{"934859", false},
{"57b73598-8764-4ad0-a76a-679bb6640eb1", true},
{"625e63f3-58f5-40b7-83a1-a72ad31acffb", true},
}
for _, test := range tests {
actual := IsUUIDv4(test.param)
if actual != test.expected {
t.Errorf("Expected IsUUIDv4(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
// UUID ver. 5
tests = []struct {
param string
expected bool
}{
{"", false},
{"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
{"9c858901-8a57-4791-81fe-4c455b099bc9", false},
{"a987fbc9-4bed-3078-cf07-9141ba07c9f3", false},
{"987fbc97-4bed-5078-af07-9141ba07c9f3", true},
{"987fbc97-4bed-5078-9f07-9141ba07c9f3", true},
}
for _, test := range tests {
actual := IsUUIDv5(test.param)
if actual != test.expected {
t.Errorf("Expected IsUUIDv5(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsCreditCard(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", false},
{"foo", false},
{"5398228707871528", false},
{"375556917985515", true},
{"36050234196908", true},
{"4716461583322103", true},
{"4716-2210-5188-5662", true},
{"4929 7226 5379 7141", true},
{"5398228707871527", true},
}
for _, test := range tests {
actual := IsCreditCard(test.param)
if actual != test.expected {
t.Errorf("Expected IsCreditCard(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsISBN(t *testing.T) {
t.Parallel()
// Without version
var tests = []struct {
param string
expected bool
}{
{"", false},
{"foo", false},
{"3836221195", true},
{"1-61729-085-8", true},
{"3 423 21412 0", true},
{"3 401 01319 X", true},
{"9784873113685", true},
{"978-4-87311-368-5", true},
{"978 3401013190", true},
{"978-3-8362-2119-1", true},
}
for _, test := range tests {
actual := IsISBN(test.param, -1)
if actual != test.expected {
t.Errorf("Expected IsISBN(%q, -1) to be %v, got %v", test.param, test.expected, actual)
}
}
// ISBN 10
tests = []struct {
param string
expected bool
}{
{"", false},
{"foo", false},
{"3423214121", false},
{"978-3836221191", false},
{"3-423-21412-1", false},
{"3 423 21412 1", false},
{"3836221195", true},
{"1-61729-085-8", true},
{"3 423 21412 0", true},
{"3 401 01319 X", true},
}
for _, test := range tests {
actual := IsISBN10(test.param)
if actual != test.expected {
t.Errorf("Expected IsISBN10(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
// ISBN 13
tests = []struct {
param string
expected bool
}{
{"", false},
{"foo", false},
{"3-8362-2119-5", false},
{"01234567890ab", false},
{"978 3 8362 2119 0", false},
{"9784873113685", true},
{"978-4-87311-368-5", true},
{"978 3401013190", true},
{"978-3-8362-2119-1", true},
}
for _, test := range tests {
actual := IsISBN13(test.param)
if actual != test.expected {
t.Errorf("Expected IsISBN13(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsDataURI(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"data:image/png;base64,TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4=", true},
{"data:text/plain;base64,Vml2YW11cyBmZXJtZW50dW0gc2VtcGVyIHBvcnRhLg==", true},
{"image/gif;base64,U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", false},
{"data:image/gif;base64,MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuMPNS1Ufof9EW/M98FNw" +
"UAKrwflsqVxaxQjBQnHQmiI7Vac40t8x7pIb8gLGV6wL7sBTJiPovJ0V7y7oc0Ye" +
"rhKh0Rm4skP2z/jHwwZICgGzBvA0rH8xlhUiTvcwDCJ0kc+fh35hNt8srZQM4619" +
"FTgB66Xmp4EtVyhpQV+t02g6NzK72oZI0vnAvqhpkxLeLiMCyrI416wHm5Tkukhx" +
"QmcL2a6hNOyu0ixX/x2kSFXApEnVrJ+/IxGyfyw8kf4N2IZpW5nEP847lpfj0SZZ" +
"Fwrd1mnfnDbYohX2zRptLy2ZUn06Qo9pkG5ntvFEPo9bfZeULtjYzIl6K8gJ2uGZ" + "HQIDAQAB", true},
{"data:image/png;base64,12345", false},
{"", false},
{"data:text,:;base85,U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", false},
}
for _, test := range tests {
actual := IsDataURI(test.param)
if actual != test.expected {
t.Errorf("Expected IsDataURI(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsBase64(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4=", true},
{"Vml2YW11cyBmZXJtZW50dW0gc2VtcGVyIHBvcnRhLg==", true},
{"U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", true},
{"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuMPNS1Ufof9EW/M98FNw" +
"UAKrwflsqVxaxQjBQnHQmiI7Vac40t8x7pIb8gLGV6wL7sBTJiPovJ0V7y7oc0Ye" +
"rhKh0Rm4skP2z/jHwwZICgGzBvA0rH8xlhUiTvcwDCJ0kc+fh35hNt8srZQM4619" +
"FTgB66Xmp4EtVyhpQV+t02g6NzK72oZI0vnAvqhpkxLeLiMCyrI416wHm5Tkukhx" +
"QmcL2a6hNOyu0ixX/x2kSFXApEnVrJ+/IxGyfyw8kf4N2IZpW5nEP847lpfj0SZZ" +
"Fwrd1mnfnDbYohX2zRptLy2ZUn06Qo9pkG5ntvFEPo9bfZeULtjYzIl6K8gJ2uGZ" + "HQIDAQAB", true},
{"12345", false},
{"", false},
{"Vml2YW11cyBmZXJtZtesting123", false},
}
for _, test := range tests {
actual := IsBase64(test.param)
if actual != test.expected {
t.Errorf("Expected IsBase64(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsISO3166Alpha2(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", false},
{"ABCD", false},
{"A", false},
{"AC", false},
{"AP", false},
{"GER", false},
{"NU", true},
{"DE", true},
{"JP", true},
{"JPN", false},
{"ZWE", false},
{"GER", false},
{"DEU", false},
}
for _, test := range tests {
actual := IsISO3166Alpha2(test.param)
if actual != test.expected {
t.Errorf("Expected IsISO3166Alpha2(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsISO3166Alpha3(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", false},
{"ABCD", false},
{"A", false},
{"AC", false},
{"AP", false},
{"NU", false},
{"DE", false},
{"JP", false},
{"ZWE", true},
{"JPN", true},
{"GER", false},
{"DEU", true},
}
for _, test := range tests {
actual := IsISO3166Alpha3(test.param)
if actual != test.expected {
t.Errorf("Expected IsISO3166Alpha3(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsISO693Alpha2(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", false},
{"abcd", false},
{"a", false},
{"ac", false},
{"ap", false},
{"de", true},
{"DE", false},
{"mk", true},
{"mac", false},
{"sw", true},
{"SW", false},
{"ger", false},
{"deu", false},
}
for _, test := range tests {
actual := IsISO693Alpha2(test.param)
if actual != test.expected {
t.Errorf("Expected IsISO693Alpha2(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsISO693Alpha3b(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", false},
{"abcd", false},
{"a", false},
{"ac", false},
{"ap", false},
{"de", false},
{"DE", false},
{"mkd", false},
{"mac", true},
{"sw", false},
{"SW", false},
{"ger", true},
{"deu", false},
}
for _, test := range tests {
actual := IsISO693Alpha3b(test.param)
if actual != test.expected {
t.Errorf("Expected IsISO693Alpha3b(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsIP(t *testing.T) {
t.Parallel()
// Without version
var tests = []struct {
param string
expected bool
}{
{"", false},
{"127.0.0.1", true},
{"0.0.0.0", true},
{"255.255.255.255", true},
{"1.2.3.4", true},
{"::1", true},
{"2001:db8:0000:1:1:1:1:1", true},
{"300.0.0.0", false},
}
for _, test := range tests {
actual := IsIP(test.param)
if actual != test.expected {
t.Errorf("Expected IsIP(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
// IPv4
tests = []struct {
param string
expected bool
}{
{"", false},
{"127.0.0.1", true},
{"0.0.0.0", true},
{"255.255.255.255", true},
{"1.2.3.4", true},
{"::1", false},
{"2001:db8:0000:1:1:1:1:1", false},
{"300.0.0.0", false},
}
for _, test := range tests {
actual := IsIPv4(test.param)
if actual != test.expected {
t.Errorf("Expected IsIPv4(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
// IPv6
tests = []struct {
param string
expected bool
}{
{"", false},
{"127.0.0.1", false},
{"0.0.0.0", false},
{"255.255.255.255", false},
{"1.2.3.4", false},
{"::1", true},
{"2001:db8:0000:1:1:1:1:1", true},
{"300.0.0.0", false},
}
for _, test := range tests {
actual := IsIPv6(test.param)
if actual != test.expected {
t.Errorf("Expected IsIPv6(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsPort(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"1", true},
{"65535", true},
{"0", false},
{"65536", false},
{"65538", false},
}
for _, test := range tests {
actual := IsPort(test.param)
if actual != test.expected {
t.Errorf("Expected IsPort(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsDNSName(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"localhost", true},
{"a.bc", true},
{"a.b.", true},
{"a.b..", false},
{"localhost.local", true},
{"localhost.localdomain.intern", true},
{"l.local.intern", true},
{"ru.link.n.svpncloud.com", true},
{"-localhost", false},
{"localhost.-localdomain", false},
{"localhost.localdomain.-int", false},
{"_localhost", true},
{"localhost._localdomain", true},
{"localhost.localdomain._int", true},
{"lÖcalhost", false},
{"localhost.lÖcaldomain", false},
{"localhost.localdomain.üntern", false},
{"__", true},
{"localhost/", false},
{"127.0.0.1", false},
{"[::1]", false},
{"50.50.50.50", false},
{"localhost.localdomain.intern:65535", false},
{"漢字汉字", false},
{"www.jubfvq1v3p38i51622y0dvmdk1mymowjyeu26gbtw9andgynj1gg8z3msb1kl5z6906k846pj3sulm4kiyk82ln5teqj9nsht59opr0cs5ssltx78lfyvml19lfq1wp4usbl0o36cmiykch1vywbttcus1p9yu0669h8fj4ll7a6bmop505908s1m83q2ec2qr9nbvql2589adma3xsq2o38os2z3dmfh2tth4is4ixyfasasasefqwe4t2ub2fz1rme.de", false},
}
for _, test := range tests {
actual := IsDNSName(test.param)
if actual != test.expected {
t.Errorf("Expected IsDNS(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsHost(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"localhost", true},
{"localhost.localdomain", true},
{"2001:db8:0000:1:1:1:1:1", true},
{"::1", true},
{"play.golang.org", true},
{"localhost.localdomain.intern:65535", false},
{"-[::1]", false},
{"-localhost", false},
{".localhost", false},
}
for _, test := range tests {
actual := IsHost(test.param)
if actual != test.expected {
t.Errorf("Expected IsHost(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsDialString(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"localhost.local:1", true},
{"localhost.localdomain:9090", true},
{"localhost.localdomain.intern:65535", true},
{"127.0.0.1:30000", true},
{"[::1]:80", true},
{"[1200::AB00:1234::2552:7777:1313]:22", false},
{"-localhost:1", false},
{"localhost.-localdomain:9090", false},
{"localhost.localdomain.-int:65535", false},
{"localhost.loc:100000", false},
{"漢字汉字:2", false},
{"www.jubfvq1v3p38i51622y0dvmdk1mymowjyeu26gbtw9andgynj1gg8z3msb1kl5z6906k846pj3sulm4kiyk82ln5teqj9nsht59opr0cs5ssltx78lfyvml19lfq1wp4usbl0o36cmiykch1vywbttcus1p9yu0669h8fj4ll7a6bmop505908s1m83q2ec2qr9nbvql2589adma3xsq2o38os2z3dmfh2tth4is4ixyfasasasefqwe4t2ub2fz1rme.de:20000", false},
}
for _, test := range tests {
actual := IsDialString(test.param)
if actual != test.expected {
t.Errorf("Expected IsDialString(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsMAC(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"3D:F2:C9:A6:B3:4F", true},
{"3D-F2-C9-A6-B3:4F", false},
{"123", false},
{"", false},
{"abacaba", false},
}
for _, test := range tests {
actual := IsMAC(test.param)
if actual != test.expected {
t.Errorf("Expected IsMAC(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestFilePath(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
osType int
}{
{"c:\\" + strings.Repeat("a", 32767), true, Win}, //See http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath
{"c:\\" + strings.Repeat("a", 32768), false, Win},
{"c:\\path\\file (x86)\bar", true, Win},
{"c:\\path\\file", true, Win},
{"c:\\path\\file:exe", false, Unknown},
{"C:\\", true, Win},
{"c:\\path\\file\\", true, Win},
{"c:/path/file/", false, Unknown},
{"/path/file/", true, Unix},
{"/path/file:SAMPLE/", true, Unix},
{"/path/file:/.txt", true, Unix},
{"/path", true, Unix},
{"/path/__bc/file.txt", true, Unix},
{"/path/a--ac/file.txt", true, Unix},
{"/_path/file.txt", true, Unix},
{"/path/__bc/file.txt", true, Unix},
{"/path/a--ac/file.txt", true, Unix},
{"/__path/--file.txt", true, Unix},
{"/path/a bc", true, Unix},
}
for _, test := range tests {
actual, osType := IsFilePath(test.param)
if actual != test.expected || osType != test.osType {
t.Errorf("Expected IsFilePath(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsLatitude(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", false},
{"-90.000", true},
{"+90", true},
{"47.1231231", true},
{"+99.9", false},
{"108", false},
}
for _, test := range tests {
actual := IsLatitude(test.param)
if actual != test.expected {
t.Errorf("Expected IsLatitude(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsLongitude(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", false},
{"-180.000", true},
{"180.1", false},
{"+73.234", true},
{"+382.3811", false},
{"23.11111111", true},
}
for _, test := range tests {
actual := IsLongitude(test.param)
if actual != test.expected {
t.Errorf("Expected IsLongitude(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsSSN(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", false},
{"00-90-8787", false},
{"66690-76", false},
{"191 60 2869", true},
{"191-60-2869", true},
}
for _, test := range tests {
actual := IsSSN(test.param)
if actual != test.expected {
t.Errorf("Expected IsSSN(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsMongoID(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"507f1f77bcf86cd799439011", true},
{"507f1f77bcf86cd7994390", false},
{"507f1f77bcf86cd79943901z", false},
{"507f1f77bcf86cd799439011 ", false},
{"", false},
}
for _, test := range tests {
actual := IsMongoID(test.param)
if actual != test.expected {
t.Errorf("Expected IsMongoID(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsSemver(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"v1.0.0", true},
{"1.0.0", true},
{"1.1.01", false},
{"1.01.0", false},
{"01.1.0", false},
{"v1.1.01", false},
{"v1.01.0", false},
{"v01.1.0", false},
{"1.0.0-alpha", true},
{"1.0.0-alpha.1", true},
{"1.0.0-0.3.7", true},
{"1.0.0-0.03.7", false},
{"1.0.0-00.3.7", false},
{"1.0.0-x.7.z.92", true},
{"1.0.0-alpha+001", true},
{"1.0.0+20130313144700", true},
{"1.0.0-beta+exp.sha.5114f85", true},
{"1.0.0-beta+exp.sha.05114f85", true},
{"1.0.0-+beta", false},
{"1.0.0-b+-9+eta", false},
{"v+1.8.0-b+-9+eta", false},
}
for _, test := range tests {
actual := IsSemver(test.param)
if actual != test.expected {
t.Errorf("Expected IsSemver(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsTime(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
format string
expected bool
}{
{"2016-12-31 11:00", time.RFC3339, false},
{"2016-12-31 11:00:00", time.RFC3339, false},
{"2016-12-31T11:00", time.RFC3339, false},
{"2016-12-31T11:00:00", time.RFC3339, false},
{"2016-12-31T11:00:00Z", time.RFC3339, true},
{"2016-12-31T11:00:00+01:00", time.RFC3339, true},
{"2016-12-31T11:00:00-01:00", time.RFC3339, true},
{"2016-12-31T11:00:00.05Z", time.RFC3339, true},
{"2016-12-31T11:00:00.05-01:00", time.RFC3339, true},
{"2016-12-31T11:00:00.05+01:00", time.RFC3339, true},
{"2016-12-31T11:00:00", RF3339WithoutZone, true},
{"2016-12-31T11:00:00Z", RF3339WithoutZone, false},
{"2016-12-31T11:00:00+01:00", RF3339WithoutZone, false},
{"2016-12-31T11:00:00-01:00", RF3339WithoutZone, false},
{"2016-12-31T11:00:00.05Z", RF3339WithoutZone, false},
{"2016-12-31T11:00:00.05-01:00", RF3339WithoutZone, false},
{"2016-12-31T11:00:00.05+01:00", RF3339WithoutZone, false},
}
for _, test := range tests {
actual := IsTime(test.param, test.format)
if actual != test.expected {
t.Errorf("Expected IsTime(%q, time.RFC3339) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsRFC3339(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"2016-12-31 11:00", false},
{"2016-12-31 11:00:00", false},
{"2016-12-31T11:00", false},
{"2016-12-31T11:00:00", false},
{"2016-12-31T11:00:00Z", true},
{"2016-12-31T11:00:00+01:00", true},
{"2016-12-31T11:00:00-01:00", true},
{"2016-12-31T11:00:00.05Z", true},
{"2016-12-31T11:00:00.05-01:00", true},
{"2016-12-31T11:00:00.05+01:00", true},
}
for _, test := range tests {
actual := IsRFC3339(test.param)
if actual != test.expected {
t.Errorf("Expected IsRFC3339(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestIsISO4217(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"", false},
{"ABCD", false},
{"A", false},
{"ZZZ", false},
{"usd", false},
{"USD", true},
}
for _, test := range tests {
actual := IsISO4217(test.param)
if actual != test.expected {
t.Errorf("Expected IsISO4217(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestByteLength(t *testing.T) {
t.Parallel()
var tests = []struct {
value string
min string
max string
expected bool
}{
{"123456", "0", "100", true},
{"1239999", "0", "0", false},
{"1239asdfasf99", "100", "200", false},
{"1239999asdff29", "10", "30", true},
{"你", "0", "1", false},
}
for _, test := range tests {
actual := ByteLength(test.value, test.min, test.max)
if actual != test.expected {
t.Errorf("Expected ByteLength(%s, %s, %s) to be %v, got %v", test.value, test.min, test.max, test.expected, actual)
}
}
}
func TestRuneLength(t *testing.T) {
t.Parallel()
var tests = []struct {
value string
min string
max string
expected bool
}{
{"123456", "0", "100", true},
{"1239999", "0", "0", false},
{"1239asdfasf99", "100", "200", false},
{"1239999asdff29", "10", "30", true},
{"你", "0", "1", true},
}
for _, test := range tests {
actual := RuneLength(test.value, test.min, test.max)
if actual != test.expected {
t.Errorf("Expected RuneLength(%s, %s, %s) to be %v, got %v", test.value, test.min, test.max, test.expected, actual)
}
}
}
func TestStringLength(t *testing.T) {
t.Parallel()
var tests = []struct {
value string
min string
max string
expected bool
}{
{"123456", "0", "100", true},
{"1239999", "0", "0", false},
{"1239asdfasf99", "100", "200", false},
{"1239999asdff29", "10", "30", true},
{"あいうえお", "0", "5", true},
{"あいうえおか", "0", "5", false},
{"あいうえお", "0", "0", false},
{"あいうえ", "5", "10", false},
}
for _, test := range tests {
actual := StringLength(test.value, test.min, test.max)
if actual != test.expected {
t.Errorf("Expected StringLength(%s, %s, %s) to be %v, got %v", test.value, test.min, test.max, test.expected, actual)
}
}
}
func TestIsIn(t *testing.T) {
t.Parallel()
var tests = []struct {
value string
params []string
expected bool
}{
{"PRESENT", []string{"PRESENT"}, true},
{"PRESENT", []string{"PRESENT", "PRÉSENTE", "NOTABSENT"}, true},
{"PRÉSENTE", []string{"PRESENT", "PRÉSENTE", "NOTABSENT"}, true},
{"PRESENT", []string{}, false},
{"PRESENT", nil, false},
{"ABSENT", []string{"PRESENT", "PRÉSENTE", "NOTABSENT"}, false},
{"", []string{"PRESENT", "PRÉSENTE", "NOTABSENT"}, false},
}
for _, test := range tests {
actual := IsIn(test.value, test.params...)
if actual != test.expected {
t.Errorf("Expected IsIn(%s, %v) to be %v, got %v", test.value, test.params, test.expected, actual)
}
}
}
type Address struct {
Street string `valid:"-"`
Zip string `json:"zip" valid:"numeric,required"`
}
type User struct {
Name string `valid:"required"`
Email string `valid:"required,email"`
Password string `valid:"required"`
Age int `valid:"required,numeric,@#\u0000"`
Home *Address
Work []Address
}
type UserValid struct {
Name string `valid:"required"`
Email string `valid:"required,email"`
Password string `valid:"required"`
Age int `valid:"required"`
Home *Address
Work []Address `valid:"required"`
}
type PrivateStruct struct {
privateField string `valid:"required,alpha,d_k"`
NonZero int
ListInt []int
ListString []string `valid:"alpha"`
Work [2]Address
Home Address
Map map[string]Address
}
type NegationStruct struct {
NotInt string `valid:"!int"`
Int string `valid:"int"`
}
type LengthStruct struct {
Length string `valid:"length(10|20)"`
}
type StringLengthStruct struct {
Length string `valid:"stringlength(10|20)"`
}
type StringMatchesStruct struct {
StringMatches string `valid:"matches(^[0-9]{3}$)"`
}
// TODO: this testcase should be fixed
// type StringMatchesComplexStruct struct {
// StringMatches string `valid:"matches(^\\$\\([\"']\\w+[\"']\\)$)"`
// }
type IsInStruct struct {
IsIn string `valid:"in(PRESENT|PRÉSENTE|NOTABSENT)"`
}
type Post struct {
Title string `valid:"alpha,required"`
Message string `valid:"ascii"`
AuthorIP string `valid:"ipv4"`
}
type MissingValidationDeclarationStruct struct {
Name string ``
Email string `valid:"required,email"`
}
type FieldsRequiredByDefaultButExemptStruct struct {
Name string `valid:"-"`
Email string `valid:"email"`
}
type FieldsRequiredByDefaultButExemptOrOptionalStruct struct {
Name string `valid:"-"`
Email string `valid:"optional,email"`
}
type MessageWithSeveralFieldsStruct struct {
Title string `valid:"length(1|10)"`
Body string `valid:"length(1|10)"`
}
func TestValidateMissingValidationDeclarationStruct(t *testing.T) {
var tests = []struct {
param MissingValidationDeclarationStruct
expected bool
}{
{MissingValidationDeclarationStruct{}, false},
{MissingValidationDeclarationStruct{Name: "TEST", Email: "test@example.com"}, false},
}
SetFieldsRequiredByDefault(true)
for _, test := range tests {
actual, err := ValidateStruct(test.param)
if actual != test.expected {
t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
if err != nil {
t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
}
}
}
SetFieldsRequiredByDefault(false)
}
func TestFieldsRequiredByDefaultButExemptStruct(t *testing.T) {
var tests = []struct {
param FieldsRequiredByDefaultButExemptStruct
expected bool
}{
{FieldsRequiredByDefaultButExemptStruct{}, false},
{FieldsRequiredByDefaultButExemptStruct{Name: "TEST"}, false},
{FieldsRequiredByDefaultButExemptStruct{Email: ""}, false},
{FieldsRequiredByDefaultButExemptStruct{Email: "test@example.com"}, true},
}
SetFieldsRequiredByDefault(true)
for _, test := range tests {
actual, err := ValidateStruct(test.param)
if actual != test.expected {
t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
if err != nil {
t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
}
}
}
SetFieldsRequiredByDefault(false)
}
func TestFieldsRequiredByDefaultButExemptOrOptionalStruct(t *testing.T) {
var tests = []struct {
param FieldsRequiredByDefaultButExemptOrOptionalStruct
expected bool
}{
{FieldsRequiredByDefaultButExemptOrOptionalStruct{}, true},
{FieldsRequiredByDefaultButExemptOrOptionalStruct{Name: "TEST"}, true},
{FieldsRequiredByDefaultButExemptOrOptionalStruct{Email: ""}, true},
{FieldsRequiredByDefaultButExemptOrOptionalStruct{Email: "test@example.com"}, true},
{FieldsRequiredByDefaultButExemptOrOptionalStruct{Email: "test@example"}, false},
}
SetFieldsRequiredByDefault(true)
for _, test := range tests {
actual, err := ValidateStruct(test.param)
if actual != test.expected {
t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
if err != nil {
t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
}
}
}
SetFieldsRequiredByDefault(false)
}
func TestInvalidValidator(t *testing.T) {
type InvalidStruct struct {
Field int `valid:"someInvalidValidator"`
}
invalidStruct := InvalidStruct{1}
if valid, err := ValidateStruct(&invalidStruct); valid || err == nil ||
err.Error() != `Field: The following validator is invalid or can't be applied to the field: "someInvalidValidator"` {
t.Errorf("Got an unexpected result for struct with invalid validator: %t %s", valid, err)
}
}
func TestCustomValidator(t *testing.T) {
type ValidStruct struct {
Field int `valid:"customTrueValidator"`
}
type InvalidStruct struct {
Field int `valid:"customFalseValidator~Custom validator error"`
}
type StructWithCustomAndBuiltinValidator struct {
Field int `valid:"customTrueValidator,required"`
}
if valid, err := ValidateStruct(&ValidStruct{Field: 1}); !valid || err != nil {
t.Errorf("Got an unexpected result for struct with custom always true validator: %t %s", valid, err)
}
if valid, err := ValidateStruct(&InvalidStruct{Field: 1}); valid || err == nil || err.Error() != "Custom validator error" {
t.Errorf("Got an unexpected result for struct with custom always false validator: %t %s", valid, err)
}
mixedStruct := StructWithCustomAndBuiltinValidator{}
if valid, err := ValidateStruct(&mixedStruct); valid || err == nil || err.Error() != "Field: non zero value required" {
t.Errorf("Got an unexpected result for invalid struct with custom and built-in validators: %t %s", valid, err)
}
mixedStruct.Field = 1
if valid, err := ValidateStruct(&mixedStruct); !valid || err != nil {
t.Errorf("Got an unexpected result for valid struct with custom and built-in validators: %t %s", valid, err)
}
}
type CustomByteArray [6]byte
type StructWithCustomByteArray struct {
ID CustomByteArray `valid:"customByteArrayValidator,customMinLengthValidator"`
Email string `valid:"email"`
CustomMinLength int `valid:"-"`
}
func TestStructWithCustomByteArray(t *testing.T) {
t.Parallel()
// add our custom byte array validator that fails when the byte array is pristine (all zeroes)
CustomTypeTagMap.Set("customByteArrayValidator", CustomTypeValidator(func(i interface{}, o interface{}) bool {
switch v := o.(type) {
case StructWithCustomByteArray:
if len(v.Email) > 0 {
if v.Email != "test@example.com" {
t.Errorf("v.Email should have been 'test@example.com' but was '%s'", v.Email)
}
}
default:
t.Errorf("Context object passed to custom validator should have been a StructWithCustomByteArray but was %T (%+v)", o, o)
}
switch v := i.(type) {
case CustomByteArray:
for _, e := range v { // check if v is empty, i.e. all zeroes
if e != 0 {
return true
}
}
}
return false
}))
CustomTypeTagMap.Set("customMinLengthValidator", CustomTypeValidator(func(i interface{}, o interface{}) bool {
switch v := o.(type) {
case StructWithCustomByteArray:
return len(v.ID) >= v.CustomMinLength
}
return false
}))
testCustomByteArray := CustomByteArray{'1', '2', '3', '4', '5', '6'}
var tests = []struct {
param StructWithCustomByteArray
expected bool
}{
{StructWithCustomByteArray{}, false},
{StructWithCustomByteArray{Email: "test@example.com"}, false},
{StructWithCustomByteArray{ID: testCustomByteArray, Email: "test@example.com"}, true},
{StructWithCustomByteArray{ID: testCustomByteArray, Email: "test@example.com", CustomMinLength: 7}, false},
}
SetFieldsRequiredByDefault(true)
for _, test := range tests {
actual, err := ValidateStruct(test.param)
if actual != test.expected {
t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
if err != nil {
t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
}
}
}
SetFieldsRequiredByDefault(false)
}
func TestValidateNegationStruct(t *testing.T) {
var tests = []struct {
param NegationStruct
expected bool
}{
{NegationStruct{"a1", "11"}, true},
{NegationStruct{"email@email.email", "11"}, true},
{NegationStruct{"123456----", "11"}, true},
{NegationStruct{"::1", "11"}, true},
{NegationStruct{"123.123", "11"}, true},
{NegationStruct{"a1", "a1"}, false},
{NegationStruct{"11", "a1"}, false},
{NegationStruct{"11", "11"}, false},
}
for _, test := range tests {
actual, err := ValidateStruct(test.param)
if actual != test.expected {
t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
if err != nil {
t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
}
}
}
}
func TestLengthStruct(t *testing.T) {
var tests = []struct {
param interface{}
expected bool
}{
{LengthStruct{"11111"}, false},
{LengthStruct{"11111111111111111110000000000000000"}, false},
{LengthStruct{"11dfffdf0099"}, true},
}
for _, test := range tests {
actual, err := ValidateStruct(test.param)
if actual != test.expected {
t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
if err != nil {
t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
}
}
}
}
func TestStringLengthStruct(t *testing.T) {
var tests = []struct {
param interface{}
expected bool
}{
{StringLengthStruct{"11111"}, false},
{StringLengthStruct{"11111111111111111110000000000000000"}, false},
{StringLengthStruct{"11dfffdf0099"}, true},
{StringLengthStruct{"あいうえお"}, false},
{StringLengthStruct{"あいうえおかきくけこ"}, true},
{StringLengthStruct{"あいうえおかきくけこさしすせそたちつてと"}, true},
{StringLengthStruct{"あいうえおかきくけこさしすせそたちつてとな"}, false},
}
for _, test := range tests {
actual, err := ValidateStruct(test.param)
if actual != test.expected {
t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
if err != nil {
t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
}
}
}
}
func TestStringMatchesStruct(t *testing.T) {
var tests = []struct {
param interface{}
expected bool
}{
{StringMatchesStruct{"123"}, true},
{StringMatchesStruct{"123456"}, false},
{StringMatchesStruct{"123abcd"}, false},
}
for _, test := range tests {
actual, err := ValidateStruct(test.param)
if actual != test.expected {
t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
if err != nil {
t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
}
}
}
}
func TestIsInStruct(t *testing.T) {
var tests = []struct {
param interface{}
expected bool
}{
{IsInStruct{"PRESENT"}, true},
{IsInStruct{""}, true},
{IsInStruct{" "}, false},
{IsInStruct{"ABSENT"}, false},
}
for _, test := range tests {
actual, err := ValidateStruct(test.param)
if actual != test.expected {
t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
if err != nil {
t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
}
}
}
}
func TestRequiredIsInStruct(t *testing.T) {
type RequiredIsInStruct struct {
IsIn string `valid:"in(PRESENT|PRÉSENTE|NOTABSENT),required"`
}
var tests = []struct {
param interface{}
expected bool
}{
{RequiredIsInStruct{"PRESENT"}, true},
{RequiredIsInStruct{""}, false},
{RequiredIsInStruct{" "}, false},
{RequiredIsInStruct{"ABSENT"}, false},
}
for _, test := range tests {
actual, err := ValidateStruct(test.param)
if actual != test.expected {
t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
if err != nil {
t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
}
}
}
}
func TestEmptyRequiredIsInStruct(t *testing.T) {
type EmptyRequiredIsInStruct struct {
IsIn string `valid:"in(),required"`
}
var tests = []struct {
param interface{}
expected bool
}{
{EmptyRequiredIsInStruct{"PRESENT"}, false},
{EmptyRequiredIsInStruct{""}, false},
{EmptyRequiredIsInStruct{" "}, false},
{EmptyRequiredIsInStruct{"ABSENT"}, false},
}
for _, test := range tests {
actual, err := ValidateStruct(test.param)
if actual != test.expected {
t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
if err != nil {
t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
}
}
}
}
func TestFunkyIsInStruct(t *testing.T) {
type FunkyIsInStruct struct {
IsIn string `valid:"in(PRESENT|| |PRÉSENTE|NOTABSENT)"`
}
var tests = []struct {
param interface{}
expected bool
}{
{FunkyIsInStruct{"PRESENT"}, true},
{FunkyIsInStruct{""}, true},
{FunkyIsInStruct{" "}, true},
{FunkyIsInStruct{"ABSENT"}, false},
}
for _, test := range tests {
actual, err := ValidateStruct(test.param)
if actual != test.expected {
t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
if err != nil {
t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
}
}
}
}
// TODO: test case broken
// func TestStringMatchesComplexStruct(t *testing.T) {
// var tests = []struct {
// param interface{}
// expected bool
// }{
// {StringMatchesComplexStruct{"$()"}, false},
// {StringMatchesComplexStruct{"$('AZERTY')"}, true},
// {StringMatchesComplexStruct{`$("AZERTY")`}, true},
// {StringMatchesComplexStruct{`$("")`}, false},
// {StringMatchesComplexStruct{"AZERTY"}, false},
// {StringMatchesComplexStruct{"$AZERTY"}, false},
// }
// for _, test := range tests {
// actual, err := ValidateStruct(test.param)
// if actual != test.expected {
// t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
// if err != nil {
// t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
// }
// }
// }
// }
func TestValidateStruct(t *testing.T) {
var tests = []struct {
param interface{}
expected bool
}{
{User{"John", "john@yahoo.com", "123G#678", 20, &Address{"Street", "123456"}, []Address{{"Street", "123456"}, {"Street", "123456"}}}, false},
{User{"John", "john!yahoo.com", "12345678", 20, &Address{"Street", "ABC456D89"}, []Address{{"Street", "ABC456D89"}, {"Street", "123456"}}}, false},
{User{"John", "", "12345", 0, &Address{"Street", "123456789"}, []Address{{"Street", "ABC456D89"}, {"Street", "123456"}}}, false},
{UserValid{"John", "john@yahoo.com", "123G#678", 20, &Address{"Street", "123456"}, []Address{{"Street", "123456"}, {"Street", "123456"}}}, true},
{UserValid{"John", "john!yahoo.com", "12345678", 20, &Address{"Street", "ABC456D89"}, []Address{}}, false},
{UserValid{"John", "john!yahoo.com", "12345678", 20, &Address{"Street", "ABC456D89"}, []Address{{"Street", "ABC456D89"}, {"Street", "123456"}}}, false},
{UserValid{"John", "", "12345", 0, &Address{"Street", "123456789"}, []Address{{"Street", "ABC456D89"}, {"Street", "123456"}}}, false},
{nil, true},
{User{"John", "john@yahoo.com", "123G#678", 0, &Address{"Street", "123456"}, []Address{}}, false},
{"im not a struct", false},
}
for _, test := range tests {
actual, err := ValidateStruct(test.param)
if actual != test.expected {
t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
if err != nil {
t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
}
}
}
TagMap["d_k"] = Validator(func(str string) bool {
return str == "d_k"
})
result, err := ValidateStruct(PrivateStruct{"d_k", 0, []int{1, 2}, []string{"hi", "super"}, [2]Address{{"Street", "123456"},
{"Street", "123456"}}, Address{"Street", "123456"}, map[string]Address{"address": {"Street", "123456"}}})
if result != true {
t.Log("Case ", 6, ": expected ", true, " when result is ", result)
t.Error(err)
t.FailNow()
}
}
type testByteArray [8]byte
type testByteMap map[byte]byte
type testByteSlice []byte
type testStringStringMap map[string]string
type testStringIntMap map[string]int
func TestRequired(t *testing.T) {
testString := "foobar"
var tests = []struct {
param interface{}
expected bool
}{
{
struct {
Pointer *string `valid:"required"`
}{},
false,
},
{
struct {
Pointer *string `valid:"required"`
}{
Pointer: &testString,
},
true,
},
{
struct {
Addr Address `valid:"required"`
}{},
false,
},
{
struct {
Addr Address `valid:"required"`
}{
Addr: Address{"", "123"},
},
true,
},
{
struct {
Pointer *Address `valid:"required"`
}{},
false,
},
{
struct {
Pointer *Address `valid:"required"`
}{
Pointer: &Address{"", "123"},
},
true,
},
{
struct {
TestByteArray testByteArray `valid:"required"`
}{},
false,
},
{
struct {
TestByteArray testByteArray `valid:"required"`
}{
testByteArray{},
},
false,
},
{
struct {
TestByteArray testByteArray `valid:"required"`
}{
testByteArray{'1', '2', '3', '4', '5', '6', '7', 'A'},
},
true,
},
{
struct {
TestByteMap testByteMap `valid:"required"`
}{},
false,
},
{
struct {
TestByteSlice testByteSlice `valid:"required"`
}{},
false,
},
{
struct {
TestStringStringMap testStringStringMap `valid:"required"`
}{
testStringStringMap{"test": "test"},
},
true,
},
{
struct {
TestIntMap testStringIntMap `valid:"required"`
}{
testStringIntMap{"test": 42},
},
true,
},
}
for _, test := range tests {
actual, err := ValidateStruct(test.param)
if actual != test.expected {
t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual)
if err != nil {
t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err)
}
}
}
}
func TestErrorByField(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected string
}{
{"message", ""},
{"Message", ""},
{"title", ""},
{"Title", "My123 does not validate as alpha"},
{"AuthorIP", "123 does not validate as ipv4"},
}
post := &Post{"My123", "duck13126", "123"}
_, err := ValidateStruct(post)
for _, test := range tests {
actual := ErrorByField(err, test.param)
if actual != test.expected {
t.Errorf("Expected ErrorByField(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestErrorsByField(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected string
}{
{"Title", "My123 does not validate as alpha"},
{"AuthorIP", "123 does not validate as ipv4"},
}
post := &Post{Title: "My123", Message: "duck13126", AuthorIP: "123"}
_, err := ValidateStruct(post)
errs := ErrorsByField(err)
if len(errs) != 2 {
t.Errorf("There should only be 2 errors but got %v", len(errs))
}
for _, test := range tests {
if actual, ok := errs[test.param]; !ok || actual != test.expected {
t.Errorf("Expected ErrorsByField(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
tests = []struct {
param string
expected string
}{
{"Title", ";:;message;:; does not validate as length(1|10)"},
{"Body", ";:;message;:; does not validate as length(1|10)"},
}
message := &MessageWithSeveralFieldsStruct{Title: ";:;message;:;", Body: ";:;message;:;"}
_, err = ValidateStruct(message)
errs = ErrorsByField(err)
if len(errs) != 2 {
t.Errorf("There should only be 2 errors but got %v", len(errs))
}
for _, test := range tests {
if actual, ok := errs[test.param]; !ok || actual != test.expected {
t.Errorf("Expected ErrorsByField(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
tests = []struct {
param string
expected string
}{
{"CustomField", "An error occurred"},
}
err = Error{"CustomField", fmt.Errorf("An error occurred"), false, "hello"}
errs = ErrorsByField(err)
if len(errs) != 1 {
t.Errorf("There should only be 1 errors but got %v", len(errs))
}
for _, test := range tests {
if actual, ok := errs[test.param]; !ok || actual != test.expected {
t.Errorf("Expected ErrorsByField(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
type StructWithCustomValidation struct {
Email string `valid:"email"`
ID string `valid:"falseValidation"`
}
CustomTypeTagMap.Set("falseValidation", CustomTypeValidator(func(i interface{}, o interface{}) bool {
return false
}))
tests = []struct {
param string
expected string
}{
{"Email", "My123 does not validate as email"},
{"ID", "duck13126 does not validate as falseValidation"},
}
s := &StructWithCustomValidation{Email: "My123", ID: "duck13126"}
_, err = ValidateStruct(s)
errs = ErrorsByField(err)
if len(errs) != 2 {
t.Errorf("There should only be 2 errors but got %v", len(errs))
}
for _, test := range tests {
if actual, ok := errs[test.param]; !ok || actual != test.expected {
t.Errorf("Expected ErrorsByField(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestValidateStructPointers(t *testing.T) {
// Struct which uses pointers for values
type UserWithPointers struct {
Name *string `valid:"-"`
Email *string `valid:"email"`
FavoriteFood *string `valid:"length(0|32)"`
Nerd *bool `valid:"-"`
}
var tests = []struct {
param string
expected string
}{
{"Name", ""},
{"Email", "invalid does not validate as email"},
{"FavoriteFood", ""},
{"Nerd", ""},
}
name := "Herman"
email := "invalid"
food := "Pizza"
nerd := true
user := &UserWithPointers{&name, &email, &food, &nerd}
_, err := ValidateStruct(user)
for _, test := range tests {
actual := ErrorByField(err, test.param)
if actual != test.expected {
t.Errorf("Expected ErrorByField(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func ExampleValidateStruct() {
type Post struct {
Title string `valid:"alphanum,required"`
Message string `valid:"duck,ascii"`
AuthorIP string `valid:"ipv4"`
}
post := &Post{"My Example Post", "duck", "123.234.54.3"}
//Add your own struct validation tags
TagMap["duck"] = Validator(func(str string) bool {
return str == "duck"
})
result, err := ValidateStruct(post)
if err != nil {
println("error: " + err.Error())
}
println(result)
}
func TestIsCIDR(t *testing.T) {
t.Parallel()
var tests = []struct {
param string
expected bool
}{
{"193.168.3.20/7", true},
{"2001:db8::/32", true},
{"2001:0db8:85a3:0000:0000:8a2e:0370:7334/64", true},
{"193.138.3.20/60", false},
{"500.323.2.23/43", false},
{"", false},
}
for _, test := range tests {
actual := IsCIDR(test.param)
if actual != test.expected {
t.Errorf("Expected IsCIDR(%q) to be %v, got %v", test.param, test.expected, actual)
}
}
}
func TestOptionalCustomValidators(t *testing.T) {
CustomTypeTagMap.Set("f2", CustomTypeValidator(func(i interface{}, o interface{}) bool {
return false
}))
var val struct {
WithCustomError string `valid:"f2~boom,optional"`
WithoutCustomError string `valid:"f2,optional"`
OptionalFirst string `valid:"optional,f2"`
}
ok, err := ValidateStruct(val)
if err != nil {
t.Errorf("Expected nil err with optional validation, got %v", err)
}
if !ok {
t.Error("Expected validation to return true, got false")
}
}
func TestJSONValidator(t *testing.T) {
var val struct {
WithJSONName string `json:"with_json_name" valid:"-,required"`
WithoutJSONName string `valid:"-,required"`
WithJSONOmit string `json:"with_other_json_name,omitempty" valid:"-,required"`
WithJSONOption string `json:",omitempty" valid:"-,required"`
WithEmptyJSONName string `json:"-" valid:"-,required"`
}
_, err := ValidateStruct(val)
if err == nil {
t.Error("Expected error but got no error")
}
if Contains(err.Error(), "WithJSONName") {
t.Errorf("Expected error message to contain with_json_name but actual error is: %s", err.Error())
}
if Contains(err.Error(), "WithoutJSONName") == false {
t.Errorf("Expected error message to contain WithoutJSONName but actual error is: %s", err.Error())
}
if Contains(err.Error(), "omitempty") {
t.Errorf("Expected error message to not contain ',omitempty' but actual error is: %s", err.Error())
}
if !Contains(err.Error(), "WithEmptyJSONName") {
t.Errorf("Expected error message to contain WithEmptyJSONName but actual error is: %s", err.Error())
}
}
func TestValidatorIncludedInError(t *testing.T) {
post := Post{
Title: "",
Message: "👍",
AuthorIP: "xyz",
}
validatorMap := map[string]string{
"Title": "required",
"Message": "ascii",
"AuthorIP": "ipv4",
}
ok, errors := ValidateStruct(post)
if ok {
t.Errorf("expected validation to fail %v", ok)
}
for _, e := range errors.(Errors) {
casted := e.(Error)
if validatorMap[casted.Name] != casted.Validator {
t.Errorf("expected validator for %s to be %s, but was %s", casted.Name, validatorMap[casted.Name], casted.Validator)
}
}
// check to make sure that validators with arguments (like length(1|10)) don't include the arguments
// in the validator name
message := MessageWithSeveralFieldsStruct{
Title: "",
Body: "asdfasdfasdfasdfasdf",
}
validatorMap = map[string]string{
"Title": "length",
"Body": "length",
}
ok, errors = ValidateStruct(message)
if ok {
t.Errorf("expected validation to fail, %v", ok)
}
for _, e := range errors.(Errors) {
casted := e.(Error)
if validatorMap[casted.Name] != casted.Validator {
t.Errorf("expected validator for %s to be %s, but was %s", casted.Name, validatorMap[casted.Name], casted.Validator)
}
}
// make sure validators with custom messages don't show up in the validator string
type CustomMessage struct {
Text string `valid:"length(1|10)~Custom message"`
}
cs := CustomMessage{Text: "asdfasdfasdfasdf"}
ok, errors = ValidateStruct(&cs)
if ok {
t.Errorf("expected validation to fail, %v", ok)
}
validator := errors.(Errors)[0].(Error).Validator
if validator != "length" {
t.Errorf("expected validator for Text to be length, but was %s", validator)
}
}
func TestIsRsaPublicKey(t *testing.T) {
var tests = []struct {
rsastr string
keylen int
expected bool
}{
{`fubar`, 2048, false},
{`MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvncDCeibmEkabJLmFec7x9y86RP6dIvkVxxbQoOJo06E+p7tH6vCmiGHKnuu
XwKYLq0DKUE3t/HHsNdowfD9+NH8caLzmXqGBx45/Dzxnwqz0qYq7idK+Qff34qrk/YFoU7498U1Ee7PkKb7/VE9BmMEcI3uoKbeXCbJRI
HoTp8bUXOpNTSUfwUNwJzbm2nsHo2xu6virKtAZLTsJFzTUmRd11MrWCvj59lWzt1/eIMN+ekjH8aXeLOOl54CL+kWp48C+V9BchyKCShZ
B7ucimFvjHTtuxziXZQRO7HlcsBOa0WwvDJnRnskdyoD31s4F4jpKEYBJNWTo63v6lUvbQIDAQAB`, 2048, true},
{`MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvncDCeibmEkabJLmFec7x9y86RP6dIvkVxxbQoOJo06E+p7tH6vCmiGHKnuu
XwKYLq0DKUE3t/HHsNdowfD9+NH8caLzmXqGBx45/Dzxnwqz0qYq7idK+Qff34qrk/YFoU7498U1Ee7PkKb7/VE9BmMEcI3uoKbeXCbJRI
HoTp8bUXOpNTSUfwUNwJzbm2nsHo2xu6virKtAZLTsJFzTUmRd11MrWCvj59lWzt1/eIMN+ekjH8aXeLOOl54CL+kWp48C+V9BchyKCShZ
B7ucimFvjHTtuxziXZQRO7HlcsBOa0WwvDJnRnskdyoD31s4F4jpKEYBJNWTo63v6lUvbQIDAQAB`, 1024, false},
{`-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvncDCeibmEkabJLmFec7
x9y86RP6dIvkVxxbQoOJo06E+p7tH6vCmiGHKnuuXwKYLq0DKUE3t/HHsNdowfD9
+NH8caLzmXqGBx45/Dzxnwqz0qYq7idK+Qff34qrk/YFoU7498U1Ee7PkKb7/VE9
BmMEcI3uoKbeXCbJRIHoTp8bUXOpNTSUfwUNwJzbm2nsHo2xu6virKtAZLTsJFzT
UmRd11MrWCvj59lWzt1/eIMN+ekjH8aXeLOOl54CL+kWp48C+V9BchyKCShZB7uc
imFvjHTtuxziXZQRO7HlcsBOa0WwvDJnRnskdyoD31s4F4jpKEYBJNWTo63v6lUv
bQIDAQAB
-----END PUBLIC KEY-----`, 2048, true},
{`-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvncDCeibmEkabJLmFec7
x9y86RP6dIvkVxxbQoOJo06E+p7tH6vCmiGHKnuuXwKYLq0DKUE3t/HHsNdowfD9
+NH8caLzmXqGBx45/Dzxnwqz0qYq7idK+Qff34qrk/YFoU7498U1Ee7PkKb7/VE9
BmMEcI3uoKbeXCbJRIHoTp8bUXOpNTSUfwUNwJzbm2nsHo2xu6virKtAZLTsJFzT
UmRd11MrWCvj59lWzt1/eIMN+ekjH8aXeLOOl54CL+kWp48C+V9BchyKCShZB7uc
imFvjHTtuxziXZQRO7HlcsBOa0WwvDJnRnskdyoD31s4F4jpKEYBJNWTo63v6lUv
bQIDAQAB
-----END PUBLIC KEY-----`, 4096, false},
}
for i, test := range tests {
actual := IsRsaPublicKey(test.rsastr, test.keylen)
if actual != test.expected {
t.Errorf("Expected TestIsRsaPublicKey(%d, %d) to be %v, got %v", i, test.keylen, test.expected, actual)
}
}
}