ソースを参照

Add more tests for `JsonObjectConst`

Benoit Blanchon 2 年 前
コミット
08cac13c43

+ 1 - 0
extras/tests/CMakeLists.txt

@@ -19,6 +19,7 @@ add_subdirectory(JsonArray)
 add_subdirectory(JsonDeserializer)
 add_subdirectory(JsonDocument)
 add_subdirectory(JsonObject)
+add_subdirectory(JsonObjectConst)
 add_subdirectory(JsonSerializer)
 add_subdirectory(JsonVariant)
 add_subdirectory(ResourceManager)

+ 0 - 6
extras/tests/JsonObject/containsKey.cpp

@@ -15,12 +15,6 @@ TEST_CASE("JsonObject::containsKey()") {
     REQUIRE(true == obj.containsKey("hello"));
   }
 
-  SECTION("works with JsonObjectConst") {
-    JsonObjectConst cobj = obj;
-    REQUIRE(false == cobj.containsKey("world"));
-    REQUIRE(true == cobj.containsKey("hello"));
-  }
-
   SECTION("returns false after remove()") {
     obj.remove("hello");
 

+ 0 - 8
extras/tests/JsonObject/equals.cpp

@@ -8,18 +8,15 @@
 TEST_CASE("JsonObject::operator==()") {
   JsonDocument doc1;
   JsonObject obj1 = doc1.to<JsonObject>();
-  JsonObjectConst obj1c = obj1;
 
   JsonDocument doc2;
   JsonObject obj2 = doc2.to<JsonObject>();
-  JsonObjectConst obj2c = obj2;
 
   SECTION("should return false when objs differ") {
     obj1["hello"] = "coucou";
     obj2["world"] = 1;
 
     REQUIRE_FALSE(obj1 == obj2);
-    REQUIRE_FALSE(obj1c == obj2c);
   }
 
   SECTION("should return false when LHS has more elements") {
@@ -28,7 +25,6 @@ TEST_CASE("JsonObject::operator==()") {
     obj2["hello"] = "coucou";
 
     REQUIRE_FALSE(obj1 == obj2);
-    REQUIRE_FALSE(obj1c == obj2c);
   }
 
   SECTION("should return false when RKS has more elements") {
@@ -37,7 +33,6 @@ TEST_CASE("JsonObject::operator==()") {
     obj2["world"] = 666;
 
     REQUIRE_FALSE(obj1 == obj2);
-    REQUIRE_FALSE(obj1c == obj2c);
   }
 
   SECTION("should return true when objs equal") {
@@ -48,20 +43,17 @@ TEST_CASE("JsonObject::operator==()") {
     obj2["hello"] = "world";
 
     REQUIRE(obj1 == obj2);
-    REQUIRE(obj1c == obj2c);
   }
 
   SECTION("should return false when RHS is null") {
     JsonObject null;
 
     REQUIRE_FALSE(obj1 == null);
-    REQUIRE_FALSE(obj1c == null);
   }
 
   SECTION("should return false when LHS is null") {
     JsonObject null;
 
     REQUIRE_FALSE(null == obj2);
-    REQUIRE_FALSE(null == obj2c);
   }
 }

+ 0 - 26
extras/tests/JsonObject/isNull.cpp

@@ -18,19 +18,6 @@ TEST_CASE("JsonObject::isNull()") {
   }
 }
 
-TEST_CASE("JsonObjectConst::isNull()") {
-  SECTION("returns true") {
-    JsonObjectConst obj;
-    REQUIRE(obj.isNull() == true);
-  }
-
-  SECTION("returns false") {
-    JsonDocument doc;
-    JsonObjectConst obj = doc.to<JsonObject>();
-    REQUIRE(obj.isNull() == false);
-  }
-}
-
 TEST_CASE("JsonObject::operator bool()") {
   SECTION("returns false") {
     JsonObject obj;
@@ -43,16 +30,3 @@ TEST_CASE("JsonObject::operator bool()") {
     REQUIRE(static_cast<bool>(obj) == true);
   }
 }
-
-TEST_CASE("JsonObjectConst::operator bool()") {
-  SECTION("returns false") {
-    JsonObjectConst obj;
-    REQUIRE(static_cast<bool>(obj) == false);
-  }
-
-  SECTION("returns true") {
-    JsonDocument doc;
-    JsonObjectConst obj = doc.to<JsonObject>();
-    REQUIRE(static_cast<bool>(obj) == true);
-  }
-}

+ 0 - 37
extras/tests/JsonObject/iterator.cpp

@@ -5,8 +5,6 @@
 #include <ArduinoJson.h>
 #include <catch.hpp>
 
-using namespace Catch::Matchers;
-
 TEST_CASE("JsonObject::begin()/end()") {
   JsonDocument doc;
   JsonObject obj = doc.to<JsonObject>();
@@ -36,38 +34,3 @@ TEST_CASE("JsonObject::begin()/end()") {
     REQUIRE(null.begin() == null.end());
   }
 }
-
-TEST_CASE("JsonObjectConst::begin()/end()") {
-  JsonDocument doc;
-  JsonObject obj = doc.to<JsonObject>();
-  obj["ab"] = 12;
-  obj["cd"] = 34;
-
-  JsonObjectConst cobj = obj;
-
-  SECTION("Iteration") {
-    JsonObjectConst::iterator it = cobj.begin();
-    REQUIRE(cobj.end() != it);
-    REQUIRE(it->key() == "ab");
-    REQUIRE(12 == it->value());
-
-    ++it;
-    REQUIRE(cobj.end() != it);
-    JsonPairConst pair = *it;
-    REQUIRE(pair.key() == "cd");
-    REQUIRE(34 == pair.value());
-
-    ++it;
-    REQUIRE(cobj.end() == it);
-  }
-
-  SECTION("Dereferencing end() is safe") {
-    REQUIRE(cobj.end()->key().isNull());
-    REQUIRE(cobj.end()->value().isNull());
-  }
-
-  SECTION("null JsonObjectConst") {
-    JsonObjectConst null;
-    REQUIRE(null.begin() == null.end());
-  }
-}

+ 0 - 10
extras/tests/JsonObject/subscript.cpp

@@ -7,8 +7,6 @@
 
 #include "Allocators.hpp"
 
-using ArduinoJson::detail::sizeofObject;
-
 TEST_CASE("JsonObject::operator[]") {
   SpyingAllocator spy;
   JsonDocument doc(&spy);
@@ -252,11 +250,3 @@ TEST_CASE("JsonObject::operator[]") {
     REQUIRE(false == obj["hello"]["world"].is<bool>());
   }
 }
-
-TEST_CASE("JsonObjectConst::operator[]") {
-  JsonDocument doc;
-  doc["hello"] = "world";
-  JsonObjectConst obj = doc.as<JsonObjectConst>();
-
-  REQUIRE(obj["hello"] == "world");  // issue #2019
-}

+ 20 - 0
extras/tests/JsonObjectConst/CMakeLists.txt

@@ -0,0 +1,20 @@
+# ArduinoJson - https://arduinojson.org
+# Copyright © 2014-2024, Benoit BLANCHON
+# MIT License
+
+add_executable(JsonObjectConstTests
+	containsKey.cpp
+	equals.cpp
+	isNull.cpp
+	iterator.cpp
+	nesting.cpp
+	size.cpp
+	subscript.cpp
+)
+
+add_test(JsonObjectConst JsonObjectConstTests)
+
+set_tests_properties(JsonObjectConst
+	PROPERTIES
+		LABELS "Catch"
+)

+ 32 - 0
extras/tests/JsonObjectConst/containsKey.cpp

@@ -0,0 +1,32 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright © 2014-2024, Benoit BLANCHON
+// MIT License
+
+#include <ArduinoJson.h>
+#include <catch.hpp>
+
+TEST_CASE("JsonObjectConst::containsKey()") {
+  JsonDocument doc;
+  doc["hello"] = 42;
+  auto obj = doc.as<JsonObjectConst>();
+
+  SECTION("supports const char*") {
+    REQUIRE(false == obj.containsKey("world"));
+    REQUIRE(true == obj.containsKey("hello"));
+  }
+
+  SECTION("supports std::string") {
+    REQUIRE(false == obj.containsKey(std::string("world")));
+    REQUIRE(true == obj.containsKey(std::string("hello")));
+  }
+
+#ifdef HAS_VARIABLE_LENGTH_ARRAY
+  SECTION("supports VLA") {
+    size_t i = 16;
+    char vla[i];
+    strcpy(vla, "hello");
+
+    REQUIRE(true == obj.containsKey(vla));
+  }
+#endif
+}

+ 65 - 0
extras/tests/JsonObjectConst/equals.cpp

@@ -0,0 +1,65 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright © 2014-2024, Benoit BLANCHON
+// MIT License
+
+#include <ArduinoJson.h>
+#include <catch.hpp>
+
+TEST_CASE("JsonObjectConst::operator==()") {
+  JsonDocument doc1;
+  JsonObjectConst obj1 = doc1.to<JsonObject>();
+
+  JsonDocument doc2;
+  JsonObjectConst obj2 = doc2.to<JsonObject>();
+
+  SECTION("should return false when objs differ") {
+    doc1["hello"] = "coucou";
+    doc2["world"] = 1;
+
+    REQUIRE_FALSE(obj1 == obj2);
+  }
+
+  SECTION("should return false when LHS has more elements") {
+    doc1["hello"] = "coucou";
+    doc1["world"] = 666;
+    doc2["hello"] = "coucou";
+
+    REQUIRE_FALSE(obj1 == obj2);
+  }
+
+  SECTION("should return false when RKS has more elements") {
+    doc1["hello"] = "coucou";
+    doc2["hello"] = "coucou";
+    doc2["world"] = 666;
+
+    REQUIRE_FALSE(obj1 == obj2);
+  }
+
+  SECTION("should return true when objs equal") {
+    doc1["hello"] = "world";
+    doc1["anwser"] = 42;
+    // insert in different order
+    doc2["anwser"] = 42;
+    doc2["hello"] = "world";
+
+    REQUIRE(obj1 == obj2);
+  }
+
+  SECTION("should return false when RHS is null") {
+    JsonObjectConst null;
+
+    REQUIRE_FALSE(obj1 == null);
+  }
+
+  SECTION("should return false when LHS is null") {
+    JsonObjectConst null;
+
+    REQUIRE_FALSE(null == obj2);
+  }
+
+  SECTION("should return true when both are null") {
+    JsonObjectConst null1, null2;
+
+    REQUIRE(null1 == null2);
+  }
+}

+ 32 - 0
extras/tests/JsonObjectConst/isNull.cpp

@@ -0,0 +1,32 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright © 2014-2024, Benoit BLANCHON
+// MIT License
+
+#include <ArduinoJson.h>
+#include <catch.hpp>
+
+TEST_CASE("JsonObjectConst::isNull()") {
+  SECTION("returns true") {
+    JsonObjectConst obj;
+    REQUIRE(obj.isNull() == true);
+  }
+
+  SECTION("returns false") {
+    JsonDocument doc;
+    JsonObjectConst obj = doc.to<JsonObject>();
+    REQUIRE(obj.isNull() == false);
+  }
+}
+
+TEST_CASE("JsonObjectConst::operator bool()") {
+  SECTION("returns false") {
+    JsonObjectConst obj;
+    REQUIRE(static_cast<bool>(obj) == false);
+  }
+
+  SECTION("returns true") {
+    JsonDocument doc;
+    JsonObjectConst obj = doc.to<JsonObject>();
+    REQUIRE(static_cast<bool>(obj) == true);
+  }
+}

+ 39 - 0
extras/tests/JsonObjectConst/iterator.cpp

@@ -0,0 +1,39 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright © 2014-2024, Benoit BLANCHON
+// MIT License
+
+#include <ArduinoJson.h>
+#include <catch.hpp>
+
+TEST_CASE("JsonObjectConst::begin()/end()") {
+  JsonDocument doc;
+  JsonObjectConst obj = doc.to<JsonObject>();
+  doc["ab"] = 12;
+  doc["cd"] = 34;
+
+  SECTION("Iteration") {
+    JsonObjectConst::iterator it = obj.begin();
+    REQUIRE(obj.end() != it);
+    REQUIRE(it->key() == "ab");
+    REQUIRE(12 == it->value());
+
+    ++it;
+    REQUIRE(obj.end() != it);
+    JsonPairConst pair = *it;
+    REQUIRE(pair.key() == "cd");
+    REQUIRE(34 == pair.value());
+
+    ++it;
+    REQUIRE(obj.end() == it);
+  }
+
+  SECTION("Dereferencing end() is safe") {
+    REQUIRE(obj.end()->key().isNull());
+    REQUIRE(obj.end()->value().isNull());
+  }
+
+  SECTION("null JsonObjectConst") {
+    JsonObjectConst null;
+    REQUIRE(null.begin() == null.end());
+  }
+}

+ 35 - 0
extras/tests/JsonObjectConst/nesting.cpp

@@ -0,0 +1,35 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright © 2014-2024, Benoit BLANCHON
+// MIT License
+
+#include <ArduinoJson.h>
+#include <catch.hpp>
+
+TEST_CASE("JsonObjectConst::nesting()") {
+  JsonDocument doc;
+  JsonObjectConst obj = doc.to<JsonObject>();
+
+  SECTION("return 0 if unbound") {
+    JsonObjectConst unbound;
+    REQUIRE(unbound.nesting() == 0);
+  }
+
+  SECTION("returns 1 for empty object") {
+    REQUIRE(obj.nesting() == 1);
+  }
+
+  SECTION("returns 1 for flat object") {
+    doc["hello"] = "world";
+    REQUIRE(obj.nesting() == 1);
+  }
+
+  SECTION("returns 2 with nested array") {
+    doc["nested"].to<JsonArray>();
+    REQUIRE(obj.nesting() == 2);
+  }
+
+  SECTION("returns 2 with nested object") {
+    doc["nested"].to<JsonObject>();
+    REQUIRE(obj.nesting() == 2);
+  }
+}

+ 22 - 0
extras/tests/JsonObjectConst/size.cpp

@@ -0,0 +1,22 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright © 2014-2024, Benoit BLANCHON
+// MIT License
+
+#include <ArduinoJson.h>
+#include <catch.hpp>
+#include <string>
+
+TEST_CASE("JsonObjectConst::size()") {
+  JsonDocument doc;
+  JsonObjectConst obj = doc.to<JsonObject>();
+
+  SECTION("returns 0 when empty") {
+    REQUIRE(0 == obj.size());
+  }
+
+  SECTION("returns the number of members") {
+    doc["hello"] = 1;
+    doc["world"] = 2;
+    REQUIRE(2 == obj.size());
+  }
+}

+ 33 - 0
extras/tests/JsonObjectConst/subscript.cpp

@@ -0,0 +1,33 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright © 2014-2024, Benoit BLANCHON
+// MIT License
+
+#include <ArduinoJson.h>
+#include <catch.hpp>
+
+#include "Allocators.hpp"
+
+TEST_CASE("JsonObjectConst::operator[]") {
+  JsonDocument doc;
+  doc["hello"] = "world";
+  JsonObjectConst obj = doc.as<JsonObjectConst>();
+
+  SECTION("supports const char*") {
+    REQUIRE(obj["hello"] == "world");  // issue #2019
+  }
+
+  SECTION("supports std::string") {
+    REQUIRE(obj[std::string("hello")] == "world");  // issue #2019
+  }
+
+#if defined(HAS_VARIABLE_LENGTH_ARRAY) && \
+    !defined(SUBSCRIPT_CONFLICTS_WITH_BUILTIN_OPERATOR)
+  SECTION("supports VLA") {
+    size_t i = 16;
+    char vla[i];
+    strcpy(vla, "hello");
+
+    REQUIRE(std::string("world") == obj[vla]);
+  }
+#endif
+}

+ 2 - 2
src/ArduinoJson/Object/JsonObjectConst.hpp

@@ -27,7 +27,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
       : data_(data), resources_(resources) {}
 
   operator JsonVariantConst() const {
-    return JsonVariantConst(collectionToVariant(data_), resources_);
+    return JsonVariantConst(getData(), resources_);
   }
 
   // Returns true if the reference is unbound.
@@ -45,7 +45,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
   // Returns the depth (nesting level) of the object.
   // https://arduinojson.org/v7/api/jsonobjectconst/nesting/
   FORCE_INLINE size_t nesting() const {
-    return detail::VariantData::nesting(collectionToVariant(data_), resources_);
+    return detail::VariantData::nesting(getData(), resources_);
   }
 
   // Returns the number of members in the object.