mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 08:42:39 +01:00 
			
		
		
		
	Fixed duplication of char*
This commit is contained in:
		| @@ -127,23 +127,28 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // set(char*) | ||||
|   template <typename T> | ||||
|   bool set(T *value, | ||||
|            typename Internals::enable_if<Internals::IsString<T *>::value>::type | ||||
|                * = 0) { | ||||
|     if (!_data) return false; | ||||
|     const char *dup = Internals::makeString(value).save(_buffer); | ||||
|     if (dup) { | ||||
|       _data->setString(dup); | ||||
|       return true; | ||||
|     } else { | ||||
|       _data->setNull(); | ||||
|       return false; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // set(const char*); | ||||
|   // set(const char[n]); // VLA | ||||
|   bool set(const char *value) { | ||||
|     if (!_data) return false; | ||||
|     _data->setString(value); | ||||
|     return true; | ||||
|   } | ||||
|   // set(const unsigned char*); | ||||
|   // set(const unsigned char[n]); // VLA | ||||
|   bool set(const unsigned char *value) { | ||||
|     return set(reinterpret_cast<const char *>(value)); | ||||
|   } | ||||
|   // set(const signed char*); | ||||
|   // set(const signed char[n]); // VLA | ||||
|   bool set(const signed char *value) { | ||||
|     return set(reinterpret_cast<const char *>(value)); | ||||
|   } | ||||
|  | ||||
|   bool set(const JsonVariant &value) { | ||||
|     if (!_data) return false; | ||||
|   | ||||
| @@ -38,7 +38,9 @@ endif() | ||||
| if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") | ||||
| 	add_compile_options( | ||||
| 		-Wstrict-null-sentinel | ||||
| 		-Wno-vla # Allow VLA in tests | ||||
| 	) | ||||
| 	add_definitions(-DHAS_VARIABLE_LENGTH_ARRAY) | ||||
|  | ||||
| 	if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.5) | ||||
| 		add_compile_options(-Wlogical-op) # the flag exists in 4.4 but is buggy | ||||
| @@ -53,6 +55,11 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") | ||||
| 	add_compile_options( | ||||
| 		-Wc++11-compat | ||||
| 		-Wdeprecated-register | ||||
| 		-Wno-vla-extension # Allow VLA in tests | ||||
| 	) | ||||
| 	add_definitions( | ||||
| 		-DHAS_VARIABLE_LENGTH_ARRAY | ||||
| 		-DSUBSCRIPT_CONFLICTS_WITH_BUILTIN_OPERATOR | ||||
| 	) | ||||
| endif() | ||||
|  | ||||
|   | ||||
| @@ -7,57 +7,69 @@ | ||||
|  | ||||
| TEST_CASE("JsonArray::add()") { | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonArray _array = doc.to<JsonArray>(); | ||||
|   JsonArray array = doc.to<JsonArray>(); | ||||
|  | ||||
|   SECTION("int") { | ||||
|     _array.add(123); | ||||
|     REQUIRE(123 == _array[0].as<int>()); | ||||
|     REQUIRE(_array[0].is<int>()); | ||||
|     REQUIRE(_array[0].is<double>()); | ||||
|     array.add(123); | ||||
|     REQUIRE(123 == array[0].as<int>()); | ||||
|     REQUIRE(array[0].is<int>()); | ||||
|     REQUIRE(array[0].is<double>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("double") { | ||||
|     _array.add(123.45); | ||||
|     REQUIRE(123.45 == _array[0].as<double>()); | ||||
|     REQUIRE(_array[0].is<double>()); | ||||
|     REQUIRE_FALSE(_array[0].is<bool>()); | ||||
|     array.add(123.45); | ||||
|     REQUIRE(123.45 == array[0].as<double>()); | ||||
|     REQUIRE(array[0].is<double>()); | ||||
|     REQUIRE_FALSE(array[0].is<bool>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("bool") { | ||||
|     _array.add(true); | ||||
|     REQUIRE(true == _array[0].as<bool>()); | ||||
|     REQUIRE(_array[0].is<bool>()); | ||||
|     REQUIRE_FALSE(_array[0].is<int>()); | ||||
|     array.add(true); | ||||
|     REQUIRE(true == array[0].as<bool>()); | ||||
|     REQUIRE(array[0].is<bool>()); | ||||
|     REQUIRE_FALSE(array[0].is<int>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("const char*") { | ||||
|     const char* str = "hello"; | ||||
|     _array.add(str); | ||||
|     REQUIRE(str == _array[0].as<std::string>()); | ||||
|     REQUIRE(_array[0].is<const char*>()); | ||||
|     REQUIRE_FALSE(_array[0].is<int>()); | ||||
|     array.add(str); | ||||
|     REQUIRE(str == array[0].as<std::string>()); | ||||
|     REQUIRE(array[0].is<const char*>()); | ||||
|     REQUIRE_FALSE(array[0].is<int>()); | ||||
|   } | ||||
|  | ||||
| #ifdef HAS_VARIABLE_LENGTH_ARRAY | ||||
|   SECTION("vla") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "world"); | ||||
|  | ||||
|     array.add(vla); | ||||
|  | ||||
|     REQUIRE(std::string("world") == array[0]); | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   SECTION("nested array") { | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonArray arr = doc2.to<JsonArray>(); | ||||
|  | ||||
|     _array.add(arr); | ||||
|     array.add(arr); | ||||
|  | ||||
|     REQUIRE(arr == _array[0].as<JsonArray>()); | ||||
|     REQUIRE(_array[0].is<JsonArray>()); | ||||
|     REQUIRE_FALSE(_array[0].is<int>()); | ||||
|     REQUIRE(arr == array[0].as<JsonArray>()); | ||||
|     REQUIRE(array[0].is<JsonArray>()); | ||||
|     REQUIRE_FALSE(array[0].is<int>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("nested object") { | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonObject obj = doc2.to<JsonObject>(); | ||||
|  | ||||
|     _array.add(obj); | ||||
|     array.add(obj); | ||||
|  | ||||
|     REQUIRE(obj == _array[0].as<JsonObject>()); | ||||
|     REQUIRE(_array[0].is<JsonObject>()); | ||||
|     REQUIRE_FALSE(_array[0].is<int>()); | ||||
|     REQUIRE(obj == array[0].as<JsonObject>()); | ||||
|     REQUIRE(array[0].is<JsonObject>()); | ||||
|     REQUIRE_FALSE(array[0].is<int>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("array subscript") { | ||||
| @@ -66,9 +78,9 @@ TEST_CASE("JsonArray::add()") { | ||||
|     JsonArray arr = doc2.to<JsonArray>(); | ||||
|     arr.add(str); | ||||
|  | ||||
|     _array.add(arr[0]); | ||||
|     array.add(arr[0]); | ||||
|  | ||||
|     REQUIRE(str == _array[0]); | ||||
|     REQUIRE(str == array[0]); | ||||
|   } | ||||
|  | ||||
|   SECTION("object subscript") { | ||||
| @@ -77,49 +89,49 @@ TEST_CASE("JsonArray::add()") { | ||||
|     JsonObject obj = doc2.to<JsonObject>(); | ||||
|     obj["x"] = str; | ||||
|  | ||||
|     _array.add(obj["x"]); | ||||
|     array.add(obj["x"]); | ||||
|  | ||||
|     REQUIRE(str == _array[0]); | ||||
|     REQUIRE(str == array[0]); | ||||
|   } | ||||
|  | ||||
|   SECTION("should not duplicate const char*") { | ||||
|     _array.add("world"); | ||||
|     array.add("world"); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char*") { | ||||
|     _array.add(const_cast<char*>("world")); | ||||
|     array.add(const_cast<char*>("world")); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string") { | ||||
|     _array.add(std::string("world")); | ||||
|     array.add(std::string("world")); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should not duplicate serialized(const char*)") { | ||||
|     _array.add(serialized("{}")); | ||||
|     array.add(serialized("{}")); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate serialized(char*)") { | ||||
|     _array.add(serialized(const_cast<char*>("{}"))); | ||||
|     array.add(serialized(const_cast<char*>("{}"))); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 2; | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate serialized(std::string)") { | ||||
|     _array.add(serialized(std::string("{}"))); | ||||
|     array.add(serialized(std::string("{}"))); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 2; | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate serialized(std::string)") { | ||||
|     _array.add(serialized(std::string("\0XX", 3))); | ||||
|     array.add(serialized(std::string("\0XX", 3))); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 3; | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|   | ||||
| @@ -9,57 +9,70 @@ using namespace Catch::Matchers; | ||||
|  | ||||
| TEST_CASE("JsonArray::set()") { | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonArray _array = doc.to<JsonArray>(); | ||||
|   _array.add(0); | ||||
|   JsonArray array = doc.to<JsonArray>(); | ||||
|   array.add(0); | ||||
|  | ||||
|   SECTION("int") { | ||||
|     _array.set(0, 123); | ||||
|     REQUIRE(123 == _array[0].as<int>()); | ||||
|     REQUIRE(_array[0].is<int>()); | ||||
|     REQUIRE_FALSE(_array[0].is<bool>()); | ||||
|     array.set(0, 123); | ||||
|     REQUIRE(123 == array[0].as<int>()); | ||||
|     REQUIRE(array[0].is<int>()); | ||||
|     REQUIRE_FALSE(array[0].is<bool>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("double") { | ||||
|     _array.set(0, 123.45); | ||||
|     REQUIRE(123.45 == _array[0].as<double>()); | ||||
|     REQUIRE(_array[0].is<double>()); | ||||
|     REQUIRE_FALSE(_array[0].is<int>()); | ||||
|     array.set(0, 123.45); | ||||
|     REQUIRE(123.45 == array[0].as<double>()); | ||||
|     REQUIRE(array[0].is<double>()); | ||||
|     REQUIRE_FALSE(array[0].is<int>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("bool") { | ||||
|     _array.set(0, true); | ||||
|     REQUIRE(true == _array[0].as<bool>()); | ||||
|     REQUIRE(_array[0].is<bool>()); | ||||
|     REQUIRE_FALSE(_array[0].is<int>()); | ||||
|     array.set(0, true); | ||||
|     REQUIRE(true == array[0].as<bool>()); | ||||
|     REQUIRE(array[0].is<bool>()); | ||||
|     REQUIRE_FALSE(array[0].is<int>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("const char*") { | ||||
|     _array.set(0, "hello"); | ||||
|     REQUIRE_THAT(_array[0].as<const char*>(), Equals("hello")); | ||||
|     REQUIRE(_array[0].is<const char*>()); | ||||
|     REQUIRE_FALSE(_array[0].is<int>()); | ||||
|     array.set(0, "hello"); | ||||
|     REQUIRE_THAT(array[0].as<const char*>(), Equals("hello")); | ||||
|     REQUIRE(array[0].is<const char*>()); | ||||
|     REQUIRE_FALSE(array[0].is<int>()); | ||||
|   } | ||||
|  | ||||
| #ifdef HAS_VARIABLE_LENGTH_ARRAY | ||||
|   SECTION("set()") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "world"); | ||||
|  | ||||
|     array.add("hello"); | ||||
|     array.set(0, vla); | ||||
|  | ||||
|     REQUIRE(std::string("world") == array[0]); | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   SECTION("nested array") { | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonArray arr = doc2.to<JsonArray>(); | ||||
|  | ||||
|     _array.set(0, arr); | ||||
|     array.set(0, arr); | ||||
|  | ||||
|     REQUIRE(arr == _array[0].as<JsonArray>()); | ||||
|     REQUIRE(_array[0].is<JsonArray>()); | ||||
|     REQUIRE_FALSE(_array[0].is<int>()); | ||||
|     REQUIRE(arr == array[0].as<JsonArray>()); | ||||
|     REQUIRE(array[0].is<JsonArray>()); | ||||
|     REQUIRE_FALSE(array[0].is<int>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("nested object") { | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonObject obj = doc2.to<JsonObject>(); | ||||
|  | ||||
|     _array.set(0, obj); | ||||
|     array.set(0, obj); | ||||
|  | ||||
|     REQUIRE(obj == _array[0].as<JsonObject>()); | ||||
|     REQUIRE(_array[0].is<JsonObject>()); | ||||
|     REQUIRE_FALSE(_array[0].is<int>()); | ||||
|     REQUIRE(obj == array[0].as<JsonObject>()); | ||||
|     REQUIRE(array[0].is<JsonObject>()); | ||||
|     REQUIRE_FALSE(array[0].is<int>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("array subscript") { | ||||
| @@ -67,9 +80,9 @@ TEST_CASE("JsonArray::set()") { | ||||
|     JsonArray arr = doc2.to<JsonArray>(); | ||||
|     arr.add("hello"); | ||||
|  | ||||
|     _array.set(0, arr[0]); | ||||
|     array.set(0, arr[0]); | ||||
|  | ||||
|     REQUIRE_THAT(_array[0].as<char*>(), Equals("hello")); | ||||
|     REQUIRE_THAT(array[0].as<char*>(), Equals("hello")); | ||||
|   } | ||||
|  | ||||
|   SECTION("object subscript") { | ||||
| @@ -77,25 +90,25 @@ TEST_CASE("JsonArray::set()") { | ||||
|     JsonObject obj = doc2.to<JsonObject>(); | ||||
|     obj["x"] = "hello"; | ||||
|  | ||||
|     _array.set(0, obj["x"]); | ||||
|     array.set(0, obj["x"]); | ||||
|  | ||||
|     REQUIRE_THAT(_array[0].as<char*>(), Equals("hello")); | ||||
|     REQUIRE_THAT(array[0].as<char*>(), Equals("hello")); | ||||
|   } | ||||
|  | ||||
|   SECTION("should not duplicate const char*") { | ||||
|     _array.set(0, "world"); | ||||
|     array.set(0, "world"); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char*") { | ||||
|     _array.set(0, const_cast<char*>("world")); | ||||
|     array.set(0, const_cast<char*>("world")); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string") { | ||||
|     _array.set(0, std::string("world")); | ||||
|     array.set(0, std::string("world")); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|   | ||||
| @@ -8,85 +8,85 @@ | ||||
|  | ||||
| TEST_CASE("JsonArray::operator[]") { | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonArray _array = doc.to<JsonArray>(); | ||||
|   _array.add(0); | ||||
|   JsonArray array = doc.to<JsonArray>(); | ||||
|   array.add(0); | ||||
|  | ||||
|   SECTION("int") { | ||||
|     _array[0] = 123; | ||||
|     REQUIRE(123 == _array[0].as<int>()); | ||||
|     REQUIRE(true == _array[0].is<int>()); | ||||
|     REQUIRE(false == _array[0].is<bool>()); | ||||
|     array[0] = 123; | ||||
|     REQUIRE(123 == array[0].as<int>()); | ||||
|     REQUIRE(true == array[0].is<int>()); | ||||
|     REQUIRE(false == array[0].is<bool>()); | ||||
|   } | ||||
|  | ||||
| #if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64 | ||||
|   SECTION("long long") { | ||||
|     _array[0] = 9223372036854775807; | ||||
|     REQUIRE(9223372036854775807 == _array[0].as<long long>()); | ||||
|     REQUIRE(true == _array[0].is<int>()); | ||||
|     REQUIRE(false == _array[0].is<bool>()); | ||||
|     array[0] = 9223372036854775807; | ||||
|     REQUIRE(9223372036854775807 == array[0].as<long long>()); | ||||
|     REQUIRE(true == array[0].is<int>()); | ||||
|     REQUIRE(false == array[0].is<bool>()); | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   SECTION("double") { | ||||
|     _array[0] = 123.45; | ||||
|     REQUIRE(123.45 == _array[0].as<double>()); | ||||
|     REQUIRE(true == _array[0].is<double>()); | ||||
|     REQUIRE(false == _array[0].is<int>()); | ||||
|     array[0] = 123.45; | ||||
|     REQUIRE(123.45 == array[0].as<double>()); | ||||
|     REQUIRE(true == array[0].is<double>()); | ||||
|     REQUIRE(false == array[0].is<int>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("bool") { | ||||
|     _array[0] = true; | ||||
|     REQUIRE(true == _array[0].as<bool>()); | ||||
|     REQUIRE(true == _array[0].is<bool>()); | ||||
|     REQUIRE(false == _array[0].is<int>()); | ||||
|     array[0] = true; | ||||
|     REQUIRE(true == array[0].as<bool>()); | ||||
|     REQUIRE(true == array[0].is<bool>()); | ||||
|     REQUIRE(false == array[0].is<int>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("const char*") { | ||||
|     const char* str = "hello"; | ||||
|  | ||||
|     _array[0] = str; | ||||
|     REQUIRE(str == _array[0].as<const char*>()); | ||||
|     REQUIRE(str == _array[0].as<char*>());  // <- short hand | ||||
|     REQUIRE(true == _array[0].is<const char*>()); | ||||
|     REQUIRE(false == _array[0].is<int>()); | ||||
|     array[0] = str; | ||||
|     REQUIRE(str == array[0].as<const char*>()); | ||||
|     REQUIRE(str == array[0].as<char*>());  // <- short hand | ||||
|     REQUIRE(true == array[0].is<const char*>()); | ||||
|     REQUIRE(false == array[0].is<int>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("nested array") { | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonArray arr = doc2.to<JsonArray>(); | ||||
|     JsonArray arr2 = doc2.to<JsonArray>(); | ||||
|  | ||||
|     _array[0] = arr; | ||||
|     array[0] = arr2; | ||||
|  | ||||
|     REQUIRE(arr == _array[0].as<JsonArray>()); | ||||
|     REQUIRE(arr == _array[0].as<JsonArray>());  // <- short hand | ||||
|     // REQUIRE(arr == _array[0].as<const JsonArray>()); | ||||
|     // REQUIRE(arr == _array[0].as<const JsonArray>());  // <- short hand | ||||
|     REQUIRE(true == _array[0].is<JsonArray>()); | ||||
|     REQUIRE(false == _array[0].is<int>()); | ||||
|     REQUIRE(arr2 == array[0].as<JsonArray>()); | ||||
|     REQUIRE(arr2 == array[0].as<JsonArray>());  // <- short hand | ||||
|     // REQUIRE(arr2 == array[0].as<const JsonArray>()); | ||||
|     // REQUIRE(arr2 == array[0].as<const JsonArray>());  // <- short hand | ||||
|     REQUIRE(true == array[0].is<JsonArray>()); | ||||
|     REQUIRE(false == array[0].is<int>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("nested object") { | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonObject obj = doc2.to<JsonObject>(); | ||||
|  | ||||
|     _array[0] = obj; | ||||
|     array[0] = obj; | ||||
|  | ||||
|     REQUIRE(obj == _array[0].as<JsonObject>()); | ||||
|     REQUIRE(obj == _array[0].as<const JsonObject>());  // <- short hand | ||||
|     REQUIRE(true == _array[0].is<JsonObject>()); | ||||
|     REQUIRE(false == _array[0].is<int>()); | ||||
|     REQUIRE(obj == array[0].as<JsonObject>()); | ||||
|     REQUIRE(obj == array[0].as<const JsonObject>());  // <- short hand | ||||
|     REQUIRE(true == array[0].is<JsonObject>()); | ||||
|     REQUIRE(false == array[0].is<int>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("array subscript") { | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonArray arr = doc2.to<JsonArray>(); | ||||
|     JsonArray arr2 = doc2.to<JsonArray>(); | ||||
|     const char* str = "hello"; | ||||
|  | ||||
|     arr.add(str); | ||||
|     arr2.add(str); | ||||
|  | ||||
|     _array[0] = arr[0]; | ||||
|     array[0] = arr2[0]; | ||||
|  | ||||
|     REQUIRE(str == _array[0]); | ||||
|     REQUIRE(str == array[0]); | ||||
|   } | ||||
|  | ||||
|   SECTION("object subscript") { | ||||
| @@ -96,26 +96,50 @@ TEST_CASE("JsonArray::operator[]") { | ||||
|  | ||||
|     obj["x"] = str; | ||||
|  | ||||
|     _array[0] = obj["x"]; | ||||
|     array[0] = obj["x"]; | ||||
|  | ||||
|     REQUIRE(str == _array[0]); | ||||
|     REQUIRE(str == array[0]); | ||||
|   } | ||||
|  | ||||
|   SECTION("should not duplicate const char*") { | ||||
|     _array[0] = "world"; | ||||
|     array[0] = "world"; | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char*") { | ||||
|     _array[0] = const_cast<char*>("world"); | ||||
|     array[0] = const_cast<char*>("world"); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string") { | ||||
|     _array[0] = std::string("world"); | ||||
|     array[0] = std::string("world"); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
| #ifdef HAS_VARIABLE_LENGTH_ARRAY | ||||
|   SECTION("set(VLA)") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "world"); | ||||
|  | ||||
|     array.add("hello"); | ||||
|     array[0].set(vla); | ||||
|  | ||||
|     REQUIRE(std::string("world") == array[0]); | ||||
|   } | ||||
|  | ||||
|   SECTION("operator=(VLA)") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "world"); | ||||
|  | ||||
|     array.add("hello"); | ||||
|     array[0] = vla; | ||||
|  | ||||
|     REQUIRE(std::string("world") == array[0]); | ||||
|   } | ||||
| #endif | ||||
| } | ||||
|   | ||||
| @@ -3,15 +3,14 @@ | ||||
| # MIT License | ||||
|  | ||||
| add_executable(JsonDeserializerTests | ||||
| 	DeserializationError.cpp | ||||
| 	deserializeJsonArray.cpp | ||||
| 	deserializeJsonArrayStatic.cpp | ||||
| 	deserializeJsonObject.cpp | ||||
| 	deserializeJsonObjectStatic.cpp | ||||
| 	deserializeJsonValue.cpp | ||||
| 	DeserializationError.cpp | ||||
| 	input_types.cpp | ||||
| 	nestingLimit.cpp | ||||
| 	std_istream.cpp | ||||
| 	std_string.cpp | ||||
| ) | ||||
|  | ||||
| target_link_libraries(JsonDeserializerTests catch) | ||||
|   | ||||
| @@ -6,6 +6,35 @@ | ||||
| #include <catch.hpp> | ||||
| #include <sstream> | ||||
| 
 | ||||
| TEST_CASE("deserializeJson(const std::string&)") { | ||||
|   DynamicJsonDocument doc; | ||||
| 
 | ||||
|   SECTION("should accept const string") { | ||||
|     const std::string input("[42]"); | ||||
| 
 | ||||
|     DeserializationError err = deserializeJson(doc, input); | ||||
| 
 | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|   } | ||||
| 
 | ||||
|   SECTION("should accept temporary string") { | ||||
|     DeserializationError err = deserializeJson(doc, std::string("[42]")); | ||||
| 
 | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|   } | ||||
| 
 | ||||
|   SECTION("should duplicate content") { | ||||
|     std::string input("[\"hello\"]"); | ||||
| 
 | ||||
|     DeserializationError err = deserializeJson(doc, input); | ||||
|     input[2] = 'X';  // alter the string tomake sure we made a copy
 | ||||
| 
 | ||||
|     JsonArray array = doc.as<JsonArray>(); | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|     REQUIRE(std::string("hello") == array[0]); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| TEST_CASE("deserializeJson(std::istream&)") { | ||||
|   DynamicJsonDocument doc; | ||||
| 
 | ||||
| @@ -71,3 +100,16 @@ TEST_CASE("deserializeJson(std::istream&)") { | ||||
|     REQUIRE('1' == char(json.get())); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| #ifdef HAS_VARIABLE_LENGTH_ARRAY | ||||
| TEST_CASE("deserializeJson(VLA)") { | ||||
|   int i = 9; | ||||
|   char vla[i]; | ||||
|   strcpy(vla, "{\"a\":42}"); | ||||
| 
 | ||||
|   StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc; | ||||
|   DeserializationError err = deserializeJson(doc, vla); | ||||
| 
 | ||||
|   REQUIRE(err == DeserializationError::Ok); | ||||
| } | ||||
| #endif | ||||
| @@ -1,35 +0,0 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("deserializeJson(const std::string&)") { | ||||
|   DynamicJsonDocument doc; | ||||
|  | ||||
|   SECTION("should accept const string") { | ||||
|     const std::string input("[42]"); | ||||
|  | ||||
|     DeserializationError err = deserializeJson(doc, input); | ||||
|  | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("should accept temporary string") { | ||||
|     DeserializationError err = deserializeJson(doc, std::string("[42]")); | ||||
|  | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate content") { | ||||
|     std::string input("[\"hello\"]"); | ||||
|  | ||||
|     DeserializationError err = deserializeJson(doc, input); | ||||
|     input[2] = 'X';  // alter the string tomake sure we made a copy | ||||
|  | ||||
|     JsonArray array = doc.as<JsonArray>(); | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|     REQUIRE(std::string("hello") == array[0]); | ||||
|   } | ||||
| } | ||||
| @@ -4,8 +4,11 @@ | ||||
|  | ||||
| add_executable(JsonObjectTests  | ||||
| 	containsKey.cpp | ||||
| 	createNestedArray.cpp | ||||
| 	createNestedObject.cpp | ||||
| 	get.cpp | ||||
| 	invalid.cpp | ||||
| 	is.cpp | ||||
| 	isNull.cpp | ||||
| 	iterator.cpp | ||||
| 	remove.cpp | ||||
|   | ||||
| @@ -8,23 +8,29 @@ | ||||
| TEST_CASE("JsonObject::containsKey()") { | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonObject obj = doc.to<JsonObject>(); | ||||
|   obj.set("hello", 42); | ||||
|  | ||||
|   SECTION("ContainsKeyReturnsFalseForNonExistingKey") { | ||||
|     obj.set("hello", 42); | ||||
|  | ||||
|   SECTION("returns false if key not present") { | ||||
|     REQUIRE(false == obj.containsKey("world")); | ||||
|   } | ||||
|  | ||||
|   SECTION("ContainsKeyReturnsTrueForDefinedValue") { | ||||
|     obj.set("hello", 42); | ||||
|  | ||||
|   SECTION("returns true if key present") { | ||||
|     REQUIRE(true == obj.containsKey("hello")); | ||||
|   } | ||||
|  | ||||
|   SECTION("ContainsKeyReturnsFalseAfterRemove") { | ||||
|     obj.set("hello", 42); | ||||
|   SECTION("returns false after remove()") { | ||||
|     obj.remove("hello"); | ||||
|  | ||||
|     REQUIRE(false == obj.containsKey("hello")); | ||||
|   } | ||||
|  | ||||
| #ifdef HAS_VARIABLE_LENGTH_ARRAY | ||||
|   SECTION("key is a VLA") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     REQUIRE(true == obj.containsKey(vla)); | ||||
|   } | ||||
| #endif | ||||
| } | ||||
|   | ||||
							
								
								
									
										25
									
								
								test/JsonObject/createNestedArray.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								test/JsonObject/createNestedArray.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonObject::createNestedArray()") { | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonObject obj = doc.to<JsonObject>(); | ||||
|  | ||||
|   SECTION("key is a const char*") { | ||||
|     obj.createNestedArray("hello"); | ||||
|   } | ||||
|  | ||||
| #ifdef HAS_VARIABLE_LENGTH_ARRAY | ||||
|   SECTION("key is a VLA") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     obj.createNestedArray(vla); | ||||
|   } | ||||
| #endif | ||||
| } | ||||
							
								
								
									
										25
									
								
								test/JsonObject/createNestedObject.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								test/JsonObject/createNestedObject.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonObject::createNestedObject()") { | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonObject obj = doc.to<JsonObject>(); | ||||
|  | ||||
|   SECTION("key is a const char*") { | ||||
|     obj.createNestedObject("hello"); | ||||
|   } | ||||
|  | ||||
| #ifdef HAS_VARIABLE_LENGTH_ARRAY | ||||
|   SECTION("key is a VLA") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     obj.createNestedObject(vla); | ||||
|   } | ||||
| #endif | ||||
| } | ||||
| @@ -11,9 +11,20 @@ TEST_CASE("JsonObject::get()") { | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonObject obj = doc.to<JsonObject>(); | ||||
|  | ||||
|   SECTION("GetConstCharPointer_GivenStringLiteral") { | ||||
|   SECTION("get<const char*>(const char*)") { | ||||
|     obj.set("hello", "world"); | ||||
|     const char* value = obj.get<const char*>("hello"); | ||||
|     REQUIRE_THAT(value, Equals("world")); | ||||
|   } | ||||
|  | ||||
| #ifdef HAS_VARIABLE_LENGTH_ARRAY | ||||
|   SECTION("get<const char*>(VLA)") { | ||||
|     obj.set("hello", "world"); | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     REQUIRE(std::string("world") == obj.get<char*>(vla)); | ||||
|   } | ||||
| #endif | ||||
| } | ||||
|   | ||||
							
								
								
									
										28
									
								
								test/JsonObject/is.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								test/JsonObject/is.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonObject::is<T>()") { | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonObject obj = doc.to<JsonObject>(); | ||||
|   obj["int"] = 42; | ||||
|   obj["str"] = "hello"; | ||||
|  | ||||
|   SECTION("is<int>(const char*)") { | ||||
|     REQUIRE(true == obj.is<int>("int")); | ||||
|     REQUIRE(false == obj.is<int>("str")); | ||||
|   } | ||||
|  | ||||
| #if HAS_VARIABLE_LENGTH_ARRAY | ||||
|   SECTION("is<T>(VLA)") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "int"); | ||||
|  | ||||
|     REQUIRE(true == obj.is<int>(vla)); | ||||
|   } | ||||
| #endif | ||||
| } | ||||
| @@ -39,4 +39,17 @@ TEST_CASE("JsonObject::remove()") { | ||||
|     serializeJson(obj, result); | ||||
|     REQUIRE("{\"a\":0,\"c\":2}" == result); | ||||
|   } | ||||
|  | ||||
| #ifdef HAS_VARIABLE_LENGTH_ARRAY | ||||
|   SECTION("key is a vla") { | ||||
|     obj["hello"] = 1; | ||||
|  | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|     obj.remove(vla); | ||||
|  | ||||
|     REQUIRE(0 == obj.size()); | ||||
|   } | ||||
| #endif | ||||
| } | ||||
|   | ||||
| @@ -42,6 +42,38 @@ TEST_CASE("JsonObject::set()") { | ||||
|     REQUIRE_FALSE(obj["hello"].is<long>()); | ||||
|   } | ||||
|  | ||||
| #ifdef HAS_VARIABLE_LENGTH_ARRAY | ||||
|   SECTION("key is a VLA") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     obj.set(vla, "world"); | ||||
|  | ||||
|     REQUIRE(std::string("world") == obj["hello"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("value is a VLA") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "world"); | ||||
|  | ||||
|     obj.set("hello", vla); | ||||
|  | ||||
|     REQUIRE(std::string("world") == obj["hello"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("key and value are VLAs") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "world"); | ||||
|  | ||||
|     obj.set(vla, vla); | ||||
|  | ||||
|     REQUIRE(std::string("world") == obj["world"]); | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   SECTION("nested array") { | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonArray arr = doc2.to<JsonArray>(); | ||||
|   | ||||
| @@ -159,4 +159,58 @@ TEST_CASE("JsonObject::operator[]") { | ||||
|     REQUIRE(obj.size() == 1); | ||||
|     REQUIRE(obj[null] == 0); | ||||
|   } | ||||
|  | ||||
| #if defined(HAS_VARIABLE_LENGTH_ARRAY) && \ | ||||
|     !defined(SUBSCRIPT_CONFLICTS_WITH_BUILTIN_OPERATOR) | ||||
|   SECTION("obj[VLA] = str") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     obj[vla] = "world"; | ||||
|  | ||||
|     REQUIRE(std::string("world") == obj["hello"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("obj[str] = VLA") {  // issue #416 | ||||
|     int i = 32; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "world"); | ||||
|  | ||||
|     obj["hello"] = vla; | ||||
|  | ||||
|     REQUIRE(std::string("world") == obj["hello"].as<char*>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("obj.set(VLA, str)") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     obj[vla] = "world"; | ||||
|  | ||||
|     REQUIRE(std::string("world") == obj["hello"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("obj.set(str, VLA)") { | ||||
|     int i = 32; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "world"); | ||||
|  | ||||
|     obj["hello"].set(vla); | ||||
|  | ||||
|     REQUIRE(std::string("world") == obj["hello"].as<char*>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("obj[VLA]") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|     obj = doc.as<JsonObject>(); | ||||
|     REQUIRE(std::string("world") == obj[vla]); | ||||
|   } | ||||
| #endif | ||||
| } | ||||
|   | ||||
| @@ -179,6 +179,38 @@ TEST_CASE("JsonVariant comparisons") { | ||||
|     REQUIRE_FALSE(null == variant); | ||||
|   } | ||||
|  | ||||
| #ifdef HAS_VARIABLE_LENGTH_ARRAY | ||||
|   SECTION("VLA equals") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonVariant variant = doc.to<JsonVariant>(); | ||||
|     variant.set("hello"); | ||||
|  | ||||
|     REQUIRE((vla == variant)); | ||||
|     REQUIRE((variant == vla)); | ||||
|     REQUIRE_FALSE((vla != variant)); | ||||
|     REQUIRE_FALSE((variant != vla)); | ||||
|   } | ||||
|  | ||||
|   SECTION("VLA differs") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonVariant variant = doc.to<JsonVariant>(); | ||||
|     variant.set("world"); | ||||
|  | ||||
|     REQUIRE((vla != variant)); | ||||
|     REQUIRE((variant != vla)); | ||||
|     REQUIRE_FALSE((vla == variant)); | ||||
|     REQUIRE_FALSE((variant == vla)); | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   DynamicJsonDocument doc1, doc2, doc3; | ||||
|   JsonVariant variant1 = doc1.to<JsonVariant>(); | ||||
|   JsonVariant variant2 = doc2.to<JsonVariant>(); | ||||
|   | ||||
| @@ -138,3 +138,74 @@ TEST_CASE("JsonVariant set()/get()") { | ||||
|     checkValue<JsonObject>(object); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonVariant and strings") { | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonVariant variant = doc.to<JsonVariant>(); | ||||
|  | ||||
|   SECTION("stores const char* by reference") { | ||||
|     char str[16]; | ||||
|  | ||||
|     strcpy(str, "hello"); | ||||
|     variant.set(static_cast<const char *>(str)); | ||||
|     strcpy(str, "world"); | ||||
|  | ||||
|     REQUIRE(variant == "world"); | ||||
|   } | ||||
|  | ||||
|   SECTION("stores char* by copy") { | ||||
|     char str[16]; | ||||
|  | ||||
|     strcpy(str, "hello"); | ||||
|     variant.set(str); | ||||
|     strcpy(str, "world"); | ||||
|  | ||||
|     REQUIRE(variant == "hello"); | ||||
|   } | ||||
|  | ||||
|   SECTION("stores unsigned char* by copy") { | ||||
|     char str[16]; | ||||
|  | ||||
|     strcpy(str, "hello"); | ||||
|     variant.set(reinterpret_cast<unsigned char *>(str)); | ||||
|     strcpy(str, "world"); | ||||
|  | ||||
|     REQUIRE(variant == "hello"); | ||||
|   } | ||||
|  | ||||
|   SECTION("stores signed char* by copy") { | ||||
|     char str[16]; | ||||
|  | ||||
|     strcpy(str, "hello"); | ||||
|     variant.set(reinterpret_cast<signed char *>(str)); | ||||
|     strcpy(str, "world"); | ||||
|  | ||||
|     REQUIRE(variant == "hello"); | ||||
|   } | ||||
|  | ||||
| #ifdef HAS_VARIABLE_LENGTH_ARRAY | ||||
|   SECTION("stores VLA by copy") { | ||||
|     int n = 16; | ||||
|     char str[n]; | ||||
|  | ||||
|     strcpy(str, "hello"); | ||||
|     variant.set(str); | ||||
|     strcpy(str, "world"); | ||||
|  | ||||
|     REQUIRE(variant == "hello"); | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   SECTION("stores std::string by copy") { | ||||
|     std::string str; | ||||
|  | ||||
|     str = "hello"; | ||||
|     variant.set(str); | ||||
|     str.replace(0, 5, "world"); | ||||
|  | ||||
|     REQUIRE(variant == "hello"); | ||||
|   } | ||||
|  | ||||
|   // TODO: string | ||||
|   // TODO: serialized() | ||||
| } | ||||
|   | ||||
| @@ -93,4 +93,29 @@ TEST_CASE("JsonVariant::operator[]") { | ||||
|       REQUIRE(std::string("world") == var["hello"]); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| #if defined(HAS_VARIABLE_LENGTH_ARRAY) && \ | ||||
|     !defined(SUBSCRIPT_CONFLICTS_WITH_BUILTIN_OPERATOR) | ||||
|   SECTION("key is a VLA") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|     JsonVariant variant = doc.as<JsonVariant>(); | ||||
|  | ||||
|     REQUIRE(std::string("world") == variant[vla]); | ||||
|   } | ||||
|  | ||||
|   SECTION("key is a VLA, const JsonVariant") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|     const JsonVariant variant = doc.as<JsonVariant>(); | ||||
|  | ||||
|     REQUIRE(std::string("world") == variant[vla]); | ||||
|   } | ||||
| #endif | ||||
| } | ||||
|   | ||||
| @@ -8,7 +8,6 @@ add_executable(MiscTests | ||||
| 	TypeTraits.cpp | ||||
| 	unsigned_char.cpp | ||||
| 	version.cpp | ||||
| 	vla.cpp | ||||
| ) | ||||
|  | ||||
| target_link_libraries(MiscTests catch) | ||||
|   | ||||
| @@ -1,327 +0,0 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| #if defined(__clang__) | ||||
| #pragma clang diagnostic ignored "-Wvla-extension" | ||||
| #define CONFLICTS_WITH_BUILTIN_OPERATOR | ||||
| #elif defined(__GNUC__) | ||||
| #pragma GCC diagnostic ignored "-Wvla" | ||||
| #else | ||||
| #define VLA_NOT_SUPPORTED | ||||
| #endif | ||||
|  | ||||
| #ifndef VLA_NOT_SUPPORTED | ||||
|  | ||||
| TEST_CASE("Variable Length Array") { | ||||
|   SECTION("deserializeJson()") { | ||||
|     int i = 9; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "{\"a\":42}"); | ||||
|  | ||||
|     StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc; | ||||
|     DeserializationError err = deserializeJson(doc, vla); | ||||
|  | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("deserializeMsgPack()") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     memcpy(vla, "\xDE\x00\x01\xA5Hello\xA5world", 15); | ||||
|  | ||||
|     StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc; | ||||
|     DeserializationError err = deserializeMsgPack(doc, vla); | ||||
|  | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("JsonVariant") { | ||||
|     DynamicJsonDocument doc; | ||||
|  | ||||
|     SECTION("set()") { | ||||
|       int i = 16; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "42"); | ||||
|  | ||||
|       JsonVariant variant = doc.to<JsonVariant>(); | ||||
|       variant.set(vla); | ||||
|  | ||||
|       REQUIRE(42 == variant.as<int>()); | ||||
|     } | ||||
|  | ||||
| #ifndef CONFLICTS_WITH_BUILTIN_OPERATOR | ||||
|     SECTION("operator[]") { | ||||
|       int i = 16; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "hello"); | ||||
|  | ||||
|       deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|       JsonVariant variant = doc.as<JsonVariant>(); | ||||
|  | ||||
|       REQUIRE(std::string("world") == variant[vla]); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
| #ifndef CONFLICTS_WITH_BUILTIN_OPERATOR | ||||
|     SECTION("operator[] const") { | ||||
|       int i = 16; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "hello"); | ||||
|  | ||||
|       deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|       const JsonVariant variant = doc.as<JsonVariant>(); | ||||
|  | ||||
|       REQUIRE(std::string("world") == variant[vla]); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|     SECTION("operator==") { | ||||
|       int i = 16; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "hello"); | ||||
|  | ||||
|       JsonVariant variant = doc.to<JsonVariant>(); | ||||
|       variant.set("hello"); | ||||
|  | ||||
|       REQUIRE((vla == variant)); | ||||
|       REQUIRE((variant == vla)); | ||||
|       REQUIRE_FALSE((vla != variant)); | ||||
|       REQUIRE_FALSE((variant != vla)); | ||||
|     } | ||||
|  | ||||
|     SECTION("operator!=") { | ||||
|       int i = 16; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "hello"); | ||||
|  | ||||
|       JsonVariant variant; | ||||
|       variant.set("world"); | ||||
|  | ||||
|       REQUIRE((vla != variant)); | ||||
|       REQUIRE((variant != vla)); | ||||
|       REQUIRE_FALSE((vla == variant)); | ||||
|       REQUIRE_FALSE((variant == vla)); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("JsonObject") { | ||||
| #ifndef CONFLICTS_WITH_BUILTIN_OPERATOR | ||||
|     SECTION("operator[]") { | ||||
|       int i = 16; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "hello"); | ||||
|  | ||||
|       DynamicJsonDocument doc; | ||||
|       JsonObject obj = doc.to<JsonObject>(); | ||||
|       obj[vla] = "world"; | ||||
|  | ||||
|       REQUIRE(std::string("world") == obj["hello"]); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
| #ifndef CONFLICTS_WITH_BUILTIN_OPERATOR | ||||
|     SECTION("operator[] const") { | ||||
|       int i = 16; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "hello"); | ||||
|  | ||||
|       DynamicJsonDocument doc; | ||||
|       deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|       REQUIRE(std::string("world") == obj[vla]); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|     SECTION("get()") { | ||||
|       int i = 16; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "hello"); | ||||
|  | ||||
|       DynamicJsonDocument doc; | ||||
|       deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|       REQUIRE(std::string("world") == obj.get<char*>(vla)); | ||||
|     } | ||||
|  | ||||
|     SECTION("set() key") { | ||||
|       int i = 16; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "hello"); | ||||
|  | ||||
|       DynamicJsonDocument doc; | ||||
|       JsonObject obj = doc.to<JsonObject>(); | ||||
|       obj.set(vla, "world"); | ||||
|  | ||||
|       REQUIRE(std::string("world") == obj["hello"]); | ||||
|     } | ||||
|  | ||||
|     SECTION("set() value") { | ||||
|       int i = 16; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "world"); | ||||
|  | ||||
|       DynamicJsonDocument doc; | ||||
|       JsonObject obj = doc.to<JsonObject>(); | ||||
|       obj.set("hello", vla); | ||||
|  | ||||
|       REQUIRE(std::string("world") == obj["hello"]); | ||||
|     } | ||||
|  | ||||
|     SECTION("set() key&value") { | ||||
|       int i = 16; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "world"); | ||||
|  | ||||
|       DynamicJsonDocument doc; | ||||
|       JsonObject obj = doc.to<JsonObject>(); | ||||
|       obj.set(vla, vla); | ||||
|  | ||||
|       REQUIRE(std::string("world") == obj["world"]); | ||||
|     } | ||||
|  | ||||
|     SECTION("containsKey()") { | ||||
|       int i = 16; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "hello"); | ||||
|  | ||||
|       DynamicJsonDocument doc; | ||||
|       deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|       REQUIRE(true == obj.containsKey(vla)); | ||||
|     } | ||||
|  | ||||
|     SECTION("remove()") { | ||||
|       int i = 16; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "hello"); | ||||
|  | ||||
|       DynamicJsonDocument doc; | ||||
|       deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|       obj.remove(vla); | ||||
|  | ||||
|       REQUIRE(0 == obj.size()); | ||||
|     } | ||||
|  | ||||
|     SECTION("is<T>()") { | ||||
|       int i = 16; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "hello"); | ||||
|  | ||||
|       DynamicJsonDocument doc; | ||||
|       deserializeJson(doc, "{\"hello\":42}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(true == obj.is<int>(vla)); | ||||
|     } | ||||
|  | ||||
|     SECTION("createNestedArray()") { | ||||
|       int i = 16; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "hello"); | ||||
|  | ||||
|       DynamicJsonDocument doc; | ||||
|       JsonObject obj = doc.to<JsonObject>(); | ||||
|       obj.createNestedArray(vla); | ||||
|     } | ||||
|  | ||||
|     SECTION("createNestedObject()") { | ||||
|       int i = 16; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "hello"); | ||||
|  | ||||
|       DynamicJsonDocument doc; | ||||
|       JsonObject obj = doc.to<JsonObject>(); | ||||
|       obj.createNestedObject(vla); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("JsonObjectSubscript") { | ||||
|     SECTION("operator=") {  // issue #416 | ||||
|       int i = 32; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "world"); | ||||
|  | ||||
|       DynamicJsonDocument doc; | ||||
|       JsonObject obj = doc.to<JsonObject>(); | ||||
|       obj["hello"] = vla; | ||||
|  | ||||
|       REQUIRE(std::string("world") == obj["hello"].as<char*>()); | ||||
|     } | ||||
|  | ||||
|     SECTION("set()") { | ||||
|       int i = 32; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "world"); | ||||
|  | ||||
|       DynamicJsonDocument doc; | ||||
|       JsonObject obj = doc.to<JsonObject>(); | ||||
|       obj["hello"].set(vla); | ||||
|  | ||||
|       REQUIRE(std::string("world") == obj["hello"].as<char*>()); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("JsonArray") { | ||||
|     SECTION("add()") { | ||||
|       int i = 16; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "world"); | ||||
|  | ||||
|       DynamicJsonDocument doc; | ||||
|       JsonArray arr = doc.to<JsonArray>(); | ||||
|       arr.add(vla); | ||||
|  | ||||
|       REQUIRE(std::string("world") == arr[0]); | ||||
|     } | ||||
|  | ||||
|     SECTION("set()") { | ||||
|       int i = 16; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "world"); | ||||
|  | ||||
|       DynamicJsonDocument doc; | ||||
|       JsonArray arr = doc.to<JsonArray>(); | ||||
|       arr.add("hello"); | ||||
|       arr.set(0, vla); | ||||
|  | ||||
|       REQUIRE(std::string("world") == arr[0]); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("JsonArraySubscript") { | ||||
|     SECTION("set()") { | ||||
|       int i = 16; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "world"); | ||||
|  | ||||
|       DynamicJsonDocument doc; | ||||
|       JsonArray arr = doc.to<JsonArray>(); | ||||
|       arr.add("hello"); | ||||
|       arr[0].set(vla); | ||||
|  | ||||
|       REQUIRE(std::string("world") == arr[0]); | ||||
|     } | ||||
|  | ||||
|     SECTION("operator=") { | ||||
|       int i = 16; | ||||
|       char vla[i]; | ||||
|       strcpy(vla, "world"); | ||||
|  | ||||
|       DynamicJsonDocument doc; | ||||
|       JsonArray arr = doc.to<JsonArray>(); | ||||
|       arr.add("hello"); | ||||
|       arr[0] = vla; | ||||
|  | ||||
|       REQUIRE(std::string("world") == arr[0]); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| #endif | ||||
| @@ -9,10 +9,9 @@ add_executable(MsgPackDeserializerTests | ||||
| 	deserializeVariant.cpp | ||||
| 	doubleToFloat.cpp | ||||
| 	incompleteInput.cpp | ||||
| 	input_types.cpp | ||||
| 	nestingLimit.cpp | ||||
| 	notSupported.cpp | ||||
| 	std_string.cpp | ||||
| 	std_istream.cpp | ||||
| ) | ||||
|  | ||||
| target_link_libraries(MsgPackDeserializerTests catch) | ||||
|   | ||||
| @@ -44,3 +44,39 @@ TEST_CASE("deserializeMsgPack(const std::string&)") { | ||||
|     REQUIRE(arr[1] == 2); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| TEST_CASE("deserializeMsgPack(std::istream&)") { | ||||
|   DynamicJsonDocument doc; | ||||
| 
 | ||||
|   SECTION("should accept a zero in input") { | ||||
|     std::istringstream input(std::string("\x92\x00\x02", 3)); | ||||
| 
 | ||||
|     DeserializationError err = deserializeMsgPack(doc, input); | ||||
| 
 | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|     JsonArray arr = doc.as<JsonArray>(); | ||||
|     REQUIRE(arr[0] == 0); | ||||
|     REQUIRE(arr[1] == 2); | ||||
|   } | ||||
| 
 | ||||
|   SECTION("should detect incomplete input") { | ||||
|     std::istringstream input("\x92\x00\x02"); | ||||
| 
 | ||||
|     DeserializationError err = deserializeMsgPack(doc, input); | ||||
| 
 | ||||
|     REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| #ifdef HAS_VARIABLE_LENGTH_ARRAY | ||||
| TEST_CASE("deserializeMsgPack(VLA)") { | ||||
|   int i = 16; | ||||
|   char vla[i]; | ||||
|   memcpy(vla, "\xDE\x00\x01\xA5Hello\xA5world", 15); | ||||
| 
 | ||||
|   StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc; | ||||
|   DeserializationError err = deserializeMsgPack(doc, vla); | ||||
| 
 | ||||
|   REQUIRE(err == DeserializationError::Ok); | ||||
| } | ||||
| #endif | ||||
| @@ -1,29 +0,0 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("deserializeMsgPack(std::istream&)") { | ||||
|   DynamicJsonDocument doc; | ||||
|  | ||||
|   SECTION("should accept a zero in input") { | ||||
|     std::istringstream input(std::string("\x92\x00\x02", 3)); | ||||
|  | ||||
|     DeserializationError err = deserializeMsgPack(doc, input); | ||||
|  | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|     JsonArray arr = doc.as<JsonArray>(); | ||||
|     REQUIRE(arr[0] == 0); | ||||
|     REQUIRE(arr[1] == 2); | ||||
|   } | ||||
|  | ||||
|   SECTION("should detect incomplete input") { | ||||
|     std::istringstream input("\x92\x00\x02"); | ||||
|  | ||||
|     DeserializationError err = deserializeMsgPack(doc, input); | ||||
|  | ||||
|     REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|   } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user