Improved coverage of JsonObject

This commit is contained in:
Benoit Blanchon
2020-02-22 14:17:10 +01:00
parent af0edecddb
commit a471aed6db
5 changed files with 60 additions and 36 deletions

View File

@ -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}");
}
}

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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