github.com/mithrandie/csvq@v1.18.1/lib/query/function_test.go (about) 1 package query 2 3 import ( 4 "context" 5 "math" 6 "reflect" 7 "testing" 8 "time" 9 10 "github.com/mithrandie/csvq/lib/option" 11 12 "github.com/mithrandie/csvq/lib/parser" 13 "github.com/mithrandie/csvq/lib/value" 14 15 "github.com/mithrandie/ternary" 16 ) 17 18 type functionTest struct { 19 Name string 20 Function parser.Function 21 Args []value.Primary 22 Result value.Primary 23 Error string 24 } 25 26 func testFunction(t *testing.T, f func(parser.Function, []value.Primary, *option.Flags) (value.Primary, error), tests []functionTest) { 27 for _, v := range tests { 28 result, err := f(v.Function, v.Args, TestTx.Flags) 29 if err != nil { 30 if len(v.Error) < 1 { 31 t.Errorf("%s: unexpected error %q", v.Name, err) 32 } else if v.Error != "environment-dependent" && err.Error() != v.Error { 33 t.Errorf("%s: error %q, want error %q", v.Name, err.Error(), v.Error) 34 } 35 continue 36 } 37 if 0 < len(v.Error) { 38 t.Errorf("%s: no error, want error %q", v.Name, v.Error) 39 continue 40 } 41 if !reflect.DeepEqual(result, v.Result) { 42 if f1, ok := v.Result.(*value.Float); ok && math.IsNaN(f1.Raw()) { 43 if f2, ok := result.(*value.Float); ok && math.IsNaN(f2.Raw()) { 44 continue 45 } 46 } 47 48 t.Errorf("%s: result = %s, want %s", v.Name, result, v.Result) 49 } 50 } 51 } 52 53 var coalesceTests = []functionTest{ 54 { 55 Name: "Coalesce", 56 Function: parser.Function{ 57 Name: "coalesce", 58 }, 59 Args: []value.Primary{ 60 value.NewNull(), 61 value.NewString("str"), 62 }, 63 Result: value.NewString("str"), 64 }, 65 { 66 Name: "Coalesce Argments Error", 67 Function: parser.Function{ 68 Name: "coalesce", 69 }, 70 Args: []value.Primary{}, 71 Error: "function coalesce takes at least 1 argument", 72 }, 73 { 74 Name: "Coalesce No Match", 75 Function: parser.Function{ 76 Name: "coalesce", 77 }, 78 Args: []value.Primary{ 79 value.NewNull(), 80 value.NewNull(), 81 }, 82 Result: value.NewNull(), 83 }, 84 } 85 86 func TestCoalesce(t *testing.T) { 87 testFunction(t, Coalesce, coalesceTests) 88 } 89 90 var ifTests = []functionTest{ 91 { 92 Name: "If True", 93 Function: parser.Function{ 94 Name: "if", 95 }, 96 Args: []value.Primary{ 97 value.NewTernary(ternary.TRUE), 98 value.NewInteger(1), 99 value.NewInteger(2), 100 }, 101 Result: value.NewInteger(1), 102 }, 103 { 104 Name: "If False", 105 Function: parser.Function{ 106 Name: "if", 107 }, 108 Args: []value.Primary{ 109 value.NewTernary(ternary.FALSE), 110 value.NewInteger(1), 111 value.NewInteger(2), 112 }, 113 Result: value.NewInteger(2), 114 }, 115 { 116 Name: "If Argumants Error", 117 Function: parser.Function{ 118 Name: "if", 119 }, 120 Args: []value.Primary{ 121 value.NewTernary(ternary.FALSE), 122 }, 123 Error: "function if takes exactly 3 arguments", 124 }, 125 } 126 127 func TestIf(t *testing.T) { 128 testFunction(t, If, ifTests) 129 } 130 131 var ifnullTests = []functionTest{ 132 { 133 Name: "Ifnull True", 134 Function: parser.Function{ 135 Name: "ifnull", 136 }, 137 Args: []value.Primary{ 138 value.NewNull(), 139 value.NewInteger(2), 140 }, 141 Result: value.NewInteger(2), 142 }, 143 { 144 Name: "Ifnull False", 145 Function: parser.Function{ 146 Name: "ifnull", 147 }, 148 Args: []value.Primary{ 149 value.NewInteger(1), 150 value.NewInteger(2), 151 }, 152 Result: value.NewInteger(1), 153 }, 154 { 155 Name: "Ifnull Arguments Error", 156 Function: parser.Function{ 157 Name: "ifnull", 158 }, 159 Args: []value.Primary{ 160 value.NewInteger(1), 161 }, 162 Error: "function ifnull takes exactly 2 arguments", 163 }, 164 } 165 166 func TestIfnull(t *testing.T) { 167 testFunction(t, Ifnull, ifnullTests) 168 } 169 170 var nullifTests = []functionTest{ 171 { 172 Name: "Nullif True", 173 Function: parser.Function{ 174 Name: "nullif", 175 }, 176 Args: []value.Primary{ 177 value.NewInteger(2), 178 value.NewInteger(2), 179 }, 180 Result: value.NewNull(), 181 }, 182 { 183 Name: "Nullif False", 184 Function: parser.Function{ 185 Name: "nullif", 186 }, 187 Args: []value.Primary{ 188 value.NewInteger(1), 189 value.NewInteger(2), 190 }, 191 Result: value.NewInteger(1), 192 }, 193 { 194 Name: "Nullif Arguments Error", 195 Function: parser.Function{ 196 Name: "nullif", 197 }, 198 Args: []value.Primary{ 199 value.NewInteger(1), 200 }, 201 Error: "function nullif takes exactly 2 arguments", 202 }, 203 } 204 205 func TestNullif(t *testing.T) { 206 testFunction(t, Nullif, nullifTests) 207 } 208 209 var ceilTests = []functionTest{ 210 { 211 Name: "Ceil", 212 Function: parser.Function{ 213 Name: "ceil", 214 }, 215 Args: []value.Primary{ 216 value.NewFloat(2.345), 217 }, 218 Result: value.NewFloat(3), 219 }, 220 { 221 Name: "Ceil Null", 222 Function: parser.Function{ 223 Name: "ceil", 224 }, 225 Args: []value.Primary{ 226 value.NewNull(), 227 }, 228 Result: value.NewNull(), 229 }, 230 { 231 Name: "Ceil Place is Null", 232 Function: parser.Function{ 233 Name: "ceil", 234 }, 235 Args: []value.Primary{ 236 value.NewFloat(2.345), 237 value.NewNull(), 238 }, 239 Result: value.NewNull(), 240 }, 241 { 242 Name: "Ceil Arguments Error", 243 Function: parser.Function{ 244 Name: "ceil", 245 }, 246 Args: []value.Primary{}, 247 Error: "function ceil takes 1 or 2 arguments", 248 }, 249 } 250 251 func TestCeil(t *testing.T) { 252 testFunction(t, Ceil, ceilTests) 253 } 254 255 var floorTests = []functionTest{ 256 { 257 Name: "Floor", 258 Function: parser.Function{ 259 Name: "floor", 260 }, 261 Args: []value.Primary{ 262 value.NewFloat(2.345), 263 value.NewInteger(1), 264 }, 265 Result: value.NewFloat(2.3), 266 }, 267 { 268 Name: "Floor Null", 269 Function: parser.Function{ 270 Name: "floor", 271 }, 272 Args: []value.Primary{ 273 value.NewNull(), 274 }, 275 Result: value.NewNull(), 276 }, 277 { 278 Name: "Floor Arguments Error", 279 Function: parser.Function{ 280 Name: "floor", 281 }, 282 Args: []value.Primary{}, 283 Error: "function floor takes 1 or 2 arguments", 284 }, 285 } 286 287 func TestFloor(t *testing.T) { 288 testFunction(t, Floor, floorTests) 289 } 290 291 var roundTests = []functionTest{ 292 { 293 Name: "Round", 294 Function: parser.Function{ 295 Name: "round", 296 }, 297 Args: []value.Primary{ 298 value.NewFloat(2.456), 299 value.NewInteger(2), 300 }, 301 Result: value.NewFloat(2.46), 302 }, 303 { 304 Name: "Round Negative Number", 305 Function: parser.Function{ 306 Name: "round", 307 }, 308 Args: []value.Primary{ 309 value.NewFloat(-2.456), 310 value.NewInteger(2), 311 }, 312 Result: value.NewFloat(-2.46), 313 }, 314 { 315 Name: "Round Null", 316 Function: parser.Function{ 317 Name: "round", 318 }, 319 Args: []value.Primary{ 320 value.NewNull(), 321 }, 322 Result: value.NewNull(), 323 }, 324 { 325 Name: "Round Arguments Error", 326 Function: parser.Function{ 327 Name: "round", 328 }, 329 Args: []value.Primary{}, 330 Error: "function round takes 1 or 2 arguments", 331 }, 332 } 333 334 func TestRound(t *testing.T) { 335 testFunction(t, Round, roundTests) 336 } 337 338 var absTests = []functionTest{ 339 { 340 Name: "Abs", 341 Function: parser.Function{ 342 Name: "abs", 343 }, 344 Args: []value.Primary{ 345 value.NewInteger(-2), 346 }, 347 Result: value.NewFloat(2), 348 }, 349 { 350 Name: "Abs Null", 351 Function: parser.Function{ 352 Name: "abs", 353 }, 354 Args: []value.Primary{ 355 value.NewNull(), 356 }, 357 Result: value.NewNull(), 358 }, 359 { 360 Name: "Abs Arguments Error", 361 Function: parser.Function{ 362 Name: "abs", 363 }, 364 Args: []value.Primary{}, 365 Error: "function abs takes exactly 1 argument", 366 }, 367 } 368 369 func TestAbs(t *testing.T) { 370 testFunction(t, Abs, absTests) 371 } 372 373 var acosTests = []functionTest{ 374 { 375 Name: "Acos", 376 Function: parser.Function{ 377 Name: "acos", 378 }, 379 Args: []value.Primary{ 380 value.NewInteger(0), 381 }, 382 Result: value.NewFloat(1.5707963267948966), 383 }, 384 } 385 386 func TestAcos(t *testing.T) { 387 testFunction(t, Acos, acosTests) 388 } 389 390 var acoshTests = []functionTest{ 391 { 392 Name: "Acosh", 393 Function: parser.Function{ 394 Name: "acosh", 395 }, 396 Args: []value.Primary{ 397 value.NewInteger(1), 398 }, 399 Result: value.NewFloat(0), 400 }, 401 } 402 403 func TestAcosh(t *testing.T) { 404 testFunction(t, Acosh, acoshTests) 405 } 406 407 var asinTests = []functionTest{ 408 { 409 Name: "Asin", 410 Function: parser.Function{ 411 Name: "asin", 412 }, 413 Args: []value.Primary{ 414 value.NewFloat(0.1), 415 }, 416 Result: value.NewFloat(0.1001674211615598), 417 }, 418 } 419 420 func TestAsin(t *testing.T) { 421 testFunction(t, Asin, asinTests) 422 } 423 424 var asinhTests = []functionTest{ 425 { 426 Name: "Asinh", 427 Function: parser.Function{ 428 Name: "asinh", 429 }, 430 Args: []value.Primary{ 431 value.NewFloat(0), 432 }, 433 Result: value.NewFloat(0), 434 }, 435 } 436 437 func TestAsinh(t *testing.T) { 438 testFunction(t, Asinh, asinhTests) 439 } 440 441 var atanTests = []functionTest{ 442 { 443 Name: "Atan", 444 Function: parser.Function{ 445 Name: "atan", 446 }, 447 Args: []value.Primary{ 448 value.NewInteger(2), 449 }, 450 Result: value.NewFloat(1.1071487177940904), 451 }, 452 } 453 454 func TestAtan(t *testing.T) { 455 testFunction(t, Atan, atanTests) 456 } 457 458 var atan2Tests = []functionTest{ 459 { 460 Name: "Atan2", 461 Function: parser.Function{ 462 Name: "atan2", 463 }, 464 Args: []value.Primary{ 465 value.NewInteger(2), 466 value.NewInteger(2), 467 }, 468 Result: value.NewFloat(0.7853981633974483), 469 }, 470 } 471 472 func TestAtan2(t *testing.T) { 473 testFunction(t, Atan2, atan2Tests) 474 } 475 476 var atanhTests = []functionTest{ 477 { 478 Name: "Atanh", 479 Function: parser.Function{ 480 Name: "atanh", 481 }, 482 Args: []value.Primary{ 483 value.NewInteger(0), 484 }, 485 Result: value.NewFloat(0), 486 }, 487 } 488 489 func TestAtanh(t *testing.T) { 490 testFunction(t, Atanh, atanhTests) 491 } 492 493 var cbrtTests = []functionTest{ 494 { 495 Name: "Cbrt", 496 Function: parser.Function{ 497 Name: "cbrt", 498 }, 499 Args: []value.Primary{ 500 value.NewInteger(8), 501 }, 502 Result: value.NewFloat(2), 503 }, 504 } 505 506 func TestCbrt(t *testing.T) { 507 testFunction(t, Cbrt, cbrtTests) 508 } 509 510 var cosTests = []functionTest{ 511 { 512 Name: "Cos", 513 Function: parser.Function{ 514 Name: "cos", 515 }, 516 Args: []value.Primary{ 517 value.NewInteger(2), 518 }, 519 Result: value.NewFloat(-0.4161468365471424), 520 }, 521 } 522 523 func TestCos(t *testing.T) { 524 testFunction(t, Cos, cosTests) 525 } 526 527 var coshTests = []functionTest{ 528 { 529 Name: "Cosh", 530 Function: parser.Function{ 531 Name: "cosh", 532 }, 533 Args: []value.Primary{ 534 value.NewInteger(0), 535 }, 536 Result: value.NewFloat(1), 537 }, 538 } 539 540 func TestCosh(t *testing.T) { 541 testFunction(t, Cosh, coshTests) 542 } 543 544 var expTests = []functionTest{ 545 { 546 Name: "Exp", 547 Function: parser.Function{ 548 Name: "exp", 549 }, 550 Args: []value.Primary{ 551 value.NewInteger(2), 552 }, 553 Result: value.NewFloat(7.38905609893065), 554 }, 555 } 556 557 func TestExp(t *testing.T) { 558 testFunction(t, Exp, expTests) 559 } 560 561 var exp2Tests = []functionTest{ 562 { 563 Name: "Exp2", 564 Function: parser.Function{ 565 Name: "exp2", 566 }, 567 Args: []value.Primary{ 568 value.NewInteger(2), 569 }, 570 Result: value.NewFloat(4), 571 }, 572 } 573 574 func TestExp2(t *testing.T) { 575 testFunction(t, Exp2, exp2Tests) 576 } 577 578 var expm1Tests = []functionTest{ 579 { 580 Name: "Expm1", 581 Function: parser.Function{ 582 Name: "expm1", 583 }, 584 Args: []value.Primary{ 585 value.NewInteger(2), 586 }, 587 Result: value.NewFloat(6.38905609893065), 588 }, 589 } 590 591 func TestExpm1(t *testing.T) { 592 testFunction(t, Expm1, expm1Tests) 593 } 594 595 var isInfTests = []functionTest{ 596 { 597 Name: "IsInf", 598 Function: parser.Function{ 599 Name: "is_inf", 600 }, 601 Args: []value.Primary{ 602 value.NewFloat(math.Inf(1)), 603 }, 604 Result: value.NewTernary(ternary.TRUE), 605 }, 606 { 607 Name: "IsInf Not Inf", 608 Function: parser.Function{ 609 Name: "is_inf", 610 }, 611 Args: []value.Primary{ 612 value.NewFloat(-2.456), 613 }, 614 Result: value.NewTernary(ternary.FALSE), 615 }, 616 { 617 Name: "IsInf Not Float", 618 Function: parser.Function{ 619 Name: "is_inf", 620 }, 621 Args: []value.Primary{ 622 value.NewString("foo"), 623 }, 624 Result: value.NewTernary(ternary.FALSE), 625 }, 626 { 627 Name: "IsInf with Sign", 628 Function: parser.Function{ 629 Name: "is_inf", 630 }, 631 Args: []value.Primary{ 632 value.NewFloat(math.Inf(1)), 633 value.NewInteger(-1), 634 }, 635 Result: value.NewTernary(ternary.FALSE), 636 }, 637 { 638 Name: "IsInf Arguments Error", 639 Function: parser.Function{ 640 Name: "is_inf", 641 }, 642 Args: []value.Primary{}, 643 Error: "function is_inf takes 1 or 2 arguments", 644 }, 645 } 646 647 func TestIsInf(t *testing.T) { 648 testFunction(t, IsInf, isInfTests) 649 } 650 651 var isNanTests = []functionTest{ 652 { 653 Name: "IsNaN", 654 Function: parser.Function{ 655 Name: "is_nan", 656 }, 657 Args: []value.Primary{ 658 value.NewFloat(math.NaN()), 659 }, 660 Result: value.NewTernary(ternary.TRUE), 661 }, 662 { 663 Name: "IsNaN Not NaN", 664 Function: parser.Function{ 665 Name: "is_nan", 666 }, 667 Args: []value.Primary{ 668 value.NewFloat(-2.456), 669 }, 670 Result: value.NewTernary(ternary.FALSE), 671 }, 672 { 673 Name: "IsNaN Not Float", 674 Function: parser.Function{ 675 Name: "is_nan", 676 }, 677 Args: []value.Primary{ 678 value.NewString("foo"), 679 }, 680 Result: value.NewTernary(ternary.FALSE), 681 }, 682 { 683 Name: "IsNaN Arguments Error", 684 Function: parser.Function{ 685 Name: "is_nan", 686 }, 687 Args: []value.Primary{}, 688 Error: "function is_nan takes exactly 1 argument", 689 }, 690 } 691 692 func TestIsNaN(t *testing.T) { 693 testFunction(t, IsNaN, isNanTests) 694 } 695 696 var mathLogTests = []functionTest{ 697 { 698 Name: "MathLog", 699 Function: parser.Function{ 700 Name: "log", 701 }, 702 Args: []value.Primary{ 703 value.NewFloat(2), 704 }, 705 Result: value.NewFloat(0.6931471805599453), 706 }, 707 } 708 709 func TestMathLog(t *testing.T) { 710 testFunction(t, MathLog, mathLogTests) 711 } 712 713 var log10Tests = []functionTest{ 714 { 715 Name: "Log10", 716 Function: parser.Function{ 717 Name: "log10", 718 }, 719 Args: []value.Primary{ 720 value.NewFloat(100), 721 }, 722 Result: value.NewFloat(2), 723 }, 724 } 725 726 func TestLog10(t *testing.T) { 727 testFunction(t, Log10, log10Tests) 728 } 729 730 var log1pTests = []functionTest{ 731 { 732 Name: "Log1p", 733 Function: parser.Function{ 734 Name: "log1p", 735 }, 736 Args: []value.Primary{ 737 value.NewFloat(1), 738 }, 739 Result: value.NewFloat(0.6931471805599453), 740 }, 741 } 742 743 func TestLog1p(t *testing.T) { 744 testFunction(t, Log1p, log1pTests) 745 } 746 747 var log2Tests = []functionTest{ 748 { 749 Name: "Log2", 750 Function: parser.Function{ 751 Name: "log2", 752 }, 753 Args: []value.Primary{ 754 value.NewFloat(16), 755 }, 756 Result: value.NewFloat(4), 757 }, 758 } 759 760 func TestLog2(t *testing.T) { 761 testFunction(t, Log2, log2Tests) 762 } 763 764 var logbTests = []functionTest{ 765 { 766 Name: "Logb", 767 Function: parser.Function{ 768 Name: "logb", 769 }, 770 Args: []value.Primary{ 771 value.NewInteger(2), 772 }, 773 Result: value.NewFloat(1), 774 }, 775 } 776 777 func TestLogb(t *testing.T) { 778 testFunction(t, Logb, logbTests) 779 } 780 781 var powTests = []functionTest{ 782 { 783 Name: "Pow", 784 Function: parser.Function{ 785 Name: "pow", 786 }, 787 Args: []value.Primary{ 788 value.NewFloat(2), 789 value.NewFloat(2), 790 }, 791 Result: value.NewFloat(4), 792 }, 793 { 794 Name: "Pow First Argument is Null", 795 Function: parser.Function{ 796 Name: "pow", 797 }, 798 Args: []value.Primary{ 799 value.NewNull(), 800 value.NewFloat(2), 801 }, 802 Result: value.NewNull(), 803 }, 804 { 805 Name: "Pow Second Argument is Null", 806 Function: parser.Function{ 807 Name: "pow", 808 }, 809 Args: []value.Primary{ 810 value.NewFloat(2), 811 value.NewNull(), 812 }, 813 Result: value.NewNull(), 814 }, 815 { 816 Name: "Pow returns NaN", 817 Function: parser.Function{ 818 Name: "pow", 819 }, 820 Args: []value.Primary{ 821 value.NewFloat(-2), 822 value.NewFloat(2.4), 823 }, 824 Result: value.NewFloat(math.NaN()), 825 }, 826 { 827 Name: "Pow Arguments Error", 828 Function: parser.Function{ 829 Name: "pow", 830 }, 831 Args: []value.Primary{}, 832 Error: "function pow takes exactly 2 arguments", 833 }, 834 } 835 836 func TestPow(t *testing.T) { 837 testFunction(t, Pow, powTests) 838 } 839 840 var sinTests = []functionTest{ 841 { 842 Name: "Sin", 843 Function: parser.Function{ 844 Name: "sin", 845 }, 846 Args: []value.Primary{ 847 value.NewInteger(1), 848 }, 849 Result: value.NewFloat(0.8414709848078965), 850 }, 851 } 852 853 func TestSin(t *testing.T) { 854 testFunction(t, Sin, sinTests) 855 } 856 857 var sinhTests = []functionTest{ 858 { 859 Name: "Sinh", 860 Function: parser.Function{ 861 Name: "sinh", 862 }, 863 Args: []value.Primary{ 864 value.NewInteger(0), 865 }, 866 Result: value.NewFloat(0), 867 }, 868 } 869 870 func TestSinh(t *testing.T) { 871 testFunction(t, Sinh, sinhTests) 872 } 873 874 var sqrtTests = []functionTest{ 875 { 876 Name: "Sqrt", 877 Function: parser.Function{ 878 Name: "sqrt", 879 }, 880 Args: []value.Primary{ 881 value.NewFloat(4), 882 }, 883 Result: value.NewFloat(2), 884 }, 885 { 886 Name: "Sqrt returns NaN", 887 Function: parser.Function{ 888 Name: "sqrt", 889 }, 890 Args: []value.Primary{ 891 value.NewFloat(-4), 892 }, 893 Result: value.NewFloat(math.NaN()), 894 }, 895 } 896 897 func TestSqrt(t *testing.T) { 898 testFunction(t, Sqrt, sqrtTests) 899 } 900 901 var tanTests = []functionTest{ 902 { 903 Name: "Tan", 904 Function: parser.Function{ 905 Name: "tan", 906 }, 907 Args: []value.Primary{ 908 value.NewInteger(2), 909 }, 910 Result: value.NewFloat(-2.185039863261519), 911 }, 912 } 913 914 func TestTan(t *testing.T) { 915 testFunction(t, Tan, tanTests) 916 } 917 918 var tanhTests = []functionTest{ 919 { 920 Name: "Tanh", 921 Function: parser.Function{ 922 Name: "tanh", 923 }, 924 Args: []value.Primary{ 925 value.NewInteger(0), 926 }, 927 Result: value.NewFloat(0), 928 }, 929 } 930 931 func TestTanh(t *testing.T) { 932 testFunction(t, Tanh, tanhTests) 933 } 934 935 var binToDecTests = []functionTest{ 936 { 937 Name: "BinToDec", 938 Function: parser.Function{ 939 Name: "bin_to_dec", 940 }, 941 Args: []value.Primary{ 942 value.NewString("1111011"), 943 }, 944 Result: value.NewInteger(123), 945 }, 946 { 947 Name: "BinToDec Null", 948 Function: parser.Function{ 949 Name: "bin_to_dec", 950 }, 951 Args: []value.Primary{ 952 value.NewNull(), 953 }, 954 Result: value.NewNull(), 955 }, 956 { 957 Name: "BinToDec Parse Error", 958 Function: parser.Function{ 959 Name: "bin_to_dec", 960 }, 961 Args: []value.Primary{ 962 value.NewString("string"), 963 }, 964 Result: value.NewNull(), 965 }, 966 { 967 Name: "BinToDec Arguments Error", 968 Function: parser.Function{ 969 Name: "bin_to_dec", 970 }, 971 Args: []value.Primary{}, 972 Error: "function bin_to_dec takes exactly 1 argument", 973 }, 974 } 975 976 func TestBinToDec(t *testing.T) { 977 testFunction(t, BinToDec, binToDecTests) 978 } 979 980 var octToDecTests = []functionTest{ 981 { 982 Name: "OctToDec", 983 Function: parser.Function{ 984 Name: "oct_to_dec", 985 }, 986 Args: []value.Primary{ 987 value.NewString("0173"), 988 }, 989 Result: value.NewInteger(123), 990 }, 991 } 992 993 func TestOctToDec(t *testing.T) { 994 testFunction(t, OctToDec, octToDecTests) 995 } 996 997 var hexToDecTests = []functionTest{ 998 { 999 Name: "HexToDec", 1000 Function: parser.Function{ 1001 Name: "hex_to_dec", 1002 }, 1003 Args: []value.Primary{ 1004 value.NewString("0x7b"), 1005 }, 1006 Result: value.NewInteger(123), 1007 }, 1008 } 1009 1010 func TestHexToDec(t *testing.T) { 1011 testFunction(t, HexToDec, hexToDecTests) 1012 } 1013 1014 var enotationToDecTests = []functionTest{ 1015 { 1016 Name: "EnotationToDec", 1017 Function: parser.Function{ 1018 Name: "enotation_to_dec", 1019 }, 1020 Args: []value.Primary{ 1021 value.NewString("1.23e-11"), 1022 }, 1023 Result: value.NewFloat(0.0000000000123), 1024 }, 1025 { 1026 Name: "EnotationToDec To Integer", 1027 Function: parser.Function{ 1028 Name: "enotation_to_dec", 1029 }, 1030 Args: []value.Primary{ 1031 value.NewString("1.23e+12"), 1032 }, 1033 Result: value.NewFloat(1230000000000), 1034 }, 1035 { 1036 Name: "EnotationToDec Null", 1037 Function: parser.Function{ 1038 Name: "enotation_to_dec", 1039 }, 1040 Args: []value.Primary{ 1041 value.NewNull(), 1042 }, 1043 Result: value.NewNull(), 1044 }, 1045 { 1046 Name: "EnotationToDec Parse Error", 1047 Function: parser.Function{ 1048 Name: "enotation_to_dec", 1049 }, 1050 Args: []value.Primary{ 1051 value.NewString("string"), 1052 }, 1053 Result: value.NewNull(), 1054 }, 1055 { 1056 Name: "EnotationToDec Arguments Error", 1057 Function: parser.Function{ 1058 Name: "enotation_to_dec", 1059 }, 1060 Args: []value.Primary{}, 1061 Error: "function enotation_to_dec takes exactly 1 argument", 1062 }, 1063 } 1064 1065 func TestEnotationToDec(t *testing.T) { 1066 testFunction(t, EnotationToDec, enotationToDecTests) 1067 } 1068 1069 var binTests = []functionTest{ 1070 { 1071 Name: "Bin", 1072 Function: parser.Function{ 1073 Name: "bin", 1074 }, 1075 Args: []value.Primary{ 1076 value.NewInteger(123), 1077 }, 1078 Result: value.NewString("1111011"), 1079 }, 1080 { 1081 Name: "Bin Null", 1082 Function: parser.Function{ 1083 Name: "bin", 1084 }, 1085 Args: []value.Primary{ 1086 value.NewNull(), 1087 }, 1088 Result: value.NewNull(), 1089 }, 1090 { 1091 Name: "Bin Arguments Error", 1092 Function: parser.Function{ 1093 Name: "bin", 1094 }, 1095 Args: []value.Primary{}, 1096 Error: "function bin takes exactly 1 argument", 1097 }, 1098 } 1099 1100 func TestBin(t *testing.T) { 1101 testFunction(t, Bin, binTests) 1102 } 1103 1104 var octTests = []functionTest{ 1105 { 1106 Name: "Oct", 1107 Function: parser.Function{ 1108 Name: "oct", 1109 }, 1110 Args: []value.Primary{ 1111 value.NewInteger(123), 1112 }, 1113 Result: value.NewString("173"), 1114 }, 1115 } 1116 1117 func TestOct(t *testing.T) { 1118 testFunction(t, Oct, octTests) 1119 } 1120 1121 var hexTests = []functionTest{ 1122 { 1123 Name: "Hex", 1124 Function: parser.Function{ 1125 Name: "hex", 1126 }, 1127 Args: []value.Primary{ 1128 value.NewInteger(123), 1129 }, 1130 Result: value.NewString("7b"), 1131 }, 1132 } 1133 1134 func TestHex(t *testing.T) { 1135 testFunction(t, Hex, hexTests) 1136 } 1137 1138 var enotationTests = []functionTest{ 1139 { 1140 Name: "Enotation", 1141 Function: parser.Function{ 1142 Name: "enotation", 1143 }, 1144 Args: []value.Primary{ 1145 value.NewFloat(0.0000000000123), 1146 }, 1147 Result: value.NewString("1.23e-11"), 1148 }, 1149 { 1150 Name: "Enotation From Integer", 1151 Function: parser.Function{ 1152 Name: "enotation", 1153 }, 1154 Args: []value.Primary{ 1155 value.NewInteger(1230000000000), 1156 }, 1157 Result: value.NewString("1.23e+12"), 1158 }, 1159 { 1160 Name: "Enotation Null", 1161 Function: parser.Function{ 1162 Name: "enotation", 1163 }, 1164 Args: []value.Primary{ 1165 value.NewNull(), 1166 }, 1167 Result: value.NewNull(), 1168 }, 1169 { 1170 Name: "Enotation Arguments Error", 1171 Function: parser.Function{ 1172 Name: "enotation", 1173 }, 1174 Args: []value.Primary{}, 1175 Error: "function enotation takes exactly 1 argument", 1176 }, 1177 } 1178 1179 func TestEnotation(t *testing.T) { 1180 testFunction(t, Enotation, enotationTests) 1181 } 1182 1183 var numberFormatTests = []functionTest{ 1184 { 1185 Name: "NumberFormat", 1186 Function: parser.Function{ 1187 Name: "number_format", 1188 }, 1189 Args: []value.Primary{ 1190 value.NewFloat(123456.789123), 1191 value.NewInteger(4), 1192 value.NewString(","), 1193 value.NewString(" "), 1194 value.NewString(" "), 1195 }, 1196 Result: value.NewString("123 456,789 1"), 1197 }, 1198 { 1199 Name: "NumberFormat Null", 1200 Function: parser.Function{ 1201 Name: "number_format", 1202 }, 1203 Args: []value.Primary{ 1204 value.NewNull(), 1205 }, 1206 Result: value.NewNull(), 1207 }, 1208 { 1209 Name: "NumberFormat Arguments Errlr", 1210 Function: parser.Function{ 1211 Name: "number_format", 1212 }, 1213 Args: []value.Primary{}, 1214 Error: "function number_format takes 1 to 5 arguments", 1215 }, 1216 } 1217 1218 func TestNumberFormat(t *testing.T) { 1219 testFunction(t, NumberFormat, numberFormatTests) 1220 } 1221 1222 var randTests = []struct { 1223 Name string 1224 Function parser.Function 1225 Args []value.Primary 1226 RangeLow float64 1227 RangeHigh float64 1228 Error string 1229 }{ 1230 { 1231 Name: "Rand", 1232 Function: parser.Function{ 1233 Name: "rand", 1234 }, 1235 RangeLow: 0.0, 1236 RangeHigh: 1.0, 1237 }, 1238 { 1239 Name: "Rand Range Specified", 1240 Function: parser.Function{ 1241 Name: "rand", 1242 }, 1243 Args: []value.Primary{ 1244 value.NewInteger(7), 1245 value.NewInteger(12), 1246 }, 1247 RangeLow: 7.0, 1248 RangeHigh: 12.0, 1249 }, 1250 { 1251 Name: "Range Arguments Error", 1252 Function: parser.Function{ 1253 Name: "rand", 1254 }, 1255 Args: []value.Primary{ 1256 value.NewInteger(1), 1257 }, 1258 Error: "function rand takes 0 or 2 arguments", 1259 }, 1260 { 1261 Name: "Range First Arguments Error", 1262 Function: parser.Function{ 1263 Name: "rand", 1264 }, 1265 Args: []value.Primary{ 1266 value.NewString("a"), 1267 value.NewInteger(2), 1268 }, 1269 Error: "the first argument must be an integer for function rand", 1270 }, 1271 { 1272 Name: "Range Second Arguments Error", 1273 Function: parser.Function{ 1274 Name: "rand", 1275 }, 1276 Args: []value.Primary{ 1277 value.NewInteger(1), 1278 value.NewString("a"), 1279 }, 1280 Error: "the second argument must be an integer for function rand", 1281 }, 1282 { 1283 Name: "Range Arguments Value Error", 1284 Function: parser.Function{ 1285 Name: "rand", 1286 }, 1287 Args: []value.Primary{ 1288 value.NewInteger(1), 1289 value.NewInteger(1), 1290 }, 1291 Error: "the second argument must be greater than the first argument for function rand", 1292 }, 1293 } 1294 1295 func TestRand(t *testing.T) { 1296 for _, v := range randTests { 1297 result, err := Rand(v.Function, v.Args, TestTx.Flags) 1298 if err != nil { 1299 if len(v.Error) < 1 { 1300 t.Errorf("%s: unexpected error %q", v.Name, err) 1301 } else if err.Error() != v.Error { 1302 t.Errorf("%s: error %q, want error %q", v.Name, err.Error(), v.Error) 1303 } 1304 continue 1305 } 1306 if 0 < len(v.Error) { 1307 t.Errorf("%s: no error, want error %q", v.Name, v.Error) 1308 continue 1309 } 1310 1311 var f float64 1312 if len(v.Args) < 1 { 1313 f = result.(*value.Float).Raw() 1314 } else { 1315 f = float64(result.(*value.Integer).Raw()) 1316 } 1317 1318 if f < v.RangeLow || v.RangeHigh < f { 1319 t.Errorf("%s: result = %f, want in range from %f to %f", v.Name, f, v.RangeLow, v.RangeHigh) 1320 } 1321 } 1322 } 1323 1324 var trimTests = []functionTest{ 1325 { 1326 Name: "Trim", 1327 Function: parser.Function{ 1328 Name: "trim", 1329 }, 1330 Args: []value.Primary{ 1331 value.NewString("aabbfoo, baraabb"), 1332 value.NewString("ab"), 1333 }, 1334 Result: value.NewString("foo, bar"), 1335 }, 1336 { 1337 Name: "Trim Spaces", 1338 Function: parser.Function{ 1339 Name: "trim", 1340 }, 1341 Args: []value.Primary{ 1342 value.NewString(" foo, bar \n"), 1343 }, 1344 Result: value.NewString("foo, bar"), 1345 }, 1346 { 1347 Name: "Trim Null", 1348 Function: parser.Function{ 1349 Name: "trim", 1350 }, 1351 Args: []value.Primary{ 1352 value.NewNull(), 1353 value.NewString("ab"), 1354 }, 1355 Result: value.NewNull(), 1356 }, 1357 { 1358 Name: "Trim Cutset is Null", 1359 Function: parser.Function{ 1360 Name: "trim", 1361 }, 1362 Args: []value.Primary{ 1363 value.NewString("aabbfoo, baraabb"), 1364 value.NewNull(), 1365 }, 1366 Result: value.NewNull(), 1367 }, 1368 { 1369 Name: "Trim Arguments Error", 1370 Function: parser.Function{ 1371 Name: "trim", 1372 }, 1373 Args: []value.Primary{}, 1374 Error: "function trim takes 1 or 2 arguments", 1375 }, 1376 } 1377 1378 func TestTrim(t *testing.T) { 1379 testFunction(t, Trim, trimTests) 1380 } 1381 1382 var ltrimTests = []functionTest{ 1383 { 1384 Name: "Ltrim", 1385 Function: parser.Function{ 1386 Name: "ltrim", 1387 }, 1388 Args: []value.Primary{ 1389 value.NewString("aabbfoo, baraabb"), 1390 value.NewString("ab"), 1391 }, 1392 Result: value.NewString("foo, baraabb"), 1393 }, 1394 { 1395 Name: "Ltrim Spaces", 1396 Function: parser.Function{ 1397 Name: "ltrim", 1398 }, 1399 Args: []value.Primary{ 1400 value.NewString(" foo, bar \n"), 1401 }, 1402 Result: value.NewString("foo, bar \n"), 1403 }, 1404 } 1405 1406 func TestLtrim(t *testing.T) { 1407 testFunction(t, Ltrim, ltrimTests) 1408 } 1409 1410 var rtrimTests = []functionTest{ 1411 { 1412 Name: "Rtrim", 1413 Function: parser.Function{ 1414 Name: "rtrim", 1415 }, 1416 Args: []value.Primary{ 1417 value.NewString("aabbfoo, baraabb"), 1418 value.NewString("ab"), 1419 }, 1420 Result: value.NewString("aabbfoo, bar"), 1421 }, 1422 { 1423 Name: "Rtrim Spaces", 1424 Function: parser.Function{ 1425 Name: "rtrim", 1426 }, 1427 Args: []value.Primary{ 1428 value.NewString(" foo, bar \n"), 1429 }, 1430 Result: value.NewString(" foo, bar"), 1431 }, 1432 } 1433 1434 func TestRtrim(t *testing.T) { 1435 testFunction(t, Rtrim, rtrimTests) 1436 } 1437 1438 var upperTests = []functionTest{ 1439 { 1440 Name: "Upper", 1441 Function: parser.Function{ 1442 Name: "upper", 1443 }, 1444 Args: []value.Primary{ 1445 value.NewString("Foo"), 1446 }, 1447 Result: value.NewString("FOO"), 1448 }, 1449 { 1450 Name: "Upper Null", 1451 Function: parser.Function{ 1452 Name: "upper", 1453 }, 1454 Args: []value.Primary{ 1455 value.NewNull(), 1456 }, 1457 Result: value.NewNull(), 1458 }, 1459 { 1460 Name: "Upper Arguments Error", 1461 Function: parser.Function{ 1462 Name: "upper", 1463 }, 1464 Args: []value.Primary{}, 1465 Error: "function upper takes exactly 1 argument", 1466 }, 1467 } 1468 1469 func TestUpper(t *testing.T) { 1470 testFunction(t, Upper, upperTests) 1471 } 1472 1473 var lowerTests = []functionTest{ 1474 { 1475 Name: "Lower", 1476 Function: parser.Function{ 1477 Name: "lower", 1478 }, 1479 Args: []value.Primary{ 1480 value.NewString("Foo"), 1481 }, 1482 Result: value.NewString("foo"), 1483 }, 1484 } 1485 1486 func TestLower(t *testing.T) { 1487 testFunction(t, Lower, lowerTests) 1488 } 1489 1490 var base64EncodeTests = []functionTest{ 1491 { 1492 Name: "Base64Encode", 1493 Function: parser.Function{ 1494 Name: "base64_encode", 1495 }, 1496 Args: []value.Primary{ 1497 value.NewString("Foo"), 1498 }, 1499 Result: value.NewString("Rm9v"), 1500 }, 1501 } 1502 1503 func TestBase64Encode(t *testing.T) { 1504 testFunction(t, Base64Encode, base64EncodeTests) 1505 } 1506 1507 var base64DecodeTests = []functionTest{ 1508 { 1509 Name: "Base64Decode", 1510 Function: parser.Function{ 1511 Name: "base64_decode", 1512 }, 1513 Args: []value.Primary{ 1514 value.NewString("Rm9v"), 1515 }, 1516 Result: value.NewString("Foo"), 1517 }, 1518 } 1519 1520 func TestBase64Decode(t *testing.T) { 1521 testFunction(t, Base64Decode, base64DecodeTests) 1522 } 1523 1524 var hexEncodeTests = []functionTest{ 1525 { 1526 Name: "HexEncode", 1527 Function: parser.Function{ 1528 Name: "hex_encode", 1529 }, 1530 Args: []value.Primary{ 1531 value.NewString("Foo"), 1532 }, 1533 Result: value.NewString("466f6f"), 1534 }, 1535 } 1536 1537 func TestHexEncode(t *testing.T) { 1538 testFunction(t, HexEncode, hexEncodeTests) 1539 } 1540 1541 var hexDecodeTests = []functionTest{ 1542 { 1543 Name: "HexDecode", 1544 Function: parser.Function{ 1545 Name: "hex_decode", 1546 }, 1547 Args: []value.Primary{ 1548 value.NewString("466f6f"), 1549 }, 1550 Result: value.NewString("Foo"), 1551 }, 1552 } 1553 1554 func TestHexDecode(t *testing.T) { 1555 testFunction(t, HexDecode, hexDecodeTests) 1556 } 1557 1558 var lenTests = []functionTest{ 1559 { 1560 Name: "Len", 1561 Function: parser.Function{ 1562 Name: "len", 1563 }, 1564 Args: []value.Primary{ 1565 value.NewString("日本語"), 1566 }, 1567 Result: value.NewInteger(3), 1568 }, 1569 { 1570 Name: "Len Null", 1571 Function: parser.Function{ 1572 Name: "len", 1573 }, 1574 Args: []value.Primary{ 1575 value.NewNull(), 1576 }, 1577 Result: value.NewNull(), 1578 }, 1579 { 1580 Name: "Len Arguments Error", 1581 Function: parser.Function{ 1582 Name: "len", 1583 }, 1584 Args: []value.Primary{}, 1585 Error: "function len takes exactly 1 argument", 1586 }, 1587 } 1588 1589 func TestLen(t *testing.T) { 1590 testFunction(t, Len, lenTests) 1591 } 1592 1593 var byteLenTests = []functionTest{ 1594 { 1595 Name: "ByteLen", 1596 Function: parser.Function{ 1597 Name: "byte_len", 1598 }, 1599 Args: []value.Primary{ 1600 value.NewString("abc日本語"), 1601 }, 1602 Result: value.NewInteger(12), 1603 }, 1604 { 1605 Name: "ByteLen SJIS", 1606 Function: parser.Function{ 1607 Name: "byte_len", 1608 }, 1609 Args: []value.Primary{ 1610 value.NewString("abc日本語"), 1611 value.NewString("sjis"), 1612 }, 1613 Result: value.NewInteger(9), 1614 }, 1615 { 1616 Name: "ByteLen Null", 1617 Function: parser.Function{ 1618 Name: "byte_len", 1619 }, 1620 Args: []value.Primary{ 1621 value.NewNull(), 1622 }, 1623 Result: value.NewNull(), 1624 }, 1625 { 1626 Name: "ByteLen Arguments Error", 1627 Function: parser.Function{ 1628 Name: "byte_len", 1629 }, 1630 Args: []value.Primary{}, 1631 Error: "function byte_len takes 1 or 2 arguments", 1632 }, 1633 { 1634 Name: "ByteLen Invalid Encoding Error", 1635 Function: parser.Function{ 1636 Name: "byte_len", 1637 }, 1638 Args: []value.Primary{ 1639 value.NewString("abc日本語"), 1640 value.NewString("invalid"), 1641 }, 1642 Error: "encoding must be one of UTF8|UTF16|SJIS for function byte_len", 1643 }, 1644 } 1645 1646 func TestByteLen(t *testing.T) { 1647 testFunction(t, ByteLen, byteLenTests) 1648 } 1649 1650 var widthTests = []functionTest{ 1651 { 1652 Name: "Width", 1653 Function: parser.Function{ 1654 Name: "width", 1655 }, 1656 Args: []value.Primary{ 1657 value.NewString("abc日本語"), 1658 }, 1659 Result: value.NewInteger(9), 1660 }, 1661 { 1662 Name: "Width Arguments Is Null", 1663 Function: parser.Function{ 1664 Name: "width", 1665 }, 1666 Args: []value.Primary{ 1667 value.NewNull(), 1668 }, 1669 Result: value.NewNull(), 1670 }, 1671 { 1672 Name: "Width Arguments Error", 1673 Function: parser.Function{ 1674 Name: "width", 1675 }, 1676 Args: []value.Primary{}, 1677 Error: "function width takes exactly 1 argument", 1678 }, 1679 } 1680 1681 func TestWidth(t *testing.T) { 1682 testFunction(t, Width, widthTests) 1683 } 1684 1685 var lpadTests = []functionTest{ 1686 { 1687 Name: "Lpad", 1688 Function: parser.Function{ 1689 Name: "lpad", 1690 }, 1691 Args: []value.Primary{ 1692 value.NewString("aaaaa"), 1693 value.NewInteger(10), 1694 value.NewString("01"), 1695 }, 1696 Result: value.NewString("01010aaaaa"), 1697 }, 1698 { 1699 Name: "Lpad by Byte Length", 1700 Function: parser.Function{ 1701 Name: "lpad", 1702 }, 1703 Args: []value.Primary{ 1704 value.NewString("日本語"), 1705 value.NewInteger(12), 1706 value.NewString("空白"), 1707 value.NewString("byte"), 1708 value.NewString("sjis"), 1709 }, 1710 Result: value.NewString("空白空日本語"), 1711 }, 1712 { 1713 Name: "Lpad by Byte Length Error", 1714 Function: parser.Function{ 1715 Name: "lpad", 1716 }, 1717 Args: []value.Primary{ 1718 value.NewString("日本語"), 1719 value.NewInteger(11), 1720 value.NewString("空白"), 1721 value.NewString("byte"), 1722 value.NewString("sjis"), 1723 }, 1724 Error: "cannot split pad string in a byte array of a character for function lpad", 1725 }, 1726 { 1727 Name: "Lpad PadType Error", 1728 Function: parser.Function{ 1729 Name: "lpad", 1730 }, 1731 Args: []value.Primary{ 1732 value.NewString("日本語"), 1733 value.NewInteger(11), 1734 value.NewString("空白"), 1735 value.NewString("invalid"), 1736 }, 1737 Error: "padding type must be one of LEN|BYTE|WIDTH for function lpad", 1738 }, 1739 { 1740 Name: "Lpad Encoding Error", 1741 Function: parser.Function{ 1742 Name: "lpad", 1743 }, 1744 Args: []value.Primary{ 1745 value.NewString("日本語"), 1746 value.NewInteger(11), 1747 value.NewString("空白"), 1748 value.NewString("byte"), 1749 value.NewString("invalid"), 1750 }, 1751 Error: "encoding must be one of UTF8|UTF16|SJIS for function lpad", 1752 }, 1753 { 1754 Name: "Lpad by Width", 1755 Function: parser.Function{ 1756 Name: "lpad", 1757 }, 1758 Args: []value.Primary{ 1759 value.NewString("日本語"), 1760 value.NewInteger(12), 1761 value.NewString("空白"), 1762 value.NewString("width"), 1763 }, 1764 Result: value.NewString("空白空日本語"), 1765 }, 1766 { 1767 Name: "Lpad by Width Length Error", 1768 Function: parser.Function{ 1769 Name: "lpad", 1770 }, 1771 Args: []value.Primary{ 1772 value.NewString("日本語"), 1773 value.NewInteger(11), 1774 value.NewString("空白"), 1775 value.NewString("width"), 1776 }, 1777 Error: "cannot split pad string in a byte array of a character for function lpad", 1778 }, 1779 { 1780 Name: "Lpad No Padding", 1781 Function: parser.Function{ 1782 Name: "lpad", 1783 }, 1784 Args: []value.Primary{ 1785 value.NewString("aaaaa"), 1786 value.NewInteger(5), 1787 value.NewString("01"), 1788 }, 1789 Result: value.NewString("aaaaa"), 1790 }, 1791 { 1792 Name: "Lpad String is Null", 1793 Function: parser.Function{ 1794 Name: "lpad", 1795 }, 1796 Args: []value.Primary{ 1797 value.NewNull(), 1798 value.NewInteger(10), 1799 value.NewString("01"), 1800 }, 1801 Result: value.NewNull(), 1802 }, 1803 { 1804 Name: "Lpad Length is Null", 1805 Function: parser.Function{ 1806 Name: "lpad", 1807 }, 1808 Args: []value.Primary{ 1809 value.NewString("aaaaa"), 1810 value.NewNull(), 1811 value.NewString("01"), 1812 }, 1813 Result: value.NewNull(), 1814 }, 1815 { 1816 Name: "Lpad Pad String is Null", 1817 Function: parser.Function{ 1818 Name: "lpad", 1819 }, 1820 Args: []value.Primary{ 1821 value.NewString("aaaaa"), 1822 value.NewInteger(10), 1823 value.NewNull(), 1824 }, 1825 Result: value.NewNull(), 1826 }, 1827 { 1828 Name: "Lpad Arguments Error", 1829 Function: parser.Function{ 1830 Name: "lpad", 1831 }, 1832 Args: []value.Primary{}, 1833 Error: "function lpad takes 3 to 5 arguments", 1834 }, 1835 } 1836 1837 func TestLpad(t *testing.T) { 1838 testFunction(t, Lpad, lpadTests) 1839 } 1840 1841 var rpadTests = []functionTest{ 1842 { 1843 Name: "Rpad", 1844 Function: parser.Function{ 1845 Name: "rpad", 1846 }, 1847 Args: []value.Primary{ 1848 value.NewString("aaaaa"), 1849 value.NewInteger(10), 1850 value.NewString("01"), 1851 }, 1852 Result: value.NewString("aaaaa01010"), 1853 }, 1854 } 1855 1856 func TestRpad(t *testing.T) { 1857 testFunction(t, Rpad, rpadTests) 1858 } 1859 1860 var substringTests = []functionTest{ 1861 { 1862 Name: "Substring with a positive argument", 1863 Function: parser.Function{ 1864 Name: "substring", 1865 }, 1866 Args: []value.Primary{ 1867 value.NewString("abcdefghijklmn"), 1868 value.NewInteger(5), 1869 }, 1870 Result: value.NewString("efghijklmn"), 1871 }, 1872 { 1873 Name: "Substring with a negative argument", 1874 Function: parser.Function{ 1875 Name: "substring", 1876 }, 1877 Args: []value.Primary{ 1878 value.NewString("abcdefghijklmn"), 1879 value.NewInteger(-5), 1880 }, 1881 Result: value.NewString("jklmn"), 1882 }, 1883 { 1884 Name: "Substring with two positive argument", 1885 Function: parser.Function{ 1886 Name: "substring", 1887 }, 1888 Args: []value.Primary{ 1889 value.NewString("abcdefghijklmn"), 1890 value.NewInteger(5), 1891 value.NewInteger(3), 1892 }, 1893 Result: value.NewString("efg"), 1894 }, 1895 { 1896 Name: "Substring starting with zero", 1897 Function: parser.Function{ 1898 Name: "substring", 1899 }, 1900 Args: []value.Primary{ 1901 value.NewString("abcdefghijklmn"), 1902 value.NewInteger(0), 1903 value.NewInteger(3), 1904 }, 1905 Result: value.NewString("abc"), 1906 }, 1907 { 1908 Name: "Substring", 1909 Function: parser.Function{ 1910 Name: "substring", 1911 }, 1912 Args: []value.Primary{ 1913 value.NewString("abcdefghijklmn"), 1914 value.NewInteger(-5), 1915 value.NewInteger(8), 1916 }, 1917 Result: value.NewString("jklmn"), 1918 }, 1919 { 1920 Name: "Substring String is Null", 1921 Function: parser.Function{ 1922 Name: "substring", 1923 }, 1924 Args: []value.Primary{ 1925 value.NewNull(), 1926 value.NewInteger(-5), 1927 value.NewInteger(8), 1928 }, 1929 Result: value.NewNull(), 1930 }, 1931 { 1932 Name: "Substring StartIndex is Null", 1933 Function: parser.Function{ 1934 Name: "substring", 1935 }, 1936 Args: []value.Primary{ 1937 value.NewString("abcdefghijklmn"), 1938 value.NewNull(), 1939 }, 1940 Result: value.NewNull(), 1941 }, 1942 { 1943 Name: "Substring Length is Null", 1944 Function: parser.Function{ 1945 Name: "substring", 1946 }, 1947 Args: []value.Primary{ 1948 value.NewString("abcdefghijklmn"), 1949 value.NewInteger(-5), 1950 value.NewNull(), 1951 }, 1952 Result: value.NewNull(), 1953 }, 1954 { 1955 Name: "Substring Length is Negative", 1956 Function: parser.Function{ 1957 Name: "substring", 1958 }, 1959 Args: []value.Primary{ 1960 value.NewString("abcdefghijklmn"), 1961 value.NewInteger(-5), 1962 value.NewInteger(-1), 1963 }, 1964 Result: value.NewNull(), 1965 }, 1966 { 1967 Name: "Substring StartIndex is Out Of Index", 1968 Function: parser.Function{ 1969 Name: "substring", 1970 }, 1971 Args: []value.Primary{ 1972 value.NewString("abcdefghijklmn"), 1973 value.NewInteger(100), 1974 value.NewInteger(8), 1975 }, 1976 Result: value.NewNull(), 1977 }, 1978 { 1979 Name: "Substring Arguments Error", 1980 Function: parser.Function{ 1981 Name: "substring", 1982 }, 1983 Args: []value.Primary{}, 1984 Error: "function substring takes 2 or 3 arguments", 1985 }, 1986 } 1987 1988 func TestSubstring(t *testing.T) { 1989 testFunction(t, Substring, substringTests) 1990 } 1991 1992 var substrTests = []functionTest{ 1993 { 1994 Name: "Substr with a positive argument", 1995 Function: parser.Function{ 1996 Name: "substr", 1997 }, 1998 Args: []value.Primary{ 1999 value.NewString("abcdefghijklmn"), 2000 value.NewInteger(5), 2001 }, 2002 Result: value.NewString("fghijklmn"), 2003 }, 2004 { 2005 Name: "Substr with a negative argument", 2006 Function: parser.Function{ 2007 Name: "substr", 2008 }, 2009 Args: []value.Primary{ 2010 value.NewString("abcdefghijklmn"), 2011 value.NewInteger(-5), 2012 }, 2013 Result: value.NewString("jklmn"), 2014 }, 2015 { 2016 Name: "Substr with two positive argument", 2017 Function: parser.Function{ 2018 Name: "substr", 2019 }, 2020 Args: []value.Primary{ 2021 value.NewString("abcdefghijklmn"), 2022 value.NewInteger(5), 2023 value.NewInteger(3), 2024 }, 2025 Result: value.NewString("fgh"), 2026 }, 2027 } 2028 2029 func TestSubstr(t *testing.T) { 2030 testFunction(t, Substr, substrTests) 2031 } 2032 2033 var instrTests = []functionTest{ 2034 { 2035 Name: "Instr", 2036 Function: parser.Function{ 2037 Name: "instr", 2038 }, 2039 Args: []value.Primary{ 2040 value.NewString("abcdefghijklmn"), 2041 value.NewString("def"), 2042 }, 2043 Result: value.NewInteger(3), 2044 }, 2045 { 2046 Name: "Instr String is Null", 2047 Function: parser.Function{ 2048 Name: "instr", 2049 }, 2050 Args: []value.Primary{ 2051 value.NewNull(), 2052 value.NewString("def"), 2053 }, 2054 Result: value.NewNull(), 2055 }, 2056 { 2057 Name: "Instr Substring is Null", 2058 Function: parser.Function{ 2059 Name: "instr", 2060 }, 2061 Args: []value.Primary{ 2062 value.NewString("abcdefghijklmn"), 2063 value.NewNull(), 2064 }, 2065 Result: value.NewNull(), 2066 }, 2067 { 2068 Name: "Instr Substring does not exist", 2069 Function: parser.Function{ 2070 Name: "instr", 2071 }, 2072 Args: []value.Primary{ 2073 value.NewString("abcdefghijklmn"), 2074 value.NewString("zzz"), 2075 }, 2076 Result: value.NewNull(), 2077 }, 2078 { 2079 Name: "Instr Arguments Error", 2080 Function: parser.Function{ 2081 Name: "instr", 2082 }, 2083 Args: []value.Primary{}, 2084 Error: "function instr takes exactly 2 arguments", 2085 }, 2086 } 2087 2088 func TestInstr(t *testing.T) { 2089 testFunction(t, Instr, instrTests) 2090 } 2091 2092 var listElemTests = []functionTest{ 2093 { 2094 Name: "ListElem", 2095 Function: parser.Function{ 2096 Name: "list_elem", 2097 }, 2098 Args: []value.Primary{ 2099 value.NewString("abc def ghi"), 2100 value.NewString(" "), 2101 value.NewInteger(1), 2102 }, 2103 Result: value.NewString("def"), 2104 }, 2105 { 2106 Name: "ListElem String is Null", 2107 Function: parser.Function{ 2108 Name: "list_elem", 2109 }, 2110 Args: []value.Primary{ 2111 value.NewNull(), 2112 value.NewString(" "), 2113 value.NewInteger(1), 2114 }, 2115 Result: value.NewNull(), 2116 }, 2117 { 2118 Name: "ListElem Separator is Null", 2119 Function: parser.Function{ 2120 Name: "list_elem", 2121 }, 2122 Args: []value.Primary{ 2123 value.NewString("abc def ghi"), 2124 value.NewNull(), 2125 value.NewInteger(1), 2126 }, 2127 Result: value.NewNull(), 2128 }, 2129 { 2130 Name: "ListElem Index is Null", 2131 Function: parser.Function{ 2132 Name: "list_elem", 2133 }, 2134 Args: []value.Primary{ 2135 value.NewString("abc def ghi"), 2136 value.NewString(" "), 2137 value.NewNull(), 2138 }, 2139 Result: value.NewNull(), 2140 }, 2141 { 2142 Name: "ListElem Index is negative value", 2143 Function: parser.Function{ 2144 Name: "list_elem", 2145 }, 2146 Args: []value.Primary{ 2147 value.NewString("abc def ghi"), 2148 value.NewString(" "), 2149 value.NewInteger(-1), 2150 }, 2151 Result: value.NewNull(), 2152 }, 2153 { 2154 Name: "ListElem Index does not exist", 2155 Function: parser.Function{ 2156 Name: "list_elem", 2157 }, 2158 Args: []value.Primary{ 2159 value.NewString("abc def ghi"), 2160 value.NewString(" "), 2161 value.NewInteger(100), 2162 }, 2163 Result: value.NewNull(), 2164 }, 2165 { 2166 Name: "ListElem Arguments Error", 2167 Function: parser.Function{ 2168 Name: "list_elem", 2169 }, 2170 Args: []value.Primary{}, 2171 Error: "function list_elem takes exactly 3 arguments", 2172 }, 2173 } 2174 2175 func TestListElem(t *testing.T) { 2176 testFunction(t, ListElem, listElemTests) 2177 } 2178 2179 var replaceFnTests = []functionTest{ 2180 { 2181 Name: "Replace", 2182 Function: parser.Function{ 2183 Name: "replace", 2184 }, 2185 Args: []value.Primary{ 2186 value.NewString("abcdefg abcdefg"), 2187 value.NewString("cd"), 2188 value.NewString("CD"), 2189 }, 2190 Result: value.NewString("abCDefg abCDefg"), 2191 }, 2192 { 2193 Name: "Replace String is Null", 2194 Function: parser.Function{ 2195 Name: "replace", 2196 }, 2197 Args: []value.Primary{ 2198 value.NewNull(), 2199 value.NewString("cd"), 2200 value.NewString("CD"), 2201 }, 2202 Result: value.NewNull(), 2203 }, 2204 { 2205 Name: "Replace Old String is Null", 2206 Function: parser.Function{ 2207 Name: "replace", 2208 }, 2209 Args: []value.Primary{ 2210 value.NewString("abcdefg abcdefg"), 2211 value.NewNull(), 2212 value.NewString("CD"), 2213 }, 2214 Result: value.NewNull(), 2215 }, 2216 { 2217 Name: "Replace New String is Null", 2218 Function: parser.Function{ 2219 Name: "replace", 2220 }, 2221 Args: []value.Primary{ 2222 value.NewString("abcdefg abcdefg"), 2223 value.NewString("cd"), 2224 value.NewNull(), 2225 }, 2226 Result: value.NewNull(), 2227 }, 2228 { 2229 Name: "Replace Arguments Error", 2230 Function: parser.Function{ 2231 Name: "replace", 2232 }, 2233 Args: []value.Primary{}, 2234 Error: "function replace takes exactly 3 arguments", 2235 }, 2236 } 2237 2238 func TestReplaceFn(t *testing.T) { 2239 testFunction(t, ReplaceFn, replaceFnTests) 2240 } 2241 2242 var regExpMatchTests = []functionTest{ 2243 { 2244 Name: "RegExpMatch", 2245 Function: parser.Function{ 2246 Name: "regexp_match", 2247 }, 2248 Args: []value.Primary{ 2249 value.NewString("abcdefg abcdefg"), 2250 value.NewString("cd"), 2251 value.NewNull(), 2252 }, 2253 Result: value.NewTernary(ternary.TRUE), 2254 }, 2255 { 2256 Name: "RegExpMatch Not Match", 2257 Function: parser.Function{ 2258 Name: "regexp_match", 2259 }, 2260 Args: []value.Primary{ 2261 value.NewString("abcdefg abcdefg"), 2262 value.NewString("CD"), 2263 }, 2264 Result: value.NewTernary(ternary.FALSE), 2265 }, 2266 { 2267 Name: "RegExpMatch Ignore Case", 2268 Function: parser.Function{ 2269 Name: "regexp_match", 2270 }, 2271 Args: []value.Primary{ 2272 value.NewString("abcdefg abcdefg"), 2273 value.NewString("CD"), 2274 value.NewString("i"), 2275 }, 2276 Result: value.NewTernary(ternary.TRUE), 2277 }, 2278 { 2279 Name: "RegExpMatch First Argument is not a String", 2280 Function: parser.Function{ 2281 Name: "regexp_match", 2282 }, 2283 Args: []value.Primary{ 2284 value.NewNull(), 2285 value.NewString("CD"), 2286 }, 2287 Result: value.NewTernary(ternary.UNKNOWN), 2288 }, 2289 { 2290 Name: "RegExpMatch Arguments Length Error", 2291 Function: parser.Function{ 2292 Name: "regexp_match", 2293 }, 2294 Args: []value.Primary{ 2295 value.NewString("abcdefg abcdefg"), 2296 }, 2297 Error: "function regexp_match takes 2 or 3 arguments", 2298 }, 2299 { 2300 Name: "RegExpMatch Pattern Not Valid Error", 2301 Function: parser.Function{ 2302 Name: "regexp_match", 2303 }, 2304 Args: []value.Primary{ 2305 value.NewString("abcdefg abcdefg"), 2306 value.NewNull(), 2307 }, 2308 Error: "pattern must be a string for function regexp_match", 2309 }, 2310 { 2311 Name: "RegExpMatch Invalid Pattern Error", 2312 Function: parser.Function{ 2313 Name: "regexp_match", 2314 }, 2315 Args: []value.Primary{ 2316 value.NewString("abcdefg abcdefg"), 2317 value.NewString("(?a)a"), 2318 }, 2319 Error: "failed to compile pattern \"(?a)a\" for function regexp_match", 2320 }, 2321 { 2322 Name: "RegExpMatch Flags Not Valud Error", 2323 Function: parser.Function{ 2324 Name: "regexp_match", 2325 }, 2326 Args: []value.Primary{ 2327 value.NewString("abcdefg abcdefg"), 2328 value.NewString("CD"), 2329 value.NewBoolean(true), 2330 }, 2331 Error: "flags must be a string for function regexp_match", 2332 }, 2333 { 2334 Name: "RegExpMatch Invalid Flag Error", 2335 Function: parser.Function{ 2336 Name: "regexp_match", 2337 }, 2338 Args: []value.Primary{ 2339 value.NewString("abcdefg abcdefg"), 2340 value.NewString("CD"), 2341 value.NewString("a"), 2342 }, 2343 Error: "invalid flag \"a\" for function regexp_match", 2344 }, 2345 } 2346 2347 func TestRegExpMatch(t *testing.T) { 2348 testFunction(t, RegExpMatch, regExpMatchTests) 2349 } 2350 2351 var regExpFindTests = []functionTest{ 2352 { 2353 Name: "RegExpFind", 2354 Function: parser.Function{ 2355 Name: "regexp_find", 2356 }, 2357 Args: []value.Primary{ 2358 value.NewString("abcdefg abcdefg"), 2359 value.NewString("cd"), 2360 }, 2361 Result: value.NewString("cd"), 2362 }, 2363 { 2364 Name: "RegExpFind Sub-Matching", 2365 Function: parser.Function{ 2366 Name: "regexp_find", 2367 }, 2368 Args: []value.Primary{ 2369 value.NewString("abcdefg abcdefg"), 2370 value.NewString("b(c\\w+)e(f)"), 2371 }, 2372 Result: value.NewString("cd"), 2373 }, 2374 { 2375 Name: "RegExpFind Not Match", 2376 Function: parser.Function{ 2377 Name: "regexp_find", 2378 }, 2379 Args: []value.Primary{ 2380 value.NewString("abcdefg abcdefg"), 2381 value.NewString("not"), 2382 }, 2383 Result: value.NewNull(), 2384 }, 2385 { 2386 Name: "RegExpFind First Argument is not a String", 2387 Function: parser.Function{ 2388 Name: "regexp_find", 2389 }, 2390 Args: []value.Primary{ 2391 value.NewNull(), 2392 value.NewString("cd"), 2393 }, 2394 Result: value.NewNull(), 2395 }, 2396 { 2397 Name: "RegExpFind Arguments Length Error", 2398 Function: parser.Function{ 2399 Name: "regexp_find", 2400 }, 2401 Args: []value.Primary{ 2402 value.NewString("abcdefg abcdefg"), 2403 }, 2404 Error: "function regexp_find takes 2 or 3 arguments", 2405 }, 2406 } 2407 2408 func TestRegExpFind(t *testing.T) { 2409 testFunction(t, RegExpFind, regExpFindTests) 2410 } 2411 2412 var regExpFindSubMatchesTests = []functionTest{ 2413 { 2414 Name: "RegExpFindSubMatches", 2415 Function: parser.Function{ 2416 Name: "regexp_find_submatches", 2417 }, 2418 Args: []value.Primary{ 2419 value.NewString("abcdefg abcdefg"), 2420 value.NewString("cd"), 2421 }, 2422 Result: value.NewString("[\"cd\"]"), 2423 }, 2424 { 2425 Name: "RegExpFindSubMatches Sub-Matching", 2426 Function: parser.Function{ 2427 Name: "regexp_find_submatches", 2428 }, 2429 Args: []value.Primary{ 2430 value.NewString("abcdefg abcdefg"), 2431 value.NewString("b(c\\w+)e(f)"), 2432 }, 2433 Result: value.NewString("[\"bcdef\",\"cd\",\"f\"]"), 2434 }, 2435 { 2436 Name: "RegExpFindSubMatches Not Match", 2437 Function: parser.Function{ 2438 Name: "regexp_find_submatches", 2439 }, 2440 Args: []value.Primary{ 2441 value.NewString("abcdefg abcdefg"), 2442 value.NewString("not"), 2443 }, 2444 Result: value.NewNull(), 2445 }, 2446 { 2447 Name: "RegExpFindSubMatches First Argument is not a String", 2448 Function: parser.Function{ 2449 Name: "regexp_find_submatches", 2450 }, 2451 Args: []value.Primary{ 2452 value.NewNull(), 2453 value.NewString("cd"), 2454 }, 2455 Result: value.NewNull(), 2456 }, 2457 { 2458 Name: "RegExpFindSubMatches Arguments Length Error", 2459 Function: parser.Function{ 2460 Name: "regexp_find_submatches", 2461 }, 2462 Args: []value.Primary{ 2463 value.NewString("abcdefg abcdefg"), 2464 }, 2465 Error: "function regexp_find_submatches takes 2 or 3 arguments", 2466 }, 2467 } 2468 2469 func TestRegExpFindSubMatches(t *testing.T) { 2470 testFunction(t, RegExpFindSubMatches, regExpFindSubMatchesTests) 2471 } 2472 2473 var regExpFindAllTests = []functionTest{ 2474 { 2475 Name: "RegExpFindAll", 2476 Function: parser.Function{ 2477 Name: "regexp_find_all", 2478 }, 2479 Args: []value.Primary{ 2480 value.NewString("abcdefg abcdefg"), 2481 value.NewString("cd"), 2482 }, 2483 Result: value.NewString("[[\"cd\"],[\"cd\"]]"), 2484 }, 2485 { 2486 Name: "RegExpFindAll Sub-Matching", 2487 Function: parser.Function{ 2488 Name: "regexp_find_all", 2489 }, 2490 Args: []value.Primary{ 2491 value.NewString("abcdefg abcdefg"), 2492 value.NewString("b(c\\w+)e(f)"), 2493 }, 2494 Result: value.NewString("[[\"bcdef\",\"cd\",\"f\"],[\"bcdef\",\"cd\",\"f\"]]"), 2495 }, 2496 { 2497 Name: "RegExpFindAll Not Match", 2498 Function: parser.Function{ 2499 Name: "regexp_find_all", 2500 }, 2501 Args: []value.Primary{ 2502 value.NewString("abcdefg abcdefg"), 2503 value.NewString("not match"), 2504 }, 2505 Result: value.NewNull(), 2506 }, 2507 { 2508 Name: "RegExpFindAll First Argument is not a String", 2509 Function: parser.Function{ 2510 Name: "regexp_find_all", 2511 }, 2512 Args: []value.Primary{ 2513 value.NewNull(), 2514 value.NewString("cd"), 2515 }, 2516 Result: value.NewNull(), 2517 }, 2518 { 2519 Name: "RegExpFindAll Arguments Length Error", 2520 Function: parser.Function{ 2521 Name: "regexp_find_all", 2522 }, 2523 Args: []value.Primary{ 2524 value.NewString("abcdefg abcdefg"), 2525 }, 2526 Error: "function regexp_find_all takes 2 or 3 arguments", 2527 }, 2528 } 2529 2530 func TestRegExpFindAll(t *testing.T) { 2531 testFunction(t, RegExpFindAll, regExpFindAllTests) 2532 } 2533 2534 var regExpReplaceTests = []functionTest{ 2535 { 2536 Name: "RegExpReplace", 2537 Function: parser.Function{ 2538 Name: "regexp_find_all", 2539 }, 2540 Args: []value.Primary{ 2541 value.NewString("abcdefg abcdefg"), 2542 value.NewString("c.e"), 2543 value.NewString("S"), 2544 }, 2545 Result: value.NewString("abSfg abSfg"), 2546 }, 2547 { 2548 Name: "RegExpReplace Submatching", 2549 Function: parser.Function{ 2550 Name: "regexp_find_all", 2551 }, 2552 Args: []value.Primary{ 2553 value.NewString("abcdefg abcdefg"), 2554 value.NewString("C(.)e(f)"), 2555 value.NewString("$1${2}"), 2556 value.NewString("i"), 2557 }, 2558 Result: value.NewString("abdfg abdfg"), 2559 }, 2560 { 2561 Name: "RegExpReplace Submatching with Replacement Text", 2562 Function: parser.Function{ 2563 Name: "regexp_find_all", 2564 }, 2565 Args: []value.Primary{ 2566 value.NewString("abcdefg abcdefg"), 2567 value.NewString("c(.)e(f)"), 2568 value.NewString("${1}Sub${2}Match"), 2569 }, 2570 Result: value.NewString("abdSubfMatchg abdSubfMatchg"), 2571 }, 2572 { 2573 Name: "RegExpReplace First Argument is not a String", 2574 Function: parser.Function{ 2575 Name: "regexp_replace", 2576 }, 2577 Args: []value.Primary{ 2578 value.NewNull(), 2579 value.NewString("cd"), 2580 value.NewString("S"), 2581 }, 2582 Result: value.NewNull(), 2583 }, 2584 { 2585 Name: "RegExpReplace Third Argument is not a String", 2586 Function: parser.Function{ 2587 Name: "regexp_replace", 2588 }, 2589 Args: []value.Primary{ 2590 value.NewString("abcdefg abcdefg"), 2591 value.NewString("cd"), 2592 value.NewNull(), 2593 }, 2594 Error: "replacement string must be a string for function regexp_replace", 2595 }, 2596 { 2597 Name: "RegExpReplace Arguments Length Error", 2598 Function: parser.Function{ 2599 Name: "regexp_replace", 2600 }, 2601 Args: []value.Primary{ 2602 value.NewString("abcdefg abcdefg"), 2603 }, 2604 Error: "function regexp_replace takes 3 or 4 arguments", 2605 }, 2606 } 2607 2608 func TestRegExpReplace(t *testing.T) { 2609 testFunction(t, RegExpReplace, regExpReplaceTests) 2610 } 2611 2612 var titleCaseTests = []functionTest{ 2613 { 2614 Name: "TitleCase", 2615 Function: parser.Function{ 2616 Name: "title_case", 2617 }, 2618 Args: []value.Primary{ 2619 value.NewString("capitalize initials of all names"), 2620 }, 2621 Result: value.NewString("Capitalize Initials Of All Names"), 2622 }, 2623 { 2624 Name: "TitleCase Argument Length Error", 2625 Function: parser.Function{ 2626 Name: "title_case", 2627 }, 2628 Args: []value.Primary{}, 2629 Error: "function title_case takes exactly 1 argument", 2630 }, 2631 { 2632 Name: "TitleCase Argument Value Error", 2633 Function: parser.Function{ 2634 Name: "title_case", 2635 }, 2636 Args: []value.Primary{ 2637 value.NewNull(), 2638 }, 2639 Error: "the first argument must be a string for function title_case", 2640 }, 2641 } 2642 2643 func TestTitleCase(t *testing.T) { 2644 testFunction(t, TitleCase, titleCaseTests) 2645 } 2646 2647 var formatTests = []functionTest{ 2648 { 2649 Name: "Format", 2650 Function: parser.Function{ 2651 Name: "format", 2652 }, 2653 Args: []value.Primary{ 2654 value.NewString("string = %q, integer = %q"), 2655 value.NewString("str"), 2656 value.NewInteger(1), 2657 }, 2658 Result: value.NewString("string = 'str', integer = '1'"), 2659 }, 2660 { 2661 Name: "Format Argument Length Error", 2662 Function: parser.Function{ 2663 Name: "format", 2664 }, 2665 Args: []value.Primary{}, 2666 Error: "function format takes at least 1 argument", 2667 }, 2668 { 2669 Name: "Format Argument Value Error", 2670 Function: parser.Function{ 2671 Name: "format", 2672 }, 2673 Args: []value.Primary{ 2674 value.NewNull(), 2675 value.NewString("str"), 2676 value.NewInteger(1), 2677 }, 2678 Error: "the first argument must be a string for function format", 2679 }, 2680 { 2681 Name: "Format Replace Holder Length Not Match Error", 2682 Function: parser.Function{ 2683 Name: "format", 2684 }, 2685 Args: []value.Primary{ 2686 value.NewString("string = %s, integer = %s"), 2687 value.NewString("str"), 2688 }, 2689 Error: "number of replace values does not match for function format", 2690 }, 2691 } 2692 2693 func TestFormat(t *testing.T) { 2694 testFunction(t, Format, formatTests) 2695 } 2696 2697 var jsonValueTests = []functionTest{ 2698 { 2699 Name: "JsonValue", 2700 Function: parser.Function{ 2701 Name: "json_value", 2702 }, 2703 Args: []value.Primary{ 2704 value.NewString("key1.key2"), 2705 value.NewString("{\"key1\":{\"key2\":\"value\"}}"), 2706 }, 2707 Result: value.NewString("value"), 2708 }, 2709 { 2710 Name: "JsonValue Query is Null", 2711 Function: parser.Function{ 2712 Name: "json_value", 2713 }, 2714 Args: []value.Primary{ 2715 value.NewNull(), 2716 value.NewString("{\"key1\":{\"key2\":\"value\"}}"), 2717 }, 2718 Result: value.NewNull(), 2719 }, 2720 { 2721 Name: "JsonValue Json-Text is Null", 2722 Function: parser.Function{ 2723 Name: "json_value", 2724 }, 2725 Args: []value.Primary{ 2726 value.NewString("key1.key2"), 2727 value.NewNull(), 2728 }, 2729 Result: value.NewNull(), 2730 }, 2731 { 2732 Name: "JsonValue Arguments Error", 2733 Function: parser.Function{ 2734 Name: "json_value", 2735 }, 2736 Args: []value.Primary{ 2737 value.NewString("key1.key2"), 2738 }, 2739 Error: "function json_value takes exactly 2 arguments", 2740 }, 2741 { 2742 Name: "JsonValue Json Loading Error", 2743 Function: parser.Function{ 2744 Name: "json_value", 2745 }, 2746 Args: []value.Primary{ 2747 value.NewString("key1.key2"), 2748 value.NewString("{key1:{\"key2\":\"value\"}}"), 2749 }, 2750 Error: "line 1, column 2: unexpected token \"key\" for function json_value", 2751 }, 2752 } 2753 2754 func TestJsonValue(t *testing.T) { 2755 testFunction(t, JsonValue, jsonValueTests) 2756 } 2757 2758 var md5Tests = []functionTest{ 2759 { 2760 Name: "Md5", 2761 Function: parser.Function{ 2762 Name: "md5", 2763 }, 2764 Args: []value.Primary{ 2765 value.NewString("foo"), 2766 }, 2767 Result: value.NewString("acbd18db4cc2f85cedef654fccc4a4d8"), 2768 }, 2769 { 2770 Name: "Md5 Null", 2771 Function: parser.Function{ 2772 Name: "md5", 2773 }, 2774 Args: []value.Primary{ 2775 value.NewNull(), 2776 }, 2777 Result: value.NewNull(), 2778 }, 2779 { 2780 Name: "Md5 Arguments Error", 2781 Function: parser.Function{ 2782 Name: "md5", 2783 }, 2784 Args: []value.Primary{}, 2785 Error: "function md5 takes exactly 1 argument", 2786 }, 2787 } 2788 2789 func TestMd5(t *testing.T) { 2790 testFunction(t, Md5, md5Tests) 2791 } 2792 2793 var sha1Tests = []functionTest{ 2794 { 2795 Name: "Sha1", 2796 Function: parser.Function{ 2797 Name: "sha1", 2798 }, 2799 Args: []value.Primary{ 2800 value.NewString("foo"), 2801 }, 2802 Result: value.NewString("0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"), 2803 }, 2804 } 2805 2806 func TestSha1(t *testing.T) { 2807 testFunction(t, Sha1, sha1Tests) 2808 } 2809 2810 var sha256Tests = []functionTest{ 2811 { 2812 Name: "Sha256", 2813 Function: parser.Function{ 2814 Name: "sha256", 2815 }, 2816 Args: []value.Primary{ 2817 value.NewString("foo"), 2818 }, 2819 Result: value.NewString("2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"), 2820 }, 2821 } 2822 2823 func TestSha256(t *testing.T) { 2824 testFunction(t, Sha256, sha256Tests) 2825 } 2826 2827 var sha512Tests = []functionTest{ 2828 { 2829 Name: "Sha512", 2830 Function: parser.Function{ 2831 Name: "sha512", 2832 }, 2833 Args: []value.Primary{ 2834 value.NewString("foo"), 2835 }, 2836 Result: value.NewString("f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7"), 2837 }, 2838 } 2839 2840 func TestSha512(t *testing.T) { 2841 testFunction(t, Sha512, sha512Tests) 2842 } 2843 2844 var md5HmacTests = []functionTest{ 2845 { 2846 Name: "Md5Hmac", 2847 Function: parser.Function{ 2848 Name: "md5_hmac", 2849 }, 2850 Args: []value.Primary{ 2851 value.NewString("foo"), 2852 value.NewString("bar"), 2853 }, 2854 Result: value.NewString("31b6db9e5eb4addb42f1a6ca07367adc"), 2855 }, 2856 { 2857 Name: "Md5Hmac String is Null", 2858 Function: parser.Function{ 2859 Name: "md5_hmac", 2860 }, 2861 Args: []value.Primary{ 2862 value.NewNull(), 2863 value.NewString("bar"), 2864 }, 2865 Result: value.NewNull(), 2866 }, 2867 { 2868 Name: "Md5Hmac Key is Null", 2869 Function: parser.Function{ 2870 Name: "md5_hmac", 2871 }, 2872 Args: []value.Primary{ 2873 value.NewString("foo"), 2874 value.NewNull(), 2875 }, 2876 Result: value.NewNull(), 2877 }, 2878 { 2879 Name: "Md5Hmac Arguments Error", 2880 Function: parser.Function{ 2881 Name: "md5_hmac", 2882 }, 2883 Args: []value.Primary{}, 2884 Error: "function md5_hmac takes exactly 2 arguments", 2885 }, 2886 } 2887 2888 func TestMd5Hmac(t *testing.T) { 2889 testFunction(t, Md5Hmac, md5HmacTests) 2890 } 2891 2892 var sha1HmacTests = []functionTest{ 2893 { 2894 Name: "Sha1Hmac", 2895 Function: parser.Function{ 2896 Name: "sha1_hmac", 2897 }, 2898 Args: []value.Primary{ 2899 value.NewString("foo"), 2900 value.NewString("bar"), 2901 }, 2902 Result: value.NewString("85d155c55ed286a300bd1cf124de08d87e914f3a"), 2903 }, 2904 } 2905 2906 func TestSha1Hmac(t *testing.T) { 2907 testFunction(t, Sha1Hmac, sha1HmacTests) 2908 } 2909 2910 var sha256HmacTests = []functionTest{ 2911 { 2912 Name: "Sha256Hmac", 2913 Function: parser.Function{ 2914 Name: "sha256_hmac", 2915 }, 2916 Args: []value.Primary{ 2917 value.NewString("foo"), 2918 value.NewString("bar"), 2919 }, 2920 Result: value.NewString("147933218aaabc0b8b10a2b3a5c34684c8d94341bcf10a4736dc7270f7741851"), 2921 }, 2922 } 2923 2924 func TestSha256Hmac(t *testing.T) { 2925 testFunction(t, Sha256Hmac, sha256HmacTests) 2926 } 2927 2928 var sha512HmacTests = []functionTest{ 2929 { 2930 Name: "Sha512Hmac", 2931 Function: parser.Function{ 2932 Name: "sha512_hmac", 2933 }, 2934 Args: []value.Primary{ 2935 value.NewString("foo"), 2936 value.NewString("bar"), 2937 }, 2938 Result: value.NewString("24257d7210582a65c731ec55159c8184cc24c02489453e58587f71f44c23a2d61b4b72154a89d17b2d49448a8452ea066f4fc56a2bcead45c088572ffccdb3d8"), 2939 }, 2940 } 2941 2942 func TestSha512Hmac(t *testing.T) { 2943 testFunction(t, Sha512Hmac, sha512HmacTests) 2944 } 2945 2946 var datetimeFormatTests = []functionTest{ 2947 { 2948 Name: "DatetimeFormat", 2949 Function: parser.Function{ 2950 Name: "datetime_format", 2951 }, 2952 Args: []value.Primary{ 2953 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 0, GetTestLocation())), 2954 value.NewString("%Y-%m-%d"), 2955 }, 2956 Result: value.NewString("2012-02-03"), 2957 }, 2958 { 2959 Name: "DatetimeFormat Datetime is Null", 2960 Function: parser.Function{ 2961 Name: "datetime_format", 2962 }, 2963 Args: []value.Primary{ 2964 value.NewNull(), 2965 value.NewString("%Y-%m-%d"), 2966 }, 2967 Result: value.NewNull(), 2968 }, 2969 { 2970 Name: "DatetimeFormat Format is Null", 2971 Function: parser.Function{ 2972 Name: "datetime_format", 2973 }, 2974 Args: []value.Primary{ 2975 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 0, GetTestLocation())), 2976 value.NewNull(), 2977 }, 2978 Result: value.NewNull(), 2979 }, 2980 { 2981 Name: "DatetimeFormat Arguments Error", 2982 Function: parser.Function{ 2983 Name: "datetime_format", 2984 }, 2985 Args: []value.Primary{ 2986 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 0, GetTestLocation())), 2987 }, 2988 Error: "function datetime_format takes exactly 2 arguments", 2989 }, 2990 } 2991 2992 func TestDatetimeFormat(t *testing.T) { 2993 testFunction(t, DatetimeFormat, datetimeFormatTests) 2994 } 2995 2996 var yearTests = []functionTest{ 2997 { 2998 Name: "Year", 2999 Function: parser.Function{ 3000 Name: "year", 3001 }, 3002 Args: []value.Primary{ 3003 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 0, GetTestLocation())), 3004 }, 3005 Result: value.NewInteger(2012), 3006 }, 3007 { 3008 Name: "Year Datetime is Null", 3009 Function: parser.Function{ 3010 Name: "year", 3011 }, 3012 Args: []value.Primary{ 3013 value.NewNull(), 3014 }, 3015 Result: value.NewNull(), 3016 }, 3017 { 3018 Name: "Year Arguments Error", 3019 Function: parser.Function{ 3020 Name: "year", 3021 }, 3022 Args: []value.Primary{}, 3023 Error: "function year takes exactly 1 argument", 3024 }, 3025 } 3026 3027 func TestYear(t *testing.T) { 3028 testFunction(t, Year, yearTests) 3029 } 3030 3031 var monthTests = []functionTest{ 3032 { 3033 Name: "Month", 3034 Function: parser.Function{ 3035 Name: "month", 3036 }, 3037 Args: []value.Primary{ 3038 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 0, GetTestLocation())), 3039 }, 3040 Result: value.NewInteger(2), 3041 }, 3042 } 3043 3044 func TestMonth(t *testing.T) { 3045 testFunction(t, Month, monthTests) 3046 } 3047 3048 var dayTests = []functionTest{ 3049 { 3050 Name: "Day", 3051 Function: parser.Function{ 3052 Name: "day", 3053 }, 3054 Args: []value.Primary{ 3055 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 0, GetTestLocation())), 3056 }, 3057 Result: value.NewInteger(3), 3058 }, 3059 } 3060 3061 func TestDay(t *testing.T) { 3062 testFunction(t, Day, dayTests) 3063 } 3064 3065 var hourTests = []functionTest{ 3066 { 3067 Name: "Hour", 3068 Function: parser.Function{ 3069 Name: "hour", 3070 }, 3071 Args: []value.Primary{ 3072 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 0, GetTestLocation())), 3073 }, 3074 Result: value.NewInteger(9), 3075 }, 3076 } 3077 3078 func TestHour(t *testing.T) { 3079 testFunction(t, Hour, hourTests) 3080 } 3081 3082 var minuteTests = []functionTest{ 3083 { 3084 Name: "Minute", 3085 Function: parser.Function{ 3086 Name: "minute", 3087 }, 3088 Args: []value.Primary{ 3089 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 0, GetTestLocation())), 3090 }, 3091 Result: value.NewInteger(18), 3092 }, 3093 } 3094 3095 func TestMinute(t *testing.T) { 3096 testFunction(t, Minute, minuteTests) 3097 } 3098 3099 var secondTests = []functionTest{ 3100 { 3101 Name: "Second", 3102 Function: parser.Function{ 3103 Name: "second", 3104 }, 3105 Args: []value.Primary{ 3106 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 0, GetTestLocation())), 3107 }, 3108 Result: value.NewInteger(15), 3109 }, 3110 } 3111 3112 func TestSecond(t *testing.T) { 3113 testFunction(t, Second, secondTests) 3114 } 3115 3116 var millisecondTests = []functionTest{ 3117 { 3118 Name: "Millisecond", 3119 Function: parser.Function{ 3120 Name: "millisecond", 3121 }, 3122 Args: []value.Primary{ 3123 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3124 }, 3125 Result: value.NewInteger(123), 3126 }, 3127 } 3128 3129 func TestMillisecond(t *testing.T) { 3130 testFunction(t, Millisecond, millisecondTests) 3131 } 3132 3133 var microsecondTests = []functionTest{ 3134 { 3135 Name: "Microsecond", 3136 Function: parser.Function{ 3137 Name: "microsecond", 3138 }, 3139 Args: []value.Primary{ 3140 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3141 }, 3142 Result: value.NewInteger(123457), 3143 }, 3144 } 3145 3146 func TestMicrosecond(t *testing.T) { 3147 testFunction(t, Microsecond, microsecondTests) 3148 } 3149 3150 var nanosecondTests = []functionTest{ 3151 { 3152 Name: "Nanosecond", 3153 Function: parser.Function{ 3154 Name: "nanosecond", 3155 }, 3156 Args: []value.Primary{ 3157 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3158 }, 3159 Result: value.NewInteger(123456789), 3160 }, 3161 } 3162 3163 func TestNanosecond(t *testing.T) { 3164 testFunction(t, Nanosecond, nanosecondTests) 3165 } 3166 3167 var weekdayTests = []functionTest{ 3168 { 3169 Name: "Weekday", 3170 Function: parser.Function{ 3171 Name: "weekday", 3172 }, 3173 Args: []value.Primary{ 3174 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 0, GetTestLocation())), 3175 }, 3176 Result: value.NewInteger(5), 3177 }, 3178 } 3179 3180 func TestWeekday(t *testing.T) { 3181 testFunction(t, Weekday, weekdayTests) 3182 } 3183 3184 var unixTimeTests = []functionTest{ 3185 { 3186 Name: "UnixTime", 3187 Function: parser.Function{ 3188 Name: "unix_time", 3189 }, 3190 Args: []value.Primary{ 3191 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 0, GetTestLocation())), 3192 }, 3193 Result: value.NewInteger(1328260695), 3194 }, 3195 } 3196 3197 func TestUnixTime(t *testing.T) { 3198 testFunction(t, UnixTime, unixTimeTests) 3199 } 3200 3201 var unixNanoTimeTests = []functionTest{ 3202 { 3203 Name: "UnixNanoTime", 3204 Function: parser.Function{ 3205 Name: "unix_nano_time", 3206 }, 3207 Args: []value.Primary{ 3208 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3209 }, 3210 Result: value.NewInteger(1328260695123456789), 3211 }, 3212 } 3213 3214 func TestUnixNanoTime(t *testing.T) { 3215 testFunction(t, UnixNanoTime, unixNanoTimeTests) 3216 } 3217 3218 var dayOfYearTests = []functionTest{ 3219 { 3220 Name: "DayOfYear", 3221 Function: parser.Function{ 3222 Name: "day_of_year", 3223 }, 3224 Args: []value.Primary{ 3225 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 0, GetTestLocation())), 3226 }, 3227 Result: value.NewInteger(34), 3228 }, 3229 } 3230 3231 func TestDayOfYear(t *testing.T) { 3232 testFunction(t, DayOfYear, dayOfYearTests) 3233 } 3234 3235 var weekOfYearTests = []functionTest{ 3236 { 3237 Name: "WeekOfYear", 3238 Function: parser.Function{ 3239 Name: "week_of_year", 3240 }, 3241 Args: []value.Primary{ 3242 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 0, GetTestLocation())), 3243 }, 3244 Result: value.NewInteger(5), 3245 }, 3246 } 3247 3248 func TestWeekOfYear(t *testing.T) { 3249 testFunction(t, WeekOfYear, weekOfYearTests) 3250 } 3251 3252 var addYearTests = []functionTest{ 3253 { 3254 Name: "AddYear", 3255 Function: parser.Function{ 3256 Name: "add_year", 3257 }, 3258 Args: []value.Primary{ 3259 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3260 value.NewInteger(2), 3261 }, 3262 Result: value.NewDatetime(time.Date(2014, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3263 }, 3264 { 3265 Name: "AddYear Datetime is Null", 3266 Function: parser.Function{ 3267 Name: "add_year", 3268 }, 3269 Args: []value.Primary{ 3270 value.NewNull(), 3271 value.NewInteger(2), 3272 }, 3273 Result: value.NewNull(), 3274 }, 3275 { 3276 Name: "AddYear Duration is Null", 3277 Function: parser.Function{ 3278 Name: "add_year", 3279 }, 3280 Args: []value.Primary{ 3281 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3282 value.NewNull(), 3283 }, 3284 Result: value.NewNull(), 3285 }, 3286 { 3287 Name: "AddYear Arguments Error", 3288 Function: parser.Function{ 3289 Name: "add_year", 3290 }, 3291 Args: []value.Primary{}, 3292 Error: "function add_year takes exactly 2 arguments", 3293 }, 3294 } 3295 3296 func TestAddYear(t *testing.T) { 3297 testFunction(t, AddYear, addYearTests) 3298 } 3299 3300 var addMonthTests = []functionTest{ 3301 { 3302 Name: "AddMonth", 3303 Function: parser.Function{ 3304 Name: "add_month", 3305 }, 3306 Args: []value.Primary{ 3307 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3308 value.NewInteger(2), 3309 }, 3310 Result: value.NewDatetime(time.Date(2012, 4, 3, 9, 18, 15, 123456789, GetTestLocation())), 3311 }, 3312 } 3313 3314 func TestAddMonth(t *testing.T) { 3315 testFunction(t, AddMonth, addMonthTests) 3316 } 3317 3318 var addDayTests = []functionTest{ 3319 { 3320 Name: "AddDay", 3321 Function: parser.Function{ 3322 Name: "add_day", 3323 }, 3324 Args: []value.Primary{ 3325 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3326 value.NewInteger(2), 3327 }, 3328 Result: value.NewDatetime(time.Date(2012, 2, 5, 9, 18, 15, 123456789, GetTestLocation())), 3329 }, 3330 } 3331 3332 func TestAddDay(t *testing.T) { 3333 testFunction(t, AddDay, addDayTests) 3334 } 3335 3336 var addHourTests = []functionTest{ 3337 { 3338 Name: "AddHour", 3339 Function: parser.Function{ 3340 Name: "add_hour", 3341 }, 3342 Args: []value.Primary{ 3343 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3344 value.NewInteger(2), 3345 }, 3346 Result: value.NewDatetime(time.Date(2012, 2, 3, 11, 18, 15, 123456789, GetTestLocation())), 3347 }, 3348 } 3349 3350 func TestAddHour(t *testing.T) { 3351 testFunction(t, AddHour, addHourTests) 3352 } 3353 3354 var addMinuteTests = []functionTest{ 3355 { 3356 Name: "AddMinute", 3357 Function: parser.Function{ 3358 Name: "add_minute", 3359 }, 3360 Args: []value.Primary{ 3361 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3362 value.NewInteger(2), 3363 }, 3364 Result: value.NewDatetime(time.Date(2012, 2, 3, 9, 20, 15, 123456789, GetTestLocation())), 3365 }, 3366 } 3367 3368 func TestAddMinute(t *testing.T) { 3369 testFunction(t, AddMinute, addMinuteTests) 3370 } 3371 3372 var addSecondTests = []functionTest{ 3373 { 3374 Name: "AddSecond", 3375 Function: parser.Function{ 3376 Name: "add_second", 3377 }, 3378 Args: []value.Primary{ 3379 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3380 value.NewInteger(2), 3381 }, 3382 Result: value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 17, 123456789, GetTestLocation())), 3383 }, 3384 } 3385 3386 func TestAddSecond(t *testing.T) { 3387 testFunction(t, AddSecond, addSecondTests) 3388 } 3389 3390 var addMilliTests = []functionTest{ 3391 { 3392 Name: "AddMilli", 3393 Function: parser.Function{ 3394 Name: "add_milli", 3395 }, 3396 Args: []value.Primary{ 3397 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3398 value.NewInteger(2), 3399 }, 3400 Result: value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 125456789, GetTestLocation())), 3401 }, 3402 } 3403 3404 func TestAddMilli(t *testing.T) { 3405 testFunction(t, AddMilli, addMilliTests) 3406 } 3407 3408 var addMicroTests = []functionTest{ 3409 { 3410 Name: "AddMicro", 3411 Function: parser.Function{ 3412 Name: "add_micro", 3413 }, 3414 Args: []value.Primary{ 3415 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3416 value.NewInteger(2), 3417 }, 3418 Result: value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123458789, GetTestLocation())), 3419 }, 3420 } 3421 3422 func TestAddMicro(t *testing.T) { 3423 testFunction(t, AddMicro, addMicroTests) 3424 } 3425 3426 var addNanoTests = []functionTest{ 3427 { 3428 Name: "AddNano", 3429 Function: parser.Function{ 3430 Name: "add_nano", 3431 }, 3432 Args: []value.Primary{ 3433 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3434 value.NewInteger(2), 3435 }, 3436 Result: value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456791, GetTestLocation())), 3437 }, 3438 } 3439 3440 func TestAddNano(t *testing.T) { 3441 testFunction(t, AddNano, addNanoTests) 3442 } 3443 3444 var truncMonthTests = []functionTest{ 3445 { 3446 Name: "TruncMonth", 3447 Function: parser.Function{ 3448 Name: "trunc_month", 3449 }, 3450 Args: []value.Primary{ 3451 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3452 }, 3453 Result: value.NewDatetime(time.Date(2012, 1, 1, 0, 0, 0, 0, GetTestLocation())), 3454 }, 3455 { 3456 Name: "TruncMonth Argument Error", 3457 Function: parser.Function{ 3458 Name: "trunc_month", 3459 }, 3460 Args: []value.Primary{}, 3461 Error: "function trunc_month takes exactly 1 argument", 3462 }, 3463 { 3464 Name: "TruncMonth Argument Is Null", 3465 Function: parser.Function{ 3466 Name: "trunc_month", 3467 }, 3468 Args: []value.Primary{ 3469 value.NewNull(), 3470 }, 3471 Result: value.NewNull(), 3472 }, 3473 } 3474 3475 func TestTruncMonth(t *testing.T) { 3476 testFunction(t, TruncMonth, truncMonthTests) 3477 } 3478 3479 var truncDayTests = []functionTest{ 3480 { 3481 Name: "TruncDay", 3482 Function: parser.Function{ 3483 Name: "trunc_day", 3484 }, 3485 Args: []value.Primary{ 3486 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3487 }, 3488 Result: value.NewDatetime(time.Date(2012, 2, 1, 0, 0, 0, 0, GetTestLocation())), 3489 }, 3490 } 3491 3492 func TestTruncDay(t *testing.T) { 3493 testFunction(t, TruncDay, truncDayTests) 3494 } 3495 3496 var truncTimeTests = []functionTest{ 3497 { 3498 Name: "TruncTime", 3499 Function: parser.Function{ 3500 Name: "trunc_time", 3501 }, 3502 Args: []value.Primary{ 3503 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3504 }, 3505 Result: value.NewDatetime(time.Date(2012, 2, 3, 0, 0, 0, 0, GetTestLocation())), 3506 }, 3507 } 3508 3509 func TestTruncTime(t *testing.T) { 3510 testFunction(t, TruncTime, truncTimeTests) 3511 } 3512 3513 var truncMinuteTests = []functionTest{ 3514 { 3515 Name: "TruncMinute", 3516 Function: parser.Function{ 3517 Name: "trunc_minute", 3518 }, 3519 Args: []value.Primary{ 3520 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3521 }, 3522 Result: value.NewDatetime(time.Date(2012, 2, 3, 9, 0, 0, 0, GetTestLocation())), 3523 }, 3524 { 3525 Name: "TruncMinute Argument Error", 3526 Function: parser.Function{ 3527 Name: "trunc_minute", 3528 }, 3529 Args: []value.Primary{}, 3530 Error: "function trunc_minute takes exactly 1 argument", 3531 }, 3532 { 3533 Name: "TruncMinute Argument Is Null", 3534 Function: parser.Function{ 3535 Name: "trunc_minute", 3536 }, 3537 Args: []value.Primary{ 3538 value.NewNull(), 3539 }, 3540 Result: value.NewNull(), 3541 }, 3542 } 3543 3544 func TestTruncMinute(t *testing.T) { 3545 testFunction(t, TruncMinute, truncMinuteTests) 3546 } 3547 3548 var truncSecondTests = []functionTest{ 3549 { 3550 Name: "TruncSecond", 3551 Function: parser.Function{ 3552 Name: "trunc_second", 3553 }, 3554 Args: []value.Primary{ 3555 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3556 }, 3557 Result: value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 0, 0, GetTestLocation())), 3558 }, 3559 } 3560 3561 func TestTruncSecond(t *testing.T) { 3562 testFunction(t, TruncSecond, truncSecondTests) 3563 } 3564 3565 var truncMilliTests = []functionTest{ 3566 { 3567 Name: "TruncMilli", 3568 Function: parser.Function{ 3569 Name: "trunc_milli", 3570 }, 3571 Args: []value.Primary{ 3572 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3573 }, 3574 Result: value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 0, GetTestLocation())), 3575 }, 3576 } 3577 3578 func TestTruncMilli(t *testing.T) { 3579 testFunction(t, TruncMilli, truncMilliTests) 3580 } 3581 3582 var truncMicroTests = []functionTest{ 3583 { 3584 Name: "TruncMicro", 3585 Function: parser.Function{ 3586 Name: "trunc_micro", 3587 }, 3588 Args: []value.Primary{ 3589 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3590 }, 3591 Result: value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123000000, GetTestLocation())), 3592 }, 3593 } 3594 3595 func TestTruncateMicro(t *testing.T) { 3596 testFunction(t, TruncMicro, truncMicroTests) 3597 } 3598 3599 var truncNanoTests = []functionTest{ 3600 { 3601 Name: "TruncNano", 3602 Function: parser.Function{ 3603 Name: "trunc_nano", 3604 }, 3605 Args: []value.Primary{ 3606 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3607 }, 3608 Result: value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456000, GetTestLocation())), 3609 }, 3610 } 3611 3612 func TestTruncateNano(t *testing.T) { 3613 testFunction(t, TruncNano, truncNanoTests) 3614 } 3615 3616 var dateDiffTests = []functionTest{ 3617 { 3618 Name: "DateDiff", 3619 Function: parser.Function{ 3620 Name: "date_diff", 3621 }, 3622 Args: []value.Primary{ 3623 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3624 value.NewDatetime(time.Date(2012, 2, 5, 1, 18, 55, 123456789, GetTestLocation())), 3625 }, 3626 Result: value.NewInteger(-2), 3627 }, 3628 { 3629 Name: "DateDiff Datetime1 is Null", 3630 Function: parser.Function{ 3631 Name: "date_diff", 3632 }, 3633 Args: []value.Primary{ 3634 value.NewNull(), 3635 value.NewDatetime(time.Date(2012, 2, 5, 1, 18, 55, 123456789, GetTestLocation())), 3636 }, 3637 Result: value.NewNull(), 3638 }, 3639 { 3640 Name: "DateDiff Datetime2 is Null", 3641 Function: parser.Function{ 3642 Name: "date_diff", 3643 }, 3644 Args: []value.Primary{ 3645 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3646 value.NewNull(), 3647 }, 3648 Result: value.NewNull(), 3649 }, 3650 { 3651 Name: "DateDiff Arguments Error", 3652 Function: parser.Function{ 3653 Name: "date_diff", 3654 }, 3655 Args: []value.Primary{}, 3656 Error: "function date_diff takes exactly 2 arguments", 3657 }, 3658 } 3659 3660 func TestDateDiff(t *testing.T) { 3661 testFunction(t, DateDiff, dateDiffTests) 3662 } 3663 3664 var timeDiffTests = []functionTest{ 3665 { 3666 Name: "TimeDiff", 3667 Function: parser.Function{ 3668 Name: "time_diff", 3669 }, 3670 Args: []value.Primary{ 3671 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3672 value.NewDatetime(time.Date(2012, 2, 3, 1, 18, 55, 123000000, GetTestLocation())), 3673 }, 3674 Result: value.NewFloat(28760.000456789), 3675 }, 3676 { 3677 Name: "TimeDiff Datetime1 is Null", 3678 Function: parser.Function{ 3679 Name: "time_diff", 3680 }, 3681 Args: []value.Primary{ 3682 value.NewNull(), 3683 value.NewDatetime(time.Date(2012, 2, 5, 1, 18, 55, 123456789, GetTestLocation())), 3684 }, 3685 Result: value.NewNull(), 3686 }, 3687 { 3688 Name: "TimeDiff Datetime2 is Null", 3689 Function: parser.Function{ 3690 Name: "time_diff", 3691 }, 3692 Args: []value.Primary{ 3693 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3694 value.NewNull(), 3695 }, 3696 Result: value.NewNull(), 3697 }, 3698 { 3699 Name: "TimeDiff Arguments Error", 3700 Function: parser.Function{ 3701 Name: "time_diff", 3702 }, 3703 Args: []value.Primary{}, 3704 Error: "function time_diff takes exactly 2 arguments", 3705 }, 3706 } 3707 3708 func TestTimeDiff(t *testing.T) { 3709 testFunction(t, TimeDiff, timeDiffTests) 3710 } 3711 3712 var timeNanoDiffTests = []functionTest{ 3713 { 3714 Name: "TimeNanoDiff", 3715 Function: parser.Function{ 3716 Name: "time_nano_diff", 3717 }, 3718 Args: []value.Primary{ 3719 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3720 value.NewDatetime(time.Date(2012, 2, 3, 1, 18, 55, 123000000, GetTestLocation())), 3721 }, 3722 Result: value.NewInteger(28760000456789), 3723 }, 3724 } 3725 3726 func TestTimeNanoDiff(t *testing.T) { 3727 testFunction(t, TimeNanoDiff, timeNanoDiffTests) 3728 } 3729 3730 var utcTests = []functionTest{ 3731 { 3732 Name: "UTC", 3733 Function: parser.Function{ 3734 Name: "utc", 3735 }, 3736 Args: []value.Primary{ 3737 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, GetTestLocation())), 3738 }, 3739 Result: value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123456789, time.UTC)), 3740 }, 3741 { 3742 Name: "UTC Argument Error", 3743 Function: parser.Function{ 3744 Name: "utc", 3745 }, 3746 Args: []value.Primary{}, 3747 Error: "function utc takes exactly 1 argument", 3748 }, 3749 { 3750 Name: "UTC Argument Is Null", 3751 Function: parser.Function{ 3752 Name: "utc", 3753 }, 3754 Args: []value.Primary{ 3755 value.NewNull(), 3756 }, 3757 Result: value.NewNull(), 3758 }, 3759 } 3760 3761 func TestUTC(t *testing.T) { 3762 testFunction(t, UTC, utcTests) 3763 } 3764 3765 var milliToDatetimeTests = []functionTest{ 3766 { 3767 Name: "MilliToDatetime", 3768 Function: parser.Function{ 3769 Name: "milli_to_datetime", 3770 }, 3771 Args: []value.Primary{ 3772 value.NewInteger(1328260695001), 3773 }, 3774 Result: value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 1000000, GetTestLocation())), 3775 }, 3776 { 3777 Name: "MilliToDatetime Invalid Argument", 3778 Function: parser.Function{ 3779 Name: "milli_to_datetime", 3780 }, 3781 Args: []value.Primary{ 3782 value.NewString("abc"), 3783 }, 3784 Result: value.NewNull(), 3785 }, 3786 { 3787 Name: "MilliToDatetime Arguments Error", 3788 Function: parser.Function{ 3789 Name: "milli_to_datetime", 3790 }, 3791 Args: []value.Primary{}, 3792 Error: "function milli_to_datetime takes exactly 1 argument", 3793 }, 3794 } 3795 3796 func TestMilliToDatetime(t *testing.T) { 3797 testFunction(t, MilliToDatetime, milliToDatetimeTests) 3798 } 3799 3800 var nanoToDatetimeTests = []functionTest{ 3801 { 3802 Name: "NanoToDatetime", 3803 Function: parser.Function{ 3804 Name: "nano_to_datetime", 3805 }, 3806 Args: []value.Primary{ 3807 value.NewInteger(1328260695000000001), 3808 }, 3809 Result: value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 1, GetTestLocation())), 3810 }, 3811 { 3812 Name: "NanoToDatetime Invalid Argument", 3813 Function: parser.Function{ 3814 Name: "nano_to_datetime", 3815 }, 3816 Args: []value.Primary{ 3817 value.NewString("abc"), 3818 }, 3819 Result: value.NewNull(), 3820 }, 3821 { 3822 Name: "NanoToDatetime Arguments Error", 3823 Function: parser.Function{ 3824 Name: "nano_to_datetime", 3825 }, 3826 Args: []value.Primary{}, 3827 Error: "function nano_to_datetime takes exactly 1 argument", 3828 }, 3829 } 3830 3831 func TestNanoToDatetime(t *testing.T) { 3832 testFunction(t, NanoToDatetime, nanoToDatetimeTests) 3833 } 3834 3835 var stringTests = []functionTest{ 3836 { 3837 Name: "String from Integer", 3838 Function: parser.Function{ 3839 Name: "string", 3840 }, 3841 Args: []value.Primary{ 3842 value.NewInteger(2), 3843 }, 3844 Result: value.NewString("2"), 3845 }, 3846 { 3847 Name: "String from Boolean", 3848 Function: parser.Function{ 3849 Name: "string", 3850 }, 3851 Args: []value.Primary{ 3852 value.NewBoolean(true), 3853 }, 3854 Result: value.NewString("true"), 3855 }, 3856 { 3857 Name: "String from Ternary", 3858 Function: parser.Function{ 3859 Name: "string", 3860 }, 3861 Args: []value.Primary{ 3862 value.NewTernary(ternary.TRUE), 3863 }, 3864 Result: value.NewString("TRUE"), 3865 }, 3866 { 3867 Name: "String from Datetime", 3868 Function: parser.Function{ 3869 Name: "string", 3870 }, 3871 Args: []value.Primary{ 3872 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 0, GetTestLocation())), 3873 }, 3874 Result: value.NewString("2012-02-03T09:18:15Z"), 3875 }, 3876 { 3877 Name: "String Arguments Error", 3878 Function: parser.Function{ 3879 Name: "string", 3880 }, 3881 Args: []value.Primary{}, 3882 Error: "function string takes exactly 1 argument", 3883 }, 3884 } 3885 3886 func TestString(t *testing.T) { 3887 testFunction(t, String, stringTests) 3888 } 3889 3890 var integerTests = []functionTest{ 3891 { 3892 Name: "Integer from Integer", 3893 Function: parser.Function{ 3894 Name: "integer", 3895 }, 3896 Args: []value.Primary{ 3897 value.NewInteger(2), 3898 }, 3899 Result: value.NewInteger(2), 3900 }, 3901 { 3902 Name: "Integer from String", 3903 Function: parser.Function{ 3904 Name: "integer", 3905 }, 3906 Args: []value.Primary{ 3907 value.NewString("2"), 3908 }, 3909 Result: value.NewInteger(2), 3910 }, 3911 { 3912 Name: "Integer from E-Notation", 3913 Function: parser.Function{ 3914 Name: "integer", 3915 }, 3916 Args: []value.Primary{ 3917 value.NewString("2e+02"), 3918 }, 3919 Result: value.NewInteger(200), 3920 }, 3921 { 3922 Name: "Integer from Float", 3923 Function: parser.Function{ 3924 Name: "integer", 3925 }, 3926 Args: []value.Primary{ 3927 value.NewFloat(1.7), 3928 }, 3929 Result: value.NewInteger(1), 3930 }, 3931 { 3932 Name: "Integer from Special Float Value", 3933 Function: parser.Function{ 3934 Name: "integer", 3935 }, 3936 Args: []value.Primary{ 3937 value.NewFloat(math.NaN()), 3938 }, 3939 Result: value.NewNull(), 3940 }, 3941 { 3942 Name: "Float Null", 3943 Function: parser.Function{ 3944 Name: "float", 3945 }, 3946 Args: []value.Primary{ 3947 value.NewNull(), 3948 }, 3949 Result: value.NewNull(), 3950 }, 3951 { 3952 Name: "Integer from Datetime", 3953 Function: parser.Function{ 3954 Name: "integer", 3955 }, 3956 Args: []value.Primary{ 3957 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 0, GetTestLocation())), 3958 }, 3959 Result: value.NewInteger(1328260695), 3960 }, 3961 { 3962 Name: "Integer Arguments Error", 3963 Function: parser.Function{ 3964 Name: "integer", 3965 }, 3966 Args: []value.Primary{}, 3967 Error: "function integer takes exactly 1 argument", 3968 }, 3969 } 3970 3971 func TestInteger(t *testing.T) { 3972 testFunction(t, Integer, integerTests) 3973 } 3974 3975 var floatTests = []functionTest{ 3976 { 3977 Name: "Float from String", 3978 Function: parser.Function{ 3979 Name: "float", 3980 }, 3981 Args: []value.Primary{ 3982 value.NewString("2"), 3983 }, 3984 Result: value.NewFloat(2), 3985 }, 3986 { 3987 Name: "Float from Datetime", 3988 Function: parser.Function{ 3989 Name: "float", 3990 }, 3991 Args: []value.Primary{ 3992 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 123450000, GetTestLocation())), 3993 }, 3994 Result: value.NewFloat(1328260695.12345), 3995 }, 3996 { 3997 Name: "Float Arguments Error", 3998 Function: parser.Function{ 3999 Name: "float", 4000 }, 4001 Args: []value.Primary{}, 4002 Error: "function float takes exactly 1 argument", 4003 }, 4004 } 4005 4006 func TestFloat(t *testing.T) { 4007 testFunction(t, Float, floatTests) 4008 } 4009 4010 var booleanTests = []functionTest{ 4011 { 4012 Name: "Boolean from String", 4013 Function: parser.Function{ 4014 Name: "boolean", 4015 }, 4016 Args: []value.Primary{ 4017 value.NewString("true"), 4018 }, 4019 Result: value.NewBoolean(true), 4020 }, 4021 { 4022 Name: "Boolean Arguments Error", 4023 Function: parser.Function{ 4024 Name: "boolean", 4025 }, 4026 Args: []value.Primary{}, 4027 Error: "function boolean takes exactly 1 argument", 4028 }, 4029 } 4030 4031 func TestBoolean(t *testing.T) { 4032 testFunction(t, Boolean, booleanTests) 4033 } 4034 4035 var ternaryTest = []functionTest{ 4036 { 4037 Name: "Ternary from String", 4038 Function: parser.Function{ 4039 Name: "ternary", 4040 }, 4041 Args: []value.Primary{ 4042 value.NewString("true"), 4043 }, 4044 Result: value.NewTernary(ternary.TRUE), 4045 }, 4046 { 4047 Name: "Ternary Arguments Error", 4048 Function: parser.Function{ 4049 Name: "ternary", 4050 }, 4051 Args: []value.Primary{}, 4052 Error: "function ternary takes exactly 1 argument", 4053 }, 4054 } 4055 4056 func TestTernary(t *testing.T) { 4057 testFunction(t, Ternary, ternaryTest) 4058 } 4059 4060 var datetimeTests = []functionTest{ 4061 { 4062 Name: "Datetime", 4063 Function: parser.Function{ 4064 Name: "datetime", 4065 }, 4066 Args: []value.Primary{ 4067 value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 0, GetTestLocation())), 4068 }, 4069 Result: value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 0, GetTestLocation())), 4070 }, 4071 { 4072 Name: "Datetime from Integer", 4073 Function: parser.Function{ 4074 Name: "datetime", 4075 }, 4076 Args: []value.Primary{ 4077 value.NewInteger(1136181845), 4078 }, 4079 Result: value.NewDatetime(time.Date(2006, 1, 2, 6, 4, 5, 0, GetTestLocation())), 4080 }, 4081 { 4082 Name: "Datetime from Float", 4083 Function: parser.Function{ 4084 Name: "datetime", 4085 }, 4086 Args: []value.Primary{ 4087 value.NewFloat(1136181845.123), 4088 }, 4089 Result: value.NewDatetime(time.Date(2006, 1, 2, 6, 4, 5, 123000000, GetTestLocation())), 4090 }, 4091 { 4092 Name: "Datetime Invalid Float Value", 4093 Function: parser.Function{ 4094 Name: "datetime", 4095 }, 4096 Args: []value.Primary{ 4097 value.NewFloat(math.NaN()), 4098 }, 4099 Result: value.NewNull(), 4100 }, 4101 { 4102 Name: "Datetime from String", 4103 Function: parser.Function{ 4104 Name: "datetime", 4105 }, 4106 Args: []value.Primary{ 4107 value.NewString("2012-02-03 09:18:15"), 4108 }, 4109 Result: value.NewDatetime(time.Date(2012, 2, 3, 9, 18, 15, 0, GetTestLocation())), 4110 }, 4111 { 4112 Name: "Datetime from String representing Integer", 4113 Function: parser.Function{ 4114 Name: "datetime", 4115 }, 4116 Args: []value.Primary{ 4117 value.NewString("1136181845"), 4118 }, 4119 Result: value.NewDatetime(time.Date(2006, 1, 2, 6, 4, 5, 0, GetTestLocation())), 4120 }, 4121 { 4122 Name: "Datetime from String representing Float", 4123 Function: parser.Function{ 4124 Name: "datetime", 4125 }, 4126 Args: []value.Primary{ 4127 value.NewString("1136181845.123"), 4128 }, 4129 Result: value.NewDatetime(time.Date(2006, 1, 2, 6, 4, 5, 123000000, GetTestLocation())), 4130 }, 4131 { 4132 Name: "Datetime from String with time zone conversion", 4133 Function: parser.Function{ 4134 Name: "datetime", 4135 }, 4136 Args: []value.Primary{ 4137 value.NewString("2012-02-03T09:18:15-07:00"), 4138 value.NewString(TestLocation), 4139 }, 4140 Result: value.NewDatetime(time.Date(2012, 2, 3, 16, 18, 15, 0, GetTestLocation())), 4141 }, 4142 { 4143 Name: "Datetime Invalid String", 4144 Function: parser.Function{ 4145 Name: "datetime", 4146 }, 4147 Args: []value.Primary{ 4148 value.NewString("abcde"), 4149 }, 4150 Result: value.NewNull(), 4151 }, 4152 { 4153 Name: "Datetime Arguments Error", 4154 Function: parser.Function{ 4155 Name: "datetime", 4156 }, 4157 Args: []value.Primary{}, 4158 Error: "function datetime takes 1 or 2 arguments", 4159 }, 4160 { 4161 Name: "Datetime Second Argument Not String Error", 4162 Function: parser.Function{ 4163 Name: "datetime", 4164 }, 4165 Args: []value.Primary{ 4166 value.NewString("2012-02-03T09:18:15-07:00"), 4167 value.NewNull(), 4168 }, 4169 Error: "failed to load time zone NULL for function datetime", 4170 }, 4171 { 4172 Name: "Datetime Second Argument Invalid Location Error", 4173 Function: parser.Function{ 4174 Name: "datetime", 4175 }, 4176 Args: []value.Primary{ 4177 value.NewString("2012-02-03T09:18:15-07:00"), 4178 value.NewString("Err"), 4179 }, 4180 Error: "failed to load time zone 'Err' for function datetime", 4181 }, 4182 } 4183 4184 func TestDatetime(t *testing.T) { 4185 testFunction(t, Datetime, datetimeTests) 4186 } 4187 4188 var callTests = []functionTest{ 4189 { 4190 Name: "Call Argument Error", 4191 Function: parser.Function{ 4192 Name: "call", 4193 }, 4194 Args: []value.Primary{}, 4195 Error: "function call takes at least 1 argument", 4196 }, 4197 { 4198 Name: "Call Command Error", 4199 Function: parser.Function{ 4200 Name: "call", 4201 }, 4202 Args: []value.Primary{ 4203 value.NewString("notexistcommand"), 4204 }, 4205 Error: "environment-dependent", 4206 }, 4207 } 4208 4209 func TestCall(t *testing.T) { 4210 ctx := context.Background() 4211 for _, v := range callTests { 4212 result, err := Call(ctx, v.Function, v.Args) 4213 if err != nil { 4214 if len(v.Error) < 1 { 4215 t.Errorf("%s: unexpected error %q", v.Name, err) 4216 } else if v.Error != "environment-dependent" && err.Error() != v.Error { 4217 t.Errorf("%s: error %q, want error %q", v.Name, err.Error(), v.Error) 4218 } 4219 continue 4220 } 4221 if 0 < len(v.Error) { 4222 t.Errorf("%s: no error, want error %q", v.Name, v.Error) 4223 continue 4224 } 4225 if !reflect.DeepEqual(result, v.Result) { 4226 t.Errorf("%s: result = %s, want %s", v.Name, result, v.Result) 4227 } 4228 } 4229 } 4230 4231 var nowTests = []struct { 4232 Name string 4233 Function parser.Function 4234 Args []value.Primary 4235 Scope *ReferenceScope 4236 Result value.Primary 4237 Error string 4238 }{ 4239 { 4240 Name: "Now From Current Time", 4241 Function: parser.Function{ 4242 Name: "now", 4243 }, 4244 Scope: NewReferenceScope(TestTx), 4245 Result: value.NewDatetime(NowForTest), 4246 }, 4247 { 4248 Name: "Now From Filter", 4249 Function: parser.Function{ 4250 Name: "now", 4251 }, 4252 Scope: GenerateReferenceScope(nil, nil, time.Date(2013, 2, 3, 0, 0, 0, 0, GetTestLocation()), nil), 4253 Result: value.NewDatetime(time.Date(2013, 2, 3, 0, 0, 0, 0, GetTestLocation())), 4254 }, 4255 { 4256 Name: "Now Arguments Error", 4257 Function: parser.Function{ 4258 Name: "now", 4259 }, 4260 Args: []value.Primary{ 4261 value.NewInteger(1), 4262 }, 4263 Scope: NewReferenceScope(TestTx), 4264 Error: "function now takes no argument", 4265 }, 4266 } 4267 4268 func TestNow(t *testing.T) { 4269 initFlag(TestTx.Flags) 4270 for _, v := range nowTests { 4271 result, err := Now(v.Scope, v.Function, v.Args) 4272 if err != nil { 4273 if len(v.Error) < 1 { 4274 t.Errorf("%s: unexpected error %q", v.Name, err) 4275 } else if err.Error() != v.Error { 4276 t.Errorf("%s: error %q, want error %q", v.Name, err.Error(), v.Error) 4277 } 4278 continue 4279 } 4280 if 0 < len(v.Error) { 4281 t.Errorf("%s: no error, want error %q", v.Name, v.Error) 4282 continue 4283 } 4284 if !reflect.DeepEqual(result, v.Result) { 4285 t.Errorf("%s: result = %s, want %s", v.Name, result, v.Result) 4286 } 4287 } 4288 } 4289 4290 var jsonObjectTests = []struct { 4291 Name string 4292 Function parser.Function 4293 ScientificNotation bool 4294 Scope *ReferenceScope 4295 Result value.Primary 4296 Error string 4297 }{ 4298 { 4299 Name: "Json Object", 4300 Function: parser.Function{ 4301 Name: "json_object", 4302 Args: []parser.QueryExpression{ 4303 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 4304 }, 4305 }, 4306 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 4307 { 4308 view: &View{ 4309 Header: NewHeaderWithId("table1", []string{"column1", "column2"}), 4310 RecordSet: []Record{ 4311 NewRecordWithId(0, []value.Primary{value.NewInteger(1), value.NewInteger(2)}), 4312 NewRecordWithId(1, []value.Primary{value.NewInteger(11), value.NewInteger(12)}), 4313 }, 4314 }, 4315 recordIndex: 1, 4316 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 4317 }, 4318 }), 4319 Result: value.NewString("{\"column1\":11}"), 4320 }, 4321 { 4322 Name: "Json Object using Scientific Notation", 4323 Function: parser.Function{ 4324 Name: "json_object", 4325 Args: []parser.QueryExpression{ 4326 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 4327 }, 4328 }, 4329 ScientificNotation: true, 4330 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 4331 { 4332 view: &View{ 4333 Header: NewHeaderWithId("table1", []string{"column1", "column2"}), 4334 RecordSet: []Record{ 4335 NewRecordWithId(0, []value.Primary{value.NewInteger(1), value.NewInteger(2)}), 4336 NewRecordWithId(1, []value.Primary{value.NewFloat(0.00000123), value.NewInteger(12)}), 4337 }, 4338 }, 4339 recordIndex: 1, 4340 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 4341 }, 4342 }), 4343 Result: value.NewString("{\"column1\":1.23e-06}"), 4344 }, 4345 { 4346 Name: "Json Object with All Columns", 4347 Function: parser.Function{ 4348 Name: "json_object", 4349 }, 4350 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 4351 { 4352 view: &View{ 4353 Header: NewHeaderWithId("table1", []string{"column1", "column2.child1"}), 4354 RecordSet: []Record{ 4355 NewRecordWithId(0, []value.Primary{value.NewInteger(1), value.NewInteger(2)}), 4356 NewRecordWithId(1, []value.Primary{value.NewInteger(11), value.NewInteger(12)}), 4357 }, 4358 }, 4359 recordIndex: 1, 4360 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 4361 }, 4362 }), 4363 Result: value.NewString("{\"column1\":11,\"column2\":{\"child1\":12}}"), 4364 }, 4365 { 4366 Name: "Json Object Unpermitted Statement Error", 4367 Function: parser.Function{ 4368 Name: "json_object", 4369 Args: []parser.QueryExpression{ 4370 parser.Field{Object: parser.FieldReference{Column: parser.Identifier{Literal: "column1"}}}, 4371 }, 4372 }, 4373 Scope: NewReferenceScope(TestTx), 4374 Result: value.NewNull(), 4375 }, 4376 { 4377 Name: "Json Object Path Error", 4378 Function: parser.Function{ 4379 Name: "json_object", 4380 }, 4381 Scope: GenerateReferenceScope(nil, nil, time.Time{}, []ReferenceRecord{ 4382 { 4383 view: &View{ 4384 Header: NewHeaderWithId("table1", []string{"column1", "column2.."}), 4385 RecordSet: []Record{ 4386 NewRecordWithId(0, []value.Primary{value.NewInteger(1), value.NewInteger(2)}), 4387 NewRecordWithId(1, []value.Primary{value.NewInteger(11), value.NewInteger(12)}), 4388 }, 4389 }, 4390 recordIndex: 1, 4391 cache: NewFieldIndexCache(10, LimitToUseFieldIndexSliceChache), 4392 }, 4393 }), 4394 Error: "unexpected token \".\" at column 9 in \"column2..\" for function json_object", 4395 }, 4396 } 4397 4398 func TestJsonObject(t *testing.T) { 4399 defer func() { 4400 TestTx.Flags.ExportOptions.ScientificNotation = false 4401 }() 4402 4403 for _, v := range jsonObjectTests { 4404 if v.Scope == nil { 4405 v.Scope = NewReferenceScope(TestTx) 4406 } 4407 4408 TestTx.Flags.ExportOptions.ScientificNotation = v.ScientificNotation 4409 4410 result, err := JsonObject(context.Background(), v.Scope, v.Function) 4411 if err != nil { 4412 if len(v.Error) < 1 { 4413 t.Errorf("%s: unexpected error %q", v.Name, err) 4414 } else if err.Error() != v.Error { 4415 t.Errorf("%s: error %q, want error %q", v.Name, err.Error(), v.Error) 4416 } 4417 continue 4418 } 4419 if 0 < len(v.Error) { 4420 t.Errorf("%s: no error, want error %q", v.Name, v.Error) 4421 continue 4422 } 4423 if !reflect.DeepEqual(result, v.Result) { 4424 t.Errorf("%s: result = %s, want %s", v.Name, result, v.Result) 4425 } 4426 } 4427 }