| 
									
										
										
										
											2021-03-29 17:14:01 +02:00
										 |  |  | // ArduinoJson - https://arduinojson.org
 | 
					
						
							| 
									
										
										
										
											2025-02-24 15:18:26 +01:00
										 |  |  | // Copyright © 2014-2025, Benoit BLANCHON
 | 
					
						
							| 
									
										
										
										
											2019-01-23 11:43:29 +01:00
										 |  |  | // MIT License
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <ArduinoJson.h>
 | 
					
						
							|  |  |  | #include <catch.hpp>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-25 11:32:03 +01:00
										 |  |  | #include "Allocators.hpp"
 | 
					
						
							| 
									
										
										
										
											2024-06-07 09:35:45 +02:00
										 |  |  | #include "Literals.hpp"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-23 11:43:29 +01:00
										 |  |  | TEST_CASE("JsonDocument::operator[]") { | 
					
						
							| 
									
										
										
										
											2023-07-17 18:15:13 +02:00
										 |  |  |   JsonDocument doc; | 
					
						
							| 
									
										
										
										
											2019-01-23 11:43:29 +01:00
										 |  |  |   const JsonDocument& cdoc = doc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   SECTION("object") { | 
					
						
							| 
									
										
										
										
											2024-11-14 14:56:47 +01:00
										 |  |  |     doc["abc"_s] = "ABC"; | 
					
						
							|  |  |  |     doc["abc\0d"_s] = "ABCD"; | 
					
						
							| 
									
										
										
										
											2019-01-23 11:43:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     SECTION("const char*") { | 
					
						
							| 
									
										
										
										
											2024-11-25 11:32:03 +01:00
										 |  |  |       const char* key = "abc"; | 
					
						
							|  |  |  |       REQUIRE(doc[key] == "ABC"); | 
					
						
							|  |  |  |       REQUIRE(cdoc[key] == "ABC"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SECTION("string literal") { | 
					
						
							| 
									
										
										
										
											2024-11-14 14:56:47 +01:00
										 |  |  |       REQUIRE(doc["abc"] == "ABC"); | 
					
						
							|  |  |  |       REQUIRE(cdoc["abc"] == "ABC"); | 
					
						
							| 
									
										
										
										
											2024-11-25 11:32:03 +01:00
										 |  |  |       REQUIRE(doc["abc\0d"] == "ABCD"); | 
					
						
							|  |  |  |       REQUIRE(cdoc["abc\0d"] == "ABCD"); | 
					
						
							| 
									
										
										
										
											2019-01-23 11:43:29 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SECTION("std::string") { | 
					
						
							| 
									
										
										
										
											2024-11-14 14:56:47 +01:00
										 |  |  |       REQUIRE(doc["abc"_s] == "ABC"); | 
					
						
							|  |  |  |       REQUIRE(cdoc["abc"_s] == "ABC"); | 
					
						
							|  |  |  |       REQUIRE(doc["abc\0d"_s] == "ABCD"); | 
					
						
							|  |  |  |       REQUIRE(cdoc["abc\0d"_s] == "ABCD"); | 
					
						
							| 
									
										
										
										
											2019-01-23 11:43:29 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-01-29 14:09:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-14 21:06:02 +02:00
										 |  |  |     SECTION("JsonVariant") { | 
					
						
							| 
									
										
										
										
											2024-11-14 14:56:47 +01:00
										 |  |  |       doc["key1"] = "abc"; | 
					
						
							|  |  |  |       doc["key2"] = "abc\0d"_s; | 
					
						
							|  |  |  |       doc["key3"] = "foo"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       CHECK(doc[doc["key1"]] == "ABC"); | 
					
						
							|  |  |  |       CHECK(doc[doc["key2"]] == "ABCD"); | 
					
						
							|  |  |  |       CHECK(doc[doc["key3"]] == nullptr); | 
					
						
							|  |  |  |       CHECK(doc[doc["key4"]] == nullptr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       CHECK(cdoc[cdoc["key1"]] == "ABC"); | 
					
						
							|  |  |  |       CHECK(cdoc[cdoc["key2"]] == "ABCD"); | 
					
						
							|  |  |  |       CHECK(cdoc[cdoc["key3"]] == nullptr); | 
					
						
							|  |  |  |       CHECK(cdoc[cdoc["key4"]] == nullptr); | 
					
						
							| 
									
										
										
										
											2024-05-14 21:06:02 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-29 14:09:09 +01:00
										 |  |  |     SECTION("supports operator|") { | 
					
						
							| 
									
										
										
										
											2024-11-14 14:56:47 +01:00
										 |  |  |       REQUIRE((doc["abc"] | "nope") == "ABC"_s); | 
					
						
							|  |  |  |       REQUIRE((doc["def"] | "nope") == "nope"_s); | 
					
						
							| 
									
										
										
										
											2019-01-29 14:09:09 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-11-07 14:19:47 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined(HAS_VARIABLE_LENGTH_ARRAY) && \
 | 
					
						
							|  |  |  |     !defined(SUBSCRIPT_CONFLICTS_WITH_BUILTIN_OPERATOR) | 
					
						
							|  |  |  |     SECTION("supports VLAs") { | 
					
						
							|  |  |  |       size_t i = 16; | 
					
						
							|  |  |  |       char vla[i]; | 
					
						
							|  |  |  |       strcpy(vla, "hello"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       doc[vla] = "world"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       REQUIRE(doc[vla] == "world"); | 
					
						
							|  |  |  |       REQUIRE(cdoc[vla] == "world"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2019-01-23 11:43:29 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   SECTION("array") { | 
					
						
							|  |  |  |     deserializeJson(doc, "[\"hello\",\"world\"]"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-05-14 21:06:02 +02:00
										 |  |  |     SECTION("int") { | 
					
						
							|  |  |  |       REQUIRE(doc[1] == "world"); | 
					
						
							|  |  |  |       REQUIRE(cdoc[1] == "world"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SECTION("JsonVariant") { | 
					
						
							|  |  |  |       doc[2] = 1; | 
					
						
							|  |  |  |       REQUIRE(doc[doc[2]] == "world"); | 
					
						
							|  |  |  |       REQUIRE(cdoc[doc[2]] == "world"); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-01-23 11:43:29 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-01-29 14:09:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | TEST_CASE("JsonDocument automatically promotes to object") { | 
					
						
							| 
									
										
										
										
											2023-07-17 18:15:13 +02:00
										 |  |  |   JsonDocument doc; | 
					
						
							| 
									
										
										
										
											2019-01-29 14:09:09 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   doc["one"]["two"]["three"] = 4; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   REQUIRE(doc["one"]["two"]["three"] == 4); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-02-20 08:59:25 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | TEST_CASE("JsonDocument automatically promotes to array") { | 
					
						
							| 
									
										
										
										
											2023-07-17 18:15:13 +02:00
										 |  |  |   JsonDocument doc; | 
					
						
							| 
									
										
										
										
											2020-02-20 08:59:25 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   doc[2] = 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   REQUIRE(doc.as<std::string>() == "[null,null,2]"); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2024-11-25 11:32:03 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | TEST_CASE("JsonDocument::operator[] key storage") { | 
					
						
							|  |  |  |   SpyingAllocator spy; | 
					
						
							|  |  |  |   JsonDocument doc(&spy); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   SECTION("string literal") { | 
					
						
							|  |  |  |     doc["hello"] = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE(doc.as<std::string>() == "{\"hello\":0}"); | 
					
						
							|  |  |  |     REQUIRE(spy.log() == AllocatorLog{ | 
					
						
							|  |  |  |                              Allocate(sizeofPool()), | 
					
						
							|  |  |  |                          }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   SECTION("const char*") { | 
					
						
							|  |  |  |     const char* key = "hello"; | 
					
						
							|  |  |  |     doc[key] = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE(doc.as<std::string>() == "{\"hello\":0}"); | 
					
						
							|  |  |  |     REQUIRE(spy.log() == AllocatorLog{ | 
					
						
							|  |  |  |                              Allocate(sizeofPool()), | 
					
						
							|  |  |  |                              Allocate(sizeofString("hello")), | 
					
						
							|  |  |  |                          }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   SECTION("char[]") { | 
					
						
							|  |  |  |     char key[] = "hello"; | 
					
						
							|  |  |  |     doc[key] = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE(doc.as<std::string>() == "{\"hello\":0}"); | 
					
						
							|  |  |  |     REQUIRE(spy.log() == AllocatorLog{ | 
					
						
							|  |  |  |                              Allocate(sizeofPool()), | 
					
						
							|  |  |  |                              Allocate(sizeofString("hello")), | 
					
						
							|  |  |  |                          }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   SECTION("std::string") { | 
					
						
							|  |  |  |     doc["hello"_s] = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE(doc.as<std::string>() == "{\"hello\":0}"); | 
					
						
							|  |  |  |     REQUIRE(spy.log() == AllocatorLog{ | 
					
						
							|  |  |  |                              Allocate(sizeofPool()), | 
					
						
							|  |  |  |                              Allocate(sizeofString("hello")), | 
					
						
							|  |  |  |                          }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #if defined(HAS_VARIABLE_LENGTH_ARRAY) && \
 | 
					
						
							|  |  |  |     !defined(SUBSCRIPT_CONFLICTS_WITH_BUILTIN_OPERATOR) | 
					
						
							|  |  |  |   SECTION("VLA") { | 
					
						
							|  |  |  |     size_t i = 16; | 
					
						
							|  |  |  |     char vla[i]; | 
					
						
							|  |  |  |     strcpy(vla, "hello"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     doc[vla] = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     REQUIRE(doc.as<std::string>() == "{\"hello\":0}"); | 
					
						
							|  |  |  |     REQUIRE(spy.log() == AllocatorLog{ | 
					
						
							|  |  |  |                              Allocate(sizeofPool()), | 
					
						
							|  |  |  |                              Allocate(sizeofString("hello")), | 
					
						
							|  |  |  |                          }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } |