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