From 5d3913c7a983ea71f0f9aceedee7dd59c018cf4d Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Fri, 27 Jul 2018 13:25:57 +0000 Subject: [PATCH] Feature: Added tests for resourcematch.c --- tests/Makefile.am | 6 +- tests/ctest_resourcematch.c | 173 ++++++++++++++++++++++++++++++++++++ 2 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 tests/ctest_resourcematch.c diff --git a/tests/Makefile.am b/tests/Makefile.am index fa1aecb5..48c8eccf 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -6,7 +6,8 @@ TEST_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \ TESTS = \ startup.test \ admin.test \ - ctest_suite.test + ctest_suite.test \ + ctest_resourcematch.test EXTRA_DIST = $(TESTS) @@ -14,7 +15,8 @@ EXTRA_DIST += \ icecast.xml \ on-connect.sh -check_PROGRAMS = ctest_suite.test +check_PROGRAMS = ctest_suite.test ctest_resourcematch.test noinst_HEADERS = ctest_lib.h ctest_suite_test_SOURCES=ctest_suite.c ctest_lib.c +ctest_resourcematch_test_SOURCES=ctest_resourcematch.c ctest_lib.c ../src/resourcematch.c diff --git a/tests/ctest_resourcematch.c b/tests/ctest_resourcematch.c new file mode 100644 index 00000000..00fb1316 --- /dev/null +++ b/tests/ctest_resourcematch.c @@ -0,0 +1,173 @@ +/* Icecast + * + * This program is distributed under the GNU General Public License, version 2. + * A copy of this license is included with this source. + * + * Copyright 2018, Philipp "ph3-der-loewe" Schafft , + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include /* for NULL */ +#include /* for snprintf() */ + +#include "ctest_lib.h" + +#include "../src/resourcematch.h" + +struct test { + const char *pattern; + const char *string; + resourcematch_result_t expected_result; +}; + +static const struct test tests[] = { + {NULL, NULL, RESOURCEMATCH_ERROR}, + {"", NULL, RESOURCEMATCH_ERROR}, + {NULL, "", RESOURCEMATCH_ERROR}, + {"", "", RESOURCEMATCH_MATCH}, + {"a", "a", RESOURCEMATCH_MATCH}, + {"aa", "b", RESOURCEMATCH_NOMATCH}, + {"aa", "ab", RESOURCEMATCH_NOMATCH}, + {"aa", "ba", RESOURCEMATCH_NOMATCH}, + {"aa", "aa", RESOURCEMATCH_MATCH}, + {"a/a", "a/a", RESOURCEMATCH_MATCH}, + {"a/%%a", "a/%a", RESOURCEMATCH_MATCH}, + + {"a/%i", "a/0", RESOURCEMATCH_MATCH}, + {"a/%i", "a/1", RESOURCEMATCH_MATCH}, + + {"a/%i", "a/12", RESOURCEMATCH_MATCH}, + {"a/%i", "a/0x12", RESOURCEMATCH_MATCH}, + {"a/%i", "a/012", RESOURCEMATCH_MATCH}, + + {"a/%d", "a/12", RESOURCEMATCH_MATCH}, + {"a/%d", "a/0x12", RESOURCEMATCH_NOMATCH}, + {"a/%d", "a/012", RESOURCEMATCH_MATCH}, + + {"a/%x", "a/12", RESOURCEMATCH_MATCH}, + {"a/%x", "a/0x12", RESOURCEMATCH_MATCH}, + {"a/%x", "a/012", RESOURCEMATCH_MATCH}, + + {"a/%o", "a/12", RESOURCEMATCH_MATCH}, + {"a/%o", "a/0x12", RESOURCEMATCH_NOMATCH}, + {"a/%o", "a/012", RESOURCEMATCH_MATCH}, + + {"a/%i/b", "a/X/b", RESOURCEMATCH_NOMATCH}, + + {"a/%d/b", "a/12/b", RESOURCEMATCH_MATCH}, + {"a/%d/b", "a/0x12/b", RESOURCEMATCH_NOMATCH}, + {"a/%d/b", "a/012/b", RESOURCEMATCH_MATCH}, + + {"a/%x/b", "a/12/b", RESOURCEMATCH_MATCH}, + {"a/%x/b", "a/0x12/b", RESOURCEMATCH_MATCH}, + {"a/%x/b", "a/012/b", RESOURCEMATCH_MATCH}, + + {"a/%o/b", "a/12/b", RESOURCEMATCH_MATCH}, + {"a/%o/b", "a/0x12/b", RESOURCEMATCH_NOMATCH}, + {"a/%o/b", "a/012/b", RESOURCEMATCH_MATCH}, + + {"a/%i/%i/b", "a/1/2/b", RESOURCEMATCH_MATCH} +}; + +static const char *res2str(resourcematch_result_t res) +{ + switch (res) { + case RESOURCEMATCH_ERROR: + return "error"; + break; + case RESOURCEMATCH_MATCH: + return "match"; + break; + case RESOURCEMATCH_NOMATCH: + return "nomatch"; + break; + default: + return ""; + break; + } +} + +static inline resourcematch_result_t run_test_base(const struct test *test, resourcematch_extract_t **extract) +{ + char name[128]; + resourcematch_result_t ret; + int ok = 1; + + ret = resourcematch_match(test->pattern, test->string, extract); + + //printf(" expected %s, got %s", res2str(test->expected_result), res2str(ret)); + + if (extract) { + if (test->expected_result == RESOURCEMATCH_MATCH) { + if (*extract) { + ctest_diagnostic(" got extract"); + } else { + ctest_diagnostic(" got no extract"); + ok = 0; + } + } + } + + snprintf(name, sizeof(name), "pattern \"%s\" and string \"%s\" %s extract", test->pattern, test->string, extract ? "with" : "without"); + ctest_test(name, test->expected_result == ret && ok); + + return ret; +} + +static inline void print_extract_group(resourcematch_extract_t *extract, size_t idx) +{ + switch (extract->group[idx].type) { + case 'i': + case 'd': + case 'x': + case 'o': + ctest_diagnostic_printf(" Group %zu, type \"%c\": value is %lli", idx, extract->group[idx].type, extract->group[idx].result.lli); + break; + default: + ctest_diagnostic_printf(" Group %zu, type \"%c\": ", idx, extract->group[idx].type, extract->group[idx].raw); + break; + } +} + +static inline void print_extract(resourcematch_extract_t *extract) +{ + size_t i; + + ctest_diagnostic_printf(" Extract with %zu groups:\n", extract->groups); + + for (i = 0; i < extract->groups; i++) { + print_extract_group(extract, i); + } +} + +static void run_test(const struct test *test) +{ + resourcematch_result_t ret; + resourcematch_extract_t *extract = NULL; + + run_test_base(test, NULL); + + ret = run_test_base(test, &extract); + if (extract) { + if (ret == RESOURCEMATCH_MATCH) + print_extract(extract); + + resourcematch_extract_free(extract); + } +} + +int main (void) +{ + size_t i; + + ctest_init(); + for (i = 0; i < (sizeof(tests)/sizeof(*tests)); i++) { + run_test(&(tests[i])); + } + ctest_fin(); + + return 0; +}