Mercurial > hg > th-libs
comparison tests.c @ 668:48e8820bc625
Some work on the regex tests.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 27 Jan 2020 19:23:06 +0200 |
parents | e1d27caf0dbd |
children | dbc71c000376 |
comparison
equal
deleted
inserted
replaced
667:039aa00cbfbf | 668:48e8820bc625 |
---|---|
566 | 566 |
567 #ifdef TH_EXPERIMENTAL_REGEX | 567 #ifdef TH_EXPERIMENTAL_REGEX |
568 | 568 |
569 typedef struct | 569 typedef struct |
570 { | 570 { |
571 th_char_t *str; | 571 const th_char_t *str; |
572 size_t nmatches; | 572 const int flags; |
573 int flags; | 573 const th_char_t *expected[4]; |
574 } test_regex_def1; | 574 } test_regex_def1; |
575 | 575 |
576 | 576 |
577 typedef struct | 577 typedef struct |
578 { | 578 { |
579 th_char_t *pattern; | 579 const th_char_t *pattern; |
580 th_char_t *str; | 580 const th_char_t *str; |
581 size_t nmatches; | 581 const int flags; |
582 int flags; | 582 const th_char_t *expected[4]; |
583 } test_regex_def2; | 583 } test_regex_def2; |
584 | 584 |
585 | 585 |
586 void test_regex_print_matches(const th_char_t *str, const th_regex_match_t *matches) | 586 BOOL test_regex_list_matches(const th_char_t *str, |
587 { | 587 const th_regex_match_t *matches, |
588 const th_char_t * const *expected, | |
589 const BOOL testOnly) | |
590 { | |
591 size_t nmatch = 0; | |
592 char *match = NULL; | |
593 | |
588 for (const th_regex_match_t *mt = matches; | 594 for (const th_regex_match_t *mt = matches; |
589 mt != NULL; mt = (th_regex_match_t *) mt->node.next) | 595 mt != NULL; |
590 { | 596 mt = (th_regex_match_t *) mt->node.next, |
591 char *tmp = th_strndup(str + mt->start, mt->len); | 597 nmatch++) |
592 | 598 { |
593 printf(" match [%3" PRIu_SIZE_T " ++ %3" PRIu_SIZE_T "]: '%s'\n", | 599 char *match = th_strndup(str + mt->start, mt->len); |
594 mt->start, mt->len, tmp); | 600 if (expected[nmatch] == NULL) |
595 | 601 { |
596 th_free(tmp); | 602 if (!testOnly) |
597 } | 603 { |
604 THERR("Expected[%" PRIu_SIZE_T "] == NULL, but match '%s' returned.\n", | |
605 nmatch, match); | |
606 } | |
607 | |
608 goto error; | |
609 } | |
610 else | |
611 { | |
612 BOOL seqMatch = strcmp(match, expected[nmatch]) == 0; | |
613 if (testOnly && !seqMatch) | |
614 goto error; | |
615 | |
616 if (th_verbosity >= 1 || !seqMatch) | |
617 { | |
618 tprint(0, " [%3" PRIu_SIZE_T " ++ %3" PRIu_SIZE_T "]: '%s' == '%s': %s\n", | |
619 mt->start, | |
620 mt->len, | |
621 match, | |
622 expected[nmatch], | |
623 seqMatch ? "YES" : "NO!"); | |
624 } | |
625 } | |
626 | |
627 th_free(match); | |
628 } | |
629 | |
630 return TRUE; | |
631 | |
632 error: | |
633 th_free(match); | |
634 return FALSE; | |
598 } | 635 } |
599 | 636 |
600 | 637 |
601 void test_regex_list1(const test_regex_def1 *list, const th_char_t *pattern) | 638 void test_regex_list1(const test_regex_def1 *list, const th_char_t *pattern) |
602 { | 639 { |
603 th_regex_t *expr = NULL; | 640 th_regex_t *expr = NULL; |
604 int res; | 641 int res; |
605 | 642 |
606 printf("\n========================================\n\n"); | |
607 printf("Compiling pattern \"%s\"\n", pattern); | |
608 if ((res = th_regex_compile(&expr, pattern)) != THERR_OK) | 643 if ((res = th_regex_compile(&expr, pattern)) != THERR_OK) |
609 { | 644 { |
610 THERR("Regex compilation failed: %s\n", | 645 THERR("Regex \"%s\" compilation failed: %s\n", |
646 pattern, | |
611 th_error_str(res)); | 647 th_error_str(res)); |
612 goto out; | 648 goto out; |
613 } | 649 } |
614 | 650 |
615 if (th_verbosity > 0) | 651 tprint(1, "\n----------------------------------------\n" |
652 "\"%s\"\n", pattern); | |
653 | |
654 if (th_verbosity >= 2) | |
616 th_regex_dump(&testio, 1, expr); | 655 th_regex_dump(&testio, 1, expr); |
617 | 656 |
618 for (const test_regex_def1 *def = list; def->str != NULL; def++) | 657 for (const test_regex_def1 *def = list; def->str != NULL; def++) |
619 { | 658 { |
620 th_regex_match_t *matches = NULL; | 659 th_regex_match_t *matches = NULL; |
621 size_t nmatches; | 660 size_t nmatches; |
622 | 661 BOOL matchOK; |
623 printf("\n----------------------------------------\n"); | 662 |
663 tprint(3, "\n----------------------------------------\n"); | |
624 if ((res = th_regex_match(expr, def->str, | 664 if ((res = th_regex_match(expr, def->str, |
625 &nmatches, &matches, -1, def->flags)) != THERR_OK) | 665 &nmatches, &matches, -1, def->flags)) != THERR_OK) |
626 { | 666 { |
627 THERR("Regex match returned error: %s\n", | 667 THERR("Regex match returned error: %s\n", |
628 th_error_str(res)); | 668 th_error_str(res)); |
629 goto out; | 669 goto out; |
630 } | 670 } |
631 | 671 |
632 printf("'%s': matched %" PRIu_SIZE_T " time(s), testresult=%s\n", | 672 matchOK = test_regex_list_matches(def->str, matches, def->expected, TRUE); |
633 def->str, | 673 if (th_verbosity < 1 && !matchOK) |
634 nmatches, | 674 { |
635 def->nmatches == nmatches ? "YES" : "NO"); | 675 tprint(0, |
636 | 676 "\n----------------------------------------\n" |
637 test_regex_print_matches(def->str, matches); | 677 " \"%s\" vs \"%s\" failures:\n", |
678 def->str, pattern); | |
679 } | |
680 else | |
681 { | |
682 tprint(1, " \"%s\": matched %" PRIu_SIZE_T " time(s)\n", | |
683 def->str, | |
684 nmatches); | |
685 } | |
686 | |
687 #ifdef TH_EXPERIMENTAL_REGEX_DEBUG | |
688 if (!matchOK && th_dbg_fh == NULL) | |
689 { | |
690 th_dbg_fh = &testio; | |
691 th_regex_match(expr, def->str, NULL, NULL, -1, def->flags); | |
692 th_dbg_fh = NULL; | |
693 } | |
694 #endif | |
695 | |
696 test_regex_list_matches(def->str, matches, def->expected, FALSE); | |
697 | |
638 th_regex_free_matches(matches); | 698 th_regex_free_matches(matches); |
639 } | 699 } |
640 | 700 |
641 out: | 701 out: |
642 th_regex_free(expr); | 702 th_regex_free(expr); |
643 } | 703 } |
644 | 704 |
645 | 705 |
646 void test_regex_list2(const test_regex_def2 *list) | 706 void test_regex_list2(const test_regex_def2 *list) |
647 { | 707 { |
648 printf("\n========================================\n\n"); | |
649 | |
650 for (const test_regex_def2 *def = list; def->str != NULL; def++) | 708 for (const test_regex_def2 *def = list; def->str != NULL; def++) |
651 { | 709 { |
652 th_regex_t *expr = NULL; | 710 th_regex_t *expr = NULL; |
653 th_regex_match_t *matches = NULL; | 711 th_regex_match_t *matches = NULL; |
654 size_t nmatches; | 712 size_t nmatches; |
655 int res; | 713 int res; |
656 | 714 |
657 printf("Compiling pattern \"%s\"\n", def->pattern); | |
658 if ((res = th_regex_compile(&expr, def->pattern)) != THERR_OK) | 715 if ((res = th_regex_compile(&expr, def->pattern)) != THERR_OK) |
659 { | 716 { |
660 THERR("Regex compilation failed: %s\n", | 717 THERR("Regex \"%s\" compilation failed: %s\n", |
718 def->pattern, | |
661 th_error_str(res)); | 719 th_error_str(res)); |
662 goto out; | 720 goto out; |
663 } | 721 } |
664 | 722 |
665 if (th_verbosity > 0) | 723 if (th_verbosity >= 2) |
666 th_regex_dump(&testio, 1, expr); | 724 th_regex_dump(&testio, 1, expr); |
667 | 725 |
668 printf("----------------------------------------\n"); | 726 tprint(3, "----------------------------------------\n"); |
669 | 727 |
670 if ((res = th_regex_match(expr, def->str, | 728 if ((res = th_regex_match(expr, def->str, |
671 &nmatches, &matches, -1, def->flags)) != THERR_OK) | 729 &nmatches, &matches, -1, def->flags)) != THERR_OK) |
672 { | 730 { |
673 THERR("Regex match returned error: %s\n", | 731 THERR("Regex match returned error: %s\n", |
674 th_error_str(res)); | 732 th_error_str(res)); |
675 goto out; | 733 goto out; |
676 } | 734 } |
677 | 735 |
678 printf("'%s': matched %" PRIu_SIZE_T " time(s), testresult=%s\n", | 736 tprint(1, "\"%s\" vs \"%s\": matched %" PRIu_SIZE_T " time(s)\n", |
679 def->str, | 737 def->pattern, def->str, |
680 nmatches, | 738 nmatches); |
681 def->nmatches == nmatches ? "YES" : "NO"); | 739 |
682 | 740 test_regex_list_matches(def->str, matches, def->expected, FALSE); |
683 test_regex_print_matches(def->str, matches); | |
684 | 741 |
685 out: | 742 out: |
686 th_regex_free_matches(matches); | 743 th_regex_free_matches(matches); |
687 th_regex_free(expr); | 744 th_regex_free(expr); |
688 } | 745 } |
947 // Regular expressions | 1004 // Regular expressions |
948 // | 1005 // |
949 #ifdef TH_EXPERIMENTAL_REGEX | 1006 #ifdef TH_EXPERIMENTAL_REGEX |
950 if (test_set_start("Regular expressions")) | 1007 if (test_set_start("Regular expressions")) |
951 { | 1008 { |
952 | |
953 #ifdef TH_EXPERIMENTAL_REGEX_DEBUG | 1009 #ifdef TH_EXPERIMENTAL_REGEX_DEBUG |
954 if (th_verbosity > 0) | 1010 th_dbg_fh = (th_verbosity >= 3) ? &testio : NULL; |
955 th_dbg_fh = &testio; | |
956 #endif | 1011 #endif |
957 | 1012 |
1013 if (1) | |
958 { | 1014 { |
959 const char *str = "z*k+abba fabboa? [a-zA-Z_-] \\{\\} k{4} ([0-9]+ yay){1,2} foo(bar|zoo)?"; | 1015 const char *str = "z*k+abba fabboa? [a-zA-Z_-] \\{\\} k{4} ([0-9]+ yay){1,2} foo(bar|zoo)?"; |
960 th_regex_t *expr = NULL; | 1016 th_regex_t *expr = NULL; |
961 int res = th_regex_compile(&expr, str); | 1017 int res = th_regex_compile(&expr, str); |
962 | 1018 |
968 printf("ERROR: %s\n", th_error_str(res)); | 1024 printf("ERROR: %s\n", th_error_str(res)); |
969 | 1025 |
970 th_regex_free(expr); | 1026 th_regex_free(expr); |
971 } | 1027 } |
972 | 1028 |
1029 if (1) | |
973 { | 1030 { |
974 static const test_regex_def1 tlist[] = | 1031 static const test_regex_def1 tlist[] = |
975 { | 1032 { |
976 { "abcfoabcccg" , 1, 0 }, | 1033 { "abcfoabcccg" , 0, { "abcfoabcccg", } }, |
977 { "abcbcfoabcccg" , 1, 0 }, | 1034 { "sabcbcfoabcccgz" , 0, { "abcbcfoabcccg", } }, |
978 { "abcbcfoabccg abcbcfoabccccg" , 2, 0 }, | 1035 { "abcbcfoabccg abcbcfoabccccg" , 0, { "abcbcfoabccg", "abcbcfoabccccg" } }, |
979 { "ffdsafS abcbcfoabccg zasdf" , 1, 0 }, | 1036 { NULL , 0, { NULL } } |
980 { NULL , 0, 0 } | |
981 }; | 1037 }; |
982 | 1038 |
983 test_regex_list1(tlist, "a(bc){1,2}fo[oab]*cc?g"); | 1039 test_regex_list1(tlist, "a(bc){1,2}fo[oab]*cc?g"); |
984 } | 1040 } |
985 | 1041 |
1042 if (1) | |
986 { | 1043 { |
987 static const test_regex_def1 tlist[] = | 1044 static const test_regex_def1 tlist[] = |
988 { | 1045 { |
989 { "abcfoabccg" , 1, 0 }, | 1046 { "abcfoabccg" , 0, { "abcfoabccg", } }, |
990 { "abcbcfoabccg" , 1, 0 }, | 1047 { "abcbcfoabccg" , 0, { "abcbcfoabccg", } }, |
991 { "abcbcfoabccgabcbcfoabccg" , 1, 0 }, | 1048 { "abcbcfoabccgabcbcfoabccg" , 0, { "abcbcfoabccg", } }, |
992 { "ffdsafS abcbcfoabccg zasdf" , 0, 0 }, | 1049 { "ffdsafS abcbcfoabccg zasdf" , 0, { NULL } }, |
993 { NULL , 0, 0 } | 1050 { NULL , 0, { NULL } } |
994 }; | 1051 }; |
995 | 1052 |
996 test_regex_list1(tlist, "^a(bc){1,2}fo[oab]*cc?g"); | 1053 test_regex_list1(tlist, "^a(bc){1,2}fo[oab]*cc?g"); |
997 } | 1054 } |
998 | 1055 |
1056 if (1) | |
999 { | 1057 { |
1000 static const test_regex_def1 tlist[] = | 1058 static const test_regex_def1 tlist[] = |
1001 { | 1059 { |
1002 { "cg" , 1, 0 }, | 1060 { "cg" , 0, { "g", } }, |
1003 { "g" , 1, 0 }, | 1061 { "g" , 0, { "g", } }, |
1004 { "" , 0, 0 }, | 1062 { "" , 0, { NULL, } }, |
1005 { "c" , 0, 0 }, | 1063 { "c" , 0, { NULL, } }, |
1006 { NULL , 0, 0 } | 1064 { NULL , 0, { NULL } } |
1007 }; | 1065 }; |
1008 | 1066 |
1009 test_regex_list1(tlist, "g$"); | 1067 test_regex_list1(tlist, "g$"); |
1010 } | 1068 } |
1011 | 1069 |
1070 if (1) | |
1012 { | 1071 { |
1013 static const test_regex_def1 tlist[] = | 1072 static const test_regex_def1 tlist[] = |
1014 { | 1073 { |
1015 { "zoobar" , 1, 0 }, | 1074 { "kzoobarzz" , 0, { "zoobar", } }, |
1016 { "hehzoo lol baromg" , 1, 0 }, | 1075 { "hehzoo lol baromg" , 0, { "zoo lol bar", } }, |
1017 { "hoho zoo lol lol bar bar" , 1, 0 }, | 1076 { "hoho zoo lol lol bar bar f" , 0, { "zoo lol lol bar", } }, |
1018 { "hoho zoobar bar" , 1, 0 }, | 1077 { "hoho zoobar bar heh" , 0, { "zoobar", } }, |
1019 { NULL , 0, 0 } | 1078 { NULL , 0, { NULL } } |
1020 }; | 1079 }; |
1021 | 1080 |
1022 test_regex_list1(tlist, "zoo.*?bar"); | 1081 test_regex_list1(tlist, "zoo.*?bar"); |
1082 } | |
1083 | |
1084 if (1) | |
1085 { | |
1086 static const test_regex_def1 tlist[] = | |
1087 { | |
1088 { "kzoobarzz" , 0, { "zoobar", } }, | |
1089 { "hehzoo lol baromg" , 0, { "zoo lol bar", } }, | |
1090 { "hoho zoo lol lol bar bar f" , 0, { "zoo lol lol bar bar", } }, | |
1091 { "hoho zoobar bar heh" , 0, { "zoobar bar", } }, | |
1092 { NULL , 0, { NULL } } | |
1093 }; | |
1094 | |
1023 test_regex_list1(tlist, "zoo.*bar"); | 1095 test_regex_list1(tlist, "zoo.*bar"); |
1024 } | 1096 } |
1097 | |
1025 } | 1098 } |
1026 #endif | 1099 #endif |
1027 | 1100 |
1028 // | 1101 // |
1029 // Print summary and exit | 1102 // Print summary and exit |