add test coverage for unlinking tree nodes w/o prev pointer default tip

Sat, 19 Oct 2024 13:21:58 +0200

author
Mike Becker <universe@uap-core.de>
date
Sat, 19 Oct 2024 13:21:58 +0200
changeset 931
be71809e69d1
parent 930
6540096c17b7

add test coverage for unlinking tree nodes w/o prev pointer

tests/test_tree.c file | annotate | diff | comparison | revisions
--- a/tests/test_tree.c	Sat Oct 19 13:08:06 2024 +0200
+++ b/tests/test_tree.c	Sat Oct 19 13:21:58 2024 +0200
@@ -103,6 +103,9 @@
 #define tree_node_layout \
     offsetof(tree_node, parent), offsetof(tree_node, children), -1, \
     offsetof(tree_node, prev), offsetof(tree_node, next)
+#define tree_node_layout_no_prev \
+    offsetof(tree_node, parent), offsetof(tree_node, children), -1, -1, \
+    offsetof(tree_node, next)
 #define tree_node_full_layout(structname) \
     offsetof(structname, parent), offsetof(structname, children),\
     offsetof(structname, last_child), \
@@ -199,8 +202,10 @@
     tree_node child1 = {0};
     tree_node child2 = {0};
     tree_node child3 = {0};
+    tree_node child4 = {0};
     cx_tree_link(&parent, &child1, tree_node_layout);
     cx_tree_link(&parent, &child3, tree_node_layout);
+    cx_tree_link(&parent, &child4, tree_node_layout);
     cx_tree_link(&child3, &child2, tree_node_layout);
 
     CX_TEST_DO {
@@ -214,7 +219,12 @@
         CX_TEST_ASSERT(child1.parent == &parent);
         CX_TEST_ASSERT(child1.children == NULL);
         CX_TEST_ASSERT(child1.prev == NULL);
-        CX_TEST_ASSERT(child1.next == NULL);
+        CX_TEST_ASSERT(child1.next == &child4);
+
+        CX_TEST_ASSERT(child4.parent == &parent);
+        CX_TEST_ASSERT(child4.children == NULL);
+        CX_TEST_ASSERT(child4.prev == &child1);
+        CX_TEST_ASSERT(child4.next == NULL);
 
         // child 3 is unlinked
         CX_TEST_ASSERT(child3.parent == NULL);
@@ -228,13 +238,64 @@
         CX_TEST_ASSERT(child2.prev == NULL);
         CX_TEST_ASSERT(child2.next == NULL);
 
-        // unlink last child from parent
+        // unlink first child from parent
         cx_tree_unlink(&child1, tree_node_layout);
         CX_TEST_ASSERT(parent.next == NULL);
         CX_TEST_ASSERT(parent.prev == NULL);
         CX_TEST_ASSERT(parent.parent == NULL);
-        CX_TEST_ASSERT(parent.children == NULL);
+        CX_TEST_ASSERT(parent.children == &child4);
         CX_TEST_ASSERT(child1.parent == NULL);
+        CX_TEST_ASSERT(child4.parent == &parent);
+        CX_TEST_ASSERT(child4.children == NULL);
+        CX_TEST_ASSERT(child4.prev == NULL);
+        CX_TEST_ASSERT(child4.next == NULL);
+    }
+}
+
+CX_TEST(test_tree_unlink_no_prev) {
+    tree_node parent = {0};
+    tree_node child1 = {0};
+    tree_node child2 = {0};
+    tree_node child3 = {0};
+    tree_node child4 = {0};
+    cx_tree_link(&parent, &child1, tree_node_layout_no_prev);
+    cx_tree_link(&parent, &child3, tree_node_layout_no_prev);
+    cx_tree_link(&parent, &child4, tree_node_layout_no_prev);
+    cx_tree_link(&child3, &child2, tree_node_layout_no_prev);
+    void * const marker = (void*) 0xc0ffee;
+    child1.prev = child2.prev = child3.prev = child4.prev = marker;
+
+    CX_TEST_DO {
+        // in contrast to the other test we here remove child 4 instead of 3!
+        cx_tree_unlink(&child4, tree_node_layout_no_prev);
+
+        CX_TEST_ASSERT(parent.next == NULL);
+        CX_TEST_ASSERT(parent.prev == NULL);
+        CX_TEST_ASSERT(parent.parent == NULL);
+        CX_TEST_ASSERT(parent.children == &child1);
+
+        CX_TEST_ASSERT(child1.parent == &parent);
+        CX_TEST_ASSERT(child1.children == NULL);
+        CX_TEST_ASSERT(child1.prev == marker);
+        CX_TEST_ASSERT(child1.next == &child3);
+
+        // child 4 is unlinked
+        CX_TEST_ASSERT(child4.parent == NULL);
+        CX_TEST_ASSERT(child4.children == NULL);
+        CX_TEST_ASSERT(child4.prev == marker);
+        CX_TEST_ASSERT(child4.next == NULL);
+
+        // unlink first child from parent
+        cx_tree_unlink(&child1, tree_node_layout_no_prev);
+        CX_TEST_ASSERT(parent.next == NULL);
+        CX_TEST_ASSERT(parent.prev == NULL);
+        CX_TEST_ASSERT(parent.parent == NULL);
+        CX_TEST_ASSERT(parent.children == &child3);
+        CX_TEST_ASSERT(child1.parent == NULL);
+        CX_TEST_ASSERT(child3.parent == &parent);
+        CX_TEST_ASSERT(child3.children == &child2);
+        CX_TEST_ASSERT(child3.prev == marker);
+        CX_TEST_ASSERT(child3.next == NULL);
     }
 }
 
@@ -2148,6 +2209,7 @@
     cx_test_register(suite, test_tree_link_add_child);
     cx_test_register(suite, test_tree_link_move_to_other_parent);
     cx_test_register(suite, test_tree_unlink);
+    cx_test_register(suite, test_tree_unlink_no_prev);
     cx_test_register(suite, test_tree2_link_new_child);
     cx_test_register(suite, test_tree2_link_add_child);
     cx_test_register(suite, test_tree2_link_move_to_other_parent);

mercurial