mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Moved ancillary files to extras/ (fixes #1011)
				
					
				
			This commit is contained in:
		
							
								
								
									
										90
									
								
								extras/tests/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								extras/tests/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,90 @@ | ||||
| # ArduinoJson - arduinojson.org | ||||
| # Copyright Benoit Blanchon 2014-2019 | ||||
| # MIT License | ||||
|  | ||||
| add_subdirectory(catch) | ||||
|  | ||||
| if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)") | ||||
| 	add_compile_options( | ||||
| 		-pedantic | ||||
| 		-Wall | ||||
| 		-Wcast-align | ||||
| 		-Wcast-qual | ||||
| 		-Wconversion | ||||
| 		-Wctor-dtor-privacy | ||||
| 		-Wdisabled-optimization | ||||
| 		-Werror | ||||
| 		-Wextra | ||||
| 		-Wformat=2 | ||||
| 		-Winit-self | ||||
| 		-Wmissing-include-dirs | ||||
| 		-Wnon-virtual-dtor | ||||
| 		-Wold-style-cast | ||||
| 		-Woverloaded-virtual | ||||
| 		-Wparentheses | ||||
| 		-Wredundant-decls | ||||
| 		-Wshadow | ||||
| 		-Wsign-promo | ||||
| 		-Wstrict-aliasing | ||||
| 		-Wundef | ||||
| 	) | ||||
|  | ||||
| 	if(NOT MINGW) | ||||
| 		add_compile_options( | ||||
| 			-std=c++98 | ||||
| 		) | ||||
| 	endif() | ||||
| 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 | ||||
| 	endif() | ||||
|  | ||||
| 	if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.6) | ||||
| 		add_compile_options(-Wnoexcept) | ||||
| 	endif() | ||||
| endif() | ||||
|  | ||||
| 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() | ||||
|  | ||||
| if(MSVC) | ||||
| 	add_definitions(-D_CRT_SECURE_NO_WARNINGS) | ||||
| 	add_compile_options( | ||||
| 		/W4 # Set warning level | ||||
| 		/WX # Treats all compiler warnings as errors. | ||||
| 	) | ||||
| endif() | ||||
|  | ||||
| add_subdirectory(ElementProxy) | ||||
| add_subdirectory(IntegrationTests) | ||||
| add_subdirectory(JsonArray) | ||||
| add_subdirectory(JsonDeserializer) | ||||
| add_subdirectory(JsonDocument) | ||||
| add_subdirectory(JsonObject) | ||||
| add_subdirectory(JsonSerializer) | ||||
| add_subdirectory(JsonVariant) | ||||
| add_subdirectory(MemberProxy) | ||||
| add_subdirectory(MemoryPool) | ||||
| add_subdirectory(Misc) | ||||
| add_subdirectory(MixedConfiguration) | ||||
| add_subdirectory(MsgPackDeserializer) | ||||
| add_subdirectory(MsgPackSerializer) | ||||
| add_subdirectory(Numbers) | ||||
| add_subdirectory(TextFormatter) | ||||
							
								
								
									
										15
									
								
								extras/tests/ElementProxy/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								extras/tests/ElementProxy/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| # ArduinoJson - arduinojson.org | ||||
| # Copyright Benoit Blanchon 2014-2019 | ||||
| # MIT License | ||||
|  | ||||
| add_executable(ElementProxyTests | ||||
| 	add.cpp | ||||
| 	clear.cpp | ||||
| 	compare.cpp | ||||
| 	remove.cpp | ||||
| 	set.cpp | ||||
| 	size.cpp | ||||
| ) | ||||
|  | ||||
| target_link_libraries(ElementProxyTests catch) | ||||
| add_test(ElementProxy ElementProxyTests) | ||||
							
								
								
									
										26
									
								
								extras/tests/ElementProxy/add.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								extras/tests/ElementProxy/add.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ARDUINOJSON_NAMESPACE; | ||||
