1package govalidator 2 3import ( 4 "fmt" 5 "strings" 6 "testing" 7 "time" 8) 9 10func init() { 11 CustomTypeTagMap.Set("customFalseValidator", CustomTypeValidator(func(i interface{}, o interface{}) bool { 12 return false 13 })) 14 CustomTypeTagMap.Set("customTrueValidator", CustomTypeValidator(func(i interface{}, o interface{}) bool { 15 return true 16 })) 17} 18 19func TestIsAlpha(t *testing.T) { 20 t.Parallel() 21 22 var tests = []struct { 23 param string 24 expected bool 25 }{ 26 {"\n", false}, 27 {"\r", false}, 28 {"Ⅸ", false}, 29 {"", true}, 30 {" fooo ", false}, 31 {"abc!!!", false}, 32 {"abc1", false}, 33 {"abc〩", false}, 34 {"abc", true}, 35 {"소주", false}, 36 {"ABC", true}, 37 {"FoObAr", true}, 38 {"소aBC", false}, 39 {"소", false}, 40 {"달기&Co.", false}, 41 {"〩Hours", false}, 42 {"\ufff0", false}, 43 {"\u0070", true}, //UTF-8(ASCII): p 44 {"\u0026", false}, //UTF-8(ASCII): & 45 {"\u0030", false}, //UTF-8(ASCII): 0 46 {"123", false}, 47 {"0123", false}, 48 {"-00123", false}, 49 {"0", false}, 50 {"-0", false}, 51 {"123.123", false}, 52 {" ", false}, 53 {".", false}, 54 {"-1¾", false}, 55 {"1¾", false}, 56 {"〥〩", false}, 57 {"모자", false}, 58 {"ix", true}, 59 {"۳۵۶۰", false}, 60 {"1--", false}, 61 {"1-1", false}, 62 {"-", false}, 63 {"--", false}, 64 {"1++", false}, 65 {"1+1", false}, 66 {"+", false}, 67 {"++", false}, 68 {"+1", false}, 69 } 70 for _, test := range tests { 71 actual := IsAlpha(test.param) 72 if actual != test.expected { 73 t.Errorf("Expected IsAlpha(%q) to be %v, got %v", test.param, test.expected, actual) 74 } 75 } 76} 77 78func TestIsUTFLetter(t *testing.T) { 79 t.Parallel() 80 81 var tests = []struct { 82 param string 83 expected bool 84 }{ 85 {"\n", false}, 86 {"\r", false}, 87 {"Ⅸ", false}, 88 {"", true}, 89 {" fooo ", false}, 90 {"abc!!!", false}, 91 {"abc1", false}, 92 {"abc〩", false}, 93 {"", true}, 94 {"abc", true}, 95 {"소주", true}, 96 {"ABC", true}, 97 {"FoObAr", true}, 98 {"소aBC", true}, 99 {"소", true}, 100 {"달기&Co.", false}, 101 {"〩Hours", false}, 102 {"\ufff0", false}, 103 {"\u0070", true}, //UTF-8(ASCII): p 104 {"\u0026", false}, //UTF-8(ASCII): & 105 {"\u0030", false}, //UTF-8(ASCII): 0 106 {"123", false}, 107 {"0123", false}, 108 {"-00123", false}, 109 {"0", false}, 110 {"-0", false}, 111 {"123.123", false}, 112 {" ", false}, 113 {".", false}, 114 {"-1¾", false}, 115 {"1¾", false}, 116 {"〥〩", false}, 117 {"모자", true}, 118 {"ix", true}, 119 {"۳۵۶۰", false}, 120 {"1--", false}, 121 {"1-1", false}, 122 {"-", false}, 123 {"--", false}, 124 {"1++", false}, 125 {"1+1", false}, 126 {"+", false}, 127 {"++", false}, 128 {"+1", false}, 129 } 130 for _, test := range tests { 131 actual := IsUTFLetter(test.param) 132 if actual != test.expected { 133 t.Errorf("Expected IsUTFLetter(%q) to be %v, got %v", test.param, test.expected, actual) 134 } 135 } 136} 137 138func TestIsAlphanumeric(t *testing.T) { 139 t.Parallel() 140 141 var tests = []struct { 142 param string 143 expected bool 144 }{ 145 {"\n", false}, 146 {"\r", false}, 147 {"Ⅸ", false}, 148 {"", true}, 149 {" fooo ", false}, 150 {"abc!!!", false}, 151 {"abc123", true}, 152 {"ABC111", true}, 153 {"abc1", true}, 154 {"abc〩", false}, 155 {"abc", true}, 156 {"소주", false}, 157 {"ABC", true}, 158 {"FoObAr", true}, 159 {"소aBC", false}, 160 {"소", false}, 161 {"달기&Co.", false}, 162 {"〩Hours", false}, 163 {"\ufff0", false}, 164 {"\u0070", true}, //UTF-8(ASCII): p 165 {"\u0026", false}, //UTF-8(ASCII): & 166 {"\u0030", true}, //UTF-8(ASCII): 0 167 {"123", true}, 168 {"0123", true}, 169 {"-00123", false}, 170 {"0", true}, 171 {"-0", false}, 172 {"123.123", false}, 173 {" ", false}, 174 {".", false}, 175 {"-1¾", false}, 176 {"1¾", false}, 177 {"〥〩", false}, 178 {"모자", false}, 179 {"ix", true}, 180 {"۳۵۶۰", false}, 181 {"1--", false}, 182 {"1-1", false}, 183 {"-", false}, 184 {"--", false}, 185 {"1++", false}, 186 {"1+1", false}, 187 {"+", false}, 188 {"++", false}, 189 {"+1", false}, 190 } 191 for _, test := range tests { 192 actual := IsAlphanumeric(test.param) 193 if actual != test.expected { 194 t.Errorf("Expected IsAlphanumeric(%q) to be %v, got %v", test.param, test.expected, actual) 195 } 196 } 197} 198 199func TestIsUTFLetterNumeric(t *testing.T) { 200 t.Parallel() 201 202 var tests = []struct { 203 param string 204 expected bool 205 }{ 206 {"\n", false}, 207 {"\r", false}, 208 {"Ⅸ", true}, 209 {"", true}, 210 {" fooo ", false}, 211 {"abc!!!", false}, 212 {"abc1", true}, 213 {"abc〩", true}, 214 {"abc", true}, 215 {"소주", true}, 216 {"ABC", true}, 217 {"FoObAr", true}, 218 {"소aBC", true}, 219 {"소", true}, 220 {"달기&Co.", false}, 221 {"〩Hours", true}, 222 {"\ufff0", false}, 223 {"\u0070", true}, //UTF-8(ASCII): p 224 {"\u0026", false}, //UTF-8(ASCII): & 225 {"\u0030", true}, //UTF-8(ASCII): 0 226 {"123", true}, 227 {"0123", true}, 228 {"-00123", false}, 229 {"0", true}, 230 {"-0", false}, 231 {"123.123", false}, 232 {" ", false}, 233 {".", false}, 234 {"-1¾", false}, 235 {"1¾", true}, 236 {"〥〩", true}, 237 {"모자", true}, 238 {"ix", true}, 239 {"۳۵۶۰", true}, 240 {"1--", false}, 241 {"1-1", false}, 242 {"-", false}, 243 {"--", false}, 244 {"1++", false}, 245 {"1+1", false}, 246 {"+", false}, 247 {"++", false}, 248 {"+1", false}, 249 } 250 for _, test := range tests { 251 actual := IsUTFLetterNumeric(test.param) 252 if actual != test.expected { 253 t.Errorf("Expected IsUTFLetterNumeric(%q) to be %v, got %v", test.param, test.expected, actual) 254 } 255 } 256} 257 258func TestIsNumeric(t *testing.T) { 259 t.Parallel() 260 261 var tests = []struct { 262 param string 263 expected bool 264 }{ 265 {"\n", false}, 266 {"\r", false}, 267 {"Ⅸ", false}, 268 {"", true}, 269 {" fooo ", false}, 270 {"abc!!!", false}, 271 {"abc1", false}, 272 {"abc〩", false}, 273 {"abc", false}, 274 {"소주", false}, 275 {"ABC", false}, 276 {"FoObAr", false}, 277 {"소aBC", false}, 278 {"소", false}, 279 {"달기&Co.", false}, 280 {"〩Hours", false}, 281 {"\ufff0", false}, 282 {"\u0070", false}, //UTF-8(ASCII): p 283 {"\u0026", false}, //UTF-8(ASCII): & 284 {"\u0030", true}, //UTF-8(ASCII): 0 285 {"123", true}, 286 {"0123", true}, 287 {"-00123", false}, 288 {"+00123", false}, 289 {"0", true}, 290 {"-0", false}, 291 {"123.123", false}, 292 {" ", false}, 293 {".", false}, 294 {"123", false}, 295 {"-1¾", false}, 296 {"1¾", false}, 297 {"〥〩", false}, 298 {"모자", false}, 299 {"ix", false}, 300 {"۳۵۶۰", false}, 301 {"1--", false}, 302 {"1-1", false}, 303 {"-", false}, 304 {"--", false}, 305 {"1++", false}, 306 {"1+1", false}, 307 {"+", false}, 308 {"++", false}, 309 {"+1", false}, 310 } 311 for _, test := range tests { 312 actual := IsNumeric(test.param) 313 if actual != test.expected { 314 t.Errorf("Expected IsNumeric(%q) to be %v, got %v", test.param, test.expected, actual) 315 } 316 } 317} 318 319func TestIsUTFNumeric(t *testing.T) { 320 t.Parallel() 321 322 var tests = []struct { 323 param string 324 expected bool 325 }{ 326 {"\n", false}, 327 {"\r", false}, 328 {"Ⅸ", true}, 329 {"", true}, 330 {" fooo ", false}, 331 {"abc!!!", false}, 332 {"abc1", false}, 333 {"abc〩", false}, 334 {"abc", false}, 335 {"소주", false}, 336 {"ABC", false}, 337 {"FoObAr", false}, 338 {"소aBC", false}, 339 {"소", false}, 340 {"달기&Co.", false}, 341 {"〩Hours", false}, 342 {"\ufff0", false}, 343 {"\u0070", false}, //UTF-8(ASCII): p 344 {"\u0026", false}, //UTF-8(ASCII): & 345 {"\u0030", true}, //UTF-8(ASCII): 0 346 {"123", true}, 347 {"0123", true}, 348 {"-00123", true}, 349 {"0", true}, 350 {"-0", true}, 351 {"--0", false}, 352 {"-0-", false}, 353 {"123.123", false}, 354 {" ", false}, 355 {".", false}, 356 {"123", true}, 357 {"-1¾", true}, 358 {"1¾", true}, 359 {"〥〩", true}, 360 {"모자", false}, 361 {"ix", false}, 362 {"۳۵۶۰", true}, 363 {"1++", false}, 364 {"1+1", false}, 365 {"+", false}, 366 {"++", false}, 367 {"+1", true}, 368 } 369 for _, test := range tests { 370 actual := IsUTFNumeric(test.param) 371 if actual != test.expected { 372 t.Errorf("Expected IsUTFNumeric(%q) to be %v, got %v", test.param, test.expected, actual) 373 } 374 } 375} 376 377func TestIsUTFDigit(t *testing.T) { 378 t.Parallel() 379 380 var tests = []struct { 381 param string 382 expected bool 383 }{ 384 385 {"\n", false}, 386 {"\r", false}, 387 {"Ⅸ", false}, 388 {"", true}, 389 {" fooo ", false}, 390 {"abc!!!", false}, 391 {"abc1", false}, 392 {"abc〩", false}, 393 {"abc", false}, 394 {"소주", false}, 395 {"ABC", false}, 396 {"FoObAr", false}, 397 {"소aBC", false}, 398 {"소", false}, 399 {"달기&Co.", false}, 400 {"〩Hours", false}, 401 {"\ufff0", false}, 402 {"\u0070", false}, //UTF-8(ASCII): p 403 {"\u0026", false}, //UTF-8(ASCII): & 404 {"\u0030", true}, //UTF-8(ASCII): 0 405 {"123", true}, 406 {"0123", true}, 407 {"-00123", true}, 408 {"0", true}, 409 {"-0", true}, 410 {"--0", false}, 411 {"-0-", false}, 412 {"123.123", false}, 413 {" ", false}, 414 {".", false}, 415 {"123", false}, 416 {"1483920", true}, 417 {"", true}, 418 {"۳۵۶۰", true}, 419 {"-29", true}, 420 {"-1¾", false}, 421 {"1¾", false}, 422 {"〥〩", false}, 423 {"모자", false}, 424 {"ix", false}, 425 {"۳۵۶۰", true}, 426 {"1++", false}, 427 {"1+1", false}, 428 {"+", false}, 429 {"++", false}, 430 {"+1", true}, 431 } 432 for _, test := range tests { 433 actual := IsUTFDigit(test.param) 434 if actual != test.expected { 435 t.Errorf("Expected IsUTFDigit(%q) to be %v, got %v", test.param, test.expected, actual) 436 } 437 } 438} 439 440func TestIsLowerCase(t *testing.T) { 441 t.Parallel() 442 443 var tests = []struct { 444 param string 445 expected bool 446 }{ 447 {"", true}, 448 {"abc123", true}, 449 {"abc", true}, 450 {"a b c", true}, 451 {"abcß", true}, 452 {"abcẞ", false}, 453 {"ABCẞ", false}, 454 {"tr竪s 端ber", true}, 455 {"fooBar", false}, 456 {"123ABC", false}, 457 {"ABC123", false}, 458 {"ABC", false}, 459 {"S T R", false}, 460 {"fooBar", false}, 461 {"abacaba123", true}, 462 } 463 for _, test := range tests { 464 actual := IsLowerCase(test.param) 465 if actual != test.expected { 466 t.Errorf("Expected IsLowerCase(%q) to be %v, got %v", test.param, test.expected, actual) 467 } 468 } 469} 470 471func TestIsUpperCase(t *testing.T) { 472 t.Parallel() 473 474 var tests = []struct { 475 param string 476 expected bool 477 }{ 478 {"", true}, 479 {"abc123", false}, 480 {"abc", false}, 481 {"a b c", false}, 482 {"abcß", false}, 483 {"abcẞ", false}, 484 {"ABCẞ", true}, 485 {"tr竪s 端ber", false}, 486 {"fooBar", false}, 487 {"123ABC", true}, 488 {"ABC123", true}, 489 {"ABC", true}, 490 {"S T R", true}, 491 {"fooBar", false}, 492 {"abacaba123", false}, 493 } 494 for _, test := range tests { 495 actual := IsUpperCase(test.param) 496 if actual != test.expected { 497 t.Errorf("Expected IsUpperCase(%q) to be %v, got %v", test.param, test.expected, actual) 498 } 499 } 500} 501 502func TestHasLowerCase(t *testing.T) { 503 t.Parallel() 504 505 var tests = []struct { 506 param string 507 expected bool 508 }{ 509 {"", true}, 510 {"abc123", true}, 511 {"abc", true}, 512 {"a b c", true}, 513 {"abcß", true}, 514 {"abcẞ", true}, 515 {"ABCẞ", false}, 516 {"tr竪s 端ber", true}, 517 {"fooBar", true}, 518 {"123ABC", false}, 519 {"ABC123", false}, 520 {"ABC", false}, 521 {"S T R", false}, 522 {"fooBar", true}, 523 {"abacaba123", true}, 524 {"FÒÔBÀŘ", false}, 525 {"fòôbàř", true}, 526 {"fÒÔBÀŘ", true}, 527 } 528 for _, test := range tests { 529 actual := HasLowerCase(test.param) 530 if actual != test.expected { 531 t.Errorf("Expected HasLowerCase(%q) to be %v, got %v", test.param, test.expected, actual) 532 } 533 } 534} 535 536func TestHasUpperCase(t *testing.T) { 537 t.Parallel() 538 539 var tests = []struct { 540 param string 541 expected bool 542 }{ 543 {"", true}, 544 {"abc123", false}, 545 {"abc", false}, 546 {"a b c", false}, 547 {"abcß", false}, 548 {"abcẞ", false}, 549 {"ABCẞ", true}, 550 {"tr竪s 端ber", false}, 551 {"fooBar", true}, 552 {"123ABC", true}, 553 {"ABC123", true}, 554 {"ABC", true}, 555 {"S T R", true}, 556 {"fooBar", true}, 557 {"abacaba123", false}, 558 {"FÒÔBÀŘ", true}, 559 {"fòôbàř", false}, 560 {"Fòôbàř", true}, 561 } 562 for _, test := range tests { 563 actual := HasUpperCase(test.param) 564 if actual != test.expected { 565 t.Errorf("Expected HasUpperCase(%q) to be %v, got %v", test.param, test.expected, actual) 566 } 567 } 568} 569 570func TestIsInt(t *testing.T) { 571 t.Parallel() 572 573 var tests = []struct { 574 param string 575 expected bool 576 }{ 577 {"-2147483648", true}, //Signed 32 Bit Min Int 578 {"2147483647", true}, //Signed 32 Bit Max Int 579 {"-2147483649", true}, //Signed 32 Bit Min Int - 1 580 {"2147483648", true}, //Signed 32 Bit Max Int + 1 581 {"4294967295", true}, //Unsigned 32 Bit Max Int 582 {"4294967296", true}, //Unsigned 32 Bit Max Int + 1 583 {"-9223372036854775808", true}, //Signed 64 Bit Min Int 584 {"9223372036854775807", true}, //Signed 64 Bit Max Int 585 {"-9223372036854775809", true}, //Signed 64 Bit Min Int - 1 586 {"9223372036854775808", true}, //Signed 64 Bit Max Int + 1 587 {"18446744073709551615", true}, //Unsigned 64 Bit Max Int 588 {"18446744073709551616", true}, //Unsigned 64 Bit Max Int + 1 589 {"", true}, 590 {"123", true}, 591 {"0", true}, 592 {"-0", true}, 593 {"+0", true}, 594 {"01", false}, 595 {"123.123", false}, 596 {" ", false}, 597 {"000", false}, 598 } 599 for _, test := range tests { 600 actual := IsInt(test.param) 601 if actual != test.expected { 602 t.Errorf("Expected IsInt(%q) to be %v, got %v", test.param, test.expected, actual) 603 } 604 } 605} 606 607func TestIsHash(t *testing.T) { 608 t.Parallel() 609 610 var tests = []struct { 611 param string 612 algo string 613 expected bool 614 }{ 615 {"3ca25ae354e192b26879f651a51d92aa8a34d8d3", "sha1", true}, 616 {"3ca25ae354e192b26879f651a51d34d8d3", "sha1", false}, 617 {"3ca25ae354e192b26879f651a51d92aa8a34d8d3", "Tiger160", true}, 618 {"3ca25ae354e192b26879f651a51d34d8d3", "ripemd160", false}, 619 {"579282cfb65ca1f109b78536effaf621b853c9f7079664a3fbe2b519f435898c", "sha256", true}, 620 {"579282cfb65ca1f109b78536effaf621b853c9f7079664a3fbe2b519f435898casfdsafsadfsdf", "sha256", false}, 621 {"bf547c3fc5841a377eb1519c2890344dbab15c40ae4150b4b34443d2212e5b04aa9d58865bf03d8ae27840fef430b891", "sha384", true}, 622 {"579282cfb65ca1f109b78536effaf621b853c9f7079664a3fbe2b519f435898casfdsafsadfsdf", "sha384", false}, 623 {"45bc5fa8cb45ee408c04b6269e9f1e1c17090c5ce26ffeeda2af097735b29953ce547e40ff3ad0d120e5361cc5f9cee35ea91ecd4077f3f589b4d439168f91b9", "sha512", true}, 624 {"579282cfb65ca1f109b78536effaf621b853c9f7079664a3fbe2b519f435898casfdsafsadfsdf", "sha512", false}, 625 {"46fc0125a148788a3ac1d649566fc04eb84a746f1a6e4fa7", "tiger192", true}, 626 {"46fc0125a148788a3ac1d649566fc04eb84a746f1a6$$%@^", "TIGER192", false}, 627 {"46fc0125a148788a3ac1d649566fc04eb84a746f1a6$$%@^", "SOMEHASH", false}, 628 } 629 for _, test := range tests { 630 actual := IsHash(test.param, test.algo) 631 if actual != test.expected { 632 t.Errorf("Expected IsHash(%q, %q) to be %v, got %v", test.param, test.algo, test.expected, actual) 633 } 634 } 635} 636 637func TestIsExistingEmail(t *testing.T) { 638 t.Parallel() 639 640 var tests = []struct { 641 param string 642 expected bool 643 }{ 644 {"", false}, 645 {"foo@bar.com", true}, 646 {"foo@bar.com.au", true}, 647 {"foo+bar@bar.com", true}, 648 {"foo@bar.coffee", true}, 649 {"foo@bar.coffee..coffee", false}, 650 {"invalidemail@", false}, 651 {"invalid.com", false}, 652 {"@invalid.com", false}, 653 {"NathAn.daVIeS@DomaIn.cOM", true}, 654 {"NATHAN.DAVIES@DOMAIN.CO.UK", true}, 655 } 656 for _, test := range tests { 657 actual := IsExistingEmail(test.param) 658 if actual != test.expected { 659 t.Errorf("Expected IsExistingEmail(%q) to be %v, got %v", test.param, test.expected, actual) 660 } 661 } 662} 663 664func TestIsEmail(t *testing.T) { 665 t.Parallel() 666 667 var tests = []struct { 668 param string 669 expected bool 670 }{ 671 {"", false}, 672 {"foo@bar.com", true}, 673 {"x@x.x", true}, 674 {"foo@bar.com.au", true}, 675 {"foo+bar@bar.com", true}, 676 {"foo@bar.coffee", true}, 677 {"foo@bar.coffee..coffee", false}, 678 {"foo@bar.bar.coffee", true}, 679 {"foo@bar.中文网", true}, 680 {"invalidemail@", false}, 681 {"invalid.com", false}, 682 {"@invalid.com", false}, 683 {"test|123@m端ller.com", true}, 684 {"hans@m端ller.com", true}, 685 {"hans.m端ller@test.com", true}, 686 {"NathAn.daVIeS@DomaIn.cOM", true}, 687 {"NATHAN.DAVIES@DOMAIN.CO.UK", true}, 688 } 689 for _, test := range tests { 690 actual := IsEmail(test.param) 691 if actual != test.expected { 692 t.Errorf("Expected IsEmail(%q) to be %v, got %v", test.param, test.expected, actual) 693 } 694 } 695} 696 697func TestIsURL(t *testing.T) { 698 t.Parallel() 699 700 var tests = []struct { 701 param string 702 expected bool 703 }{ 704 {"", false}, 705 {"http://foo.bar#com", true}, 706 {"http://foobar.com", true}, 707 {"https://foobar.com", true}, 708 {"foobar.com", true}, 709 {"http://foobar.coffee/", true}, 710 {"http://foobar.中文网/", true}, 711 {"http://foobar.org/", true}, 712 {"http://foobar.ORG", true}, 713 {"http://foobar.org:8080/", true}, 714 {"ftp://foobar.ru/", true}, 715 {"ftp.foo.bar", true}, 716 {"http://user:pass@www.foobar.com/", true}, 717 {"http://user:pass@www.foobar.com/path/file", true}, 718 {"http://127.0.0.1/", true}, 719 {"http://duckduckgo.com/?q=%2F", true}, 720 {"http://localhost:3000/", true}, 721 {"http://foobar.com/?foo=bar#baz=qux", true}, 722 {"http://foobar.com?foo=bar", true}, 723 {"http://www.xn--froschgrn-x9a.net/", true}, 724 {"http://foobar.com/a-", true}, 725 {"http://foobar.پاکستان/", true}, 726 {"http://foobar.c_o_m", false}, 727 {"http://_foobar.com", false}, 728 {"http://foo_bar.com", true}, 729 {"http://user:pass@foo_bar_bar.bar_foo.com", true}, 730 {"", false}, 731 {"xyz://foobar.com", false}, 732 // {"invalid.", false}, is it false like "localhost."? 733 {".com", false}, 734 {"rtmp://foobar.com", false}, 735 {"http://localhost:3000/", true}, 736 {"http://foobar.com#baz=qux", true}, 737 {"http://foobar.com/t$-_.+!*\\'(),", true}, 738 {"http://www.foobar.com/~foobar", true}, 739 {"http://www.-foobar.com/", false}, 740 {"http://www.foo---bar.com/", false}, 741 {"http://r6---snnvoxuioq6.googlevideo.com", true}, 742 {"mailto:someone@example.com", true}, 743 {"irc://irc.server.org/channel", false}, 744 {"irc://#channel@network", true}, 745 {"/abs/test/dir", false}, 746 {"./rel/test/dir", false}, 747 {"http://foo^bar.org", false}, 748 {"http://foo&*bar.org", false}, 749 {"http://foo&bar.org", false}, 750 {"http://foo bar.org", false}, 751 {"http://foo.bar.org", true}, 752 {"http://www.foo.bar.org", true}, 753 {"http://www.foo.co.uk", true}, 754 {"foo", false}, 755 {"http://.foo.com", false}, 756 {"http://,foo.com", false}, 757 {",foo.com", false}, 758 {"http://myservice.:9093/", true}, 759 // according to issues #62 #66 760 {"https://pbs.twimg.com/profile_images/560826135676588032/j8fWrmYY_normal.jpeg", true}, 761 // according to #125 762 {"http://prometheus-alertmanager.service.q:9093", true}, 763 {"aio1_alertmanager_container-63376c45:9093", true}, 764 {"https://www.logn-123-123.url.with.sigle.letter.d:12345/url/path/foo?bar=zzz#user", true}, 765 {"http://me.example.com", true}, 766 {"http://www.me.example.com", true}, 767 {"https://farm6.static.flickr.com", true}, 768 {"https://zh.wikipedia.org/wiki/Wikipedia:%E9%A6%96%E9%A1%B5", true}, 769 {"google", false}, 770 // According to #87 771 {"http://hyphenated-host-name.example.co.in", true}, 772 {"http://cant-end-with-hyphen-.example.com", false}, 773 {"http://-cant-start-with-hyphen.example.com", false}, 774 {"http://www.domain-can-have-dashes.com", true}, 775 {"http://m.abcd.com/test.html", true}, 776 {"http://m.abcd.com/a/b/c/d/test.html?args=a&b=c", true}, 777 {"http://[::1]:9093", true}, 778 {"http://[::1]:909388", false}, 779 {"1200::AB00:1234::2552:7777:1313", false}, 780 {"http://[2001:db8:a0b:12f0::1]/index.html", true}, 781 {"http://[1200:0000:AB00:1234:0000:2552:7777:1313]", true}, 782 {"http://user:pass@[::1]:9093/a/b/c/?a=v#abc", true}, 783 {"https://127.0.0.1/a/b/c?a=v&c=11d", true}, 784 {"https://foo_bar.example.com", true}, 785 {"http://foo_bar.example.com", true}, 786 {"http://foo_bar_fizz_buzz.example.com", true}, 787 {"http://_cant_start_with_underescore", false}, 788 {"http://cant_end_with_underescore_", false}, 789 {"foo_bar.example.com", true}, 790 {"foo_bar_fizz_buzz.example.com", true}, 791 {"http://hello_world.example.com", true}, 792 // According to #212 793 {"foo_bar-fizz-buzz:1313", true}, 794 {"foo_bar-fizz-buzz:13:13", false}, 795 {"foo_bar-fizz-buzz://1313", false}, 796 } 797 for _, test := range tests { 798 actual := IsURL(test.param) 799 if actual != test.expected { 800 t.Errorf("Expected IsURL(%q) to be %v, got %v", test.param, test.expected, actual) 801 } 802 } 803} 804 805func TestIsRequestURL(t *testing.T) { 806 t.Parallel() 807 808 var tests = []struct { 809 param string 810 expected bool 811 }{ 812 {"", false}, 813 {"http://foo.bar/#com", true}, 814 {"http://foobar.com", true}, 815 {"https://foobar.com", true}, 816 {"foobar.com", false}, 817 {"http://foobar.coffee/", true}, 818 {"http://foobar.中文网/", true}, 819 {"http://foobar.org/", true}, 820 {"http://foobar.org:8080/", true}, 821 {"ftp://foobar.ru/", true}, 822 {"http://user:pass@www.foobar.com/", true}, 823 {"http://127.0.0.1/", true}, 824 {"http://duckduckgo.com/?q=%2F", true}, 825 {"http://localhost:3000/", true}, 826 {"http://foobar.com/?foo=bar#baz=qux", true}, 827 {"http://foobar.com?foo=bar", true}, 828 {"http://www.xn--froschgrn-x9a.net/", true}, 829 {"", false}, 830 {"xyz://foobar.com", true}, 831 {"invalid.", false}, 832 {".com", false}, 833 {"rtmp://foobar.com", true}, 834 {"http://www.foo_bar.com/", true}, 835 {"http://localhost:3000/", true}, 836 {"http://foobar.com/#baz=qux", true}, 837 {"http://foobar.com/t$-_.+!*\\'(),", true}, 838 {"http://www.foobar.com/~foobar", true}, 839 {"http://www.-foobar.com/", true}, 840 {"http://www.foo---bar.com/", true}, 841 {"mailto:someone@example.com", true}, 842 {"irc://irc.server.org/channel", true}, 843 {"/abs/test/dir", false}, 844 {"./rel/test/dir", false}, 845 } 846 for _, test := range tests { 847 actual := IsRequestURL(test.param) 848 if actual != test.expected { 849 t.Errorf("Expected IsRequestURL(%q) to be %v, got %v", test.param, test.expected, actual) 850 } 851 } 852} 853 854func TestIsRequestURI(t *testing.T) { 855 t.Parallel() 856 857 var tests = []struct { 858 param string 859 expected bool 860 }{ 861 {"", false}, 862 {"http://foo.bar/#com", true}, 863 {"http://foobar.com", true}, 864 {"https://foobar.com", true}, 865 {"foobar.com", false}, 866 {"http://foobar.coffee/", true}, 867 {"http://foobar.中文网/", true}, 868 {"http://foobar.org/", true}, 869 {"http://foobar.org:8080/", true}, 870 {"ftp://foobar.ru/", true}, 871 {"http://user:pass@www.foobar.com/", true}, 872 {"http://127.0.0.1/", true}, 873 {"http://duckduckgo.com/?q=%2F", true}, 874 {"http://localhost:3000/", true}, 875 {"http://foobar.com/?foo=bar#baz=qux", true}, 876 {"http://foobar.com?foo=bar", true}, 877 {"http://www.xn--froschgrn-x9a.net/", true}, 878 {"xyz://foobar.com", true}, 879 {"invalid.", false}, 880 {".com", false}, 881 {"rtmp://foobar.com", true}, 882 {"http://www.foo_bar.com/", true}, 883 {"http://localhost:3000/", true}, 884 {"http://foobar.com/#baz=qux", true}, 885 {"http://foobar.com/t$-_.+!*\\'(),", true}, 886 {"http://www.foobar.com/~foobar", true}, 887 {"http://www.-foobar.com/", true}, 888 {"http://www.foo---bar.com/", true}, 889 {"mailto:someone@example.com", true}, 890 {"irc://irc.server.org/channel", true}, 891 {"/abs/test/dir", true}, 892 {"./rel/test/dir", false}, 893 } 894 for _, test := range tests { 895 actual := IsRequestURI(test.param) 896 if actual != test.expected { 897 t.Errorf("Expected IsRequestURI(%q) to be %v, got %v", test.param, test.expected, actual) 898 } 899 } 900} 901 902func TestIsFloat(t *testing.T) { 903 t.Parallel() 904 905 var tests = []struct { 906 param string 907 expected bool 908 }{ 909 {"", false}, 910 {" ", false}, 911 {"-.123", false}, 912 {"abacaba", false}, 913 {"1f", false}, 914 {"-1f", false}, 915 {"+1f", false}, 916 {"123", true}, 917 {"123.", true}, 918 {"123.123", true}, 919 {"-123.123", true}, 920 {"+123.123", true}, 921 {"0.123", true}, 922 {"-0.123", true}, 923 {"+0.123", true}, 924 {".0", true}, 925 {"01.123", true}, 926 {"-0.22250738585072011e-307", true}, 927 {"+0.22250738585072011e-307", true}, 928 } 929 for _, test := range tests { 930 actual := IsFloat(test.param) 931 if actual != test.expected { 932 t.Errorf("Expected IsFloat(%q) to be %v, got %v", test.param, test.expected, actual) 933 } 934 } 935} 936 937func TestIsHexadecimal(t *testing.T) { 938 t.Parallel() 939 940 var tests = []struct { 941 param string 942 expected bool 943 }{ 944 {"abcdefg", false}, 945 {"", false}, 946 {"..", false}, 947 {"deadBEEF", true}, 948 {"ff0044", true}, 949 } 950 for _, test := range tests { 951 actual := IsHexadecimal(test.param) 952 if actual != test.expected { 953 t.Errorf("Expected IsHexadecimal(%q) to be %v, got %v", test.param, test.expected, actual) 954 } 955 } 956} 957 958func TestIsHexcolor(t *testing.T) { 959 t.Parallel() 960 961 var tests = []struct { 962 param string 963 expected bool 964 }{ 965 {"", false}, 966 {"#ff", false}, 967 {"fff0", false}, 968 {"#ff12FG", false}, 969 {"CCccCC", true}, 970 {"fff", true}, 971 {"#f00", true}, 972 } 973 for _, test := range tests { 974 actual := IsHexcolor(test.param) 975 if actual != test.expected { 976 t.Errorf("Expected IsHexcolor(%q) to be %v, got %v", test.param, test.expected, actual) 977 } 978 } 979} 980 981func TestIsRGBcolor(t *testing.T) { 982 t.Parallel() 983 984 var tests = []struct { 985 param string 986 expected bool 987 }{ 988 {"", false}, 989 {"rgb(0,31,255)", true}, 990 {"rgb(1,349,275)", false}, 991 {"rgb(01,31,255)", false}, 992 {"rgb(0.6,31,255)", false}, 993 {"rgba(0,31,255)", false}, 994 {"rgb(0, 31, 255)", true}, 995 } 996 for _, test := range tests { 997 actual := IsRGBcolor(test.param) 998 if actual != test.expected { 999 t.Errorf("Expected IsRGBcolor(%q) to be %v, got %v", test.param, test.expected, actual) 1000 } 1001 } 1002} 1003 1004func TestIsNull(t *testing.T) { 1005 t.Parallel() 1006 1007 var tests = []struct { 1008 param string 1009 expected bool 1010 }{ 1011 {"abacaba", false}, 1012 {"", true}, 1013 } 1014 for _, test := range tests { 1015 actual := IsNull(test.param) 1016 if actual != test.expected { 1017 t.Errorf("Expected IsNull(%q) to be %v, got %v", test.param, test.expected, actual) 1018 } 1019 } 1020} 1021 1022func TestHasWhitespaceOnly(t *testing.T) { 1023 t.Parallel() 1024 1025 var tests = []struct { 1026 param string 1027 expected bool 1028 }{ 1029 {"abacaba", false}, 1030 {"", false}, 1031 {" ", true}, 1032 {" \r\n ", true}, 1033 {"\014\012\011\013\015", true}, 1034 {"\014\012\011\013 abc \015", false}, 1035 {"\f\n\t\v\r\f", true}, 1036 {"x\n\t\t\t\t", false}, 1037 {"\f\n\t \n\n\n \v\r\f", true}, 1038 } 1039 for _, test := range tests { 1040 actual := HasWhitespaceOnly(test.param) 1041 if actual != test.expected { 1042 t.Errorf("Expected HasWhitespaceOnly(%q) to be %v, got %v", test.param, test.expected, actual) 1043 } 1044 } 1045} 1046 1047func TestHasWhitespace(t *testing.T) { 1048 t.Parallel() 1049 1050 var tests = []struct { 1051 param string 1052 expected bool 1053 }{ 1054 {"abacaba", false}, 1055 {"", false}, 1056 {" ", true}, 1057 {" \r\n ", true}, 1058 {"\014\012\011\013\015", true}, 1059 {"\014\012\011\013 abc \015", true}, 1060 {"\f\n\t\v\r\f", true}, 1061 {"x\n\t\t\t\t", true}, 1062 {"\f\n\t \n\n\n \v\r\f", true}, 1063 } 1064 for _, test := range tests { 1065 actual := HasWhitespace(test.param) 1066 if actual != test.expected { 1067 t.Errorf("Expected HasWhitespace(%q) to be %v, got %v", test.param, test.expected, actual) 1068 } 1069 } 1070} 1071 1072func TestIsDivisibleBy(t *testing.T) { 1073 t.Parallel() 1074 1075 var tests = []struct { 1076 param1 string 1077 param2 string 1078 expected bool 1079 }{ 1080 {"4", "2", true}, 1081 {"100", "10", true}, 1082 {"", "1", true}, 1083 {"123", "foo", false}, 1084 {"123", "0", false}, 1085 } 1086 for _, test := range tests { 1087 actual := IsDivisibleBy(test.param1, test.param2) 1088 if actual != test.expected { 1089 t.Errorf("Expected IsDivisibleBy(%q, %q) to be %v, got %v", test.param1, test.param2, test.expected, actual) 1090 } 1091 } 1092} 1093 1094// This small example illustrate how to work with IsDivisibleBy function. 1095func ExampleIsDivisibleBy() { 1096 println("1024 is divisible by 64: ", IsDivisibleBy("1024", "64")) 1097} 1098 1099func TestIsByteLength(t *testing.T) { 1100 t.Parallel() 1101 1102 var tests = []struct { 1103 param1 string 1104 param2 int 1105 param3 int 1106 expected bool 1107 }{ 1108 {"abacaba", 100, -1, false}, 1109 {"abacaba", 1, 3, false}, 1110 {"abacaba", 1, 7, true}, 1111 {"abacaba", 0, 8, true}, 1112 {"\ufff0", 1, 1, false}, 1113 } 1114 for _, test := range tests { 1115 actual := IsByteLength(test.param1, test.param2, test.param3) 1116 if actual != test.expected { 1117 t.Errorf("Expected IsByteLength(%q, %q, %q) to be %v, got %v", test.param1, test.param2, test.param3, test.expected, actual) 1118 } 1119 } 1120} 1121 1122func TestIsJSON(t *testing.T) { 1123 t.Parallel() 1124 1125 var tests = []struct { 1126 param string 1127 expected bool 1128 }{ 1129 {"", false}, 1130 {"145", true}, 1131 {"asdf", false}, 1132 {"123:f00", false}, 1133 {"{\"Name\":\"Alice\",\"Body\":\"Hello\",\"Time\":1294706395881547000}", true}, 1134 {"{}", true}, 1135 {"{\"Key\":{\"Key\":{\"Key\":123}}}", true}, 1136 {"[]", true}, 1137 {"null", true}, 1138 } 1139 for _, test := range tests { 1140 actual := IsJSON(test.param) 1141 if actual != test.expected { 1142 t.Errorf("Expected IsJSON(%q) to be %v, got %v", test.param, test.expected, actual) 1143 } 1144 } 1145} 1146 1147func TestIsMultibyte(t *testing.T) { 1148 t.Parallel() 1149 1150 var tests = []struct { 1151 param string 1152 expected bool 1153 }{ 1154 {"abc", false}, 1155 {"123", false}, 1156 {"<>@;.-=", false}, 1157 {"ひらがな・カタカナ、.漢字", true}, 1158 {"あいうえお foobar", true}, 1159 {"test@example.com", true}, 1160 {"test@example.com", true}, 1161 {"1234abcDExyz", true}, 1162 {"カタカナ", true}, 1163 {"", true}, 1164 } 1165 for _, test := range tests { 1166 actual := IsMultibyte(test.param) 1167 if actual != test.expected { 1168 t.Errorf("Expected IsMultibyte(%q) to be %v, got %v", test.param, test.expected, actual) 1169 } 1170 } 1171} 1172 1173func TestIsASCII(t *testing.T) { 1174 t.Parallel() 1175 1176 var tests = []struct { 1177 param string 1178 expected bool 1179 }{ 1180 {"", true}, 1181 {"foobar", false}, 1182 {"xyz098", false}, 1183 {"123456", false}, 1184 {"カタカナ", false}, 1185 {"foobar", true}, 1186 {"0987654321", true}, 1187 {"test@example.com", true}, 1188 {"1234abcDEF", true}, 1189 {"", true}, 1190 } 1191 for _, test := range tests { 1192 actual := IsASCII(test.param) 1193 if actual != test.expected { 1194 t.Errorf("Expected IsASCII(%q) to be %v, got %v", test.param, test.expected, actual) 1195 } 1196 } 1197} 1198 1199func TestIsPrintableASCII(t *testing.T) { 1200 t.Parallel() 1201 1202 var tests = []struct { 1203 param string 1204 expected bool 1205 }{ 1206 {"", true}, 1207 {"foobar", false}, 1208 {"xyz098", false}, 1209 {"123456", false}, 1210 {"カタカナ", false}, 1211 {"foobar", true}, 1212 {"0987654321", true}, 1213 {"test@example.com", true}, 1214 {"1234abcDEF", true}, 1215 {"newline\n", false}, 1216 {"\x19test\x7F", false}, 1217 } 1218 for _, test := range tests { 1219 actual := IsPrintableASCII(test.param) 1220 if actual != test.expected { 1221 t.Errorf("Expected IsPrintableASCII(%q) to be %v, got %v", test.param, test.expected, actual) 1222 } 1223 } 1224} 1225 1226func TestIsFullWidth(t *testing.T) { 1227 t.Parallel() 1228 1229 var tests = []struct { 1230 param string 1231 expected bool 1232 }{ 1233 {"", true}, 1234 {"abc", false}, 1235 {"abc123", false}, 1236 {"!\"#$%&()<>/+=-_? ~^|.,@`{}[]", false}, 1237 {"ひらがな・カタカナ、.漢字", true}, 1238 {"3ー0 a@com", true}, 1239 {"Fカタカナ゙ᆲ", true}, 1240 {"Good=Parts", true}, 1241 {"", true}, 1242 } 1243 for _, test := range tests { 1244 actual := IsFullWidth(test.param) 1245 if actual != test.expected { 1246 t.Errorf("Expected IsFullWidth(%q) to be %v, got %v", test.param, test.expected, actual) 1247 } 1248 } 1249} 1250 1251func TestIsHalfWidth(t *testing.T) { 1252 t.Parallel() 1253 1254 var tests = []struct { 1255 param string 1256 expected bool 1257 }{ 1258 {"", true}, 1259 {"あいうえお", false}, 1260 {"0011", false}, 1261 {"!\"#$%&()<>/+=-_? ~^|.,@`{}[]", true}, 1262 {"l-btn_02--active", true}, 1263 {"abc123い", true}, 1264 {"カタカナ゙ᆲ←", true}, 1265 {"", true}, 1266 } 1267 for _, test := range tests { 1268 actual := IsHalfWidth(test.param) 1269 if actual != test.expected { 1270 t.Errorf("Expected IsHalfWidth(%q) to be %v, got %v", test.param, test.expected, actual) 1271 } 1272 } 1273} 1274 1275func TestIsVariableWidth(t *testing.T) { 1276 t.Parallel() 1277 1278 var tests = []struct { 1279 param string 1280 expected bool 1281 }{ 1282 {"", true}, 1283 {"ひらがなカタカナ漢字ABCDE", true}, 1284 {"3ー0123", true}, 1285 {"Fカタカナ゙ᆲ", true}, 1286 {"", true}, 1287 {"Good=Parts", true}, 1288 {"abc", false}, 1289 {"abc123", false}, 1290 {"!\"#$%&()<>/+=-_? ~^|.,@`{}[]", false}, 1291 {"ひらがな・カタカナ、.漢字", false}, 1292 {"123456", false}, 1293 {"カタカナ゙ᆲ", false}, 1294 } 1295 for _, test := range tests { 1296 actual := IsVariableWidth(test.param) 1297 if actual != test.expected { 1298 t.Errorf("Expected IsVariableWidth(%q) to be %v, got %v", test.param, test.expected, actual) 1299 } 1300 } 1301} 1302 1303func TestIsUUID(t *testing.T) { 1304 t.Parallel() 1305 1306 // Tests without version 1307 var tests = []struct { 1308 param string 1309 expected bool 1310 }{ 1311 {"", false}, 1312 {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, 1313 {"a987fbc9-4bed-3078-cf07-9141ba07c9f3xxx", false}, 1314 {"a987fbc94bed3078cf079141ba07c9f3", false}, 1315 {"934859", false}, 1316 {"987fbc9-4bed-3078-cf07a-9141ba07c9f3", false}, 1317 {"aaaaaaaa-1111-1111-aaag-111111111111", false}, 1318 {"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true}, 1319 } 1320 for _, test := range tests { 1321 actual := IsUUID(test.param) 1322 if actual != test.expected { 1323 t.Errorf("Expected IsUUID(%q) to be %v, got %v", test.param, test.expected, actual) 1324 } 1325 } 1326 1327 // UUID ver. 3 1328 tests = []struct { 1329 param string 1330 expected bool 1331 }{ 1332 {"", false}, 1333 {"412452646", false}, 1334 {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, 1335 {"a987fbc9-4bed-4078-8f07-9141ba07c9f3", false}, 1336 {"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true}, 1337 } 1338 for _, test := range tests { 1339 actual := IsUUIDv3(test.param) 1340 if actual != test.expected { 1341 t.Errorf("Expected IsUUIDv3(%q) to be %v, got %v", test.param, test.expected, actual) 1342 } 1343 } 1344 1345 // UUID ver. 4 1346 tests = []struct { 1347 param string 1348 expected bool 1349 }{ 1350 {"", false}, 1351 {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, 1352 {"a987fbc9-4bed-5078-af07-9141ba07c9f3", false}, 1353 {"934859", false}, 1354 {"57b73598-8764-4ad0-a76a-679bb6640eb1", true}, 1355 {"625e63f3-58f5-40b7-83a1-a72ad31acffb", true}, 1356 } 1357 for _, test := range tests { 1358 actual := IsUUIDv4(test.param) 1359 if actual != test.expected { 1360 t.Errorf("Expected IsUUIDv4(%q) to be %v, got %v", test.param, test.expected, actual) 1361 } 1362 } 1363 1364 // UUID ver. 5 1365 tests = []struct { 1366 param string 1367 expected bool 1368 }{ 1369 1370 {"", false}, 1371 {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, 1372 {"9c858901-8a57-4791-81fe-4c455b099bc9", false}, 1373 {"a987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, 1374 {"987fbc97-4bed-5078-af07-9141ba07c9f3", true}, 1375 {"987fbc97-4bed-5078-9f07-9141ba07c9f3", true}, 1376 } 1377 for _, test := range tests { 1378 actual := IsUUIDv5(test.param) 1379 if actual != test.expected { 1380 t.Errorf("Expected IsUUIDv5(%q) to be %v, got %v", test.param, test.expected, actual) 1381 } 1382 } 1383} 1384 1385func TestIsCreditCard(t *testing.T) { 1386 t.Parallel() 1387 1388 var tests = []struct { 1389 param string 1390 expected bool 1391 }{ 1392 {"", false}, 1393 {"foo", false}, 1394 {"5398228707871528", false}, 1395 {"375556917985515", true}, 1396 {"36050234196908", true}, 1397 {"4716461583322103", true}, 1398 {"4716-2210-5188-5662", true}, 1399 {"4929 7226 5379 7141", true}, 1400 {"5398228707871527", true}, 1401 } 1402 for _, test := range tests { 1403 actual := IsCreditCard(test.param) 1404 if actual != test.expected { 1405 t.Errorf("Expected IsCreditCard(%q) to be %v, got %v", test.param, test.expected, actual) 1406 } 1407 } 1408} 1409 1410func TestIsISBN(t *testing.T) { 1411 t.Parallel() 1412 1413 // Without version 1414 var tests = []struct { 1415 param string 1416 expected bool 1417 }{ 1418 {"", false}, 1419 {"foo", false}, 1420 {"3836221195", true}, 1421 {"1-61729-085-8", true}, 1422 {"3 423 21412 0", true}, 1423 {"3 401 01319 X", true}, 1424 {"9784873113685", true}, 1425 {"978-4-87311-368-5", true}, 1426 {"978 3401013190", true}, 1427 {"978-3-8362-2119-1", true}, 1428 } 1429 for _, test := range tests { 1430 actual := IsISBN(test.param, -1) 1431 if actual != test.expected { 1432 t.Errorf("Expected IsISBN(%q, -1) to be %v, got %v", test.param, test.expected, actual) 1433 } 1434 } 1435 1436 // ISBN 10 1437 tests = []struct { 1438 param string 1439 expected bool 1440 }{ 1441 {"", false}, 1442 {"foo", false}, 1443 {"3423214121", false}, 1444 {"978-3836221191", false}, 1445 {"3-423-21412-1", false}, 1446 {"3 423 21412 1", false}, 1447 {"3836221195", true}, 1448 {"1-61729-085-8", true}, 1449 {"3 423 21412 0", true}, 1450 {"3 401 01319 X", true}, 1451 } 1452 for _, test := range tests { 1453 actual := IsISBN10(test.param) 1454 if actual != test.expected { 1455 t.Errorf("Expected IsISBN10(%q) to be %v, got %v", test.param, test.expected, actual) 1456 } 1457 } 1458 1459 // ISBN 13 1460 tests = []struct { 1461 param string 1462 expected bool 1463 }{ 1464 {"", false}, 1465 {"foo", false}, 1466 {"3-8362-2119-5", false}, 1467 {"01234567890ab", false}, 1468 {"978 3 8362 2119 0", false}, 1469 {"9784873113685", true}, 1470 {"978-4-87311-368-5", true}, 1471 {"978 3401013190", true}, 1472 {"978-3-8362-2119-1", true}, 1473 } 1474 for _, test := range tests { 1475 actual := IsISBN13(test.param) 1476 if actual != test.expected { 1477 t.Errorf("Expected IsISBN13(%q) to be %v, got %v", test.param, test.expected, actual) 1478 } 1479 } 1480} 1481 1482func TestIsDataURI(t *testing.T) { 1483 t.Parallel() 1484 1485 var tests = []struct { 1486 param string 1487 expected bool 1488 }{ 1489 {"data:image/png;base64,TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4=", true}, 1490 {"data:text/plain;base64,Vml2YW11cyBmZXJtZW50dW0gc2VtcGVyIHBvcnRhLg==", true}, 1491 {"image/gif;base64,U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", false}, 1492 {"data:image/gif;base64,MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuMPNS1Ufof9EW/M98FNw" + 1493 "UAKrwflsqVxaxQjBQnHQmiI7Vac40t8x7pIb8gLGV6wL7sBTJiPovJ0V7y7oc0Ye" + 1494 "rhKh0Rm4skP2z/jHwwZICgGzBvA0rH8xlhUiTvcwDCJ0kc+fh35hNt8srZQM4619" + 1495 "FTgB66Xmp4EtVyhpQV+t02g6NzK72oZI0vnAvqhpkxLeLiMCyrI416wHm5Tkukhx" + 1496 "QmcL2a6hNOyu0ixX/x2kSFXApEnVrJ+/IxGyfyw8kf4N2IZpW5nEP847lpfj0SZZ" + 1497 "Fwrd1mnfnDbYohX2zRptLy2ZUn06Qo9pkG5ntvFEPo9bfZeULtjYzIl6K8gJ2uGZ" + "HQIDAQAB", true}, 1498 {"data:image/png;base64,12345", false}, 1499 {"", false}, 1500 {"data:text,:;base85,U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", false}, 1501 } 1502 for _, test := range tests { 1503 actual := IsDataURI(test.param) 1504 if actual != test.expected { 1505 t.Errorf("Expected IsDataURI(%q) to be %v, got %v", test.param, test.expected, actual) 1506 } 1507 } 1508} 1509 1510func TestIsBase64(t *testing.T) { 1511 t.Parallel() 1512 1513 var tests = []struct { 1514 param string 1515 expected bool 1516 }{ 1517 {"TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4=", true}, 1518 {"Vml2YW11cyBmZXJtZW50dW0gc2VtcGVyIHBvcnRhLg==", true}, 1519 {"U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", true}, 1520 {"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuMPNS1Ufof9EW/M98FNw" + 1521 "UAKrwflsqVxaxQjBQnHQmiI7Vac40t8x7pIb8gLGV6wL7sBTJiPovJ0V7y7oc0Ye" + 1522 "rhKh0Rm4skP2z/jHwwZICgGzBvA0rH8xlhUiTvcwDCJ0kc+fh35hNt8srZQM4619" + 1523 "FTgB66Xmp4EtVyhpQV+t02g6NzK72oZI0vnAvqhpkxLeLiMCyrI416wHm5Tkukhx" + 1524 "QmcL2a6hNOyu0ixX/x2kSFXApEnVrJ+/IxGyfyw8kf4N2IZpW5nEP847lpfj0SZZ" + 1525 "Fwrd1mnfnDbYohX2zRptLy2ZUn06Qo9pkG5ntvFEPo9bfZeULtjYzIl6K8gJ2uGZ" + "HQIDAQAB", true}, 1526 {"12345", false}, 1527 {"", false}, 1528 {"Vml2YW11cyBmZXJtZtesting123", false}, 1529 } 1530 for _, test := range tests { 1531 actual := IsBase64(test.param) 1532 if actual != test.expected { 1533 t.Errorf("Expected IsBase64(%q) to be %v, got %v", test.param, test.expected, actual) 1534 } 1535 } 1536} 1537 1538func TestIsISO3166Alpha2(t *testing.T) { 1539 t.Parallel() 1540 1541 var tests = []struct { 1542 param string 1543 expected bool 1544 }{ 1545 {"", false}, 1546 {"ABCD", false}, 1547 {"A", false}, 1548 {"AC", false}, 1549 {"AP", false}, 1550 {"GER", false}, 1551 {"NU", true}, 1552 {"DE", true}, 1553 {"JP", true}, 1554 {"JPN", false}, 1555 {"ZWE", false}, 1556 {"GER", false}, 1557 {"DEU", false}, 1558 } 1559 for _, test := range tests { 1560 actual := IsISO3166Alpha2(test.param) 1561 if actual != test.expected { 1562 t.Errorf("Expected IsISO3166Alpha2(%q) to be %v, got %v", test.param, test.expected, actual) 1563 } 1564 } 1565} 1566 1567func TestIsISO3166Alpha3(t *testing.T) { 1568 t.Parallel() 1569 1570 var tests = []struct { 1571 param string 1572 expected bool 1573 }{ 1574 {"", false}, 1575 {"ABCD", false}, 1576 {"A", false}, 1577 {"AC", false}, 1578 {"AP", false}, 1579 {"NU", false}, 1580 {"DE", false}, 1581 {"JP", false}, 1582 {"ZWE", true}, 1583 {"JPN", true}, 1584 {"GER", false}, 1585 {"DEU", true}, 1586 } 1587 for _, test := range tests { 1588 actual := IsISO3166Alpha3(test.param) 1589 if actual != test.expected { 1590 t.Errorf("Expected IsISO3166Alpha3(%q) to be %v, got %v", test.param, test.expected, actual) 1591 } 1592 } 1593} 1594 1595func TestIsISO693Alpha2(t *testing.T) { 1596 t.Parallel() 1597 1598 var tests = []struct { 1599 param string 1600 expected bool 1601 }{ 1602 {"", false}, 1603 {"abcd", false}, 1604 {"a", false}, 1605 {"ac", false}, 1606 {"ap", false}, 1607 {"de", true}, 1608 {"DE", false}, 1609 {"mk", true}, 1610 {"mac", false}, 1611 {"sw", true}, 1612 {"SW", false}, 1613 {"ger", false}, 1614 {"deu", false}, 1615 } 1616 for _, test := range tests { 1617 actual := IsISO693Alpha2(test.param) 1618 if actual != test.expected { 1619 t.Errorf("Expected IsISO693Alpha2(%q) to be %v, got %v", test.param, test.expected, actual) 1620 } 1621 } 1622} 1623 1624func TestIsISO693Alpha3b(t *testing.T) { 1625 t.Parallel() 1626 1627 var tests = []struct { 1628 param string 1629 expected bool 1630 }{ 1631 {"", false}, 1632 {"abcd", false}, 1633 {"a", false}, 1634 {"ac", false}, 1635 {"ap", false}, 1636 {"de", false}, 1637 {"DE", false}, 1638 {"mkd", false}, 1639 {"mac", true}, 1640 {"sw", false}, 1641 {"SW", false}, 1642 {"ger", true}, 1643 {"deu", false}, 1644 } 1645 for _, test := range tests { 1646 actual := IsISO693Alpha3b(test.param) 1647 if actual != test.expected { 1648 t.Errorf("Expected IsISO693Alpha3b(%q) to be %v, got %v", test.param, test.expected, actual) 1649 } 1650 } 1651} 1652 1653func TestIsIP(t *testing.T) { 1654 t.Parallel() 1655 1656 // Without version 1657 var tests = []struct { 1658 param string 1659 expected bool 1660 }{ 1661 {"", false}, 1662 {"127.0.0.1", true}, 1663 {"0.0.0.0", true}, 1664 {"255.255.255.255", true}, 1665 {"1.2.3.4", true}, 1666 {"::1", true}, 1667 {"2001:db8:0000:1:1:1:1:1", true}, 1668 {"300.0.0.0", false}, 1669 } 1670 for _, test := range tests { 1671 actual := IsIP(test.param) 1672 if actual != test.expected { 1673 t.Errorf("Expected IsIP(%q) to be %v, got %v", test.param, test.expected, actual) 1674 } 1675 } 1676 1677 // IPv4 1678 tests = []struct { 1679 param string 1680 expected bool 1681 }{ 1682 {"", false}, 1683 {"127.0.0.1", true}, 1684 {"0.0.0.0", true}, 1685 {"255.255.255.255", true}, 1686 {"1.2.3.4", true}, 1687 {"::1", false}, 1688 {"2001:db8:0000:1:1:1:1:1", false}, 1689 {"300.0.0.0", false}, 1690 } 1691 for _, test := range tests { 1692 actual := IsIPv4(test.param) 1693 if actual != test.expected { 1694 t.Errorf("Expected IsIPv4(%q) to be %v, got %v", test.param, test.expected, actual) 1695 } 1696 } 1697 1698 // IPv6 1699 tests = []struct { 1700 param string 1701 expected bool 1702 }{ 1703 {"", false}, 1704 {"127.0.0.1", false}, 1705 {"0.0.0.0", false}, 1706 {"255.255.255.255", false}, 1707 {"1.2.3.4", false}, 1708 {"::1", true}, 1709 {"2001:db8:0000:1:1:1:1:1", true}, 1710 {"300.0.0.0", false}, 1711 } 1712 for _, test := range tests { 1713 actual := IsIPv6(test.param) 1714 if actual != test.expected { 1715 t.Errorf("Expected IsIPv6(%q) to be %v, got %v", test.param, test.expected, actual) 1716 } 1717 } 1718} 1719 1720func TestIsPort(t *testing.T) { 1721 t.Parallel() 1722 1723 var tests = []struct { 1724 param string 1725 expected bool 1726 }{ 1727 {"1", true}, 1728 {"65535", true}, 1729 {"0", false}, 1730 {"65536", false}, 1731 {"65538", false}, 1732 } 1733 1734 for _, test := range tests { 1735 actual := IsPort(test.param) 1736 if actual != test.expected { 1737 t.Errorf("Expected IsPort(%q) to be %v, got %v", test.param, test.expected, actual) 1738 } 1739 } 1740} 1741 1742func TestIsDNSName(t *testing.T) { 1743 t.Parallel() 1744 1745 var tests = []struct { 1746 param string 1747 expected bool 1748 }{ 1749 {"localhost", true}, 1750 {"a.bc", true}, 1751 {"a.b.", true}, 1752 {"a.b..", false}, 1753 {"localhost.local", true}, 1754 {"localhost.localdomain.intern", true}, 1755 {"l.local.intern", true}, 1756 {"ru.link.n.svpncloud.com", true}, 1757 {"-localhost", false}, 1758 {"localhost.-localdomain", false}, 1759 {"localhost.localdomain.-int", false}, 1760 {"_localhost", true}, 1761 {"localhost._localdomain", true}, 1762 {"localhost.localdomain._int", true}, 1763 {"lÖcalhost", false}, 1764 {"localhost.lÖcaldomain", false}, 1765 {"localhost.localdomain.üntern", false}, 1766 {"__", true}, 1767 {"localhost/", false}, 1768 {"127.0.0.1", false}, 1769 {"[::1]", false}, 1770 {"50.50.50.50", false}, 1771 {"localhost.localdomain.intern:65535", false}, 1772 {"漢字汉字", false}, 1773 {"www.jubfvq1v3p38i51622y0dvmdk1mymowjyeu26gbtw9andgynj1gg8z3msb1kl5z6906k846pj3sulm4kiyk82ln5teqj9nsht59opr0cs5ssltx78lfyvml19lfq1wp4usbl0o36cmiykch1vywbttcus1p9yu0669h8fj4ll7a6bmop505908s1m83q2ec2qr9nbvql2589adma3xsq2o38os2z3dmfh2tth4is4ixyfasasasefqwe4t2ub2fz1rme.de", false}, 1774 } 1775 1776 for _, test := range tests { 1777 actual := IsDNSName(test.param) 1778 if actual != test.expected { 1779 t.Errorf("Expected IsDNS(%q) to be %v, got %v", test.param, test.expected, actual) 1780 } 1781 } 1782} 1783 1784func TestIsHost(t *testing.T) { 1785 t.Parallel() 1786 var tests = []struct { 1787 param string 1788 expected bool 1789 }{ 1790 {"localhost", true}, 1791 {"localhost.localdomain", true}, 1792 {"2001:db8:0000:1:1:1:1:1", true}, 1793 {"::1", true}, 1794 {"play.golang.org", true}, 1795 {"localhost.localdomain.intern:65535", false}, 1796 {"-[::1]", false}, 1797 {"-localhost", false}, 1798 {".localhost", false}, 1799 } 1800 for _, test := range tests { 1801 actual := IsHost(test.param) 1802 if actual != test.expected { 1803 t.Errorf("Expected IsHost(%q) to be %v, got %v", test.param, test.expected, actual) 1804 } 1805 } 1806 1807} 1808 1809func TestIsDialString(t *testing.T) { 1810 t.Parallel() 1811 1812 var tests = []struct { 1813 param string 1814 expected bool 1815 }{ 1816 {"localhost.local:1", true}, 1817 {"localhost.localdomain:9090", true}, 1818 {"localhost.localdomain.intern:65535", true}, 1819 {"127.0.0.1:30000", true}, 1820 {"[::1]:80", true}, 1821 {"[1200::AB00:1234::2552:7777:1313]:22", false}, 1822 {"-localhost:1", false}, 1823 {"localhost.-localdomain:9090", false}, 1824 {"localhost.localdomain.-int:65535", false}, 1825 {"localhost.loc:100000", false}, 1826 {"漢字汉字:2", false}, 1827 {"www.jubfvq1v3p38i51622y0dvmdk1mymowjyeu26gbtw9andgynj1gg8z3msb1kl5z6906k846pj3sulm4kiyk82ln5teqj9nsht59opr0cs5ssltx78lfyvml19lfq1wp4usbl0o36cmiykch1vywbttcus1p9yu0669h8fj4ll7a6bmop505908s1m83q2ec2qr9nbvql2589adma3xsq2o38os2z3dmfh2tth4is4ixyfasasasefqwe4t2ub2fz1rme.de:20000", false}, 1828 } 1829 1830 for _, test := range tests { 1831 actual := IsDialString(test.param) 1832 if actual != test.expected { 1833 t.Errorf("Expected IsDialString(%q) to be %v, got %v", test.param, test.expected, actual) 1834 } 1835 } 1836} 1837 1838func TestIsMAC(t *testing.T) { 1839 t.Parallel() 1840 1841 var tests = []struct { 1842 param string 1843 expected bool 1844 }{ 1845 {"3D:F2:C9:A6:B3:4F", true}, 1846 {"3D-F2-C9-A6-B3:4F", false}, 1847 {"123", false}, 1848 {"", false}, 1849 {"abacaba", false}, 1850 } 1851 for _, test := range tests { 1852 actual := IsMAC(test.param) 1853 if actual != test.expected { 1854 t.Errorf("Expected IsMAC(%q) to be %v, got %v", test.param, test.expected, actual) 1855 } 1856 } 1857} 1858 1859func TestFilePath(t *testing.T) { 1860 t.Parallel() 1861 1862 var tests = []struct { 1863 param string 1864 expected bool 1865 osType int 1866 }{ 1867 {"c:\\" + strings.Repeat("a", 32767), true, Win}, //See http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath 1868 {"c:\\" + strings.Repeat("a", 32768), false, Win}, 1869 {"c:\\path\\file (x86)\bar", true, Win}, 1870 {"c:\\path\\file", true, Win}, 1871 {"c:\\path\\file:exe", false, Unknown}, 1872 {"C:\\", true, Win}, 1873 {"c:\\path\\file\\", true, Win}, 1874 {"c:/path/file/", false, Unknown}, 1875 {"/path/file/", true, Unix}, 1876 {"/path/file:SAMPLE/", true, Unix}, 1877 {"/path/file:/.txt", true, Unix}, 1878 {"/path", true, Unix}, 1879 {"/path/__bc/file.txt", true, Unix}, 1880 {"/path/a--ac/file.txt", true, Unix}, 1881 {"/_path/file.txt", true, Unix}, 1882 {"/path/__bc/file.txt", true, Unix}, 1883 {"/path/a--ac/file.txt", true, Unix}, 1884 {"/__path/--file.txt", true, Unix}, 1885 {"/path/a bc", true, Unix}, 1886 } 1887 for _, test := range tests { 1888 actual, osType := IsFilePath(test.param) 1889 if actual != test.expected || osType != test.osType { 1890 t.Errorf("Expected IsFilePath(%q) to be %v, got %v", test.param, test.expected, actual) 1891 } 1892 } 1893} 1894 1895func TestIsLatitude(t *testing.T) { 1896 t.Parallel() 1897 1898 var tests = []struct { 1899 param string 1900 expected bool 1901 }{ 1902 {"", false}, 1903 {"-90.000", true}, 1904 {"+90", true}, 1905 {"47.1231231", true}, 1906 {"+99.9", false}, 1907 {"108", false}, 1908 } 1909 for _, test := range tests { 1910 actual := IsLatitude(test.param) 1911 if actual != test.expected { 1912 t.Errorf("Expected IsLatitude(%q) to be %v, got %v", test.param, test.expected, actual) 1913 } 1914 } 1915} 1916 1917func TestIsLongitude(t *testing.T) { 1918 t.Parallel() 1919 1920 var tests = []struct { 1921 param string 1922 expected bool 1923 }{ 1924 {"", false}, 1925 {"-180.000", true}, 1926 {"180.1", false}, 1927 {"+73.234", true}, 1928 {"+382.3811", false}, 1929 {"23.11111111", true}, 1930 } 1931 for _, test := range tests { 1932 actual := IsLongitude(test.param) 1933 if actual != test.expected { 1934 t.Errorf("Expected IsLongitude(%q) to be %v, got %v", test.param, test.expected, actual) 1935 } 1936 } 1937} 1938 1939func TestIsSSN(t *testing.T) { 1940 t.Parallel() 1941 1942 var tests = []struct { 1943 param string 1944 expected bool 1945 }{ 1946 {"", false}, 1947 {"00-90-8787", false}, 1948 {"66690-76", false}, 1949 {"191 60 2869", true}, 1950 {"191-60-2869", true}, 1951 } 1952 for _, test := range tests { 1953 actual := IsSSN(test.param) 1954 if actual != test.expected { 1955 t.Errorf("Expected IsSSN(%q) to be %v, got %v", test.param, test.expected, actual) 1956 } 1957 } 1958} 1959 1960func TestIsMongoID(t *testing.T) { 1961 t.Parallel() 1962 1963 var tests = []struct { 1964 param string 1965 expected bool 1966 }{ 1967 {"507f1f77bcf86cd799439011", true}, 1968 {"507f1f77bcf86cd7994390", false}, 1969 {"507f1f77bcf86cd79943901z", false}, 1970 {"507f1f77bcf86cd799439011 ", false}, 1971 {"", false}, 1972 } 1973 for _, test := range tests { 1974 actual := IsMongoID(test.param) 1975 if actual != test.expected { 1976 t.Errorf("Expected IsMongoID(%q) to be %v, got %v", test.param, test.expected, actual) 1977 } 1978 } 1979} 1980 1981func TestIsSemver(t *testing.T) { 1982 t.Parallel() 1983 var tests = []struct { 1984 param string 1985 expected bool 1986 }{ 1987 {"v1.0.0", true}, 1988 {"1.0.0", true}, 1989 {"1.1.01", false}, 1990 {"1.01.0", false}, 1991 {"01.1.0", false}, 1992 {"v1.1.01", false}, 1993 {"v1.01.0", false}, 1994 {"v01.1.0", false}, 1995 {"1.0.0-alpha", true}, 1996 {"1.0.0-alpha.1", true}, 1997 {"1.0.0-0.3.7", true}, 1998 {"1.0.0-0.03.7", false}, 1999 {"1.0.0-00.3.7", false}, 2000 {"1.0.0-x.7.z.92", true}, 2001 {"1.0.0-alpha+001", true}, 2002 {"1.0.0+20130313144700", true}, 2003 {"1.0.0-beta+exp.sha.5114f85", true}, 2004 {"1.0.0-beta+exp.sha.05114f85", true}, 2005 {"1.0.0-+beta", false}, 2006 {"1.0.0-b+-9+eta", false}, 2007 {"v+1.8.0-b+-9+eta", false}, 2008 } 2009 for _, test := range tests { 2010 actual := IsSemver(test.param) 2011 if actual != test.expected { 2012 t.Errorf("Expected IsSemver(%q) to be %v, got %v", test.param, test.expected, actual) 2013 } 2014 } 2015} 2016 2017func TestIsTime(t *testing.T) { 2018 t.Parallel() 2019 var tests = []struct { 2020 param string 2021 format string 2022 expected bool 2023 }{ 2024 {"2016-12-31 11:00", time.RFC3339, false}, 2025 {"2016-12-31 11:00:00", time.RFC3339, false}, 2026 {"2016-12-31T11:00", time.RFC3339, false}, 2027 {"2016-12-31T11:00:00", time.RFC3339, false}, 2028 {"2016-12-31T11:00:00Z", time.RFC3339, true}, 2029 {"2016-12-31T11:00:00+01:00", time.RFC3339, true}, 2030 {"2016-12-31T11:00:00-01:00", time.RFC3339, true}, 2031 {"2016-12-31T11:00:00.05Z", time.RFC3339, true}, 2032 {"2016-12-31T11:00:00.05-01:00", time.RFC3339, true}, 2033 {"2016-12-31T11:00:00.05+01:00", time.RFC3339, true}, 2034 {"2016-12-31T11:00:00", RF3339WithoutZone, true}, 2035 {"2016-12-31T11:00:00Z", RF3339WithoutZone, false}, 2036 {"2016-12-31T11:00:00+01:00", RF3339WithoutZone, false}, 2037 {"2016-12-31T11:00:00-01:00", RF3339WithoutZone, false}, 2038 {"2016-12-31T11:00:00.05Z", RF3339WithoutZone, false}, 2039 {"2016-12-31T11:00:00.05-01:00", RF3339WithoutZone, false}, 2040 {"2016-12-31T11:00:00.05+01:00", RF3339WithoutZone, false}, 2041 } 2042 for _, test := range tests { 2043 actual := IsTime(test.param, test.format) 2044 if actual != test.expected { 2045 t.Errorf("Expected IsTime(%q, time.RFC3339) to be %v, got %v", test.param, test.expected, actual) 2046 } 2047 } 2048} 2049 2050func TestIsRFC3339(t *testing.T) { 2051 t.Parallel() 2052 var tests = []struct { 2053 param string 2054 expected bool 2055 }{ 2056 {"2016-12-31 11:00", false}, 2057 {"2016-12-31 11:00:00", false}, 2058 {"2016-12-31T11:00", false}, 2059 {"2016-12-31T11:00:00", false}, 2060 {"2016-12-31T11:00:00Z", true}, 2061 {"2016-12-31T11:00:00+01:00", true}, 2062 {"2016-12-31T11:00:00-01:00", true}, 2063 {"2016-12-31T11:00:00.05Z", true}, 2064 {"2016-12-31T11:00:00.05-01:00", true}, 2065 {"2016-12-31T11:00:00.05+01:00", true}, 2066 } 2067 for _, test := range tests { 2068 actual := IsRFC3339(test.param) 2069 if actual != test.expected { 2070 t.Errorf("Expected IsRFC3339(%q) to be %v, got %v", test.param, test.expected, actual) 2071 } 2072 } 2073} 2074 2075func TestIsISO4217(t *testing.T) { 2076 t.Parallel() 2077 2078 var tests = []struct { 2079 param string 2080 expected bool 2081 }{ 2082 {"", false}, 2083 {"ABCD", false}, 2084 {"A", false}, 2085 {"ZZZ", false}, 2086 {"usd", false}, 2087 {"USD", true}, 2088 } 2089 for _, test := range tests { 2090 actual := IsISO4217(test.param) 2091 if actual != test.expected { 2092 t.Errorf("Expected IsISO4217(%q) to be %v, got %v", test.param, test.expected, actual) 2093 } 2094 } 2095} 2096 2097func TestByteLength(t *testing.T) { 2098 t.Parallel() 2099 2100 var tests = []struct { 2101 value string 2102 min string 2103 max string 2104 expected bool 2105 }{ 2106 {"123456", "0", "100", true}, 2107 {"1239999", "0", "0", false}, 2108 {"1239asdfasf99", "100", "200", false}, 2109 {"1239999asdff29", "10", "30", true}, 2110 {"你", "0", "1", false}, 2111 } 2112 for _, test := range tests { 2113 actual := ByteLength(test.value, test.min, test.max) 2114 if actual != test.expected { 2115 t.Errorf("Expected ByteLength(%s, %s, %s) to be %v, got %v", test.value, test.min, test.max, test.expected, actual) 2116 } 2117 } 2118} 2119 2120func TestRuneLength(t *testing.T) { 2121 t.Parallel() 2122 2123 var tests = []struct { 2124 value string 2125 min string 2126 max string 2127 expected bool 2128 }{ 2129 {"123456", "0", "100", true}, 2130 {"1239999", "0", "0", false}, 2131 {"1239asdfasf99", "100", "200", false}, 2132 {"1239999asdff29", "10", "30", true}, 2133 {"你", "0", "1", true}, 2134 } 2135 for _, test := range tests { 2136 actual := RuneLength(test.value, test.min, test.max) 2137 if actual != test.expected { 2138 t.Errorf("Expected RuneLength(%s, %s, %s) to be %v, got %v", test.value, test.min, test.max, test.expected, actual) 2139 } 2140 } 2141} 2142 2143func TestStringLength(t *testing.T) { 2144 t.Parallel() 2145 2146 var tests = []struct { 2147 value string 2148 min string 2149 max string 2150 expected bool 2151 }{ 2152 {"123456", "0", "100", true}, 2153 {"1239999", "0", "0", false}, 2154 {"1239asdfasf99", "100", "200", false}, 2155 {"1239999asdff29", "10", "30", true}, 2156 {"あいうえお", "0", "5", true}, 2157 {"あいうえおか", "0", "5", false}, 2158 {"あいうえお", "0", "0", false}, 2159 {"あいうえ", "5", "10", false}, 2160 } 2161 for _, test := range tests { 2162 actual := StringLength(test.value, test.min, test.max) 2163 if actual != test.expected { 2164 t.Errorf("Expected StringLength(%s, %s, %s) to be %v, got %v", test.value, test.min, test.max, test.expected, actual) 2165 } 2166 } 2167} 2168 2169func TestIsIn(t *testing.T) { 2170 t.Parallel() 2171 2172 var tests = []struct { 2173 value string 2174 params []string 2175 expected bool 2176 }{ 2177 {"PRESENT", []string{"PRESENT"}, true}, 2178 {"PRESENT", []string{"PRESENT", "PRÉSENTE", "NOTABSENT"}, true}, 2179 {"PRÉSENTE", []string{"PRESENT", "PRÉSENTE", "NOTABSENT"}, true}, 2180 {"PRESENT", []string{}, false}, 2181 {"PRESENT", nil, false}, 2182 {"ABSENT", []string{"PRESENT", "PRÉSENTE", "NOTABSENT"}, false}, 2183 {"", []string{"PRESENT", "PRÉSENTE", "NOTABSENT"}, false}, 2184 } 2185 for _, test := range tests { 2186 actual := IsIn(test.value, test.params...) 2187 if actual != test.expected { 2188 t.Errorf("Expected IsIn(%s, %v) to be %v, got %v", test.value, test.params, test.expected, actual) 2189 } 2190 } 2191} 2192 2193type Address struct { 2194 Street string `valid:"-"` 2195 Zip string `json:"zip" valid:"numeric,required"` 2196} 2197 2198type User struct { 2199 Name string `valid:"required"` 2200 Email string `valid:"required,email"` 2201 Password string `valid:"required"` 2202 Age int `valid:"required,numeric,@#\u0000"` 2203 Home *Address 2204 Work []Address 2205} 2206 2207type UserValid struct { 2208 Name string `valid:"required"` 2209 Email string `valid:"required,email"` 2210 Password string `valid:"required"` 2211 Age int `valid:"required"` 2212 Home *Address 2213 Work []Address `valid:"required"` 2214} 2215 2216type PrivateStruct struct { 2217 privateField string `valid:"required,alpha,d_k"` 2218 NonZero int 2219 ListInt []int 2220 ListString []string `valid:"alpha"` 2221 Work [2]Address 2222 Home Address 2223 Map map[string]Address 2224} 2225 2226type NegationStruct struct { 2227 NotInt string `valid:"!int"` 2228 Int string `valid:"int"` 2229} 2230 2231type LengthStruct struct { 2232 Length string `valid:"length(10|20)"` 2233} 2234 2235type StringLengthStruct struct { 2236 Length string `valid:"stringlength(10|20)"` 2237} 2238 2239type StringMatchesStruct struct { 2240 StringMatches string `valid:"matches(^[0-9]{3}$)"` 2241} 2242 2243// TODO: this testcase should be fixed 2244// type StringMatchesComplexStruct struct { 2245// StringMatches string `valid:"matches(^\\$\\([\"']\\w+[\"']\\)$)"` 2246// } 2247 2248type IsInStruct struct { 2249 IsIn string `valid:"in(PRESENT|PRÉSENTE|NOTABSENT)"` 2250} 2251 2252type Post struct { 2253 Title string `valid:"alpha,required"` 2254 Message string `valid:"ascii"` 2255 AuthorIP string `valid:"ipv4"` 2256} 2257 2258type MissingValidationDeclarationStruct struct { 2259 Name string `` 2260 Email string `valid:"required,email"` 2261} 2262 2263type FieldRequiredByDefault struct { 2264 Email string `valid:"email"` 2265} 2266 2267type MultipleFieldsRequiredByDefault struct { 2268 Url string `valid:"url"` 2269 Email string `valid:"email"` 2270} 2271 2272type FieldsRequiredByDefaultButExemptStruct struct { 2273 Name string `valid:"-"` 2274 Email string `valid:"email"` 2275} 2276 2277type FieldsRequiredByDefaultButExemptOrOptionalStruct struct { 2278 Name string `valid:"-"` 2279 Email string `valid:"optional,email"` 2280} 2281 2282type MessageWithSeveralFieldsStruct struct { 2283 Title string `valid:"length(1|10)"` 2284 Body string `valid:"length(1|10)"` 2285} 2286 2287func TestValidateMissingValidationDeclarationStruct(t *testing.T) { 2288 var tests = []struct { 2289 param MissingValidationDeclarationStruct 2290 expected bool 2291 }{ 2292 {MissingValidationDeclarationStruct{}, false}, 2293 {MissingValidationDeclarationStruct{Name: "TEST", Email: "test@example.com"}, false}, 2294 } 2295 SetFieldsRequiredByDefault(true) 2296 for _, test := range tests { 2297 actual, err := ValidateStruct(test.param) 2298 if actual != test.expected { 2299 t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) 2300 if err != nil { 2301 t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) 2302 } 2303 } 2304 } 2305 SetFieldsRequiredByDefault(false) 2306} 2307 2308func TestFieldRequiredByDefault(t *testing.T) { 2309 var tests = []struct { 2310 param FieldRequiredByDefault 2311 expected bool 2312 }{ 2313 {FieldRequiredByDefault{}, false}, 2314 } 2315 SetFieldsRequiredByDefault(true) 2316 for _, test := range tests { 2317 actual, err := ValidateStruct(test.param) 2318 if actual != test.expected { 2319 t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) 2320 if err != nil { 2321 t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) 2322 } 2323 } 2324 } 2325 SetFieldsRequiredByDefault(false) 2326} 2327 2328func TestMultipleFieldsRequiredByDefault(t *testing.T) { 2329 var tests = []struct { 2330 param MultipleFieldsRequiredByDefault 2331 expected bool 2332 }{ 2333 {MultipleFieldsRequiredByDefault{}, false}, 2334 } 2335 SetFieldsRequiredByDefault(true) 2336 for _, test := range tests { 2337 actual, err := ValidateStruct(test.param) 2338 if actual != test.expected { 2339 t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) 2340 if err != nil { 2341 t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) 2342 } 2343 } 2344 } 2345 SetFieldsRequiredByDefault(false) 2346} 2347 2348func TestFieldsRequiredByDefaultButExemptStruct(t *testing.T) { 2349 var tests = []struct { 2350 param FieldsRequiredByDefaultButExemptStruct 2351 expected bool 2352 }{ 2353 {FieldsRequiredByDefaultButExemptStruct{}, false}, 2354 {FieldsRequiredByDefaultButExemptStruct{Name: "TEST"}, false}, 2355 {FieldsRequiredByDefaultButExemptStruct{Email: ""}, false}, 2356 {FieldsRequiredByDefaultButExemptStruct{Email: "test@example.com"}, true}, 2357 } 2358 SetFieldsRequiredByDefault(true) 2359 for _, test := range tests { 2360 actual, err := ValidateStruct(test.param) 2361 if actual != test.expected { 2362 t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) 2363 if err != nil { 2364 t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) 2365 } 2366 } 2367 } 2368 SetFieldsRequiredByDefault(false) 2369} 2370 2371func TestFieldsRequiredByDefaultButExemptOrOptionalStruct(t *testing.T) { 2372 var tests = []struct { 2373 param FieldsRequiredByDefaultButExemptOrOptionalStruct 2374 expected bool 2375 }{ 2376 {FieldsRequiredByDefaultButExemptOrOptionalStruct{}, true}, 2377 {FieldsRequiredByDefaultButExemptOrOptionalStruct{Name: "TEST"}, true}, 2378 {FieldsRequiredByDefaultButExemptOrOptionalStruct{Email: ""}, true}, 2379 {FieldsRequiredByDefaultButExemptOrOptionalStruct{Email: "test@example.com"}, true}, 2380 {FieldsRequiredByDefaultButExemptOrOptionalStruct{Email: "test@example"}, false}, 2381 } 2382 SetFieldsRequiredByDefault(true) 2383 for _, test := range tests { 2384 actual, err := ValidateStruct(test.param) 2385 if actual != test.expected { 2386 t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) 2387 if err != nil { 2388 t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) 2389 } 2390 } 2391 } 2392 SetFieldsRequiredByDefault(false) 2393} 2394 2395func TestInvalidValidator(t *testing.T) { 2396 type InvalidStruct struct { 2397 Field int `valid:"someInvalidValidator"` 2398 } 2399 2400 invalidStruct := InvalidStruct{1} 2401 if valid, err := ValidateStruct(&invalidStruct); valid || err == nil || 2402 err.Error() != `Field: The following validator is invalid or can't be applied to the field: "someInvalidValidator"` { 2403 t.Errorf("Got an unexpected result for struct with invalid validator: %t %s", valid, err) 2404 } 2405} 2406 2407func TestCustomValidator(t *testing.T) { 2408 type ValidStruct struct { 2409 Field int `valid:"customTrueValidator"` 2410 } 2411 2412 type InvalidStruct struct { 2413 Field int `valid:"customFalseValidator~Value: %s Custom validator error: %s"` 2414 } 2415 2416 type StructWithCustomAndBuiltinValidator struct { 2417 Field int `valid:"customTrueValidator,required"` 2418 } 2419 2420 if valid, err := ValidateStruct(&ValidStruct{Field: 1}); !valid || err != nil { 2421 t.Errorf("Got an unexpected result for struct with custom always true validator: %t %s", valid, err) 2422 } 2423 2424 if valid, err := ValidateStruct(&InvalidStruct{Field: 1}); valid || err == nil || err.Error() != "Value: 1 Custom validator error: customFalseValidator" { 2425 fmt.Println(err) 2426 t.Errorf("Got an unexpected result for struct with custom always false validator: %t %s", valid, err) 2427 } 2428 2429 mixedStruct := StructWithCustomAndBuiltinValidator{} 2430 if valid, err := ValidateStruct(&mixedStruct); valid || err == nil || err.Error() != "Field: non zero value required" { 2431 t.Errorf("Got an unexpected result for invalid struct with custom and built-in validators: %t %s", valid, err) 2432 } 2433 2434 mixedStruct.Field = 1 2435 if valid, err := ValidateStruct(&mixedStruct); !valid || err != nil { 2436 t.Errorf("Got an unexpected result for valid struct with custom and built-in validators: %t %s", valid, err) 2437 } 2438} 2439 2440type CustomByteArray [6]byte 2441 2442type StructWithCustomByteArray struct { 2443 ID CustomByteArray `valid:"customByteArrayValidator,customMinLengthValidator"` 2444 Email string `valid:"email"` 2445 CustomMinLength int `valid:"-"` 2446} 2447 2448func TestStructWithCustomByteArray(t *testing.T) { 2449 t.Parallel() 2450 2451 // add our custom byte array validator that fails when the byte array is pristine (all zeroes) 2452 CustomTypeTagMap.Set("customByteArrayValidator", CustomTypeValidator(func(i interface{}, o interface{}) bool { 2453 switch v := o.(type) { 2454 case StructWithCustomByteArray: 2455 if len(v.Email) > 0 { 2456 if v.Email != "test@example.com" { 2457 t.Errorf("v.Email should have been 'test@example.com' but was '%s'", v.Email) 2458 } 2459 } 2460 default: 2461 t.Errorf("Context object passed to custom validator should have been a StructWithCustomByteArray but was %T (%+v)", o, o) 2462 } 2463 2464 switch v := i.(type) { 2465 case CustomByteArray: 2466 for _, e := range v { // check if v is empty, i.e. all zeroes 2467 if e != 0 { 2468 return true 2469 } 2470 } 2471 } 2472 return false 2473 })) 2474 CustomTypeTagMap.Set("customMinLengthValidator", CustomTypeValidator(func(i interface{}, o interface{}) bool { 2475 switch v := o.(type) { 2476 case StructWithCustomByteArray: 2477 return len(v.ID) >= v.CustomMinLength 2478 } 2479 return false 2480 })) 2481 testCustomByteArray := CustomByteArray{'1', '2', '3', '4', '5', '6'} 2482 var tests = []struct { 2483 param StructWithCustomByteArray 2484 expected bool 2485 }{ 2486 {StructWithCustomByteArray{}, false}, 2487 {StructWithCustomByteArray{Email: "test@example.com"}, false}, 2488 {StructWithCustomByteArray{ID: testCustomByteArray, Email: "test@example.com"}, true}, 2489 {StructWithCustomByteArray{ID: testCustomByteArray, Email: "test@example.com", CustomMinLength: 7}, false}, 2490 } 2491 SetFieldsRequiredByDefault(true) 2492 for _, test := range tests { 2493 actual, err := ValidateStruct(test.param) 2494 if actual != test.expected { 2495 t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) 2496 if err != nil { 2497 t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) 2498 } 2499 } 2500 } 2501 SetFieldsRequiredByDefault(false) 2502} 2503 2504func TestValidateNegationStruct(t *testing.T) { 2505 var tests = []struct { 2506 param NegationStruct 2507 expected bool 2508 }{ 2509 {NegationStruct{"a1", "11"}, true}, 2510 {NegationStruct{"email@email.email", "11"}, true}, 2511 {NegationStruct{"123456----", "11"}, true}, 2512 {NegationStruct{"::1", "11"}, true}, 2513 {NegationStruct{"123.123", "11"}, true}, 2514 {NegationStruct{"a1", "a1"}, false}, 2515 {NegationStruct{"11", "a1"}, false}, 2516 {NegationStruct{"11", "11"}, false}, 2517 } 2518 for _, test := range tests { 2519 actual, err := ValidateStruct(test.param) 2520 if actual != test.expected { 2521 t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) 2522 if err != nil { 2523 t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) 2524 } 2525 } 2526 } 2527} 2528 2529func TestLengthStruct(t *testing.T) { 2530 var tests = []struct { 2531 param interface{} 2532 expected bool 2533 }{ 2534 {LengthStruct{"11111"}, false}, 2535 {LengthStruct{"11111111111111111110000000000000000"}, false}, 2536 {LengthStruct{"11dfffdf0099"}, true}, 2537 } 2538 2539 for _, test := range tests { 2540 actual, err := ValidateStruct(test.param) 2541 if actual != test.expected { 2542 t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) 2543 if err != nil { 2544 t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) 2545 } 2546 } 2547 } 2548} 2549 2550func TestStringLengthStruct(t *testing.T) { 2551 var tests = []struct { 2552 param interface{} 2553 expected bool 2554 }{ 2555 {StringLengthStruct{"11111"}, false}, 2556 {StringLengthStruct{"11111111111111111110000000000000000"}, false}, 2557 {StringLengthStruct{"11dfffdf0099"}, true}, 2558 {StringLengthStruct{"あいうえお"}, false}, 2559 {StringLengthStruct{"あいうえおかきくけこ"}, true}, 2560 {StringLengthStruct{"あいうえおかきくけこさしすせそたちつてと"}, true}, 2561 {StringLengthStruct{"あいうえおかきくけこさしすせそたちつてとな"}, false}, 2562 } 2563 2564 for _, test := range tests { 2565 actual, err := ValidateStruct(test.param) 2566 if actual != test.expected { 2567 t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) 2568 if err != nil { 2569 t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) 2570 } 2571 } 2572 } 2573} 2574 2575func TestStringMatchesStruct(t *testing.T) { 2576 var tests = []struct { 2577 param interface{} 2578 expected bool 2579 }{ 2580 {StringMatchesStruct{"123"}, true}, 2581 {StringMatchesStruct{"123456"}, false}, 2582 {StringMatchesStruct{"123abcd"}, false}, 2583 } 2584 2585 for _, test := range tests { 2586 actual, err := ValidateStruct(test.param) 2587 if actual != test.expected { 2588 t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) 2589 if err != nil { 2590 t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) 2591 } 2592 } 2593 } 2594} 2595 2596func TestIsInStruct(t *testing.T) { 2597 var tests = []struct { 2598 param interface{} 2599 expected bool 2600 }{ 2601 {IsInStruct{"PRESENT"}, true}, 2602 {IsInStruct{""}, true}, 2603 {IsInStruct{" "}, false}, 2604 {IsInStruct{"ABSENT"}, false}, 2605 } 2606 2607 for _, test := range tests { 2608 actual, err := ValidateStruct(test.param) 2609 if actual != test.expected { 2610 t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) 2611 if err != nil { 2612 t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) 2613 } 2614 } 2615 } 2616} 2617 2618func TestRequiredIsInStruct(t *testing.T) { 2619 type RequiredIsInStruct struct { 2620 IsIn string `valid:"in(PRESENT|PRÉSENTE|NOTABSENT),required"` 2621 } 2622 2623 var tests = []struct { 2624 param interface{} 2625 expected bool 2626 }{ 2627 {RequiredIsInStruct{"PRESENT"}, true}, 2628 {RequiredIsInStruct{""}, false}, 2629 {RequiredIsInStruct{" "}, false}, 2630 {RequiredIsInStruct{"ABSENT"}, false}, 2631 } 2632 2633 for _, test := range tests { 2634 actual, err := ValidateStruct(test.param) 2635 if actual != test.expected { 2636 t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) 2637 if err != nil { 2638 t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) 2639 } 2640 } 2641 } 2642} 2643 2644func TestEmptyRequiredIsInStruct(t *testing.T) { 2645 type EmptyRequiredIsInStruct struct { 2646 IsIn string `valid:"in(),required"` 2647 } 2648 2649 var tests = []struct { 2650 param interface{} 2651 expected bool 2652 }{ 2653 {EmptyRequiredIsInStruct{"PRESENT"}, false}, 2654 {EmptyRequiredIsInStruct{""}, false}, 2655 {EmptyRequiredIsInStruct{" "}, false}, 2656 {EmptyRequiredIsInStruct{"ABSENT"}, false}, 2657 } 2658 2659 for _, test := range tests { 2660 actual, err := ValidateStruct(test.param) 2661 if actual != test.expected { 2662 t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) 2663 if err != nil { 2664 t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) 2665 } 2666 } 2667 } 2668} 2669 2670func TestEmptyStringPtr(t *testing.T) { 2671 type EmptyIsInStruct struct { 2672 IsIn *string `valid:"length(3|5),required"` 2673 } 2674 2675 var empty = "" 2676 var valid = "123" 2677 var invalid = "123456" 2678 2679 var tests = []struct { 2680 param interface{} 2681 expected bool 2682 expectedErr string 2683 }{ 2684 {EmptyIsInStruct{&empty}, false, "IsIn: non zero value required"}, 2685 {EmptyIsInStruct{nil}, true, ""}, 2686 {EmptyIsInStruct{&valid}, true, ""}, 2687 {EmptyIsInStruct{&invalid}, false, "IsIn: 123456 does not validate as length(3|5)"}, 2688 } 2689 2690 SetNilPtrAllowedByRequired(true) 2691 for _, test := range tests { 2692 actual, err := ValidateStruct(test.param) 2693 2694 if actual != test.expected { 2695 t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) 2696 } 2697 if err != nil { 2698 if err.Error() != test.expectedErr { 2699 t.Errorf("Got Error on ValidateStruct(%q). Expected: %s Actual: %s", test.param, test.expectedErr, err) 2700 } 2701 } else if test.expectedErr != "" { 2702 t.Errorf("Expected error on ValidateStruct(%q).", test.param) 2703 } 2704 } 2705 SetNilPtrAllowedByRequired(false) 2706} 2707 2708func TestNestedStruct(t *testing.T) { 2709 type EvenMoreNestedStruct struct { 2710 Bar string `valid:"length(3|5)"` 2711 } 2712 type NestedStruct struct { 2713 Foo string `valid:"length(3|5),required"` 2714 EvenMoreNested EvenMoreNestedStruct 2715 SliceEvenMoreNested []EvenMoreNestedStruct 2716 MapEvenMoreNested map[string]EvenMoreNestedStruct 2717 } 2718 type OuterStruct struct { 2719 Nested NestedStruct 2720 } 2721 2722 var tests = []struct { 2723 param interface{} 2724 expected bool 2725 expectedErr string 2726 }{ 2727 {OuterStruct{ 2728 Nested: NestedStruct{ 2729 Foo: "", 2730 }, 2731 }, false, "Nested.Foo: non zero value required"}, 2732 {OuterStruct{ 2733 Nested: NestedStruct{ 2734 Foo: "123", 2735 }, 2736 }, true, ""}, 2737 {OuterStruct{ 2738 Nested: NestedStruct{ 2739 Foo: "123456", 2740 }, 2741 }, false, "Nested.Foo: 123456 does not validate as length(3|5)"}, 2742 {OuterStruct{ 2743 Nested: NestedStruct{ 2744 Foo: "123", 2745 EvenMoreNested: EvenMoreNestedStruct{ 2746 Bar: "123456", 2747 }, 2748 }, 2749 }, false, "Nested.EvenMoreNested.Bar: 123456 does not validate as length(3|5)"}, 2750 {OuterStruct{ 2751 Nested: NestedStruct{ 2752 Foo: "123", 2753 SliceEvenMoreNested: []EvenMoreNestedStruct{ 2754 EvenMoreNestedStruct{ 2755 Bar: "123456", 2756 }, 2757 }, 2758 }, 2759 }, false, "Nested.SliceEvenMoreNested.0.Bar: 123456 does not validate as length(3|5)"}, 2760 {OuterStruct{ 2761 Nested: NestedStruct{ 2762 Foo: "123", 2763 MapEvenMoreNested: map[string]EvenMoreNestedStruct{ 2764 "Foo": EvenMoreNestedStruct{ 2765 Bar: "123456", 2766 }, 2767 }, 2768 }, 2769 }, false, "Nested.MapEvenMoreNested.Foo.Bar: 123456 does not validate as length(3|5)"}, 2770 } 2771 2772 for _, test := range tests { 2773 actual, err := ValidateStruct(test.param) 2774 2775 if actual != test.expected { 2776 t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) 2777 } 2778 if err != nil { 2779 if err.Error() != test.expectedErr { 2780 t.Errorf("Got Error on ValidateStruct(%q). Expected: %s Actual: %s", test.param, test.expectedErr, err) 2781 } 2782 } else if test.expectedErr != "" { 2783 t.Errorf("Expected error on ValidateStruct(%q).", test.param) 2784 } 2785 } 2786} 2787 2788func TestFunkyIsInStruct(t *testing.T) { 2789 type FunkyIsInStruct struct { 2790 IsIn string `valid:"in(PRESENT|| |PRÉSENTE|NOTABSENT)"` 2791 } 2792 2793 var tests = []struct { 2794 param interface{} 2795 expected bool 2796 }{ 2797 {FunkyIsInStruct{"PRESENT"}, true}, 2798 {FunkyIsInStruct{""}, true}, 2799 {FunkyIsInStruct{" "}, true}, 2800 {FunkyIsInStruct{"ABSENT"}, false}, 2801 } 2802 2803 for _, test := range tests { 2804 actual, err := ValidateStruct(test.param) 2805 if actual != test.expected { 2806 t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) 2807 if err != nil { 2808 t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) 2809 } 2810 } 2811 } 2812} 2813 2814// TODO: test case broken 2815// func TestStringMatchesComplexStruct(t *testing.T) { 2816// var tests = []struct { 2817// param interface{} 2818// expected bool 2819// }{ 2820// {StringMatchesComplexStruct{"$()"}, false}, 2821// {StringMatchesComplexStruct{"$('AZERTY')"}, true}, 2822// {StringMatchesComplexStruct{`$("AZERTY")`}, true}, 2823// {StringMatchesComplexStruct{`$("")`}, false}, 2824// {StringMatchesComplexStruct{"AZERTY"}, false}, 2825// {StringMatchesComplexStruct{"$AZERTY"}, false}, 2826// } 2827 2828// for _, test := range tests { 2829// actual, err := ValidateStruct(test.param) 2830// if actual != test.expected { 2831// t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) 2832// if err != nil { 2833// t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) 2834// } 2835// } 2836// } 2837// } 2838 2839func TestValidateStruct(t *testing.T) { 2840 2841 var tests = []struct { 2842 param interface{} 2843 expected bool 2844 }{ 2845 {User{"John", "john@yahoo.com", "123G#678", 20, &Address{"Street", "ABC456D89"}, []Address{{"Street", "123456"}, {"Street", "123456"}}}, false}, 2846 {User{"John", "john!yahoo.com", "12345678", 20, &Address{"Street", "ABC456D89"}, []Address{{"Street", "ABC456D89"}, {"Street", "123456"}}}, false}, 2847 {User{"John", "", "12345", 0, &Address{"Street", "123456789"}, []Address{{"Street", "ABC456D89"}, {"Street", "123456"}}}, false}, 2848 {UserValid{"John", "john@yahoo.com", "123G#678", 20, &Address{"Street", "123456"}, []Address{{"Street", "123456"}, {"Street", "123456"}}}, true}, 2849 {UserValid{"John", "john!yahoo.com", "12345678", 20, &Address{"Street", "ABC456D89"}, []Address{}}, false}, 2850 {UserValid{"John", "john@yahoo.com", "12345678", 20, &Address{"Street", "123456xxx"}, []Address{{"Street", "123456"}, {"Street", "123456"}}}, false}, 2851 {UserValid{"John", "john!yahoo.com", "12345678", 20, &Address{"Street", "ABC456D89"}, []Address{{"Street", "ABC456D89"}, {"Street", "123456"}}}, false}, 2852 {UserValid{"John", "", "12345", 0, &Address{"Street", "123456789"}, []Address{{"Street", "ABC456D89"}, {"Street", "123456"}}}, false}, 2853 {nil, true}, 2854 {User{"John", "john@yahoo.com", "123G#678", 0, &Address{"Street", "123456"}, []Address{}}, false}, 2855 {"im not a struct", false}, 2856 } 2857 for _, test := range tests { 2858 actual, err := ValidateStruct(test.param) 2859 if actual != test.expected { 2860 t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) 2861 if err != nil { 2862 t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) 2863 } 2864 } 2865 } 2866 2867 TagMap["d_k"] = Validator(func(str string) bool { 2868 return str == "d_k" 2869 }) 2870 result, err := ValidateStruct(PrivateStruct{"d_k", 0, []int{1, 2}, []string{"hi", "super"}, [2]Address{{"Street", "123456"}, 2871 {"Street", "123456"}}, Address{"Street", "123456"}, map[string]Address{"address": {"Street", "123456"}}}) 2872 if !result { 2873 t.Log("Case ", 6, ": expected ", true, " when result is ", result) 2874 t.Error(err) 2875 t.FailNow() 2876 } 2877} 2878 2879type testByteArray [8]byte 2880type testByteMap map[byte]byte 2881type testByteSlice []byte 2882type testStringStringMap map[string]string 2883type testStringIntMap map[string]int 2884 2885func TestRequired(t *testing.T) { 2886 2887 testString := "foobar" 2888 testEmptyString := "" 2889 var tests = []struct { 2890 param interface{} 2891 expected bool 2892 }{ 2893 { 2894 struct { 2895 Pointer *string `valid:"required"` 2896 }{}, 2897 false, 2898 }, 2899 { 2900 struct { 2901 Pointer *string `valid:"required"` 2902 }{ 2903 Pointer: &testEmptyString, 2904 }, 2905 false, 2906 }, 2907 { 2908 struct { 2909 Pointer *string `valid:"required"` 2910 }{ 2911 Pointer: &testString, 2912 }, 2913 true, 2914 }, 2915 { 2916 struct { 2917 Addr Address `valid:"required"` 2918 }{}, 2919 false, 2920 }, 2921 { 2922 struct { 2923 Addr Address `valid:"required"` 2924 }{ 2925 Addr: Address{"", "123"}, 2926 }, 2927 true, 2928 }, 2929 { 2930 struct { 2931 Pointer *Address `valid:"required"` 2932 }{}, 2933 false, 2934 }, 2935 { 2936 struct { 2937 Pointer *Address `valid:"required"` 2938 }{ 2939 Pointer: &Address{"", "123"}, 2940 }, 2941 true, 2942 }, 2943 { 2944 struct { 2945 TestByteArray testByteArray `valid:"required"` 2946 }{}, 2947 false, 2948 }, 2949 { 2950 struct { 2951 TestByteArray testByteArray `valid:"required"` 2952 }{ 2953 testByteArray{}, 2954 }, 2955 false, 2956 }, 2957 { 2958 struct { 2959 TestByteArray testByteArray `valid:"required"` 2960 }{ 2961 testByteArray{'1', '2', '3', '4', '5', '6', '7', 'A'}, 2962 }, 2963 true, 2964 }, 2965 { 2966 struct { 2967 TestByteMap testByteMap `valid:"required"` 2968 }{}, 2969 false, 2970 }, 2971 { 2972 struct { 2973 TestByteSlice testByteSlice `valid:"required"` 2974 }{}, 2975 false, 2976 }, 2977 { 2978 struct { 2979 TestStringStringMap testStringStringMap `valid:"required"` 2980 }{ 2981 testStringStringMap{"test": "test"}, 2982 }, 2983 true, 2984 }, 2985 { 2986 struct { 2987 TestIntMap testStringIntMap `valid:"required"` 2988 }{ 2989 testStringIntMap{"test": 42}, 2990 }, 2991 true, 2992 }, 2993 } 2994 for _, test := range tests { 2995 actual, err := ValidateStruct(test.param) 2996 if actual != test.expected { 2997 t.Errorf("Expected ValidateStruct(%q) to be %v, got %v", test.param, test.expected, actual) 2998 if err != nil { 2999 t.Errorf("Got Error on ValidateStruct(%q): %s", test.param, err) 3000 } 3001 } 3002 } 3003} 3004 3005func TestErrorByField(t *testing.T) { 3006 t.Parallel() 3007 3008 var tests = []struct { 3009 param string 3010 expected string 3011 }{ 3012 {"message", ""}, 3013 {"Message", ""}, 3014 {"title", ""}, 3015 {"Title", "My123 does not validate as alpha"}, 3016 {"AuthorIP", "123 does not validate as ipv4"}, 3017 } 3018 post := &Post{"My123", "duck13126", "123"} 3019 _, err := ValidateStruct(post) 3020 3021 for _, test := range tests { 3022 actual := ErrorByField(err, test.param) 3023 if actual != test.expected { 3024 t.Errorf("Expected ErrorByField(%q) to be %v, got %v", test.param, test.expected, actual) 3025 } 3026 } 3027} 3028 3029func TestErrorsByField(t *testing.T) { 3030 t.Parallel() 3031 3032 var tests = []struct { 3033 param string 3034 expected string 3035 }{ 3036 {"Title", "My123 does not validate as alpha"}, 3037 {"AuthorIP", "123 does not validate as ipv4"}, 3038 } 3039 post := &Post{Title: "My123", Message: "duck13126", AuthorIP: "123"} 3040 _, err := ValidateStruct(post) 3041 errs := ErrorsByField(err) 3042 if len(errs) != 2 { 3043 t.Errorf("There should only be 2 errors but got %v", len(errs)) 3044 } 3045 3046 for _, test := range tests { 3047 if actual, ok := errs[test.param]; !ok || actual != test.expected { 3048 t.Errorf("Expected ErrorsByField(%q) to be %v, got %v", test.param, test.expected, actual) 3049 } 3050 } 3051 3052 tests = []struct { 3053 param string 3054 expected string 3055 }{ 3056 {"Title", ";:;message;:; does not validate as length(1|10)"}, 3057 {"Body", ";:;message;:; does not validate as length(1|10)"}, 3058 } 3059 3060 message := &MessageWithSeveralFieldsStruct{Title: ";:;message;:;", Body: ";:;message;:;"} 3061 _, err = ValidateStruct(message) 3062 errs = ErrorsByField(err) 3063 if len(errs) != 2 { 3064 t.Errorf("There should only be 2 errors but got %v", len(errs)) 3065 } 3066 3067 for _, test := range tests { 3068 if actual, ok := errs[test.param]; !ok || actual != test.expected { 3069 t.Errorf("Expected ErrorsByField(%q) to be %v, got %v", test.param, test.expected, actual) 3070 } 3071 } 3072 3073 tests = []struct { 3074 param string 3075 expected string 3076 }{ 3077 {"CustomField", "An error occurred"}, 3078 } 3079 3080 err = Error{"CustomField", fmt.Errorf("An error occurred"), false, "hello", []string{}} 3081 errs = ErrorsByField(err) 3082 3083 if len(errs) != 1 { 3084 t.Errorf("There should only be 1 errors but got %v", len(errs)) 3085 } 3086 3087 for _, test := range tests { 3088 if actual, ok := errs[test.param]; !ok || actual != test.expected { 3089 t.Errorf("Expected ErrorsByField(%q) to be %v, got %v", test.param, test.expected, actual) 3090 } 3091 } 3092 3093 type StructWithCustomValidation struct { 3094 Email string `valid:"email"` 3095 ID string `valid:"falseValidation"` 3096 } 3097 3098 CustomTypeTagMap.Set("falseValidation", CustomTypeValidator(func(i interface{}, o interface{}) bool { 3099 return false 3100 })) 3101 3102 tests = []struct { 3103 param string 3104 expected string 3105 }{ 3106 {"Email", "My123 does not validate as email"}, 3107 {"ID", "duck13126 does not validate as falseValidation"}, 3108 } 3109 s := &StructWithCustomValidation{Email: "My123", ID: "duck13126"} 3110 _, err = ValidateStruct(s) 3111 errs = ErrorsByField(err) 3112 if len(errs) != 2 { 3113 t.Errorf("There should only be 2 errors but got %v", len(errs)) 3114 } 3115 3116 for _, test := range tests { 3117 if actual, ok := errs[test.param]; !ok || actual != test.expected { 3118 t.Errorf("Expected ErrorsByField(%q) to be %v, got %v", test.param, test.expected, actual) 3119 } 3120 } 3121} 3122 3123func TestValidateStructPointers(t *testing.T) { 3124 // Struct which uses pointers for values 3125 type UserWithPointers struct { 3126 Name *string `valid:"-"` 3127 Email *string `valid:"email"` 3128 FavoriteFood *string `valid:"length(0|32)"` 3129 Nerd *bool `valid:"-"` 3130 } 3131 3132 var tests = []struct { 3133 param string 3134 expected string 3135 }{ 3136 {"Name", ""}, 3137 {"Email", "invalid does not validate as email"}, 3138 {"FavoriteFood", ""}, 3139 {"Nerd", ""}, 3140 } 3141 3142 name := "Herman" 3143 email := "invalid" 3144 food := "Pizza" 3145 nerd := true 3146 user := &UserWithPointers{&name, &email, &food, &nerd} 3147 _, err := ValidateStruct(user) 3148 3149 for _, test := range tests { 3150 actual := ErrorByField(err, test.param) 3151 if actual != test.expected { 3152 t.Errorf("Expected ErrorByField(%q) to be %v, got %v", test.param, test.expected, actual) 3153 } 3154 } 3155} 3156 3157func ExampleValidateStruct() { 3158 type Post struct { 3159 Title string `valid:"alphanum,required"` 3160 Message string `valid:"duck,ascii"` 3161 AuthorIP string `valid:"ipv4"` 3162 } 3163 post := &Post{"My Example Post", "duck", "123.234.54.3"} 3164 3165 //Add your own struct validation tags 3166 TagMap["duck"] = Validator(func(str string) bool { 3167 return str == "duck" 3168 }) 3169 3170 result, err := ValidateStruct(post) 3171 if err != nil { 3172 println("error: " + err.Error()) 3173 } 3174 println(result) 3175} 3176 3177func TestValidateStructParamValidatorInt(t *testing.T) { 3178 type Test1 struct { 3179 Int int `valid:"range(1|10)"` 3180 Int8 int8 `valid:"range(1|10)"` 3181 Int16 int16 `valid:"range(1|10)"` 3182 Int32 int32 `valid:"range(1|10)"` 3183 Int64 int64 `valid:"range(1|10)"` 3184 3185 Uint uint `valid:"range(1|10)"` 3186 Uint8 uint8 `valid:"range(1|10)"` 3187 Uint16 uint16 `valid:"range(1|10)"` 3188 Uint32 uint32 `valid:"range(1|10)"` 3189 Uint64 uint64 `valid:"range(1|10)"` 3190 3191 Float32 float32 `valid:"range(1|10)"` 3192 Float64 float64 `valid:"range(1|10)"` 3193 } 3194 test1Ok := &Test1{5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5} 3195 test1NotOk := &Test1{11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11} 3196 3197 _, err := ValidateStruct(test1Ok) 3198 if err != nil { 3199 t.Errorf("Test failed: %s", err) 3200 } 3201 3202 _, err = ValidateStruct(test1NotOk) 3203 if err == nil { 3204 t.Errorf("Test failed: nil") 3205 } 3206 3207 type Test2 struct { 3208 Int int `valid:"in(1|10)"` 3209 Int8 int8 `valid:"in(1|10)"` 3210 Int16 int16 `valid:"in(1|10)"` 3211 Int32 int32 `valid:"in(1|10)"` 3212 Int64 int64 `valid:"in(1|10)"` 3213 3214 Uint uint `valid:"in(1|10)"` 3215 Uint8 uint8 `valid:"in(1|10)"` 3216 Uint16 uint16 `valid:"in(1|10)"` 3217 Uint32 uint32 `valid:"in(1|10)"` 3218 Uint64 uint64 `valid:"in(1|10)"` 3219 3220 Float32 float32 `valid:"in(1|10)"` 3221 Float64 float64 `valid:"in(1|10)"` 3222 } 3223 3224 test2Ok1 := &Test2{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} 3225 test2Ok2 := &Test2{10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10} 3226 test2NotOk := &Test2{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2} 3227 3228 _, err = ValidateStruct(test2Ok1) 3229 if err != nil { 3230 t.Errorf("Test failed: %s", err) 3231 } 3232 3233 _, err = ValidateStruct(test2Ok2) 3234 if err != nil { 3235 t.Errorf("Test failed: %s", err) 3236 } 3237 3238 _, err = ValidateStruct(test2NotOk) 3239 if err == nil { 3240 t.Errorf("Test failed: nil") 3241 } 3242 3243 type Test3 struct { 3244 Int int `valid:"in(1|10),int"` 3245 Int8 int8 `valid:"in(1|10),int8"` 3246 Int16 int16 `valid:"in(1|10),int16"` 3247 Int32 int32 `valid:"in(1|10),int32"` 3248 Int64 int64 `valid:"in(1|10),int64"` 3249 3250 Uint uint `valid:"in(1|10),uint"` 3251 Uint8 uint8 `valid:"in(1|10),uint8"` 3252 Uint16 uint16 `valid:"in(1|10),uint16"` 3253 Uint32 uint32 `valid:"in(1|10),uint32"` 3254 Uint64 uint64 `valid:"in(1|10),uint64"` 3255 3256 Float32 float32 `valid:"in(1|10),float32"` 3257 Float64 float64 `valid:"in(1|10),float64"` 3258 } 3259 3260 test3Ok1 := &Test2{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} 3261 test3Ok2 := &Test2{10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10} 3262 test3NotOk := &Test2{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2} 3263 3264 _, err = ValidateStruct(test3Ok1) 3265 if err != nil { 3266 t.Errorf("Test failed: %s", err) 3267 } 3268 3269 _, err = ValidateStruct(test3Ok2) 3270 if err != nil { 3271 t.Errorf("Test failed: %s", err) 3272 } 3273 3274 _, err = ValidateStruct(test3NotOk) 3275 if err == nil { 3276 t.Errorf("Test failed: nil") 3277 } 3278} 3279 3280func TestValidateStructUpperAndLowerCaseWithNumTypeCheck(t *testing.T) { 3281 3282 type StructCapital struct { 3283 Total float32 `valid:"float,required"` 3284 } 3285 3286 structCapital := &StructCapital{53.3535} 3287 _, err := ValidateStruct(structCapital) 3288 if err != nil { 3289 t.Errorf("Test failed: nil") 3290 fmt.Println(err) 3291 } 3292 3293 type StructLower struct { 3294 total float32 `valid:"float,required"` 3295 } 3296 3297 structLower := &StructLower{53.3535} 3298 _, err = ValidateStruct(structLower) 3299 if err != nil { 3300 t.Errorf("Test failed: nil") 3301 fmt.Println(err) 3302 } 3303} 3304 3305func TestIsCIDR(t *testing.T) { 3306 t.Parallel() 3307 3308 var tests = []struct { 3309 param string 3310 expected bool 3311 }{ 3312 {"193.168.3.20/7", true}, 3313 {"2001:db8::/32", true}, 3314 {"2001:0db8:85a3:0000:0000:8a2e:0370:7334/64", true}, 3315 {"193.138.3.20/60", false}, 3316 {"500.323.2.23/43", false}, 3317 {"", false}, 3318 } 3319 for _, test := range tests { 3320 actual := IsCIDR(test.param) 3321 if actual != test.expected { 3322 t.Errorf("Expected IsCIDR(%q) to be %v, got %v", test.param, test.expected, actual) 3323 } 3324 } 3325} 3326 3327func TestOptionalCustomValidators(t *testing.T) { 3328 3329 CustomTypeTagMap.Set("f2", CustomTypeValidator(func(i interface{}, o interface{}) bool { 3330 return false 3331 })) 3332 3333 var val struct { 3334 WithCustomError string `valid:"f2~boom,optional"` 3335 WithoutCustomError string `valid:"f2,optional"` 3336 OptionalFirst string `valid:"optional,f2"` 3337 } 3338 3339 ok, err := ValidateStruct(val) 3340 3341 if err != nil { 3342 t.Errorf("Expected nil err with optional validation, got %v", err) 3343 } 3344 3345 if !ok { 3346 t.Error("Expected validation to return true, got false") 3347 } 3348} 3349 3350func TestJSONValidator(t *testing.T) { 3351 3352 var val struct { 3353 WithJSONName string `json:"with_json_name" valid:"-,required"` 3354 WithoutJSONName string `valid:"-,required"` 3355 WithJSONOmit string `json:"with_other_json_name,omitempty" valid:"-,required"` 3356 WithJSONOption string `json:",omitempty" valid:"-,required"` 3357 WithEmptyJSONName string `json:"-" valid:"-,required"` 3358 } 3359 3360 _, err := ValidateStruct(val) 3361 3362 if err == nil { 3363 t.Error("Expected error but got no error") 3364 } 3365 3366 if Contains(err.Error(), "WithJSONName") { 3367 t.Errorf("Expected error message to contain with_json_name but actual error is: %s", err.Error()) 3368 } 3369 3370 if !Contains(err.Error(), "WithoutJSONName") { 3371 t.Errorf("Expected error message to contain WithoutJSONName but actual error is: %s", err.Error()) 3372 } 3373 3374 if Contains(err.Error(), "omitempty") { 3375 t.Errorf("Expected error message to not contain ',omitempty' but actual error is: %s", err.Error()) 3376 } 3377 3378 if !Contains(err.Error(), "WithEmptyJSONName") { 3379 t.Errorf("Expected error message to contain WithEmptyJSONName but actual error is: %s", err.Error()) 3380 } 3381} 3382 3383func TestValidatorIncludedInError(t *testing.T) { 3384 post := Post{ 3385 Title: "", 3386 Message: "", 3387 AuthorIP: "xyz", 3388 } 3389 3390 validatorMap := map[string]string{ 3391 "Title": "required", 3392 "Message": "ascii", 3393 "AuthorIP": "ipv4", 3394 } 3395 3396 ok, errors := ValidateStruct(post) 3397 if ok { 3398 t.Errorf("expected validation to fail %v", ok) 3399 } 3400 3401 for _, e := range errors.(Errors) { 3402 casted := e.(Error) 3403 if validatorMap[casted.Name] != casted.Validator { 3404 t.Errorf("expected validator for %s to be %s, but was %s", casted.Name, validatorMap[casted.Name], casted.Validator) 3405 } 3406 } 3407 3408 // check to make sure that validators with arguments (like length(1|10)) don't include the arguments 3409 // in the validator name 3410 message := MessageWithSeveralFieldsStruct{ 3411 Title: "", 3412 Body: "asdfasdfasdfasdfasdf", 3413 } 3414 3415 validatorMap = map[string]string{ 3416 "Title": "length", 3417 "Body": "length", 3418 } 3419 3420 ok, errors = ValidateStruct(message) 3421 if ok { 3422 t.Errorf("expected validation to fail, %v", ok) 3423 } 3424 3425 for _, e := range errors.(Errors) { 3426 casted := e.(Error) 3427 if validatorMap[casted.Name] != casted.Validator { 3428 t.Errorf("expected validator for %s to be %s, but was %s", casted.Name, validatorMap[casted.Name], casted.Validator) 3429 } 3430 } 3431 3432 // make sure validators with custom messages don't show up in the validator string 3433 type CustomMessage struct { 3434 Text string `valid:"length(1|10)~Custom message"` 3435 } 3436 cs := CustomMessage{Text: "asdfasdfasdfasdf"} 3437 3438 ok, errors = ValidateStruct(&cs) 3439 if ok { 3440 t.Errorf("expected validation to fail, %v", ok) 3441 } 3442 3443 validator := errors.(Errors)[0].(Error).Validator 3444 if validator != "length" { 3445 t.Errorf("expected validator for Text to be length, but was %s", validator) 3446 } 3447 3448} 3449 3450func TestIsRsaPublicKey(t *testing.T) { 3451 var tests = []struct { 3452 rsastr string 3453 keylen int 3454 expected bool 3455 }{ 3456 {`fubar`, 2048, false}, 3457 {`MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvncDCeibmEkabJLmFec7x9y86RP6dIvkVxxbQoOJo06E+p7tH6vCmiGHKnuu 3458XwKYLq0DKUE3t/HHsNdowfD9+NH8caLzmXqGBx45/Dzxnwqz0qYq7idK+Qff34qrk/YFoU7498U1Ee7PkKb7/VE9BmMEcI3uoKbeXCbJRI 3459HoTp8bUXOpNTSUfwUNwJzbm2nsHo2xu6virKtAZLTsJFzTUmRd11MrWCvj59lWzt1/eIMN+ekjH8aXeLOOl54CL+kWp48C+V9BchyKCShZ 3460B7ucimFvjHTtuxziXZQRO7HlcsBOa0WwvDJnRnskdyoD31s4F4jpKEYBJNWTo63v6lUvbQIDAQAB`, 2048, true}, 3461 {`MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvncDCeibmEkabJLmFec7x9y86RP6dIvkVxxbQoOJo06E+p7tH6vCmiGHKnuu 3462XwKYLq0DKUE3t/HHsNdowfD9+NH8caLzmXqGBx45/Dzxnwqz0qYq7idK+Qff34qrk/YFoU7498U1Ee7PkKb7/VE9BmMEcI3uoKbeXCbJRI 3463HoTp8bUXOpNTSUfwUNwJzbm2nsHo2xu6virKtAZLTsJFzTUmRd11MrWCvj59lWzt1/eIMN+ekjH8aXeLOOl54CL+kWp48C+V9BchyKCShZ 3464B7ucimFvjHTtuxziXZQRO7HlcsBOa0WwvDJnRnskdyoD31s4F4jpKEYBJNWTo63v6lUvbQIDAQAB`, 1024, false}, 3465 {`-----BEGIN PUBLIC KEY----- 3466MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvncDCeibmEkabJLmFec7 3467x9y86RP6dIvkVxxbQoOJo06E+p7tH6vCmiGHKnuuXwKYLq0DKUE3t/HHsNdowfD9 3468+NH8caLzmXqGBx45/Dzxnwqz0qYq7idK+Qff34qrk/YFoU7498U1Ee7PkKb7/VE9 3469BmMEcI3uoKbeXCbJRIHoTp8bUXOpNTSUfwUNwJzbm2nsHo2xu6virKtAZLTsJFzT 3470UmRd11MrWCvj59lWzt1/eIMN+ekjH8aXeLOOl54CL+kWp48C+V9BchyKCShZB7uc 3471imFvjHTtuxziXZQRO7HlcsBOa0WwvDJnRnskdyoD31s4F4jpKEYBJNWTo63v6lUv 3472bQIDAQAB 3473-----END PUBLIC KEY-----`, 2048, true}, 3474 {`-----BEGIN PUBLIC KEY----- 3475MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvncDCeibmEkabJLmFec7 3476x9y86RP6dIvkVxxbQoOJo06E+p7tH6vCmiGHKnuuXwKYLq0DKUE3t/HHsNdowfD9 3477+NH8caLzmXqGBx45/Dzxnwqz0qYq7idK+Qff34qrk/YFoU7498U1Ee7PkKb7/VE9 3478BmMEcI3uoKbeXCbJRIHoTp8bUXOpNTSUfwUNwJzbm2nsHo2xu6virKtAZLTsJFzT 3479UmRd11MrWCvj59lWzt1/eIMN+ekjH8aXeLOOl54CL+kWp48C+V9BchyKCShZB7uc 3480imFvjHTtuxziXZQRO7HlcsBOa0WwvDJnRnskdyoD31s4F4jpKEYBJNWTo63v6lUv 3481bQIDAQAB 3482-----END PUBLIC KEY-----`, 4096, false}, 3483 } 3484 for i, test := range tests { 3485 actual := IsRsaPublicKey(test.rsastr, test.keylen) 3486 if actual != test.expected { 3487 t.Errorf("Expected TestIsRsaPublicKey(%d, %d) to be %v, got %v", i, test.keylen, test.expected, actual) 3488 } 3489 } 3490} 3491