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:
		
							
								
								
									
										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); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user