add missing test coverage for cx_array_reserve()

Tue, 18 Nov 2025 17:36:41 +0100

author
Mike Becker <universe@uap-core.de>
date
Tue, 18 Nov 2025 17:36:41 +0100
changeset 1494
f027a95d93f2
parent 1493
33f556a7eca6
child 1495
beee442be85a

add missing test coverage for cx_array_reserve()

src/array_list.c file | annotate | diff | comparison | revisions
tests/test_list.c file | annotate | diff | comparison | revisions
--- a/src/array_list.c	Mon Nov 17 22:28:04 2025 +0100
+++ b/src/array_list.c	Tue Nov 18 17:36:41 2025 +0100
@@ -42,10 +42,11 @@
         cx_attr_unused CxArrayReallocator *alloc
 ) {
     size_t n;
+    // LCOV_EXCL_START
     if (cx_szmul(new_capacity, elem_size, &n)) {
         errno = EOVERFLOW;
         return NULL;
-    }
+    } // LCOV_EXCL_STOP
     return cxReallocDefault(array, n);
 }
 
@@ -66,10 +67,11 @@
 ) {
     // check for overflow
     size_t n;
+    // LCOV_EXCL_START
     if (cx_szmul(new_capacity, elem_size, &n)) {
         errno = EOVERFLOW;
         return NULL;
-    }
+    } // LCOV_EXCL_STOP
 
     // retrieve the pointer to the actual allocator
     const CxAllocator *al = alloc->allocator;
@@ -108,13 +110,11 @@
  *
  * @param current_capacity the current capacity of the array
  * @param needed_capacity the required capacity of the array
