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