This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a commit to branch feature/674-add-element-type-to-array-list
in repository https://gitbox.apache.org/repos/asf/celix.git


The following commit(s) were added to 
refs/heads/feature/674-add-element-type-to-array-list by this push:
     new 5097e483 #674 Add add/assign nullptr test for array list
5097e483 is described below

commit 5097e4831f20dbe3c947c0fb327327a1ad3cd3e3
Author: Pepijn Noltes <[email protected]>
AuthorDate: Wed Feb 7 19:25:38 2024 +0100

    #674 Add add/assign nullptr test for array list
---
 .../gtest/src/ArrayListErrorInjectionTestSuite.cc  | 26 +++++++-
 libs/utils/gtest/src/ArrayListTestSuite.cc         | 64 ++++++++++++++++++++
 libs/utils/include/celix_array_list.h              | 43 +++++++++++++-
 libs/utils/src/array_list.c                        | 69 +++++++++++-----------
 4 files changed, 162 insertions(+), 40 deletions(-)

diff --git a/libs/utils/gtest/src/ArrayListErrorInjectionTestSuite.cc 
b/libs/utils/gtest/src/ArrayListErrorInjectionTestSuite.cc
index 309d54d0..f808d3af 100644
--- a/libs/utils/gtest/src/ArrayListErrorInjectionTestSuite.cc
+++ b/libs/utils/gtest/src/ArrayListErrorInjectionTestSuite.cc
@@ -20,7 +20,6 @@
 #include <gtest/gtest.h>
 
 #include "celix_array_list.h"
-#include "celix_array_list_ei.h"
 #include "celix_err.h"
 #include "celix_utils_ei.h"
 #include "celix_version_ei.h"
@@ -34,10 +33,28 @@ public:
         celix_ei_expect_calloc(nullptr, 0, nullptr);
         celix_ei_expect_celix_utils_strdup(nullptr, 0, nullptr);
         celix_ei_expect_celix_version_copy(nullptr, 0, nullptr);
+        celix_err_resetErrors();
     }
 };
 
