| 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 TestHasLowerCase(t *testing.T) { |
| t.Parallel() |
| |
| var tests = []struct { |
| param string |
| expected bool |
| }{ |
| {"", true}, |
| {"abc123", true}, |
| {"abc", true}, |
| {"a b c", true}, |
| {"abcß", true}, |
| {"abcẞ", true}, |
| {"ABCẞ", false}, |
| {"tr竪s 端ber", true}, |
| {"fooBar", true}, |
| {"123ABC", false}, |
| {"ABC123", false}, |
| {"ABC", false}, |
| {"S T R", false}, |
| {"fooBar", true}, |
| {"abacaba123", true}, |
| {"FÒÔBÀŘ", false}, |
| {"fòôbàř", true}, |
| {"fÒÔBÀŘ", true}, |
| } |
| for _, test := range tests { |
| actual := HasLowerCase(test.param) |
| if actual != test.expected { |
| t.Errorf("Expected HasLowerCase(%q) to be %v, got %v", test.param, test.expected, actual) |
| } |
| } |
| } |
| |
| func TestHasUpperCase(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", true}, |
| {"123ABC", true}, |
| {"ABC123", true}, |
| {"ABC", true}, |
| {"S T R", true}, |
| {"fooBar", true}, |
| {"abacaba123", false}, |
| {"FÒÔBÀŘ", true}, |
| {"fòôbàř", false}, |
| {"Fòôbàř", true}, |
| } |
| for _, test := range tests { |
| actual := HasUpperCase(test.param) |
| if actual != test.expected { |
| t.Errorf("Expected HasUpperCase(%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 TestIsExistingEmail(t *testing.T) { |
| t.Parallel() |
| |
| var tests = []struct { |
| param string |
| expected bool |
| }{ |
| {"", false}, |
| {"foo@bar.com", true}, |
| {"foo@bar.com.au", true}, |
| {"foo+bar@bar.com", true}, |
| {"foo@bar.coffee", true}, |
| {"foo@bar.coffee..coffee", false}, |
| {"invalidemail@", false}, |
| {"invalid.com", false}, |
| {"@invalid.com", false}, |
| {"NathAn.daVIeS@DomaIn.cOM", true}, |
| {"NATHAN.DAVIES@DOMAIN.CO.UK", true}, |
| } |
| for _, test := range tests { |
| actual := IsExistingEmail(test.param) |
| if actual != test.expected { |
| t.Errorf("Expected IsExistingEmail(%q) to be %v, got %v", test.param, 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}, |
| {"/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}, |
| {"/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}, |
| {"test@example.com", true}, |
| {"test@example.com", true}, |
| {"1234abcDExyz", 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}, |
| {"foobar", false}, |
| {"xyz098", false}, |
| {"123456", 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}, |
| {"foobar", false}, |
| {"xyz098", false}, |
| {"123456", 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}, |
| {"Good=Parts", 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}, |
| {"0011", 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}, |
| {"3ー0123", true}, |
| {"Fカタカナ゙ᆲ", true}, |
| {"", true}, |
| {"Good=Parts", true}, |
| {"abc", false}, |
| {"abc123", false}, |
| {"!\"#$%&()<>/+=-_? ~^|.,@`{}[]", false}, |
| {"ひらがな・カタカナ、.漢字", false}, |
| {"123456", 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 FieldRequiredByDefault struct { |
| Email string `valid:"email"` |
| } |
| |
| type MultipleFieldsRequiredByDefault struct { |
| Url string `valid:"url"` |
| Email string `valid:"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 TestFieldRequiredByDefault(t *testing.T) { |
| var tests = []struct { |
| param FieldRequiredByDefault |
| expected bool |
| }{ |
| {FieldRequiredByDefault{}, 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 TestMultipleFieldsRequiredByDefault(t *testing.T) { |
| var tests = []struct { |
| param MultipleFieldsRequiredByDefault |
| expected bool |
| }{ |
| {MultipleFieldsRequiredByDefault{}, 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", "123456xxx"}, []Address{{"Street", "123456"}, {"Street", "123456"}}}, 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 TestValidateStructParamValidatorInt(t *testing.T) { |
| type Test1 struct { |
| Int int `valid:"range(1|10)"` |
| Int8 int8 `valid:"range(1|10)"` |
| Int16 int16 `valid:"range(1|10)"` |
| Int32 int32 `valid:"range(1|10)"` |
| Int64 int64 `valid:"range(1|10)"` |
| |
| Uint uint `valid:"range(1|10)"` |
| Uint8 uint8 `valid:"range(1|10)"` |
| Uint16 uint16 `valid:"range(1|10)"` |
| Uint32 uint32 `valid:"range(1|10)"` |
| Uint64 uint64 `valid:"range(1|10)"` |
| |
| Float32 float32 `valid:"range(1|10)"` |
| Float64 float64 `valid:"range(1|10)"` |
| } |
| test1Ok := &Test1{5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5} |
| test1NotOk := &Test1{11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11} |
| |
| _, err := ValidateStruct(test1Ok) |
| if err != nil { |
| t.Errorf("Test failed: %s", err) |
| } |
| |
| _, err = ValidateStruct(test1NotOk) |
| if err == nil { |
| t.Errorf("Test failed: nil") |
| } |
| |
| type Test2 struct { |
| Int int `valid:"in(1|10)"` |
| Int8 int8 `valid:"in(1|10)"` |
| Int16 int16 `valid:"in(1|10)"` |
| Int32 int32 `valid:"in(1|10)"` |
| Int64 int64 `valid:"in(1|10)"` |
| |
| Uint uint `valid:"in(1|10)"` |
| Uint8 uint8 `valid:"in(1|10)"` |
| Uint16 uint16 `valid:"in(1|10)"` |
| Uint32 uint32 `valid:"in(1|10)"` |
| Uint64 uint64 `valid:"in(1|10)"` |
| |
| Float32 float32 `valid:"in(1|10)"` |
| Float64 float64 `valid:"in(1|10)"` |
| } |
| |
| test2Ok1 := &Test2{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} |
| test2Ok2 := &Test2{10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10} |
| test2NotOk := &Test2{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2} |
| |
| _, err = ValidateStruct(test2Ok1) |
| if err != nil { |
| t.Errorf("Test failed: %s", err) |
| } |
| |
| _, err = ValidateStruct(test2Ok2) |
| if err != nil { |
| t.Errorf("Test failed: %s", err) |
| } |
| |
| _, err = ValidateStruct(test2NotOk) |
| if err == nil { |
| t.Errorf("Test failed: nil") |
| } |
| } |
| |
| 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) |
| } |
| } |
| } |