1.1 --- a/tests/test_tree.c Thu Mar 14 22:07:19 2024 +0100 1.2 +++ b/tests/test_tree.c Wed Mar 20 23:31:41 2024 +0100 1.3 @@ -286,6 +286,14 @@ 1.4 tree_node cc = {0}; 1.5 tree_node cba = {0}; 1.6 1.7 + tree_node* expected_order[] = { 1.8 + &root, 1.9 + &c, &cc,&cb, &cba,&ca, 1.10 + &b, &ba, 1.11 + &a, &ab, &aa, 1.12 + }; 1.13 + tree_node* actual_order[16]; // reserve more space in case s.t. goes wrong 1.14 + 1.15 cx_tree_link(&root, &a, tree_node_layout); 1.16 cx_tree_link(&root, &b, tree_node_layout); 1.17 cx_tree_link(&root, &c, tree_node_layout); 1.18 @@ -302,6 +310,7 @@ 1.19 cx_foreach(tree_node*, node, iter) { 1.20 CX_TEST_ASSERT(node->data == 0); 1.21 node->data++; 1.22 + actual_order[chk] = node; 1.23 chk++; 1.24 CX_TEST_ASSERT(node == iter.node); 1.25 CX_TEST_ASSERT(!iter.exiting); 1.26 @@ -317,18 +326,11 @@ 1.27 } 1.28 CX_TEST_ASSERT(iter.counter == 11); 1.29 CX_TEST_ASSERT(chk == 11); 1.30 + for (unsigned i = 0 ; i < chk ; i++) { 1.31 + CX_TEST_ASSERT(actual_order[i] == expected_order[i]); 1.32 + CX_TEST_ASSERT(actual_order[i]->data == 1); 1.33 + } 1.34 CX_TEST_ASSERT(iter.stack == NULL); 1.35 - CX_TEST_ASSERT(root.data == 1); 1.36 - CX_TEST_ASSERT(a.data == 1); 1.37 - CX_TEST_ASSERT(b.data == 1); 1.38 - CX_TEST_ASSERT(c.data == 1); 1.39 - CX_TEST_ASSERT(aa.data == 1); 1.40 - CX_TEST_ASSERT(ab.data == 1); 1.41 - CX_TEST_ASSERT(ba.data == 1); 1.42 - CX_TEST_ASSERT(ca.data == 1); 1.43 - CX_TEST_ASSERT(cb.data == 1); 1.44 - CX_TEST_ASSERT(cc.data == 1); 1.45 - CX_TEST_ASSERT(cba.data == 1); 1.46 } 1.47 } 1.48 1.49 @@ -507,6 +509,120 @@ 1.50 cx_testing_allocator_destroy(&talloc); 1.51 } 1.52 1.53 +CX_TEST(test_tree_visitor) { 1.54 + tree_node root = {0}; 1.55 + tree_node a = {0}; 1.56 + tree_node b = {0}; 1.57 + tree_node c = {0}; 1.58 + tree_node aa = {0}; 1.59 + tree_node ab = {0}; 1.60 + tree_node ba = {0}; 1.61 + tree_node ca = {0}; 1.62 + tree_node cb = {0}; 1.63 + tree_node cc = {0}; 1.64 + tree_node cba = {0}; 1.65 + 1.66 + tree_node* expected_order[] = { 1.67 + &root, 1.68 + &c, &b, &a, 1.69 + &cc, &cb, &ca, &ba, &ab, &aa, 1.70 + &cba 1.71 + }; 1.72 + tree_node* actual_order[16]; // reserve more space in case s.t. goes wrong 1.73 + 1.74 + cx_tree_link(&root, &a, tree_node_layout); 1.75 + cx_tree_link(&root, &b, tree_node_layout); 1.76 + cx_tree_link(&root, &c, tree_node_layout); 1.77 + cx_tree_link(&a, &aa, tree_node_layout); 1.78 + cx_tree_link(&a, &ab, tree_node_layout); 1.79 + cx_tree_link(&b, &ba, tree_node_layout); 1.80 + cx_tree_link(&c, &ca, tree_node_layout); 1.81 + cx_tree_link(&c, &cb, tree_node_layout); 1.82 + cx_tree_link(&c, &cc, tree_node_layout); 1.83 + cx_tree_link(&cb, &cba, tree_node_layout); 1.84 + CX_TEST_DO { 1.85 + CxTreeVisitor iter = cx_tree_visitor(&root, tree_child_list); 1.86 + unsigned chk = 0; 1.87 + cx_foreach(tree_node*, node, iter) { 1.88 + CX_TEST_ASSERT(node->data == 0); 1.89 + node->data++; 1.90 + actual_order[chk] = node; 1.91 + chk++; 1.92 + CX_TEST_ASSERT(node == iter.node); 1.93 + if (node == &root) { 1.94 + CX_TEST_ASSERT(iter.depth == 1); 1.95 + } else if (node == &a || node == &b || node == &c) { 1.96 + CX_TEST_ASSERT(iter.depth == 2); 1.97 + } else if (node == &cba) { 1.98 + CX_TEST_ASSERT(iter.depth == 4); 1.99 + } else { 1.100 + CX_TEST_ASSERT(iter.depth == 3); 1.101 + } 1.102 + } 1.103 + CX_TEST_ASSERT(iter.counter == 11); 1.104 + CX_TEST_ASSERT(chk == 11); 1.105 + for (unsigned i = 0 ; i < chk ; i++) { 1.106 + CX_TEST_ASSERT(actual_order[i] == expected_order[i]); 1.107 + CX_TEST_ASSERT(actual_order[i]->data == 1); 1.108 + } 1.109 + CX_TEST_ASSERT(iter.queue_next == NULL); 1.110 + CX_TEST_ASSERT(iter.queue_last == NULL); 1.111 + } 1.112 +} 1.113 + 1.114 +CX_TEST(test_tree_visitor_no_children) { 1.115 + tree_node root = {0}; 1.116 + 1.117 + CX_TEST_DO { 1.118 + CxTreeVisitor iter = cx_tree_visitor(&root, tree_child_list); 1.119 + unsigned chk = 0; 1.120 + cx_foreach(tree_node*, node, iter) { 1.121 + CX_TEST_ASSERT(node == iter.node); 1.122 + chk++; 1.123 + } 1.124 + CX_TEST_ASSERT(iter.counter == 1); 1.125 + CX_TEST_ASSERT(chk == 1); 1.126 + CX_TEST_ASSERT(iter.queue_next == NULL); 1.127 + CX_TEST_ASSERT(iter.queue_last == NULL); 1.128 + } 1.129 +} 1.130 + 1.131 +CX_TEST(test_tree_visitor_no_branching) { 1.132 + tree_node root = {0}; 1.133 + tree_node a = {0}; 1.134 + tree_node b = {0}; 1.135 + tree_node c = {0}; 1.136 + 1.137 + tree_node* expected_order[] = { 1.138 + &root, &a, &b, &c 1.139 + }; 1.140 + tree_node* actual_order[4]; 1.141 + 1.142 + cx_tree_link(&root, &a, tree_node_layout); 1.143 + cx_tree_link(&a, &b, tree_node_layout); 1.144 + cx_tree_link(&b, &c, tree_node_layout); 1.145 + 1.146 + CX_TEST_DO { 1.147 + CxTreeVisitor iter = cx_tree_visitor(&root, tree_child_list); 1.148 + unsigned chk = 0; 1.149 + cx_foreach(tree_node*, node, iter) { 1.150 + CX_TEST_ASSERT(node == iter.node); 1.151 + CX_TEST_ASSERT(node->data == 0); 1.152 + node->data++; 1.153 + actual_order[chk] = node; 1.154 + chk++; 1.155 + } 1.156 + CX_TEST_ASSERT(iter.counter == 4); 1.157 + CX_TEST_ASSERT(chk == 4); 1.158 + CX_TEST_ASSERT(iter.queue_next == NULL); 1.159 + CX_TEST_ASSERT(iter.queue_last == NULL); 1.160 + for (unsigned i = 0 ; i < chk ; i++) { 1.161 + CX_TEST_ASSERT(actual_order[i] == expected_order[i]); 1.162 + CX_TEST_ASSERT(actual_order[i]->data == 1); 1.163 + } 1.164 + } 1.165 +} 1.166 + 1.167 CxTestSuite *cx_test_suite_tree_low_level(void) { 1.168 CxTestSuite *suite = cx_test_suite_new("tree (low level)"); 1.169 1.170 @@ -520,6 +636,9 @@ 1.171 cx_test_register(suite, test_tree_iterator_basic_enter_and_exit); 1.172 cx_test_register(suite, test_tree_iterator_xml); 1.173 cx_test_register(suite, test_tree_iterator_free_nodes); 1.174 + cx_test_register(suite, test_tree_visitor); 1.175 + cx_test_register(suite, test_tree_visitor_no_children); 1.176 + cx_test_register(suite, test_tree_visitor_no_branching); 1.177 1.178 return suite; 1.179 }