PengZheng commented on code in PR #470:
URL: https://github.com/apache/celix/pull/470#discussion_r1378446643


##########
libs/rcm/src/celix_capability.c:
##########
@@ -83,22 +83,19 @@ bool celix_capability_equals(const celix_capability_t* 
cap1, const celix_capabil
 
     //compare attributes
     bool equals = true;
-    const char* visit;
-    CELIX_PROPERTIES_FOR_EACH(cap1->attributes, visit) {
-        const char* value1 = celix_properties_get(cap1->attributes, visit, 
NULL);
-        const char* value2 = celix_properties_get(cap2->attributes, visit, 
NULL);
-        if (!celix_utils_stringEquals(value1, value2)) {
+    CELIX_PROPERTIES_ITERATE(cap1->attributes, visit) {

Review Comment:
   Shall we use `celix_properties_equals` instead? 



##########
libs/utils/gtest/src/CxxPropertiesTestSuite.cc:
##########
@@ -74,17 +97,111 @@ TEST_F(CxxPropertiesTestSuite, testCopy) {
     EXPECT_EQ(v2, "value1_new");
 }
 
-TEST_F(CxxPropertiesTestSuite, testWrap) {
+TEST_F(CxxPropertiesTestSuite, WrapTest) {
     auto *props = celix_properties_create();
     celix_properties_set(props, "test", "test");
 
     EXPECT_EQ(1, celix_properties_size(props));
     {
         auto cxxProps = celix::Properties::wrap(props);
-        EXPECT_EQ(1, cxxProps->size());
-        EXPECT_EQ(props, cxxProps->getCProperties());
+        EXPECT_EQ(1, cxxProps.size());
+        EXPECT_EQ(props, cxxProps.getCProperties());
+    } //NOTE cxxProps out of scope, but will not destroy celix_properties
+    EXPECT_EQ(1, celix_properties_size(props));
+
+    celix_properties_destroy(props);
+}
+
+TEST_F(CxxPropertiesTestSuite, CopyCPropsTest) {
+    auto *props = celix_properties_create();
+    celix_properties_set(props, "test", "test");
+
+    EXPECT_EQ(1, celix_properties_size(props));
+    {
+        auto cxxProps = celix::Properties::copy(props);
+        EXPECT_EQ(1, cxxProps.size());
+        EXPECT_NE(props, cxxProps.getCProperties());
     } //NOTE cxxProps out of scope, but will not destroy celix_properties
     EXPECT_EQ(1, celix_properties_size(props));
 
     celix_properties_destroy(props);
 }
+
+TEST_F(CxxPropertiesTestSuite, GetTypeTest) {
+    celix::Properties props{};
+
+    const auto v2 = celix::Version{1, 2, 3};
+    auto v3 = celix::Version{1, 2, 4};
+
+    props.set("bool", true);
+    props.set("long1", 1l);
+    props.set("long2", (int)1); //should lead to long;
+    props.set("long3", (unsigned int)1); //should lead to long;
+    props.set("long4", (short)1); //should lead to long;
+    props.set("long5", (unsigned short)1); //should lead to long;
+    props.set("long6", (char)1); //should lead to long;
+    props.set("long7", (unsigned char)1); //should lead to long;
+    props.set("double1", 1.0);
+    props.set("double2", 1.0f); //set float should lead to double
+    props.set("version1", celix::Version{1, 2, 3});
+    props.set("version2", v2);
+    props.set("version3", v3);
+
+    EXPECT_EQ(props.getType("bool"), celix::Properties::ValueType::Bool);
+    EXPECT_EQ(props.getType("long1"), celix::Properties::ValueType::Long);
+    EXPECT_EQ(props.getType("long2"), celix::Properties::ValueType::Long);
+    EXPECT_EQ(props.getType("long3"), celix::Properties::ValueType::Long);
+    EXPECT_EQ(props.getType("long4"), celix::Properties::ValueType::Long);
+    EXPECT_EQ(props.getType("long5"), celix::Properties::ValueType::Long);
+    EXPECT_EQ(props.getType("long6"), celix::Properties::ValueType::Long);
+    EXPECT_EQ(props.getType("long7"), celix::Properties::ValueType::Long);
+    EXPECT_EQ(props.getType("double1"), celix::Properties::ValueType::Double);
+    EXPECT_EQ(props.getType("double2"), celix::Properties::ValueType::Double);
+    EXPECT_EQ(props.getType("version1"), 
celix::Properties::ValueType::Version);
+    EXPECT_EQ(props.getType("version2"), 
celix::Properties::ValueType::Version);
+    EXPECT_EQ(props.getType("version3"), 
celix::Properties::ValueType::Version);
+}
+
+TEST_F(CxxPropertiesTestSuite, GetAsVersionTest) {
+    celix::Properties props;
+
+    // Test getting a version from a string property
+    props.set("key", "1.2.3");
+    celix::Version ver{1, 2, 3};
+    EXPECT_TRUE(props.getAsVersion("key") == ver);
+
+    // Test getting a version from a version property
+    props.set("key", celix::Version{2, 3, 4});
+    ver = celix::Version{2, 3, 4};
+    EXPECT_EQ(props.getAsVersion("key"), ver);
+
+    // Test getting default value when property is not set
+    ver = celix::Version{3, 4, 5};
+    EXPECT_EQ(props.getAsVersion("non_existent_key", celix::Version{3, 4, 5}), 
ver);
+
+    // Test getting default value when property value is not a valid version 
string
+    props.set("key", "invalid_version_string");
+    ver = celix::Version{4, 5, 6};
+    EXPECT_EQ(props.getAsVersion("key", celix::Version{4, 5, 6}), ver);
+}
+
+TEST_F(CxxPropertiesTestSuite, StoreAndLoadTest) {
+    std::string path{"cxx_store_and_load_test.properties"};
+
+    celix::Properties props{};
+    props.set("key1", 1);
+    props.set("key2", 2);
+
+    EXPECT_NO_THROW(props.store(path));
+
+    celix::Properties loadedProps{};
+    EXPECT_NO_THROW(loadedProps = celix::Properties::load(path));
+    EXPECT_EQ(props.size(), loadedProps.size());

Review Comment:
   If #674 were solved, this should be equality test.



##########
libs/rcm/src/celix_requirement.c:
##########
@@ -89,45 +89,33 @@ bool celix_requirement_equals(const celix_requirement_t* 
req1, const celix_requi
     }
 
     //compare attributes
-    bool equals = true;
-    const char* visit;
-    CELIX_PROPERTIES_FOR_EACH(req1->attributes, visit) {
-        const char* val1 = celix_properties_get(req1->attributes, visit, NULL);
-        const char* val2 = celix_properties_get(req2->attributes, visit, NULL);
-        if (!celix_utils_stringEquals(val1, val2)) {
-            equals = false;
-            break;
+    CELIX_PROPERTIES_ITERATE(req1->attributes, visit) {

Review Comment:
   Shall we use `celix_properties_equals` instead? 



##########
libs/utils/gtest/src/HashMapTestSuite.cc:
##########
@@ -534,25 +514,159 @@ TEST_F(HashMapTestSuite, IterateWithRemoveTest) {
     auto iter2 = celix_longHashMap_begin(lMap);
     while (!celix_longHashMapIterator_isEnd(&iter2)) {
         if (iter2.index % 2 == 0) {
-            //note only removing entries where the iter index is even
+            // note only removing entries where the iter index is even
             celix_longHashMapIterator_remove(&iter2);
         } else {
             celix_longHashMapIterator_next(&iter2);
         }
     }
     EXPECT_EQ(3, celix_longHashMap_size(lMap));
     EXPECT_TRUE(celix_longHashMapIterator_isEnd(&iter2));
-    celix_longHashMapIterator_next(&iter2); //calling next on end iter, does 
nothing
+    celix_longHashMapIterator_next(&iter2); // calling next on end iter, does 
nothing
     EXPECT_TRUE(celix_longHashMapIterator_isEnd(&iter2));
     celix_longHashMap_destroy(lMap);
 }
 
-TEST_F(HashMapTestSuite, StringHashMapCleanup) {
+TEST_F(HashMapTestSuite, IterateEndTest) {
+    auto* sMap1 = createStringHashMap(0);
+    auto* sMap2 = createStringHashMap(6);
+    auto* lMap1 = createLongHashMap(0);
+    auto* lMap2 = createLongHashMap(6);
+
+    auto sIter1 = celix_stringHashMap_end(sMap1);
+    auto sIter2 = celix_stringHashMap_end(sMap2);
+    auto lIter1 = celix_longHashMap_end(lMap1);
+    auto lIter2 = celix_longHashMap_end(lMap2);
+
+    EXPECT_EQ(sIter1.index, 0);
+    EXPECT_EQ(sIter2.index, 6);
+    EXPECT_EQ(lIter1.index, 0);
+    EXPECT_EQ(lIter2.index, 6);
+    EXPECT_TRUE(celix_stringHashMapIterator_isEnd(&sIter1));
+    EXPECT_TRUE(celix_stringHashMapIterator_isEnd(&sIter2));
+    EXPECT_TRUE(celix_longHashMapIterator_isEnd(&lIter1));
+    EXPECT_TRUE(celix_longHashMapIterator_isEnd(&lIter2));
+
+    celix_stringHashMap_destroy(sMap1);
+    celix_stringHashMap_destroy(sMap2);
+    celix_longHashMap_destroy(lMap1);
+    celix_longHashMap_destroy(lMap2);
+}
+
+TEST_F(HashMapTestSuite, EqualsTest) {
+    auto* sMap = createStringHashMap(2);
+    auto sIter1 = celix_stringHashMap_begin(sMap);
+    auto sIter2 = celix_stringHashMap_begin(sMap);
+
+    // Test equal iterators
+    EXPECT_TRUE(celix_stringHashMapIterator_equals(&sIter1, &sIter2));
+
+    // Test unequal iterators after only 1 modification
+    celix_stringHashMapIterator_next(&sIter1);
+    EXPECT_FALSE(celix_stringHashMapIterator_equals(&sIter1, &sIter2));
+
+    // Test equal iterators after both modification
+    celix_stringHashMapIterator_next(&sIter2);
+    EXPECT_TRUE(celix_stringHashMapIterator_equals(&sIter1, &sIter2));
+
+    // Same for long hash map
+    auto* lMap = createLongHashMap(1);
+    auto lIter1 = celix_longHashMap_begin(lMap);
+    auto lIter2 = celix_longHashMap_begin(lMap);
+
+    // Test equal iterators
+    EXPECT_TRUE(celix_longHashMapIterator_equals(&lIter1, &lIter2));
+
+    // Test unequal iterators after only 1 modification
+    celix_longHashMapIterator_next(&lIter1);
+    EXPECT_FALSE(celix_longHashMapIterator_equals(&lIter1, &lIter2));
+
+    // Test equal iterators after both modification
+    celix_longHashMapIterator_next(&lIter2);
+    EXPECT_TRUE(celix_longHashMapIterator_equals(&lIter1, &lIter2));
+
+    celix_stringHashMap_destroy(sMap);
+    celix_longHashMap_destroy(lMap);
+}
+
+TEST_F(HashMapTestSuite, EqualsZeroSizeMapTest) {
+    // Because map size is 0, begin iter should equal end iter
+    auto* sMap = createStringHashMap(0);
+    auto sIter1 = celix_stringHashMap_begin(sMap);
+    auto sEnd = celix_stringHashMap_end(sMap);
+    EXPECT_TRUE(celix_stringHashMapIterator_equals(&sIter1, &sEnd));
+
+    // Because map size is 0, begin iter should equal end iter
+    auto* lMap = createLongHashMap(0);
+    auto lIter1 = celix_longHashMap_begin(lMap);
+    auto lEnd = celix_longHashMap_end(lMap);
+    EXPECT_TRUE(celix_longHashMapIterator_equals(&lIter1, &lEnd));
+
+    celix_stringHashMap_destroy(sMap);
+    celix_longHashMap_destroy(lMap);
+}
+
+TEST_F(HashMapTestSuite, StoreKeysWeaklyTest) {
+    celix_string_hash_map_create_options_t opts{};
+    opts.removedCallbackData = (void*)0x1;
+    opts.storeKeysWeakly = true;
+    opts.removedKeyCallback = [](void* data, char* key) {
+        EXPECT_EQ(data, (void*)0x1);
+        free(key);
+    };
+    auto* sMap = celix_stringHashMap_createWithOptions(&opts);
+    EXPECT_FALSE(celix_stringHashMap_putLong(sMap, celix_utils_strdup("key1"), 
1)); // new key -> takes ownership

Review Comment:
   `celix_stringHashMap_putXXX` no longer returns boolean value. 
   Documentation of `opts.removedKeyCallback` should also be updated.



##########
libs/utils/gtest/src/CxxPropertiesTestSuite.cc:
##########
@@ -52,14 +52,37 @@ TEST_F(CxxPropertiesTestSuite, testFillAndLoop) {
     EXPECT_EQ(props.getAsBool("key5", false), true);
 
     int count = 0;
+    for (auto it = props.begin(); it != props.end(); ++it) {

Review Comment:
   Is this equivalent to the following range-based loop? Why shall we need both?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscr...@celix.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to