test: shlist tests
authorMarko Kreen <markokr@gmail.com>
Mon, 31 Jan 2011 09:53:09 +0000 (11:53 +0200)
committerMarko Kreen <markokr@gmail.com>
Mon, 31 Jan 2011 09:53:09 +0000 (11:53 +0200)
test/Makefile
test/test_common.c
test/test_common.h
test/test_shlist.c [new file with mode: 0644]

index 6f1fb038594f61e1b7fdbd4ccabf9b855f2a296b..89f26e71e1f39c56e6e64e9b80410edc2046938c 100644 (file)
@@ -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
+
index 2f5c0d0cf40b33a7f7b16a3fbff95901b86f350b..505cbb8c63f98ff442338972a043b5e791d5b231 100644 (file)
@@ -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 },
index 6a88a98c6c57bac8d91e7277e299c72e4ecdb0e0..0af3d689e9d68b848df6405e997bb399258aba88 100644 (file)
@@ -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 (file)
index 0000000..118e7b0
--- /dev/null
@@ -0,0 +1,148 @@
+#include <usual/shlist.h>
+
+#include "test_common.h"
+
+#include <usual/string.h>
+
+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
+};
+