- * @param maximum_capacity the maximum capacity (given by the data type)
  * @return the new capacity
  */
 static size_t cx_array_grow_capacity(
     size_t current_capacity,
-    size_t needed_capacity,
-    size_t maximum_capacity
+    size_t needed_capacity
 ) {
     if (current_capacity >= needed_capacity) {
         return current_capacity;
@@ -125,12 +125,7 @@
     else if (cap < 1024) alignment = 64;
     else if (cap < 8192) alignment = 512;
     else alignment = 1024;
-
-    if (cap - 1 > maximum_capacity - alignment) {
-        return maximum_capacity;
-    } else {
-        return cap - (cap % alignment) + alignment;
-    }
+    return cap - (cap % alignment) + alignment;
 }
 
 int cx_array_reserve(
@@ -288,7 +283,7 @@
     const size_t newsize = oldsize < minsize ? minsize : oldsize;
 
     // reallocate if necessary
-    const size_t newcap = cx_array_grow_capacity(oldcap, newsize, max_size);
+    const size_t newcap = cx_array_grow_capacity(oldcap, newsize);
     if (newcap > oldcap) {
         // check if we need to repair the src pointer
         uintptr_t targetaddr = (uintptr_t) *target;
@@ -381,8 +376,7 @@
     const size_t old_size = *size;
     const size_t old_capacity = *capacity;
     // the necessary capacity is the worst case assumption, including duplicates
-    const size_t needed_capacity = cx_array_grow_capacity(old_capacity,
-        old_size + elem_count, SIZE_MAX);
+    const size_t needed_capacity = cx_array_grow_capacity(old_capacity, old_size + elem_count);
 
     // if we need more than we have, try a reallocation
     if (needed_capacity > old_capacity) {
@@ -792,8 +786,7 @@
 
     // guarantee enough capacity
     if (arl->capacity < list->collection.size + n) {
-        const size_t new_capacity = cx_array_grow_capacity(arl->capacity,
-            list->collection.size + n, SIZE_MAX);
+        const size_t new_capacity = cx_array_grow_capacity(arl->capacity,list->collection.size + n);
         if (cxReallocateArray(
                 list->collection.allocator,
                 &arl->data, new_capacity,
--- a/tests/test_list.c	Mon Nov 17 22:28:04 2025 +0100
+++ b/tests/test_list.c	Tue Nov 18 17:36:41 2025 +0100
@@ -144,20 +144,112 @@
 }
 
 CX_TEST(test_array_reserve) {
+    {
+        // default size
+        CX_ARRAY_DECLARE(int, arr);
+        cx_array_initialize(arr, 16);
+        int result;
+        CX_TEST_DO {
+            result = cx_array_reserve(
+                (void **) &(arr),
+                &(arr_size),
+                &(arr_capacity),
+                0, // default width
+                sizeof(int),
+                30,
+                cx_array_default_reallocator
+            );
+            CX_TEST_ASSERT(result == 0);
+            CX_TEST_ASSERT(arr_size == 0);
+            CX_TEST_ASSERT(arr_capacity == 30);
+        }
+        cxFreeDefault(arr);
+    }
+    {
+        // 16-bit size
+        CX_ARRAY_DECLARE_SIZED(char, arr, uint16_t);
+        cx_array_initialize(arr, 16);
+        arr_size = 5;
+        int result;
+        CX_TEST_DO {
+            errno = 0;
+            result = cx_array_simple_reserve(arr, 3);
+            CX_TEST_ASSERT(result == 0);
+            CX_TEST_ASSERT(errno == 0);
+            CX_TEST_ASSERT(arr_size == 5);
+            CX_TEST_ASSERT(arr_capacity == 16);
+
+            result = cx_array_simple_reserve(arr, 20);
+            CX_TEST_ASSERT(result == 0);
+            CX_TEST_ASSERT(errno == 0);
+            CX_TEST_ASSERT(arr_size == 5);
+            CX_TEST_ASSERT(arr_capacity == 25);
+
+            result = cx_array_simple_reserve(arr, 2000);
+            CX_TEST_ASSERT(result == 0);
+            CX_TEST_ASSERT(errno == 0);
+            CX_TEST_ASSERT(arr_size == 5);
+            CX_TEST_ASSERT(arr_capacity == 2005);
+
+            // this does not fit into an array with a 16-bit size
+            result = cx_array_simple_reserve(arr, 70000);
+            CX_TEST_ASSERT(result == 1);
+            CX_TEST_ASSERT(errno == EOVERFLOW);
+            CX_TEST_ASSERT(arr_size == 5);
+            CX_TEST_ASSERT(arr_capacity == 2005);
+        }
+        cxFreeDefault(arr);
+    }
+    {
+        // 8-bit size
+        CX_ARRAY_DECLARE_SIZED(char, arr, uint8_t);
+        cx_array_initialize(arr, 16);
+        arr_size = 5;
+        int result;
+        CX_TEST_DO {
+            errno = 0;
+            result = cx_array_simple_reserve(arr, 3);
+            CX_TEST_ASSERT(result == 0);
+            CX_TEST_ASSERT(errno == 0);
+            CX_TEST_ASSERT(arr_size == 5);
+            CX_TEST_ASSERT(arr_capacity == 16);
+
+            result = cx_array_simple_reserve(arr, 20);
+            CX_TEST_ASSERT(result == 0);
+            CX_TEST_ASSERT(errno == 0);
+            CX_TEST_ASSERT(arr_size == 5);
+            CX_TEST_ASSERT(arr_capacity == 25);
+
+            // this does not fit into an array with an 8-bit size
+            arr_size = 10;
+            result = cx_array_simple_reserve(arr, 250);
+            CX_TEST_ASSERT(result == 1);
+            CX_TEST_ASSERT(errno == EOVERFLOW);
+            CX_TEST_ASSERT(arr_size == 10);
+            CX_TEST_ASSERT(arr_capacity == 25);
+        }
+        cxFreeDefault(arr);
+    }
+}
+
+CX_TEST(test_array_reserve_unsupported_width) {
     CX_ARRAY_DECLARE_SIZED(int, arr, uint16_t);
     cx_array_initialize(arr, 16);
-    arr_size = 5;
     int result;
     CX_TEST_DO {
-        result = cx_array_simple_reserve(arr, 3);
-        CX_TEST_ASSERT(result == 0);
-        CX_TEST_ASSERT(arr_size == 5);
+        result = cx_array_reserve(
+            (void **) &(arr),
+            &(arr_size),
+            &(arr_capacity),
+            12, // unsupported width
+            sizeof(int),
+            30,
+            cx_array_default_reallocator
+        );
+        CX_TEST_ASSERT(result != 0);
+        CX_TEST_ASSERT(errno == EINVAL);
+        CX_TEST_ASSERT(arr_size == 0);
         CX_TEST_ASSERT(arr_capacity == 16);
-
-        result = cx_array_simple_reserve(arr, 20);
-        CX_TEST_ASSERT(result == 0);
-        CX_TEST_ASSERT(arr_size == 5);
-        CX_TEST_ASSERT(arr_capacity == 25);
     }
     cxFreeDefault(arr);
 }
@@ -3196,6 +3288,7 @@
     cx_test_register(suite, test_array_add8);
     cx_test_register(suite, test_array_copy_unsupported_width);
     cx_test_register(suite, test_array_reserve);
+    cx_test_register(suite, test_array_reserve_unsupported_width);
     cx_test_register(suite, test_array_insert_sorted);
     cx_test_register(suite, test_array_insert_unique);
     cx_test_register(suite, test_array_binary_search);

mercurial