|  | ||||
| TEST_CASE("ElementProxy::add()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   doc.addElement(); | ||||
|   ElementProxy<JsonDocument&> ep = doc[0]; | ||||
|  | ||||
|   SECTION("add(int)") { | ||||
|     ep.add(42); | ||||
|  | ||||
|     REQUIRE(doc.as<std::string>() == "[[42]]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("add(const char*)") { | ||||
|     ep.add("world"); | ||||
|  | ||||
|     REQUIRE(doc.as<std::string>() == "[[\"world\"]]"); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										28
									
								
								extras/tests/ElementProxy/clear.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								extras/tests/ElementProxy/clear.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ARDUINOJSON_NAMESPACE; | ||||
|  | ||||
| TEST_CASE("ElementProxy::clear()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   doc.addElement(); | ||||
|   ElementProxy<JsonDocument&> ep = doc[0]; | ||||
|  | ||||
|   SECTION("size goes back to zero") { | ||||
|     ep.add(42); | ||||
|     ep.clear(); | ||||
|  | ||||
|     REQUIRE(ep.size() == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("isNull() return true") { | ||||
|     ep.add("hello"); | ||||
|     ep.clear(); | ||||
|  | ||||
|     REQUIRE(ep.isNull() == true); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										28
									
								
								extras/tests/ElementProxy/compare.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								extras/tests/ElementProxy/compare.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ARDUINOJSON_NAMESPACE; | ||||
|  | ||||
| TEST_CASE("ElementProxy::operator==()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("same value") { | ||||
|     doc.add(1); | ||||
|     doc.add(1); | ||||
|  | ||||
|     REQUIRE(doc[0] == doc[1]); | ||||
|     REQUIRE_FALSE(doc[0] != doc[1]); | ||||
|   } | ||||
|  | ||||
|   SECTION("different values") { | ||||
|     doc.add(1); | ||||
|     doc.add(2); | ||||
|  | ||||
|     REQUIRE_FALSE(doc[0] == doc[1]); | ||||
|     REQUIRE(doc[0] != doc[1]); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										56
									
								
								extras/tests/ElementProxy/remove.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								extras/tests/ElementProxy/remove.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ARDUINOJSON_NAMESPACE; | ||||
|  | ||||
| TEST_CASE("ElementProxy::remove()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   doc.addElement(); | ||||
|   ElementProxy<JsonDocument&> ep = doc[0]; | ||||
|  | ||||
|   SECTION("remove(int)") { | ||||
|     ep.add(1); | ||||
|     ep.add(2); | ||||
|     ep.add(3); | ||||
|  | ||||
|     ep.remove(1); | ||||
|  | ||||
|     REQUIRE(ep.as<std::string>() == "[1,3]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("remove(const char *)") { | ||||
|     ep["a"] = 1; | ||||
|     ep["b"] = 2; | ||||
|  | ||||
|     ep.remove("a"); | ||||
|  | ||||
|     REQUIRE(ep.as<std::string>() == "{\"b\":2}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("remove(std::string)") { | ||||
|     ep["a"] = 1; | ||||
|     ep["b"] = 2; | ||||
|  | ||||
|     ep.remove(std::string("b")); | ||||
|  | ||||
|     REQUIRE(ep.as<std::string>() == "{\"a\":1}"); | ||||
|   } | ||||
|  | ||||
| #ifdef HAS_VARIABLE_LENGTH_ARRAY | ||||
|   SECTION("remove(vla)") { | ||||
|     ep["a"] = 1; | ||||
|     ep["b"] = 2; | ||||
|  | ||||
|     int i = 4; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "b"); | ||||
|     ep.remove(vla); | ||||
|  | ||||
|     REQUIRE(ep.as<std::string>() == "{\"a\":1}"); | ||||
|   } | ||||
| #endif | ||||
| } | ||||
							
								
								
									
										26
									
								
								extras/tests/ElementProxy/set.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								extras/tests/ElementProxy/set.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ARDUINOJSON_NAMESPACE; | ||||
|  | ||||
| TEST_CASE("ElementProxy::set()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   doc.addElement(); | ||||
|   ElementProxy<JsonDocument&> ep = doc[0]; | ||||
|  | ||||
|   SECTION("set(int)") { | ||||
|     ep.set(42); | ||||
|  | ||||
|     REQUIRE(doc.as<std::string>() == "[42]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("set(const char*)") { | ||||
|     ep.set("world"); | ||||
|  | ||||
|     REQUIRE(doc.as<std::string>() == "[\"world\"]"); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										30
									
								
								extras/tests/ElementProxy/size.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								extras/tests/ElementProxy/size.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ARDUINOJSON_NAMESPACE; | ||||
|  | ||||
| TEST_CASE("ElementProxy::size()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   doc.addElement(); | ||||
|   ElementProxy<JsonDocument&> ep = doc[0]; | ||||
|  | ||||
|   SECTION("returns 0") { | ||||
|     REQUIRE(ep.size() == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("as an array, returns 2") { | ||||
|     ep.add(1); | ||||
|     ep.add(2); | ||||
|     REQUIRE(ep.size() == 2); | ||||
|   } | ||||
|  | ||||
|   SECTION("as an object, returns 2") { | ||||
|     ep["a"] = 1; | ||||
|     ep["b"] = 2; | ||||
|     REQUIRE(ep.size() == 2); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										19
									
								
								extras/tests/IntegrationTests/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								extras/tests/IntegrationTests/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| # ArduinoJson - arduinojson.org | ||||
| # Copyright Benoit Blanchon 2014-2019 | ||||
| # MIT License | ||||
|  | ||||
| add_executable(IntegrationTests | ||||
| 	gbathree.cpp | ||||
| 	issue772.cpp | ||||
| 	round_trip.cpp | ||||
| ) | ||||
|  | ||||
| if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") | ||||
| 	target_compile_options(IntegrationTests | ||||
| 		PUBLIC | ||||
| 		-fsingle-precision-constant # issue 544 | ||||
| 	) | ||||
| endif() | ||||
|  | ||||
| target_link_libraries(IntegrationTests catch) | ||||
| add_test(IntegrationTests IntegrationTests) | ||||
							
								
								
									
										210
									
								
								extras/tests/IntegrationTests/gbathree.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								extras/tests/IntegrationTests/gbathree.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,210 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("Gbathree") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   DeserializationError error = deserializeJson( | ||||
|       doc, | ||||
|       "{\"protocol_name\":\"fluorescence\",\"repeats\":1,\"wait\":0," | ||||
|       "\"averages\":1,\"measurements\":3,\"meas2_light\":15,\"meas1_" | ||||
|       "baseline\":0,\"act_light\":20,\"pulsesize\":25,\"pulsedistance\":" | ||||
|       "10000,\"actintensity1\":50,\"actintensity2\":255,\"measintensity\":" | ||||
|       "255,\"calintensity\":255,\"pulses\":[50,50,50],\"act\":[2,1,2,2]," | ||||
|       "\"red\":[2,2,2,2],\"detectors\":[[34,34,34,34],[34,34,34,34],[34," | ||||
|       "34,34,34],[34,34,34,34]],\"alta\":[2,2,2,2],\"altb\":[2,2,2,2]," | ||||
|       "\"measlights\":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15," | ||||
|       "15,15]],\"measlights2\":[[15,15,15,15],[15,15,15,15],[15,15,15,15]," | ||||
|       "[15,15,15,15]],\"altc\":[2,2,2,2],\"altd\":[2,2,2,2]}"); | ||||
|   JsonObject root = doc.as<JsonObject>(); | ||||
|  | ||||
|   SECTION("Success") { | ||||
|     REQUIRE(error == DeserializationError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("ProtocolName") { | ||||
|     REQUIRE("fluorescence" == root["protocol_name"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Repeats") { | ||||
|     REQUIRE(1 == root["repeats"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Wait") { | ||||
|     REQUIRE(0 == root["wait"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Measurements") { | ||||
|     REQUIRE(3 == root["measurements"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Meas2_Light") { | ||||
|     REQUIRE(15 == root["meas2_light"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Meas1_Baseline") { | ||||
|     REQUIRE(0 == root["meas1_baseline"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Act_Light") { | ||||
|     REQUIRE(20 == root["act_light"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Pulsesize") { | ||||
|     REQUIRE(25 == root["pulsesize"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Pulsedistance") { | ||||
|     REQUIRE(10000 == root["pulsedistance"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Actintensity1") { | ||||
|     REQUIRE(50 == root["actintensity1"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Actintensity2") { | ||||
|     REQUIRE(255 == root["actintensity2"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Measintensity") { | ||||
|     REQUIRE(255 == root["measintensity"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Calintensity") { | ||||
|     REQUIRE(255 == root["calintensity"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Pulses") { | ||||
|     // "pulses":[50,50,50] | ||||
|  | ||||
|     JsonArray array = root["pulses"]; | ||||
|     REQUIRE(array.isNull() == false); | ||||
|  | ||||
|     REQUIRE(3 == array.size()); | ||||
|  | ||||
|     for (size_t i = 0; i < 3; i++) { | ||||
|       REQUIRE(50 == array[i]); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Act") { | ||||
|     // "act":[2,1,2,2] | ||||
|  | ||||
|     JsonArray array = root["act"]; | ||||
|     REQUIRE(array.isNull() == false); | ||||
|  | ||||
|     REQUIRE(4 == array.size()); | ||||
|     REQUIRE(2 == array[0]); | ||||
|     REQUIRE(1 == array[1]); | ||||
|     REQUIRE(2 == array[2]); | ||||
|     REQUIRE(2 == array[3]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Detectors") { | ||||
|     // "detectors":[[34,34,34,34],[34,34,34,34],[34,34,34,34],[34,34,34,34]] | ||||
|  | ||||
|     JsonArray array = root["detectors"]; | ||||
|     REQUIRE(array.isNull() == false); | ||||
|     REQUIRE(4 == array.size()); | ||||
|  | ||||
|     for (size_t i = 0; i < 4; i++) { | ||||
|       JsonArray nestedArray = array[i]; | ||||
|       REQUIRE(4 == nestedArray.size()); | ||||
|  | ||||
|       for (size_t j = 0; j < 4; j++) { | ||||
|         REQUIRE(34 == nestedArray[j]); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Alta") { | ||||
|     // alta:[2,2,2,2] | ||||
|  | ||||
|     JsonArray array = root["alta"]; | ||||
|     REQUIRE(array.isNull() == false); | ||||
|  | ||||
|     REQUIRE(4 == array.size()); | ||||
|  | ||||
|     for (size_t i = 0; i < 4; i++) { | ||||
|       REQUIRE(2 == array[i]); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Altb") { | ||||
|     // altb:[2,2,2,2] | ||||
|  | ||||
|     JsonArray array = root["altb"]; | ||||
|     REQUIRE(array.isNull() == false); | ||||
|  | ||||
|     REQUIRE(4 == array.size()); | ||||
|  | ||||
|     for (size_t i = 0; i < 4; i++) { | ||||
|       REQUIRE(2 == array[i]); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Measlights") { | ||||
|     // "measlights":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]] | ||||
|  | ||||
|     JsonArray array = root["measlights"]; | ||||
|     REQUIRE(array.isNull() == false); | ||||
|     REQUIRE(4 == array.size()); | ||||
|  | ||||
|     for (size_t i = 0; i < 4; i++) { | ||||
|       JsonArray nestedArray = array[i]; | ||||
|  | ||||
|       REQUIRE(4 == nestedArray.size()); | ||||
|  | ||||
|       for (size_t j = 0; j < 4; j++) { | ||||
|         REQUIRE(15 == nestedArray[j]); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Measlights2") { | ||||
|     // "measlights2":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]] | ||||
|  | ||||
|     JsonArray array = root["measlights2"]; | ||||
|     REQUIRE(array.isNull() == false); | ||||
|     REQUIRE(4 == array.size()); | ||||
|  | ||||
|     for (size_t i = 0; i < 4; i++) { | ||||
|       JsonArray nestedArray = array[i]; | ||||
|       REQUIRE(4 == nestedArray.size()); | ||||
|  | ||||
|       for (size_t j = 0; j < 4; j++) { | ||||
|         REQUIRE(15 == nestedArray[j]); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Altc") { | ||||
|     // altc:[2,2,2,2] | ||||
|  | ||||
|     JsonArray array = root["altc"]; | ||||
|     REQUIRE(array.isNull() == false); | ||||
|  | ||||
|     REQUIRE(4 == array.size()); | ||||
|  | ||||
|     for (size_t i = 0; i < 4; i++) { | ||||
|       REQUIRE(2 == array[i]); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Altd") { | ||||
|     // altd:[2,2,2,2] | ||||
|  | ||||
|     JsonArray array = root["altd"]; | ||||
|     REQUIRE(array.isNull() == false); | ||||
|  | ||||
|     REQUIRE(4 == array.size()); | ||||
|  | ||||
|     for (size_t i = 0; i < 4; i++) { | ||||
|       REQUIRE(2 == array[i]); | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										28
									
								
								extras/tests/IntegrationTests/issue772.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								extras/tests/IntegrationTests/issue772.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| // https://github.com/bblanchon/ArduinoJson/issues/772 | ||||
|  | ||||
| TEST_CASE("Issue772") { | ||||
|   DynamicJsonDocument doc1(4096); | ||||
|   DynamicJsonDocument doc2(4096); | ||||
|   DeserializationError err; | ||||
|   std::string data = | ||||
|       "{\"state\":{\"reported\":{\"timestamp\":\"2018-07-02T09:40:12Z\"," | ||||
|       "\"mac\":\"2C3AE84FC076\",\"firmwareVersion\":\"v0.2.7-5-gf4d4d78\"," | ||||
|       "\"visibleLight\":261,\"infraRed\":255,\"ultraViolet\":0.02," | ||||
|       "\"Temperature\":26.63,\"Pressure\":101145.7,\"Humidity\":54.79883," | ||||
|       "\"Vbat\":4.171261,\"soilMoisture\":0,\"ActB\":0}}}"; | ||||
|   err = deserializeJson(doc1, data); | ||||
|   REQUIRE(err == DeserializationError::Ok); | ||||
|  | ||||
|   data = ""; | ||||
|   serializeMsgPack(doc1, data); | ||||
|   err = deserializeMsgPack(doc2, data); | ||||
|  | ||||
|   REQUIRE(err == DeserializationError::Ok); | ||||
| } | ||||
							
								
								
									
										82
									
								
								extras/tests/IntegrationTests/round_trip.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								extras/tests/IntegrationTests/round_trip.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| void check(std::string originalJson) { | ||||
|   DynamicJsonDocument doc(16384); | ||||
|  | ||||
|   std::string prettyJson; | ||||
|   deserializeJson(doc, originalJson); | ||||
|   serializeJsonPretty(doc, prettyJson); | ||||
|  | ||||
|   std::string finalJson; | ||||
|   deserializeJson(doc, originalJson); | ||||
|   serializeJson(doc, finalJson); | ||||
|  | ||||
|   REQUIRE(originalJson == finalJson); | ||||
| } | ||||
|  | ||||
| TEST_CASE("Round Trip: parse -> prettyPrint -> parse -> print") { | ||||
|   SECTION("OpenWeatherMap") { | ||||
|     check( | ||||
|         "{\"coord\":{\"lon\":145.77,\"lat\":-16.92},\"sys\":{\"type\":1,\"id\":" | ||||
|         "8166,\"message\":0.1222,\"country\":\"AU\",\"sunrise\":1414784325," | ||||
|         "\"sunset\":1414830137},\"weather\":[{\"id\":801,\"main\":\"Clouds\"," | ||||
|         "\"description\":\"few clouds\",\"icon\":\"02n\"}],\"base\":\"cmc " | ||||
|         "stations\",\"main\":{\"temp\":296.15,\"pressure\":1014,\"humidity\":" | ||||
|         "83,\"temp_min\":296.15,\"temp_max\":296.15},\"wind\":{\"speed\":2.22," | ||||
|         "\"deg\":114.501},\"clouds\":{\"all\":20},\"dt\":1414846800,\"id\":" | ||||
|         "2172797,\"name\":\"Cairns\",\"cod\":200}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("YahooQueryLanguage") { | ||||
|     check( | ||||
|         "{\"query\":{\"count\":40,\"created\":\"2014-11-01T14:16:49Z\"," | ||||
|         "\"lang\":\"fr-FR\",\"results\":{\"item\":[{\"title\":\"Burkina army " | ||||
|         "backs Zida as interim leader\"},{\"title\":\"British jets intercept " | ||||
|         "Russian bombers\"},{\"title\":\"Doubts chip away at nation's most " | ||||
|         "trusted agencies\"},{\"title\":\"Cruise ship stuck off Norway, no " | ||||
|         "damage\"},{\"title\":\"U.S. military launches 10 air strikes in " | ||||
|         "Syria, Iraq\"},{\"title\":\"Blackout hits Bangladesh as line from " | ||||
|         "India fails\"},{\"title\":\"Burkina Faso president in Ivory Coast " | ||||
|         "after ouster\"},{\"title\":\"Kurds in Turkey rally to back city " | ||||
|         "besieged by IS\"},{\"title\":\"A majority of Scots would vote for " | ||||
|         "independence now:poll\"},{\"title\":\"Tunisia elections possible " | ||||
|         "model for region\"},{\"title\":\"Islamic State kills 85 more members " | ||||
|         "of Iraqi tribe\"},{\"title\":\"Iraqi officials:IS extremists line " | ||||
|         "up, kill 50\"},{\"title\":\"Burkina Faso army backs presidential " | ||||
|         "guard official to lead transition\"},{\"title\":\"Kurdish peshmerga " | ||||
|         "arrive with weapons in Syria's Kobani\"},{\"title\":\"Driver sought " | ||||
|         "in crash that killed 3 on Halloween\"},{\"title\":\"Ex-Marine arrives " | ||||
|         "in US after release from Mexico jail\"},{\"title\":\"UN panel " | ||||
|         "scrambling to finish climate report\"},{\"title\":\"Investigators, " | ||||
|         "Branson go to spacecraft crash site\"},{\"title\":\"Soldiers vie for " | ||||
|         "power after Burkina Faso president quits\"},{\"title\":\"For a man " | ||||
|         "without a party, turnout is big test\"},{\"title\":\"'We just had a " | ||||
|         "hunch':US marshals nab Eric Frein\"},{\"title\":\"Boko Haram leader " | ||||
|         "threatens to kill German hostage\"},{\"title\":\"Nurse free to move " | ||||
|         "about as restrictions eased\"},{\"title\":\"Former Burkina president " | ||||
|         "Compaore arrives in Ivory Coast:sources\"},{\"title\":\"Libyan port " | ||||
|         "rebel leader refuses to hand over oil ports to rival " | ||||
|         "group\"},{\"title\":\"Iraqi peshmerga fighters prepare for Syria " | ||||
|         "battle\"},{\"title\":\"1 Dem Senate candidate welcoming Obama's " | ||||
|         "help\"},{\"title\":\"Bikers cancel party after police recover " | ||||
|         "bar\"},{\"title\":\"New question in Texas:Can Davis survive " | ||||
|         "defeat?\"},{\"title\":\"Ukraine rebels to hold election, despite " | ||||
|         "criticism\"},{\"title\":\"Iraqi officials say Islamic State group " | ||||
|         "lines up, kills 50 tribesmen, women in Anbar " | ||||
|         "province\"},{\"title\":\"James rebounds, leads Cavaliers past " | ||||
|         "Bulls\"},{\"title\":\"UK warns travelers they could be terror " | ||||
|         "targets\"},{\"title\":\"Hello Kitty celebrates 40th " | ||||
|         "birthday\"},{\"title\":\"A look at people killed during space " | ||||
|         "missions\"},{\"title\":\"Nigeria's purported Boko Haram leader says " | ||||
|         "has 'married off' girls:AFP\"},{\"title\":\"Mexico orders immediate " | ||||
|         "release of Marine veteran\"},{\"title\":\"As election closes in, " | ||||
|         "Obama on center stage\"},{\"title\":\"Body of Zambian president " | ||||
|         "arrives home\"},{\"title\":\"South Africa arrests 2 Vietnamese for " | ||||
|         "poaching\"}]}}}"); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										23
									
								
								extras/tests/JsonArray/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								extras/tests/JsonArray/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| # ArduinoJson - arduinojson.org | ||||
| # Copyright Benoit Blanchon 2014-2019 | ||||
| # MIT License | ||||
|  | ||||
| add_executable(JsonArrayTests  | ||||
| 	add.cpp | ||||
| 	copyArray.cpp | ||||
| 	createNested.cpp | ||||
| 	equals.cpp | ||||
| 	get.cpp | ||||
| 	isNull.cpp | ||||
| 	iterator.cpp | ||||
| 	memoryUsage.cpp | ||||
| 	nesting.cpp | ||||
| 	remove.cpp | ||||
| 	size.cpp | ||||
| 	std_string.cpp | ||||
| 	subscript.cpp | ||||
| 	undefined.cpp | ||||
| ) | ||||
|  | ||||
| target_link_libraries(JsonArrayTests catch) | ||||
| add_test(JsonArray JsonArrayTests) | ||||
							
								
								
									
										138
									
								
								extras/tests/JsonArray/add.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								extras/tests/JsonArray/add.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,138 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonArray::add()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   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>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("double") { | ||||
|     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>()); | ||||
|   } | ||||
|  | ||||
|   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>()); | ||||
|   } | ||||
|  | ||||
| #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(4096); | ||||
|     JsonArray arr = doc2.to<JsonArray>(); | ||||
|  | ||||
|     array.add(arr); | ||||
|  | ||||
|     REQUIRE(arr == array[0].as<JsonArray>()); | ||||
|     REQUIRE(array[0].is<JsonArray>()); | ||||
|     REQUIRE_FALSE(array[0].is<int>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("nested object") { | ||||
|     DynamicJsonDocument doc2(4096); | ||||
|     JsonObject obj = doc2.to<JsonObject>(); | ||||
|  | ||||
|     array.add(obj); | ||||
|  | ||||
|     REQUIRE(obj == array[0].as<JsonObject>()); | ||||
|     REQUIRE(array[0].is<JsonObject>()); | ||||
|     REQUIRE_FALSE(array[0].is<int>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("array subscript") { | ||||
|     const char* str = "hello"; | ||||
|     DynamicJsonDocument doc2(4096); | ||||
|     JsonArray arr = doc2.to<JsonArray>(); | ||||
|     arr.add(str); | ||||
|  | ||||
|     array.add(arr[0]); | ||||
|  | ||||
|     REQUIRE(str == array[0]); | ||||
|   } | ||||
|  | ||||
|   SECTION("object subscript") { | ||||
|     const char* str = "hello"; | ||||
|     DynamicJsonDocument doc2(4096); | ||||
|     JsonObject obj = doc2.to<JsonObject>(); | ||||
|     obj["x"] = str; | ||||
|  | ||||
|     array.add(obj["x"]); | ||||
|  | ||||
|     REQUIRE(str == array[0]); | ||||
|   } | ||||
|  | ||||
|   SECTION("should not duplicate const char*") { | ||||
|     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")); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(6); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string") { | ||||
|     array.add(std::string("world")); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(6); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should not duplicate serialized(const char*)") { | ||||
|     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*>("{}"))); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(2); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate serialized(std::string)") { | ||||
|     array.add(serialized(std::string("{}"))); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(2); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate serialized(std::string)") { | ||||
|     array.add(serialized(std::string("\0XX", 3))); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(3); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										117
									
								
								extras/tests/JsonArray/copyArray.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								extras/tests/JsonArray/copyArray.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,117 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("copyArray()") { | ||||
|   SECTION("1D -> JsonArray") { | ||||
|     DynamicJsonDocument doc(4096); | ||||
|     JsonArray array = doc.to<JsonArray>(); | ||||
|     char json[32]; | ||||
|     int source[] = {1, 2, 3}; | ||||
|  | ||||
|     bool ok = copyArray(source, array); | ||||
|     REQUIRE(ok); | ||||
|  | ||||
|     serializeJson(array, json, sizeof(json)); | ||||
|     REQUIRE(std::string("[1,2,3]") == json); | ||||
|   } | ||||
|  | ||||
|   SECTION("1D -> JsonArray, but not enough memory") { | ||||
|     const size_t SIZE = JSON_ARRAY_SIZE(2); | ||||
|     StaticJsonDocument<SIZE> doc; | ||||
|     JsonArray array = doc.to<JsonArray>(); | ||||
|     char json[32]; | ||||
|     int source[] = {1, 2, 3}; | ||||
|  | ||||
|     bool ok = copyArray(source, array); | ||||
|     REQUIRE_FALSE(ok); | ||||
|  | ||||
|     serializeJson(array, json, sizeof(json)); | ||||
|     REQUIRE(std::string("[1,2]") == json); | ||||
|   } | ||||
|  | ||||
|   SECTION("2D -> JsonArray") { | ||||
|     DynamicJsonDocument doc(4096); | ||||
|     JsonArray array = doc.to<JsonArray>(); | ||||
|     char json[32]; | ||||
|     int source[][3] = {{1, 2, 3}, {4, 5, 6}}; | ||||
|  | ||||
|     bool ok = copyArray(source, array); | ||||
|     REQUIRE(ok); | ||||
|  | ||||
|     serializeJson(array, json, sizeof(json)); | ||||
|     REQUIRE(std::string("[[1,2,3],[4,5,6]]") == json); | ||||
|   } | ||||
|  | ||||
|   SECTION("2D -> JsonArray, but not enough memory") { | ||||
|     const size_t SIZE = | ||||
|         JSON_ARRAY_SIZE(2) + JSON_ARRAY_SIZE(3) + JSON_ARRAY_SIZE(2); | ||||
|     StaticJsonDocument<SIZE> doc; | ||||
|     JsonArray array = doc.to<JsonArray>(); | ||||
|     char json[32] = ""; | ||||
|     int source[][3] = {{1, 2, 3}, {4, 5, 6}}; | ||||
|  | ||||
|     CAPTURE(SIZE) | ||||
|  | ||||
|     bool ok = copyArray(source, array); | ||||
|     CAPTURE(doc.memoryUsage()); | ||||
|     CHECK_FALSE(ok); | ||||
|  | ||||
|     serializeJson(array, json, sizeof(json)); | ||||
|     REQUIRE(std::string("[[1,2,3],[4,5]]") == json); | ||||
|   } | ||||
|  | ||||
|   SECTION("JsonArray -> 1D, with more space than needed") { | ||||
|     DynamicJsonDocument doc(4096); | ||||
|     char json[] = "[1,2,3]"; | ||||
|     DeserializationError err = deserializeJson(doc, json); | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|     JsonArray array = doc.as<JsonArray>(); | ||||
|  | ||||
|     int destination[4] = {0}; | ||||
|     size_t result = copyArray(array, destination); | ||||
|  | ||||
|     REQUIRE(3 == result); | ||||
|     REQUIRE(1 == destination[0]); | ||||
|     REQUIRE(2 == destination[1]); | ||||
|     REQUIRE(3 == destination[2]); | ||||
|     REQUIRE(0 == destination[3]); | ||||
|   } | ||||
|  | ||||
|   SECTION("JsonArray -> 1D, without enough space") { | ||||
|     DynamicJsonDocument doc(4096); | ||||
|     char json[] = "[1,2,3]"; | ||||
|     DeserializationError err = deserializeJson(doc, json); | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|     JsonArray array = doc.as<JsonArray>(); | ||||
|  | ||||
|     int destination[2] = {0}; | ||||
|     size_t result = copyArray(array, destination); | ||||
|  | ||||
|     REQUIRE(2 == result); | ||||
|     REQUIRE(1 == destination[0]); | ||||
|     REQUIRE(2 == destination[1]); | ||||
|   } | ||||
|  | ||||
|   SECTION("JsonArray -> 2D") { | ||||
|     DynamicJsonDocument doc(4096); | ||||
|     char json[] = "[[1,2],[3],[4]]"; | ||||
|  | ||||
|     DeserializationError err = deserializeJson(doc, json); | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|     JsonArray array = doc.as<JsonArray>(); | ||||
|  | ||||
|     int destination[3][2] = {{0}}; | ||||
|     copyArray(array, destination); | ||||
|  | ||||
|     REQUIRE(1 == destination[0][0]); | ||||
|     REQUIRE(2 == destination[0][1]); | ||||
|     REQUIRE(3 == destination[1][0]); | ||||
|     REQUIRE(0 == destination[1][1]); | ||||
|     REQUIRE(4 == destination[2][0]); | ||||
|     REQUIRE(0 == destination[2][1]); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										21
									
								
								extras/tests/JsonArray/createNested.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								extras/tests/JsonArray/createNested.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonArray basics") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonArray array = doc.to<JsonArray>(); | ||||
|  | ||||
|   SECTION("CreateNestedArray") { | ||||
|     JsonArray arr = array.createNestedArray(); | ||||
|     REQUIRE(arr == array[0].as<JsonArray>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("CreateNestedObject") { | ||||
|     JsonObject obj = array.createNestedObject(); | ||||
|     REQUIRE(obj == array[0].as<JsonObject>()); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										50
									
								
								extras/tests/JsonArray/equals.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								extras/tests/JsonArray/equals.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonArray::operator==()") { | ||||
|   DynamicJsonDocument doc1(4096); | ||||
|   JsonArray array1 = doc1.to<JsonArray>(); | ||||
|   JsonArrayConst array1c = array1; | ||||
|  | ||||
|   DynamicJsonDocument doc2(4096); | ||||
|   JsonArray array2 = doc2.to<JsonArray>(); | ||||
|   JsonArrayConst array2c = array2; | ||||
|  | ||||
|   SECTION("should return false when arrays differ") { | ||||
|     array1.add("coucou"); | ||||
|     array2.add(1); | ||||
|  | ||||
|     REQUIRE_FALSE(array1 == array2); | ||||
|     REQUIRE_FALSE(array1c == array2c); | ||||
|   } | ||||
|  | ||||
|   SECTION("should return false when LHS has more elements") { | ||||
|     array1.add(1); | ||||
|     array1.add(2); | ||||
|     array2.add(1); | ||||
|  | ||||
|     REQUIRE_FALSE(array1 == array2); | ||||
|     REQUIRE_FALSE(array1c == array2c); | ||||
|   } | ||||
|  | ||||
|   SECTION("should return false when RKS has more elements") { | ||||
|     array1.add(1); | ||||
|     array2.add(1); | ||||
|     array2.add(2); | ||||
|  | ||||
|     REQUIRE_FALSE(array1 == array2); | ||||
|     REQUIRE_FALSE(array1c == array2c); | ||||
|   } | ||||
|  | ||||
|   SECTION("should return true when arrays equal") { | ||||
|     array1.add("coucou"); | ||||
|     array2.add("coucou"); | ||||
|  | ||||
|     REQUIRE(array1 == array2); | ||||
|     REQUIRE(array1c == array2c); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										16
									
								
								extras/tests/JsonArray/get.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								extras/tests/JsonArray/get.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonArray::get()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   deserializeJson(doc, "[1,2,3]"); | ||||
|   JsonArray array = doc.as<JsonArray>(); | ||||
|  | ||||
|   SECTION("Overflow") { | ||||
|     REQUIRE(array.getElement(3).isNull()); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										34
									
								
								extras/tests/JsonArray/isNull.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								extras/tests/JsonArray/isNull.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonArray::isNull()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("returns true") { | ||||
|     JsonArray arr; | ||||
|     REQUIRE(arr.isNull() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns false") { | ||||
|     JsonArray arr = doc.to<JsonArray>(); | ||||
|     REQUIRE(arr.isNull() == false); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonArrayConst::isNull()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("returns true") { | ||||
|     JsonArrayConst arr; | ||||
|     REQUIRE(arr.isNull() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns false") { | ||||
|     JsonArrayConst arr = doc.to<JsonArray>(); | ||||
|     REQUIRE(arr.isNull() == false); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										36
									
								
								extras/tests/JsonArray/iterator.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								extras/tests/JsonArray/iterator.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| template <typename TArray> | ||||
| static void run_iterator_test() { | ||||
|   StaticJsonDocument<JSON_ARRAY_SIZE(2)> doc; | ||||
|   JsonArray tmp = doc.to<JsonArray>(); | ||||
|   tmp.add(12); | ||||
|   tmp.add(34); | ||||
|  | ||||
|   TArray array = tmp; | ||||
|   typename TArray::iterator it = array.begin(); | ||||
|   typename TArray::iterator end = array.end(); | ||||
|  | ||||
|   REQUIRE(end != it); | ||||
|   REQUIRE(12 == it->template as<int>()); | ||||
|   REQUIRE(12 == static_cast<int>(*it)); | ||||
|   ++it; | ||||
|   REQUIRE(end != it); | ||||
|   REQUIRE(34 == it->template as<int>()); | ||||
|   REQUIRE(34 == static_cast<int>(*it)); | ||||
|   ++it; | ||||
|   REQUIRE(end == it); | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonArray::begin()/end()") { | ||||
|   run_iterator_test<JsonArray>(); | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonArrayConst::begin()/end()") { | ||||
|   run_iterator_test<JsonArrayConst>(); | ||||
| } | ||||
							
								
								
									
										42
									
								
								extras/tests/JsonArray/memoryUsage.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								extras/tests/JsonArray/memoryUsage.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonArray::memoryUsage()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonArray arr = doc.to<JsonArray>(); | ||||
|  | ||||
|   SECTION("return 0 if uninitialized") { | ||||
|     JsonArray unitialized; | ||||
|     REQUIRE(unitialized.memoryUsage() == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("JSON_ARRAY_SIZE(0) if empty") { | ||||
|     REQUIRE(arr.memoryUsage() == JSON_ARRAY_SIZE(0)); | ||||
|   } | ||||
|  | ||||
|   SECTION("JSON_ARRAY_SIZE(1) after add") { | ||||
|     arr.add("hello"); | ||||
|     REQUIRE(arr.memoryUsage() == JSON_ARRAY_SIZE(1)); | ||||
|   } | ||||
|  | ||||
|   SECTION("includes the size of the string") { | ||||
|     arr.add(std::string("hello")); | ||||
|     REQUIRE(arr.memoryUsage() == JSON_ARRAY_SIZE(1) + 6); | ||||
|   } | ||||
|  | ||||
|   SECTION("includes the size of the nested array") { | ||||
|     JsonArray nested = arr.createNestedArray(); | ||||
|     nested.add(42); | ||||
|     REQUIRE(arr.memoryUsage() == 2 * JSON_ARRAY_SIZE(1)); | ||||
|   } | ||||
|  | ||||
|   SECTION("includes the size of the nested arrect") { | ||||
|     JsonObject nested = arr.createNestedObject(); | ||||
|     nested["hello"] = "world"; | ||||
|     REQUIRE(arr.memoryUsage() == JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(1)); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										35
									
								
								extras/tests/JsonArray/nesting.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								extras/tests/JsonArray/nesting.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonArray::nesting()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonArray arr = doc.to<JsonArray>(); | ||||
|  | ||||
|   SECTION("return 0 if uninitialized") { | ||||
|     JsonArray unitialized; | ||||
|     REQUIRE(unitialized.nesting() == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns 1 for empty array") { | ||||
|     REQUIRE(arr.nesting() == 1); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns 1 for flat array") { | ||||
|     arr.add("hello"); | ||||
|     REQUIRE(arr.nesting() == 1); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns 2 with nested array") { | ||||
|     arr.createNestedArray(); | ||||
|     REQUIRE(arr.nesting() == 2); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns 2 with nested object") { | ||||
|     arr.createNestedObject(); | ||||
|     REQUIRE(arr.nesting() == 2); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										68
									
								
								extras/tests/JsonArray/remove.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								extras/tests/JsonArray/remove.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonArray::remove()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonArray _array = doc.to<JsonArray>(); | ||||
|   _array.add(1); | ||||
|   _array.add(2); | ||||
|   _array.add(3); | ||||
|  | ||||
|   SECTION("RemoveFirstByIndex") { | ||||
|     _array.remove(0); | ||||
|  | ||||
|     REQUIRE(2 == _array.size()); | ||||
|     REQUIRE(_array[0] == 2); | ||||
|     REQUIRE(_array[1] == 3); | ||||
|   } | ||||
|  | ||||
|   SECTION("RemoveMiddleByIndex") { | ||||
|     _array.remove(1); | ||||
|  | ||||
|     REQUIRE(2 == _array.size()); | ||||
|     REQUIRE(_array[0] == 1); | ||||
|     REQUIRE(_array[1] == 3); | ||||
|   } | ||||
|  | ||||
|   SECTION("RemoveLastByIndex") { | ||||
|     _array.remove(2); | ||||
|  | ||||
|     REQUIRE(2 == _array.size()); | ||||
|     REQUIRE(_array[0] == 1); | ||||
|     REQUIRE(_array[1] == 2); | ||||
|   } | ||||
|  | ||||
|   SECTION("RemoveFirstByIterator") { | ||||
|     JsonArray::iterator it = _array.begin(); | ||||
|     _array.remove(it); | ||||
|  | ||||
|     REQUIRE(2 == _array.size()); | ||||
|     REQUIRE(_array[0] == 2); | ||||
|     REQUIRE(_array[1] == 3); | ||||
|   } | ||||
|  | ||||
|   SECTION("RemoveMiddleByIterator") { | ||||
|     JsonArray::iterator it = _array.begin(); | ||||
|     ++it; | ||||
|     _array.remove(it); | ||||
|  | ||||
|     REQUIRE(2 == _array.size()); | ||||
|     REQUIRE(_array[0] == 1); | ||||
|     REQUIRE(_array[1] == 3); | ||||
|   } | ||||
|  | ||||
|   SECTION("RemoveLastByIterator") { | ||||
|     JsonArray::iterator it = _array.begin(); | ||||
|     ++it; | ||||
|     ++it; | ||||
|     _array.remove(it); | ||||
|  | ||||
|     REQUIRE(2 == _array.size()); | ||||
|     REQUIRE(_array[0] == 1); | ||||
|     REQUIRE(_array[1] == 2); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										31
									
								
								extras/tests/JsonArray/size.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								extras/tests/JsonArray/size.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonArray::size()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonArray array = doc.to<JsonArray>(); | ||||
|  | ||||
|   SECTION("returns 0 is empty") { | ||||
|     REQUIRE(0U == array.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("increases after add()") { | ||||
|     array.add("hello"); | ||||
|     REQUIRE(1U == array.size()); | ||||
|  | ||||
|     array.add("world"); | ||||
|     REQUIRE(2U == array.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("remains the same after replacing an element") { | ||||
|     array.add("hello"); | ||||
|     REQUIRE(1U == array.size()); | ||||
|  | ||||
|     array[0] = "hello"; | ||||
|     REQUIRE(1U == array.size()); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										31
									
								
								extras/tests/JsonArray/std_string.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								extras/tests/JsonArray/std_string.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| static void eraseString(std::string &str) { | ||||
|   char *p = const_cast<char *>(str.c_str()); | ||||
|   while (*p) *p++ = '*'; | ||||
| } | ||||
|  | ||||
| TEST_CASE("std::string") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonArray array = doc.to<JsonArray>(); | ||||
|  | ||||
|   SECTION("add()") { | ||||
|     std::string value("hello"); | ||||
|     array.add(value); | ||||
|     eraseString(value); | ||||
|     REQUIRE(std::string("hello") == array[0]); | ||||
|   } | ||||
|  | ||||
|   SECTION("operator[]") { | ||||
|     std::string value("world"); | ||||
|     array.add("hello"); | ||||
|     array[0] = value; | ||||
|     eraseString(value); | ||||
|     REQUIRE(std::string("world") == array[0]); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										162
									
								
								extras/tests/JsonArray/subscript.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								extras/tests/JsonArray/subscript.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,162 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <stdint.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonArray::operator[]") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   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>()); | ||||
|   } | ||||
|  | ||||
| #if ARDUINOJSON_USE_LONG_LONG | ||||
|   SECTION("long long") { | ||||
|     array[0] = 9223372036854775807; | ||||
|     REQUIRE(9223372036854775807 == array[0].as<int64_t>()); | ||||
|     REQUIRE(true == array[0].is<int64_t>()); | ||||
|     REQUIRE(false == array[0].is<int32_t>()); | ||||
|     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>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("bool") { | ||||
|     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>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("nested array") { | ||||
|     DynamicJsonDocument doc2(4096); | ||||
|     JsonArray arr2 = doc2.to<JsonArray>(); | ||||
|  | ||||
|     array[0] = arr2; | ||||
|  | ||||
|     REQUIRE(arr2 == array[0].as<JsonArray>()); | ||||
|     REQUIRE(true == array[0].is<JsonArray>()); | ||||
|     REQUIRE(false == array[0].is<int>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("nested object") { | ||||
|     DynamicJsonDocument doc2(4096); | ||||
|     JsonObject obj = doc2.to<JsonObject>(); | ||||
|  | ||||
|     array[0] = obj; | ||||
|  | ||||
|     REQUIRE(obj == array[0].as<JsonObject>()); | ||||
|     REQUIRE(true == array[0].is<JsonObject>()); | ||||
|     REQUIRE(false == array[0].is<int>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("array subscript") { | ||||
|     DynamicJsonDocument doc2(4096); | ||||
|     JsonArray arr2 = doc2.to<JsonArray>(); | ||||
|     const char* str = "hello"; | ||||
|  | ||||
|     arr2.add(str); | ||||
|  | ||||
|     array[0] = arr2[0]; | ||||
|  | ||||
|     REQUIRE(str == array[0]); | ||||
|   } | ||||
|  | ||||
|   SECTION("object subscript") { | ||||
|     const char* str = "hello"; | ||||
|     DynamicJsonDocument doc2(4096); | ||||
|     JsonObject obj = doc2.to<JsonObject>(); | ||||
|  | ||||
|     obj["x"] = str; | ||||
|  | ||||
|     array[0] = obj["x"]; | ||||
|  | ||||
|     REQUIRE(str == array[0]); | ||||
|   } | ||||
|  | ||||
|   SECTION("should not duplicate const char*") { | ||||
|     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"); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(6); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string") { | ||||
|     array[0] = std::string("world"); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(6); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("array[0].to<JsonObject>()") { | ||||
|     JsonObject obj = array[0].to<JsonObject>(); | ||||
|     REQUIRE(obj.isNull() == false); | ||||
|   } | ||||
|  | ||||
| #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 | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonArrayConst::operator[]") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonArray array = doc.to<JsonArray>(); | ||||
|   array.add(0); | ||||
|  | ||||
|   SECTION("int") { | ||||
|     array[0] = 123; | ||||
|     JsonArrayConst carr = array; | ||||
|  | ||||
|     REQUIRE(123 == carr[0].as<int>()); | ||||
|     REQUIRE(true == carr[0].is<int>()); | ||||
|     REQUIRE(false == carr[0].is<bool>()); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										35
									
								
								extras/tests/JsonArray/undefined.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								extras/tests/JsonArray/undefined.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace Catch::Matchers; | ||||
|  | ||||
| TEST_CASE("Undefined JsonArray") { | ||||
|   JsonArray array; | ||||
|  | ||||
|   SECTION("SubscriptFails") { | ||||
|     REQUIRE(array[0].isNull()); | ||||
|   } | ||||
|  | ||||
|   SECTION("AddFails") { | ||||
|     array.add(1); | ||||
|     REQUIRE(0 == array.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("CreateNestedArrayFails") { | ||||
|     REQUIRE(array.createNestedArray().isNull()); | ||||
|   } | ||||
|  | ||||
|   SECTION("CreateNestedObjectFails") { | ||||
|     REQUIRE(array.createNestedObject().isNull()); | ||||
|   } | ||||
|  | ||||
|   SECTION("PrintToWritesBrackets") { | ||||
|     char buffer[32]; | ||||
|     serializeJson(array, buffer, sizeof(buffer)); | ||||
|     REQUIRE_THAT(buffer, Equals("null")); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										21
									
								
								extras/tests/JsonDeserializer/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								extras/tests/JsonDeserializer/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| # ArduinoJson - arduinojson.org | ||||
| # Copyright Benoit Blanchon 2014-2019 | ||||
| # MIT License | ||||
|  | ||||
| add_executable(JsonDeserializerTests | ||||
| 	array.cpp | ||||
| 	array_static.cpp | ||||
| 	DeserializationError.cpp | ||||
| 	incomplete_input.cpp | ||||
| 	input_types.cpp | ||||
| 	number.cpp | ||||
| 	invalid_input.cpp | ||||
| 	misc.cpp | ||||
| 	nestingLimit.cpp | ||||
| 	object.cpp | ||||
| 	object_static.cpp | ||||
| 	string.cpp | ||||
| ) | ||||
|  | ||||
| target_link_libraries(JsonDeserializerTests catch) | ||||
| add_test(JsonDeserializer JsonDeserializerTests) | ||||
							
								
								
									
										137
									
								
								extras/tests/JsonDeserializer/DeserializationError.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								extras/tests/JsonDeserializer/DeserializationError.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,137 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| void testStringification(DeserializationError error, std::string expected) { | ||||
|   REQUIRE(error.c_str() == expected); | ||||
| } | ||||
|  | ||||
| void testBoolification(DeserializationError error, bool expected) { | ||||
|   // DeserializationError on left-hand side | ||||
|   CHECK(error == expected); | ||||
|   CHECK(error != !expected); | ||||
|   CHECK(!error == !expected); | ||||
|  | ||||
|   // DeserializationError on right-hand side | ||||
|   CHECK(expected == error); | ||||
|   CHECK(!expected != error); | ||||
|   CHECK(!expected == !error); | ||||
| } | ||||
|  | ||||
| #define TEST_STRINGIFICATION(symbol) \ | ||||
|   testStringification(DeserializationError::symbol, #symbol) | ||||
|  | ||||
| #define TEST_BOOLIFICATION(symbol, expected) \ | ||||
|   testBoolification(DeserializationError::symbol, expected) | ||||
|  | ||||
| TEST_CASE("DeserializationError") { | ||||
|   SECTION("c_str()") { | ||||
|     TEST_STRINGIFICATION(Ok); | ||||
|     TEST_STRINGIFICATION(TooDeep); | ||||
|     TEST_STRINGIFICATION(NoMemory); | ||||
|     TEST_STRINGIFICATION(InvalidInput); | ||||
|     TEST_STRINGIFICATION(IncompleteInput); | ||||
|     TEST_STRINGIFICATION(NotSupported); | ||||
|   } | ||||
|  | ||||
|   SECTION("as boolean") { | ||||
|     TEST_BOOLIFICATION(Ok, false); | ||||
|     TEST_BOOLIFICATION(TooDeep, true); | ||||
|     TEST_BOOLIFICATION(NoMemory, true); | ||||
|     TEST_BOOLIFICATION(InvalidInput, true); | ||||
|     TEST_BOOLIFICATION(IncompleteInput, true); | ||||
|     TEST_BOOLIFICATION(NotSupported, true); | ||||
|   } | ||||
|  | ||||
|   SECTION("ostream DeserializationError") { | ||||
|     std::stringstream s; | ||||
|     s << DeserializationError(DeserializationError::InvalidInput); | ||||
|     REQUIRE(s.str() == "InvalidInput"); | ||||
|   } | ||||
|  | ||||
|   SECTION("ostream DeserializationError::Code") { | ||||
|     std::stringstream s; | ||||
|     s << DeserializationError::InvalidInput; | ||||
|     REQUIRE(s.str() == "InvalidInput"); | ||||
|   } | ||||
|  | ||||
|   SECTION("out of range") { | ||||
|     int code = 666; | ||||
|     DeserializationError err( | ||||
|         *reinterpret_cast<DeserializationError::Code*>(&code)); | ||||
|     REQUIRE(err.c_str() == std::string("???")); | ||||
|   } | ||||
|  | ||||
|   SECTION("switch") { | ||||
|     DeserializationError err = DeserializationError::InvalidInput; | ||||
|     switch (err.code()) { | ||||
|       case DeserializationError::InvalidInput: | ||||
|         SUCCEED(); | ||||
|         break; | ||||
|       default: | ||||
|         FAIL(); | ||||
|         break; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Comparisons") { | ||||
|     DeserializationError invalidInput(DeserializationError::InvalidInput); | ||||
|     DeserializationError ok(DeserializationError::Ok); | ||||
|  | ||||
|     SECTION("DeserializationError == bool") { | ||||
|       REQUIRE(invalidInput == true); | ||||
|       REQUIRE(ok == false); | ||||
|     } | ||||
|  | ||||
|     SECTION("bool == DeserializationError") { | ||||
|       REQUIRE(true == invalidInput); | ||||
|       REQUIRE(false == ok); | ||||
|     } | ||||
|  | ||||
|     SECTION("DeserializationError != bool") { | ||||
|       REQUIRE(invalidInput != false); | ||||
|       REQUIRE(ok != true); | ||||
|     } | ||||
|  | ||||
|     SECTION("bool != DeserializationError") { | ||||
|       REQUIRE(false != invalidInput); | ||||
|       REQUIRE(true != ok); | ||||
|     } | ||||
|  | ||||
|     SECTION("Negations") { | ||||
|       REQUIRE(!invalidInput == false); | ||||
|       REQUIRE(!ok == true); | ||||
|     } | ||||
|  | ||||
|     SECTION("DeserializationError == Code") { | ||||
|       REQUIRE(invalidInput == DeserializationError::InvalidInput); | ||||
|       REQUIRE(ok == DeserializationError::Ok); | ||||
|     } | ||||
|  | ||||
|     SECTION("Code == DeserializationError") { | ||||
|       REQUIRE(DeserializationError::InvalidInput == invalidInput); | ||||
|       REQUIRE(DeserializationError::Ok == ok); | ||||
|     } | ||||
|  | ||||
|     SECTION("DeserializationError != Code") { | ||||
|       REQUIRE(invalidInput != DeserializationError::Ok); | ||||
|       REQUIRE(ok != DeserializationError::InvalidInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("Code != DeserializationError") { | ||||
|       REQUIRE(DeserializationError::Ok != invalidInput); | ||||
|       REQUIRE(DeserializationError::InvalidInput != ok); | ||||
|     } | ||||
|  | ||||
|     SECTION("DeserializationError == DeserializationError") { | ||||
|       REQUIRE_FALSE(invalidInput == ok); | ||||
|     } | ||||
|  | ||||
|     SECTION("DeserializationError != DeserializationError") { | ||||
|       REQUIRE(invalidInput != ok); | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										402
									
								
								extras/tests/JsonDeserializer/array.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										402
									
								
								extras/tests/JsonDeserializer/array.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,402 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("deserialize JSON array") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("An empty array") { | ||||
|     DeserializationError err = deserializeJson(doc, "[]"); | ||||
|     JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|     REQUIRE(0 == arr.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("Spaces") { | ||||
|     SECTION("Before the opening bracket") { | ||||
|       DeserializationError err = deserializeJson(doc, "  []"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(0 == arr.size()); | ||||
|     } | ||||
|  | ||||
|     SECTION("Before first value") { | ||||
|       DeserializationError err = deserializeJson(doc, "[ \t\r\n42]"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
|       REQUIRE(arr[0] == 42); | ||||
|     } | ||||
|  | ||||
|     SECTION("After first value") { | ||||
|       DeserializationError err = deserializeJson(doc, "[42 \t\r\n]"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
|       REQUIRE(arr[0] == 42); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Values types") { | ||||
|     SECTION("On integer") { | ||||
|       DeserializationError err = deserializeJson(doc, "[42]"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
|       REQUIRE(arr[0] == 42); | ||||
|     } | ||||
|  | ||||
|     SECTION("Two integers") { | ||||
|       DeserializationError err = deserializeJson(doc, "[42,84]"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
|       REQUIRE(arr[0] == 42); | ||||
|       REQUIRE(arr[1] == 84); | ||||
|     } | ||||
|  | ||||
|     SECTION("Double") { | ||||
|       DeserializationError err = deserializeJson(doc, "[4.2,1e2]"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
|       REQUIRE(arr[0] == 4.2); | ||||
|       REQUIRE(arr[1] == 1e2); | ||||
|     } | ||||
|  | ||||
|     SECTION("Unsigned long") { | ||||
|       DeserializationError err = deserializeJson(doc, "[4294967295]"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
|       REQUIRE(arr[0] == 4294967295UL); | ||||
|     } | ||||
|  | ||||
|     SECTION("Boolean") { | ||||
|       DeserializationError err = deserializeJson(doc, "[true,false]"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
|       REQUIRE(arr[0] == true); | ||||
|       REQUIRE(arr[1] == false); | ||||
|     } | ||||
|  | ||||
|     SECTION("Null") { | ||||
|       DeserializationError err = deserializeJson(doc, "[null,null]"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
|       REQUIRE(arr[0].as<char*>() == 0); | ||||
|       REQUIRE(arr[1].as<char*>() == 0); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Quotes") { | ||||
|     SECTION("Double quotes") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "[ \"hello\" , \"world\" ]"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
|       REQUIRE(arr[0] == "hello"); | ||||
|       REQUIRE(arr[1] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Single quotes") { | ||||
|       DeserializationError err = deserializeJson(doc, "[ 'hello' , 'world' ]"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
|       REQUIRE(arr[0] == "hello"); | ||||
|       REQUIRE(arr[1] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("No quotes") { | ||||
|       DeserializationError err = deserializeJson(doc, "[ hello , world ]"); | ||||
|       REQUIRE(err == DeserializationError::InvalidInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("Double quotes (empty strings)") { | ||||
|       DeserializationError err = deserializeJson(doc, "[\"\",\"\"]"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
|       REQUIRE(arr[0] == ""); | ||||
|       REQUIRE(arr[1] == ""); | ||||
|     } | ||||
|  | ||||
|     SECTION("Single quotes (empty strings)") { | ||||
|       DeserializationError err = deserializeJson(doc, "[\'\',\'\']"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
|       REQUIRE(arr[0] == ""); | ||||
|       REQUIRE(arr[1] == ""); | ||||
|     } | ||||
|  | ||||
|     SECTION("No quotes (empty strings)") { | ||||
|       DeserializationError err = deserializeJson(doc, "[,]"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::InvalidInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("Closing single quotes missing") { | ||||
|       DeserializationError err = deserializeJson(doc, "[\"]"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("Closing double quotes missing") { | ||||
|       DeserializationError err = deserializeJson(doc, "[\']"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Block comments") { | ||||
|     SECTION("Before opening bracket") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "/*COMMENT*/  [\"hello\"]"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
|       REQUIRE(arr[0] == "hello"); | ||||
|     } | ||||
|  | ||||
|     SECTION("After opening bracket") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "[/*COMMENT*/ \"hello\"]"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
|       REQUIRE(arr[0] == "hello"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Before closing bracket") { | ||||
|       DeserializationError err = deserializeJson(doc, "[\"hello\"/*COMMENT*/]"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
|       REQUIRE(arr[0] == "hello"); | ||||
|     } | ||||
|  | ||||
|     SECTION("After closing bracket") { | ||||
|       DeserializationError err = deserializeJson(doc, "[\"hello\"]/*COMMENT*/"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
|       REQUIRE(arr[0] == "hello"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Before comma") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "[\"hello\"/*COMMENT*/,\"world\"]"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
|       REQUIRE(arr[0] == "hello"); | ||||
|       REQUIRE(arr[1] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("After comma") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "[\"hello\",/*COMMENT*/ \"world\"]"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
|       REQUIRE(arr[0] == "hello"); | ||||
|       REQUIRE(arr[1] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("/*/") { | ||||
|       DeserializationError err = deserializeJson(doc, "[/*/\n]"); | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("Unfinished comment") { | ||||
|       DeserializationError err = deserializeJson(doc, "[/*COMMENT]"); | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("Final slash missing") { | ||||
|       DeserializationError err = deserializeJson(doc, "[/*COMMENT*]"); | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Trailing comments") { | ||||
|     SECTION("Before opening bracket") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "//COMMENT\n\t[\"hello\"]"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
|       REQUIRE(arr[0] == "hello"); | ||||
|     } | ||||
|  | ||||
|     SECTION("After opening bracket") { | ||||
|       DeserializationError err = deserializeJson(doc, "[//COMMENT\n\"hello\"]"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
|       REQUIRE(arr[0] == "hello"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Before closing bracket") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "[\"hello\"//COMMENT\r\n]"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
|       REQUIRE(arr[0] == "hello"); | ||||
|     } | ||||
|  | ||||
|     SECTION("After closing bracket") { | ||||
|       DeserializationError err = deserializeJson(doc, "[\"hello\"]//COMMENT\n"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
|       REQUIRE(arr[0] == "hello"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Before comma") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "[\"hello\"//COMMENT\n,\"world\"]"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
|       REQUIRE(arr[0] == "hello"); | ||||
|       REQUIRE(arr[1] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("After comma") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "[\"hello\",//COMMENT\n\"world\"]"); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
|       REQUIRE(arr[0] == "hello"); | ||||
|       REQUIRE(arr[1] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Invalid comment") { | ||||
|       DeserializationError err = deserializeJson(doc, "[/COMMENT\n]"); | ||||
|       REQUIRE(err == DeserializationError::InvalidInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("End document with comment") { | ||||
|       DeserializationError err = deserializeJson(doc, "[//COMMENT"); | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Premature null-terminator") { | ||||
|     SECTION("After opening bracket") { | ||||
|       DeserializationError err = deserializeJson(doc, "["); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("After value") { | ||||
|       DeserializationError err = deserializeJson(doc, "[1"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("After comma") { | ||||
|       DeserializationError err = deserializeJson(doc, "[1,"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Premature end of input") { | ||||
|     const char* input = "[1,2]"; | ||||
|  | ||||
|     SECTION("After opening bracket") { | ||||
|       DeserializationError err = deserializeJson(doc, input, 1); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("After value") { | ||||
|       DeserializationError err = deserializeJson(doc, input, 2); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("After comma") { | ||||
|       DeserializationError err = deserializeJson(doc, input, 3); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Misc") { | ||||
|     SECTION("Nested objects") { | ||||
|       char jsonString[] = | ||||
|           " [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] "; | ||||
|  | ||||
|       DeserializationError err = deserializeJson(doc, jsonString); | ||||
|       JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|       JsonObject object1 = arr[0]; | ||||
|       const JsonObject object2 = arr[1]; | ||||
|       JsonObject object3 = arr[2]; | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|  | ||||
|       REQUIRE(object1.isNull() == false); | ||||
|       REQUIRE(object2.isNull() == false); | ||||
|       REQUIRE(object3.isNull() == true); | ||||
|  | ||||
|       REQUIRE(2 == object1.size()); | ||||
|       REQUIRE(2 == object2.size()); | ||||
|       REQUIRE(0 == object3.size()); | ||||
|  | ||||
|       REQUIRE(1 == object1["a"].as<int>()); | ||||
|       REQUIRE(2 == object1["b"].as<int>()); | ||||
|       REQUIRE(3 == object2["c"].as<int>()); | ||||
|       REQUIRE(4 == object2["d"].as<int>()); | ||||
|       REQUIRE(0 == object3["e"].as<int>()); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Should clear the JsonArray") { | ||||
|     deserializeJson(doc, "[1,2,3,4]"); | ||||
|     deserializeJson(doc, "[]"); | ||||
|     JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|     REQUIRE(arr.size() == 0); | ||||
|     REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(0)); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										89
									
								
								extras/tests/JsonDeserializer/array_static.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								extras/tests/JsonDeserializer/array_static.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("deserialize JSON array with a StaticJsonDocument") { | ||||
|   SECTION("BufferOfTheRightSizeForEmptyArray") { | ||||
|     StaticJsonDocument<JSON_ARRAY_SIZE(0)> doc; | ||||
|     char input[] = "[]"; | ||||
|  | ||||
|     DeserializationError err = deserializeJson(doc, input); | ||||
|  | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("TooSmallBufferForArrayWithOneValue") { | ||||
|     StaticJsonDocument<JSON_ARRAY_SIZE(0)> doc; | ||||
|     char input[] = "[1]"; | ||||
|  | ||||
|     DeserializationError err = deserializeJson(doc, input); | ||||
|  | ||||
|     REQUIRE(err == DeserializationError::NoMemory); | ||||
|   } | ||||
|  | ||||
|   SECTION("BufferOfTheRightSizeForArrayWithOneValue") { | ||||
|     StaticJsonDocument<JSON_ARRAY_SIZE(1)> doc; | ||||
|     char input[] = "[1]"; | ||||
|  | ||||
|     DeserializationError err = deserializeJson(doc, input); | ||||
|  | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("TooSmallBufferForArrayWithNestedObject") { | ||||
|     StaticJsonDocument<JSON_ARRAY_SIZE(0) + JSON_OBJECT_SIZE(0)> doc; | ||||
|     char input[] = "[{}]"; | ||||
|  | ||||
|     DeserializationError err = deserializeJson(doc, input); | ||||
|  | ||||
|     REQUIRE(err == DeserializationError::NoMemory); | ||||
|   } | ||||
|  | ||||
|   SECTION("BufferOfTheRightSizeForArrayWithNestedObject") { | ||||
|     StaticJsonDocument<JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(0)> doc; | ||||
|     char input[] = "[{}]"; | ||||
|  | ||||
|     DeserializationError err = deserializeJson(doc, input); | ||||
|  | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("CopyStringNotSpaces") { | ||||
|     StaticJsonDocument<100> doc; | ||||
|  | ||||
|     deserializeJson(doc, "  [ \"1234567\" ] "); | ||||
|  | ||||
|     REQUIRE(JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(8) == doc.memoryUsage()); | ||||
|     // note: we use a string of 8 bytes to be sure that the StaticMemoryPool | ||||
|     // will not insert bytes to enforce alignement | ||||
|   } | ||||
|  | ||||
|   SECTION("Should clear the JsonArray") { | ||||
|     StaticJsonDocument<JSON_ARRAY_SIZE(4)> doc; | ||||
|     char input[] = "[1,2,3,4]"; | ||||
|  | ||||
|     deserializeJson(doc, input); | ||||
|     deserializeJson(doc, "[]"); | ||||
|  | ||||
|     JsonArray arr = doc.as<JsonArray>(); | ||||
|     REQUIRE(arr.size() == 0); | ||||
|     REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(0)); | ||||
|   } | ||||
|  | ||||
|   SECTION("Array") { | ||||
|     StaticJsonDocument<JSON_ARRAY_SIZE(2)> doc; | ||||
|     char input[] = "[1,2]"; | ||||
|  | ||||
|     DeserializationError err = deserializeJson(doc, input); | ||||
|     JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|     REQUIRE(doc.is<JsonArray>()); | ||||
|     REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2)); | ||||
|     REQUIRE(arr[0] == 1); | ||||
|     REQUIRE(arr[1] == 2); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										27
									
								
								extras/tests/JsonDeserializer/incomplete_input.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								extras/tests/JsonDeserializer/incomplete_input.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #define ARDUINOJSON_DECODE_UNICODE 1 | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("Truncated JSON input") { | ||||
|   const char* testCases[] = {"\"hello", "\'hello", "'\\u", "'\\u00", "'\\u000", | ||||
|                              // false | ||||
|                              "f", "fa", "fal", "fals", | ||||
|                              // true | ||||
|                              "t", "tr", "tru", | ||||
|                              // null | ||||
|                              "n", "nu", "nul"}; | ||||
|   const size_t testCount = sizeof(testCases) / sizeof(testCases[0]); | ||||
|  | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   for (size_t i = 0; i < testCount; i++) { | ||||
|     const char* input = testCases[i]; | ||||
|     CAPTURE(input); | ||||
|     REQUIRE(deserializeJson(doc, input) == | ||||
|             DeserializationError::IncompleteInput); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										115
									
								
								extras/tests/JsonDeserializer/input_types.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								extras/tests/JsonDeserializer/input_types.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,115 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
| #include <sstream> | ||||
|  | ||||
| TEST_CASE("deserializeJson(const std::string&)") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   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(4096); | ||||
|  | ||||
|   SECTION("array") { | ||||
|     std::istringstream json(" [ 42 /* comment */ ] "); | ||||
|  | ||||
|     DeserializationError err = deserializeJson(doc, json); | ||||
|     JsonArray arr = doc.as<JsonArray>(); | ||||
|  | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|     REQUIRE(1 == arr.size()); | ||||
|     REQUIRE(42 == arr[0]); | ||||
|   } | ||||
|  | ||||
|   SECTION("object") { | ||||
|     std::istringstream json(" { hello : 'world' // comment\n }"); | ||||
|  | ||||
|     DeserializationError err = deserializeJson(doc, json); | ||||
|     JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|     REQUIRE(1 == obj.size()); | ||||
|     REQUIRE(std::string("world") == obj["hello"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Should not read after the closing brace of an empty object") { | ||||
|     std::istringstream json("{}123"); | ||||
|  | ||||
|     deserializeJson(doc, json); | ||||
|  | ||||
|     REQUIRE('1' == char(json.get())); | ||||
|   } | ||||
|  | ||||
|   SECTION("Should not read after the closing brace") { | ||||
|     std::istringstream json("{\"hello\":\"world\"}123"); | ||||
|  | ||||
|     deserializeJson(doc, json); | ||||
|  | ||||
|     REQUIRE('1' == char(json.get())); | ||||
|   } | ||||
|  | ||||
|   SECTION("Should not read after the closing bracket of an empty array") { | ||||
|     std::istringstream json("[]123"); | ||||
|  | ||||
|     deserializeJson(doc, json); | ||||
|  | ||||
|     REQUIRE('1' == char(json.get())); | ||||
|   } | ||||
|  | ||||
|   SECTION("Should not read after the closing bracket") { | ||||
|     std::istringstream json("[\"hello\",\"world\"]123"); | ||||
|  | ||||
|     deserializeJson(doc, json); | ||||
|  | ||||
|     REQUIRE('1' == char(json.get())); | ||||
|   } | ||||
|  | ||||
|   SECTION("Should not read after the closing quote") { | ||||
|     std::istringstream json("\"hello\"123"); | ||||
|  | ||||
|     deserializeJson(doc, json); | ||||
|  | ||||
|     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 | ||||
							
								
								
									
										35
									
								
								extras/tests/JsonDeserializer/invalid_input.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								extras/tests/JsonDeserializer/invalid_input.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #define ARDUINOJSON_DECODE_UNICODE 1 | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("Invalid JSON input") { | ||||
|   const char* testCases[] = {"'\\u'",     "'\\u000g'", "'\\u000'", "'\\u000G'", | ||||
|                              "'\\u000/'", "\\x1234",   "6a9",      "1,", | ||||
|                              "2]",        "3}"}; | ||||
|   const size_t testCount = sizeof(testCases) / sizeof(testCases[0]); | ||||
|  | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   for (size_t i = 0; i < testCount; i++) { | ||||
|     const char* input = testCases[i]; | ||||
|     CAPTURE(input); | ||||
|     REQUIRE(deserializeJson(doc, input) == DeserializationError::InvalidInput); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("Invalid JSON input that should pass") { | ||||
|   const char* testCases[] = {"nulL", "tru3", "fals3"}; | ||||
|   const size_t testCount = sizeof(testCases) / sizeof(testCases[0]); | ||||
|  | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   for (size_t i = 0; i < testCount; i++) { | ||||
|     const char* input = testCases[i]; | ||||
|     CAPTURE(input); | ||||
|     REQUIRE(deserializeJson(doc, input) == DeserializationError::Ok); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										143
									
								
								extras/tests/JsonDeserializer/misc.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								extras/tests/JsonDeserializer/misc.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,143 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace Catch::Matchers; | ||||
|  | ||||
| TEST_CASE("deserializeJson(DynamicJsonDocument&)") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("Edge cases") { | ||||
|     SECTION("null char*") { | ||||
|       DeserializationError err = deserializeJson(doc, static_cast<char*>(0)); | ||||
|  | ||||
|       REQUIRE(err != DeserializationError::Ok); | ||||
|     } | ||||
|  | ||||
|     SECTION("null const char*") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, static_cast<const char*>(0)); | ||||
|  | ||||
|       REQUIRE(err != DeserializationError::Ok); | ||||
|     } | ||||
|  | ||||
|     SECTION("Empty input") { | ||||
|       DeserializationError err = deserializeJson(doc, ""); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("issue #628") { | ||||
|       DeserializationError err = deserializeJson(doc, "null"); | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<float>() == false); | ||||
|     } | ||||
|  | ||||
|     SECTION("Garbage") { | ||||
|       DeserializationError err = deserializeJson(doc, "%*$£¤"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::InvalidInput); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Booleans") { | ||||
|     SECTION("True") { | ||||
|       DeserializationError err = deserializeJson(doc, "true"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<bool>()); | ||||
|       REQUIRE(doc.as<bool>() == true); | ||||
|     } | ||||
|  | ||||
|     SECTION("False") { | ||||
|       DeserializationError err = deserializeJson(doc, "false"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<bool>()); | ||||
|       REQUIRE(doc.as<bool>() == false); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Comments") { | ||||
|     SECTION("Just a trailing comment") { | ||||
|       DeserializationError err = deserializeJson(doc, "// comment"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("Just a block comment") { | ||||
|       DeserializationError err = deserializeJson(doc, "/*comment*/"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("Just a slash") { | ||||
|       DeserializationError err = deserializeJson(doc, "/"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::InvalidInput); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Premature null-terminator") { | ||||
|     SECTION("In escape sequence") { | ||||
|       DeserializationError err = deserializeJson(doc, "\"\\"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("In block comment") { | ||||
|       DeserializationError err = deserializeJson(doc, "/* comment"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("In double quoted string") { | ||||
|       DeserializationError err = deserializeJson(doc, "\"hello"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("In single quoted string") { | ||||
|       DeserializationError err = deserializeJson(doc, "'hello"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Premature end of input") { | ||||
|     SECTION("In escape sequence") { | ||||
|       DeserializationError err = deserializeJson(doc, "\"\\n\"", 2); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("In block comment") { | ||||
|       DeserializationError err = deserializeJson(doc, "/* comment */", 10); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("In double quoted string") { | ||||
|       DeserializationError err = deserializeJson(doc, "\"hello\"", 6); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("In single quoted string") { | ||||
|       DeserializationError err = deserializeJson(doc, "'hello'", 6); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Should clear the JsonVariant") { | ||||
|     deserializeJson(doc, "[1,2,3]"); | ||||
|     deserializeJson(doc, "{}"); | ||||
|  | ||||
|     REQUIRE(doc.is<JsonObject>()); | ||||
|     REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										101
									
								
								extras/tests/JsonDeserializer/nestingLimit.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								extras/tests/JsonDeserializer/nestingLimit.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| #define SHOULD_WORK(expression) REQUIRE(DeserializationError::Ok == expression); | ||||
| #define SHOULD_FAIL(expression) \ | ||||
|   REQUIRE(DeserializationError::TooDeep == expression); | ||||
|  | ||||
| TEST_CASE("JsonDeserializer nesting") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("Input = const char*") { | ||||
|     SECTION("limit = 0") { | ||||
|       DeserializationOption::NestingLimit nesting(0); | ||||
|       SHOULD_WORK(deserializeJson(doc, "\"toto\"", nesting)); | ||||
|       SHOULD_WORK(deserializeJson(doc, "123", nesting)); | ||||
|       SHOULD_WORK(deserializeJson(doc, "true", nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, "[]", nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, "{}", nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, "[\"toto\"]", nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, "{\"toto\":1}", nesting)); | ||||
|     } | ||||
|  | ||||
|     SECTION("limit = 1") { | ||||
|       DeserializationOption::NestingLimit nesting(1); | ||||
|       SHOULD_WORK(deserializeJson(doc, "[\"toto\"]", nesting)); | ||||
|       SHOULD_WORK(deserializeJson(doc, "{\"toto\":1}", nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, "{\"toto\":{}}", nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, "{\"toto\":[]}", nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, "[[\"toto\"]]", nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, "[{\"toto\":1}]", nesting)); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("char* and size_t") { | ||||
|     SECTION("limit = 0") { | ||||
|       DeserializationOption::NestingLimit nesting(0); | ||||
|       SHOULD_WORK(deserializeJson(doc, "\"toto\"", 6, nesting)); | ||||
|       SHOULD_WORK(deserializeJson(doc, "123", 3, nesting)); | ||||
|       SHOULD_WORK(deserializeJson(doc, "true", 4, nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, "[]", 2, nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, "{}", 2, nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, "[\"toto\"]", 8, nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, "{\"toto\":1}", 10, nesting)); | ||||
|     } | ||||
|  | ||||
|     SECTION("limit = 1") { | ||||
|       DeserializationOption::NestingLimit nesting(1); | ||||
|       SHOULD_WORK(deserializeJson(doc, "[\"toto\"]", 8, nesting)); | ||||
|       SHOULD_WORK(deserializeJson(doc, "{\"toto\":1}", 10, nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, "{\"toto\":{}}", 11, nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, "{\"toto\":[]}", 11, nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, "[[\"toto\"]]", 10, nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, "[{\"toto\":1}]", 12, nesting)); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Input = std::string") { | ||||
|     SECTION("limit = 0") { | ||||
|       DeserializationOption::NestingLimit nesting(0); | ||||
|       SHOULD_WORK(deserializeJson(doc, std::string("\"toto\""), nesting)); | ||||
|       SHOULD_WORK(deserializeJson(doc, std::string("123"), nesting)); | ||||
|       SHOULD_WORK(deserializeJson(doc, std::string("true"), nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, std::string("[]"), nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, std::string("{}"), nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, std::string("[\"toto\"]"), nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, std::string("{\"toto\":1}"), nesting)); | ||||
|     } | ||||
|  | ||||
|     SECTION("limit = 1") { | ||||
|       DeserializationOption::NestingLimit nesting(1); | ||||
|       SHOULD_WORK(deserializeJson(doc, std::string("[\"toto\"]"), nesting)); | ||||
|       SHOULD_WORK(deserializeJson(doc, std::string("{\"toto\":1}"), nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, std::string("{\"toto\":{}}"), nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, std::string("{\"toto\":[]}"), nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, std::string("[[\"toto\"]]"), nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, std::string("[{\"toto\":1}]"), nesting)); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Input = std::istream") { | ||||
|     SECTION("limit = 0") { | ||||
|       DeserializationOption::NestingLimit nesting(0); | ||||
|       std::istringstream good("true"); | ||||
|       std::istringstream bad("[]"); | ||||
|       SHOULD_WORK(deserializeJson(doc, good, nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, bad, nesting)); | ||||
|     } | ||||
|  | ||||
|     SECTION("limit = 1") { | ||||
|       DeserializationOption::NestingLimit nesting(1); | ||||
|       std::istringstream good("[\"toto\"]"); | ||||
|       std::istringstream bad("{\"toto\":{}}"); | ||||
|       SHOULD_WORK(deserializeJson(doc, good, nesting)); | ||||
|       SHOULD_FAIL(deserializeJson(doc, bad, nesting)); | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										133
									
								
								extras/tests/JsonDeserializer/number.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								extras/tests/JsonDeserializer/number.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #define ARDUINOJSON_USE_LONG_LONG 0 | ||||
| #define ARDUINOJSON_ENABLE_NAN 1 | ||||
| #define ARDUINOJSON_ENABLE_INFINITY 1 | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <limits.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| namespace my { | ||||
| using ARDUINOJSON_NAMESPACE::isinf; | ||||
| using ARDUINOJSON_NAMESPACE::isnan; | ||||
| }  // namespace my | ||||
|  | ||||
| TEST_CASE("deserialize an integer") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("Integer") { | ||||
|     SECTION("0") { | ||||
|       DeserializationError err = deserializeJson(doc, "0"); | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<int>() == true); | ||||
|       REQUIRE(doc.as<int>() == 0); | ||||
|       REQUIRE(doc.as<std::string>() == "0");  // issue #808 | ||||
|     } | ||||
|  | ||||
|     SECTION("Negative") { | ||||
|       DeserializationError err = deserializeJson(doc, "-42"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<int>()); | ||||
|       REQUIRE_FALSE(doc.is<bool>()); | ||||
|       REQUIRE(doc.as<int>() == -42); | ||||
|     } | ||||
|  | ||||
| #if LONG_MAX == 2147483647 | ||||
|     SECTION("LONG_MAX") { | ||||
|       DeserializationError err = deserializeJson(doc, "2147483647"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<long>() == true); | ||||
|       REQUIRE(doc.as<long>() == LONG_MAX); | ||||
|     } | ||||
|  | ||||
|     SECTION("LONG_MAX + 1") { | ||||
|       DeserializationError err = deserializeJson(doc, "2147483648"); | ||||
|  | ||||
|       CAPTURE(LONG_MIN); | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<long>() == false); | ||||
|       REQUIRE(doc.is<float>() == true); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
| #if LONG_MIN == -2147483648 | ||||
|     SECTION("LONG_MIN") { | ||||
|       DeserializationError err = deserializeJson(doc, "-2147483648"); | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<long>() == true); | ||||
|       REQUIRE(doc.as<long>() == LONG_MIN); | ||||
|     } | ||||
|  | ||||
|     SECTION("LONG_MIN - 1") { | ||||
|       DeserializationError err = deserializeJson(doc, "-2147483649"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<long>() == false); | ||||
|       REQUIRE(doc.is<float>() == true); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
| #if ULONG_MAX == 4294967295 | ||||
|     SECTION("ULONG_MAX") { | ||||
|       DeserializationError err = deserializeJson(doc, "4294967295"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<unsigned long>() == true); | ||||
|       REQUIRE(doc.as<unsigned long>() == ULONG_MAX); | ||||
|       REQUIRE(doc.is<long>() == false); | ||||
|     } | ||||
|  | ||||
|     SECTION("ULONG_MAX + 1") { | ||||
|       DeserializationError err = deserializeJson(doc, "4294967296"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<unsigned long>() == false); | ||||
|       REQUIRE(doc.is<float>() == true); | ||||
|     } | ||||
| #endif | ||||
|   } | ||||
|  | ||||
|   SECTION("Floats") { | ||||
|     SECTION("Double") { | ||||
|       DeserializationError err = deserializeJson(doc, "-1.23e+4"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE_FALSE(doc.is<int>()); | ||||
|       REQUIRE(doc.is<double>()); | ||||
|       REQUIRE(doc.as<double>() == Approx(-1.23e+4)); | ||||
|     } | ||||
|  | ||||
|     SECTION("NaN") { | ||||
|       DeserializationError err = deserializeJson(doc, "NaN"); | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<float>() == true); | ||||
|       REQUIRE(my::isnan(doc.as<float>())); | ||||
|     } | ||||
|  | ||||
|     SECTION("Infinity") { | ||||
|       DeserializationError err = deserializeJson(doc, "Infinity"); | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<float>() == true); | ||||
|       REQUIRE(my::isinf(doc.as<float>())); | ||||
|     } | ||||
|  | ||||
|     SECTION("+Infinity") { | ||||
|       DeserializationError err = deserializeJson(doc, "+Infinity"); | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<float>() == true); | ||||
|       REQUIRE(my::isinf(doc.as<float>())); | ||||
|     } | ||||
|  | ||||
|     SECTION("-Infinity") { | ||||
|       DeserializationError err = deserializeJson(doc, "-Infinity"); | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<float>() == true); | ||||
|       REQUIRE(my::isinf(doc.as<float>())); | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										498
									
								
								extras/tests/JsonDeserializer/object.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										498
									
								
								extras/tests/JsonDeserializer/object.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,498 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("deserialize JSON object") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("An empty object") { | ||||
|     DeserializationError err = deserializeJson(doc, "{}"); | ||||
|     JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|     REQUIRE(doc.is<JsonObject>()); | ||||
|     REQUIRE(obj.size() == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("Quotes") { | ||||
|     SECTION("Double quotes") { | ||||
|       DeserializationError err = deserializeJson(doc, "{\"key\":\"value\"}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["key"] == "value"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Single quotes") { | ||||
|       DeserializationError err = deserializeJson(doc, "{'key':'value'}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["key"] == "value"); | ||||
|     } | ||||
|  | ||||
|     SECTION("No quotes") { | ||||
|       DeserializationError err = deserializeJson(doc, "{key:'value'}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["key"] == "value"); | ||||
|     } | ||||
|  | ||||
|     SECTION("No quotes, allow underscore in key") { | ||||
|       DeserializationError err = deserializeJson(doc, "{_k_e_y_:42}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["_k_e_y_"] == 42); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Spaces") { | ||||
|     SECTION("Before the key") { | ||||
|       DeserializationError err = deserializeJson(doc, "{ \"key\":\"value\"}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["key"] == "value"); | ||||
|     } | ||||
|  | ||||
|     SECTION("After the key") { | ||||
|       DeserializationError err = deserializeJson(doc, "{\"key\" :\"value\"}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["key"] == "value"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Before the value") { | ||||
|       DeserializationError err = deserializeJson(doc, "{\"key\": \"value\"}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["key"] == "value"); | ||||
|     } | ||||
|  | ||||
|     SECTION("After the value") { | ||||
|       DeserializationError err = deserializeJson(doc, "{\"key\":\"value\" }"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["key"] == "value"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Before the colon") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
|       REQUIRE(obj["key1"] == "value1"); | ||||
|       REQUIRE(obj["key2"] == "value2"); | ||||
|     } | ||||
|  | ||||
|     SECTION("After the colon") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
|       REQUIRE(obj["key1"] == "value1"); | ||||
|       REQUIRE(obj["key2"] == "value2"); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Values types") { | ||||
|     SECTION("String") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "{\"key1\":\"value1\",\"key2\":\"value2\"}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
|       REQUIRE(obj["key1"] == "value1"); | ||||
|       REQUIRE(obj["key2"] == "value2"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Integer") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "{\"key1\":42,\"key2\":-42}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
|       REQUIRE(obj["key1"] == 42); | ||||
|       REQUIRE(obj["key2"] == -42); | ||||
|     } | ||||
|  | ||||
|     SECTION("Double") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "{\"key1\":12.345,\"key2\":-7E89}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
|       REQUIRE(obj["key1"] == 12.345); | ||||
|       REQUIRE(obj["key2"] == -7E89); | ||||
|     } | ||||
|  | ||||
|     SECTION("Booleans") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "{\"key1\":true,\"key2\":false}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
|       REQUIRE(obj["key1"] == true); | ||||
|       REQUIRE(obj["key2"] == false); | ||||
|     } | ||||
|  | ||||
|     SECTION("Null") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "{\"key1\":null,\"key2\":null}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
|       REQUIRE(obj["key1"].as<char*>() == 0); | ||||
|       REQUIRE(obj["key2"].as<char*>() == 0); | ||||
|     } | ||||
|  | ||||
|     SECTION("Array") { | ||||
|       char jsonString[] = " { \"ab\" : [ 1 , 2 ] , \"cd\" : [ 3 , 4 ] } "; | ||||
|  | ||||
|       DeserializationError err = deserializeJson(doc, jsonString); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       JsonArray array1 = obj["ab"]; | ||||
|       const JsonArray array2 = obj["cd"]; | ||||
|       JsonArray array3 = obj["ef"]; | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|  | ||||
|       REQUIRE(array1.isNull() == false); | ||||
|       REQUIRE(array2.isNull() == false); | ||||
|       REQUIRE(array3.isNull() == true); | ||||
|  | ||||
|       REQUIRE(2 == array1.size()); | ||||
|       REQUIRE(2 == array2.size()); | ||||
|       REQUIRE(0 == array3.size()); | ||||
|  | ||||
|       REQUIRE(1 == array1[0].as<int>()); | ||||
|       REQUIRE(2 == array1[1].as<int>()); | ||||
|  | ||||
|       REQUIRE(3 == array2[0].as<int>()); | ||||
|       REQUIRE(4 == array2[1].as<int>()); | ||||
|  | ||||
|       REQUIRE(0 == array3[0].as<int>()); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Premature null terminator") { | ||||
|     SECTION("After opening brace") { | ||||
|       DeserializationError err = deserializeJson(doc, "{"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("After key") { | ||||
|       DeserializationError err = deserializeJson(doc, "{\"hello\""); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("After colon") { | ||||
|       DeserializationError err = deserializeJson(doc, "{\"hello\":"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("After value") { | ||||
|       DeserializationError err = deserializeJson(doc, "{\"hello\":\"world\""); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("After comma") { | ||||
|       DeserializationError err = deserializeJson(doc, "{\"hello\":\"world\","); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::IncompleteInput); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Misc") { | ||||
|     SECTION("A quoted key without value") { | ||||
|       DeserializationError err = deserializeJson(doc, "{\"key\"}"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::InvalidInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("A non-quoted key without value") { | ||||
|       DeserializationError err = deserializeJson(doc, "{key}"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::InvalidInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("A dangling comma") { | ||||
|       DeserializationError err = deserializeJson(doc, "{\"key1\":\"value1\",}"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::InvalidInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("null as a key") { | ||||
|       DeserializationError err = deserializeJson(doc, "{null:\"value\"}"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|     } | ||||
|  | ||||
|     SECTION("Repeated key") { | ||||
|       DeserializationError err = deserializeJson(doc, "{a:{b:{c:1}},a:2}"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Block comments") { | ||||
|     SECTION("Before opening brace") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "/*COMMENT*/ {\"hello\":\"world\"}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(obj["hello"] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("After opening brace") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "{/*COMMENT*/\"hello\":\"world\"}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(obj["hello"] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Before colon") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "{\"hello\"/*COMMENT*/:\"world\"}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(obj["hello"] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("After colon") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "{\"hello\":/*COMMENT*/\"world\"}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(obj["hello"] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Before closing brace") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "{\"hello\":\"world\"/*COMMENT*/}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(obj["hello"] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("After closing brace") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "{\"hello\":\"world\"}/*COMMENT*/"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(obj["hello"] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Before comma") { | ||||
|       DeserializationError err = deserializeJson( | ||||
|           doc, "{\"hello\":\"world\"/*COMMENT*/,\"answer\":42}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(obj["hello"] == "world"); | ||||
|       REQUIRE(obj["answer"] == 42); | ||||
|     } | ||||
|  | ||||
|     SECTION("After comma") { | ||||
|       DeserializationError err = deserializeJson( | ||||
|           doc, "{\"hello\":\"world\",/*COMMENT*/\"answer\":42}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(obj["hello"] == "world"); | ||||
|       REQUIRE(obj["answer"] == 42); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Trailing comments") { | ||||
|     SECTION("Before opening brace") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "//COMMENT\n {\"hello\":\"world\"}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(obj["hello"] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("After opening brace") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "{//COMMENT\n\"hello\":\"world\"}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(obj["hello"] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Before colon") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "{\"hello\"//COMMENT\n:\"world\"}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(obj["hello"] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("After colon") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "{\"hello\"://COMMENT\n\"world\"}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(obj["hello"] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Before closing brace") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "{\"hello\":\"world\"//COMMENT\n}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(obj["hello"] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("After closing brace") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "{\"hello\":\"world\"}//COMMENT\n"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(obj["hello"] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Before comma") { | ||||
|       DeserializationError err = deserializeJson( | ||||
|           doc, "{\"hello\":\"world\"//COMMENT\n,\"answer\":42}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(obj["hello"] == "world"); | ||||
|       REQUIRE(obj["answer"] == 42); | ||||
|     } | ||||
|  | ||||
|     SECTION("After comma") { | ||||
|       DeserializationError err = deserializeJson( | ||||
|           doc, "{\"hello\":\"world\",//COMMENT\n\"answer\":42}"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(obj["hello"] == "world"); | ||||
|       REQUIRE(obj["answer"] == 42); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Dangling slash") { | ||||
|     SECTION("Before opening brace") { | ||||
|       DeserializationError err = deserializeJson(doc, "/{\"hello\":\"world\"}"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::InvalidInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("After opening brace") { | ||||
|       DeserializationError err = deserializeJson(doc, "{/\"hello\":\"world\"}"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::InvalidInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("Before colon") { | ||||
|       DeserializationError err = deserializeJson(doc, "{\"hello\"/:\"world\"}"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::InvalidInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("After colon") { | ||||
|       DeserializationError err = deserializeJson(doc, "{\"hello\":/\"world\"}"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::InvalidInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("Before closing brace") { | ||||
|       DeserializationError err = deserializeJson(doc, "{\"hello\":\"world\"/}"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::InvalidInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("After closing brace") { | ||||
|       DeserializationError err = deserializeJson(doc, "{\"hello\":\"world\"}/"); | ||||
|       JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::Ok); | ||||
|       REQUIRE(obj["hello"] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Before comma") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "{\"hello\":\"world\"/,\"answer\":42}"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::InvalidInput); | ||||
|     } | ||||
|  | ||||
|     SECTION("After comma") { | ||||
|       DeserializationError err = | ||||
|           deserializeJson(doc, "{\"hello\":\"world\",/\"answer\":42}"); | ||||
|  | ||||
|       REQUIRE(err == DeserializationError::InvalidInput); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Should clear the JsonObject") { | ||||
|     deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|     deserializeJson(doc, "{}"); | ||||
|     JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|     REQUIRE(doc.is<JsonObject>()); | ||||
|     REQUIRE(obj.size() == 0); | ||||
|     REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										64
									
								
								extras/tests/JsonDeserializer/object_static.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								extras/tests/JsonDeserializer/object_static.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("deserialize JSON object with StaticJsonDocument") { | ||||
|   SECTION("BufferOfTheRightSizeForEmptyObject") { | ||||
|     StaticJsonDocument<JSON_OBJECT_SIZE(0)> doc; | ||||
|     char input[] = "{}"; | ||||
|  | ||||
|     DeserializationError err = deserializeJson(doc, input); | ||||
|  | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("TooSmallBufferForObjectWithOneValue") { | ||||
|     StaticJsonDocument<JSON_OBJECT_SIZE(0)> doc; | ||||
|     char input[] = "{\"a\":1}"; | ||||
|  | ||||
|     DeserializationError err = deserializeJson(doc, input); | ||||
|  | ||||
|     REQUIRE(err == DeserializationError::NoMemory); | ||||
|   } | ||||
|  | ||||
|   SECTION("BufferOfTheRightSizeForObjectWithOneValue") { | ||||
|     StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc; | ||||
|     char input[] = "{\"a\":1}"; | ||||
|  | ||||
|     DeserializationError err = deserializeJson(doc, input); | ||||
|  | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("TooSmallBufferForObjectWithNestedObject") { | ||||
|     StaticJsonDocument<JSON_OBJECT_SIZE(0) + JSON_ARRAY_SIZE(0)> doc; | ||||
|     char input[] = "{\"a\":[]}"; | ||||
|  | ||||
|     DeserializationError err = deserializeJson(doc, input); | ||||
|  | ||||
|     REQUIRE(err == DeserializationError::NoMemory); | ||||
|   } | ||||
|  | ||||
|   SECTION("BufferOfTheRightSizeForObjectWithNestedObject") { | ||||
|     StaticJsonDocument<JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(0)> doc; | ||||
|     char input[] = "{\"a\":[]}"; | ||||
|  | ||||
|     DeserializationError err = deserializeJson(doc, input); | ||||
|  | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("Should clear the JsonObject") { | ||||
|     StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc; | ||||
|     char input[] = "{\"hello\":\"world\"}"; | ||||
|  | ||||
|     deserializeJson(doc, input); | ||||
|     deserializeJson(doc, "{}"); | ||||
|  | ||||
|     REQUIRE(doc.as<JsonObject>().size() == 0); | ||||
|     REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										72
									
								
								extras/tests/JsonDeserializer/string.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								extras/tests/JsonDeserializer/string.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #define ARDUINOJSON_DECODE_UNICODE 1 | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("Valid JSON strings value") { | ||||
|   struct TestCase { | ||||
|     const char* input; | ||||
|     const char* expectedOutput; | ||||
|   }; | ||||
|  | ||||
|   TestCase testCases[] = { | ||||
|       {"\"hello world\"", "hello world"}, | ||||
|       {"\'hello world\'", "hello world"}, | ||||
|       {"\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"", "1\"2\\3/4\b5\f6\n7\r8\t9"}, | ||||
|       {"'\\u0041'", "A"}, | ||||
|       {"'\\u00e4'", "\xc3\xa4"},      // ä | ||||
|       {"'\\u00E4'", "\xc3\xa4"},      // ä | ||||
|       {"'\\u3042'", "\xe3\x81\x82"},  // あ | ||||
|  | ||||
|   }; | ||||
|   const size_t testCount = sizeof(testCases) / sizeof(testCases[0]); | ||||
|  | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   for (size_t i = 0; i < testCount; i++) { | ||||
|     const TestCase& testCase = testCases[i]; | ||||
|     CAPTURE(testCase.input); | ||||
|     DeserializationError err = deserializeJson(doc, testCase.input); | ||||
|     REQUIRE(err == DeserializationError::Ok); | ||||
|     REQUIRE(doc.as<std::string>() == testCase.expectedOutput); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("Truncated JSON string") { | ||||
|   const char* testCases[] = {"\"hello", "\'hello", "'\\u", "'\\u00", "'\\u000"}; | ||||
|   const size_t testCount = sizeof(testCases) / sizeof(testCases[0]); | ||||
|  | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   for (size_t i = 0; i < testCount; i++) { | ||||
|     const char* input = testCases[i]; | ||||
|     CAPTURE(input); | ||||
|     REQUIRE(deserializeJson(doc, input) == | ||||
|             DeserializationError::IncompleteInput); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("Invalid JSON string") { | ||||
|   const char* testCases[] = {"'\\u'",     "'\\u000g'", "'\\u000'", | ||||
|                              "'\\u000G'", "'\\u000/'", "\\x1234"}; | ||||
|   const size_t testCount = sizeof(testCases) / sizeof(testCases[0]); | ||||
|  | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   for (size_t i = 0; i < testCount; i++) { | ||||
|     const char* input = testCases[i]; | ||||
|     CAPTURE(input); | ||||
|     REQUIRE(deserializeJson(doc, input) == DeserializationError::InvalidInput); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("Not enough room to duplicate the string") { | ||||
|   DynamicJsonDocument doc(4); | ||||
|  | ||||
|   REQUIRE(deserializeJson(doc, "\"hello world!\"") == | ||||
|           DeserializationError::NoMemory); | ||||
|   REQUIRE(doc.isNull() == true); | ||||
| } | ||||
							
								
								
									
										49
									
								
								extras/tests/JsonDocument/BasicJsonDocument.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								extras/tests/JsonDocument/BasicJsonDocument.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <stdlib.h>  // malloc, free | ||||
| #include <catch.hpp> | ||||
| #include <sstream> | ||||
|  | ||||
| using ARDUINOJSON_NAMESPACE::addPadding; | ||||
|  | ||||
| class SpyingAllocator { | ||||
|  public: | ||||
|   SpyingAllocator(std::ostream& log) : _log(log) {} | ||||
|  | ||||
|   void* allocate(size_t n) { | ||||
|     _log << "A" << n; | ||||
|     return malloc(n); | ||||
|   } | ||||
|   void deallocate(void* p) { | ||||
|     _log << "F"; | ||||
|     free(p); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   SpyingAllocator& operator=(const SpyingAllocator& src); | ||||
|  | ||||
|   std::ostream& _log; | ||||
| }; | ||||
|  | ||||
| typedef BasicJsonDocument<SpyingAllocator> MyJsonDocument; | ||||
|  | ||||
| TEST_CASE("BasicJsonDocument") { | ||||
|   std::stringstream log; | ||||
|  | ||||
|   SECTION("Construct/Destruct") { | ||||
|     { MyJsonDocument doc(4096, log); } | ||||
|     REQUIRE(log.str() == "A4096F"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Copy construct") { | ||||
|     { | ||||
|       MyJsonDocument doc1(4096, log); | ||||
|       doc1.set(std::string("The size of this string is 32!!")); | ||||
|       MyJsonDocument doc2(doc1); | ||||
|     } | ||||
|     REQUIRE(log.str() == "A4096A32FF"); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										21
									
								
								extras/tests/JsonDocument/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								extras/tests/JsonDocument/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| # ArduinoJson - arduinojson.org | ||||
| # Copyright Benoit Blanchon 2014-2019 | ||||
| # MIT License | ||||
|  | ||||
| add_executable(JsonDocumentTests | ||||
| 	add.cpp | ||||
| 	BasicJsonDocument.cpp | ||||
| 	compare.cpp | ||||
| 	containsKey.cpp | ||||
| 	createNested.cpp | ||||
| 	DynamicJsonDocument.cpp | ||||
| 	isNull.cpp | ||||
| 	nesting.cpp | ||||
| 	remove.cpp | ||||
| 	size.cpp | ||||
| 	StaticJsonDocument.cpp | ||||
| 	subscript.cpp | ||||
| ) | ||||
|  | ||||
| target_link_libraries(JsonDocumentTests catch) | ||||
| add_test(JsonDocument JsonDocumentTests) | ||||
							
								
								
									
										209
									
								
								extras/tests/JsonDocument/DynamicJsonDocument.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										209
									
								
								extras/tests/JsonDocument/DynamicJsonDocument.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,209 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using ARDUINOJSON_NAMESPACE::addPadding; | ||||
|  | ||||
| static void REQUIRE_JSON(JsonDocument& doc, const std::string& expected) { | ||||
|   std::string json; | ||||
|   serializeJson(doc, json); | ||||
|   REQUIRE(json == expected); | ||||
| } | ||||
|  | ||||
| TEST_CASE("DynamicJsonDocument") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("serializeJson()") { | ||||
|     JsonObject obj = doc.to<JsonObject>(); | ||||
|     obj["hello"] = "world"; | ||||
|  | ||||
|     std::string json; | ||||
|     serializeJson(doc, json); | ||||
|  | ||||
|     REQUIRE(json == "{\"hello\":\"world\"}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("memoryUsage()") { | ||||
|     SECTION("starts at zero") { | ||||
|       REQUIRE(doc.memoryUsage() == 0); | ||||
|     } | ||||
|  | ||||
|     SECTION("JSON_ARRAY_SIZE(0)") { | ||||
|       doc.to<JsonArray>(); | ||||
|       REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(0)); | ||||
|     } | ||||
|  | ||||
|     SECTION("JSON_ARRAY_SIZE(1)") { | ||||
|       doc.to<JsonArray>().add(42); | ||||
|       REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(1)); | ||||
|     } | ||||
|  | ||||
|     SECTION("JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(0)") { | ||||
|       doc.to<JsonArray>().createNestedArray(); | ||||
|       REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(0)); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("capacity()") { | ||||
|     SECTION("matches constructor argument") { | ||||
|       DynamicJsonDocument doc2(256); | ||||
|       REQUIRE(doc2.capacity() == 256); | ||||
|     } | ||||
|  | ||||
|     SECTION("rounds up constructor argument") { | ||||
|       DynamicJsonDocument doc2(253); | ||||
|       REQUIRE(doc2.capacity() == 256); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("memoryUsage()") { | ||||
|     SECTION("Increases after adding value to array") { | ||||
|       JsonArray arr = doc.to<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(0)); | ||||
|       arr.add(42); | ||||
|       REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(1)); | ||||
|       arr.add(43); | ||||
|       REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2)); | ||||
|     } | ||||
|  | ||||
|     SECTION("Increases after adding value to object") { | ||||
|       JsonObject obj = doc.to<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); | ||||
|       obj["a"] = 1; | ||||
|       REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(1)); | ||||
|       obj["b"] = 2; | ||||
|       REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(2)); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("DynamicJsonDocument constructor") { | ||||
|   SECTION("Copy constructor") { | ||||
|     DynamicJsonDocument doc1(1234); | ||||
|     deserializeJson(doc1, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|     DynamicJsonDocument doc2 = doc1; | ||||
|  | ||||
|     REQUIRE_JSON(doc2, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|     REQUIRE(doc2.capacity() == addPadding(doc1.memoryUsage())); | ||||
|   } | ||||
|  | ||||
|   SECTION("Construct from StaticJsonDocument") { | ||||
|     StaticJsonDocument<200> doc1; | ||||
|     deserializeJson(doc1, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|     DynamicJsonDocument doc2 = doc1; | ||||
|  | ||||
|     REQUIRE_JSON(doc2, "{\"hello\":\"world\"}"); | ||||
|     REQUIRE(doc2.capacity() == addPadding(doc1.memoryUsage())); | ||||
|   } | ||||
|  | ||||
|   SECTION("Construct from JsonObject") { | ||||
|     StaticJsonDocument<200> doc1; | ||||
|     JsonObject obj = doc1.to<JsonObject>(); | ||||
|     obj["hello"] = "world"; | ||||
|  | ||||
|     DynamicJsonDocument doc2 = obj; | ||||
|  | ||||
|     REQUIRE_JSON(doc2, "{\"hello\":\"world\"}"); | ||||
|     REQUIRE(doc2.capacity() == addPadding(doc1.memoryUsage())); | ||||
|   } | ||||
|  | ||||
|   SECTION("Construct from JsonArray") { | ||||
|     StaticJsonDocument<200> doc1; | ||||
|     JsonArray arr = doc1.to<JsonArray>(); | ||||
|     arr.add("hello"); | ||||
|  | ||||
|     DynamicJsonDocument doc2 = arr; | ||||
|  | ||||
|     REQUIRE_JSON(doc2, "[\"hello\"]"); | ||||
|     REQUIRE(doc2.capacity() == addPadding(doc1.memoryUsage())); | ||||
|   } | ||||
|  | ||||
|   SECTION("Construct from JsonVariant") { | ||||
|     StaticJsonDocument<200> doc1; | ||||
|     deserializeJson(doc1, "42"); | ||||
|  | ||||
|     DynamicJsonDocument doc2 = doc1.as<JsonVariant>(); | ||||
|  | ||||
|     REQUIRE_JSON(doc2, "42"); | ||||
|     REQUIRE(doc2.capacity() == addPadding(doc1.memoryUsage())); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("DynamicJsonDocument assignment") { | ||||
|   SECTION("Copy assignment preserves the buffer when capacity is sufficient") { | ||||
|     DynamicJsonDocument doc1(1234); | ||||
|     deserializeJson(doc1, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|     DynamicJsonDocument doc2(doc1.capacity()); | ||||
|     doc2 = doc1; | ||||
|  | ||||
|     REQUIRE_JSON(doc2, "{\"hello\":\"world\"}"); | ||||
|     REQUIRE(doc2.capacity() == doc1.capacity()); | ||||
|   } | ||||
|  | ||||
|   SECTION("Copy assignment realloc the buffer when capacity is insufficient") { | ||||
|     DynamicJsonDocument doc1(1234); | ||||
|     deserializeJson(doc1, "{\"hello\":\"world\"}"); | ||||
|     DynamicJsonDocument doc2(8); | ||||
|  | ||||
|     REQUIRE(doc2.capacity() < doc1.memoryUsage()); | ||||
|     doc2 = doc1; | ||||
|     REQUIRE(doc2.capacity() >= doc1.memoryUsage()); | ||||
|  | ||||
|     REQUIRE_JSON(doc2, "{\"hello\":\"world\"}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Assign from StaticJsonDocument") { | ||||
|     StaticJsonDocument<200> doc1; | ||||
|     deserializeJson(doc1, "{\"hello\":\"world\"}"); | ||||
|     DynamicJsonDocument doc2(4096); | ||||
|     doc2.to<JsonVariant>().set(666); | ||||
|  | ||||
|     doc2 = doc1; | ||||
|  | ||||
|     REQUIRE_JSON(doc2, "{\"hello\":\"world\"}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Assign from JsonObject") { | ||||
|     StaticJsonDocument<200> doc1; | ||||
|     JsonObject obj = doc1.to<JsonObject>(); | ||||
|     obj["hello"] = "world"; | ||||
|  | ||||
|     DynamicJsonDocument doc2(4096); | ||||
|     doc2 = obj; | ||||
|  | ||||
|     REQUIRE_JSON(doc2, "{\"hello\":\"world\"}"); | ||||
|     REQUIRE(doc2.capacity() == 4096); | ||||
|   } | ||||
|  | ||||
|   SECTION("Assign from JsonArray") { | ||||
|     StaticJsonDocument<200> doc1; | ||||
|     JsonArray arr = doc1.to<JsonArray>(); | ||||
|     arr.add("hello"); | ||||
|  | ||||
|     DynamicJsonDocument doc2(4096); | ||||
|     doc2 = arr; | ||||
|  | ||||
|     REQUIRE_JSON(doc2, "[\"hello\"]"); | ||||
|     REQUIRE(doc2.capacity() == 4096); | ||||
|   } | ||||
|  | ||||
|   SECTION("Assign from JsonVariant") { | ||||
|     StaticJsonDocument<200> doc1; | ||||
|     deserializeJson(doc1, "42"); | ||||
|  | ||||
|     DynamicJsonDocument doc2(4096); | ||||
|     doc2 = doc1.as<JsonVariant>(); | ||||
|  | ||||
|     REQUIRE_JSON(doc2, "42"); | ||||
|     REQUIRE(doc2.capacity() == 4096); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										212
									
								
								extras/tests/JsonDocument/StaticJsonDocument.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										212
									
								
								extras/tests/JsonDocument/StaticJsonDocument.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,212 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| static void REQUIRE_JSON(JsonDocument& doc, const std::string& expected) { | ||||
|   std::string json; | ||||
|   serializeJson(doc, json); | ||||
|   REQUIRE(json == expected); | ||||
| } | ||||
|  | ||||
| TEST_CASE("StaticJsonDocument") { | ||||
|   SECTION("capacity()") { | ||||
|     SECTION("matches template argument") { | ||||
|       StaticJsonDocument<256> doc; | ||||
|       REQUIRE(doc.capacity() == 256); | ||||
|     } | ||||
|  | ||||
|     SECTION("rounds up template argument") { | ||||
|       StaticJsonDocument<253> doc; | ||||
|       REQUIRE(doc.capacity() == 256); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("serializeJson()") { | ||||
|     StaticJsonDocument<200> doc; | ||||
|     JsonObject obj = doc.to<JsonObject>(); | ||||
|     obj["hello"] = "world"; | ||||
|  | ||||
|     std::string json; | ||||
|     serializeJson(doc, json); | ||||
|  | ||||
|     REQUIRE(json == "{\"hello\":\"world\"}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Copy assignment") { | ||||
|     StaticJsonDocument<200> doc1, doc2; | ||||
|     doc1.to<JsonVariant>().set(666); | ||||
|     deserializeJson(doc2, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|     doc1 = doc2; | ||||
|  | ||||
|     REQUIRE_JSON(doc2, "{\"hello\":\"world\"}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Contructor") { | ||||
|     SECTION("Copy constructor") { | ||||
|       StaticJsonDocument<200> doc1; | ||||
|       deserializeJson(doc1, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|       StaticJsonDocument<200> doc2 = doc1; | ||||
|  | ||||
|       deserializeJson(doc1, "{\"HELLO\":\"WORLD\"}"); | ||||
|       REQUIRE_JSON(doc2, "{\"hello\":\"world\"}"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Construct from StaticJsonDocument of different size") { | ||||
|       StaticJsonDocument<300> doc1; | ||||
|       deserializeJson(doc1, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|       StaticJsonDocument<200> doc2 = doc1; | ||||
|  | ||||
|       REQUIRE_JSON(doc2, "{\"hello\":\"world\"}"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Construct from DynamicJsonDocument") { | ||||
|       DynamicJsonDocument doc1(4096); | ||||
|       deserializeJson(doc1, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|       StaticJsonDocument<200> doc2 = doc1; | ||||
|  | ||||
|       REQUIRE_JSON(doc2, "{\"hello\":\"world\"}"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Construct from JsonObject") { | ||||
|       DynamicJsonDocument doc1(4096); | ||||
|       deserializeJson(doc1, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|       StaticJsonDocument<200> doc2 = doc1.as<JsonObject>(); | ||||
|  | ||||
|       deserializeJson(doc1, "{\"HELLO\":\"WORLD\"}"); | ||||
|       REQUIRE_JSON(doc2, "{\"hello\":\"world\"}"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Construct from JsonArray") { | ||||
|       DynamicJsonDocument doc1(4096); | ||||
|       deserializeJson(doc1, "[\"hello\",\"world\"]"); | ||||
|  | ||||
|       StaticJsonDocument<200> doc2 = doc1.as<JsonArray>(); | ||||
|  | ||||
|       deserializeJson(doc1, "[\"HELLO\",\"WORLD\"]"); | ||||
|       REQUIRE_JSON(doc2, "[\"hello\",\"world\"]"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Construct from JsonVariant") { | ||||
|       DynamicJsonDocument doc1(4096); | ||||
|       deserializeJson(doc1, "42"); | ||||
|  | ||||
|       StaticJsonDocument<200> doc2 = doc1.as<JsonVariant>(); | ||||
|  | ||||
|       REQUIRE_JSON(doc2, "42"); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Assignment") { | ||||
|     SECTION("Copy assignment") { | ||||
|       StaticJsonDocument<200> doc1, doc2; | ||||
|       doc1.to<JsonVariant>().set(666); | ||||
|       deserializeJson(doc1, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|       doc2 = doc1; | ||||
|  | ||||
|       deserializeJson(doc1, "{\"HELLO\":\"WORLD\"}"); | ||||
|       REQUIRE_JSON(doc2, "{\"hello\":\"world\"}"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Assign from StaticJsonDocument of different capacity") { | ||||
|       StaticJsonDocument<200> doc1; | ||||
|       StaticJsonDocument<300> doc2; | ||||
|       doc1.to<JsonVariant>().set(666); | ||||
|       deserializeJson(doc1, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|       doc2 = doc1; | ||||
|  | ||||
|       REQUIRE_JSON(doc2, "{\"hello\":\"world\"}"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Assign from DynamicJsonDocument") { | ||||
|       StaticJsonDocument<200> doc1; | ||||
|       DynamicJsonDocument doc2(4096); | ||||
|       doc1.to<JsonVariant>().set(666); | ||||
|       deserializeJson(doc1, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|       doc2 = doc1; | ||||
|  | ||||
|       deserializeJson(doc1, "{\"HELLO\":\"WORLD\"}"); | ||||
|       REQUIRE_JSON(doc2, "{\"hello\":\"world\"}"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Assign from JsonArray") { | ||||
|       StaticJsonDocument<200> doc1; | ||||
|       DynamicJsonDocument doc2(4096); | ||||
|       doc1.to<JsonVariant>().set(666); | ||||
|       deserializeJson(doc1, "[\"hello\",\"world\"]"); | ||||
|  | ||||
|       doc2 = doc1.as<JsonArray>(); | ||||
|  | ||||
|       deserializeJson(doc1, "[\"HELLO\",\"WORLD\"]"); | ||||
|       REQUIRE_JSON(doc2, "[\"hello\",\"world\"]"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Assign from JsonArrayConst") { | ||||
|       StaticJsonDocument<200> doc1; | ||||
|       DynamicJsonDocument doc2(4096); | ||||
|       doc1.to<JsonVariant>().set(666); | ||||
|       deserializeJson(doc1, "[\"hello\",\"world\"]"); | ||||
|  | ||||
|       doc2 = doc1.as<JsonArrayConst>(); | ||||
|  | ||||
|       deserializeJson(doc1, "[\"HELLO\",\"WORLD\"]"); | ||||
|       REQUIRE_JSON(doc2, "[\"hello\",\"world\"]"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Assign from JsonObject") { | ||||
|       StaticJsonDocument<200> doc1; | ||||
|       DynamicJsonDocument doc2(4096); | ||||
|       doc1.to<JsonVariant>().set(666); | ||||
|       deserializeJson(doc1, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|       doc2 = doc1.as<JsonObject>(); | ||||
|  | ||||
|       deserializeJson(doc1, "{\"HELLO\":\"WORLD\"}"); | ||||
|       REQUIRE_JSON(doc2, "{\"hello\":\"world\"}"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Assign from JsonObjectConst") { | ||||
|       StaticJsonDocument<200> doc1; | ||||
|       DynamicJsonDocument doc2(4096); | ||||
|       doc1.to<JsonVariant>().set(666); | ||||
|       deserializeJson(doc1, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|       doc2 = doc1.as<JsonObjectConst>(); | ||||
|  | ||||
|       deserializeJson(doc1, "{\"HELLO\":\"WORLD\"}"); | ||||
|       REQUIRE_JSON(doc2, "{\"hello\":\"world\"}"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Assign from JsonVariant") { | ||||
|       DynamicJsonDocument doc1(4096); | ||||
|       doc1.to<JsonVariant>().set(666); | ||||
|       deserializeJson(doc1, "42"); | ||||
|  | ||||
|       StaticJsonDocument<200> doc2; | ||||
|       doc2 = doc1.as<JsonVariant>(); | ||||
|  | ||||
|       REQUIRE_JSON(doc2, "42"); | ||||
|     } | ||||
|  | ||||
|     SECTION("Assign from JsonVariantConst") { | ||||
|       DynamicJsonDocument doc1(4096); | ||||
|       doc1.to<JsonVariant>().set(666); | ||||
|       deserializeJson(doc1, "42"); | ||||
|  | ||||
|       StaticJsonDocument<200> doc2; | ||||
|       doc2 = doc1.as<JsonVariantConst>(); | ||||
|  | ||||
|       REQUIRE_JSON(doc2, "42"); | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										22
									
								
								extras/tests/JsonDocument/add.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								extras/tests/JsonDocument/add.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonDocument::add()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("integer") { | ||||
|     doc.add(42); | ||||
|  | ||||
|     REQUIRE(doc.as<std::string>() == "[42]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("const char*") { | ||||
|     doc.add("hello"); | ||||
|  | ||||
|     REQUIRE(doc.as<std::string>() == "[\"hello\"]"); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										77
									
								
								extras/tests/JsonDocument/compare.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								extras/tests/JsonDocument/compare.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("DynamicJsonDocument::operator==(const DynamicJsonDocument&)") { | ||||
|   DynamicJsonDocument doc1(4096); | ||||
|   DynamicJsonDocument doc2(4096); | ||||
|  | ||||
|   SECTION("Empty") { | ||||
|     REQUIRE(doc1 == doc2); | ||||
|     REQUIRE_FALSE(doc1 != doc2); | ||||
|   } | ||||
|  | ||||
|   SECTION("With same object") { | ||||
|     doc1["hello"] = "world"; | ||||
|     doc2["hello"] = "world"; | ||||
|     REQUIRE(doc1 == doc2); | ||||
|     REQUIRE_FALSE(doc1 != doc2); | ||||
|   } | ||||
|   SECTION("With different object") { | ||||
|     doc1["hello"] = "world"; | ||||
|     doc2["world"] = "hello"; | ||||
|     REQUIRE_FALSE(doc1 == doc2); | ||||
|     REQUIRE(doc1 != doc2); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("DynamicJsonDocument::operator==(const StaticJsonDocument&)") { | ||||
|   DynamicJsonDocument doc1(4096); | ||||
|   StaticJsonDocument<256> doc2; | ||||
|  | ||||
|   SECTION("Empty") { | ||||
|     REQUIRE(doc1 == doc2); | ||||
|     REQUIRE_FALSE(doc1 != doc2); | ||||
|   } | ||||
|  | ||||
|   SECTION("With same object") { | ||||
|     doc1["hello"] = "world"; | ||||
|     doc2["hello"] = "world"; | ||||
|     REQUIRE(doc1 == doc2); | ||||
|     REQUIRE_FALSE(doc1 != doc2); | ||||
|   } | ||||
|  | ||||
|   SECTION("With different object") { | ||||
|     doc1["hello"] = "world"; | ||||
|     doc2["world"] = "hello"; | ||||
|     REQUIRE_FALSE(doc1 == doc2); | ||||
|     REQUIRE(doc1 != doc2); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("StaticJsonDocument::operator==(const DynamicJsonDocument&)") { | ||||
|   StaticJsonDocument<256> doc1; | ||||
|   DynamicJsonDocument doc2(4096); | ||||
|  | ||||
|   SECTION("Empty") { | ||||
|     REQUIRE(doc1 == doc2); | ||||
|     REQUIRE_FALSE(doc1 != doc2); | ||||
|   } | ||||
|  | ||||
|   SECTION("With same object") { | ||||
|     doc1["hello"] = "world"; | ||||
|     doc2["hello"] = "world"; | ||||
|     REQUIRE(doc1 == doc2); | ||||
|     REQUIRE_FALSE(doc1 != doc2); | ||||
|   } | ||||
|  | ||||
|   SECTION("With different object") { | ||||
|     doc1["hello"] = "world"; | ||||
|     doc2["world"] = "hello"; | ||||
|     REQUIRE_FALSE(doc1 == doc2); | ||||
|     REQUIRE(doc1 != doc2); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										44
									
								
								extras/tests/JsonDocument/containsKey.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								extras/tests/JsonDocument/containsKey.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonDocument::containsKey()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("returns true on object") { | ||||
|     doc["hello"] = "world"; | ||||
|  | ||||
|     REQUIRE(doc.containsKey("hello") == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns true when value is null") { | ||||
|     doc["hello"] = static_cast<const char*>(0); | ||||
|  | ||||
|     REQUIRE(doc.containsKey("hello") == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns true when key is a std::string") { | ||||
|     doc["hello"] = "world"; | ||||
|  | ||||
|     REQUIRE(doc.containsKey(std::string("hello")) == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns false  on object") { | ||||
|     doc["world"] = "hello"; | ||||
|  | ||||
|     REQUIRE(doc.containsKey("hello") == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns false on array") { | ||||
|     doc.add("hello"); | ||||
|  | ||||
|     REQUIRE(doc.containsKey("hello") == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns false on null") { | ||||
|     REQUIRE(doc.containsKey("hello") == false); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										66
									
								
								extras/tests/JsonDocument/createNested.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								extras/tests/JsonDocument/createNested.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonDocument::createNestedArray()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("promotes to array") { | ||||
|     doc.createNestedArray(); | ||||
|  | ||||
|     REQUIRE(doc.is<JsonArray>()); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonDocument::createNestedArray(key)") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("key is const char*") { | ||||
|     SECTION("promotes to object") { | ||||
|       doc.createNestedArray("hello"); | ||||
|  | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("key is std::string") { | ||||
|     SECTION("promotes to object") { | ||||
|       doc.createNestedArray(std::string("hello")); | ||||
|  | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonDocument::createNestedObject()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("promotes to array") { | ||||
|     doc.createNestedObject(); | ||||
|  | ||||
|     REQUIRE(doc.is<JsonArray>()); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonDocument::createNestedObject(key)") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("key is const char*") { | ||||
|     SECTION("promotes to object") { | ||||
|       doc.createNestedObject("hello"); | ||||
|  | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("key is std::string") { | ||||
|     SECTION("promotes to object") { | ||||
|       doc.createNestedObject(std::string("hello")); | ||||
|  | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										39
									
								
								extras/tests/JsonDocument/isNull.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								extras/tests/JsonDocument/isNull.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonDocument::isNull()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("returns true if uninitialized") { | ||||
|     REQUIRE(doc.isNull() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns false after to<JsonObject>()") { | ||||
|     doc.to<JsonObject>(); | ||||
|     REQUIRE(doc.isNull() == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns false after to<JsonArray>()") { | ||||
|     doc.to<JsonArray>(); | ||||
|     REQUIRE(doc.isNull() == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns true after to<JsonVariant>()") { | ||||
|     REQUIRE(doc.isNull() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns false after set()") { | ||||
|     doc.to<JsonVariant>().set(42); | ||||
|     REQUIRE(doc.isNull() == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns true after clear()") { | ||||
|     doc.to<JsonObject>(); | ||||
|     doc.clear(); | ||||
|     REQUIRE(doc.isNull() == true); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										30
									
								
								extras/tests/JsonDocument/nesting.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								extras/tests/JsonDocument/nesting.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonDocument::nesting()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("return 0 if uninitialized") { | ||||
|     REQUIRE(doc.nesting() == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns 0 for string") { | ||||
|     JsonVariant var = doc.to<JsonVariant>(); | ||||
|     var.set("hello"); | ||||
|     REQUIRE(doc.nesting() == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns 1 for empty object") { | ||||
|     doc.to<JsonObject>(); | ||||
|     REQUIRE(doc.nesting() == 1); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns 1 for empty array") { | ||||
|     doc.to<JsonArray>(); | ||||
|     REQUIRE(doc.nesting() == 1); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										52
									
								
								extras/tests/JsonDocument/remove.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								extras/tests/JsonDocument/remove.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonDocument::remove()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("remove(int)") { | ||||
|     doc.add(1); | ||||
|     doc.add(2); | ||||
|     doc.add(3); | ||||
|  | ||||
|     doc.remove(1); | ||||
|  | ||||
|     REQUIRE(doc.as<std::string>() == "[1,3]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("remove(const char *)") { | ||||
|     doc["a"] = 1; | ||||
|     doc["b"] = 2; | ||||
|  | ||||
|     doc.remove("a"); | ||||
|  | ||||
|     REQUIRE(doc.as<std::string>() == "{\"b\":2}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("remove(std::string)") { | ||||
|     doc["a"] = 1; | ||||
|     doc["b"] = 2; | ||||
|  | ||||
|     doc.remove(std::string("b")); | ||||
|  | ||||
|     REQUIRE(doc.as<std::string>() == "{\"a\":1}"); | ||||
|   } | ||||
|  | ||||
| #ifdef HAS_VARIABLE_LENGTH_ARRAY | ||||
|   SECTION("remove(vla)") { | ||||
|     doc["a"] = 1; | ||||
|     doc["b"] = 2; | ||||
|  | ||||
|     int i = 4; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "b"); | ||||
|     doc.remove(vla); | ||||
|  | ||||
|     REQUIRE(doc.as<std::string>() == "{\"a\":1}"); | ||||
|   } | ||||
| #endif | ||||
| } | ||||
							
								
								
									
										28
									
								
								extras/tests/JsonDocument/size.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								extras/tests/JsonDocument/size.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonDocument::size()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("returns 0") { | ||||
|     REQUIRE(doc.size() == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("as an array, return 2") { | ||||
|     doc.add(1); | ||||
|     doc.add(2); | ||||
|  | ||||
|     REQUIRE(doc.size() == 2); | ||||
|   } | ||||
|  | ||||
|   SECTION("as an object, return 2") { | ||||
|     doc["a"] = 1; | ||||
|     doc["b"] = 2; | ||||
|  | ||||
|     REQUIRE(doc.size() == 2); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										45
									
								
								extras/tests/JsonDocument/subscript.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								extras/tests/JsonDocument/subscript.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonDocument::operator[]") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   const JsonDocument& cdoc = doc; | ||||
|  | ||||
|   SECTION("object") { | ||||
|     deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|     SECTION("const char*") { | ||||
|       REQUIRE(doc["hello"] == "world"); | ||||
|       REQUIRE(cdoc["hello"] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("std::string") { | ||||
|       REQUIRE(doc[std::string("hello")] == "world"); | ||||
|       REQUIRE(cdoc[std::string("hello")] == "world"); | ||||
|     } | ||||
|  | ||||
|     SECTION("supports operator|") { | ||||
|       REQUIRE((doc["hello"] | "nope") == std::string("world")); | ||||
|       REQUIRE((doc["world"] | "nope") == std::string("nope")); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("array") { | ||||
|     deserializeJson(doc, "[\"hello\",\"world\"]"); | ||||
|  | ||||
|     REQUIRE(doc[1] == "world"); | ||||
|     REQUIRE(cdoc[1] == "world"); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonDocument automatically promotes to object") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   doc["one"]["two"]["three"] = 4; | ||||
|  | ||||
|   REQUIRE(doc["one"]["two"]["three"] == 4); | ||||
| } | ||||
							
								
								
									
										23
									
								
								extras/tests/JsonObject/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								extras/tests/JsonObject/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| # ArduinoJson - arduinojson.org | ||||
| # Copyright Benoit Blanchon 2014-2019 | ||||
| # MIT License | ||||
|  | ||||
| add_executable(JsonObjectTests  | ||||
| 	containsKey.cpp | ||||
| 	copy.cpp | ||||
| 	createNestedArray.cpp | ||||
| 	createNestedObject.cpp | ||||
| 	equals.cpp | ||||
| 	invalid.cpp | ||||
| 	isNull.cpp | ||||
| 	iterator.cpp | ||||
| 	memoryUsage.cpp | ||||
| 	nesting.cpp | ||||
| 	remove.cpp | ||||
| 	size.cpp | ||||
| 	std_string.cpp | ||||
| 	subscript.cpp | ||||
| ) | ||||
|  | ||||
| target_link_libraries(JsonObjectTests catch) | ||||
| add_test(JsonObject JsonObjectTests) | ||||
							
								
								
									
										39
									
								
								extras/tests/JsonObject/containsKey.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								extras/tests/JsonObject/containsKey.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonObject::containsKey()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonObject obj = doc.to<JsonObject>(); | ||||
|   obj["hello"] = 42; | ||||
|  | ||||
|   SECTION("returns true only if key is present") { | ||||
|     REQUIRE(false == obj.containsKey("world")); | ||||
|     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"); | ||||
|  | ||||
|     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 | ||||
| } | ||||
							
								
								
									
										68
									
								
								extras/tests/JsonObject/copy.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								extras/tests/JsonObject/copy.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonObject::set()") { | ||||
|   DynamicJsonDocument doc1(4096); | ||||
|   DynamicJsonDocument doc2(4096); | ||||
|  | ||||
|   JsonObject obj1 = doc1.to<JsonObject>(); | ||||
|   JsonObject obj2 = doc2.to<JsonObject>(); | ||||
|  | ||||
|   SECTION("doesn't copy static string in key or value") { | ||||
|     obj1["hello"] = "world"; | ||||
|  | ||||
|     obj2.set(obj1); | ||||
|  | ||||
|     REQUIRE(doc1.memoryUsage() == doc2.memoryUsage()); | ||||
|     REQUIRE(obj2["hello"] == std::string("world")); | ||||
|   } | ||||
|  | ||||
|   SECTION("copy local string value") { | ||||
|     obj1["hello"] = std::string("world"); | ||||
|  | ||||
|     obj2.set(obj1); | ||||
|  | ||||
|     REQUIRE(doc1.memoryUsage() == doc2.memoryUsage()); | ||||
|     REQUIRE(obj2["hello"] == std::string("world")); | ||||
|   } | ||||
|  | ||||
|   SECTION("copy local key") { | ||||
|     obj1[std::string("hello")] = "world"; | ||||
|  | ||||
|     obj2.set(obj1); | ||||
|  | ||||
|     REQUIRE(doc1.memoryUsage() == doc2.memoryUsage()); | ||||
|     REQUIRE(obj2["hello"] == std::string("world")); | ||||
|   } | ||||
|  | ||||
|   SECTION("copy string from deserializeJson()") { | ||||
|     deserializeJson(doc1, "{'hello':'world'}"); | ||||
|  | ||||
|     obj2.set(obj1); | ||||
|  | ||||
|     REQUIRE(doc1.memoryUsage() == doc2.memoryUsage()); | ||||
|     REQUIRE(obj2["hello"] == std::string("world")); | ||||
|   } | ||||
|  | ||||
|   SECTION("copy string from deserializeMsgPack()") { | ||||
|     deserializeMsgPack(doc1, "\x81\xA5hello\xA5world"); | ||||
|  | ||||
|     obj2.set(obj1); | ||||
|  | ||||
|     REQUIRE(doc1.memoryUsage() == doc2.memoryUsage()); | ||||
|     REQUIRE(obj2["hello"] == std::string("world")); | ||||
|   } | ||||
|  | ||||
|   SECTION("should work with JsonObjectConst") { | ||||
|     obj1["hello"] = "world"; | ||||
|  | ||||
|     obj2.set(static_cast<JsonObjectConst>(obj1)); | ||||
|  | ||||
|     REQUIRE(doc1.memoryUsage() == doc2.memoryUsage()); | ||||
|     REQUIRE(obj2["hello"] == std::string("world")); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										27
									
								
								extras/tests/JsonObject/createNestedArray.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								extras/tests/JsonObject/createNestedArray.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonObject::createNestedArray()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonObject obj = doc.to<JsonObject>(); | ||||
|  | ||||
|   SECTION("key is a const char*") { | ||||
|     JsonArray arr = obj.createNestedArray("hello"); | ||||
|     REQUIRE(arr.isNull() == false); | ||||
|   } | ||||
|  | ||||
| #ifdef HAS_VARIABLE_LENGTH_ARRAY | ||||
|   SECTION("key is a VLA") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     JsonArray arr = obj.createNestedArray(vla); | ||||
|     REQUIRE(arr.isNull() == false); | ||||
|   } | ||||
| #endif | ||||
| } | ||||
							
								
								
									
										25
									
								
								extras/tests/JsonObject/createNestedObject.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								extras/tests/JsonObject/createNestedObject.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonObject::createNestedObject()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   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 | ||||
| } | ||||
							
								
								
									
										53
									
								
								extras/tests/JsonObject/equals.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								extras/tests/JsonObject/equals.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonObject::operator==()") { | ||||
|   DynamicJsonDocument doc1(4096); | ||||
|   JsonObject obj1 = doc1.to<JsonObject>(); | ||||
|   JsonObjectConst obj1c = obj1; | ||||
|  | ||||
|   DynamicJsonDocument doc2(4096); | ||||
|   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") { | ||||
|     obj1["hello"] = "coucou"; | ||||
|     obj1["world"] = 666; | ||||
|     obj2["hello"] = "coucou"; | ||||
|  | ||||
|     REQUIRE_FALSE(obj1 == obj2); | ||||
|     REQUIRE_FALSE(obj1c == obj2c); | ||||
|   } | ||||
|  | ||||
|   SECTION("should return false when RKS has more elements") { | ||||
|     obj1["hello"] = "coucou"; | ||||
|     obj2["hello"] = "coucou"; | ||||
|     obj2["world"] = 666; | ||||
|  | ||||
|     REQUIRE_FALSE(obj1 == obj2); | ||||
|     REQUIRE_FALSE(obj1c == obj2c); | ||||
|   } | ||||
|  | ||||
|   SECTION("should return true when objs equal") { | ||||
|     obj1["hello"] = "world"; | ||||
|     obj1["anwser"] = 42; | ||||
|     // insert in different order | ||||
|     obj2["anwser"] = 42; | ||||
|     obj2["hello"] = "world"; | ||||
|  | ||||
|     REQUIRE(obj1 == obj2); | ||||
|     REQUIRE(obj1c == obj2c); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										35
									
								
								extras/tests/JsonObject/invalid.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								extras/tests/JsonObject/invalid.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace Catch::Matchers; | ||||
|  | ||||
| TEST_CASE("JsonObject::invalid()") { | ||||
|   JsonObject obj; | ||||
|  | ||||
|   SECTION("SubscriptFails") { | ||||
|     REQUIRE(obj["key"].isNull()); | ||||
|   } | ||||
|  | ||||
|   SECTION("AddFails") { | ||||
|     obj["hello"] = "world"; | ||||
|     REQUIRE(0 == obj.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("CreateNestedArrayFails") { | ||||
|     REQUIRE(obj.createNestedArray("hello").isNull()); | ||||
|   } | ||||
|  | ||||
|   SECTION("CreateNestedObjectFails") { | ||||
|     REQUIRE(obj.createNestedObject("world").isNull()); | ||||
|   } | ||||
|  | ||||
|   SECTION("serialize to 'null'") { | ||||
|     char buffer[32]; | ||||
|     serializeJson(obj, buffer, sizeof(buffer)); | ||||
|     REQUIRE_THAT(buffer, Equals("null")); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										34
									
								
								extras/tests/JsonObject/isNull.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								extras/tests/JsonObject/isNull.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonObject::isNull()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("returns true") { | ||||
|     JsonObject obj; | ||||
|     REQUIRE(obj.isNull() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns false") { | ||||
|     JsonObject obj = doc.to<JsonObject>(); | ||||
|     REQUIRE(obj.isNull() == false); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonObjectConst::isNull()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("returns true") { | ||||
|     JsonObjectConst obj; | ||||
|     REQUIRE(obj.isNull() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns false") { | ||||
|     JsonObjectConst obj = doc.to<JsonObject>(); | ||||
|     REQUIRE(obj.isNull() == false); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										60
									
								
								extras/tests/JsonObject/iterator.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								extras/tests/JsonObject/iterator.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace Catch::Matchers; | ||||
|  | ||||
| TEST_CASE("JsonObject::begin()/end()") { | ||||
|   StaticJsonDocument<JSON_OBJECT_SIZE(2)> doc; | ||||
|   JsonObject obj = doc.to<JsonObject>(); | ||||
|   obj["ab"] = 12; | ||||
|   obj["cd"] = 34; | ||||
|  | ||||
|   SECTION("NonConstIterator") { | ||||
|     JsonObject::iterator it = obj.begin(); | ||||
|     REQUIRE(obj.end() != it); | ||||
|     REQUIRE(it->key() == "ab"); | ||||
|     REQUIRE(12 == it->value()); | ||||
|     ++it; | ||||
|     REQUIRE(obj.end() != it); | ||||
|     REQUIRE(it->key() == "cd"); | ||||
|     REQUIRE(34 == it->value()); | ||||
|     ++it; | ||||
|     REQUIRE(obj.end() == it); | ||||
|   } | ||||
|  | ||||
|   SECTION("Dereferencing end() is safe") { | ||||
|     REQUIRE(obj.end()->key().isNull()); | ||||
|     REQUIRE(obj.end()->value().isNull()); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonObjectConst::begin()/end()") { | ||||
|   StaticJsonDocument<JSON_OBJECT_SIZE(2)> doc; | ||||
|   JsonObject obj = doc.to<JsonObject>(); | ||||
|   obj["ab"] = 12; | ||||
|   obj["cd"] = 34; | ||||
|  | ||||
|   JsonObjectConst cobj = obj; | ||||
|  | ||||
|   SECTION("NonConstIterator") { | ||||
|     JsonObjectConst::iterator it = cobj.begin(); | ||||
|     REQUIRE(cobj.end() != it); | ||||
|     REQUIRE(it->key() == "ab"); | ||||
|     REQUIRE(12 == it->value()); | ||||
|     ++it; | ||||
|     REQUIRE(cobj.end() != it); | ||||
|     REQUIRE(it->key() == "cd"); | ||||
|     REQUIRE(34 == it->value()); | ||||
|     ++it; | ||||
|     REQUIRE(cobj.end() == it); | ||||
|   } | ||||
|  | ||||
|   SECTION("Dereferencing end() is safe") { | ||||
|     REQUIRE(cobj.end()->key().isNull()); | ||||
|     REQUIRE(cobj.end()->value().isNull()); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										43
									
								
								extras/tests/JsonObject/memoryUsage.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								extras/tests/JsonObject/memoryUsage.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
| #include <string> | ||||
|  | ||||
| TEST_CASE("JsonObject::memoryUsage()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonObject obj = doc.to<JsonObject>(); | ||||
|  | ||||
|   SECTION("return 0 if uninitialized") { | ||||
|     JsonObject unitialized; | ||||
|     REQUIRE(unitialized.memoryUsage() == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("JSON_OBJECT_SIZE(0) for empty object") { | ||||
|     REQUIRE(obj.memoryUsage() == JSON_OBJECT_SIZE(0)); | ||||
|   } | ||||
|  | ||||
|   SECTION("JSON_OBJECT_SIZE(1) after add") { | ||||
|     obj["hello"] = 42; | ||||
|     REQUIRE(obj.memoryUsage() == JSON_OBJECT_SIZE(1)); | ||||
|   } | ||||
|  | ||||
|   SECTION("includes the size of the key") { | ||||
|     obj[std::string("hello")] = 42; | ||||
|     REQUIRE(obj.memoryUsage() == JSON_OBJECT_SIZE(1) + 6); | ||||
|   } | ||||
|  | ||||
|   SECTION("includes the size of the nested array") { | ||||
|     JsonArray nested = obj.createNestedArray("nested"); | ||||
|     nested.add(42); | ||||
|     REQUIRE(obj.memoryUsage() == JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(1)); | ||||
|   } | ||||
|  | ||||
|   SECTION("includes the size of the nested object") { | ||||
|     JsonObject nested = obj.createNestedObject("nested"); | ||||
|     nested["hello"] = "world"; | ||||
|     REQUIRE(obj.memoryUsage() == 2 * JSON_OBJECT_SIZE(1)); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										35
									
								
								extras/tests/JsonObject/nesting.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								extras/tests/JsonObject/nesting.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonObject::nesting()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonObject obj = doc.to<JsonObject>(); | ||||
|  | ||||
|   SECTION("return 0 if uninitialized") { | ||||
|     JsonObject unitialized; | ||||
|     REQUIRE(unitialized.nesting() == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns 1 for empty object") { | ||||
|     REQUIRE(obj.nesting() == 1); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns 1 for flat object") { | ||||
|     obj["hello"] = "world"; | ||||
|     REQUIRE(obj.nesting() == 1); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns 2 with nested array") { | ||||
|     obj.createNestedArray("nested"); | ||||
|     REQUIRE(obj.nesting() == 2); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns 2 with nested object") { | ||||
|     obj.createNestedObject("nested"); | ||||
|     REQUIRE(obj.nesting() == 2); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										72
									
								
								extras/tests/JsonObject/remove.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								extras/tests/JsonObject/remove.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
| #include <string> | ||||
|  | ||||
| TEST_CASE("JsonObject::remove()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonObject obj = doc.to<JsonObject>(); | ||||
|   obj["a"] = 0; | ||||
|   obj["b"] = 1; | ||||
|   obj["c"] = 2; | ||||
|   std::string result; | ||||
|  | ||||
|   SECTION("remove(key)") { | ||||
|     SECTION("Remove first") { | ||||
|       obj.remove("a"); | ||||
|       serializeJson(obj, result); | ||||
|       REQUIRE("{\"b\":1,\"c\":2}" == result); | ||||
|     } | ||||
|  | ||||
|     SECTION("Remove middle") { | ||||
|       obj.remove("b"); | ||||
|       serializeJson(obj, result); | ||||
|       REQUIRE("{\"a\":0,\"c\":2}" == result); | ||||
|     } | ||||
|  | ||||
|     SECTION("Remove last") { | ||||
|       obj.remove("c"); | ||||
|       serializeJson(obj, result); | ||||
|       REQUIRE("{\"a\":0,\"b\":1}" == result); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("remove(iterator)") { | ||||
|     JsonObject::iterator it = obj.begin(); | ||||
|  | ||||
|     SECTION("Remove first") { | ||||
|       obj.remove(it); | ||||
|       serializeJson(obj, result); | ||||
|       REQUIRE("{\"b\":1,\"c\":2}" == result); | ||||
|     } | ||||
|  | ||||
|     SECTION("Remove middle") { | ||||
|       ++it; | ||||
|       obj.remove(it); | ||||
|       serializeJson(obj, result); | ||||
|       REQUIRE("{\"a\":0,\"c\":2}" == result); | ||||
|     } | ||||
|  | ||||
|     SECTION("Remove last") { | ||||
|       it += 2; | ||||
|       obj.remove(it); | ||||
|       serializeJson(obj, result); | ||||
|       REQUIRE("{\"a\":0,\"b\":1}" == result); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| #ifdef HAS_VARIABLE_LENGTH_ARRAY | ||||
|   SECTION("key is a vla") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "b"); | ||||
|     obj.remove(vla); | ||||
|  | ||||
|     serializeJson(obj, result); | ||||
|     REQUIRE("{\"a\":0,\"c\":2}" == result); | ||||
|   } | ||||
| #endif | ||||
| } | ||||
							
								
								
									
										39
									
								
								extras/tests/JsonObject/size.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								extras/tests/JsonObject/size.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
| #include <string> | ||||
|  | ||||
| TEST_CASE("JsonObject::size()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonObject obj = doc.to<JsonObject>(); | ||||
|  | ||||
|   SECTION("initial size is zero") { | ||||
|     REQUIRE(0 == obj.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("increases when values are added") { | ||||
|     obj["hello"] = 42; | ||||
|     REQUIRE(1 == obj.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("decreases when values are removed") { | ||||
|     obj["hello"] = 42; | ||||
|     obj.remove("hello"); | ||||
|     REQUIRE(0 == obj.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("doesn't increase when the same key is added twice") { | ||||
|     obj["hello"] = 1; | ||||
|     obj["hello"] = 2; | ||||
|     REQUIRE(1 == obj.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("doesn't decrease when another key is removed") { | ||||
|     obj["hello"] = 1; | ||||
|     obj.remove("world"); | ||||
|     REQUIRE(1 == obj.size()); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										109
									
								
								extras/tests/JsonObject/std_string.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								extras/tests/JsonObject/std_string.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| static void eraseString(std::string &str) { | ||||
|   char *p = const_cast<char *>(str.c_str()); | ||||
|   while (*p) *p++ = '*'; | ||||
| } | ||||
|  | ||||
| TEST_CASE("std::string") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   SECTION("operator[]") { | ||||
|     char json[] = "{\"key\":\"value\"}"; | ||||
|  | ||||
|     deserializeJson(doc, json); | ||||
|     JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|     REQUIRE(std::string("value") == obj[std::string("key")]); | ||||
|   } | ||||
|  | ||||
|   SECTION("operator[] const") { | ||||
|     char json[] = "{\"key\":\"value\"}"; | ||||
|  | ||||
|     deserializeJson(doc, json); | ||||
|     JsonObject obj = doc.as<JsonObject>(); | ||||
|  | ||||
|     REQUIRE(std::string("value") == obj[std::string("key")]); | ||||
|   } | ||||
|  | ||||
|   SECTION("createNestedObject()") { | ||||
|     JsonObject obj = doc.to<JsonObject>(); | ||||
|     std::string key = "key"; | ||||
|     char json[64]; | ||||
|     obj.createNestedObject(key); | ||||
|     eraseString(key); | ||||
|     serializeJson(doc, json, sizeof(json)); | ||||
|     REQUIRE(std::string("{\"key\":{}}") == json); | ||||
|   } | ||||
|  | ||||
|   SECTION("createNestedArray()") { | ||||
|     JsonObject obj = doc.to<JsonObject>(); | ||||
|     std::string key = "key"; | ||||
|     char json[64]; | ||||
|     obj.createNestedArray(key); | ||||
|     eraseString(key); | ||||
|     serializeJson(doc, json, sizeof(json)); | ||||
|     REQUIRE(std::string("{\"key\":[]}") == json); | ||||
|   } | ||||
|  | ||||
|   SECTION("containsKey()") { | ||||
|     char json[] = "{\"key\":\"value\"}"; | ||||
|     deserializeJson(doc, json); | ||||
|     JsonObject obj = doc.as<JsonObject>(); | ||||
|     REQUIRE(true == obj.containsKey(std::string("key"))); | ||||
|   } | ||||
|  | ||||
|   SECTION("remove()") { | ||||
|     JsonObject obj = doc.to<JsonObject>(); | ||||
|     obj["key"] = "value"; | ||||
|  | ||||
|     obj.remove(std::string("key")); | ||||
|  | ||||
|     REQUIRE(0 == obj.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("operator[], set key") { | ||||
|     std::string key("hello"); | ||||
|     JsonObject obj = doc.to<JsonObject>(); | ||||
|     obj[key] = "world"; | ||||
|     eraseString(key); | ||||
|     REQUIRE(std::string("world") == obj["hello"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("operator[], set value") { | ||||
|     std::string value("world"); | ||||
|     JsonObject obj = doc.to<JsonObject>(); | ||||
|     obj["hello"] = value; | ||||
|     eraseString(value); | ||||
|     REQUIRE(std::string("world") == obj["hello"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("memoryUsage() increases when adding a new key") { | ||||
|     std::string key1("hello"), key2("world"); | ||||
|     JsonObject obj = doc.to<JsonObject>(); | ||||
|  | ||||
|     obj[key1] = 1; | ||||
|     size_t sizeBefore = doc.memoryUsage(); | ||||
|     obj[key2] = 2; | ||||
|     size_t sizeAfter = doc.memoryUsage(); | ||||
|  | ||||
|     REQUIRE(sizeAfter - sizeBefore >= key2.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("memoryUsage() remains when adding the same key") { | ||||
|     std::string key("hello"); | ||||
|     JsonObject obj = doc.to<JsonObject>(); | ||||
|  | ||||
|     obj[key] = 1; | ||||
|     size_t sizeBefore = doc.memoryUsage(); | ||||
|     obj[key] = 2; | ||||
|     size_t sizeAfter = doc.memoryUsage(); | ||||
|  | ||||
|     REQUIRE(sizeBefore == sizeAfter); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										234
									
								
								extras/tests/JsonObject/subscript.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										234
									
								
								extras/tests/JsonObject/subscript.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,234 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonObject::operator[]") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonObject obj = doc.to<JsonObject>(); | ||||
|  | ||||
|   SECTION("int") { | ||||
|     obj["hello"] = 123; | ||||
|  | ||||
|     REQUIRE(123 == obj["hello"].as<int>()); | ||||
|     REQUIRE(true == obj["hello"].is<int>()); | ||||
|     REQUIRE(false == obj["hello"].is<bool>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("volatile int") {  // issue #415 | ||||
|     volatile int i = 123; | ||||
|     obj["hello"] = i; | ||||
|  | ||||
|     REQUIRE(123 == obj["hello"].as<int>()); | ||||
|     REQUIRE(true == obj["hello"].is<int>()); | ||||
|     REQUIRE(false == obj["hello"].is<bool>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("double") { | ||||
|     obj["hello"] = 123.45; | ||||
|  | ||||
|     REQUIRE(true == obj["hello"].is<double>()); | ||||
|     REQUIRE(false == obj["hello"].is<long>()); | ||||
|     REQUIRE(123.45 == obj["hello"].as<double>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("bool") { | ||||
|     obj["hello"] = true; | ||||
|  | ||||
|     REQUIRE(true == obj["hello"].is<bool>()); | ||||
|     REQUIRE(false == obj["hello"].is<long>()); | ||||
|     REQUIRE(true == obj["hello"].as<bool>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("const char*") { | ||||
|     obj["hello"] = "h3110"; | ||||
|  | ||||
|     REQUIRE(true == obj["hello"].is<const char*>()); | ||||
|     REQUIRE(false == obj["hello"].is<long>()); | ||||
|     REQUIRE(std::string("h3110") == obj["hello"].as<const char*>()); | ||||
|     REQUIRE(std::string("h3110") == obj["hello"].as<char*>());  // <- short hand | ||||
|   } | ||||
|  | ||||
|   SECTION("array") { | ||||
|     DynamicJsonDocument doc2(4096); | ||||
|     JsonArray arr = doc2.to<JsonArray>(); | ||||
|  | ||||
|     obj["hello"] = arr; | ||||
|  | ||||
|     REQUIRE(arr == obj["hello"].as<JsonArray>()); | ||||
|     REQUIRE(true == obj["hello"].is<JsonArray>()); | ||||
|     REQUIRE(false == obj["hello"].is<JsonObject>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("object") { | ||||
|     DynamicJsonDocument doc2(4096); | ||||
|     JsonObject obj2 = doc2.to<JsonObject>(); | ||||
|  | ||||
|     obj["hello"] = obj2; | ||||
|  | ||||
|     REQUIRE(obj2 == obj["hello"].as<JsonObject>()); | ||||
|     REQUIRE(true == obj["hello"].is<JsonObject>()); | ||||
|     REQUIRE(false == obj["hello"].is<JsonArray>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("array subscript") { | ||||
|     DynamicJsonDocument doc2(4096); | ||||
|     JsonArray arr = doc2.to<JsonArray>(); | ||||
|     arr.add(42); | ||||
|  | ||||
|     obj["a"] = arr[0]; | ||||
|  | ||||
|     REQUIRE(42 == obj["a"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("object subscript") { | ||||
|     DynamicJsonDocument doc2(4096); | ||||
|     JsonObject obj2 = doc2.to<JsonObject>(); | ||||
|     obj2["x"] = 42; | ||||
|  | ||||
|     obj["a"] = obj2["x"]; | ||||
|  | ||||
|     REQUIRE(42 == obj["a"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("char key[]") {  // issue #423 | ||||
|     char key[] = "hello"; | ||||
|     obj[key] = 42; | ||||
|     REQUIRE(42 == obj[key]); | ||||
|   } | ||||
|  | ||||
|   SECTION("should not duplicate const char*") { | ||||
|     obj["hello"] = "world"; | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char* value") { | ||||
|     obj["hello"] = const_cast<char*>("world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(6); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char* key") { | ||||
|     obj[const_cast<char*>("hello")] = "world"; | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(6); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char* key&value") { | ||||
|     obj[const_cast<char*>("hello")] = const_cast<char*>("world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 2 * JSON_STRING_SIZE(6); | ||||
|     REQUIRE(expectedSize <= doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string value") { | ||||
|     obj["hello"] = std::string("world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(6); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string key") { | ||||
|     obj[std::string("hello")] = "world"; | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(6); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string key&value") { | ||||
|     obj[std::string("hello")] = std::string("world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 2 * JSON_STRING_SIZE(6); | ||||
|     REQUIRE(expectedSize <= doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate a non-static JsonString key") { | ||||
|     obj[JsonString("hello", false)] = "world"; | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(6); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should not duplicate a static JsonString key") { | ||||
|     obj[JsonString("hello", true)] = "world"; | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should ignore null key") { | ||||
|     // object must have a value to make a call to strcmp() | ||||
|     obj["dummy"] = 42; | ||||
|  | ||||
|     const char* null = 0; | ||||
|     obj[null] = 666; | ||||
|  | ||||
|     REQUIRE(obj.size() == 1); | ||||
|     REQUIRE(obj[null] == null); | ||||
|   } | ||||
|  | ||||
|   SECTION("obj[key].to<JsonArray>()") { | ||||
|     JsonArray arr = obj["hello"].to<JsonArray>(); | ||||
|  | ||||
|     REQUIRE(arr.isNull() == false); | ||||
|   } | ||||
|  | ||||
| #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 | ||||
|  | ||||
|   SECTION("chain") { | ||||
|     obj.createNestedObject("hello")["world"] = 123; | ||||
|  | ||||
|     REQUIRE(123 == obj["hello"]["world"].as<int>()); | ||||
|     REQUIRE(true == obj["hello"]["world"].is<int>()); | ||||
|     REQUIRE(false == obj["hello"]["world"].is<bool>()); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										17
									
								
								extras/tests/JsonSerializer/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								extras/tests/JsonSerializer/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| # ArduinoJson - arduinojson.org | ||||
| # Copyright Benoit Blanchon 2014-2019 | ||||
| # MIT License | ||||
|  | ||||
| add_executable(JsonSerializerTests | ||||
| 	JsonArray.cpp | ||||
| 	JsonArrayPretty.cpp | ||||
| 	JsonObject.cpp | ||||
| 	JsonObjectPretty.cpp | ||||
| 	JsonVariant.cpp | ||||
| 	misc.cpp | ||||
| 	std_stream.cpp | ||||
| 	std_string.cpp | ||||
| ) | ||||
|  | ||||
| target_link_libraries(JsonSerializerTests catch) | ||||
| add_test(JsonSerializer JsonSerializerTests) | ||||
							
								
								
									
										129
									
								
								extras/tests/JsonSerializer/JsonArray.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								extras/tests/JsonSerializer/JsonArray.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,129 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| static void check(JsonArray array, std::string expected) { | ||||
|   std::string actual; | ||||
|   size_t actualLen = serializeJson(array, actual); | ||||
|   REQUIRE(expected == actual); | ||||
|   REQUIRE(actualLen == expected.size()); | ||||
|   size_t measuredLen = measureJson(array); | ||||
|   REQUIRE(measuredLen == expected.size()); | ||||
| } | ||||
|  | ||||
| TEST_CASE("serializeJson(JsonArray)") { | ||||
|   StaticJsonDocument<JSON_ARRAY_SIZE(2)> doc; | ||||
|   JsonArray array = doc.to<JsonArray>(); | ||||
|  | ||||
|   SECTION("Empty") { | ||||
|     check(array, "[]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Null") { | ||||
|     array.add(static_cast<char *>(0)); | ||||
|  | ||||
|     check(array, "[null]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("OneString") { | ||||
|     array.add("hello"); | ||||
|  | ||||
|     check(array, "[\"hello\"]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("TwoStrings") { | ||||
|     array.add("hello"); | ||||
|     array.add("world"); | ||||
|  | ||||
|     check(array, "[\"hello\",\"world\"]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("OneStringOverCapacity") { | ||||
|     array.add("hello"); | ||||
|     array.add("world"); | ||||
|     array.add("lost"); | ||||
|  | ||||
|     check(array, "[\"hello\",\"world\"]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("One double") { | ||||
|     array.add(3.1415927); | ||||
|     check(array, "[3.1415927]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("OneInteger") { | ||||
|     array.add(1); | ||||
|  | ||||
|     check(array, "[1]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("TwoIntegers") { | ||||
|     array.add(1); | ||||
|     array.add(2); | ||||
|  | ||||
|     check(array, "[1,2]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("serialized(const char*)") { | ||||
|     array.add(serialized("{\"key\":\"value\"}")); | ||||
|  | ||||
|     check(array, "[{\"key\":\"value\"}]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("serialized(char*)") { | ||||
|     char tmp[] = "{\"key\":\"value\"}"; | ||||
|     array.add(serialized(tmp)); | ||||
|  | ||||
|     check(array, "[{\"key\":\"value\"}]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("OneIntegerOverCapacity") { | ||||
|     array.add(1); | ||||
|     array.add(2); | ||||
|     array.add(3); | ||||
|  | ||||
|     check(array, "[1,2]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("OneTrue") { | ||||
|     array.add(true); | ||||
|  | ||||
|     check(array, "[true]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("OneFalse") { | ||||
|     array.add(false); | ||||
|  | ||||
|     check(array, "[false]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("TwoBooleans") { | ||||
|     array.add(false); | ||||
|     array.add(true); | ||||
|  | ||||
|     check(array, "[false,true]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("OneBooleanOverCapacity") { | ||||
|     array.add(false); | ||||
|     array.add(true); | ||||
|     array.add(false); | ||||
|  | ||||
|     check(array, "[false,true]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("OneEmptyNestedArray") { | ||||
|     array.createNestedArray(); | ||||
|  | ||||
|     check(array, "[[]]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("OneEmptyNestedHash") { | ||||
|     array.createNestedObject(); | ||||
|  | ||||
|     check(array, "[{}]"); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										75
									
								
								extras/tests/JsonSerializer/JsonArrayPretty.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								extras/tests/JsonSerializer/JsonArrayPretty.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| static void check(JsonArray array, std::string expected) { | ||||
|   std::string actual; | ||||
|   size_t actualLen = serializeJsonPretty(array, actual); | ||||
|   size_t measuredLen = measureJsonPretty(array); | ||||
|   CHECK(actualLen == expected.size()); | ||||
|   CHECK(measuredLen == expected.size()); | ||||
|   REQUIRE(expected == actual); | ||||
| } | ||||
|  | ||||
| TEST_CASE("serializeJsonPretty(JsonArray)") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonArray array = doc.to<JsonArray>(); | ||||
|  | ||||
|   SECTION("Empty") { | ||||
|     check(array, "[]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("OneElement") { | ||||
|     array.add(1); | ||||
|  | ||||
|     check(array, | ||||
|           "[\r\n" | ||||
|           "  1\r\n" | ||||
|           "]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("TwoElements") { | ||||
|     array.add(1); | ||||
|     array.add(2); | ||||
|  | ||||
|     check(array, | ||||
|           "[\r\n" | ||||
|           "  1,\r\n" | ||||
|           "  2\r\n" | ||||
|           "]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("EmptyNestedArrays") { | ||||
|     array.createNestedArray(); | ||||
|     array.createNestedArray(); | ||||
|  | ||||
|     check(array, | ||||
|           "[\r\n" | ||||
|           "  [],\r\n" | ||||
|           "  []\r\n" | ||||
|           "]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("NestedArrays") { | ||||
|     JsonArray nested1 = array.createNestedArray(); | ||||
|     nested1.add(1); | ||||
|     nested1.add(2); | ||||
|  | ||||
|     JsonObject nested2 = array.createNestedObject(); | ||||
|     nested2["key"] = 3; | ||||
|  | ||||
|     check(array, | ||||
|           "[\r\n" | ||||
|           "  [\r\n" | ||||
|           "    1,\r\n" | ||||
|           "    2\r\n" | ||||
|           "  ],\r\n" | ||||
|           "  {\r\n" | ||||
|           "    \"key\": 3\r\n" | ||||
|           "  }\r\n" | ||||
|           "]"); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										116
									
								
								extras/tests/JsonSerializer/JsonObject.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								extras/tests/JsonSerializer/JsonObject.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,116 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
| #include <string> | ||||
|  | ||||
| void check(const JsonObject obj, const std::string &expected) { | ||||
|   char actual[256]; | ||||
|   size_t actualLen = serializeJson(obj, actual); | ||||
|   size_t measuredLen = measureJson(obj); | ||||
|  | ||||
|   REQUIRE(expected == actual); | ||||
|   REQUIRE(expected.size() == actualLen); | ||||
|   REQUIRE(expected.size() == measuredLen); | ||||
| } | ||||
|  | ||||
| TEST_CASE("serializeJson(JsonObject)") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonObject obj = doc.to<JsonObject>(); | ||||
|  | ||||
|   SECTION("EmptyObject") { | ||||
|     check(obj, "{}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("TwoStrings") { | ||||
|     obj["key1"] = "value1"; | ||||
|     obj["key2"] = "value2"; | ||||
|  | ||||
|     check(obj, "{\"key1\":\"value1\",\"key2\":\"value2\"}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("RemoveFirst") { | ||||
|     obj["key1"] = "value1"; | ||||
|     obj["key2"] = "value2"; | ||||
|     obj.remove("key1"); | ||||
|  | ||||
|     check(obj, "{\"key2\":\"value2\"}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("RemoveLast") { | ||||
|     obj["key1"] = "value1"; | ||||
|     obj["key2"] = "value2"; | ||||
|     obj.remove("key2"); | ||||
|  | ||||
|     check(obj, "{\"key1\":\"value1\"}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("RemoveUnexistingKey") { | ||||
|     obj["key1"] = "value1"; | ||||
|     obj["key2"] = "value2"; | ||||
|     obj.remove("key3"); | ||||
|  | ||||
|     check(obj, "{\"key1\":\"value1\",\"key2\":\"value2\"}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("ReplaceExistingKey") { | ||||
|     obj["key"] = "value1"; | ||||
|     obj["key"] = "value2"; | ||||
|  | ||||
|     check(obj, "{\"key\":\"value2\"}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("TwoIntegers") { | ||||
|     obj["a"] = 1; | ||||
|     obj["b"] = 2; | ||||
|     check(obj, "{\"a\":1,\"b\":2}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("serialized(const char*)") { | ||||
|     obj["a"] = serialized("[1,2]"); | ||||
|     obj["b"] = serialized("[4,5]"); | ||||
|     check(obj, "{\"a\":[1,2],\"b\":[4,5]}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Two doubles") { | ||||
|     obj["a"] = 12.34; | ||||
|     obj["b"] = 56.78; | ||||
|     check(obj, "{\"a\":12.34,\"b\":56.78}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("TwoNull") { | ||||
|     obj["a"] = static_cast<char *>(0); | ||||
|     obj["b"] = static_cast<char *>(0); | ||||
|     check(obj, "{\"a\":null,\"b\":null}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("TwoBooleans") { | ||||
|     obj["a"] = true; | ||||
|     obj["b"] = false; | ||||
|     check(obj, "{\"a\":true,\"b\":false}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("ThreeNestedArrays") { | ||||
|     DynamicJsonDocument b(4096); | ||||
|     DynamicJsonDocument c(4096); | ||||
|  | ||||
|     obj.createNestedArray("a"); | ||||
|     obj["b"] = b.to<JsonArray>(); | ||||
|     obj["c"] = c.to<JsonArray>(); | ||||
|  | ||||
|     check(obj, "{\"a\":[],\"b\":[],\"c\":[]}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("ThreeNestedObjects") { | ||||
|     DynamicJsonDocument b(4096); | ||||
|     DynamicJsonDocument c(4096); | ||||
|  | ||||
|     obj.createNestedObject("a"); | ||||
|     obj["b"] = b.to<JsonObject>(); | ||||
|     obj["c"] = c.to<JsonObject>(); | ||||
|  | ||||
|     check(obj, "{\"a\":{},\"b\":{},\"c\":{}}"); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										76
									
								
								extras/tests/JsonSerializer/JsonObjectPretty.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								extras/tests/JsonSerializer/JsonObjectPretty.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
| #include <string> | ||||
|  | ||||
| void check(const JsonObject obj, const std::string expected) { | ||||
|   char json[256]; | ||||
|  | ||||
|   size_t actualLen = serializeJsonPretty(obj, json); | ||||
|   size_t measuredLen = measureJsonPretty(obj); | ||||
|  | ||||
|   REQUIRE(json == expected); | ||||
|   REQUIRE(expected.size() == actualLen); | ||||
|   REQUIRE(expected.size() == measuredLen); | ||||
| } | ||||
|  | ||||
| TEST_CASE("serializeJsonPretty(JsonObject)") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonObject obj = doc.to<JsonObject>(); | ||||
|  | ||||
|   SECTION("EmptyObject") { | ||||
|     check(obj, "{}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("OneMember") { | ||||
|     obj["key"] = "value"; | ||||
|  | ||||
|     check(obj, | ||||
|           "{\r\n" | ||||
|           "  \"key\": \"value\"\r\n" | ||||
|           "}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("TwoMembers") { | ||||
|     obj["key1"] = "value1"; | ||||
|     obj["key2"] = "value2"; | ||||
|  | ||||
|     check(obj, | ||||
|           "{\r\n" | ||||
|           "  \"key1\": \"value1\",\r\n" | ||||
|           "  \"key2\": \"value2\"\r\n" | ||||
|           "}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("EmptyNestedContainers") { | ||||
|     obj.createNestedObject("key1"); | ||||
|     obj.createNestedArray("key2"); | ||||
|  | ||||
|     check(obj, | ||||
|           "{\r\n" | ||||
|           "  \"key1\": {},\r\n" | ||||
|           "  \"key2\": []\r\n" | ||||
|           "}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("NestedContainers") { | ||||
|     JsonObject nested1 = obj.createNestedObject("key1"); | ||||
|     nested1["a"] = 1; | ||||
|  | ||||
|     JsonArray nested2 = obj.createNestedArray("key2"); | ||||
|     nested2.add(2); | ||||
|  | ||||
|     check(obj, | ||||
|           "{\r\n" | ||||
|           "  \"key1\": {\r\n" | ||||
|           "    \"a\": 1\r\n" | ||||
|           "  },\r\n" | ||||
|           "  \"key2\": [\r\n" | ||||
|           "    2\r\n" | ||||
|           "  ]\r\n" | ||||
|           "}"); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										85
									
								
								extras/tests/JsonSerializer/JsonVariant.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								extras/tests/JsonSerializer/JsonVariant.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,85 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
| #include <limits> | ||||
|  | ||||
| template <typename T> | ||||
| void check(T value, const std::string &expected) { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   doc.to<JsonVariant>().set(value); | ||||
|   char buffer[256] = ""; | ||||
|   size_t returnValue = serializeJson(doc, buffer, sizeof(buffer)); | ||||
|   REQUIRE(expected == buffer); | ||||
|   REQUIRE(expected.size() == returnValue); | ||||
| } | ||||
|  | ||||
| TEST_CASE("serializeJson(JsonVariant)") { | ||||
|   SECTION("Undefined") { | ||||
|     check(JsonVariant(), "null"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Null string") { | ||||
|     check(static_cast<char *>(0), "null"); | ||||
|   } | ||||
|  | ||||
|   SECTION("const char*") { | ||||
|     check("hello", "\"hello\""); | ||||
|   } | ||||
|  | ||||
|   SECTION("string") { | ||||
|     check(std::string("hello"), "\"hello\""); | ||||
|   } | ||||
|  | ||||
|   SECTION("SerializedValue<const char*>") { | ||||
|     check(serialized("[1,2]"), "[1,2]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("SerializedValue<std::string>") { | ||||
|     check(serialized(std::string("[1,2]")), "[1,2]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Double") { | ||||
|     check(3.1415927, "3.1415927"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Zero") { | ||||
|     check(0, "0"); | ||||
|   } | ||||
|  | ||||
|   SECTION("Integer") { | ||||
|     check(42, "42"); | ||||
|   } | ||||
|  | ||||
|   SECTION("NegativeLong") { | ||||
|     check(-42, "-42"); | ||||
|   } | ||||
|  | ||||
|   SECTION("UnsignedLong") { | ||||
|     check(4294967295UL, "4294967295"); | ||||
|   } | ||||
|  | ||||
|   SECTION("True") { | ||||
|     check(true, "true"); | ||||
|   } | ||||
|  | ||||
|   SECTION("OneFalse") { | ||||
|     check(false, "false"); | ||||
|   } | ||||
|  | ||||
| #if ARDUINOJSON_USE_LONG_LONG | ||||
|   SECTION("NegativeInt64") { | ||||
|     check(-9223372036854775807 - 1, "-9223372036854775808"); | ||||
|   } | ||||
|  | ||||
|   SECTION("PositiveInt64") { | ||||
|     check(9223372036854775807, "9223372036854775807"); | ||||
|   } | ||||
|  | ||||
|   SECTION("UInt64") { | ||||
|     check(18446744073709551615U, "18446744073709551615"); | ||||
|   } | ||||
| #endif | ||||
| } | ||||
							
								
								
									
										46
									
								
								extras/tests/JsonSerializer/misc.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								extras/tests/JsonSerializer/misc.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
| #include <limits> | ||||
|  | ||||
| template <typename T> | ||||
| void check(T value, const std::string &expected) { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   doc.to<JsonVariant>().set(value); | ||||
|   char buffer[256] = ""; | ||||
|   size_t returnValue = serializeJson(doc, buffer, sizeof(buffer)); | ||||
|   REQUIRE(expected == buffer); | ||||
|   REQUIRE(expected.size() == returnValue); | ||||
| } | ||||
|  | ||||
| TEST_CASE("serializeJson(MemberProxy)") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   deserializeJson(doc, "{\"hello\":42}"); | ||||
|   JsonObject obj = doc.as<JsonObject>(); | ||||
|   std::string result; | ||||
|  | ||||
|   serializeJson(obj["hello"], result); | ||||
|  | ||||
|   REQUIRE(result == "42"); | ||||
| } | ||||
|  | ||||
| TEST_CASE("serializeJson(ElementProxy)") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   deserializeJson(doc, "[42]"); | ||||
|   JsonArray arr = doc.as<JsonArray>(); | ||||
|   std::string result; | ||||
|  | ||||
|   serializeJson(arr[0], result); | ||||
|  | ||||
|   REQUIRE(result == "42"); | ||||
| } | ||||
|  | ||||
| TEST_CASE("serializeJson(JsonVariantSubscript)") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   deserializeJson(doc, "[42]"); | ||||
|   JsonVariant var = doc.as<JsonVariant>(); | ||||
|   std::string result; | ||||
|  | ||||
|   serializeJson(var[0], result); | ||||
|  | ||||
|   REQUIRE(result == "42"); | ||||
| } | ||||
							
								
								
									
										66
									
								
								extras/tests/JsonSerializer/std_stream.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								extras/tests/JsonSerializer/std_stream.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
| #include <sstream> | ||||
|  | ||||
| TEST_CASE("operator<<(std::ostream)") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   std::ostringstream os; | ||||
|  | ||||
|   SECTION("JsonVariant containing false") { | ||||
|     JsonVariant variant = doc.to<JsonVariant>(); | ||||
|  | ||||
|     variant.set(false); | ||||
|     os << variant; | ||||
|  | ||||
|     REQUIRE("false" == os.str()); | ||||
|   } | ||||
|  | ||||
|   SECTION("JsonVariant containing string") { | ||||
|     JsonVariant variant = doc.to<JsonVariant>(); | ||||
|  | ||||
|     variant.set("coucou"); | ||||
|     os << variant; | ||||
|  | ||||
|     REQUIRE("\"coucou\"" == os.str()); | ||||
|   } | ||||
|  | ||||
|   SECTION("JsonObject") { | ||||
|     JsonObject object = doc.to<JsonObject>(); | ||||
|     object["key"] = "value"; | ||||
|  | ||||
|     os << object; | ||||
|  | ||||
|     REQUIRE("{\"key\":\"value\"}" == os.str()); | ||||
|   } | ||||
|  | ||||
|   SECTION("MemberProxy") { | ||||
|     JsonObject object = doc.to<JsonObject>(); | ||||
|     object["key"] = "value"; | ||||
|  | ||||
|     os << object["key"]; | ||||
|  | ||||
|     REQUIRE("\"value\"" == os.str()); | ||||
|   } | ||||
|  | ||||
|   SECTION("JsonArray") { | ||||
|     JsonArray array = doc.to<JsonArray>(); | ||||
|     array.add("value"); | ||||
|  | ||||
|     os << array; | ||||
|  | ||||
|     REQUIRE("[\"value\"]" == os.str()); | ||||
|   } | ||||
|  | ||||
|   SECTION("ElementProxy") { | ||||
|     JsonArray array = doc.to<JsonArray>(); | ||||
|     array.add("value"); | ||||
|  | ||||
|     os << array[0]; | ||||
|  | ||||
|     REQUIRE("\"value\"" == os.str()); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										47
									
								
								extras/tests/JsonSerializer/std_string.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								extras/tests/JsonSerializer/std_string.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("serialize JsonArray to std::string") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonArray array = doc.to<JsonArray>(); | ||||
|   array.add(4); | ||||
|   array.add(2); | ||||
|  | ||||
|   SECTION("serializeJson()") { | ||||
|     std::string json; | ||||
|     serializeJson(array, json); | ||||
|  | ||||
|     REQUIRE("[4,2]" == json); | ||||
|   } | ||||
|  | ||||
|   SECTION("serializeJsonPretty") { | ||||
|     std::string json; | ||||
|     serializeJsonPretty(array, json); | ||||
|  | ||||
|     REQUIRE("[\r\n  4,\r\n  2\r\n]" == json); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("serialize JsonObject to std::string") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonObject obj = doc.to<JsonObject>(); | ||||
|   obj["key"] = "value"; | ||||
|  | ||||
|   SECTION("object") { | ||||
|     std::string json; | ||||
|     serializeJson(doc, json); | ||||
|  | ||||
|     REQUIRE("{\"key\":\"value\"}" == json); | ||||
|   } | ||||
|  | ||||
|   SECTION("serializeJsonPretty") { | ||||
|     std::string json; | ||||
|     serializeJsonPretty(doc, json); | ||||
|  | ||||
|     REQUIRE("{\r\n  \"key\": \"value\"\r\n}" == json); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										28
									
								
								extras/tests/JsonVariant/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								extras/tests/JsonVariant/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| # ArduinoJson - arduinojson.org | ||||
| # Copyright Benoit Blanchon 2014-2019 | ||||
| # MIT License | ||||
|  | ||||
| add_executable(JsonVariantTests | ||||
| 	add.cpp | ||||
| 	as.cpp | ||||
| 	clear.cpp | ||||
| 	compare.cpp | ||||
| 	containsKey.cpp | ||||
| 	copy.cpp | ||||
| 	createNested.cpp | ||||
| 	is.cpp | ||||
| 	isnull.cpp | ||||
| 	memoryUsage.cpp | ||||
| 	misc.cpp | ||||
| 	nesting.cpp | ||||
| 	or.cpp | ||||
| 	overflow.cpp | ||||
| 	remove.cpp | ||||
| 	set.cpp | ||||
| 	subscript.cpp | ||||
| 	types.cpp | ||||
| 	undefined.cpp | ||||
| ) | ||||
|  | ||||
| target_link_libraries(JsonVariantTests catch) | ||||
| add_test(JsonVariant JsonVariantTests) | ||||
							
								
								
									
										32
									
								
								extras/tests/JsonVariant/add.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								extras/tests/JsonVariant/add.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <stdint.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| static const char* null = 0; | ||||
|  | ||||
| TEST_CASE("JsonVariant::add()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant var = doc.to<JsonVariant>(); | ||||
|  | ||||
|   SECTION("integer") { | ||||
|     var.add(42); | ||||
|  | ||||
|     REQUIRE(var.as<std::string>() == "[42]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("const char*") { | ||||
|     var.add("hello"); | ||||
|  | ||||
|     REQUIRE(var.as<std::string>() == "[\"hello\"]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("std::string") { | ||||
|     var.add(std::string("hello")); | ||||
|  | ||||
|     REQUIRE(var.as<std::string>() == "[\"hello\"]"); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										215
									
								
								extras/tests/JsonVariant/as.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										215
									
								
								extras/tests/JsonVariant/as.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,215 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <stdint.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| namespace my { | ||||
| using ARDUINOJSON_NAMESPACE::isinf; | ||||
| }  // namespace my | ||||
|  | ||||
| static const char* null = 0; | ||||
|  | ||||
| TEST_CASE("JsonVariant::as()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant variant = doc.to<JsonVariant>(); | ||||
|  | ||||
|   SECTION("not set") { | ||||
|     REQUIRE(false == variant.as<bool>()); | ||||
|     REQUIRE(0 == variant.as<int>()); | ||||
|     REQUIRE(0.0f == variant.as<float>()); | ||||
|     REQUIRE(0 == variant.as<char*>()); | ||||
|     REQUIRE("null" == variant.as<std::string>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("set(4.2)") { | ||||
|     variant.set(4.2); | ||||
|  | ||||
|     REQUIRE(variant.as<bool>()); | ||||
|     REQUIRE(0 == variant.as<const char*>()); | ||||
|     REQUIRE(variant.as<std::string>() == "4.2"); | ||||
|     REQUIRE(variant.as<long>() == 4L); | ||||
|     REQUIRE(variant.as<unsigned>() == 4U); | ||||
|   } | ||||
|  | ||||
|   SECTION("set(0.0)") { | ||||
|     variant.set(0.0); | ||||
|  | ||||
|     REQUIRE(variant.as<bool>() == false); | ||||
|     REQUIRE(variant.as<long>() == 0L); | ||||
|   } | ||||
|  | ||||
|   SECTION("set(false)") { | ||||
|     variant.set(false); | ||||
|  | ||||
|     REQUIRE(false == variant.as<bool>()); | ||||
|     REQUIRE(variant.as<double>() == 0.0); | ||||
|     REQUIRE(variant.as<long>() == 0L); | ||||
|     REQUIRE(variant.as<std::string>() == "false"); | ||||
|   } | ||||
|  | ||||
|   SECTION("set(true)") { | ||||
|     variant.set(true); | ||||
|  | ||||
|     REQUIRE(variant.as<bool>()); | ||||
|     REQUIRE(variant.as<double>() == 1.0); | ||||
|     REQUIRE(variant.as<long>() == 1L); | ||||
|     REQUIRE(variant.as<std::string>() == "true"); | ||||
|   } | ||||
|  | ||||
|   SECTION("set(42L)") { | ||||
|     variant.set(42L); | ||||
|  | ||||
|     REQUIRE(variant.as<bool>() == true); | ||||
|     REQUIRE(variant.as<double>() == 42.0); | ||||
|     REQUIRE(variant.as<std::string>() == "42"); | ||||
|   } | ||||
|  | ||||
|   SECTION("set(-42L)") { | ||||
|     variant.set(-42L); | ||||
|  | ||||
|     REQUIRE(variant.as<double>() == -42.0); | ||||
|     REQUIRE(variant.as<std::string>() == "-42"); | ||||
|   } | ||||
|  | ||||
|   SECTION("set(0L)") { | ||||
|     variant.set(0L); | ||||
|  | ||||
|     REQUIRE(variant.as<bool>() == false); | ||||
|     REQUIRE(variant.as<double>() == 0.0); | ||||
|   } | ||||
|  | ||||
|   SECTION("set(null)") { | ||||
|     variant.set(null); | ||||
|  | ||||
|     REQUIRE(variant.as<bool>() == false); | ||||
|     REQUIRE(variant.as<double>() == 0.0); | ||||
|     REQUIRE(variant.as<long>() == 0L); | ||||
|     REQUIRE(variant.as<std::string>() == "null"); | ||||
|   } | ||||
|  | ||||
|   SECTION("set(\"42\")") { | ||||
|     variant.set("42"); | ||||
|  | ||||
|     REQUIRE(variant.as<long>() == 42L); | ||||
|   } | ||||
|  | ||||
|   SECTION("set(\"hello\")") { | ||||
|     variant.set("hello"); | ||||
|  | ||||
|     REQUIRE(variant.as<bool>() == true); | ||||
|     REQUIRE(variant.as<long>() == 0L); | ||||
|     REQUIRE(variant.as<const char*>() == std::string("hello")); | ||||
|     REQUIRE(variant.as<char*>() == std::string("hello")); | ||||
|     REQUIRE(variant.as<std::string>() == std::string("hello")); | ||||
|   } | ||||
|  | ||||
|   SECTION("set(std::string(\"4.2\"))") { | ||||
|     variant.set(std::string("4.2")); | ||||
|  | ||||
|     REQUIRE(variant.as<bool>() == true); | ||||
|     REQUIRE(variant.as<long>() == 4L); | ||||
|     REQUIRE(variant.as<double>() == 4.2); | ||||
|     REQUIRE(variant.as<char*>() == std::string("4.2")); | ||||
|     REQUIRE(variant.as<std::string>() == std::string("4.2")); | ||||
|   } | ||||
|  | ||||
|   SECTION("set(\"true\")") { | ||||
|     variant.set("true"); | ||||
|  | ||||
|     REQUIRE(variant.as<bool>() == true); | ||||
|     REQUIRE(variant.as<int>() == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("set(-1e300)") { | ||||
|     variant.set(-1e300); | ||||
|  | ||||
|     REQUIRE(variant.as<bool>() == true); | ||||
|     REQUIRE(variant.as<double>() == -1e300); | ||||
|     REQUIRE(variant.as<float>() < 0); | ||||
|     REQUIRE(my::isinf(variant.as<float>())); | ||||
|   } | ||||
|  | ||||
|   SECTION("set(1e300)") { | ||||
|     variant.set(1e300); | ||||
|  | ||||
|     REQUIRE(variant.as<bool>() == true); | ||||
|     REQUIRE(variant.as<double>() == 1e300); | ||||
|     REQUIRE(variant.as<float>() > 0); | ||||
|     REQUIRE(my::isinf(variant.as<float>())); | ||||
|   } | ||||
|  | ||||
|   SECTION("set(1e-300)") { | ||||
|     variant.set(1e-300); | ||||
|  | ||||
|     REQUIRE(variant.as<bool>() == true); | ||||
|     REQUIRE(variant.as<double>() == 1e-300); | ||||
|     REQUIRE(variant.as<float>() == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("to<JsonObject>()") { | ||||
|     JsonObject obj = variant.to<JsonObject>(); | ||||
|     obj["key"] = "value"; | ||||
|  | ||||
|     SECTION("as<bool>()") { | ||||
|       REQUIRE(variant.as<bool>() == true); | ||||
|     } | ||||
|  | ||||
|     SECTION("as<std::string>()") { | ||||
|       REQUIRE(variant.as<std::string>() == std::string("{\"key\":\"value\"}")); | ||||
|     } | ||||
|  | ||||
|     SECTION("ObjectAsJsonObject") { | ||||
|       JsonObject o = variant.as<JsonObject>(); | ||||
|       REQUIRE(o.size() == 1); | ||||
|       REQUIRE(o["key"] == std::string("value")); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("to<JsonArray>()") { | ||||
|     JsonArray arr = variant.to<JsonArray>(); | ||||
|     arr.add(4); | ||||
|     arr.add(2); | ||||
|  | ||||
|     SECTION("as<bool>()") { | ||||
|       REQUIRE(variant.as<bool>() == true); | ||||
|     } | ||||
|  | ||||
|     SECTION("as<std::string>()") { | ||||
|       REQUIRE(variant.as<std::string>() == std::string("[4,2]")); | ||||
|     } | ||||
|  | ||||
|     SECTION("as<JsonArray>()") { | ||||
|       JsonArray a = variant.as<JsonArray>(); | ||||
|       REQUIRE(a.size() == 2); | ||||
|       REQUIRE(a[0] == 4); | ||||
|       REQUIRE(a[1] == 2); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| #if ARDUINOJSON_USE_LONG_LONG | ||||
|   SECTION("Smallest int64 negative") { | ||||
|     variant.set("-9223372036854775808"); | ||||
|     REQUIRE(variant.as<long long>() == -9223372036854775807 - 1); | ||||
|   } | ||||
|  | ||||
|   SECTION("Biggerst int64 positive") { | ||||
|     variant.set("9223372036854775807"); | ||||
|     REQUIRE(variant.as<long long>() == 9223372036854775807); | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   SECTION("should work on JsonVariantConst") { | ||||
|     variant.set("hello"); | ||||
|  | ||||
|     JsonVariantConst cvar = variant; | ||||
|  | ||||
|     REQUIRE(cvar.as<bool>() == true); | ||||
|     REQUIRE(cvar.as<long>() == 0L); | ||||
|     REQUIRE(cvar.as<const char*>() == std::string("hello")); | ||||
|     REQUIRE(cvar.as<char*>() == std::string("hello")); | ||||
|     // REQUIRE(cvar.as<std::string>() == std::string("hello")); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										28
									
								
								extras/tests/JsonVariant/clear.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								extras/tests/JsonVariant/clear.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <stdint.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| static const char* null = 0; | ||||
|  | ||||
| TEST_CASE("JsonVariant::clear()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant var = doc.to<JsonVariant>(); | ||||
|  | ||||
|   SECTION("size goes back to zero") { | ||||
|     var.add(42); | ||||
|     var.clear(); | ||||
|  | ||||
|     REQUIRE(var.size() == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("isNull() return true") { | ||||
|     var.add("hello"); | ||||
|     var.clear(); | ||||
|  | ||||
|     REQUIRE(var.isNull() == true); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										464
									
								
								extras/tests/JsonVariant/compare.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										464
									
								
								extras/tests/JsonVariant/compare.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,464 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| static const char* null = 0; | ||||
|  | ||||
| template <typename T> | ||||
| void checkEquals(T a, T b) { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant variant = doc.to<JsonVariant>(); | ||||
|   variant.set(a); | ||||
|  | ||||
|   REQUIRE(b == variant); | ||||
|   REQUIRE(variant == b); | ||||
|   REQUIRE(b <= variant); | ||||
|   REQUIRE(variant <= b); | ||||
|   REQUIRE(b >= variant); | ||||
|   REQUIRE(variant >= b); | ||||
|  | ||||
|   REQUIRE_FALSE(b != variant); | ||||
|   REQUIRE_FALSE(variant != b); | ||||
|   REQUIRE_FALSE(b > variant); | ||||
|   REQUIRE_FALSE(variant > b); | ||||
|   REQUIRE_FALSE(b < variant); | ||||
|   REQUIRE_FALSE(variant < b); | ||||
| } | ||||
|  | ||||
| template <typename T> | ||||
| void checkGreater(T a, T b) { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant variant = doc.to<JsonVariant>(); | ||||
|   variant.set(a); | ||||
|  | ||||
|   REQUIRE(variant > b); | ||||
|   REQUIRE(b < variant); | ||||
|   REQUIRE(variant != b); | ||||
|   REQUIRE(b != variant); | ||||
|  | ||||
|   REQUIRE_FALSE(variant < b); | ||||
|   REQUIRE_FALSE(b > variant); | ||||
|   REQUIRE_FALSE(variant == b); | ||||
|   REQUIRE_FALSE(b == variant); | ||||
| } | ||||
|  | ||||
| template <typename T> | ||||
| void checkLower(T a, T b) { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant variant = doc.to<JsonVariant>(); | ||||
|   variant.set(a); | ||||
|  | ||||
|   REQUIRE(variant < b); | ||||
|   REQUIRE(b > variant); | ||||
|   REQUIRE(variant != b); | ||||
|   REQUIRE(b != variant); | ||||
|  | ||||
|   REQUIRE_FALSE(variant > b); | ||||
|   REQUIRE_FALSE(b < variant); | ||||
|   REQUIRE_FALSE(variant == b); | ||||
|   REQUIRE_FALSE(b == variant); | ||||
| } | ||||
|  | ||||
| template <typename T> | ||||
| void checkComparisons(T low, T mid, T high) { | ||||
|   checkEquals(mid, mid); | ||||
|   checkGreater(mid, low); | ||||
|   checkLower(mid, high); | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonVariant comparisons") { | ||||
|   SECTION("Double") { | ||||
|     checkComparisons<double>(123.44, 123.45, 123.46); | ||||
|   } | ||||
|  | ||||
|   SECTION("Float") { | ||||
|     checkComparisons<float>(123.44f, 123.45f, 123.46f); | ||||
|   } | ||||
|  | ||||
|   SECTION("SChar") { | ||||
|     checkComparisons<signed char>(122, 123, 124); | ||||
|   } | ||||
|  | ||||
|   SECTION("SInt") { | ||||
|     checkComparisons<signed int>(122, 123, 124); | ||||
|   } | ||||
|  | ||||
|   SECTION("SLong") { | ||||
|     checkComparisons<signed long>(122L, 123L, 124L); | ||||
|   } | ||||
|  | ||||
|   SECTION("SShort") { | ||||
|     checkComparisons<signed short>(122, 123, 124); | ||||
|   } | ||||
|  | ||||
|   SECTION("UChar") { | ||||
|     checkComparisons<unsigned char>(122, 123, 124); | ||||
|   } | ||||
|  | ||||
|   SECTION("UInt") { | ||||
|     checkComparisons<unsigned int>(122, 123, 124); | ||||
|   } | ||||
|  | ||||
|   SECTION("ULong") { | ||||
|     checkComparisons<unsigned long>(122L, 123L, 124L); | ||||
|   } | ||||
|  | ||||
|   SECTION("UShort") { | ||||
|     checkComparisons<unsigned short>(122, 123, 124); | ||||
|   } | ||||
|  | ||||
|   SECTION("null") { | ||||
|     DynamicJsonDocument doc(4096); | ||||
|     JsonVariant variant = doc.to<JsonVariant>(); | ||||
|     variant.set(null); | ||||
|  | ||||
|     REQUIRE(variant == variant); | ||||
|     REQUIRE_FALSE(variant != variant); | ||||
|  | ||||
|     REQUIRE(variant == null); | ||||
|     REQUIRE_FALSE(variant != null); | ||||
|  | ||||
|     REQUIRE(variant != "null"); | ||||
|     REQUIRE_FALSE(variant == "null"); | ||||
|   } | ||||
|  | ||||
|   SECTION("StringLiteral") { | ||||
|     DynamicJsonDocument doc(4096); | ||||
|     deserializeJson(doc, "\"hello\""); | ||||
|     JsonVariant variant = doc.as<JsonVariant>(); | ||||
|  | ||||
|     REQUIRE(variant == variant); | ||||
|     REQUIRE_FALSE(variant != variant); | ||||
|  | ||||
|     REQUIRE(variant == "hello"); | ||||
|     REQUIRE_FALSE(variant != "hello"); | ||||
|  | ||||
|     REQUIRE(variant != "world"); | ||||
|     REQUIRE_FALSE(variant == "world"); | ||||
|  | ||||
|     REQUIRE(variant != null); | ||||
|     REQUIRE_FALSE(variant == null); | ||||
|  | ||||
|     REQUIRE("hello" == variant); | ||||
|     REQUIRE_FALSE("hello" != variant); | ||||
|  | ||||
|     REQUIRE("world" != variant); | ||||
|     REQUIRE_FALSE("world" == variant); | ||||
|  | ||||
|     REQUIRE(null != variant); | ||||
|     REQUIRE_FALSE(null == variant); | ||||
|   } | ||||
|  | ||||
|   SECTION("String") { | ||||
|     DynamicJsonDocument doc(4096); | ||||
|     JsonVariant variant = doc.to<JsonVariant>(); | ||||
|     variant.set("hello"); | ||||
|  | ||||
|     REQUIRE(variant == variant); | ||||
|     REQUIRE_FALSE(variant != variant); | ||||
|  | ||||
|     REQUIRE(variant == std::string("hello")); | ||||
|     REQUIRE_FALSE(variant != std::string("hello")); | ||||
|  | ||||
|     REQUIRE(variant != std::string("world")); | ||||
|     REQUIRE_FALSE(variant == std::string("world")); | ||||
|  | ||||
|     REQUIRE(variant != null); | ||||
|     REQUIRE_FALSE(variant == null); | ||||
|  | ||||
|     REQUIRE(std::string("hello") == variant); | ||||
|     REQUIRE_FALSE(std::string("hello") != variant); | ||||
|  | ||||
|     REQUIRE(std::string("world") != variant); | ||||
|     REQUIRE_FALSE(std::string("world") == variant); | ||||
|  | ||||
|     REQUIRE(null != variant); | ||||
|     REQUIRE_FALSE(null == variant); | ||||
|   } | ||||
|  | ||||
| #ifdef HAS_VARIABLE_LENGTH_ARRAY | ||||
|   SECTION("VLA equals") { | ||||
|     int i = 16; | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     DynamicJsonDocument doc(4096); | ||||
|     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(4096); | ||||
|     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(4096), doc2(4096), doc3(4096); | ||||
|   JsonVariant variant1 = doc1.to<JsonVariant>(); | ||||
|   JsonVariant variant2 = doc2.to<JsonVariant>(); | ||||
|   JsonVariant variant3 = doc3.to<JsonVariant>(); | ||||
|  | ||||
|   SECTION("Variants containing integers") { | ||||
|     variant1.set(42); | ||||
|     variant2.set(42); | ||||
|     variant3.set(666); | ||||
|  | ||||
|     REQUIRE(variant1 == variant2); | ||||
|     REQUIRE_FALSE(variant1 != variant2); | ||||
|  | ||||
|     REQUIRE(variant1 != variant3); | ||||
|     REQUIRE_FALSE(variant1 == variant3); | ||||
|   } | ||||
|  | ||||
|   SECTION("Variants containing linked strings") { | ||||
|     // create two identical strings at different addresses | ||||
|     char hello1[] = "hello"; | ||||
|     char hello2[] = "hello"; | ||||
|     REQUIRE(hello1 != hello2); | ||||
|  | ||||
|     variant1.set(hello1); | ||||
|     variant2.set(hello2); | ||||
|     variant3.set("world"); | ||||
|  | ||||
|     REQUIRE(variant1 == variant2); | ||||
|     REQUIRE_FALSE(variant1 != variant2); | ||||
|  | ||||
|     REQUIRE(variant1 != variant3); | ||||
|     REQUIRE_FALSE(variant1 == variant3); | ||||
|   } | ||||
|  | ||||
|   SECTION("Variants containing owned strings") { | ||||
|     variant1.set(std::string("hello")); | ||||
|     variant2.set(std::string("hello")); | ||||
|     variant3.set(std::string("world")); | ||||
|  | ||||
|     REQUIRE(variant1 == variant2); | ||||
|     REQUIRE_FALSE(variant1 != variant2); | ||||
|  | ||||
|     REQUIRE(variant1 != variant3); | ||||
|     REQUIRE_FALSE(variant1 == variant3); | ||||
|   } | ||||
|  | ||||
|   SECTION("Variants containing linked raws") { | ||||
|     // create two identical strings at different addresses | ||||
|     char hello1[] = "hello"; | ||||
|     char hello2[] = "hello"; | ||||
|     REQUIRE(hello1 != hello2); | ||||
|  | ||||
|     variant1.set(serialized(hello1)); | ||||
|     variant2.set(serialized(hello2)); | ||||
|     variant3.set(serialized("world")); | ||||
|  | ||||
|     REQUIRE(variant1 == variant2); | ||||
|     REQUIRE_FALSE(variant1 != variant2); | ||||
|  | ||||
|     REQUIRE(variant1 != variant3); | ||||
|     REQUIRE_FALSE(variant1 == variant3); | ||||
|   } | ||||
|  | ||||
|   SECTION("Variants containing owned raws") { | ||||
|     variant1.set(serialized(std::string("hello"))); | ||||
|     variant2.set(serialized(std::string("hello"))); | ||||
|     variant3.set(serialized(std::string("world"))); | ||||
|  | ||||
|     REQUIRE(variant1 == variant2); | ||||
|     REQUIRE_FALSE(variant1 != variant2); | ||||
|  | ||||
|     REQUIRE(variant1 != variant3); | ||||
|     REQUIRE_FALSE(variant1 == variant3); | ||||
|   } | ||||
|  | ||||
|   SECTION("Variants containing mixed strings (issue #1051)") { | ||||
|     variant1.set("hello"); | ||||
|     variant2.set(std::string("hello")); | ||||
|  | ||||
|     REQUIRE(variant1 == variant2); | ||||
|     REQUIRE_FALSE(variant1 != variant2); | ||||
|  | ||||
|     REQUIRE(variant2 == variant1); | ||||
|     REQUIRE_FALSE(variant2 != variant1); | ||||
|   } | ||||
|  | ||||
|   SECTION("Variants containing double") { | ||||
|     variant1.set(42.0); | ||||
|     variant2.set(42.0); | ||||
|     variant3.set(666.0); | ||||
|  | ||||
|     REQUIRE(variant1 == variant2); | ||||
|     REQUIRE_FALSE(variant1 != variant2); | ||||
|  | ||||
|     REQUIRE(variant1 != variant3); | ||||
|     REQUIRE_FALSE(variant1 == variant3); | ||||
|   } | ||||
|  | ||||
|   SECTION("BoolInVariant") { | ||||
|     variant1.set(true); | ||||
|     variant2.set(true); | ||||
|     variant3.set(false); | ||||
|  | ||||
|     REQUIRE(variant1 == variant2); | ||||
|     REQUIRE_FALSE(variant1 != variant2); | ||||
|  | ||||
|     REQUIRE(variant1 != variant3); | ||||
|     REQUIRE_FALSE(variant1 == variant3); | ||||
|   } | ||||
|  | ||||
|   SECTION("ArrayInVariant") { | ||||
|     JsonArray array1 = variant1.to<JsonArray>(); | ||||
|     JsonArray array2 = variant2.to<JsonArray>(); | ||||
|  | ||||
|     array1.add(42); | ||||
|     array2.add(42); | ||||
|  | ||||
|     REQUIRE(variant1 == variant2); | ||||
|     REQUIRE_FALSE(variant1 != variant2); | ||||
|  | ||||
|     REQUIRE(variant1 != variant3); | ||||
|     REQUIRE_FALSE(variant1 == variant3); | ||||
|   } | ||||
|  | ||||
|   SECTION("ObjectInVariant") { | ||||
|     JsonObject obj1 = variant1.to<JsonObject>(); | ||||
|     JsonObject obj2 = variant2.to<JsonObject>(); | ||||
|  | ||||
|     obj1["hello"] = "world"; | ||||
|     obj2["hello"] = "world"; | ||||
|  | ||||
|     REQUIRE(variant1 == variant2); | ||||
|     REQUIRE_FALSE(variant1 != variant2); | ||||
|  | ||||
|     REQUIRE(variant1 != variant3); | ||||
|     REQUIRE_FALSE(variant1 == variant3); | ||||
|   } | ||||
| } | ||||
|  | ||||
| class VariantComparisionFixture { | ||||
|  private: | ||||
|   StaticJsonDocument<256> doc; | ||||
|   JsonVariant variant; | ||||
|  | ||||
|  public: | ||||
|   VariantComparisionFixture() : variant(doc.to<JsonVariant>()) {} | ||||
|  | ||||
|  protected: | ||||
|   template <typename T> | ||||
|   void setValue(const T& value) { | ||||
|     variant.set(value); | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   void assertEqualsTo(const T& value) { | ||||
|     REQUIRE(variant == value); | ||||
|     REQUIRE(value == variant); | ||||
|  | ||||
|     REQUIRE_FALSE(variant != value); | ||||
|     REQUIRE_FALSE(value != variant); | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   void assertDiffersFrom(const T& value) { | ||||
|     REQUIRE(variant != value); | ||||
|     REQUIRE(value != variant); | ||||
|  | ||||
|     REQUIRE_FALSE(variant == value); | ||||
|     REQUIRE_FALSE(value == variant); | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   void assertGreaterThan(const T& value) { | ||||
|     REQUIRE((variant > value)); | ||||
|     REQUIRE((variant >= value)); | ||||
|     REQUIRE(value < variant); | ||||
|     REQUIRE(value <= variant); | ||||
|  | ||||
|     REQUIRE_FALSE((variant < value)); | ||||
|     REQUIRE_FALSE((variant <= value)); | ||||
|     REQUIRE_FALSE(value > variant); | ||||
|     REQUIRE_FALSE(value >= variant); | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   void assertLowerThan(const T& value) { | ||||
|     REQUIRE(variant < value); | ||||
|     REQUIRE(variant <= value); | ||||
|     REQUIRE(value > variant); | ||||
|     REQUIRE(value >= variant); | ||||
|  | ||||
|     REQUIRE_FALSE(variant > value); | ||||
|     REQUIRE_FALSE(variant >= value); | ||||
|     REQUIRE_FALSE(value < variant); | ||||
|     REQUIRE_FALSE(value <= variant); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| TEST_CASE_METHOD(VariantComparisionFixture, | ||||
|                  "Compare variant with another type") { | ||||
|   SECTION("null") { | ||||
|     assertDiffersFrom(3); | ||||
|     assertDiffersFrom("world"); | ||||
|   } | ||||
|  | ||||
|   SECTION("string") { | ||||
|     setValue("hello"); | ||||
|     assertEqualsTo("hello"); | ||||
|     assertDiffersFrom(3); | ||||
|     assertDiffersFrom("world"); | ||||
|     assertGreaterThan("helln"); | ||||
|     assertLowerThan("hellp"); | ||||
|   } | ||||
|  | ||||
|   SECTION("positive integer") { | ||||
|     setValue(42); | ||||
|     assertEqualsTo(42); | ||||
|     assertDiffersFrom(43); | ||||
|     assertGreaterThan(41); | ||||
|     assertLowerThan(43); | ||||
|     assertDiffersFrom("world"); | ||||
|   } | ||||
|  | ||||
|   SECTION("negative integer") { | ||||
|     setValue(-42); | ||||
|     assertEqualsTo(-42); | ||||
|     assertDiffersFrom(42); | ||||
|     assertGreaterThan(-43); | ||||
|     assertLowerThan(-41); | ||||
|     assertDiffersFrom("world"); | ||||
|   } | ||||
|  | ||||
|   SECTION("double") { | ||||
|     setValue(42.0); | ||||
|     assertEqualsTo(42.0); | ||||
|     assertDiffersFrom(42.1); | ||||
|     assertGreaterThan(41.0); | ||||
|     assertLowerThan(43.0); | ||||
|     assertDiffersFrom("42.0"); | ||||
|   } | ||||
|  | ||||
|   SECTION("true") { | ||||
|     setValue(true); | ||||
|     assertEqualsTo(true); | ||||
|     assertDiffersFrom(false); | ||||
|     assertDiffersFrom(1); | ||||
|     assertDiffersFrom("true"); | ||||
|     assertDiffersFrom(1.0); | ||||
|     assertGreaterThan(false); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										28
									
								
								extras/tests/JsonVariant/containsKey.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								extras/tests/JsonVariant/containsKey.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <stdint.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| static const char* null = 0; | ||||
|  | ||||
| TEST_CASE("JsonVariant::containsKey()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant var = doc.to<JsonVariant>(); | ||||
|  | ||||
|   SECTION("containsKey(const char*) returns true") { | ||||
|     var["hello"] = "world"; | ||||
|  | ||||
|     REQUIRE(var.containsKey("hello") == true); | ||||
|     REQUIRE(var.containsKey("world") == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("containsKey(std::string) returns true") { | ||||
|     var["hello"] = "world"; | ||||
|  | ||||
|     REQUIRE(var.containsKey(std::string("hello")) == true); | ||||
|     REQUIRE(var.containsKey(std::string("world")) == false); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										86
									
								
								extras/tests/JsonVariant/copy.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								extras/tests/JsonVariant/copy.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonVariant::set(JsonVariant)") { | ||||
|   DynamicJsonDocument doc1(4096); | ||||
|   DynamicJsonDocument doc2(4096); | ||||
|   JsonVariant var1 = doc1.to<JsonVariant>(); | ||||
|   JsonVariant var2 = doc2.to<JsonVariant>(); | ||||
|  | ||||
|   SECTION("stores JsonArray by copy") { | ||||
|     JsonArray arr = doc2.to<JsonArray>(); | ||||
|     JsonObject obj = arr.createNestedObject(); | ||||
|     obj["hello"] = "world"; | ||||
|  | ||||
|     var1.set(arr); | ||||
|  | ||||
|     arr[0] = 666; | ||||
|     REQUIRE(var1.as<std::string>() == "[{\"hello\":\"world\"}]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("stores JsonObject by copy") { | ||||
|     JsonObject obj = doc2.to<JsonObject>(); | ||||
|     JsonArray arr = obj.createNestedArray("value"); | ||||
|     arr.add(42); | ||||
|  | ||||
|     var1.set(obj); | ||||
|  | ||||
|     obj["value"] = 666; | ||||
|     REQUIRE(var1.as<std::string>() == "{\"value\":[42]}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("stores const char* by reference") { | ||||
|     var1.set("hello!!"); | ||||
|     var2.set(var1); | ||||
|  | ||||
|     REQUIRE(doc1.memoryUsage() == 0); | ||||
|     REQUIRE(doc2.memoryUsage() == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("stores char* by copy") { | ||||
|     char str[] = "hello!!"; | ||||
|  | ||||
|     var1.set(str); | ||||
|     var2.set(var1); | ||||
|  | ||||
|     REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(8)); | ||||
|     REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(8)); | ||||
|   } | ||||
|  | ||||
|   SECTION("stores std::string by copy") { | ||||
|     var1.set(std::string("hello!!")); | ||||
|     var2.set(var1); | ||||
|  | ||||
|     REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(8)); | ||||
|     REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(8)); | ||||
|   } | ||||
|  | ||||
|   SECTION("stores Serialized<const char*> by reference") { | ||||
|     var1.set(serialized("hello!!", JSON_STRING_SIZE(8))); | ||||
|     var2.set(var1); | ||||
|  | ||||
|     REQUIRE(doc1.memoryUsage() == 0); | ||||
|     REQUIRE(doc2.memoryUsage() == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("stores Serialized<char*> by copy") { | ||||
|     char str[] = "hello!!"; | ||||
|     var1.set(serialized(str, 8)); | ||||
|     var2.set(var1); | ||||
|  | ||||
|     REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(8)); | ||||
|     REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(8)); | ||||
|   } | ||||
|  | ||||
|   SECTION("stores Serialized<std::string> by copy") { | ||||
|     var1.set(serialized(std::string("hello!!!"))); | ||||
|     var2.set(var1); | ||||
|  | ||||
|     REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(8)); | ||||
|     REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(8)); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										88
									
								
								extras/tests/JsonVariant/createNested.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								extras/tests/JsonVariant/createNested.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <stdint.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| static const char* null = 0; | ||||
|  | ||||
| TEST_CASE("JsonVariant::createNestedObject()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant variant = doc.to<JsonVariant>(); | ||||
|  | ||||
|   SECTION("promotes to array") { | ||||
|     JsonObject obj = variant.createNestedObject(); | ||||
|     obj["value"] = 42; | ||||
|  | ||||
|     REQUIRE(variant.is<JsonArray>() == true); | ||||
|     REQUIRE(variant[0]["value"] == 42); | ||||
|     REQUIRE(obj.isNull() == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("works on MemberProxy") { | ||||
|     JsonObject obj = variant["items"].createNestedObject(); | ||||
|     obj["value"] = 42; | ||||
|  | ||||
|     REQUIRE(variant["items"][0]["value"] == 42); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonVariant::createNestedArray()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant variant = doc.to<JsonVariant>(); | ||||
|  | ||||
|   SECTION("promotes to array") { | ||||
|     JsonArray arr = variant.createNestedArray(); | ||||
|  | ||||
|     REQUIRE(variant.is<JsonArray>() == true); | ||||
|     REQUIRE(arr.isNull() == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("works on MemberProxy") { | ||||
|     JsonArray arr = variant["items"].createNestedArray(); | ||||
|     arr.add(42); | ||||
|  | ||||
|     REQUIRE(variant["items"][0][0] == 42); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonVariant::createNestedObject(key)") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant variant = doc.to<JsonVariant>(); | ||||
|  | ||||
|   SECTION("promotes to object") { | ||||
|     JsonObject obj = variant.createNestedObject("weather"); | ||||
|     obj["temp"] = 42; | ||||
|  | ||||
|     REQUIRE(variant.is<JsonObject>() == true); | ||||
|     REQUIRE(variant["weather"]["temp"] == 42); | ||||
|   } | ||||
|  | ||||
|   SECTION("works on MemberProxy") { | ||||
|     JsonObject obj = variant["status"].createNestedObject("weather"); | ||||
|     obj["temp"] = 42; | ||||
|  | ||||
|     REQUIRE(variant["status"]["weather"]["temp"] == 42); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonVariant::createNestedArray(key)") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant variant = doc.to<JsonVariant>(); | ||||
|  | ||||
|   SECTION("promotes to object") { | ||||
|     JsonArray arr = variant.createNestedArray("items"); | ||||
|  | ||||
|     REQUIRE(variant.is<JsonObject>() == true); | ||||
|     REQUIRE(arr.isNull() == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("works on MemberProxy") { | ||||
|     JsonArray arr = variant["weather"].createNestedArray("temp"); | ||||
|     arr.add(42); | ||||
|  | ||||
|     REQUIRE(variant["weather"]["temp"][0] == 42); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										162
									
								
								extras/tests/JsonVariant/is.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								extras/tests/JsonVariant/is.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,162 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| template <typename TVariant> | ||||
| void checkIsArray(TVariant var) { | ||||
|   REQUIRE(var.template is<JsonArray>()); | ||||
|  | ||||
|   REQUIRE_FALSE(var.template is<bool>()); | ||||
|   REQUIRE_FALSE(var.template is<double>()); | ||||
|   REQUIRE_FALSE(var.template is<float>()); | ||||
|   REQUIRE_FALSE(var.template is<int>()); | ||||
|   REQUIRE_FALSE(var.template is<long>()); | ||||
|   REQUIRE_FALSE(var.template is<const char *>()); | ||||
|   REQUIRE_FALSE(var.template is<JsonObject>()); | ||||
| } | ||||
|  | ||||
| void testArray(JsonArray value) { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
|   JsonVariant var = doc.to<JsonVariant>(); | ||||
|   var.set(value); | ||||
|  | ||||
|   checkIsArray(var); | ||||
|  | ||||
|   JsonVariantConst cvar = var; | ||||
|   checkIsArray(cvar); | ||||
| } | ||||
|  | ||||
| template <typename TVariant> | ||||
| void checkIsBool(TVariant var) { | ||||
|   REQUIRE(var.template is<bool>()); | ||||
|  | ||||
|   REQUIRE_FALSE(var.template is<double>()); | ||||
|   REQUIRE_FALSE(var.template is<float>()); | ||||
|   REQUIRE_FALSE(var.template is<int>()); | ||||
|   REQUIRE_FALSE(var.template is<long>()); | ||||
|   REQUIRE_FALSE(var.template is<const char *>()); | ||||
|   REQUIRE_FALSE(var.template is<JsonArray>()); | ||||
|   REQUIRE_FALSE(var.template is<JsonObject>()); | ||||
| } | ||||
|  | ||||
| void testBool(bool value) { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant var = doc.to<JsonVariant>(); | ||||
|   var.set(value); | ||||
|  | ||||
|   checkIsBool(var); | ||||
|   checkIsBool(JsonVariantConst(var)); | ||||
| } | ||||
|  | ||||
| template <typename TVariant> | ||||
| void checkIsFloat(TVariant var) { | ||||
|   REQUIRE(var.template is<double>()); | ||||
|   REQUIRE(var.template is<float>()); | ||||
|  | ||||
|   REQUIRE_FALSE(var.template is<bool>()); | ||||
|   REQUIRE_FALSE(var.template is<int>()); | ||||
|   REQUIRE_FALSE(var.template is<long>()); | ||||
|   REQUIRE_FALSE(var.template is<const char *>()); | ||||
|   REQUIRE_FALSE(var.template is<JsonArray>()); | ||||
|   REQUIRE_FALSE(var.template is<JsonObject>()); | ||||
| } | ||||
|  | ||||
| void testFloat(double value) { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant var = doc.to<JsonVariant>(); | ||||
|   var.set(value); | ||||
|  | ||||
|   checkIsFloat(var); | ||||
|   checkIsFloat(JsonVariantConst(var)); | ||||
| } | ||||
|  | ||||
| template <typename TVariant> | ||||
| void checkIsInteger(TVariant var) { | ||||
|   REQUIRE(var.template is<long>()); | ||||
|   REQUIRE(var.template is<int>()); | ||||
|   REQUIRE(var.template is<float>()); | ||||
|   REQUIRE(var.template is<double>()); | ||||
|  | ||||
|   REQUIRE_FALSE(var.template is<bool>()); | ||||
|   REQUIRE_FALSE(var.template is<const char *>()); | ||||
|   REQUIRE_FALSE(var.template is<JsonArray>()); | ||||
|   REQUIRE_FALSE(var.template is<JsonObject>()); | ||||
| } | ||||
|  | ||||
| template <typename T> | ||||
| void testInteger(T value) { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant var = doc.to<JsonVariant>(); | ||||
|   var.set(value); | ||||
|  | ||||
|   checkIsInteger(var); | ||||
|   checkIsInteger(JsonVariantConst(var)); | ||||
| } | ||||
|  | ||||
| template <typename TVariant> | ||||
| void checkIsString(TVariant var) { | ||||
|   REQUIRE(var.template is<const char *>()); | ||||
|   REQUIRE(var.template is<std::string>()); | ||||
|  | ||||
|   REQUIRE_FALSE(var.template is<bool>()); | ||||
|   REQUIRE_FALSE(var.template is<int>()); | ||||
|   REQUIRE_FALSE(var.template is<double>()); | ||||
|   REQUIRE_FALSE(var.template is<float>()); | ||||
|   REQUIRE_FALSE(var.template is<long>()); | ||||
|   REQUIRE_FALSE(var.template is<JsonArray>()); | ||||
|   REQUIRE_FALSE(var.template is<JsonObject>()); | ||||
| } | ||||
|  | ||||
| void testString(const char *value) { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant var = doc.to<JsonVariant>(); | ||||
|   var.set(value); | ||||
|  | ||||
|   checkIsString(var); | ||||
|   checkIsString(JsonVariantConst(var)); | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonVariant::is()") { | ||||
|   SECTION("JsonArray") { | ||||
|     DynamicJsonDocument doc(4096); | ||||
|     JsonArray array = doc.to<JsonArray>(); | ||||
|     testArray(array); | ||||
|   } | ||||
|  | ||||
|   SECTION("bool") { | ||||
|     testBool(true); | ||||
|     testBool(false); | ||||
|   } | ||||
|  | ||||
|   SECTION("double") { | ||||
|     testFloat(4.2); | ||||
|   } | ||||
|  | ||||
|   SECTION("int") { | ||||
|     testInteger(42); | ||||
|   } | ||||
|  | ||||
|   SECTION("long") { | ||||
|     testInteger(42L); | ||||
|   } | ||||
|  | ||||
|   SECTION("string") { | ||||
|     testString("42"); | ||||
|   } | ||||
|  | ||||
|   SECTION("null") { | ||||
|     DynamicJsonDocument doc(4096); | ||||
|     deserializeJson(doc, "[null]"); | ||||
|     JsonVariant v = doc[0]; | ||||
|  | ||||
|     REQUIRE(v.is<bool>() == false); | ||||
|     REQUIRE(v.is<char *>() == false); | ||||
|     REQUIRE(v.is<int>() == false); | ||||
|     REQUIRE(v.is<std::string>() == false); | ||||
|     REQUIRE(v.is<float>() == false); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										80
									
								
								extras/tests/JsonVariant/isnull.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								extras/tests/JsonVariant/isnull.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonVariant::isNull()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant variant = doc.to<JsonVariant>(); | ||||
|  | ||||
|   SECTION("return true when Undefined") { | ||||
|     REQUIRE(variant.isNull() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("return false when Integer") { | ||||
|     variant.set(42); | ||||
|  | ||||
|     REQUIRE(variant.isNull() == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("return false when EmptyArray") { | ||||
|     DynamicJsonDocument doc2(4096); | ||||
|     JsonArray array = doc2.to<JsonArray>(); | ||||
|  | ||||
|     variant.set(array); | ||||
|     REQUIRE(variant.isNull() == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("return false when EmptyObject") { | ||||
|     DynamicJsonDocument doc2(4096); | ||||
|     JsonObject obj = doc2.to<JsonObject>(); | ||||
|  | ||||
|     variant.set(obj); | ||||
|     REQUIRE(variant.isNull() == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("return true after set(JsonArray())") { | ||||
|     variant.set(JsonArray()); | ||||
|     REQUIRE(variant.isNull() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("return true after set(JsonObject())") { | ||||
|     variant.set(JsonObject()); | ||||
|     REQUIRE(variant.isNull() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("return false after set('hello')") { | ||||
|     variant.set("hello"); | ||||
|     REQUIRE(variant.isNull() == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("return true after set((char*)0)") { | ||||
|     variant.set(static_cast<char*>(0)); | ||||
|     REQUIRE(variant.isNull() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("return true after set((const char*)0)") { | ||||
|     variant.set(static_cast<const char*>(0)); | ||||
|     REQUIRE(variant.isNull() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("return true after set(serialized((char*)0))") { | ||||
|     variant.set(serialized(static_cast<char*>(0))); | ||||
|     REQUIRE(variant.isNull() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("return true after set(serialized((const char*)0))") { | ||||
|     variant.set(serialized(static_cast<const char*>(0))); | ||||
|     REQUIRE(variant.isNull() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("works with JsonVariantConst") { | ||||
|     variant.set(42); | ||||
|  | ||||
|     JsonVariantConst cvar = variant; | ||||
|  | ||||
|     REQUIRE(cvar.isNull() == false); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										39
									
								
								extras/tests/JsonVariant/memoryUsage.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								extras/tests/JsonVariant/memoryUsage.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
| #include <string> | ||||
|  | ||||
| TEST_CASE("JsonVariant::memoryUsage()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant var = doc.to<JsonVariant>(); | ||||
|  | ||||
|   SECTION("returns 0 if uninitialized") { | ||||
|     JsonVariant unitialized; | ||||
|     REQUIRE(unitialized.memoryUsage() == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns size of object") { | ||||
|     JsonObject obj = var.to<JsonObject>(); | ||||
|     obj["hello"] = 42; | ||||
|     REQUIRE(var.memoryUsage() == JSON_OBJECT_SIZE(1)); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns size of array") { | ||||
|     JsonArray arr = var.to<JsonArray>(); | ||||
|     arr.add(42); | ||||
|     REQUIRE(var.memoryUsage() == JSON_ARRAY_SIZE(1)); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns size of owned string") { | ||||
|     var.set(std::string("hello")); | ||||
|     REQUIRE(var.memoryUsage() == 6); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns size of owned raw") { | ||||
|     var.set(serialized(std::string("hello"))); | ||||
|     REQUIRE(var.memoryUsage() == 5); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										50
									
								
								extras/tests/JsonVariant/misc.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								extras/tests/JsonVariant/misc.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonVariant from JsonArray") { | ||||
|   SECTION("JsonArray is null") { | ||||
|     JsonArray arr; | ||||
|     JsonVariant v = arr; | ||||
|     REQUIRE(v.isNull() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("JsonArray is not null") { | ||||
|     DynamicJsonDocument doc(4096); | ||||
|     JsonArray arr = doc.to<JsonArray>(); | ||||
|     arr.add(12); | ||||
|     arr.add(34); | ||||
|  | ||||
|     JsonVariant v = arr; | ||||
|  | ||||
|     REQUIRE(v.is<JsonArray>() == true); | ||||
|     REQUIRE(v.size() == 2); | ||||
|     REQUIRE(v[0] == 12); | ||||
|     REQUIRE(v[1] == 34); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonVariant from JsonObject") { | ||||
|   SECTION("JsonObject is null") { | ||||
|     JsonObject obj; | ||||
|     JsonVariant v = obj; | ||||
|     REQUIRE(v.isNull() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("JsonObject is not null") { | ||||
|     DynamicJsonDocument doc(4096); | ||||
|     JsonObject obj = doc.to<JsonObject>(); | ||||
|     obj["a"] = 12; | ||||
|     obj["b"] = 34; | ||||
|  | ||||
|     JsonVariant v = obj; | ||||
|  | ||||
|     REQUIRE(v.is<JsonObject>() == true); | ||||
|     REQUIRE(v.size() == 2); | ||||
|     REQUIRE(v["a"] == 12); | ||||
|     REQUIRE(v["b"] == 34); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										31
									
								
								extras/tests/JsonVariant/nesting.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								extras/tests/JsonVariant/nesting.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonVariant::nesting()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant var = doc.to<JsonVariant>(); | ||||
|  | ||||
|   SECTION("return 0 if uninitialized") { | ||||
|     JsonVariant unitialized; | ||||
|     REQUIRE(unitialized.nesting() == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns 0 for string") { | ||||
|     var.set("hello"); | ||||
|     REQUIRE(var.nesting() == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns 1 for empty object") { | ||||
|     var.to<JsonObject>(); | ||||
|     REQUIRE(var.nesting() == 1); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns 1 for empty array") { | ||||
|     var.to<JsonArray>(); | ||||
|     REQUIRE(var.nesting() == 1); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										96
									
								
								extras/tests/JsonVariant/or.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								extras/tests/JsonVariant/or.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,96 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonVariant::operator|()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant variant = doc.to<JsonVariant>(); | ||||
|  | ||||
|   SECTION("undefined") { | ||||
|     SECTION("undefined | const char*") { | ||||
|       std::string result = variant | "default"; | ||||
|       REQUIRE(result == "default"); | ||||
|     } | ||||
|  | ||||
|     SECTION("undefined | int") { | ||||
|       int result = variant | 42; | ||||
|       REQUIRE(result == 42); | ||||
|     } | ||||
|  | ||||
|     SECTION("undefined | bool") { | ||||
|       bool result = variant | true; | ||||
|       REQUIRE(result == true); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("null") { | ||||
|     variant.set(static_cast<const char*>(0)); | ||||
|  | ||||
|     SECTION("null | const char*") { | ||||
|       std::string result = variant | "default"; | ||||
|       REQUIRE(result == "default"); | ||||
|     } | ||||
|  | ||||
|     SECTION("null | int") { | ||||
|       int result = variant | 42; | ||||
|       REQUIRE(result == 42); | ||||
|     } | ||||
|  | ||||
|     SECTION("null | bool") { | ||||
|       bool result = variant | true; | ||||
|       REQUIRE(result == true); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("int | const char*") { | ||||
|     variant.set(42); | ||||
|     std::string result = variant | "default"; | ||||
|     REQUIRE(result == "default"); | ||||
|   } | ||||
|  | ||||
|   SECTION("int | uint8_t (out of range)") { | ||||
|     variant.set(666); | ||||
|     uint8_t result = variant | static_cast<uint8_t>(42); | ||||
|     REQUIRE(result == 42); | ||||
|   } | ||||
|  | ||||
|   SECTION("int | int") { | ||||
|     variant.set(0); | ||||
|     int result = variant | 666; | ||||
|     REQUIRE(result == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("double | int") { | ||||
|     // NOTE: changed the behavior to fix #981 | ||||
|     variant.set(666.0); | ||||
|     int result = variant | 42; | ||||
|     REQUIRE(result == 42); | ||||
|   } | ||||
|  | ||||
|   SECTION("bool | bool") { | ||||
|     variant.set(false); | ||||
|     bool result = variant | true; | ||||
|     REQUIRE(result == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("int | bool") { | ||||
|     variant.set(0); | ||||
|     bool result = variant | true; | ||||
|     REQUIRE(result == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("const char* | const char*") { | ||||
|     variant.set("not default"); | ||||
|     std::string result = variant | "default"; | ||||
|     REQUIRE(result == "not default"); | ||||
|   } | ||||
|  | ||||
|   SECTION("const char* | int") { | ||||
|     variant.set("not default"); | ||||
|     int result = variant | 42; | ||||
|     REQUIRE(result == 42); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										72
									
								
								extras/tests/JsonVariant/overflow.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								extras/tests/JsonVariant/overflow.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| template <typename TOut, typename TIn> | ||||
| void shouldBeOk(TIn value) { | ||||
|   StaticJsonDocument<1> doc; | ||||
|   JsonVariant var = doc.to<JsonVariant>(); | ||||
|   var.set(value); | ||||
|   REQUIRE(var.as<TOut>() == TOut(value)); | ||||
| } | ||||
|  | ||||
| template <typename TOut, typename TIn> | ||||
| void shouldOverflow(TIn value) { | ||||
|   StaticJsonDocument<1> doc; | ||||
|   JsonVariant var = doc.to<JsonVariant>(); | ||||
|   var.set(value); | ||||
|   REQUIRE(var.as<TOut>() == 0); | ||||
|   REQUIRE(var.is<TOut>() == false); | ||||
| } | ||||
|  | ||||
| TEST_CASE("Handle integer overflow in stored integer") { | ||||
|   SECTION("int8_t") { | ||||
|     // ok | ||||
|     shouldBeOk<int8_t>(-128); | ||||
|     shouldBeOk<int8_t>(42.0); | ||||
|     shouldBeOk<int8_t>(127); | ||||
|  | ||||
|     // too low | ||||
|     shouldOverflow<int8_t>(-128.1); | ||||
|     shouldOverflow<int8_t>(-129); | ||||
|  | ||||
|     // too high | ||||
|     shouldOverflow<int8_t>(128); | ||||
|     shouldOverflow<int8_t>(127.1); | ||||
|   } | ||||
|  | ||||
|   SECTION("int16_t") { | ||||
|     // ok | ||||
|     shouldBeOk<int16_t>(-32768); | ||||
|     shouldBeOk<int16_t>(-32767.9); | ||||
|     shouldBeOk<int16_t>(32766.9); | ||||
|     shouldBeOk<int16_t>(32767); | ||||
|  | ||||
|     // too low | ||||
|     shouldOverflow<int16_t>(-32768.1); | ||||
|     shouldOverflow<int16_t>(-32769); | ||||
|  | ||||
|     // too high | ||||
|     shouldOverflow<int16_t>(32767.1); | ||||
|     shouldOverflow<int16_t>(32768); | ||||
|   } | ||||
|  | ||||
|   SECTION("uint8_t") { | ||||
|     // ok | ||||
|     shouldBeOk<uint8_t>(1); | ||||
|     shouldBeOk<uint8_t>(42.0); | ||||
|     shouldBeOk<uint8_t>(255); | ||||
|  | ||||
|     // too low | ||||
|     shouldOverflow<uint8_t>(-1); | ||||
|     shouldOverflow<uint8_t>(-0.1); | ||||
|  | ||||
|     // to high | ||||
|     shouldOverflow<uint8_t>(255.1); | ||||
|     shouldOverflow<uint8_t>(256); | ||||
|     shouldOverflow<uint8_t>(257); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										42
									
								
								extras/tests/JsonVariant/remove.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								extras/tests/JsonVariant/remove.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <stdint.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| static const char* null = 0; | ||||
|  | ||||
| TEST_CASE("JsonVariant::remove()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant var = doc.to<JsonVariant>(); | ||||
|  | ||||
|   SECTION("remove(int)") { | ||||
|     var.add(1); | ||||
|     var.add(2); | ||||
|     var.add(3); | ||||
|  | ||||
|     var.remove(1); | ||||
|  | ||||
|     REQUIRE(var.as<std::string>() == "[1,3]"); | ||||
|   } | ||||
|  | ||||
|   SECTION("remove(const char *)") { | ||||
|     var["a"] = 1; | ||||
|     var["b"] = 2; | ||||
|  | ||||
|     var.remove("a"); | ||||
|  | ||||
|     REQUIRE(var.as<std::string>() == "{\"b\":2}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("remove(std::string)") { | ||||
|     var["a"] = 1; | ||||
|     var["b"] = 2; | ||||
|  | ||||
|     var.remove(std::string("b")); | ||||
|  | ||||
|     REQUIRE(var.as<std::string>() == "{\"a\":1}"); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										126
									
								
								extras/tests/JsonVariant/set.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								extras/tests/JsonVariant/set.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonVariant and strings") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   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"); | ||||
|   } | ||||
|  | ||||
|   SECTION("stores static JsonString by reference") { | ||||
|     char str[16]; | ||||
|  | ||||
|     strcpy(str, "hello"); | ||||
|     variant.set(JsonString(str, true)); | ||||
|     strcpy(str, "world"); | ||||
|  | ||||
|     REQUIRE(variant == "hello"); | ||||
|   } | ||||
|  | ||||
|   SECTION("stores non-static JsonString by copy") { | ||||
|     char str[16]; | ||||
|  | ||||
|     strcpy(str, "hello"); | ||||
|     variant.set(JsonString(str, false)); | ||||
|     strcpy(str, "world"); | ||||
|  | ||||
|     REQUIRE(variant == "hello"); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonVariant with not enough memory") { | ||||
|   StaticJsonDocument<1> doc; | ||||
|  | ||||
|   JsonVariant v = doc.to<JsonVariant>(); | ||||
|  | ||||
|   SECTION("std::string") { | ||||
|     v.set(std::string("hello world!!")); | ||||
|     REQUIRE(v.isNull()); | ||||
|   } | ||||
|  | ||||
|   SECTION("Serialized<std::string>") { | ||||
|     v.set(serialized(std::string("hello world!!"))); | ||||
|     REQUIRE(v.isNull()); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonVariant::set(DynamicJsonDocument)") { | ||||
|   DynamicJsonDocument doc1(1024); | ||||
|   doc1["hello"] = "world"; | ||||
|  | ||||
|   DynamicJsonDocument doc2(1024); | ||||
|   JsonVariant v = doc2.to<JsonVariant>(); | ||||
|  | ||||
|   // Should copy the doc | ||||
|   v.set(doc1); | ||||
|   doc1.clear(); | ||||
|  | ||||
|   std::string json; | ||||
|   serializeJson(doc2, json); | ||||
|   REQUIRE(json == "{\"hello\":\"world\"}"); | ||||
| } | ||||
							
								
								
									
										195
									
								
								extras/tests/JsonVariant/subscript.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										195
									
								
								extras/tests/JsonVariant/subscript.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,195 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonVariant::operator[]") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant var = doc.to<JsonVariant>(); | ||||
|  | ||||
|   SECTION("The JsonVariant is undefined") { | ||||
|     REQUIRE(0 == var.size()); | ||||
|     REQUIRE(var["0"].isNull()); | ||||
|     REQUIRE(var[0].isNull()); | ||||
|   } | ||||
|  | ||||
|   SECTION("The JsonVariant is a string") { | ||||
|     var.set("hello world"); | ||||
|     REQUIRE(0 == var.size()); | ||||
|     REQUIRE(var["0"].isNull()); | ||||
|     REQUIRE(var[0].isNull()); | ||||
|   } | ||||
|  | ||||
|   SECTION("The JsonVariant is a JsonArray") { | ||||
|     JsonArray array = var.to<JsonArray>(); | ||||
|  | ||||
|     SECTION("get value") { | ||||
|       array.add("element at index 0"); | ||||
|       array.add("element at index 1"); | ||||
|  | ||||
|       REQUIRE(2 == var.size()); | ||||
|       var[0].as<std::string>(); | ||||
|       // REQUIRE(std::string("element at index 0") == ); | ||||
|       REQUIRE(std::string("element at index 1") == var[1]); | ||||
|       REQUIRE(std::string("element at index 0") == | ||||
|               var[static_cast<unsigned char>(0)]);  // issue #381 | ||||
|       REQUIRE(var[666].isNull()); | ||||
|       REQUIRE(var[3].isNull()); | ||||
|       REQUIRE(var["0"].isNull()); | ||||
|     } | ||||
|  | ||||
|     SECTION("set value") { | ||||
|       array.add("hello"); | ||||
|  | ||||
|       var[0] = "world"; | ||||
|  | ||||
|       REQUIRE(1 == var.size()); | ||||
|       REQUIRE(std::string("world") == var[0]); | ||||
|     } | ||||
|  | ||||
|     SECTION("set value in a nested object") { | ||||
|       array.createNestedObject(); | ||||
|  | ||||
|       var[0]["hello"] = "world"; | ||||
|  | ||||
|       REQUIRE(1 == var.size()); | ||||
|       REQUIRE(1 == var[0].size()); | ||||
|       REQUIRE(std::string("world") == var[0]["hello"]); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("The JsonVariant is a JsonObject") { | ||||
|     JsonObject object = var.to<JsonObject>(); | ||||
|  | ||||
|     SECTION("get value") { | ||||
|       object["a"] = "element at key \"a\""; | ||||
|       object["b"] = "element at key \"b\""; | ||||
|  | ||||
|       REQUIRE(2 == var.size()); | ||||
|       REQUIRE(std::string("element at key \"a\"") == var["a"]); | ||||
|       REQUIRE(std::string("element at key \"b\"") == var["b"]); | ||||
|       REQUIRE(var["c"].isNull()); | ||||
|       REQUIRE(var[0].isNull()); | ||||
|     } | ||||
|  | ||||
|     SECTION("set value, key is a const char*") { | ||||
|       var["hello"] = "world"; | ||||
|  | ||||
|       REQUIRE(1 == var.size()); | ||||
|       REQUIRE(std::string("world") == var["hello"]); | ||||
|     } | ||||
|  | ||||
|     SECTION("set value, key is a char[]") { | ||||
|       char key[] = "hello"; | ||||
|       var[key] = "world"; | ||||
|       key[0] = '!';  // make sure the key is duplicated | ||||
|  | ||||
|       REQUIRE(1 == var.size()); | ||||
|       REQUIRE(std::string("world") == var["hello"]); | ||||
|     } | ||||
|  | ||||
|     SECTION("var[key].to<JsonArray>()") { | ||||
|       JsonArray arr = var["hello"].to<JsonArray>(); | ||||
|       REQUIRE(arr.isNull() == false); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| #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 | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonVariantConst::operator[]") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant var = doc.to<JsonVariant>(); | ||||
|   JsonVariantConst cvar = var; | ||||
|  | ||||
|   SECTION("The JsonVariant is undefined") { | ||||
|     REQUIRE(0 == cvar.size()); | ||||
|     REQUIRE(cvar["0"].isNull()); | ||||
|     REQUIRE(cvar[0].isNull()); | ||||
|   } | ||||
|  | ||||
|   SECTION("The JsonVariant is a string") { | ||||
|     var.set("hello world"); | ||||
|     REQUIRE(0 == cvar.size()); | ||||
|     REQUIRE(cvar["0"].isNull()); | ||||
|     REQUIRE(cvar[0].isNull()); | ||||
|   } | ||||
|  | ||||
|   SECTION("The JsonVariant is a JsonArray") { | ||||
|     JsonArray array = var.to<JsonArray>(); | ||||
|  | ||||
|     SECTION("get value") { | ||||
|       array.add("element at index 0"); | ||||
|       array.add("element at index 1"); | ||||
|  | ||||
|       REQUIRE(2 == cvar.size()); | ||||
|       REQUIRE(std::string("element at index 0") == cvar[0]); | ||||
|       REQUIRE(std::string("element at index 1") == cvar[1]); | ||||
|       REQUIRE(std::string("element at index 0") == | ||||
|               var[static_cast<unsigned char>(0)]);  // issue #381 | ||||
|       REQUIRE(cvar[666].isNull()); | ||||
|       REQUIRE(cvar[3].isNull()); | ||||
|       REQUIRE(cvar["0"].isNull()); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("The JsonVariant is a JsonObject") { | ||||
|     JsonObject object = var.to<JsonObject>(); | ||||
|  | ||||
|     SECTION("get value") { | ||||
|       object["a"] = "element at key \"a\""; | ||||
|       object["b"] = "element at key \"b\""; | ||||
|  | ||||
|       REQUIRE(2 == cvar.size()); | ||||
|       REQUIRE(std::string("element at key \"a\"") == cvar["a"]); | ||||
|       REQUIRE(std::string("element at key \"b\"") == cvar["b"]); | ||||
|       REQUIRE(cvar["c"].isNull()); | ||||
|       REQUIRE(cvar[0].isNull()); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("Auto promote null JsonVariant to JsonObject") { | ||||
|     var["hello"] = "world"; | ||||
|  | ||||
|     REQUIRE(var.is<JsonObject>() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("Don't auto promote non-null JsonVariant to JsonObject") { | ||||
|     var.set(42); | ||||
|     var["hello"] = "world"; | ||||
|  | ||||
|     REQUIRE(var.is<JsonObject>() == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("Don't auto promote null JsonVariant to JsonObject when reading") { | ||||
|     const char* value = var["hello"]; | ||||
|  | ||||
|     REQUIRE(var.is<JsonObject>() == false); | ||||
|     REQUIRE(value == 0); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										140
									
								
								extras/tests/JsonVariant/types.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								extras/tests/JsonVariant/types.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,140 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <stdint.h> | ||||
| #include <catch.hpp> | ||||
| #include <limits> | ||||
|  | ||||
| template <typename T> | ||||
| void checkValue(T expected) { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   JsonVariant variant = doc.to<JsonVariant>(); | ||||
|  | ||||
|   variant.set(expected); | ||||
|   REQUIRE(expected == variant.as<T>()); | ||||
| } | ||||
|  | ||||
| template <typename T> | ||||
| void checkReference(T &expected) { | ||||
|   JsonVariant variant = expected; | ||||
|   REQUIRE(expected == variant.as<T &>()); | ||||
| } | ||||
|  | ||||
| template <typename T> | ||||
| void checkNumericType() { | ||||
|   DynamicJsonDocument docMin(4096), docMax(4096); | ||||
|   JsonVariant variantMin = docMin.to<JsonVariant>(); | ||||
|   JsonVariant variantMax = docMax.to<JsonVariant>(); | ||||
|  | ||||
|   T min = std::numeric_limits<T>::min(); | ||||
|   T max = std::numeric_limits<T>::max(); | ||||
|  | ||||
|   variantMin.set(min); | ||||
|   variantMax.set(max); | ||||
|  | ||||
|   REQUIRE(min == variantMin.as<T>()); | ||||
|   REQUIRE(max == variantMax.as<T>()); | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonVariant set()/get()") { | ||||
| #if ARDUINOJSON_USE_LONG_LONG | ||||
|   SECTION("SizeOfJsonInteger") { | ||||
|     REQUIRE(8 == sizeof(JsonInteger)); | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   SECTION("Null") { | ||||
|     checkValue<const char *>(NULL); | ||||
|   } | ||||
|   SECTION("const char*") { | ||||
|     checkValue<const char *>("hello"); | ||||
|   } | ||||
|   SECTION("std::string") { | ||||
|     checkValue<std::string>("hello"); | ||||
|   } | ||||
|  | ||||
|   SECTION("False") { | ||||
|     checkValue<bool>(false); | ||||
|   } | ||||
|   SECTION("True") { | ||||
|     checkValue<bool>(true); | ||||
|   } | ||||
|  | ||||
|   SECTION("Double") { | ||||
|     checkNumericType<double>(); | ||||
|   } | ||||
|   SECTION("Float") { | ||||
|     checkNumericType<float>(); | ||||
|   } | ||||
|   SECTION("Char") { | ||||
|     checkNumericType<char>(); | ||||
|   } | ||||
|   SECTION("SChar") { | ||||
|     checkNumericType<signed char>(); | ||||
|   } | ||||
|   SECTION("SInt") { | ||||
|     checkNumericType<signed int>(); | ||||
|   } | ||||
|   SECTION("SLong") { | ||||
|     checkNumericType<signed long>(); | ||||
|   } | ||||
|   SECTION("SShort") { | ||||
|     checkNumericType<signed short>(); | ||||
|   } | ||||
|   SECTION("UChar") { | ||||
|     checkNumericType<unsigned char>(); | ||||
|   } | ||||
|   SECTION("UInt") { | ||||
|     checkNumericType<unsigned int>(); | ||||
|   } | ||||
|   SECTION("ULong") { | ||||
|     checkNumericType<unsigned long>(); | ||||
|   } | ||||
|   SECTION("UShort") { | ||||
|     checkNumericType<unsigned short>(); | ||||
|   } | ||||
| #if ARDUINOJSON_USE_LONG_LONG | ||||
|   SECTION("LongLong") { | ||||
|     checkNumericType<unsigned long long>(); | ||||
|   } | ||||
|   SECTION("ULongLong") { | ||||
|     checkNumericType<unsigned long long>(); | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   SECTION("Int8") { | ||||
|     checkNumericType<int8_t>(); | ||||
|   } | ||||
|   SECTION("Uint8") { | ||||
|     checkNumericType<uint8_t>(); | ||||
|   } | ||||
|   SECTION("Int16") { | ||||
|     checkNumericType<int16_t>(); | ||||
|   } | ||||
|   SECTION("Uint16") { | ||||
|     checkNumericType<uint16_t>(); | ||||
|   } | ||||
|   SECTION("Int32") { | ||||
|     checkNumericType<int32_t>(); | ||||
|   } | ||||
|   SECTION("Uint32") { | ||||
|     checkNumericType<uint32_t>(); | ||||
|   } | ||||
| #if ARDUINOJSON_USE_LONG_LONG | ||||
|   SECTION("Int64") { | ||||
|     checkNumericType<int64_t>(); | ||||
|   } | ||||
|   SECTION("Uint64") { | ||||
|     checkNumericType<uint64_t>(); | ||||
|   } | ||||
| #endif | ||||
|  | ||||
|   SECTION("CanStoreObject") { | ||||
|     DynamicJsonDocument doc(4096); | ||||
|     JsonObject object = doc.to<JsonObject>(); | ||||
|  | ||||
|     checkValue<JsonObject>(object); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										70
									
								
								extras/tests/JsonVariant/undefined.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								extras/tests/JsonVariant/undefined.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonVariant undefined") { | ||||
|   JsonVariant variant; | ||||
|  | ||||
|   SECTION("as<T>()") { | ||||
|     SECTION("long") { | ||||
|       REQUIRE(variant.as<long>() == 0); | ||||
|     } | ||||
|  | ||||
|     SECTION("unsigned") { | ||||
|       REQUIRE(variant.as<unsigned>() == 0); | ||||
|     } | ||||
|  | ||||
|     SECTION("char*") { | ||||
|       REQUIRE(variant.as<char*>() == 0); | ||||
|     } | ||||
|  | ||||
|     SECTION("double") { | ||||
|       REQUIRE(variant.as<double>() == 0); | ||||
|     } | ||||
|  | ||||
|     SECTION("bool") { | ||||
|       REQUIRE(variant.as<bool>() == false); | ||||
|     } | ||||
|  | ||||
|     SECTION("JsonArray") { | ||||
|       REQUIRE(variant.as<JsonArray>().isNull()); | ||||
|     } | ||||
|  | ||||
|     SECTION("JsonObject") { | ||||
|       REQUIRE(variant.as<JsonObject>().isNull()); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("is<T>()") { | ||||
|     SECTION("long") { | ||||
|       REQUIRE(variant.is<long>() == false); | ||||
|     } | ||||
|  | ||||
|     SECTION("unsigned") { | ||||
|       REQUIRE(variant.is<unsigned>() == false); | ||||
|     } | ||||
|  | ||||
|     SECTION("char*") { | ||||
|       REQUIRE(variant.is<char*>() == false); | ||||
|     } | ||||
|  | ||||
|     SECTION("double") { | ||||
|       REQUIRE(variant.is<double>() == false); | ||||
|     } | ||||
|  | ||||
|     SECTION("bool") { | ||||
|       REQUIRE(variant.is<bool>() == false); | ||||
|     } | ||||
|  | ||||
|     SECTION("JsonArray") { | ||||
|       REQUIRE(variant.is<JsonArray>() == false); | ||||
|     } | ||||
|  | ||||
|     SECTION("JsonObject") { | ||||
|       REQUIRE(variant.is<JsonObject>() == false); | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										17
									
								
								extras/tests/MemberProxy/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								extras/tests/MemberProxy/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| # ArduinoJson - arduinojson.org | ||||
| # Copyright Benoit Blanchon 2014-2019 | ||||
| # MIT License | ||||
|  | ||||
| add_executable(MemberProxyTests | ||||
| 	add.cpp | ||||
| 	clear.cpp | ||||
| 	compare.cpp | ||||
| 	containsKey.cpp | ||||
| 	remove.cpp | ||||
| 	set.cpp | ||||
| 	size.cpp | ||||
| 	subscript.cpp | ||||
| ) | ||||
|  | ||||
| target_link_libraries(MemberProxyTests catch) | ||||
| add_test(MemberProxy MemberProxyTests) | ||||
							
								
								
									
										25
									
								
								extras/tests/MemberProxy/add.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								extras/tests/MemberProxy/add.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ARDUINOJSON_NAMESPACE; | ||||
|  | ||||
| TEST_CASE("MemberProxy::add()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   MemberProxy<JsonDocument&, const char*> mp = doc["hello"]; | ||||
|  | ||||
|   SECTION("add(int)") { | ||||
|     mp.add(42); | ||||
|  | ||||
|     REQUIRE(doc.as<std::string>() == "{\"hello\":[42]}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("add(const char*)") { | ||||
|     mp.add("world"); | ||||
|  | ||||
|     REQUIRE(doc.as<std::string>() == "{\"hello\":[\"world\"]}"); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										27
									
								
								extras/tests/MemberProxy/clear.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								extras/tests/MemberProxy/clear.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ARDUINOJSON_NAMESPACE; | ||||
|  | ||||
| TEST_CASE("MemberProxy::clear()") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   MemberProxy<JsonDocument&, const char*> mp = doc["hello"]; | ||||
|  | ||||
|   SECTION("size goes back to zero") { | ||||
|     mp.add(42); | ||||
|     mp.clear(); | ||||
|  | ||||
|     REQUIRE(mp.size() == 0); | ||||
|   } | ||||
|  | ||||
|   SECTION("isNull() return true") { | ||||
|     mp.add("hello"); | ||||
|     mp.clear(); | ||||
|  | ||||
|     REQUIRE(mp.isNull() == true); | ||||
|   } | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user