Wed, 06 Nov 2019 16:27:54 +0100
adds testcase to uncover a bug in ucx_array_append()
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2019 Mike Becker, Olaf Wintermann All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
29 #include "array_tests.h"
30 #include <ucx/utils.h>
32 UCX_TEST(test_ucx_array_destroy) {
33 UcxArray array;
34 ucx_array_init(&array, 16, sizeof(int));
36 UCX_TEST_BEGIN
37 ucx_array_destroy(&array);
38 UCX_TEST_ASSERT(array.data == NULL, "data pointer not NULL after destroy");
39 UCX_TEST_ASSERT(array.size == 0, "size not zero after destroy");
40 UCX_TEST_ASSERT(array.capacity == 0, "capacity not zero after destroy");
41 UCX_TEST_ASSERT(array.allocator == ucx_default_allocator(),
42 "allocator corrupted during destroy");
43 UCX_TEST_END
44 }
46 UCX_TEST(test_ucx_array_new) {
47 UcxArray* array = ucx_array_new(16, 47);
49 UCX_TEST_BEGIN
50 UCX_TEST_ASSERT(array->data, "no memory allocated");
51 UCX_TEST_ASSERT(array->size == 0, "size not initially zero");
52 UCX_TEST_ASSERT(array->capacity == 16, "capacity not as requested");
53 UCX_TEST_ASSERT(array->elemsize == 47, "element size not as requested");
54 UCX_TEST_ASSERT(array->allocator == ucx_default_allocator(),
55 "array not using the default allocator");
56 UCX_TEST_END
57 ucx_array_free(array);
58 }
60 UCX_TEST(test_ucx_array_append_from) {
61 UcxArray *array = ucx_array_new(16, sizeof(int));
62 int *elements;
64 int x = 42;
65 ucx_array_append_from(array, &x, 1);
66 UCX_TEST_BEGIN
68 elements = array->data;
69 UCX_TEST_ASSERT(elements[0] == 42, "failed");
71 int y[2] = {13, 37};
72 ucx_array_append_from(array, y, 2);
74 elements = array->data;
75 UCX_TEST_ASSERT(array->size == 3, "incorrect size after append");
76 UCX_TEST_ASSERT(elements[1] == 13, "failed");
77 UCX_TEST_ASSERT(elements[2] == 37, "failed");
78 UCX_TEST_ASSERT(elements[0] == 42,
79 "append corrupted previously inserted data");
81 ucx_array_append_from(array, NULL, 2);
83 elements = array->data;
84 UCX_TEST_ASSERT(array->size == 5, "incorrect size after NULL append");
85 UCX_TEST_ASSERT(elements[3] == 0, "element is not zeroed");
86 UCX_TEST_ASSERT(elements[4] == 0, "element is not zeroed");
87 UCX_TEST_ASSERT(elements[0] == 42,
88 "NULL append corrupted previously inserted data");
89 UCX_TEST_ASSERT(elements[1] == 13,
90 "NULL append corrupted previously inserted data");
91 UCX_TEST_ASSERT(elements[2] == 37,
92 "NULL append corrupted previously inserted data");
94 UCX_TEST_END
96 ucx_array_free(array);
97 }
99 UCX_TEST(test_ucx_array_append_from_struct) {
100 struct teststruct {
101 unsigned long long x;
102 unsigned long long y;
103 unsigned long long z;
104 };
106 UcxArray *array = ucx_array_new(16, sizeof(struct teststruct));
107 struct teststruct *elements;
109 struct teststruct data;
110 data.x = 13; data.y = 37; data.z = 47;
112 ucx_array_append_from(array, &data, 1);
113 UCX_TEST_BEGIN
115 elements = array->data;
116 UCX_TEST_ASSERT(elements[0].x == 13, "failed");
117 UCX_TEST_ASSERT(elements[0].y == 37, "failed");
118 UCX_TEST_ASSERT(elements[0].z == 47, "failed");
120 data.x = 0; data.y = 8; data.z = 15;
121 ucx_array_append_from(array, &data, 1);
123 elements = array->data;
124 UCX_TEST_ASSERT(array->size == 2, "incorrect size after append");
125 UCX_TEST_ASSERT(elements[1].x == 0, "failed");
126 UCX_TEST_ASSERT(elements[1].y == 8, "failed");
127 UCX_TEST_ASSERT(elements[1].z == 15, "failed");
129 UCX_TEST_ASSERT(elements[0].x == 13,
130 "append corrupted previously inserted data");
131 UCX_TEST_ASSERT(elements[0].y == 37,
132 "append corrupted previously inserted data");
133 UCX_TEST_ASSERT(elements[0].z == 47,
134 "append corrupted previously inserted data");
136 UCX_TEST_END
138 ucx_array_destroy(array);
139 }
141 UCX_TEST(test_ucx_array_prepend_from) {
142 int *elems;
143 UcxArray *array = ucx_array_new(16, sizeof(int));
145 int x = 42;
146 ucx_array_prepend_from(array, &x, 1);
147 UCX_TEST_BEGIN
149 elems = array->data;
150 UCX_TEST_ASSERT(elems[0] == 42, "failed");
152 int y[2] = {13, 37};
153 ucx_array_prepend_from(array, y, 2);
155 elems = array->data;
156 UCX_TEST_ASSERT(array->size == 3, "incorrect size after prepend");
157 UCX_TEST_ASSERT(elems[0] == 13, "failed");
158 UCX_TEST_ASSERT(elems[1] == 37, "failed");
159 UCX_TEST_ASSERT(elems[2] == 42,
160 "prepend corrupted previously inserted data");
162 ucx_array_prepend_from(array, NULL, 2);
164 elems = array->data;
165 UCX_TEST_ASSERT(array->size == 5, "incorrect size after NULL prepend");
166 UCX_TEST_ASSERT(elems[0] == 0, "element is not zeroed");
167 UCX_TEST_ASSERT(elems[1] == 0, "element is not zeroed");
168 UCX_TEST_ASSERT(elems[2] == 13,
169 "NULL prepend corrupted previously inserted data");
170 UCX_TEST_ASSERT(elems[3] == 37,
171 "NULL prepend corrupted previously inserted data");
172 UCX_TEST_ASSERT(elems[4] == 42,
173 "NULL prepend corrupted previously inserted data");
175 UCX_TEST_END
177 ucx_array_free(array);
178 }
180 UCX_TEST(test_ucx_array_set_from) {
181 int *elems;
182 UcxArray *array = ucx_array_new(16, sizeof(int));
184 int x = 42;
186 UCX_TEST_BEGIN
188 ucx_array_set_from(array, 7, &x, 1);
190 elems = array->data;
191 UCX_TEST_ASSERT(elems[7] == 42, "failed");
192 UCX_TEST_ASSERT(array->size >= 8, "array not resized on set");
193 UCX_TEST_ASSERT(array->capacity == 16, "capacity changed unnecessarily");
195 int y[2] = {13, 37};
196 ucx_array_set_from(array, 27, y, 2);
198 elems = array->data;
199 UCX_TEST_ASSERT(elems[27] == 13, "failed");
200 UCX_TEST_ASSERT(elems[28] == 37, "failed");
201 UCX_TEST_ASSERT(array->size == 29, "array not resized on set");
202 UCX_TEST_ASSERT(array->capacity == 32, "capacity not grown");
204 ucx_array_set_from(array, 7, NULL, 2);
206 elems = array->data;
207 UCX_TEST_ASSERT(elems[7] == 0, "not zeroed on NULL set");
208 UCX_TEST_ASSERT(elems[8] == 0, "not zeroed on NULL set");
210 UCX_TEST_END
212 ucx_array_free(array);
213 }
215 UCX_TEST(test_ucx_array_append) {
216 UcxArray *array = ucx_array_new(16, sizeof(int));
217 int *elements;
219 ucx_array_append(array, 42);
220 UCX_TEST_BEGIN
222 elements = array->data;
223 UCX_TEST_ASSERT(elements[0] == 42, "failed");
225 ucx_array_append(array, 13);
226 ucx_array_append(array, 37);
228 elements = array->data;
229 UCX_TEST_ASSERT(array->size == 3, "incorrect size after append");
230 UCX_TEST_ASSERT(elements[1] == 13, "failed");
231 UCX_TEST_ASSERT(elements[2] == 37, "failed");
232 UCX_TEST_ASSERT(elements[0] == 42,
233 "append corrupted previously inserted data");
235 UCX_TEST_END
237 ucx_array_destroy(array);
238 }
240 UCX_TEST(test_ucx_array_append_struct) {
241 struct teststruct {
242 unsigned long long x;
243 unsigned long long y;
244 unsigned long long z;
245 };
247 UcxArray *array = ucx_array_new(16, sizeof(struct teststruct));
248 struct teststruct *elements;
250 struct teststruct data;
251 data.x = 13; data.y = 37; data.z = 47;
253 ucx_array_append(array, data);
254 UCX_TEST_BEGIN
256 elements = array->data;
257 UCX_TEST_ASSERT(elements[0].x == 13, "failed");
258 UCX_TEST_ASSERT(elements[0].y == 37, "failed");
259 UCX_TEST_ASSERT(elements[0].z == 47, "failed");
261 data.x = 0; data.y = 8; data.z = 15;
262 ucx_array_append(array, data);
264 elements = array->data;
265 UCX_TEST_ASSERT(array->size == 2, "incorrect size after append");
266 UCX_TEST_ASSERT(elements[1].x == 0, "failed");
267 UCX_TEST_ASSERT(elements[1].y == 8, "failed");
268 UCX_TEST_ASSERT(elements[1].z == 15, "failed");
270 UCX_TEST_ASSERT(elements[0].x == 13,
271 "append corrupted previously inserted data");
272 UCX_TEST_ASSERT(elements[0].y == 37,
273 "append corrupted previously inserted data");
274 UCX_TEST_ASSERT(elements[0].z == 47,
275 "append corrupted previously inserted data");
277 UCX_TEST_END
279 ucx_array_destroy(array);
280 }
282 UCX_TEST(test_ucx_array_prepend) {
283 int *elems;
284 UcxArray *array = ucx_array_new(16, sizeof(int));
286 ucx_array_prepend(array, 42);
287 UCX_TEST_BEGIN
289 elems = array->data;
290 UCX_TEST_ASSERT(elems[0] == 42, "failed");
292 ucx_array_prepend(array, 37);
293 ucx_array_prepend(array, 13);
295 elems = array->data;
296 UCX_TEST_ASSERT(array->size == 3, "incorrect size after prepend");
297 UCX_TEST_ASSERT(elems[0] == 13, "failed");
298 UCX_TEST_ASSERT(elems[1] == 37, "failed");
299 UCX_TEST_ASSERT(elems[2] == 42,
300 "prepend corrupted previously inserted data");
302 UCX_TEST_END
304 ucx_array_free(array);
305 }
307 UCX_TEST(test_ucx_array_set) {
308 int *elems;
309 UcxArray *array = ucx_array_new(16, sizeof(int));
311 UCX_TEST_BEGIN
313 ucx_array_set(array, 7, 42);
315 elems = array->data;
316 UCX_TEST_ASSERT(elems[7] == 42, "failed");
317 UCX_TEST_ASSERT(array->size == 8, "array not resized on set");
318 UCX_TEST_ASSERT(array->capacity == 16, "capacity changed unnecessarily");
320 ucx_array_set(array, 27, 13);
321 ucx_array_set(array, 28, 37);
323 elems = array->data;
324 UCX_TEST_ASSERT(elems[27] == 13, "failed");
325 UCX_TEST_ASSERT(elems[28] == 37, "failed");
326 UCX_TEST_ASSERT(array->size == 29, "array not resized on set");
327 UCX_TEST_ASSERT(array->capacity == 32, "capacity not grown");
329 UCX_TEST_END
331 ucx_array_free(array);
332 }
334 UCX_TEST(test_ucx_array_equals) {
335 UcxArray *a1 = ucx_array_new(16, sizeof(int32_t));
336 UcxArray *a2 = ucx_array_new(16, sizeof(int32_t));
337 UcxArray *a3 = ucx_array_new(16, sizeof(int64_t));
338 UcxArray *a4 = ucx_array_new(16, sizeof(int32_t));
340 int32_t *intelems;
341 int64_t *longintelems;
343 a1->size = 5;
344 intelems = a1->data;
345 intelems[0] = 47;
346 intelems[1] = 11;
347 intelems[2] = 0;
348 intelems[3] = 8;
349 intelems[4] = 15;
350 a2->size = 5;
351 intelems = a2->data;
352 intelems[0] = 47;
353 intelems[1] = 11;
354 intelems[2] = 0;
355 intelems[3] = 8;
356 intelems[4] = 15;
357 a3->size = 5;
358 longintelems = a3->data;
359 longintelems[0] = 47;
360 longintelems[1] = 11;
361 longintelems[2] = 0;
362 longintelems[3] = 8;
363 longintelems[4] = 15;
364 a4->size = 5;
365 intelems = a4->data;
366 intelems[0] = 47;
367 intelems[1] = 11;
368 intelems[2] = -6;
369 intelems[3] = 8;
370 intelems[4] = 15;
372 UCX_TEST_BEGIN
374 UCX_TEST_ASSERT(ucx_array_equals(a1, a2, ucx_cmp_int32, NULL), "failed");
375 UCX_TEST_ASSERT(!ucx_array_equals(a1, a4, ucx_cmp_int32, NULL), "failed");
376 UCX_TEST_ASSERT(!ucx_array_equals(a4, a1, ucx_cmp_int32, NULL), "failed");
377 UCX_TEST_ASSERT(!ucx_array_equals(a1, a3, ucx_cmp_int64, NULL),
378 "comparing arrays of different element size shall fail");
379 UCX_TEST_ASSERT(!ucx_array_equals(a3, a1, ucx_cmp_int64, NULL),
380 "comparing arrays of different element size shall fail");
382 UCX_TEST_ASSERT(ucx_array_equals(a1, a2, NULL, NULL),
383 "compare using memcmp() failed");
384 UCX_TEST_ASSERT(!ucx_array_equals(a1, a4, NULL, NULL),
385 "compare using memcmp() failed");
387 UCX_TEST_END
388 ucx_array_free(a1);
389 ucx_array_free(a2);
390 ucx_array_free(a3);
391 ucx_array_free(a4);
392 }
394 UCX_TEST(test_ucx_array_concat) {
395 UcxArray *a1 = ucx_array_new(16, sizeof(int));
396 UcxArray *a2 = ucx_array_new(16, sizeof(int));
397 int *elems;
399 a1->size = 2;
400 elems = a1->data;
401 elems[0] = 47;
402 elems[1] = 11;
403 a2->size = 3;
404 elems = a2->data;
405 elems[0] = 0;
406 elems[1] = 8;
407 elems[2] = 15;
409 UCX_TEST_BEGIN
411 UCX_TEST_ASSERT(!ucx_array_concat(a1, a2), "failed");
412 UCX_TEST_ASSERT(a1->size == 5, "failed");
413 elems = a1->data;
414 UCX_TEST_ASSERT(elems[0] == 47, "failed");
415 UCX_TEST_ASSERT(elems[1] == 11, "failed");
416 UCX_TEST_ASSERT(elems[2] == 0, "failed");
417 UCX_TEST_ASSERT(elems[3] == 8, "failed");
418 UCX_TEST_ASSERT(elems[4] == 15, "failed");
420 a1->elemsize *= 2;
421 UCX_TEST_ASSERT(ucx_array_concat(a1, a2),
422 "arrays of different element size must not be concatenated");
423 UCX_TEST_ASSERT(a1->size == 5,
424 "arrays of different element size must not be concatenated");
426 UCX_TEST_END
427 ucx_array_free(a1);
428 ucx_array_free(a2);
429 }
431 UCX_TEST(test_ucx_array_at) {
432 UcxArray *array = ucx_array_new(16, sizeof(int));
434 int x[3] = {42, 13, 5};
435 ucx_array_append_from(array, x, 3);
437 UCX_TEST_BEGIN
439 UCX_TEST_ASSERT(*(int*)ucx_array_at(array, 1) == 13, "failed");
440 *(int*)ucx_array_at(array, 1) = 80;
441 UCX_TEST_ASSERT(*(int*)ucx_array_at(array, 1) == 80, "assignment failed");
443 UCX_TEST_ASSERT(*(int*)ucx_array_at(array, 0) == 42, "corrupted data");
444 UCX_TEST_ASSERT(*(int*)ucx_array_at(array, 2) == 5, "corrupted data");
446 UCX_TEST_END
448 ucx_array_free(array);
449 }
451 UCX_TEST(test_ucx_array_find) {
452 UcxArray *array = ucx_array_new(16, sizeof(int));
453 int *elems;
455 array->size = 5;
456 elems = array->data;
457 elems[0] = 47;
458 elems[1] = 11;
459 elems[2] = 0;
460 elems[3] = 8;
461 elems[4] = 15;
463 int x = 8;
464 int y = 90;
466 UCX_TEST_BEGIN
468 UCX_TEST_ASSERT(ucx_array_find(array,(void*)&x,ucx_cmp_int,NULL) == 3,
469 "doesn't find element");
470 UCX_TEST_ASSERT(ucx_array_find(array,(void*)&y,ucx_cmp_int,NULL) == 5,
471 "finds non-existing element");
473 UCX_TEST_ASSERT(ucx_array_find(array,(void*)&x,NULL,NULL) == 3,
474 "failed using memcmp()");
475 UCX_TEST_ASSERT(ucx_array_find(array,(void*)&y,NULL,NULL) == 5,
476 "failed using memcmp()");
478 UCX_TEST_END
479 ucx_array_free(array);
480 }
482 UCX_TEST(test_ucx_array_contains) {
483 UcxArray *array = ucx_array_new(16, sizeof(int));
484 int *elems;
486 array->size = 5;
487 elems = array->data;
488 elems[0] = 47;
489 elems[1] = 11;
490 elems[2] = 0;
491 elems[3] = 8;
492 elems[4] = 15;
494 int x = 8;
495 int y = 90;
497 UCX_TEST_BEGIN
499 UCX_TEST_ASSERT(ucx_array_contains(array,(void*)&x,ucx_cmp_int,NULL),
500 "false negative");
501 UCX_TEST_ASSERT(!ucx_array_contains(array,(void*)&y,ucx_cmp_int,NULL),
502 "false positive");
504 UCX_TEST_ASSERT(ucx_array_contains(array,(void*)&x,NULL,NULL),
505 "false negative using memcmp()");
506 UCX_TEST_ASSERT(!ucx_array_contains(array,(void*)&y,NULL,NULL),
507 "false positive using memcmp()");
509 UCX_TEST_END
510 ucx_array_free(array);
511 }
513 UCX_TEST(test_ucx_array_remove) {
514 UcxArray *array = ucx_array_new(16, sizeof(int));
515 int *elems;
517 array->size = 5;
518 elems = array->data;
519 elems[0] = 47;
520 elems[1] = 11;
521 elems[2] = 0;
522 elems[3] = 8;
523 elems[4] = 15;
525 UCX_TEST_BEGIN
527 ucx_array_remove(array, 2);
528 elems = array->data;
529 UCX_TEST_ASSERT(
530 elems[0] == 47 &&
531 elems[1] == 11 &&
532 elems[2] == 8 &&
533 elems[3] == 15,
534 "wrong contents after remove");
535 UCX_TEST_ASSERT(array->size == 4, "wrong size after remove");
537 ucx_array_remove_fast(array, 1);
538 elems = array->data;
539 UCX_TEST_ASSERT(
540 elems[0] == 47 &&
541 elems[1] == 15 &&
542 elems[2] == 8,
543 "wrong contents after fast remove");
544 UCX_TEST_ASSERT(array->size == 3, "wrong size after fast remove");
546 UCX_TEST_END
547 ucx_array_free(array);
548 }
550 UCX_TEST(test_ucx_array_clone) {
551 UcxArray array;
552 UcxArray copy;
553 ucx_array_init(&array, 16, sizeof(int));
554 ucx_array_init(©, 4, 2*sizeof(double));
555 int *elems;
557 array.size = 5;
558 elems = array.data;
559 elems[0] = 47;
560 elems[1] = 11;
561 elems[2] = 0;
562 elems[3] = 8;
563 elems[4] = 15;
565 ucx_array_clone(©, &array);
566 UCX_TEST_BEGIN
568 UCX_TEST_ASSERT(array.data != copy.data, "no true copy");
569 UCX_TEST_ASSERT(array.size == copy.size, "size mismatch");
570 UCX_TEST_ASSERT(array.capacity == copy.capacity, "capacity mismatch");
571 UCX_TEST_ASSERT(array.elemsize == copy.elemsize, "element size mismatch");
572 UCX_TEST_ASSERT(array.allocator == copy.allocator, "allocator mismatch");
573 UCX_TEST_ASSERT(ucx_array_equals(&array, ©, ucx_cmp_int, NULL),
574 "contents do not match after clone");
576 UCX_TEST_END
578 ucx_array_destroy(&array);
579 ucx_array_destroy(©);
580 }
582 static int ucx_cmp_int_reverse(const void* x, const void* y, void* data) {
583 return -ucx_cmp_int(x,y,data);
584 }
586 UCX_TEST(test_ucx_array_sort) {
587 int *elems;
589 UcxArray *array = ucx_array_new(16, sizeof(int));
590 array->size = 5;
591 elems = array->data;
592 elems[0] = 47;
593 elems[1] = 11;
594 elems[2] = 0;
595 elems[3] = 8;
596 elems[4] = 15;
598 UcxArray *expected = ucx_array_new(16, sizeof(int));
599 expected->size = 5;
600 elems = expected->data;
601 elems[0] = 0;
602 elems[1] = 8;
603 elems[2] = 11;
604 elems[3] = 15;
605 elems[4] = 47;
607 UcxArray *expectedrev = ucx_array_new(16, sizeof(int));
608 expectedrev->size = 5;
609 elems = expectedrev->data;
610 elems[0] = 47;
611 elems[1] = 15;
612 elems[2] = 11;
613 elems[3] = 8;
614 elems[4] = 0;
617 UCX_TEST_BEGIN
618 void* original_ptr = array->data;
619 ucx_array_sort(array, ucx_cmp_int, NULL);
620 UCX_TEST_ASSERT(ucx_array_equals(array, expected, NULL, NULL), "failed");
621 UCX_TEST_ASSERT(array->size == 5, "size corrupted");
622 UCX_TEST_ASSERT(array->data == original_ptr, "shall not reallocate");
624 ucx_array_sort(array, ucx_cmp_int_reverse, NULL);
625 UCX_TEST_ASSERT(ucx_array_equals(array, expectedrev, NULL, NULL), "failed");
627 ucx_array_reserve(array, 32);
628 ucx_array_reserve(expected, 32);
629 array->size = expected->size = 32;
630 for (size_t i = 0 ; i < 32 ; i++) {
631 ((int*)array->data)[i]= ((i%2==0)?-1:1) * ((int) i);
632 ((int*)expected->data)[i] = (-30+2*i) - (i > 15 ? 1 : 0);
633 }
635 /* dummy third argument to trigger a possible fallback for qsort_s */
636 ucx_array_sort(array, ucx_cmp_int, array->data);
637 UCX_TEST_ASSERT(ucx_array_equals(array, expected, NULL, NULL),
638 "failed for bigger arrays");
639 UCX_TEST_END
641 ucx_array_free(expectedrev);
642 ucx_array_free(expected);
643 ucx_array_free(array);
644 }
646 UCX_TEST(test_ucx_array_autogrow) {
647 int *elems;
648 UcxArray *array = ucx_array_new(4, sizeof(int));
649 array->size = 3;
650 elems = array->data;
651 elems[0] = 47;
652 elems[1] = 11;
653 int x = 5;
655 UCX_TEST_BEGIN
657 void* oldptr = array->data;
659 ucx_array_append(array, 5);
660 UCX_TEST_ASSERT(array->capacity == 4 && array->data == oldptr,
661 "array should not grow too early");
662 ucx_array_append(array, 5);
663 elems = array->data;
664 UCX_TEST_ASSERT(array->capacity == 8, "array did not grow");
665 UCX_TEST_ASSERT(array->size == 5, "incorrect size after grow");
666 UCX_TEST_ASSERT(elems[3] == 5 && elems[4] == 5, "corrupt data");
668 UCX_TEST_END
669 ucx_array_free(array);
670 }
672 UCX_TEST(test_ucx_array_shrink) {
673 UcxArray *array = ucx_array_new(16, sizeof(int));
674 array->size = 4;
676 UCX_TEST_BEGIN
677 UCX_TEST_ASSERT(!ucx_array_shrink(array), "failed");
678 UCX_TEST_ASSERT(array->capacity == 4, "incorrect capacity after shrink");
679 UCX_TEST_END
680 ucx_array_free(array);
681 }
683 UCX_TEST(test_ucx_array_resize) {
684 UcxArray *array = ucx_array_new(16, sizeof(int));
685 array->size = 8;
687 UCX_TEST_BEGIN
689 UCX_TEST_ASSERT(!ucx_array_resize(array, 32), "failed");
690 UCX_TEST_ASSERT(array->capacity == 32, "incorrect capacity after resize");
691 UCX_TEST_ASSERT(array->size == 8, "incorrect size after resize");
693 UCX_TEST_ASSERT(!ucx_array_resize(array, 4), "failed");
694 UCX_TEST_ASSERT(array->capacity == 4, "incorrect capacity after resize");
695 UCX_TEST_ASSERT(array->size == 4, "incorrect size after resize");
697 UCX_TEST_END
698 ucx_array_free(array);
699 }
701 UCX_TEST(test_ucx_array_reserve) {
702 UcxArray *array = ucx_array_new(16, sizeof(int));
704 UCX_TEST_BEGIN
706 UCX_TEST_ASSERT(!ucx_array_reserve(array, 4), "failed");
707 UCX_TEST_ASSERT(array->capacity == 16, "reserve shall not shrink");
709 UCX_TEST_ASSERT(!ucx_array_resize(array, 32), "failed");
710 UCX_TEST_ASSERT(array->capacity == 32, "incorrect capacity after reserve");
712 UCX_TEST_END
713 ucx_array_free(array);
714 }
716 UCX_TEST(test_ucx_array_util_set) {
717 size_t capacity = 16;
718 int* array = malloc(sizeof(int)*capacity);
720 UCX_TEST_BEGIN
722 UCX_ARRAY_UTIL_SET(&array, &capacity, 7, 42);
724 UCX_TEST_ASSERT(array[7] == 42, "failed");
725 UCX_TEST_ASSERT(capacity == 16, "capacity changed unnecessarily");
727 UCX_ARRAY_UTIL_SET(&array, &capacity, 37, 13);
728 UCX_ARRAY_UTIL_SET(&array, &capacity, 38, 37);
730 UCX_TEST_ASSERT(array[37] == 13, "failed");
731 UCX_TEST_ASSERT(array[38] == 37, "failed");
732 UCX_TEST_ASSERT(capacity == 64, "capacity not grown");
734 UCX_TEST_END
736 free(array);
737 }