subscript.cpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. // ArduinoJson - https://arduinojson.org
  2. // Copyright © 2014-2023, Benoit BLANCHON
  3. // MIT License
  4. #include <ArduinoJson.h>
  5. #include <catch.hpp>
  6. using ArduinoJson::detail::sizeofObject;
  7. using ArduinoJson::detail::sizeofString;
  8. TEST_CASE("JsonObject::operator[]") {
  9. JsonDocument doc(4096);
  10. JsonObject obj = doc.to<JsonObject>();
  11. SECTION("int") {
  12. obj["hello"] = 123;
  13. REQUIRE(123 == obj["hello"].as<int>());
  14. REQUIRE(true == obj["hello"].is<int>());
  15. REQUIRE(false == obj["hello"].is<bool>());
  16. }
  17. SECTION("volatile int") { // issue #415
  18. volatile int i = 123;
  19. obj["hello"] = i;
  20. REQUIRE(123 == obj["hello"].as<int>());
  21. REQUIRE(true == obj["hello"].is<int>());
  22. REQUIRE(false == obj["hello"].is<bool>());
  23. }
  24. SECTION("double") {
  25. obj["hello"] = 123.45;
  26. REQUIRE(true == obj["hello"].is<double>());
  27. REQUIRE(false == obj["hello"].is<long>());
  28. REQUIRE(123.45 == obj["hello"].as<double>());
  29. }
  30. SECTION("bool") {
  31. obj["hello"] = true;
  32. REQUIRE(true == obj["hello"].is<bool>());
  33. REQUIRE(false == obj["hello"].is<long>());
  34. REQUIRE(true == obj["hello"].as<bool>());
  35. }
  36. SECTION("const char*") {
  37. obj["hello"] = "h3110";
  38. REQUIRE(true == obj["hello"].is<const char*>());
  39. REQUIRE(false == obj["hello"].is<long>());
  40. REQUIRE(std::string("h3110") == obj["hello"].as<const char*>());
  41. }
  42. SECTION("array") {
  43. JsonDocument doc2(4096);
  44. JsonArray arr = doc2.to<JsonArray>();
  45. obj["hello"] = arr;
  46. REQUIRE(arr == obj["hello"].as<JsonArray>());
  47. REQUIRE(true == obj["hello"].is<JsonArray>());
  48. REQUIRE(false == obj["hello"].is<JsonObject>());
  49. }
  50. SECTION("object") {
  51. JsonDocument doc2(4096);
  52. JsonObject obj2 = doc2.to<JsonObject>();
  53. obj["hello"] = obj2;
  54. REQUIRE(obj2 == obj["hello"].as<JsonObject>());
  55. REQUIRE(true == obj["hello"].is<JsonObject>());
  56. REQUIRE(false == obj["hello"].is<JsonArray>());
  57. }
  58. SECTION("array subscript") {
  59. JsonDocument doc2(4096);
  60. JsonArray arr = doc2.to<JsonArray>();
  61. arr.add(42);
  62. obj["a"] = arr[0];
  63. REQUIRE(42 == obj["a"]);
  64. }
  65. SECTION("object subscript") {
  66. JsonDocument doc2(4096);
  67. JsonObject obj2 = doc2.to<JsonObject>();
  68. obj2["x"] = 42;
  69. obj["a"] = obj2["x"];
  70. REQUIRE(42 == obj["a"]);
  71. }
  72. SECTION("char key[]") { // issue #423
  73. char key[] = "hello";
  74. obj[key] = 42;
  75. REQUIRE(42 == obj[key]);
  76. }
  77. SECTION("should not duplicate const char*") {
  78. obj["hello"] = "world";
  79. const size_t expectedSize = sizeofObject(1);
  80. REQUIRE(expectedSize == doc.memoryUsage());
  81. }
  82. SECTION("should duplicate char* value") {
  83. obj["hello"] = const_cast<char*>("world");
  84. const size_t expectedSize = sizeofObject(1) + sizeofString(5);
  85. REQUIRE(expectedSize == doc.memoryUsage());
  86. }
  87. SECTION("should duplicate char* key") {
  88. obj[const_cast<char*>("hello")] = "world";
  89. const size_t expectedSize = sizeofObject(1) + sizeofString(5);
  90. REQUIRE(expectedSize == doc.memoryUsage());
  91. }
  92. SECTION("should duplicate char* key&value") {
  93. obj[const_cast<char*>("hello")] = const_cast<char*>("world");
  94. const size_t expectedSize = sizeofObject(1) + 2 * sizeofString(5);
  95. REQUIRE(expectedSize <= doc.memoryUsage());
  96. }
  97. SECTION("should duplicate std::string value") {
  98. obj["hello"] = std::string("world");
  99. const size_t expectedSize = sizeofObject(1) + sizeofString(5);
  100. REQUIRE(expectedSize == doc.memoryUsage());
  101. }
  102. SECTION("should duplicate std::string key") {
  103. obj[std::string("hello")] = "world";
  104. const size_t expectedSize = sizeofObject(1) + sizeofString(5);
  105. REQUIRE(expectedSize == doc.memoryUsage());
  106. }
  107. SECTION("should duplicate std::string key&value") {
  108. obj[std::string("hello")] = std::string("world");
  109. const size_t expectedSize = sizeofObject(1) + 2 * sizeofString(5);
  110. REQUIRE(expectedSize <= doc.memoryUsage());
  111. }
  112. SECTION("should duplicate a non-static JsonString key") {
  113. obj[JsonString("hello", JsonString::Copied)] = "world";
  114. const size_t expectedSize = sizeofObject(1) + sizeofString(5);
  115. REQUIRE(expectedSize == doc.memoryUsage());
  116. }
  117. SECTION("should not duplicate a static JsonString key") {
  118. obj[JsonString("hello", JsonString::Linked)] = "world";
  119. const size_t expectedSize = sizeofObject(1);
  120. REQUIRE(expectedSize == doc.memoryUsage());
  121. }
  122. SECTION("should ignore null key") {
  123. // object must have a value to make a call to strcmp()
  124. obj["dummy"] = 42;
  125. const char* null = 0;
  126. obj[null] = 666;
  127. REQUIRE(obj.size() == 1);
  128. REQUIRE(obj[null] == null);
  129. }
  130. SECTION("obj[key].to<JsonArray>()") {
  131. JsonArray arr = obj["hello"].to<JsonArray>();
  132. REQUIRE(arr.isNull() == false);
  133. }
  134. #if defined(HAS_VARIABLE_LENGTH_ARRAY) && \
  135. !defined(SUBSCRIPT_CONFLICTS_WITH_BUILTIN_OPERATOR)
  136. SECTION("obj[VLA] = str") {
  137. size_t i = 16;
  138. char vla[i];
  139. strcpy(vla, "hello");
  140. obj[vla] = "world";
  141. REQUIRE(std::string("world") == obj["hello"]);
  142. }
  143. SECTION("obj[str] = VLA") { // issue #416
  144. size_t i = 32;
  145. char vla[i];
  146. strcpy(vla, "world");
  147. obj["hello"] = vla;
  148. REQUIRE(std::string("world") == obj["hello"].as<const char*>());
  149. }
  150. SECTION("obj.set(VLA, str)") {
  151. size_t i = 16;
  152. char vla[i];
  153. strcpy(vla, "hello");
  154. obj[vla] = "world";
  155. REQUIRE(std::string("world") == obj["hello"]);
  156. }
  157. SECTION("obj.set(str, VLA)") {
  158. size_t i = 32;
  159. char vla[i];
  160. strcpy(vla, "world");
  161. obj["hello"].set(vla);
  162. REQUIRE(std::string("world") == obj["hello"].as<const char*>());
  163. }
  164. SECTION("obj[VLA]") {
  165. size_t i = 16;
  166. char vla[i];
  167. strcpy(vla, "hello");
  168. deserializeJson(doc, "{\"hello\":\"world\"}");
  169. obj = doc.as<JsonObject>();
  170. REQUIRE(std::string("world") == obj[vla]);
  171. }
  172. #endif
  173. SECTION("chain") {
  174. obj.createNestedObject("hello")["world"] = 123;
  175. REQUIRE(123 == obj["hello"]["world"].as<int>());
  176. REQUIRE(true == obj["hello"]["world"].is<int>());
  177. REQUIRE(false == obj["hello"]["world"].is<bool>());
  178. }
  179. }