tests/test_list.c

Thu, 25 Jan 2024 22:05:48 +0100

author
Mike Becker <universe@uap-core.de>
date
Thu, 25 Jan 2024 22:05:48 +0100
changeset 819
5da2ead43077
parent 818
2be8fe3d5a2d
child 831
7970eac1c598
permissions
-rw-r--r--

rename cx_array_copy_result to just cx_array_result

universe@798 1 /*
universe@798 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
universe@798 3 *
universe@798 4 * Copyright 2023 Mike Becker, Olaf Wintermann All rights reserved.
universe@798 5 *
universe@798 6 * Redistribution and use in source and binary forms, with or without
universe@798 7 * modification, are permitted provided that the following conditions are met:
universe@798 8 *
universe@798 9 * 1. Redistributions of source code must retain the above copyright
universe@798 10 * notice, this list of conditions and the following disclaimer.
universe@798 11 *
universe@798 12 * 2. Redistributions in binary form must reproduce the above copyright
universe@798 13 * notice, this list of conditions and the following disclaimer in the
universe@798 14 * documentation and/or other materials provided with the distribution.
universe@798 15 *
universe@798 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
universe@798 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
universe@798 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
universe@798 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
universe@798 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
universe@798 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
universe@798 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
universe@798 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
universe@798 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
universe@798 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
universe@798 26 * POSSIBILITY OF SUCH DAMAGE.
universe@798 27 */
universe@798 28
universe@798 29 #include "cx/test.h"
universe@798 30 #include "util_allocator.h"
universe@798 31 #include "cx/compare.h"
universe@803 32 #include "cx/utils.h"
universe@798 33
universe@798 34 #include "cx/array_list.h"
universe@798 35 #include "cx/linked_list.h"
universe@798 36
universe@798 37 #include <stdarg.h>
universe@798 38
universe@818 39 CX_TEST(test_array_add) {
universe@818 40 int stackspace[5] = {1,1,2,3,5};
universe@818 41 int *stackarray = stackspace;
universe@818 42 size_t stackarray_size = 3;
universe@818 43 size_t stackarray_capacity = 5;
universe@818 44 int *heaparray = calloc(5, sizeof(int));
universe@818 45 heaparray[0] = 2;
universe@818 46 heaparray[1] = 3;
universe@818 47 heaparray[2] = 5;
universe@818 48 heaparray[3] = 7;
universe@818 49 heaparray[4] = 11;
universe@818 50 size_t heaparray_size = 3;
universe@818 51 size_t heaparray_capacity = 5;
universe@818 52 int elem = 8, elem2 = 47;
universe@819 53 enum cx_array_result result;
universe@818 54 CX_TEST_DO {
universe@818 55 result = cx_array_add(&stackarray, &stackarray_size, &stackarray_capacity, sizeof(int), &elem, NULL);
universe@819 56 CX_TEST_ASSERT(result == CX_ARRAY_SUCCESS);
universe@818 57 CX_TEST_ASSERT(stackarray[0] == 1);
universe@818 58 CX_TEST_ASSERT(stackarray[1] == 1);
universe@818 59 CX_TEST_ASSERT(stackarray[2] == 2);
universe@818 60 CX_TEST_ASSERT(stackarray[3] == 8);
universe@818 61 CX_TEST_ASSERT(stackarray[4] == 5);
universe@818 62 CX_TEST_ASSERT(stackarray_size == 4);
universe@818 63 CX_TEST_ASSERT(stackarray_capacity == 5);
universe@818 64
universe@818 65 stackarray_size = 5;
universe@818 66 result = cx_array_add(&stackarray, &stackarray_size, &stackarray_capacity, sizeof(int), &elem2, NULL);
universe@819 67 CX_TEST_ASSERT(result == CX_ARRAY_REALLOC_NOT_SUPPORTED);
universe@818 68 CX_TEST_ASSERT(stackarray[0] == 1);
universe@818 69 CX_TEST_ASSERT(stackarray[1] == 1);
universe@818 70 CX_TEST_ASSERT(stackarray[2] == 2);
universe@818 71 CX_TEST_ASSERT(stackarray[3] == 8);
universe@818 72 CX_TEST_ASSERT(stackarray[4] == 5);
universe@818 73 CX_TEST_ASSERT(stackarray_size == 5);
universe@818 74 CX_TEST_ASSERT(stackarray_capacity == 5);
universe@818 75
universe@818 76 result = cx_array_add(&heaparray, &heaparray_size, &heaparray_capacity, sizeof(int), &elem, cx_array_default_reallocator);
universe@819 77 CX_TEST_ASSERT(result == CX_ARRAY_SUCCESS);
universe@818 78 CX_TEST_ASSERT(heaparray[0] == 2);
universe@818 79 CX_TEST_ASSERT(heaparray[1] == 3);
universe@818 80 CX_TEST_ASSERT(heaparray[2] == 5);
universe@818 81 CX_TEST_ASSERT(heaparray[3] == 8);
universe@818 82 CX_TEST_ASSERT(heaparray[4] == 11);
universe@818 83 CX_TEST_ASSERT(heaparray_size == 4);
universe@818 84 CX_TEST_ASSERT(heaparray_capacity == 5);
universe@818 85
universe@818 86 heaparray_size = 5;
universe@818 87 result = cx_array_add(&heaparray, &heaparray_size, &heaparray_capacity, sizeof(int), &elem2, cx_array_default_reallocator);
universe@819 88 CX_TEST_ASSERT(result == CX_ARRAY_SUCCESS);
universe@818 89 CX_TEST_ASSERT(heaparray[0] == 2);
universe@818 90 CX_TEST_ASSERT(heaparray[1] == 3);
universe@818 91 CX_TEST_ASSERT(heaparray[2] == 5);
universe@818 92 CX_TEST_ASSERT(heaparray[3] == 8);
universe@818 93 CX_TEST_ASSERT(heaparray[4] == 11);
universe@818 94 CX_TEST_ASSERT(heaparray[5] == 47);
universe@818 95 CX_TEST_ASSERT(heaparray_size == 6);
universe@818 96 CX_TEST_ASSERT(heaparray_capacity >= 6);
universe@818 97 }
universe@818 98 free(heaparray);
universe@818 99 }
universe@818 100
universe@798 101 typedef struct node {
universe@798 102 struct node *next;
universe@798 103 struct node *prev;
universe@798 104 int data;
universe@798 105 } node;
universe@798 106
universe@798 107 const ptrdiff_t loc_prev = offsetof(struct node, prev);
universe@798 108 const ptrdiff_t loc_next = offsetof(struct node, next);
universe@798 109 const ptrdiff_t loc_data = offsetof(struct node, data);
universe@798 110
universe@798 111 static node *create_nodes_test_data(size_t len) {
universe@798 112 node *begin = calloc(1, sizeof(node));
universe@798 113 void *prev = begin;
universe@798 114 for (size_t i = 1; i < len; i++) {
universe@798 115 node *n = calloc(1, sizeof(node));
universe@798 116 cx_linked_list_link(prev, n, loc_prev, loc_next);
universe@798 117 prev = n;
universe@798 118 }
universe@798 119 return begin;
universe@798 120 }
universe@798 121
universe@798 122 void assign_nodes_test_data(node *n, ...) {
universe@798 123 va_list ap;
universe@798 124 va_start(ap, n);
universe@798 125 while (n != NULL) {
universe@798 126 n->data = va_arg(ap, int);
universe@798 127 n = n->next;
universe@798 128 }
universe@798 129 va_end(ap);
universe@798 130 }
universe@798 131
universe@798 132 static void destroy_nodes_test_data(node *n) {
universe@798 133 while (n != NULL) {
universe@798 134 void *next = n->next;
universe@798 135 free(n);
universe@798 136 n = next;
universe@798 137 }
universe@798 138 }
universe@798 139
universe@798 140 static int *int_test_data(size_t len) {
universe@798 141 int *data = malloc(len*sizeof(int));
universe@798 142 for (size_t i = 0 ; i < len ; i++) {
universe@798 143 data[i] = rand(); // NOLINT(*-msc50-cpp)
universe@798 144 }
universe@798 145 return data;
universe@798 146 }
universe@798 147
universe@798 148 CX_TEST(test_linked_list_link_unlink) {
universe@798 149 node a = {0}, b = {0}, c = {0};
universe@798 150
universe@798 151 CX_TEST_DO {
universe@798 152 cx_linked_list_link(&a, &b, loc_prev, loc_next);
universe@798 153 CX_TEST_ASSERT(a.prev == NULL);
universe@798 154 CX_TEST_ASSERT(a.next == &b);
universe@798 155 CX_TEST_ASSERT(b.prev == &a);
universe@798 156 CX_TEST_ASSERT(b.next == NULL);
universe@798 157
universe@798 158 cx_linked_list_unlink(&a, &b, loc_prev, loc_next);
universe@798 159 CX_TEST_ASSERT(a.prev == NULL);
universe@798 160 CX_TEST_ASSERT(a.next == NULL);
universe@798 161 CX_TEST_ASSERT(b.prev == NULL);
universe@798 162 CX_TEST_ASSERT(b.next == NULL);
universe@798 163
universe@798 164 cx_linked_list_link(&b, &c, loc_prev, loc_next);
universe@798 165 cx_linked_list_link(&a, &b, loc_prev, loc_next);
universe@798 166 cx_linked_list_unlink(&b, &c, loc_prev, loc_next);
universe@798 167 CX_TEST_ASSERT(a.prev == NULL);
universe@798 168 CX_TEST_ASSERT(a.next == &b);
universe@798 169 CX_TEST_ASSERT(b.prev == &a);
universe@798 170 CX_TEST_ASSERT(b.next == NULL);
universe@798 171 CX_TEST_ASSERT(c.prev == NULL);
universe@798 172 CX_TEST_ASSERT(c.next == NULL);
universe@798 173 }
universe@798 174 }
universe@798 175
universe@798 176 CX_TEST(test_linked_list_at) {
universe@798 177 node a = {0}, b = {0}, c = {0}, d = {0};
universe@798 178
universe@798 179 cx_linked_list_link(&a, &b, loc_prev, loc_next);
universe@798 180 cx_linked_list_link(&b, &c, loc_prev, loc_next);
universe@798 181 cx_linked_list_link(&c, &d, loc_prev, loc_next);
universe@798 182
universe@798 183 CX_TEST_DO {
universe@798 184 CX_TEST_ASSERT(cx_linked_list_at(&a, 0, loc_next, 0) == &a);
universe@798 185 CX_TEST_ASSERT(cx_linked_list_at(&a, 0, loc_next, 1) == &b);
universe@798 186 CX_TEST_ASSERT(cx_linked_list_at(&a, 0, loc_next, 2) == &c);
universe@798 187 CX_TEST_ASSERT(cx_linked_list_at(&a, 0, loc_next, 3) == &d);
universe@798 188 CX_TEST_ASSERT(cx_linked_list_at(&a, 0, loc_next, 4) == NULL);
universe@798 189 CX_TEST_ASSERT(cx_linked_list_at(&b, 1, loc_prev, 0) == &a);
universe@798 190 CX_TEST_ASSERT(cx_linked_list_at(&b, 1, loc_next, 1) == &b);
universe@798 191 CX_TEST_ASSERT(cx_linked_list_at(&b, 1, loc_next, 2) == &c);
universe@798 192 CX_TEST_ASSERT(cx_linked_list_at(&b, 1, loc_next, 3) == &d);
universe@798 193 CX_TEST_ASSERT(cx_linked_list_at(&b, 1, loc_next, 4) == NULL);
universe@798 194 CX_TEST_ASSERT(cx_linked_list_at(&d, 3, loc_prev, 0) == &a);
universe@798 195 CX_TEST_ASSERT(cx_linked_list_at(&d, 3, loc_prev, 1) == &b);
universe@798 196 }
universe@798 197 }
universe@798 198
universe@798 199 CX_TEST(test_linked_list_find) {
universe@798 200 void *list = create_nodes_test_data(4);
universe@798 201 assign_nodes_test_data(list, 2, 4, 6, 8);
universe@798 202 CX_TEST_DO {
universe@798 203 int s;
universe@798 204 s = 2;
universe@798 205 CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) == 0);
universe@798 206 s = 4;
universe@798 207 CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) == 1);
universe@798 208 s = 6;
universe@798 209 CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) == 2);
universe@798 210 s = 8;
universe@798 211 CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) == 3);
universe@798 212 s = 10;
universe@798 213 CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) < 0);
universe@798 214 s = -2;
universe@798 215 CX_TEST_ASSERT(cx_linked_list_find(list, loc_next, loc_data, cx_cmp_int, &s) < 0);
universe@798 216 }
universe@798 217 destroy_nodes_test_data(list);
universe@798 218 }
universe@798 219
universe@798 220 CX_TEST(test_linked_list_compare) {
universe@798 221 void *la = create_nodes_test_data(4);
universe@798 222 void *lb = create_nodes_test_data(3);
universe@798 223 void *lc = create_nodes_test_data(4);
universe@798 224 assign_nodes_test_data(la, 2, 4, 6, 8);
universe@798 225 assign_nodes_test_data(lb, 2, 4, 6);
universe@798 226 assign_nodes_test_data(lc, 2, 4, 6, 9);
universe@798 227 CX_TEST_DO {
universe@798 228 CX_TEST_ASSERT(cx_linked_list_compare(la, lb, loc_next, loc_data, cx_cmp_int) > 0);
universe@798 229 CX_TEST_ASSERT(cx_linked_list_compare(lb, la, loc_next, loc_data, cx_cmp_int) < 0);
universe@798 230 CX_TEST_ASSERT(cx_linked_list_compare(lc, la, loc_next, loc_data, cx_cmp_int) > 0);
universe@798 231 CX_TEST_ASSERT(cx_linked_list_compare(la, lc, loc_next, loc_data, cx_cmp_int) < 0);
universe@798 232 CX_TEST_ASSERT(cx_linked_list_compare(la, la, loc_next, loc_data, cx_cmp_int) == 0);
universe@798 233 }
universe@798 234 destroy_nodes_test_data(la);
universe@798 235 destroy_nodes_test_data(lb);
universe@798 236 destroy_nodes_test_data(lc);
universe@798 237 }
universe@798 238
universe@798 239 CX_TEST(test_linked_list_add) {
universe@798 240 node nodes[4];
universe@798 241 void *begin, *end;
universe@798 242 CX_TEST_DO {
universe@798 243 // test with begin, end / prev, next
universe@798 244 memset(nodes, 0, sizeof(node)*4);
universe@798 245 end = begin = NULL;
universe@798 246
universe@798 247 cx_linked_list_add(&begin, &end, loc_prev, loc_next, &nodes[0]);
universe@798 248 CX_TEST_ASSERT(begin == &nodes[0]);
universe@798 249 CX_TEST_ASSERT(end == &nodes[0]);
universe@798 250 CX_TEST_ASSERT(nodes[0].prev == NULL);
universe@798 251 CX_TEST_ASSERT(nodes[0].next == NULL);
universe@798 252
universe@798 253 cx_linked_list_add(&begin, &end, loc_prev, loc_next, &nodes[1]);
universe@798 254 CX_TEST_ASSERT(begin == &nodes[0]);
universe@798 255 CX_TEST_ASSERT(end == &nodes[1]);
universe@798 256 CX_TEST_ASSERT(nodes[0].next == &nodes[1]);
universe@798 257 CX_TEST_ASSERT(nodes[1].prev == &nodes[0]);
universe@798 258
universe@798 259 // test with begin only / prev, next
universe@798 260 memset(nodes, 0, sizeof(node)*4);
universe@798 261 end = begin = NULL;
universe@798 262
universe@798 263 cx_linked_list_add(&begin, NULL, loc_prev, loc_next, &nodes[0]);
universe@798 264 CX_TEST_ASSERT(begin == &nodes[0]);
universe@798 265 cx_linked_list_add(&begin, NULL, loc_prev, loc_next, &nodes[1]);
universe@798 266 CX_TEST_ASSERT(begin == &nodes[0]);
universe@798 267 CX_TEST_ASSERT(nodes[0].next == &nodes[1]);
universe@798 268 CX_TEST_ASSERT(nodes[1].prev == &nodes[0]);
universe@798 269
universe@798 270 cx_linked_list_add(&begin, NULL, loc_prev, loc_next, &nodes[2]);
universe@798 271 CX_TEST_ASSERT(nodes[1].next == &nodes[2]);
universe@798 272 CX_TEST_ASSERT(nodes[2].prev == &nodes[1]);
universe@798 273
universe@798 274 // test with end only / prev, next
universe@798 275 memset(nodes, 0, sizeof(node)*4);
universe@798 276 end = begin = NULL;
universe@798 277
universe@798 278 cx_linked_list_add(NULL, &end, loc_prev, loc_next, &nodes[0]);
universe@798 279 CX_TEST_ASSERT(end == &nodes[0]);
universe@798 280 cx_linked_list_add(NULL, &end, loc_prev, loc_next, &nodes[1]);
universe@798 281 CX_TEST_ASSERT(end == &nodes[1]);
universe@798 282 CX_TEST_ASSERT(nodes[0].next == &nodes[1]);
universe@798 283 CX_TEST_ASSERT(nodes[1].prev == &nodes[0]);
universe@798 284
universe@798 285 cx_linked_list_add(NULL, &end, loc_prev, loc_next, &nodes[2]);
universe@798 286 CX_TEST_ASSERT(end == &nodes[2]);
universe@798 287 CX_TEST_ASSERT(nodes[1].next == &nodes[2]);
universe@798 288 CX_TEST_ASSERT(nodes[2].prev == &nodes[1]);
universe@798 289
universe@798 290 // test with begin, end / next
universe@798 291 memset(nodes, 0, sizeof(node)*4);
universe@798 292 end = begin = NULL;
universe@798 293
universe@798 294 cx_linked_list_add(&begin, &end, -1, loc_next, &nodes[0]);
universe@798 295 CX_TEST_ASSERT(begin == &nodes[0]);
universe@798 296 CX_TEST_ASSERT(end == &nodes[0]);
universe@798 297 cx_linked_list_add(&begin, &end, -1, loc_next, &nodes[1]);
universe@798 298 CX_TEST_ASSERT(end == &nodes[1]);
universe@798 299 CX_TEST_ASSERT(nodes[0].next == &nodes[1]);
universe@798 300 CX_TEST_ASSERT(nodes[1].prev == NULL);
universe@798 301 }
universe@798 302 }
universe@798 303
universe@798 304 CX_TEST(test_linked_list_prepend) {
universe@798 305 node nodes[4];
universe@798 306 void *begin, *end;
universe@798 307 CX_TEST_DO {
universe@798 308 // test with begin, end / prev, next
universe@798 309 memset(nodes, 0, sizeof(node) * 4);
universe@798 310 end = begin = NULL;
universe@798 311
universe@798 312 cx_linked_list_prepend(&begin, &end, loc_prev, loc_next, &nodes[0]);
universe@798 313 CX_TEST_ASSERT(begin == &nodes[0]);
universe@798 314 CX_TEST_ASSERT(end == &nodes[0]);
universe@798 315 CX_TEST_ASSERT(nodes[0].prev == NULL);
universe@798 316 CX_TEST_ASSERT(nodes[0].next == NULL);
universe@798 317
universe@798 318 cx_linked_list_prepend(&begin, &end, loc_prev, loc_next, &nodes[1]);
universe@798 319 CX_TEST_ASSERT(begin == &nodes[1]);
universe@798 320 CX_TEST_ASSERT(end == &nodes[0]);
universe@798 321 CX_TEST_ASSERT(nodes[1].next == &nodes[0]);
universe@798 322 CX_TEST_ASSERT(nodes[0].prev == &nodes[1]);
universe@798 323
universe@798 324 // test with begin only / prev, next
universe@798 325 memset(nodes, 0, sizeof(node) * 4);
universe@798 326 end = begin = NULL;
universe@798 327
universe@798 328 cx_linked_list_prepend(&begin, NULL, loc_prev, loc_next, &nodes[0]);
universe@798 329 CX_TEST_ASSERT(begin == &nodes[0]);
universe@798 330 cx_linked_list_prepend(&begin, NULL, loc_prev, loc_next, &nodes[1]);
universe@798 331 CX_TEST_ASSERT(begin == &nodes[1]);
universe@798 332 CX_TEST_ASSERT(nodes[1].next == &nodes[0]);
universe@798 333 CX_TEST_ASSERT(nodes[0].prev == &nodes[1]);
universe@798 334
universe@798 335 cx_linked_list_prepend(&begin, NULL, loc_prev, loc_next, &nodes[2]);
universe@798 336 CX_TEST_ASSERT(begin == &nodes[2]);
universe@798 337 CX_TEST_ASSERT(nodes[2].next == &nodes[1]);
universe@798 338 CX_TEST_ASSERT(nodes[1].prev == &nodes[2]);
universe@798 339
universe@798 340 // test with end only / prev, next
universe@798 341 memset(nodes, 0, sizeof(node) * 4);
universe@798 342 end = begin = NULL;
universe@798 343
universe@798 344 cx_linked_list_prepend(NULL, &end, loc_prev, loc_next, &nodes[0]);
universe@798 345 CX_TEST_ASSERT(end == &nodes[0]);
universe@798 346 cx_linked_list_prepend(NULL, &end, loc_prev, loc_next, &nodes[1]);
universe@798 347 CX_TEST_ASSERT(end == &nodes[0]);
universe@798 348 CX_TEST_ASSERT(nodes[1].next == &nodes[0]);
universe@798 349 CX_TEST_ASSERT(nodes[0].prev == &nodes[1]);
universe@798 350
universe@798 351 cx_linked_list_prepend(NULL, &end, loc_prev, loc_next, &nodes[2]);
universe@798 352 CX_TEST_ASSERT(end == &nodes[0]);
universe@798 353 CX_TEST_ASSERT(nodes[2].next == &nodes[1]);
universe@798 354 CX_TEST_ASSERT(nodes[1].prev == &nodes[2]);
universe@798 355
universe@798 356 // test with begin, end / next
universe@798 357 memset(nodes, 0, sizeof(node) * 4);
universe@798 358 end = begin = NULL;
universe@798 359
universe@798 360 cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[0]);
universe@798 361 CX_TEST_ASSERT(begin == &nodes[0]);
universe@798 362 CX_TEST_ASSERT(end == &nodes[0]);
universe@798 363 cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[1]);
universe@798 364 cx_linked_list_prepend(&begin, &end, -1, loc_next, &nodes[2]);
universe@798 365 CX_TEST_ASSERT(begin == &nodes[2]);
universe@798 366 CX_TEST_ASSERT(end == &nodes[0]);
universe@798 367 CX_TEST_ASSERT(nodes[1].next == &nodes[0]);
universe@798 368 CX_TEST_ASSERT(nodes[2].next == &nodes[1]);
universe@798 369 CX_TEST_ASSERT(nodes[1].prev == NULL);
universe@798 370 CX_TEST_ASSERT(nodes[0].prev == NULL);
universe@798 371 }
universe@798 372 }
universe@798 373
universe@798 374 CX_TEST(test_linked_list_insert) {
universe@798 375 node nodes[4];
universe@798 376 void *begin, *end;
universe@798 377 CX_TEST_DO {
universe@798 378 // insert mid list
universe@798 379 memset(nodes, 0, sizeof(node) * 4);
universe@798 380 begin = &nodes[0];
universe@798 381 end = &nodes[2];
universe@798 382
universe@798 383 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
universe@798 384 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
universe@798 385
universe@798 386 cx_linked_list_insert(&begin, &end, loc_prev, loc_next, &nodes[1], &nodes[3]);
universe@798 387 CX_TEST_ASSERT(begin == &nodes[0]);
universe@798 388 CX_TEST_ASSERT(end == &nodes[2]);
universe@798 389 CX_TEST_ASSERT(nodes[1].next == &nodes[3]);
universe@798 390 CX_TEST_ASSERT(nodes[2].prev == &nodes[3]);
universe@798 391 CX_TEST_ASSERT(nodes[3].prev == &nodes[1]);
universe@798 392 CX_TEST_ASSERT(nodes[3].next == &nodes[2]);
universe@798 393
universe@798 394 // insert end
universe@798 395 memset(nodes, 0, sizeof(node) * 4);
universe@798 396 begin = &nodes[0];
universe@798 397 end = &nodes[2];
universe@798 398
universe@798 399 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
universe@798 400 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
universe@798 401
universe@798 402 cx_linked_list_insert(&begin, &end, loc_prev, loc_next, &nodes[2], &nodes[3]);
universe@798 403 CX_TEST_ASSERT(begin == &nodes[0]);
universe@798 404 CX_TEST_ASSERT(end == &nodes[3]);
universe@798 405 CX_TEST_ASSERT(nodes[2].next == &nodes[3]);
universe@798 406 CX_TEST_ASSERT(nodes[3].prev == &nodes[2]);
universe@798 407 CX_TEST_ASSERT(nodes[3].next == NULL);
universe@798 408
universe@798 409 // insert begin
universe@798 410 memset(nodes, 0, sizeof(node) * 4);
universe@798 411 begin = &nodes[0];
universe@798 412 end = &nodes[2];
universe@798 413
universe@798 414 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
universe@798 415 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
universe@798 416
universe@798 417 cx_linked_list_insert(&begin, &end, loc_prev, loc_next, NULL, &nodes[3]);
universe@798 418 CX_TEST_ASSERT(begin == &nodes[3]);
universe@798 419 CX_TEST_ASSERT(end == &nodes[2]);
universe@798 420 CX_TEST_ASSERT(nodes[0].prev == &nodes[3]);
universe@798 421 CX_TEST_ASSERT(nodes[3].prev == NULL);
universe@798 422 CX_TEST_ASSERT(nodes[3].next == &nodes[0]);
universe@798 423 }
universe@798 424 }
universe@798 425
universe@798 426 CX_TEST(test_linked_list_insert_chain) {
universe@798 427 node nodes[5];
universe@798 428 void *begin, *end;
universe@798 429 CX_TEST_DO {
universe@798 430 // insert mid list
universe@798 431 memset(nodes, 0, sizeof(node) * 5);
universe@798 432 begin = &nodes[0]; end = &nodes[2];
universe@798 433
universe@798 434 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
universe@798 435 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
universe@798 436 cx_linked_list_link(&nodes[3], &nodes[4], loc_prev, loc_next);
universe@798 437
universe@798 438 cx_linked_list_insert_chain(&begin, &end, loc_prev, loc_next, &nodes[1], &nodes[3], NULL);
universe@798 439 CX_TEST_ASSERT(begin == &nodes[0]);
universe@798 440 CX_TEST_ASSERT(end == &nodes[2]);
universe@798 441 CX_TEST_ASSERT(nodes[1].next == &nodes[3]);
universe@798 442 CX_TEST_ASSERT(nodes[2].prev == &nodes[4]);
universe@798 443 CX_TEST_ASSERT(nodes[3].prev == &nodes[1]);
universe@798 444 CX_TEST_ASSERT(nodes[4].next == &nodes[2]);
universe@798 445
universe@798 446 // insert end
universe@798 447 memset(nodes, 0, sizeof(node) * 5);
universe@798 448 begin = &nodes[0]; end = &nodes[2];
universe@798 449
universe@798 450 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
universe@798 451 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
universe@798 452 cx_linked_list_link(&nodes[3], &nodes[4], loc_prev, loc_next);
universe@798 453
universe@798 454 cx_linked_list_insert_chain(&begin, &end, loc_prev, loc_next, &nodes[2], &nodes[3], NULL);
universe@798 455 CX_TEST_ASSERT(begin == &nodes[0]);
universe@798 456 CX_TEST_ASSERT(end == &nodes[4]);
universe@798 457 CX_TEST_ASSERT(nodes[2].next == &nodes[3]);
universe@798 458 CX_TEST_ASSERT(nodes[3].prev == &nodes[2]);
universe@798 459 CX_TEST_ASSERT(nodes[4].next == NULL);
universe@798 460
universe@798 461 // insert begin
universe@798 462 memset(nodes, 0, sizeof(node) * 5);
universe@798 463 begin = &nodes[0]; end = &nodes[2];
universe@798 464
universe@798 465 cx_linked_list_link(&nodes[0], &nodes[1], loc_prev, loc_next);
universe@798 466 cx_linked_list_link(&nodes[1], &nodes[2], loc_prev, loc_next);
universe@798 467 cx_linked_list_link(&nodes[3], &nodes[4], loc_prev, loc_next);
universe@798 468
universe@798 469 cx_linked_list_insert_chain(&begin, &end, loc_prev, loc_next, NULL, &nodes[3], NULL);
universe@798 470 CX_TEST_ASSERT(begin == &nodes[3]);
universe@798 471 CX_TEST_ASSERT(end == &nodes[2]);
universe@798 472 CX_TEST_ASSERT(nodes[0].prev == &nodes[4]);
universe@798 473 CX_TEST_ASSERT(nodes[3].prev == NULL);
universe@798 474 CX_TEST_ASSERT(nodes[4].next == &nodes[0]);
universe@798 475 }
universe@798 476 }
universe@798 477
universe@798 478 CX_TEST(test_linked_list_first) {
universe@798 479 node *testdata = create_nodes_test_data(3);
universe@798 480 void *begin = testdata;
universe@798 481 CX_TEST_DO {
universe@798 482 CX_TEST_ASSERT(begin == cx_linked_list_first(testdata, loc_prev));
universe@798 483 CX_TEST_ASSERT(begin == cx_linked_list_first(testdata->next, loc_prev));
universe@798 484 CX_TEST_ASSERT(begin == cx_linked_list_first(testdata->next->next, loc_prev));
universe@798 485 }
universe@798 486 destroy_nodes_test_data(testdata);
universe@798 487 }
universe@798 488
universe@798 489 CX_TEST(test_linked_list_last) {
universe@798 490 node *testdata = create_nodes_test_data(3);
universe@798 491 void *end = testdata->next->next;
universe@798 492 CX_TEST_DO {
universe@798 493 CX_TEST_ASSERT(end == cx_linked_list_last(testdata, loc_next));
universe@798 494 CX_TEST_ASSERT(end == cx_linked_list_last(testdata->next, loc_next));
universe@798 495 CX_TEST_ASSERT(end == cx_linked_list_last(testdata->next->next, loc_next));
universe@798 496 }
universe@798 497 destroy_nodes_test_data(testdata);
universe@798 498 }
universe@798 499
universe@798 500 CX_TEST(test_linked_list_prev) {
universe@798 501 node *testdata = create_nodes_test_data(3);
universe@798 502 CX_TEST_DO {
universe@798 503 CX_TEST_ASSERT(cx_linked_list_prev(testdata, loc_next, testdata) == NULL);
universe@798 504 CX_TEST_ASSERT(cx_linked_list_prev(testdata, loc_next, testdata->next) == testdata);
universe@798 505 CX_TEST_ASSERT(cx_linked_list_prev(testdata, loc_next, testdata->next->next) == testdata->next);
universe@798 506 }
universe@798 507 destroy_nodes_test_data(testdata);
universe@798 508 }
universe@798 509
universe@798 510 CX_TEST(test_linked_list_remove) {
universe@798 511 node *testdata = create_nodes_test_data(3);
universe@798 512 assign_nodes_test_data(testdata, 2, 4, 6);
universe@798 513 node *first = testdata;
universe@798 514 node *second = first->next;
universe@798 515 node *third = second->next;
universe@798 516 void *begin = testdata;
universe@798 517 void *end = third;
universe@798 518
universe@798 519 CX_TEST_DO {
universe@798 520 cx_linked_list_remove(&begin, &end, loc_prev, loc_next, second);
universe@798 521 CX_TEST_ASSERT(begin == first);
universe@798 522 CX_TEST_ASSERT(end == third);
universe@798 523 CX_TEST_ASSERT(first->prev == NULL);
universe@798 524 CX_TEST_ASSERT(first->next == third);
universe@798 525 CX_TEST_ASSERT(third->prev == first);
universe@798 526 CX_TEST_ASSERT(third->next == NULL);
universe@798 527
universe@798 528 cx_linked_list_remove(&begin, &end, loc_prev, loc_next, third);
universe@798 529 CX_TEST_ASSERT(begin == first);
universe@798 530 CX_TEST_ASSERT(end == first);
universe@798 531 CX_TEST_ASSERT(first->prev == NULL);
universe@798 532 CX_TEST_ASSERT(first->next == NULL);
universe@798 533
universe@798 534 cx_linked_list_remove(&begin, &end, loc_prev, loc_next, first);
universe@798 535 CX_TEST_ASSERT(begin == NULL);
universe@798 536 CX_TEST_ASSERT(end == NULL);
universe@798 537 }
universe@798 538 // list is not intact anymore, we have to free nodes individually
universe@798 539 free(first);
universe@798 540 free(second);
universe@798 541 free(third);
universe@798 542 }
universe@798 543
universe@798 544 CX_TEST(test_linked_list_size) {
universe@798 545 node *td5 = create_nodes_test_data(5);
universe@798 546 node *td13 = create_nodes_test_data(13);
universe@798 547 CX_TEST_DO {
universe@798 548 CX_TEST_ASSERT(cx_linked_list_size(NULL, loc_next) == 0);
universe@798 549 CX_TEST_ASSERT(cx_linked_list_size(td5, loc_next) == 5);
universe@798 550 CX_TEST_ASSERT(cx_linked_list_size(td13, loc_next) == 13);
universe@798 551 }
universe@798 552 destroy_nodes_test_data(td5);
universe@798 553 destroy_nodes_test_data(td13);
universe@798 554 }
universe@798 555
universe@798 556 CX_TEST(test_linked_list_sort_empty) {
universe@798 557 void *begin = NULL;
universe@799 558 CX_TEST_DO {
universe@799 559 // cannot assert something, we can just test that it does not crash
universe@799 560 cx_linked_list_sort(&begin, NULL, loc_prev, loc_next, loc_data, cx_cmp_int);
universe@799 561 CX_TEST_ASSERT(true);
universe@799 562 }
universe@798 563 }
universe@798 564
universe@798 565 CX_TEST(test_linked_list_sort) {
universe@798 566 const size_t len = 1500;
universe@798 567 int *testdata = int_test_data(len);
universe@798 568 void *scrambled = create_nodes_test_data(len);
universe@798 569 node *n = scrambled;
universe@798 570 for (size_t i = 0; i < len; i++) {
universe@798 571 n->data = testdata[i];
universe@798 572 n = n->next;
universe@798 573 }
universe@798 574 int *sorted = malloc(len*sizeof(int));
universe@798 575 memcpy(sorted, testdata, len*sizeof(int));
universe@798 576 qsort(sorted, len, sizeof(int), cx_cmp_int);
universe@798 577
universe@798 578 void *begin = scrambled;
universe@798 579 void *end = cx_linked_list_last(begin, loc_next);
universe@798 580
universe@798 581 CX_TEST_DO {
universe@798 582 cx_linked_list_sort(&begin, &end, loc_prev, loc_next, loc_data, cx_cmp_int);
universe@798 583 node *check = begin;
universe@798 584 node *check_last = NULL;
universe@798 585 for (size_t i = 0; i < len; i++) {
universe@798 586 CX_TEST_ASSERT(check->data == sorted[i]);
universe@798 587 CX_TEST_ASSERT(check->prev == check_last);
universe@798 588 if (i < len - 1) {
universe@798 589 CX_TEST_ASSERT(check->next != NULL);
universe@798 590 }
universe@798 591 check_last = check;
universe@798 592 check = check->next;
universe@798 593 }
universe@798 594 CX_TEST_ASSERT(check == NULL);
universe@798 595 CX_TEST_ASSERT(end == check_last);
universe@798 596 }
universe@799 597 destroy_nodes_test_data(begin);
universe@799 598 free(sorted);
universe@798 599 free(testdata);
universe@798 600 }
universe@798 601
universe@798 602 CX_TEST(test_linked_list_reverse) {
universe@798 603 void *testdata = create_nodes_test_data(4);
universe@798 604 void *expected = create_nodes_test_data(4);
universe@798 605 assign_nodes_test_data(testdata, 2, 4, 6, 8);
universe@798 606 assign_nodes_test_data(expected, 8, 6, 4, 2);
universe@799 607 void *begin = testdata;
universe@798 608 CX_TEST_DO {
universe@798 609 void *end = cx_linked_list_last(begin, loc_next);
universe@798 610 void *orig_begin = begin, *orig_end = end;
universe@798 611
universe@798 612 cx_linked_list_reverse(&begin, &end, loc_prev, loc_next);
universe@798 613 CX_TEST_ASSERT(end == orig_begin);
universe@798 614 CX_TEST_ASSERT(begin == orig_end);
universe@798 615 CX_TEST_ASSERT(0 == cx_linked_list_compare(begin, expected, loc_next, loc_data, cx_cmp_int));
universe@798 616 }
universe@799 617 destroy_nodes_test_data(begin);
universe@798 618 destroy_nodes_test_data(expected);
universe@798 619 }
universe@798 620
universe@800 621
universe@800 622 CX_TEST(test_empty_list_size) {
universe@800 623 CX_TEST_DO {
universe@800 624 CX_TEST_ASSERT(cxEmptyList->size == 0);
universe@800 625 CX_TEST_ASSERT(cxListSize(cxEmptyList) == 0);
universe@800 626 }
universe@800 627 }
universe@800 628
universe@800 629 CX_TEST(test_empty_list_iterator) {
universe@800 630 CxList *list = cxEmptyList;
universe@800 631
universe@800 632 CxIterator it1 = cxListIterator(list);
universe@800 633 CxIterator it2 = cxListBackwardsIterator(list);
universe@800 634 CxMutIterator it3 = cxListMutIterator(list);
universe@800 635 CxMutIterator it4 = cxListMutBackwardsIterator(list);
universe@800 636
universe@800 637 CX_TEST_DO {
universe@800 638 CX_TEST_ASSERT(!cxIteratorValid(it1));
universe@800 639 CX_TEST_ASSERT(!cxIteratorValid(it2));
universe@800 640 CX_TEST_ASSERT(!cxIteratorValid(it3));
universe@800 641 CX_TEST_ASSERT(!cxIteratorValid(it4));
universe@800 642
universe@800 643 int c = 0;
universe@800 644 cx_foreach(void*, data, it1) c++;
universe@800 645 cx_foreach(void*, data, it2) c++;
universe@800 646 cx_foreach(void*, data, it3) c++;
universe@800 647 cx_foreach(void*, data, it4) c++;
universe@800 648 CX_TEST_ASSERT(c == 0);
universe@800 649 }
universe@800 650 }
universe@800 651
universe@800 652 CX_TEST(test_empty_list_noops) {
universe@800 653 CX_TEST_DO {
universe@800 654 CxList copy = *cxEmptyList;
universe@800 655 cxListSort(cxEmptyList);
universe@800 656 cxListClear(cxEmptyList);
universe@800 657 cxListDestroy(cxEmptyList);
universe@800 658 CX_TEST_ASSERT(0 == memcmp(&copy, cxEmptyList, sizeof(CxList))); // NOLINT(*-suspicious-memory-comparison)
universe@800 659 }
universe@800 660 }
universe@800 661
universe@800 662 CX_TEST(test_empty_list_at) {
universe@800 663 CX_TEST_DO {
universe@800 664 CX_TEST_ASSERT(cxListAt(cxEmptyList, 0) == NULL);
universe@800 665 CX_TEST_ASSERT(cxListAt(cxEmptyList, 1) == NULL);
universe@800 666 }
universe@800 667 }
universe@800 668
universe@800 669 CX_TEST(test_empty_list_find) {
universe@800 670 int x = 42, y = 1337;
universe@800 671 CX_TEST_DO {
universe@800 672 CX_TEST_ASSERT(cxListFind(cxEmptyList, &x) < 0);
universe@800 673 CX_TEST_ASSERT(cxListFind(cxEmptyList, &y) < 0);
universe@800 674 }
universe@800 675 }
universe@800 676
universe@800 677 CX_TEST(test_empty_list_compare) {
universe@800 678 CxList *empty = cxEmptyList;
universe@800 679 CxList *ll = cxLinkedListCreateSimple(sizeof(int));
universe@800 680 CxList *al = cxArrayListCreateSimple(sizeof(int), 8);
universe@800 681 int x = 5;
universe@800 682 CX_TEST_DO {
universe@800 683 CX_TEST_ASSERT(0 == cxListCompare(empty, cxEmptyList));
universe@800 684 CX_TEST_ASSERT(0 == cxListCompare(ll, cxEmptyList));
universe@800 685 CX_TEST_ASSERT(0 == cxListCompare(al, cxEmptyList));
universe@800 686 CX_TEST_ASSERT(0 == cxListCompare(cxEmptyList, ll));
universe@800 687 CX_TEST_ASSERT(0 == cxListCompare(cxEmptyList, al));
universe@800 688
universe@800 689 cxListAdd(ll, &x);
universe@800 690 cxListAdd(al, &x);
universe@800 691
universe@800 692 CX_TEST_ASSERT(0 < cxListCompare(ll, cxEmptyList));
universe@800 693 CX_TEST_ASSERT(0 < cxListCompare(al, cxEmptyList));
universe@800 694 CX_TEST_ASSERT(0 > cxListCompare(cxEmptyList, ll));
universe@800 695 CX_TEST_ASSERT(0 > cxListCompare(cxEmptyList, al));
universe@800 696 }
universe@800 697 cxListDestroy(ll);
universe@800 698 cxListDestroy(al);
universe@800 699 }
universe@800 700
universe@801 701 CX_TEST(test_list_ll_create) {
universe@801 702 CxTestingAllocator talloc;
universe@801 703 cx_testing_allocator_init(&talloc);
universe@801 704 CxAllocator *alloc = &talloc.base;
universe@801 705 CX_TEST_DO {
universe@801 706 CxList *list = cxLinkedListCreate(alloc, cx_cmp_int, sizeof(int));
universe@801 707 CX_TEST_ASSERT(list != NULL);
universe@801 708 CX_TEST_ASSERT(list->item_size == sizeof(int));
universe@801 709 CX_TEST_ASSERT(list->simple_destructor == NULL);
universe@801 710 CX_TEST_ASSERT(list->advanced_destructor == NULL);
universe@801 711 CX_TEST_ASSERT(list->destructor_data == NULL);
universe@801 712 CX_TEST_ASSERT(cxListSize(list) == 0);
universe@801 713 CX_TEST_ASSERT(list->allocator == alloc);
universe@801 714 CX_TEST_ASSERT(list->cmpfunc == cx_cmp_int);
universe@801 715 CX_TEST_ASSERT(!cxListIsStoringPointers(list));
universe@801 716 cxListDestroy(list);
universe@801 717 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
universe@801 718 }
universe@801 719 cx_testing_allocator_destroy(&talloc);
universe@801 720 }
universe@801 721
universe@801 722 CX_TEST(test_list_ll_create_simple) {
universe@801 723 CxList *list = cxLinkedListCreateSimple(sizeof(int));
universe@801 724 CX_TEST_DO {
universe@801 725 CX_TEST_ASSERT(list != NULL);
universe@801 726 CX_TEST_ASSERT(list->item_size == sizeof(int));
universe@801 727 CX_TEST_ASSERT(list->simple_destructor == NULL);
universe@801 728 CX_TEST_ASSERT(list->advanced_destructor == NULL);
universe@801 729 CX_TEST_ASSERT(list->destructor_data == NULL);
universe@801 730 CX_TEST_ASSERT(cxListSize(list) == 0);
universe@801 731 CX_TEST_ASSERT(list->allocator == cxDefaultAllocator);
universe@801 732 CX_TEST_ASSERT(list->cmpfunc == NULL);
universe@801 733 CX_TEST_ASSERT(!cxListIsStoringPointers(list));
universe@801 734 }
universe@801 735 cxListDestroy(list);
universe@801 736 }
universe@801 737
universe@801 738 CX_TEST(test_list_ll_store_pointers) {
universe@801 739 CxList *list = cxLinkedListCreateSimple(47);
universe@801 740 CX_TEST_DO {
universe@801 741 CX_TEST_ASSERT(!cxListIsStoringPointers(list));
universe@801 742 cxListStorePointers(list);
universe@801 743 CX_TEST_ASSERT(list->item_size == sizeof(void *));
universe@801 744 CX_TEST_ASSERT(list->cl != NULL);
universe@801 745 CX_TEST_ASSERT(list->climpl != NULL);
universe@801 746 CX_TEST_ASSERT(cxListIsStoringPointers(list));
universe@801 747 cxListStoreObjects(list);
universe@801 748 CX_TEST_ASSERT(list->cl != NULL);
universe@801 749 CX_TEST_ASSERT(list->climpl == NULL);
universe@801 750 CX_TEST_ASSERT(!cxListIsStoringPointers(list));
universe@801 751 }
universe@801 752 cxListDestroy(list);
universe@801 753 }
universe@801 754
universe@801 755 CX_TEST(test_list_ll_create_simple_for_pointers) {
universe@801 756 CxList *list = cxLinkedListCreateSimple(CX_STORE_POINTERS);
universe@801 757 CX_TEST_DO {
universe@801 758 CX_TEST_ASSERT(list != NULL);
universe@801 759 CX_TEST_ASSERT(list->item_size == sizeof(void*));
universe@801 760 CX_TEST_ASSERT(list->simple_destructor == NULL);
universe@801 761 CX_TEST_ASSERT(list->advanced_destructor == NULL);
universe@801 762 CX_TEST_ASSERT(list->destructor_data == NULL);
universe@801 763 CX_TEST_ASSERT(cxListSize(list) == 0);
universe@801 764 CX_TEST_ASSERT(list->allocator == cxDefaultAllocator);
universe@801 765 CX_TEST_ASSERT(list->cmpfunc == cx_cmp_ptr);
universe@801 766 CX_TEST_ASSERT(cxListIsStoringPointers(list));
universe@801 767 }
universe@801 768 cxListDestroy(list);
universe@801 769 }
universe@801 770
universe@801 771 CX_TEST(test_list_arl_create) {
universe@801 772 CxTestingAllocator talloc;
universe@801 773 cx_testing_allocator_init(&talloc);
universe@801 774 CxAllocator *alloc = &talloc.base;
universe@801 775 CX_TEST_DO {
universe@801 776 CxList *list = cxArrayListCreate(alloc, cx_cmp_int, sizeof(int), 8);
universe@801 777 CX_TEST_ASSERT(list != NULL);
universe@801 778 CX_TEST_ASSERT(list->item_size == sizeof(int));
universe@801 779 CX_TEST_ASSERT(list->simple_destructor == NULL);
universe@801 780 CX_TEST_ASSERT(list->advanced_destructor == NULL);
universe@801 781 CX_TEST_ASSERT(list->destructor_data == NULL);
universe@801 782 CX_TEST_ASSERT(cxListSize(list) == 0);
universe@801 783 CX_TEST_ASSERT(list->allocator == alloc);
universe@801 784 CX_TEST_ASSERT(list->cmpfunc == cx_cmp_int);
universe@801 785 CX_TEST_ASSERT(!cxListIsStoringPointers(list));
universe@801 786 cxListDestroy(list);
universe@801 787 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
universe@801 788 }
universe@801 789 cx_testing_allocator_destroy(&talloc);
universe@801 790 }
universe@801 791
universe@801 792 CX_TEST(test_list_arl_create_simple) {
universe@801 793 CxList *list = cxArrayListCreateSimple(sizeof(int), 8);
universe@801 794 CX_TEST_DO {
universe@801 795 CX_TEST_ASSERT(list != NULL);
universe@801 796 CX_TEST_ASSERT(list->item_size == sizeof(int));
universe@801 797 CX_TEST_ASSERT(list->simple_destructor == NULL);
universe@801 798 CX_TEST_ASSERT(list->advanced_destructor == NULL);
universe@801 799 CX_TEST_ASSERT(list->destructor_data == NULL);
universe@801 800 CX_TEST_ASSERT(cxListSize(list) == 0);
universe@801 801 CX_TEST_ASSERT(list->allocator == cxDefaultAllocator);
universe@801 802 CX_TEST_ASSERT(list->cmpfunc == NULL);
universe@801 803 CX_TEST_ASSERT(!cxListIsStoringPointers(list));
universe@801 804 }
universe@801 805 cxListDestroy(list);
universe@801 806 }
universe@801 807
universe@801 808 CX_TEST(test_list_arl_create_simple_for_pointers) {
universe@801 809 CxList *list = cxArrayListCreateSimple(CX_STORE_POINTERS, 8);
universe@801 810 CX_TEST_DO {
universe@801 811 CX_TEST_ASSERT(list != NULL);
universe@801 812 CX_TEST_ASSERT(list->item_size == sizeof(void*));
universe@801 813 CX_TEST_ASSERT(list->simple_destructor == NULL);
universe@801 814 CX_TEST_ASSERT(list->advanced_destructor == NULL);
universe@801 815 CX_TEST_ASSERT(list->destructor_data == NULL);
universe@801 816 CX_TEST_ASSERT(cxListSize(list) == 0);
universe@801 817 CX_TEST_ASSERT(list->allocator == cxDefaultAllocator);
universe@801 818 CX_TEST_ASSERT(list->cmpfunc == cx_cmp_ptr);
universe@801 819 CX_TEST_ASSERT(cxListIsStoringPointers(list));
universe@801 820 }
universe@801 821 cxListDestroy(list);
universe@801 822 }
universe@801 823
universe@801 824 static void test_fake_simple_int_destr(void *elem) {
universe@801 825 *(int *) elem = 42;
universe@801 826 }
universe@801 827
universe@801 828 CX_TEST(test_list_pll_destroy_no_destr) {
universe@801 829 CxTestingAllocator talloc;
universe@801 830 cx_testing_allocator_init(&talloc);
universe@801 831 CxAllocator *alloc = &talloc.base;
universe@801 832 CX_TEST_DO {
universe@801 833 void *item = cxMalloc(alloc, sizeof(int));
universe@801 834 CxList *list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS);
universe@801 835 cxListAdd(list, item);
universe@801 836 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
universe@801 837 cxListDestroy(list);
universe@801 838 // item is not yet freed
universe@801 839 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
universe@801 840 cxFree(alloc, item);
universe@801 841 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
universe@801 842 }
universe@801 843 cx_testing_allocator_destroy(&talloc);
universe@801 844 }
universe@801 845
universe@801 846 CX_TEST(test_list_pll_destroy_simple_destr) {
universe@801 847 CX_TEST_DO {
universe@801 848 int item = 0;
universe@801 849 CxList *list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS);
universe@801 850 list->simple_destructor = test_fake_simple_int_destr;
universe@801 851 cxListAdd(list, &item);
universe@801 852 cxListDestroy(list);
universe@801 853 CX_TEST_ASSERT(item == 42);
universe@801 854 }
universe@801 855 }
universe@801 856
universe@801 857 CX_TEST(test_list_pll_destroy_adv_destr) {
universe@801 858 CxTestingAllocator talloc;
universe@801 859 cx_testing_allocator_init(&talloc);
universe@801 860 CxAllocator *alloc = &talloc.base;
universe@801 861 CX_TEST_DO {
universe@801 862 void *item = cxMalloc(alloc, sizeof(int));
universe@801 863 CxList *list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS);
universe@801 864 list->destructor_data = alloc;
universe@801 865 list->advanced_destructor = (cx_destructor_func2) cxFree;
universe@801 866 cxListAdd(list, item);
universe@801 867 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
universe@801 868 cxListDestroy(list);
universe@801 869 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
universe@801 870 }
universe@801 871 cx_testing_allocator_destroy(&talloc);
universe@801 872 }
universe@801 873
universe@801 874 CX_TEST(test_list_parl_destroy_no_destr) {
universe@801 875 CxTestingAllocator talloc;
universe@801 876 cx_testing_allocator_init(&talloc);
universe@801 877 CxAllocator *alloc = &talloc.base;
universe@801 878 CX_TEST_DO {
universe@801 879 void *item = cxMalloc(alloc, sizeof(int));
universe@801 880 CxList *list = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 4);
universe@801 881 cxListAdd(list, item);
universe@801 882 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
universe@801 883 cxListDestroy(list);
universe@801 884 // item is not yet freed
universe@801 885 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
universe@801 886 cxFree(alloc, item);
universe@801 887 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
universe@801 888 }
universe@801 889 cx_testing_allocator_destroy(&talloc);
universe@801 890 }
universe@801 891
universe@801 892 CX_TEST(test_list_parl_destroy_simple_destr) {
universe@801 893 CX_TEST_DO {
universe@801 894 int item = 0;
universe@801 895 CxList *list = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 4);
universe@801 896 list->simple_destructor = test_fake_simple_int_destr;
universe@801 897 cxListAdd(list, &item);
universe@801 898 cxListDestroy(list);
universe@801 899 CX_TEST_ASSERT(item == 42);
universe@801 900 }
universe@801 901 }
universe@801 902
universe@801 903 CX_TEST(test_list_parl_destroy_adv_destr) {
universe@801 904 CxTestingAllocator talloc;
universe@801 905 cx_testing_allocator_init(&talloc);
universe@801 906 CxAllocator *alloc = &talloc.base;
universe@801 907 CX_TEST_DO {
universe@801 908 void *item = cxMalloc(alloc, sizeof(int));
universe@801 909 CxList *list = cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 4);
universe@801 910 list->destructor_data = alloc;
universe@801 911 list->advanced_destructor = (cx_destructor_func2) cxFree;
universe@801 912 cxListAdd(list, item);
universe@801 913 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
universe@801 914 cxListDestroy(list);
universe@801 915 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
universe@801 916 }
universe@801 917 cx_testing_allocator_destroy(&talloc);
universe@801 918 }
universe@801 919
universe@803 920 #define set_up_combo \
universe@803 921 CxTestingAllocator talloc; \
universe@803 922 cx_testing_allocator_init(&talloc); \
universe@803 923 CxAllocator *alloc = &talloc.base; \
universe@803 924 CX_TEST_DO {
universe@803 925 #define tear_down_combo \
universe@803 926 cxListDestroy(list); \
universe@803 927 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));\
universe@803 928 } \
universe@803 929 cx_testing_allocator_destroy(&talloc);
universe@803 930 #define roll_out_test_combos(name, body) \
universe@803 931 static CX_TEST_SUBROUTINE(test_list_verify_##name, CxList *list, \
universe@807 932 __attribute__((__unused__)) bool isptrlist) body \
universe@803 933 CX_TEST(test_list_ll_##name) { \
universe@803 934 set_up_combo \
universe@803 935 CxList *list = cxLinkedListCreate(alloc, cx_cmp_int, sizeof(int)); \
universe@807 936 CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, false); \
universe@803 937 tear_down_combo \
universe@803 938 } \
universe@803 939 CX_TEST(test_list_arl_##name) { \
universe@803 940 set_up_combo \
universe@803 941 CxList *list = cxArrayListCreate(alloc, cx_cmp_int, sizeof(int), 8); \
universe@807 942 CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, false); \
universe@803 943 tear_down_combo \
universe@803 944 } \
universe@803 945 CX_TEST(test_list_pll_##name) { \
universe@803 946 set_up_combo \
universe@803 947 CxList *list = cxLinkedListCreate(alloc, cx_cmp_int, CX_STORE_POINTERS); \
universe@807 948 CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, true); \
universe@803 949 tear_down_combo \
universe@803 950 } \
universe@803 951 CX_TEST(test_list_parl_##name) { \
universe@803 952 set_up_combo \
universe@803 953 CxList *list = cxArrayListCreate(alloc, cx_cmp_int, CX_STORE_POINTERS, 8); \
universe@807 954 CX_TEST_CALL_SUBROUTINE(test_list_verify_##name, list, true); \
universe@803 955 tear_down_combo \
universe@803 956 }
universe@803 957 #define array_init(...) {__VA_ARGS__}
universe@803 958
universe@803 959 static inline int *int_test_data_added_to_list(CxList *list, bool isptrlist, size_t len) {
universe@803 960 int *testdata = int_test_data(len);
universe@803 961 if (isptrlist) {
universe@803 962 cx_for_n(i, len) {
universe@803 963 cxListAdd(list, &testdata[i]);
universe@803 964 }
universe@803 965 } else {
universe@803 966 cxListAddArray(list, testdata, len);
universe@803 967 }
universe@803 968 return testdata;
universe@803 969 }
universe@803 970
universe@803 971 roll_out_test_combos(add, {
universe@803 972 const size_t len = 250;
universe@803 973 int *testdata = int_test_data(len);
universe@803 974 cx_for_n (i, len) CX_TEST_ASSERT(cxListAdd(list, &testdata[i]) == 0);
universe@803 975 CX_TEST_ASSERT(cxListSize(list) == len);
universe@803 976 cx_for_n (i, len) CX_TEST_ASSERT(*(int *) cxListAt(list, i) == testdata[i]);
universe@803 977 cx_for_n (i, len) ++testdata[i];
universe@803 978 if (isptrlist) {
universe@803 979 cx_for_n (i, len) CX_TEST_ASSERT(*(int *) cxListAt(list, i) == testdata[i]);
universe@803 980 } else {
universe@803 981 cx_for_n (i, len) CX_TEST_ASSERT(*(int *) cxListAt(list, i) == testdata[i] - 1);
universe@803 982 }
universe@803 983 free(testdata);
universe@803 984 })
universe@803 985
universe@803 986 roll_out_test_combos(insert, {
universe@803 987 int a = 5;
universe@803 988 int b = 47;
universe@803 989 int c = 13;
universe@803 990 int d = 42;
universe@803 991 CX_TEST_ASSERT(cxListInsert(list, 1, &a) != 0);
universe@803 992 CX_TEST_ASSERT(cxListSize(list) == 0);
universe@803 993 CX_TEST_ASSERT(cxListInsert(list, 0, &a) == 0);
universe@803 994 CX_TEST_ASSERT(cxListSize(list) == 1);
universe@803 995 CX_TEST_ASSERT(cxListInsert(list, 0, &b) == 0);
universe@803 996 CX_TEST_ASSERT(cxListSize(list) == 2);
universe@803 997 CX_TEST_ASSERT(cxListInsert(list, 1, &c) == 0);
universe@803 998 CX_TEST_ASSERT(cxListSize(list) == 3);
universe@803 999 CX_TEST_ASSERT(cxListInsert(list, 3, &d) == 0);
universe@803 1000 CX_TEST_ASSERT(cxListSize(list) == 4);
universe@803 1001 CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == 47);
universe@803 1002 CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == 13);
universe@803 1003 CX_TEST_ASSERT(*(int *) cxListAt(list, 2) == 5);
universe@803 1004 CX_TEST_ASSERT(*(int *) cxListAt(list, 3) == 42);
universe@803 1005 })
universe@803 1006
universe@803 1007 roll_out_test_combos(insert_array, {
universe@803 1008 int a[5] = array_init(5, 47, 11, 13, 42);
universe@803 1009 int b[5] = array_init(9, 18, 72, 50, 7);
universe@803 1010 int *aptr[5];
universe@803 1011 int *bptr[5];
universe@803 1012 cx_for_n(i, 5) {
universe@803 1013 aptr[i] = &a[i];
universe@803 1014 bptr[i] = &b[i];
universe@803 1015 }
universe@803 1016
universe@803 1017 size_t inserted;
universe@803 1018
universe@803 1019 if (isptrlist) {
universe@803 1020 inserted = cxListInsertArray(list, 0, aptr, 5);
universe@803 1021 } else {
universe@803 1022 inserted = cxListInsertArray(list, 0, a, 5);
universe@803 1023 }
universe@803 1024 CX_TEST_ASSERT(inserted == 5);
universe@803 1025 CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == 5);
universe@803 1026 CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == 47);
universe@803 1027 CX_TEST_ASSERT(*(int *) cxListAt(list, 2) == 11);
universe@803 1028 CX_TEST_ASSERT(*(int *) cxListAt(list, 3) == 13);
universe@803 1029 CX_TEST_ASSERT(*(int *) cxListAt(list, 4) == 42);
universe@803 1030 if (isptrlist) {
universe@803 1031 inserted = cxListInsertArray(list, 3, bptr, 5);
universe@803 1032 } else {
universe@803 1033 inserted = cxListInsertArray(list, 3, b, 5);
universe@803 1034 }
universe@803 1035 CX_TEST_ASSERT(inserted == 5);
universe@803 1036 CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == 5);
universe@803 1037 CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == 47);
universe@803 1038 CX_TEST_ASSERT(*(int *) cxListAt(list, 2) == 11);
universe@803 1039 CX_TEST_ASSERT(*(int *) cxListAt(list, 3) == 9);
universe@803 1040 CX_TEST_ASSERT(*(int *) cxListAt(list, 4) == 18);
universe@803 1041 CX_TEST_ASSERT(*(int *) cxListAt(list, 5) == 72);
universe@803 1042 CX_TEST_ASSERT(*(int *) cxListAt(list, 6) == 50);
universe@803 1043 CX_TEST_ASSERT(*(int *) cxListAt(list, 7) == 7);
universe@803 1044 CX_TEST_ASSERT(*(int *) cxListAt(list, 8) == 13);
universe@803 1045 CX_TEST_ASSERT(*(int *) cxListAt(list, 9) == 42);
universe@803 1046 })
universe@803 1047
universe@803 1048 roll_out_test_combos(remove, {
universe@803 1049 const size_t testdata_len = 32;
universe@803 1050 int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len);
universe@803 1051
universe@803 1052 CX_TEST_ASSERT(cxListRemove(list, 2) == 0);
universe@803 1053 CX_TEST_ASSERT(cxListRemove(list, 4) == 0);
universe@803 1054 CX_TEST_ASSERT(cxListSize(list) == testdata_len - 2);
universe@803 1055 CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == testdata[0]);
universe@803 1056 CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == testdata[1]);
universe@803 1057 CX_TEST_ASSERT(*(int *) cxListAt(list, 2) == testdata[3]);
universe@803 1058 CX_TEST_ASSERT(*(int *) cxListAt(list, 3) == testdata[4]);
universe@803 1059 CX_TEST_ASSERT(*(int *) cxListAt(list, 4) == testdata[6]);
universe@803 1060 CX_TEST_ASSERT(cxListRemove(list, 0) == 0);
universe@803 1061 CX_TEST_ASSERT(cxListSize(list) == testdata_len - 3);
universe@803 1062 CX_TEST_ASSERT(*(int *) cxListAt(list, 0) == testdata[1]);
universe@803 1063 CX_TEST_ASSERT(*(int *) cxListAt(list, 1) == testdata[3]);
universe@803 1064 CX_TEST_ASSERT(cxListRemove(list, testdata_len) != 0);
universe@803 1065 free(testdata);
universe@803 1066 })
universe@803 1067
universe@803 1068 roll_out_test_combos(find_remove, {
universe@803 1069 const size_t testdata_len = 250;
universe@803 1070 int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len);
universe@803 1071
universe@803 1072 int exp = rand() % testdata_len; // NOLINT(cert-msc50-cpp)
universe@803 1073 int val = testdata[exp];
universe@803 1074 // randomly picked number could occur earlier in list - find first position
universe@803 1075 for (int i = 0 ; i < exp ; i++) {
universe@803 1076 if (testdata[i] == val) {
universe@803 1077 exp = i;
universe@803 1078 break;
universe@803 1079 }
universe@803 1080 }
universe@803 1081 CX_TEST_ASSERT(cxListSize(list) == testdata_len);
universe@803 1082 CX_TEST_ASSERT(cxListFind(list, &val) == exp);
universe@803 1083 CX_TEST_ASSERT(cxListFindRemove(list, &val) == exp);
universe@803 1084 CX_TEST_ASSERT(cxListSize(list) == testdata_len - 1);
universe@803 1085 CX_TEST_ASSERT(cxListFind(list, &val) != exp);
universe@803 1086
universe@803 1087 int notinlist = -1;
universe@803 1088 CX_TEST_ASSERT(cxListFindRemove(list, &notinlist) < 0);
universe@803 1089 CX_TEST_ASSERT(cxListSize(list) == testdata_len - 1);
universe@803 1090
universe@803 1091 free(testdata);
universe@803 1092 })
universe@803 1093
universe@803 1094 roll_out_test_combos(clear, {
universe@803 1095 int *testdata = int_test_data_added_to_list(list, isptrlist, 8);
universe@803 1096 CX_TEST_ASSERT(cxListSize(list) > 0);
universe@803 1097 cxListClear(list);
universe@803 1098 CX_TEST_ASSERT(cxListSize(list) == 0);
universe@803 1099 free(testdata);
universe@803 1100 })
universe@803 1101
universe@803 1102 roll_out_test_combos(at, {
universe@803 1103 size_t len = 128;
universe@803 1104 int *testdata = int_test_data_added_to_list(list, isptrlist, 128);
universe@803 1105 CX_TEST_ASSERT(cxListSize(list) == len);
universe@803 1106 cx_for_n (i, len) {
universe@803 1107 CX_TEST_ASSERT(*(int *) cxListAt(list, i) == testdata[i]);
universe@803 1108 }
universe@803 1109 CX_TEST_ASSERT(cxListAt(list, cxListSize(list)) == NULL);
universe@803 1110 free(testdata);
universe@803 1111 })
universe@803 1112
universe@803 1113 roll_out_test_combos(swap, {
universe@803 1114 int original[16] = array_init(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
universe@803 1115 int swapped[16] = array_init(8, 4, 14, 3, 1, 5, 9, 12, 0, 6, 11, 10, 7, 15, 2, 13);
universe@803 1116
universe@803 1117 cx_for_n(i, 16) {
universe@803 1118 cxListAdd(list, &original[i]);
universe@803 1119 }
universe@803 1120
universe@803 1121 CX_TEST_ASSERT(0 == cxListSwap(list, 1, 4));
universe@803 1122 CX_TEST_ASSERT(0 == cxListSwap(list, 2, 14));
universe@803 1123 CX_TEST_ASSERT(0 == cxListSwap(list, 9, 6));
universe@803 1124 CX_TEST_ASSERT(0 == cxListSwap(list, 3, 3));
universe@803 1125 CX_TEST_ASSERT(0 == cxListSwap(list, 10, 11));
universe@803 1126 CX_TEST_ASSERT(0 == cxListSwap(list, 8, 0));
universe@803 1127 CX_TEST_ASSERT(0 == cxListSwap(list, 7, 12));
universe@803 1128 CX_TEST_ASSERT(0 == cxListSwap(list, 13, 15));
universe@803 1129
universe@803 1130 CX_TEST_ASSERT(0 != cxListSwap(list, 5, 16));
universe@803 1131 CX_TEST_ASSERT(0 != cxListSwap(list, 16, 6));
universe@803 1132 CX_TEST_ASSERT(0 != cxListSwap(list, 16, 17));
universe@803 1133
universe@803 1134 CxIterator iter = cxListIterator(list);
universe@803 1135 cx_foreach(int*, e, iter) {
universe@803 1136 CX_TEST_ASSERT(*e == swapped[iter.index]);
universe@803 1137 }
universe@803 1138 iter = cxListBackwardsIterator(list);
universe@803 1139 cx_foreach(int*, e, iter) {
universe@803 1140 CX_TEST_ASSERT(*e == swapped[iter.index]);
universe@803 1141 }
universe@803 1142 })
universe@803 1143
universe@807 1144 CX_TEST(test_list_ll_swap_no_sbo) {
universe@807 1145 set_up_combo
universe@807 1146 CxList *list = cxLinkedListCreate(alloc, cx_cmp_int, 2*cx_linked_list_swap_sbo_size);
universe@807 1147 CX_TEST_CALL_SUBROUTINE(test_list_verify_swap, list, false);
universe@807 1148 tear_down_combo
universe@807 1149 }
universe@807 1150 CX_TEST(test_list_arl_swap_no_sbo) {
universe@807 1151 set_up_combo
universe@807 1152 CxList *list = cxArrayListCreate(alloc, cx_cmp_int, 2*cx_array_swap_sbo_size, 8);
universe@807 1153 CX_TEST_CALL_SUBROUTINE(test_list_verify_swap, list, false);
universe@807 1154 tear_down_combo
universe@807 1155 }
universe@803 1156
universe@803 1157 roll_out_test_combos(find, {
universe@803 1158 const size_t testdata_len = 500;
universe@803 1159 int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len);
universe@803 1160
universe@803 1161 cx_for_n (attempt, 25) {
universe@803 1162 int exp = rand() % testdata_len; // NOLINT(cert-msc50-cpp)
universe@803 1163 int val = testdata[exp];
universe@803 1164 // randomly picked number could occur earlier in list - find first position
universe@803 1165 for (int i = 0 ; i < exp ; i++) {
universe@803 1166 if (testdata[i] == val) {
universe@803 1167 exp = i;
universe@803 1168 break;
universe@803 1169 }
universe@803 1170 }
universe@803 1171 CX_TEST_ASSERT(cxListFind(list, &val) == exp);
universe@803 1172 }
universe@803 1173
universe@803 1174 int notinlist = -1;
universe@803 1175 CX_TEST_ASSERT(cxListFind(list, &notinlist) < 0);
universe@803 1176
universe@803 1177 free(testdata);
universe@803 1178 })
universe@803 1179
universe@803 1180 roll_out_test_combos(sort, {
universe@803 1181 const size_t testdata_len = 250;
universe@803 1182 int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len);
universe@803 1183 int *expected = malloc(testdata_len*sizeof(int));
universe@803 1184 memcpy(expected, testdata, testdata_len*sizeof(int));
universe@803 1185 qsort(expected, testdata_len, sizeof(int), cx_cmp_int);
universe@803 1186
universe@803 1187 cxListSort(list);
universe@803 1188 cx_for_n (i, testdata_len) CX_TEST_ASSERT(*(int *) cxListAt(list, i) == expected[i]);
universe@803 1189
universe@803 1190 free(expected);
universe@803 1191 free(testdata);
universe@803 1192 })
universe@803 1193
universe@803 1194 roll_out_test_combos(reverse, {
universe@803 1195 const size_t testdata_len = 50;
universe@803 1196 int *testdata = int_test_data_added_to_list(list, isptrlist, testdata_len);
universe@803 1197 cxListReverse(list);
universe@803 1198 cx_for_n(i, testdata_len) {
universe@803 1199 CX_TEST_ASSERT(*(int *) cxListAt(list, i) == testdata[testdata_len - 1 - i]);
universe@803 1200 }
universe@803 1201 free(testdata);
universe@803 1202 })
universe@803 1203
universe@803 1204 roll_out_test_combos(iterator, {
universe@803 1205 const size_t len = 50;
universe@803 1206 int *testdata = int_test_data_added_to_list(list, isptrlist, len);
universe@803 1207
universe@803 1208 CxIterator iter = cxListIterator(list);
universe@803 1209 size_t i = 0;
universe@803 1210 cx_foreach(int*, x, iter) {
universe@803 1211 CX_TEST_ASSERT(i == iter.index);
universe@803 1212 CX_TEST_ASSERT(*x == testdata[iter.index]);
universe@803 1213 i++;
universe@803 1214 }
universe@803 1215 CX_TEST_ASSERT(i == cxListSize(list));
universe@803 1216 iter = cxListBackwardsIterator(list);
universe@803 1217 cx_foreach(int*, x, iter) {
universe@803 1218 CX_TEST_ASSERT(i - 1 == iter.index);
universe@803 1219 CX_TEST_ASSERT(*x == testdata[iter.index]);
universe@803 1220 i--;
universe@803 1221 }
universe@803 1222 CX_TEST_ASSERT(i == 0);
universe@803 1223 i = len / 2;
universe@803 1224 CxMutIterator mut_iter = cxListMutIteratorAt(list, i);
universe@803 1225 size_t j = 0;
universe@803 1226 cx_foreach(int*, x, mut_iter) {
universe@803 1227 CX_TEST_ASSERT(mut_iter.index == len / 2 + j / 2);
universe@803 1228 CX_TEST_ASSERT(*x == testdata[i]);
universe@803 1229 if (i % 2 == 1) cxIteratorFlagRemoval(mut_iter);
universe@803 1230 i++;
universe@803 1231 j++;
universe@803 1232 }
universe@803 1233 CX_TEST_ASSERT(i == len);
universe@803 1234 i = len / 2;
universe@803 1235 j = 0;
universe@803 1236 mut_iter = cxListMutBackwardsIteratorAt(list, i - 1);
universe@803 1237 cx_foreach(int*, x, mut_iter) {
universe@803 1238 CX_TEST_ASSERT(mut_iter.index == len / 2 - 1 - j);
universe@803 1239 CX_TEST_ASSERT(*x == testdata[i - 1]);
universe@803 1240 if (i % 2 == 0) cxIteratorFlagRemoval(mut_iter);
universe@803 1241 i--;
universe@803 1242 j++;
universe@803 1243 }
universe@803 1244 CX_TEST_ASSERT(i == 0);
universe@803 1245 CX_TEST_ASSERT(cxListSize(list) == len / 2);
universe@803 1246 cx_for_n(k, len / 2) CX_TEST_ASSERT(*(int *) cxListAt(list, k) == testdata[k * 2]);
universe@803 1247
universe@803 1248 free(testdata);
universe@803 1249 })
universe@803 1250
universe@803 1251 roll_out_test_combos(insert_with_iterator, {
universe@803 1252 int fivenums[] = array_init(0, 1, 2, 3, 4);
universe@803 1253 cx_for_n(i, 5) cxListAdd(list, &fivenums[i]);
universe@803 1254 int newdata[] = array_init(10, 20, 30, 40, 50);
universe@803 1255
universe@803 1256 CxMutIterator iter = cxListMutIteratorAt(list, 2);
universe@803 1257 CX_TEST_ASSERT(cxIteratorValid(iter));
universe@803 1258 CX_TEST_ASSERT(iter.index == 2);
universe@803 1259 CX_TEST_ASSERT(*(int *) cxIteratorCurrent(iter) == 2);
universe@803 1260 cxListInsertAfter(&iter, &newdata[0]);
universe@803 1261 CX_TEST_ASSERT(cxIteratorValid(iter));
universe@803 1262 CX_TEST_ASSERT(iter.index == 2);
universe@803 1263 CX_TEST_ASSERT(*(int *) cxIteratorCurrent(iter) == 2);
universe@803 1264 cxListInsertBefore(&iter, &newdata[1]);
universe@803 1265 CX_TEST_ASSERT(cxIteratorValid(iter));
universe@803 1266 CX_TEST_ASSERT(iter.index == 3);
universe@803 1267 CX_TEST_ASSERT(*(int *) cxIteratorCurrent(iter) == 2);
universe@803 1268
universe@803 1269 iter = cxListMutIterator(list);
universe@803 1270 cxListInsertBefore(&iter, &newdata[2]);
universe@803 1271 CX_TEST_ASSERT(cxIteratorValid(iter));
universe@803 1272 CX_TEST_ASSERT(iter.index == 1);
universe@803 1273 CX_TEST_ASSERT(*(int *) cxIteratorCurrent(iter) == 0);
universe@803 1274 iter = cxListMutIteratorAt(list, cxListSize(list));
universe@803 1275 cxListInsertBefore(&iter, &newdata[3]);
universe@803 1276 CX_TEST_ASSERT(!cxIteratorValid(iter));
universe@803 1277 CX_TEST_ASSERT(iter.index == 9);
universe@803 1278 iter = cxListMutIteratorAt(list, cxListSize(list));
universe@803 1279 cxListInsertAfter(&iter, &newdata[4]);
universe@803 1280 CX_TEST_ASSERT(!cxIteratorValid(iter));
universe@803 1281 CX_TEST_ASSERT(iter.index == 10);
universe@803 1282
universe@803 1283 int expdata[] = array_init(30, 0, 1, 20, 2, 10, 3, 4, 40, 50);
universe@803 1284 cx_for_n (j, 10) CX_TEST_ASSERT(*(int *) cxListAt(list, j) == expdata[j]);
universe@803 1285 })
universe@803 1286
universe@803 1287 static CX_TEST_SUBROUTINE(test_list_verify_compare, CxList *left, CxList *right) {
universe@803 1288 CX_TEST_ASSERTM(cxListCompare(left, right) == 0, "lists don't start identical");
universe@803 1289 int x = 42;
universe@803 1290 cxListAdd(left, &x);
universe@803 1291 CX_TEST_ASSERT(cxListSize(left) > cxListSize(right));
universe@803 1292 CX_TEST_ASSERT(cxListCompare(left, right) > 0);
universe@803 1293 CX_TEST_ASSERT(cxListCompare(right, left) < 0);
universe@803 1294 cxListAdd(right, &x);
universe@803 1295 CX_TEST_ASSERT(cxListSize(left) == cxListSize(right));
universe@803 1296 CX_TEST_ASSERT(cxListCompare(left, right) == 0);
universe@803 1297 int a = 5, b = 10;
universe@803 1298 cxListInsert(left, 15, &a);
universe@803 1299 cxListInsert(right, 15, &b);
universe@803 1300 CX_TEST_ASSERT(cxListSize(left) == cxListSize(right));
universe@803 1301 CX_TEST_ASSERT(cxListCompare(left, right) < 0);
universe@803 1302 CX_TEST_ASSERT(cxListCompare(right, left) > 0);
universe@803 1303 *(int *) cxListAt(left, 15) = 10;
universe@803 1304 CX_TEST_ASSERT(cxListCompare(left, right) == 0);
universe@803 1305 }
universe@803 1306
universe@803 1307 #define roll_out_compare_tests(suffix, otherctr) \
universe@803 1308 roll_out_test_combos(compare_##suffix, { \
universe@803 1309 const size_t len = 47; \
universe@803 1310 int *testdata = int_test_data_added_to_list(list, isptrlist, len); \
universe@803 1311 CxList *other = otherctr; \
universe@803 1312 cx_for_n(i, len) cxListAdd(other, &testdata[i]); \
universe@803 1313 CX_TEST_CALL_SUBROUTINE(test_list_verify_compare, list, other); \
universe@803 1314 cxListDestroy(other); \
universe@803 1315 free(testdata); \
universe@803 1316 })
universe@803 1317
universe@803 1318 roll_out_compare_tests(
universe@803 1319 ll, cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int))
universe@803 1320 )
universe@803 1321
universe@803 1322 roll_out_compare_tests(
universe@803 1323 pll, cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS)
universe@803 1324 )
universe@803 1325
universe@803 1326 roll_out_compare_tests(
universe@803 1327 arl, cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, sizeof(int), 50)
universe@803 1328 )
universe@803 1329
universe@803 1330 roll_out_compare_tests(
universe@803 1331 parl, cxArrayListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS, 50)
universe@803 1332 )
universe@803 1333
universe@803 1334 static unsigned destr_test_ctr;
universe@803 1335 static int destr_last_value;
universe@803 1336
universe@803 1337 static void simple_destr_test_fun(void *data) {
universe@803 1338 int *ptr = data;
universe@803 1339 destr_last_value = *ptr;
universe@803 1340 *ptr = destr_last_value + 1;
universe@803 1341 destr_test_ctr++;
universe@803 1342 }
universe@803 1343
universe@803 1344 static void advanced_destr_test_fun(__attribute__((__unused__)) void *u, void *data) {
universe@803 1345 simple_destr_test_fun(data);
universe@803 1346 }
universe@803 1347
universe@803 1348 static CX_TEST_SUBROUTINE(test_list_verify_destructor, CxList *list,
universe@803 1349 int const *testdata, size_t testdata_len) {
universe@803 1350 destr_test_ctr = 0;
universe@803 1351
universe@803 1352 int off = cxListIsStoringPointers(list) ? 1 : 0;
universe@803 1353
universe@803 1354 cxListRemove(list, 15);
universe@803 1355 CX_TEST_ASSERT(1 == destr_test_ctr);
universe@803 1356 CX_TEST_ASSERT(testdata[15] == destr_last_value + off);
universe@803 1357 CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list));
universe@803 1358 cxListRemove(list, 47);
universe@803 1359 CX_TEST_ASSERT(2 == destr_test_ctr);
universe@803 1360 CX_TEST_ASSERT(testdata[48] == destr_last_value + off);
universe@803 1361 CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list));
universe@803 1362
universe@803 1363 CxMutIterator iter = cxListMutIteratorAt(list, 7);
universe@803 1364 cxIteratorNext(iter);
universe@803 1365 CX_TEST_ASSERT(2 == destr_test_ctr);
universe@803 1366 CX_TEST_ASSERT(testdata[48] == destr_last_value + off);
universe@803 1367 CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list));
universe@803 1368 cxIteratorFlagRemoval(iter);
universe@803 1369 cxIteratorNext(iter);
universe@803 1370 CX_TEST_ASSERT(3 == destr_test_ctr);
universe@803 1371 CX_TEST_ASSERT(testdata[8] == destr_last_value + off);
universe@803 1372 CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list));
universe@803 1373
universe@803 1374 iter = cxListMutBackwardsIteratorAt(list, 5);
universe@803 1375 cxIteratorNext(iter);
universe@803 1376 CX_TEST_ASSERT(3 == destr_test_ctr);
universe@803 1377 CX_TEST_ASSERT(testdata[8] == destr_last_value + off);
universe@803 1378 CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list));
universe@803 1379 cxIteratorFlagRemoval(iter);
universe@803 1380 cxIteratorNext(iter);
universe@803 1381 CX_TEST_ASSERT(4 == destr_test_ctr);
universe@803 1382 CX_TEST_ASSERT(testdata[4] == destr_last_value + off);
universe@803 1383 CX_TEST_ASSERT(testdata_len - destr_test_ctr == cxListSize(list));
universe@803 1384
universe@803 1385 cxListClear(list);
universe@803 1386 CX_TEST_ASSERT(testdata_len == destr_test_ctr);
universe@803 1387 CX_TEST_ASSERT(testdata[testdata_len - 1] == destr_last_value + off);
universe@803 1388 }
universe@803 1389
universe@803 1390 roll_out_test_combos(simple_destr, {
universe@803 1391 const size_t len = 60;
universe@803 1392 int *testdata = int_test_data_added_to_list(list, isptrlist, len);
universe@803 1393 list->simple_destructor = simple_destr_test_fun;
universe@803 1394 CX_TEST_CALL_SUBROUTINE(test_list_verify_destructor, list, testdata, len);
universe@803 1395 free(testdata);
universe@803 1396 })
universe@803 1397
universe@803 1398 roll_out_test_combos(advanced_destr, {
universe@803 1399 const size_t len = 75;
universe@803 1400 int *testdata = int_test_data_added_to_list(list, isptrlist, len);
universe@803 1401 list->advanced_destructor = advanced_destr_test_fun;
universe@803 1402 CX_TEST_CALL_SUBROUTINE(test_list_verify_destructor, list, testdata, len);
universe@803 1403 free(testdata);
universe@803 1404 })
universe@803 1405
universe@798 1406 CxTestSuite *cx_test_suite_array_list(void) {
universe@798 1407 CxTestSuite *suite = cx_test_suite_new("array_list");
universe@798 1408
universe@818 1409 cx_test_register(suite, test_array_add);
universe@818 1410
universe@801 1411 cx_test_register(suite, test_list_arl_create);
universe@801 1412 cx_test_register(suite, test_list_arl_create_simple);
universe@801 1413 cx_test_register(suite, test_list_arl_create_simple_for_pointers);
universe@801 1414 cx_test_register(suite, test_list_parl_destroy_no_destr);
universe@801 1415 cx_test_register(suite, test_list_parl_destroy_simple_destr);
universe@801 1416 cx_test_register(suite, test_list_parl_destroy_adv_destr);
universe@801 1417
universe@803 1418 cx_test_register(suite, test_list_arl_add);
universe@803 1419 cx_test_register(suite, test_list_parl_add);
universe@803 1420 cx_test_register(suite, test_list_arl_insert);
universe@803 1421 cx_test_register(suite, test_list_parl_insert);
universe@803 1422 cx_test_register(suite, test_list_arl_insert_array);
universe@803 1423 cx_test_register(suite, test_list_parl_insert_array);
universe@803 1424 cx_test_register(suite, test_list_arl_remove);
universe@803 1425 cx_test_register(suite, test_list_parl_remove);
universe@803 1426 cx_test_register(suite, test_list_arl_find_remove);
universe@803 1427 cx_test_register(suite, test_list_parl_find_remove);
universe@803 1428 cx_test_register(suite, test_list_arl_clear);
universe@803 1429 cx_test_register(suite, test_list_parl_clear);
universe@803 1430 cx_test_register(suite, test_list_arl_at);
universe@803 1431 cx_test_register(suite, test_list_parl_at);
universe@803 1432 cx_test_register(suite, test_list_arl_swap);
universe@803 1433 cx_test_register(suite, test_list_parl_swap);
universe@803 1434 cx_test_register(suite, test_list_arl_swap_no_sbo);
universe@803 1435 cx_test_register(suite, test_list_arl_find);
universe@803 1436 cx_test_register(suite, test_list_parl_find);
universe@803 1437 cx_test_register(suite, test_list_arl_sort);
universe@803 1438 cx_test_register(suite, test_list_parl_sort);
universe@803 1439 cx_test_register(suite, test_list_arl_reverse);
universe@803 1440 cx_test_register(suite, test_list_parl_reverse);
universe@803 1441 cx_test_register(suite, test_list_arl_iterator);
universe@803 1442 cx_test_register(suite, test_list_parl_iterator);
universe@803 1443 cx_test_register(suite, test_list_arl_insert_with_iterator);
universe@803 1444 cx_test_register(suite, test_list_parl_insert_with_iterator);
universe@803 1445 cx_test_register(suite, test_list_arl_compare_ll);
universe@803 1446 cx_test_register(suite, test_list_arl_compare_arl);
universe@803 1447 cx_test_register(suite, test_list_arl_compare_pll);
universe@803 1448 cx_test_register(suite, test_list_arl_compare_parl);
universe@803 1449 cx_test_register(suite, test_list_parl_compare_ll);
universe@803 1450 cx_test_register(suite, test_list_parl_compare_arl);
universe@803 1451 cx_test_register(suite, test_list_parl_compare_pll);
universe@803 1452 cx_test_register(suite, test_list_parl_compare_parl);
universe@803 1453 cx_test_register(suite, test_list_arl_simple_destr);
universe@803 1454 cx_test_register(suite, test_list_parl_simple_destr);
universe@803 1455 cx_test_register(suite, test_list_arl_advanced_destr);
universe@803 1456 cx_test_register(suite, test_list_parl_advanced_destr);
universe@803 1457
universe@798 1458 return suite;
universe@798 1459 }
universe@798 1460
universe@798 1461 CxTestSuite *cx_test_suite_linked_list(void) {
universe@798 1462 CxTestSuite *suite = cx_test_suite_new("linked_list");
universe@798 1463
universe@798 1464 cx_test_register(suite, test_linked_list_link_unlink);
universe@798 1465 cx_test_register(suite, test_linked_list_at);
universe@798 1466 cx_test_register(suite, test_linked_list_find);
universe@798 1467 cx_test_register(suite, test_linked_list_compare);
universe@798 1468 cx_test_register(suite, test_linked_list_add);
universe@798 1469 cx_test_register(suite, test_linked_list_prepend);
universe@798 1470 cx_test_register(suite, test_linked_list_insert);
universe@798 1471 cx_test_register(suite, test_linked_list_insert_chain);
universe@798 1472 cx_test_register(suite, test_linked_list_first);
universe@798 1473 cx_test_register(suite, test_linked_list_last);
universe@798 1474 cx_test_register(suite, test_linked_list_prev);
universe@798 1475 cx_test_register(suite, test_linked_list_remove);
universe@798 1476 cx_test_register(suite, test_linked_list_size);
universe@798 1477 cx_test_register(suite, test_linked_list_sort_empty);
universe@798 1478 cx_test_register(suite, test_linked_list_sort);
universe@798 1479 cx_test_register(suite, test_linked_list_reverse);
universe@798 1480
universe@801 1481 cx_test_register(suite, test_list_ll_create);
universe@801 1482 cx_test_register(suite, test_list_ll_create_simple);
universe@801 1483 cx_test_register(suite, test_list_ll_store_pointers);
universe@801 1484 cx_test_register(suite, test_list_ll_create_simple_for_pointers);
universe@801 1485 cx_test_register(suite, test_list_pll_destroy_no_destr);
universe@801 1486 cx_test_register(suite, test_list_pll_destroy_simple_destr);
universe@801 1487 cx_test_register(suite, test_list_pll_destroy_adv_destr);
universe@801 1488
universe@803 1489 cx_test_register(suite, test_list_ll_add);
universe@803 1490 cx_test_register(suite, test_list_pll_add);
universe@803 1491 cx_test_register(suite, test_list_ll_insert);
universe@803 1492 cx_test_register(suite, test_list_pll_insert);
universe@803 1493 cx_test_register(suite, test_list_ll_insert_array);
universe@803 1494 cx_test_register(suite, test_list_pll_insert_array);
universe@803 1495 cx_test_register(suite, test_list_ll_remove);
universe@803 1496 cx_test_register(suite, test_list_pll_remove);
universe@803 1497 cx_test_register(suite, test_list_ll_find_remove);
universe@803 1498 cx_test_register(suite, test_list_pll_find_remove);
universe@803 1499 cx_test_register(suite, test_list_ll_clear);
universe@803 1500 cx_test_register(suite, test_list_pll_clear);
universe@803 1501 cx_test_register(suite, test_list_ll_at);
universe@803 1502 cx_test_register(suite, test_list_pll_at);
universe@803 1503 cx_test_register(suite, test_list_ll_swap);
universe@803 1504 cx_test_register(suite, test_list_pll_swap);
universe@803 1505 cx_test_register(suite, test_list_ll_swap_no_sbo);
universe@803 1506 cx_test_register(suite, test_list_ll_find);
universe@803 1507 cx_test_register(suite, test_list_pll_find);
universe@803 1508 cx_test_register(suite, test_list_ll_sort);
universe@803 1509 cx_test_register(suite, test_list_pll_sort);
universe@803 1510 cx_test_register(suite, test_list_ll_reverse);
universe@803 1511 cx_test_register(suite, test_list_pll_reverse);
universe@803 1512 cx_test_register(suite, test_list_ll_iterator);
universe@803 1513 cx_test_register(suite, test_list_pll_iterator);
universe@803 1514 cx_test_register(suite, test_list_ll_insert_with_iterator);
universe@803 1515 cx_test_register(suite, test_list_pll_insert_with_iterator);
universe@803 1516 cx_test_register(suite, test_list_ll_compare_ll);
universe@803 1517 cx_test_register(suite, test_list_ll_compare_arl);
universe@803 1518 cx_test_register(suite, test_list_ll_compare_pll);
universe@803 1519 cx_test_register(suite, test_list_ll_compare_parl);
universe@803 1520 cx_test_register(suite, test_list_pll_compare_ll);
universe@803 1521 cx_test_register(suite, test_list_pll_compare_arl);
universe@803 1522 cx_test_register(suite, test_list_pll_compare_pll);
universe@803 1523 cx_test_register(suite, test_list_pll_compare_parl);
universe@803 1524 cx_test_register(suite, test_list_ll_simple_destr);
universe@803 1525 cx_test_register(suite, test_list_pll_simple_destr);
universe@803 1526 cx_test_register(suite, test_list_ll_advanced_destr);
universe@803 1527 cx_test_register(suite, test_list_pll_advanced_destr);
universe@803 1528
universe@798 1529 return suite;
universe@798 1530 }
universe@798 1531
universe@800 1532 CxTestSuite *cx_test_suite_empty_list(void) {
universe@800 1533 CxTestSuite *suite = cx_test_suite_new("empty list dummy");
universe@800 1534
universe@800 1535 cx_test_register(suite, test_empty_list_size);
universe@800 1536 cx_test_register(suite, test_empty_list_iterator);
universe@800 1537 cx_test_register(suite, test_empty_list_noops);
universe@800 1538 cx_test_register(suite, test_empty_list_at);
universe@800 1539 cx_test_register(suite, test_empty_list_find);
universe@800 1540 cx_test_register(suite, test_empty_list_compare);
universe@800 1541
universe@800 1542 return suite;
universe@800 1543 }

mercurial