From 36a32a0f6af18b00f789a8dc671a889c617ce10b Mon Sep 17 00:00:00 2001 From: Marko Kreen Date: Mon, 31 Jan 2011 11:53:09 +0200 Subject: [PATCH] test: shlist tests --- test/Makefile | 11 +++- test/test_common.c | 1 + test/test_common.h | 1 + test/test_shlist.c | 148 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 test/test_shlist.c diff --git a/test/Makefile b/test/Makefile index 6f1fb03..89f26e7 100644 --- a/test/Makefile +++ b/test/Makefile @@ -4,7 +4,8 @@ SRCS = test_string.c test_crypto.c test_aatree.c test_heap.c \ test_common.c test_list.c tinytest.c test_cbtree.c \ test_utf8.c test_strpool.c test_pgutil.c test_regex.c \ test_cxalloc.c test_bits.c test_base.c test_netdb.c \ - test_cfparser.c test_endian.c test_hashtab.c test_mdict.c + test_cfparser.c test_endian.c test_hashtab.c test_mdict.c \ + test_shlist.c OBJS = $(addprefix obj/, $(SRCS:.c=.o)) HDRS = test_common.h test_config.h tinytest.h tinytest_macros.h LIBS = @@ -50,7 +51,7 @@ regtest: $(objs) $(Q) $(CC) -o $@ $(objs) $(LIBS) clean: - rm -f libusual.a obj/* *.o regtest + rm -f libusual.a obj/* *.o regtest *.gcov rm -f config.test usual/config.h test_config.h rm -f regtest.compat regtest.system rm -f libusual_compat.a libusual_system.a @@ -73,3 +74,9 @@ test: regtest vcheck: regtest valgrind --leak-check=full ./regtest +BADGC = ../usual/base.c ../usual/signal.c +gc: + make clean all CC="$(CC) -fprofile-arcs -ftest-coverage" + ./regtest + gcov -f -o obj $(SRCS) $(filter-out $(BADGC), $(USUAL_SRCS)) > gc.log + diff --git a/test/test_common.c b/test/test_common.c index 2f5c0d0..505cbb8 100644 --- a/test/test_common.c +++ b/test/test_common.c @@ -14,6 +14,7 @@ struct testgroup_t groups[] = { { "heap/", heap_tests }, { "hashtab/", hashtab_tests }, { "list/", list_tests }, + { "shlist/", shlist_tests }, { "utf8/", utf8_tests }, { "strpool/", strpool_tests }, { "pgutil/", pgutil_tests }, diff --git a/test/test_common.h b/test/test_common.h index 6a88a98..0af3d68 100644 --- a/test/test_common.h +++ b/test/test_common.h @@ -26,4 +26,5 @@ extern struct testcase_t cfparser_tests[]; extern struct testcase_t endian_tests[]; extern struct testcase_t hashtab_tests[]; extern struct testcase_t mdict_tests[]; +extern struct testcase_t shlist_tests[]; diff --git a/test/test_shlist.c b/test/test_shlist.c new file mode 100644 index 0000000..118e7b0 --- /dev/null +++ b/test/test_shlist.c @@ -0,0 +1,148 @@ +#include + +#include "test_common.h" + +#include + +struct MyNode { + struct SHList node; + char val[16]; +}; + +static const char *xval(const struct SHList *elem) +{ + const struct MyNode *n; + if (!elem) return NULL; + n = container_of(elem, struct MyNode, node); + return n->val; +} + +static struct MyNode *new_node(int v) +{ + struct MyNode *n = malloc(sizeof(*n)); + if (!n) return NULL; + shlist_init(&n->node); + snprintf(n->val, sizeof(n->val), "%d", v); + return n; +} + +static const char *check_list(const struct SHList *list) +{ + const struct SHList *old, *cur; + + old = NULL; + for (cur = shlist_next(list, list); cur != list; cur = shlist_next(list, cur)) { + if (old) { + if (shlist_prev(list, cur) != old) + return "FAIL 1"; + } else { + if (shlist_prev(list, cur) != list) + return "FAIL 2"; + } + old = cur; + } + if (shlist_prev(list, list) != ((old) ? old : list)) + return "FAIL 3"; + return "OK"; +} + +static const char *xshow(const struct SHList *list) +{ + static char res[1024]; + struct SHList *el; + const char *ck = check_list(list); + + if (strcmp(ck, "OK") != 0) + return ck; + + res[0] = 0; + shlist_for_each(el, list) { + if (res[0]) + strcat(res, ","); + strcat(res, xval(el)); + } + return res; +} + +static const char *xadd(struct SHList *list, int v) +{ + struct MyNode *n = new_node(v); + if (!n) return "FAIL"; + shlist_append(list, &n->node); + return xshow(list); +} + +static const char *xadd1(struct SHList *list, int v) +{ + struct MyNode *n = new_node(v); + if (!n) return "FAIL"; + shlist_prepend(list, &n->node); + return xshow(list); +} + +static const char *xdel(struct SHList *list, int v) +{ + char buf[32]; + struct SHList *el, *tmp; + struct MyNode *n; + snprintf(buf, sizeof(buf), "%d", v); + shlist_for_each_safe(el, list, tmp) { + n = container_of(el, struct MyNode, node); + if (strcmp(buf, n->val) == 0) { + shlist_remove(list, el); + free(n); + } + } + if (!check_list(list)) + return "FAIL"; + return xshow(list); +} + +static void test_shlist(void *p) +{ + struct SHList rlist, *list = &rlist; + shlist_init(list); + str_check(check_list(list), "OK"); + str_check(xadd(list, 2), "2"); + str_check(xadd1(list, 1), "1,2"); + str_check(xadd(list, 3), "1,2,3"); + str_check(xadd(list, 4), "1,2,3,4"); + str_check(check_list(list), "OK"); + + { + struct MyNode *n; + str_check(xadd1(list, 0), "0,1,2,3,4"); + n = shlist_pop_type(list, struct MyNode, node); + str_check(n->val, "0"); + free(n); + } + + { + struct MyNode *n; + struct SHList *el; + str_check(xadd1(list, 0), "0,1,2,3,4"); + el = shlist_pop(list); + n = container_of(el, struct MyNode, node); + str_check(n->val, "0"); + free(n); + } + + + str_check(xval(shlist_first(list)), "1"); + str_check(xval(shlist_last(list)), "4"); + int_check(shlist_empty(list), 0); + + str_check(xdel(list, 2), "1,3,4"); + str_check(xdel(list, 1), "3,4"); + str_check(xdel(list, 4), "3"); + str_check(xdel(list, 3), ""); + str_check(check_list(list), "OK"); + int_check(shlist_empty(list), 1); +end:; +} + +struct testcase_t shlist_tests[] = { + { "basic", test_shlist }, + END_OF_TESTCASES +}; + -- 2.39.5