-TEST_F(ArrayListErrorInjectionTestSuite, TestAddFunctions) {
+TEST_F(ArrayListErrorInjectionTestSuite, CreateTest) {
+    //Given an error is injected for calloc (used for the array struct)
+    celix_ei_expect_calloc(CELIX_EI_UNKNOWN_CALLER, 1, nullptr);
+    //Then creating an array list should fail
+    EXPECT_EQ(nullptr, celix_arrayList_create());
+    //And an error is logged to the celix_err
+    EXPECT_EQ(1, celix_err_getErrorCount());
+
+    //Given an error is injected for malloc (used for the element data)
+    celix_ei_expect_malloc(CELIX_EI_UNKNOWN_CALLER, 0, nullptr);
+    //Then creating an array list should fail
+    EXPECT_EQ(nullptr, celix_arrayList_create());
+    //And an error is logged to the celix_err
+    EXPECT_EQ(2, celix_err_getErrorCount());
+}
+
+
+TEST_F(ArrayListErrorInjectionTestSuite, AddFunctionsTest) {
     //Given an array list with a capacity of 10 (whitebox knowledge)
     auto* list = celix_arrayList_create();
 
@@ -53,6 +70,8 @@ TEST_F(ArrayListErrorInjectionTestSuite, TestAddFunctions) {
     //Then adding an element should fail
     EXPECT_EQ(CELIX_ENOMEM, celix_arrayList_addInt(list, 10));
     EXPECT_EQ(10, celix_arrayList_size(list));
+    //And an error is logged to the celix_err
+    EXPECT_EQ(1, celix_err_getErrorCount());
 
     celix_arrayList_destroy(list);
 }
@@ -70,7 +89,8 @@ TEST_F(ArrayListErrorInjectionTestSuite, 
AddStringAndAddVersionFailureTest) {
     // When an error is injected for celix_version_copy
     celix_ei_expect_celix_version_copy((void*)celix_arrayList_addVersion, 0, 
nullptr);
     // Then adding a version should fail
-    EXPECT_EQ(CELIX_ENOMEM, celix_arrayList_addVersion(versionList, NULL));
+    celix_autoptr(celix_version_t) version = 
celix_version_createVersionFromString("1.0.0");
+    EXPECT_EQ(CELIX_ENOMEM, celix_arrayList_addVersion(versionList, version));
 }
 
 TEST_F(ArrayListErrorInjectionTestSuite, CopyArrayListFailureTest) {
diff --git a/libs/utils/gtest/src/ArrayListTestSuite.cc 
b/libs/utils/gtest/src/ArrayListTestSuite.cc
index 0bc61c26..e820f714 100644
--- a/libs/utils/gtest/src/ArrayListTestSuite.cc
+++ b/libs/utils/gtest/src/ArrayListTestSuite.cc
@@ -528,3 +528,67 @@ TEST_F(ArrayListTestSuite, AutoCleanupTest) {
     celix_autoptr(celix_array_list_t) list = celix_arrayList_create();
     EXPECT_NE(nullptr, list);
 }
+
+TEST_F(ArrayListTestSuite, AddNullTest) {
+    // Given an undefined type, string, string ref and version list
+    celix_autoptr(celix_array_list_t) list = celix_arrayList_create();
+    celix_autoptr(celix_array_list_t) stringList = 
celix_arrayList_createStringArray();
+    celix_autoptr(celix_array_list_t) stringRefList = 
celix_arrayList_createStringRefArray();
+    celix_autoptr(celix_array_list_t) versionList = 
celix_arrayList_createVersionArray();
+
+    // When adding a null value to the lists
+    celix_arrayList_add(list, nullptr);
+    celix_arrayList_addString(stringList, nullptr);
+    celix_arrayList_addString(stringRefList, nullptr);
+    celix_arrayList_addVersion(versionList, nullptr);
+
+    // Then the lists contain the null value
+    EXPECT_EQ(1, celix_arrayList_size(list));
+    EXPECT_EQ(nullptr, celix_arrayList_get(list, 0));
+    EXPECT_EQ(1, celix_arrayList_size(stringList));
+    EXPECT_EQ(nullptr, celix_arrayList_getString(stringList, 0));
+    EXPECT_EQ(1, celix_arrayList_size(stringRefList));
+    EXPECT_EQ(nullptr, celix_arrayList_getString(stringRefList, 0));
+    EXPECT_EQ(1, celix_arrayList_size(versionList));
+    EXPECT_EQ(nullptr, celix_arrayList_getVersion(versionList, 0));
+
+    // When copying the lists
+    celix_autoptr(celix_array_list_t) listCopy = celix_arrayList_copy(list);
+    celix_autoptr(celix_array_list_t) stringListCopy = 
celix_arrayList_copy(stringList);
+    celix_autoptr(celix_array_list_t) stringRefListCopy = 
celix_arrayList_copy(stringRefList);
+    celix_autoptr(celix_array_list_t) versionListCopy = 
celix_arrayList_copy(versionList);
+
+    // Then the copied lists contain the null value
+    EXPECT_EQ(1, celix_arrayList_size(listCopy));
+    EXPECT_EQ(nullptr, celix_arrayList_get(listCopy, 0));
+    EXPECT_EQ(1, celix_arrayList_size(stringListCopy));
+    EXPECT_EQ(nullptr, celix_arrayList_getString(stringListCopy, 0));
+    EXPECT_EQ(1, celix_arrayList_size(stringRefListCopy));
+    EXPECT_EQ(nullptr, celix_arrayList_getString(stringRefListCopy, 0));
+    EXPECT_EQ(1, celix_arrayList_size(versionListCopy));
+    EXPECT_EQ(nullptr, celix_arrayList_getVersion(versionListCopy, 0));
+}
+
+TEST_F(ArrayListTestSuite, AssignNullTest) {
+    // Given a string and version list
+    celix_autoptr(celix_array_list_t) stringList = 
celix_arrayList_createStringArray();
+    celix_autoptr(celix_array_list_t) versionList = 
celix_arrayList_createVersionArray();
+
+    // When assigning a null value to the lists
+    celix_arrayList_assignString(stringList, nullptr);
+    celix_arrayList_assignVersion(versionList, nullptr);
+
+    // Then the lists contain the null value
+    EXPECT_EQ(1, celix_arrayList_size(stringList));
+    EXPECT_EQ(nullptr, celix_arrayList_getString(stringList, 0));
+    EXPECT_EQ(1, celix_arrayList_size(versionList));
+    EXPECT_EQ(nullptr, celix_arrayList_getVersion(versionList, 0));
+
+    // When copying the lists
+    celix_autoptr(celix_array_list_t) stringListCopy = 
celix_arrayList_copy(stringList);
+    celix_autoptr(celix_array_list_t) versionListCopy = 
celix_arrayList_copy(versionList);
+
+    // Then the copied lists contain the null value
+    EXPECT_EQ(1, celix_arrayList_size(stringListCopy));
+    EXPECT_EQ(nullptr, celix_arrayList_getString(stringListCopy, 0));
+}
diff --git a/libs/utils/include/celix_array_list.h 
b/libs/utils/include/celix_array_list.h
index 716aa194..a35d87a6 100644
--- a/libs/utils/include/celix_array_list.h
+++ b/libs/utils/include/celix_array_list.h
@@ -177,16 +177,20 @@ typedef struct celix_array_list_create_options {
  *
  * The remove, equals and compare callback will be NULL.
  *
- * @deprecated Use celix_arrayList_createWithOptions instead.
+ * @return A new empty array list or NULL if the array list could not be 
created. If NULL is returned an error message
+ * is logged to celix_err.
  */
 CELIX_UTILS_DEPRECATED_EXPORT
-celix_array_list_t* celix_arrayList_create() __attribute__((deprecated("use 
create typed array list instead")));
+celix_array_list_t* celix_arrayList_create();
 
 /**
  * @brief Creates a new empty array list with a pointer element type where the 
array list is not the owner of the
  * pointers.
  *
  * The remove, equals and compare callback will be NULL.
+ *
+ * @return A new empty array list or NULL if the array list could not be 
created. If NULL is returned an error message
+ * is logged to celix_err.
  */
 CELIX_UTILS_EXPORT
 celix_array_list_t* celix_arrayList_createPointerArray();
@@ -196,6 +200,9 @@ celix_array_list_t* celix_arrayList_createPointerArray();
  *
  * The remove callback will be configured to free the string, and equals and 
compare callback will be configured for
  * string comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be 
created. If NULL is returned an error message
+ * is logged to celix_err.
  */
 CELIX_UTILS_EXPORT
 celix_array_list_t* celix_arrayList_createStringArray();
@@ -206,6 +213,9 @@ celix_array_list_t* celix_arrayList_createStringArray();
  *
  * The remove callback will be configured to NULL, and equals and compare 
callback will be configured for
  * string comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be 
created. If NULL is returned an error message
+ * is logged to celix_err.
  */
 CELIX_UTILS_EXPORT
 celix_array_list_t* celix_arrayList_createStringRefArray();
@@ -215,6 +225,9 @@ celix_array_list_t* celix_arrayList_createStringRefArray();
  *
  * The remove callback will be configured to NULL, and equals and compare 
callback will be configured for
  * integer comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be 
created. If NULL is returned an error message
+ * is logged to celix_err.
  */
 CELIX_UTILS_EXPORT
 celix_array_list_t* celix_arrayList_createIntArray();
@@ -224,6 +237,9 @@ celix_array_list_t* celix_arrayList_createIntArray();
  *
  * The remove callback will be configured to NULL, and equals and compare 
callback will be configured for
  * integer comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be 
created. If NULL is returned an error message
+ * is logged to celix_err.
  */
 CELIX_UTILS_EXPORT
 celix_array_list_t* celix_arrayList_createLongArray();
@@ -233,6 +249,9 @@ celix_array_list_t* celix_arrayList_createLongArray();
  *
  * The remove callback will be configured to NULL, and equals and compare 
callback will be configured for
  * unsigned integer comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be 
created. If NULL is returned an error message
+ * is logged to celix_err.
  */
 CELIX_UTILS_EXPORT
 celix_array_list_t* celix_arrayList_createUIntArray();
@@ -242,6 +261,9 @@ celix_array_list_t* celix_arrayList_createUIntArray();
  *
  * The remove callback will be configured to NULL, and equals and compare 
callback will be configured for
  * unsigned integer comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be 
created. If NULL is returned an error message
+ * is logged to celix_err.
  */
 CELIX_UTILS_EXPORT
 celix_array_list_t* celix_arrayList_createULongArray();
@@ -251,6 +273,9 @@ celix_array_list_t* celix_arrayList_createULongArray();
  *
  * The remove callback will be configured to NULL, and equals and compare 
callback will be configured for
  * float comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be 
created. If NULL is returned an error message
+ * is logged to celix_err.
  */
 CELIX_UTILS_EXPORT
 celix_array_list_t* celix_arrayList_createFloatArray();
@@ -260,6 +285,9 @@ celix_array_list_t* celix_arrayList_createFloatArray();
  *
  * The remove callback will be configured to NULL, and equals and compare 
callback will be configured for
  * double comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be 
created. If NULL is returned an error message
+ * is logged to celix_err.
  */
 CELIX_UTILS_EXPORT
 celix_array_list_t* celix_arrayList_createDoubleArray();
@@ -269,6 +297,9 @@ celix_array_list_t* celix_arrayList_createDoubleArray();
  *
  * The remove callback will be configured to NULL, and equals and compare 
callback will be configured for
  * boolean comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be 
created. If NULL is returned an error message
+ * is logged to celix_err.
  */
 CELIX_UTILS_EXPORT
 celix_array_list_t* celix_arrayList_createBoolArray();
@@ -278,6 +309,9 @@ celix_array_list_t* celix_arrayList_createBoolArray();
  *
  * The remove callback will be configured to NULL, and equals and compare 
callback will be configured for
  * unsigned integer comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be 
created. If NULL is returned an error message
+ * is logged to celix_err.
  */
 CELIX_UTILS_EXPORT
 celix_array_list_t* celix_arrayList_createSizeArray();
@@ -287,6 +321,9 @@ celix_array_list_t* celix_arrayList_createSizeArray();
  *
  * The remove callback will be configured to free a celix version, and equals 
and compare callback will be configured
  * for celix version comparison.
+ *
+ * @return A new empty array list or NULL if the array list could not be 
created. If NULL is returned an error message
+ * is logged to celix_err.
  */
 CELIX_UTILS_EXPORT
 celix_array_list_t* celix_arrayList_createVersionArray();
@@ -299,6 +336,8 @@ celix_array_list_t* celix_arrayList_createVersionArray();
  * The provided callbacks in the options will override the default callbacks.
  *
  * @param opts The create options, only used during the creation of the array 
list.
+ * @return A new empty array list or NULL if the array list could not be 
created. If NULL is returned an error message
+ * is logged to celix_err.
  */
 CELIX_UTILS_EXPORT
 celix_array_list_t* celix_arrayList_createWithOptions(const 
celix_array_list_create_options_t* opts);
diff --git a/libs/utils/src/array_list.c b/libs/utils/src/array_list.c
index d35f40df..094a313c 100644
--- a/libs/utils/src/array_list.c
+++ b/libs/utils/src/array_list.c
@@ -158,23 +158,20 @@ static void 
celix_arrayList_callRemovedCallback(celix_array_list_t *list, int in
 }
 
 static celix_status_t celix_arrayList_ensureCapacity(celix_array_list_t* list, 
int capacity) {
-    celix_status_t status = CELIX_SUCCESS;
     celix_array_list_entry_t *newList;
     list->modCount++;
     size_t oldCapacity = list->capacity;
     if (capacity > oldCapacity) {
         size_t newCapacity = (oldCapacity * 3) / 2 + 1;
-        if (newCapacity < capacity) {
-            newCapacity = capacity;
-        }
         newList = realloc(list->elementData, sizeof(celix_array_list_entry_t) 
* newCapacity);
-        if (newList != NULL) {
-            list->capacity = newCapacity;
-            list->elementData = newList;
+        if (!newList) {
+            celix_err_push("Failed to reallocate memory for elementData");
+            return CELIX_ENOMEM;
         }
-        status = newList == NULL ? CELIX_ENOMEM : CELIX_SUCCESS;
+        list->capacity = newCapacity;
+        list->elementData = newList;
     }
-    return status;
+    return CELIX_SUCCESS;
 }
 
 static void celix_arrayList_setTypeSpecificCallbacks(celix_array_list_t* list) 
{
@@ -238,31 +235,34 @@ static void 
celix_arrayList_setTypeSpecificCallbacks(celix_array_list_t* list) {
 
 celix_array_list_t* celix_arrayList_createWithOptions(const 
celix_array_list_create_options_t* opts) {
     celix_autofree celix_array_list_t *list = calloc(1, sizeof(*list));
-    if (list) {
-        list->capacity = 10;
-        list->elementData = malloc(sizeof(celix_array_list_entry_t) * 
list->capacity);
-        if (!list->elementData) {
-            celix_err_push("Failed to allocate memory for elementData");
-            return NULL;
-        }
+    if (!list) {
+        celix_err_push("Failed to allocate memory for list");
+        return NULL;
+    }
 
-        list->elementType = opts->elementType;
-        celix_arrayList_setTypeSpecificCallbacks(list);
+    list->capacity = 10;
+    list->elementData = malloc(sizeof(celix_array_list_entry_t) * 
list->capacity);
+    if (!list->elementData) {
+        celix_err_push("Failed to allocate memory for elementData");
+        return NULL;
+    }
 
-        //if opts contains callbacks, use them and override the default ones
-        if (opts->simpleRemovedCallback) {
-            list->simpleRemovedCallback = opts->simpleRemovedCallback;
-        }
-        if (opts->removedCallback) {
-            list->removedCallback = opts->removedCallback;
-            list->removedCallbackData = opts->removedCallbackData;
-        }
-        if (opts->equalsCallback) {
-            list->equalsCallback = opts->equalsCallback;
-        }
-        if (opts->compareCallback) {
-            list->compareCallback = opts->compareCallback;
-        }
+    list->elementType = opts->elementType;
+    celix_arrayList_setTypeSpecificCallbacks(list);
+
+    //if opts contains callbacks, use them and override the default ones
+    if (opts->simpleRemovedCallback) {
+        list->simpleRemovedCallback = opts->simpleRemovedCallback;
+    }
+    if (opts->removedCallback) {
+        list->removedCallback = opts->removedCallback;
+        list->removedCallbackData = opts->removedCallbackData;
+    }
+    if (opts->equalsCallback) {
+        list->equalsCallback = opts->equalsCallback;
+    }
+    if (opts->compareCallback) {
+        list->compareCallback = opts->compareCallback;
     }
     return celix_steal_ptr(list);
 }
@@ -439,7 +439,7 @@ celix_status_t 
celix_arrayList_addString(celix_array_list_t* list, const char* v
            list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
     celix_array_list_entry_t entry;
     memset(&entry, 0, sizeof(entry));
-    if (list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING) {
+    if (list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_STRING && val) {
         entry.stringVal = celix_utils_strdup(val);
         if (entry.stringVal == NULL) {
             return CELIX_ENOMEM;
@@ -535,7 +535,7 @@ celix_status_t 
celix_arrayList_addVersion(celix_array_list_t* list, const celix_
            list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_UNDEFINED);
     celix_array_list_entry_t entry;
     memset(&entry, 0, sizeof(entry));
-    if (list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION) {
+    if (list->elementType == CELIX_ARRAY_LIST_ELEMENT_TYPE_VERSION && value) {
         entry.versionVal = celix_version_copy(value);
         if (entry.versionVal == NULL) {
             return CELIX_ENOMEM;
@@ -739,7 +739,6 @@ celix_array_list_t* celix_arrayList_copy(const 
celix_array_list_t* list) {
     opts.simpleRemovedCallback = list->simpleRemovedCallback;
     celix_autoptr(celix_array_list_t) copy = 
celix_arrayList_createWithOptions(&opts);
     if (!copy) {
-        celix_err_push("Failed to create copy list. Out of memory.");
         return NULL;
     }
 

Reply via email to