1.1 --- a/tests/test_tree.c Wed Mar 20 23:35:32 2024 +0100 1.2 +++ b/tests/test_tree.c Wed Apr 03 21:22:23 2024 +0200 1.3 @@ -644,6 +644,196 @@ 1.4 } 1.5 } 1.6 1.7 +CX_TEST(test_tree_visitor_continue) { 1.8 + tree_node root = {0}; 1.9 + tree_node a = {0}; 1.10 + tree_node b = {0}; 1.11 + tree_node c = {0}; 1.12 + tree_node aa = {0}; 1.13 + tree_node ab = {0}; 1.14 + tree_node ba = {0}; 1.15 + tree_node ca = {0}; 1.16 + tree_node cb = {0}; 1.17 + tree_node cc = {0}; 1.18 + tree_node cba = {0}; 1.19 + 1.20 + tree_node* expected_order[] = { 1.21 + &root, 1.22 + &c, &b, &a, 1.23 + &ba, &ab, &aa 1.24 + }; 1.25 + tree_node* actual_order[16]; // reserve more space in case s.t. goes wrong 1.26 + 1.27 + cx_tree_link(&root, &a, tree_node_layout); 1.28 + cx_tree_link(&root, &b, tree_node_layout); 1.29 + cx_tree_link(&root, &c, tree_node_layout); 1.30 + cx_tree_link(&a, &aa, tree_node_layout); 1.31 + cx_tree_link(&a, &ab, tree_node_layout); 1.32 + cx_tree_link(&b, &ba, tree_node_layout); 1.33 + cx_tree_link(&c, &ca, tree_node_layout); 1.34 + cx_tree_link(&c, &cb, tree_node_layout); 1.35 + cx_tree_link(&c, &cc, tree_node_layout); 1.36 + cx_tree_link(&cb, &cba, tree_node_layout); 1.37 + CX_TEST_DO { 1.38 + CxTreeVisitor iter = cx_tree_visitor(&root, tree_child_list); 1.39 + unsigned chk = 0; 1.40 + cx_foreach(tree_node*, node, iter) { 1.41 + CX_TEST_ASSERT(node->data == 0); 1.42 + node->data++; 1.43 + actual_order[chk] = node; 1.44 + chk++; 1.45 + CX_TEST_ASSERT(node == iter.node); 1.46 + if (node == &root) { 1.47 + CX_TEST_ASSERT(iter.depth == 1); 1.48 + } else if (node == &a || node == &b || node == &c) { 1.49 + CX_TEST_ASSERT(iter.depth == 2); 1.50 + } else { 1.51 + CX_TEST_ASSERT(iter.depth == 3); 1.52 + } 1.53 + if (node == &c) { 1.54 + cxTreeVisitorContinue(iter); 1.55 + } 1.56 + } 1.57 + CX_TEST_ASSERT(iter.counter == 7); 1.58 + CX_TEST_ASSERT(chk == 7); 1.59 + for (unsigned i = 0 ; i < chk ; i++) { 1.60 + CX_TEST_ASSERT(actual_order[i] == expected_order[i]); 1.61 + CX_TEST_ASSERT(actual_order[i]->data == 1); 1.62 + } 1.63 + CX_TEST_ASSERT(ca.data == 0); 1.64 + CX_TEST_ASSERT(cb.data == 0); 1.65 + CX_TEST_ASSERT(cc.data == 0); 1.66 + CX_TEST_ASSERT(cba.data == 0); 1.67 + CX_TEST_ASSERT(iter.queue_next == NULL); 1.68 + CX_TEST_ASSERT(iter.queue_last == NULL); 1.69 + } 1.70 +} 1.71 + 1.72 +CX_TEST(test_tree_iterator_continue) { 1.73 + tree_node root = {0}; 1.74 + tree_node a = {0}; 1.75 + tree_node b = {0}; 1.76 + tree_node c = {0}; 1.77 + tree_node aa = {0}; 1.78 + tree_node ab = {0}; 1.79 + tree_node ba = {0}; 1.80 + tree_node ca = {0}; 1.81 + tree_node cb = {0}; 1.82 + tree_node cc = {0}; 1.83 + tree_node cba = {0}; 1.84 + 1.85 + tree_node* expected_order[] = { 1.86 + &root, 1.87 + &c, 1.88 + &b, &ba, 1.89 + &a, &ab, &aa, 1.90 + }; 1.91 + tree_node* actual_order[16]; // reserve more space in case s.t. goes wrong 1.92 + 1.93 + cx_tree_link(&root, &a, tree_node_layout); 1.94 + cx_tree_link(&root, &b, tree_node_layout); 1.95 + cx_tree_link(&root, &c, tree_node_layout); 1.96 + cx_tree_link(&a, &aa, tree_node_layout); 1.97 + cx_tree_link(&a, &ab, tree_node_layout); 1.98 + cx_tree_link(&b, &ba, tree_node_layout); 1.99 + cx_tree_link(&c, &ca, tree_node_layout); 1.100 + cx_tree_link(&c, &cb, tree_node_layout); 1.101 + cx_tree_link(&c, &cc, tree_node_layout); 1.102 + cx_tree_link(&cb, &cba, tree_node_layout); 1.103 + CX_TEST_DO { 1.104 + CxTreeIterator iter = cx_tree_iterator(&root, false, tree_child_list); 1.105 + unsigned chk = 0; 1.106 + cx_foreach(tree_node*, node, iter) { 1.107 + CX_TEST_ASSERT(node->data == 0); 1.108 + node->data++; 1.109 + actual_order[chk] = node; 1.110 + chk++; 1.111 + CX_TEST_ASSERT(node == iter.node); 1.112 + CX_TEST_ASSERT(!iter.exiting); 1.113 + if (node == &root) { 1.114 + CX_TEST_ASSERT(iter.depth == 1); 1.115 + } else if (node == &a || node == &b || node == &c) { 1.116 + CX_TEST_ASSERT(iter.depth == 2); 1.117 + } else { 1.118 + CX_TEST_ASSERT(iter.depth == 3); 1.119 + } 1.120 + if (node == &c) { 1.121 + cxTreeIteratorContinue(iter); 1.122 + } 1.123 + } 1.124 + CX_TEST_ASSERT(iter.counter == 7); 1.125 + CX_TEST_ASSERT(chk == 7); 1.126 + for (unsigned i = 0 ; i < chk ; i++) { 1.127 + CX_TEST_ASSERT(actual_order[i] == expected_order[i]); 1.128 + CX_TEST_ASSERT(actual_order[i]->data == 1); 1.129 + } 1.130 + CX_TEST_ASSERT(ca.data == 0); 1.131 + CX_TEST_ASSERT(cb.data == 0); 1.132 + CX_TEST_ASSERT(cc.data == 0); 1.133 + CX_TEST_ASSERT(cba.data == 0); 1.134 + CX_TEST_ASSERT(iter.stack == NULL); 1.135 + } 1.136 +} 1.137 + 1.138 +CX_TEST(test_tree_iterator_continue_with_exit) { 1.139 + tree_node root = {0}; 1.140 + tree_node a = {0}; 1.141 + tree_node b = {0}; 1.142 + tree_node c = {0}; 1.143 + tree_node aa = {0}; 1.144 + tree_node ab = {0}; 1.145 + tree_node ba = {0}; 1.146 + tree_node ca = {0}; 1.147 + tree_node cb = {0}; 1.148 + tree_node cc = {0}; 1.149 + tree_node cba = {0}; 1.150 + 1.151 + cx_tree_link(&root, &a, tree_node_layout); 1.152 + cx_tree_link(&root, &b, tree_node_layout); 1.153 + cx_tree_link(&root, &c, tree_node_layout); 1.154 + cx_tree_link(&a, &aa, tree_node_layout); 1.155 + cx_tree_link(&a, &ab, tree_node_layout); 1.156 + cx_tree_link(&b, &ba, tree_node_layout); 1.157 + cx_tree_link(&c, &ca, tree_node_layout); 1.158 + cx_tree_link(&c, &cb, tree_node_layout); 1.159 + cx_tree_link(&c, &cc, tree_node_layout); 1.160 + cx_tree_link(&cb, &cba, tree_node_layout); 1.161 + CX_TEST_DO { 1.162 + CxTreeIterator iter = cx_tree_iterator(&root, true, tree_child_list); 1.163 + unsigned chk = 0; 1.164 + cx_foreach(tree_node*, node, iter) { 1.165 + CX_TEST_ASSERT(iter.exiting || node->data == 0); 1.166 + node->data++; 1.167 + chk++; 1.168 + CX_TEST_ASSERT(node == iter.node); 1.169 + if (node == &root) { 1.170 + CX_TEST_ASSERT(iter.depth == 1); 1.171 + } else if (node == &a || node == &b || node == &c) { 1.172 + CX_TEST_ASSERT(iter.depth == 2); 1.173 + } else { 1.174 + CX_TEST_ASSERT(iter.depth == 3); 1.175 + } 1.176 + if (node == &c) { 1.177 + cxTreeIteratorContinue(iter); 1.178 + } 1.179 + } 1.180 + CX_TEST_ASSERT(iter.counter == 7); 1.181 + CX_TEST_ASSERT(chk == 14); 1.182 + CX_TEST_ASSERT(iter.stack == NULL); 1.183 + CX_TEST_ASSERT(root.data == 2); 1.184 + CX_TEST_ASSERT(a.data == 2); 1.185 + CX_TEST_ASSERT(b.data == 2); 1.186 + CX_TEST_ASSERT(c.data == 2); 1.187 + CX_TEST_ASSERT(aa.data == 2); 1.188 + CX_TEST_ASSERT(ab.data == 2); 1.189 + CX_TEST_ASSERT(ba.data == 2); 1.190 + CX_TEST_ASSERT(ca.data == 0); 1.191 + CX_TEST_ASSERT(cb.data == 0); 1.192 + CX_TEST_ASSERT(cc.data == 0); 1.193 + CX_TEST_ASSERT(cba.data == 0); 1.194 + } 1.195 +} 1.196 + 1.197 CxTestSuite *cx_test_suite_tree_low_level(void) { 1.198 CxTestSuite *suite = cx_test_suite_new("tree (low level)"); 1.199 1.200 @@ -660,6 +850,9 @@ 1.201 cx_test_register(suite, test_tree_visitor); 1.202 cx_test_register(suite, test_tree_visitor_no_children); 1.203 cx_test_register(suite, test_tree_visitor_no_branching); 1.204 + cx_test_register(suite, test_tree_visitor_continue); 1.205 + cx_test_register(suite, test_tree_iterator_continue); 1.206 + cx_test_register(suite, test_tree_iterator_continue_with_exit); 1.207 1.208 return suite; 1.209 }