Prechádzať zdrojové kódy

Improved coverage of JsonObject

Benoit Blanchon 6 rokov pred
rodič
commit
a471aed6db

+ 34 - 5
extras/tests/JsonObject/copy.cpp

@@ -15,8 +15,9 @@ TEST_CASE("JsonObject::set()") {
   SECTION("doesn't copy static string in key or value") {
     obj1["hello"] = "world";
 
-    obj2.set(obj1);
+    bool success = obj2.set(obj1);
 
+    REQUIRE(success == true);
     REQUIRE(doc1.memoryUsage() == doc2.memoryUsage());
     REQUIRE(obj2["hello"] == std::string("world"));
   }
@@ -24,8 +25,9 @@ TEST_CASE("JsonObject::set()") {
   SECTION("copy local string value") {
     obj1["hello"] = std::string("world");
 
-    obj2.set(obj1);
+    bool success = obj2.set(obj1);
 
+    REQUIRE(success == true);
     REQUIRE(doc1.memoryUsage() == doc2.memoryUsage());
     REQUIRE(obj2["hello"] == std::string("world"));
   }
@@ -33,8 +35,9 @@ TEST_CASE("JsonObject::set()") {
   SECTION("copy local key") {
     obj1[std::string("hello")] = "world";
 
-    obj2.set(obj1);
+    bool success = obj2.set(obj1);
 
+    REQUIRE(success == true);
     REQUIRE(doc1.memoryUsage() == doc2.memoryUsage());
     REQUIRE(obj2["hello"] == std::string("world"));
   }
@@ -42,8 +45,9 @@ TEST_CASE("JsonObject::set()") {
   SECTION("copy string from deserializeJson()") {
     deserializeJson(doc1, "{'hello':'world'}");
 
-    obj2.set(obj1);
+    bool success = obj2.set(obj1);
 
+    REQUIRE(success == true);
     REQUIRE(doc1.memoryUsage() == doc2.memoryUsage());
     REQUIRE(obj2["hello"] == std::string("world"));
   }
@@ -51,8 +55,9 @@ TEST_CASE("JsonObject::set()") {
   SECTION("copy string from deserializeMsgPack()") {
     deserializeMsgPack(doc1, "\x81\xA5hello\xA5world");
 
-    obj2.set(obj1);
+    bool success = obj2.set(obj1);
 
+    REQUIRE(success == true);
     REQUIRE(doc1.memoryUsage() == doc2.memoryUsage());
     REQUIRE(obj2["hello"] == std::string("world"));
   }
@@ -65,4 +70,28 @@ TEST_CASE("JsonObject::set()") {
     REQUIRE(doc1.memoryUsage() == doc2.memoryUsage());
     REQUIRE(obj2["hello"] == std::string("world"));
   }
+
+  SECTION("destination too small to store the key") {
+    StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc3;
+    JsonObject obj3 = doc3.to<JsonObject>();
+
+    obj1[std::string("hello")] = "world";
+
+    bool success = obj3.set(obj1);
+
+    REQUIRE(success == false);
+    REQUIRE(doc3.as<std::string>() == "{}");
+  }
+
+  SECTION("destination too small to store the value") {
+    StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc3;
+    JsonObject obj3 = doc3.to<JsonObject>();
+
+    obj1["hello"] = std::string("world");
+
+    bool success = obj3.set(obj1);
+
+    REQUIRE(success == false);
+    REQUIRE(doc3.as<std::string>() == "{\"hello\":null}");
+  }
 }

+ 12 - 2
src/ArduinoJson/Collection/CollectionImpl.hpp

@@ -34,8 +34,10 @@ template <typename TAdaptedString>
 inline VariantData* CollectionData::addMember(TAdaptedString key,
                                               MemoryPool* pool) {
   VariantSlot* slot = addSlot(pool);
-  if (!slotSetKey(slot, key, pool))
+  if (!slotSetKey(slot, key, pool)) {
+    removeSlot(slot);
     return 0;
+  }
   return slot->data();
 }
 
@@ -132,8 +134,16 @@ inline VariantData* CollectionData::getMember(TAdaptedString key) const {
 template <typename TAdaptedString>
 inline VariantData* CollectionData::getOrAddMember(TAdaptedString key,
                                                    MemoryPool* pool) {
+  // ignore null key
+  if (key.isNull())
+    return 0;
+
+  // search a matching key
   VariantSlot* slot = getSlot(key);
-  return slot ? slot->data() : addMember(key, pool);
+  if (slot)
+    return slot->data();
+
+  return addMember(key, pool);
 }
 
 inline VariantData* CollectionData::getElement(size_t index) const {

+ 5 - 13
src/ArduinoJson/Object/ObjectFunctions.hpp

@@ -25,7 +25,8 @@ inline bool objectEquals(const CollectionData *lhs, const CollectionData *rhs) {
 }
 
 template <typename TAdaptedString>
-inline VariantData *objectGet(const CollectionData *obj, TAdaptedString key) {
+inline VariantData *objectGetMember(const CollectionData *obj,
+                                    TAdaptedString key) {
   if (!obj)
     return 0;
   return obj->getMember(key);
@@ -39,20 +40,11 @@ void objectRemove(CollectionData *obj, TAdaptedString key) {
 }
 
 template <typename TAdaptedString>
-inline VariantData *objectGetOrCreate(CollectionData *obj, TAdaptedString key,
-                                      MemoryPool *pool) {
+inline VariantData *objectGetOrAddMember(CollectionData *obj,
+                                         TAdaptedString key, MemoryPool *pool) {
   if (!obj)
     return 0;
 
-  // ignore null key
-  if (key.isNull())
-    return 0;
-
-  // search a matching key
-  VariantData *var = obj->getMember(key);
-  if (var)
-    return var;
-
-  return obj->addMember(key, pool);
+  return obj->getOrAddMember(key, pool);
 }
 }  // namespace ARDUINOJSON_NAMESPACE

+ 7 - 15
src/ArduinoJson/Object/ObjectRef.hpp

@@ -129,7 +129,7 @@ class ObjectConstRef : public ObjectRefBase<const CollectionData>,
  private:
   template <typename TAdaptedString>
   FORCE_INLINE VariantConstRef get_impl(TAdaptedString key) const {
-    return VariantConstRef(objectGet(_data, key));
+    return VariantConstRef(objectGetMember(_data, key));
   }
 };
 
@@ -180,7 +180,7 @@ class ObjectRef : public ObjectRefBase<CollectionData>,
   // getMember(const String&) const
   template <typename TString>
   FORCE_INLINE VariantRef getMember(const TString& key) const {
-    return get_impl(adaptString(key));
+    return VariantRef(_pool, objectGetMember(_data, adaptString(key)));
   }
 
   // getMember(char*) const
@@ -188,14 +188,15 @@ class ObjectRef : public ObjectRefBase<CollectionData>,
   // getMember(const __FlashStringHelper*) const
   template <typename TChar>
   FORCE_INLINE VariantRef getMember(TChar* key) const {
-    return get_impl(adaptString(key));
+    return VariantRef(_pool, objectGetMember(_data, adaptString(key)));
   }
 
   // getOrAddMember(const std::string&) const
   // getOrAddMember(const String&) const
   template <typename TString>
   FORCE_INLINE VariantRef getOrAddMember(const TString& key) const {
-    return getOrCreate_impl(adaptString(key));
+    return VariantRef(_pool,
+                      objectGetOrAddMember(_data, adaptString(key), _pool));
   }
 
   // getOrAddMember(char*) const
@@ -203,7 +204,8 @@ class ObjectRef : public ObjectRefBase<CollectionData>,
   // getOrAddMember(const __FlashStringHelper*) const
   template <typename TChar>
   FORCE_INLINE VariantRef getOrAddMember(TChar* key) const {
-    return getOrCreate_impl(adaptString(key));
+    return VariantRef(_pool,
+                      objectGetOrAddMember(_data, adaptString(key), _pool));
   }
 
   FORCE_INLINE bool operator==(ObjectRef rhs) const {
@@ -232,16 +234,6 @@ class ObjectRef : public ObjectRefBase<CollectionData>,
   }
 
  private:
-  template <typename TAdaptedString>
-  FORCE_INLINE VariantRef get_impl(TAdaptedString key) const {
-    return VariantRef(_pool, objectGet(_data, key));
-  }
-
-  template <typename TAdaptedString>
-  FORCE_INLINE VariantRef getOrCreate_impl(TAdaptedString key) const {
-    return VariantRef(_pool, objectGetOrCreate(_data, key, _pool));
-  }
-
   MemoryPool* _pool;
 };
 }  // namespace ARDUINOJSON_NAMESPACE

+ 2 - 1
src/ArduinoJson/Variant/VariantRef.hpp

@@ -384,7 +384,8 @@ class VariantConstRef : public VariantRefBase<const VariantData>,
   // getMember(const String&) const
   template <typename TString>
   FORCE_INLINE VariantConstRef getMember(const TString &key) const {
-    return VariantConstRef(objectGet(variantAsObject(_data), adaptString(key)));
+    return VariantConstRef(
+        objectGetMember(variantAsObject(_data), adaptString(key)));
   }
 
   // getMember(char*) const