subscript.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. // ArduinoJson - https://arduinojson.org
  2. // Copyright © 2014-2025, Benoit BLANCHON
  3. // MIT License
  4. #include <ArduinoJson.h>
  5. #include <catch.hpp>
  6. #include "Allocators.hpp"
  7. #include "Literals.hpp"
  8. TEST_CASE("JsonObject::operator[]") {
  9. SpyingAllocator spy;
  10. JsonDocument doc(&spy);
  11. JsonObject obj = doc.to<JsonObject>();
  12. SECTION("int") {
  13. obj["hello"] = 123;
  14. REQUIRE(123 == obj["hello"].as<int>());
  15. REQUIRE(true == obj["hello"].is<int>());
  16. REQUIRE(false == obj["hello"].is<bool>());
  17. }
  18. SECTION("volatile int") { // issue #415
  19. volatile int i = 123;
  20. obj["hello"] = i;
  21. REQUIRE(123 == obj["hello"].as<int>());
  22. REQUIRE(true == obj["hello"].is<int>());
  23. REQUIRE(false == obj["hello"].is<bool>());
  24. }
  25. SECTION("double") {
  26. obj["hello"] = 123.45;
  27. REQUIRE(true == obj["hello"].is<double>());
  28. REQUIRE(false == obj["hello"].is<long>());
  29. REQUIRE(123.45 == obj["hello"].as<double>());
  30. }
  31. SECTION("bool") {
  32. obj["hello"] = true;
  33. REQUIRE(true == obj["hello"].is<bool>());
  34. REQUIRE(false == obj["hello"].is<long>());
  35. REQUIRE(true == obj["hello"].as<bool>());
  36. }
  37. SECTION("const char*") {
  38. obj["hello"] = "h3110";
  39. REQUIRE(true == obj["hello"].is<const char*>());
  40. REQUIRE(false == obj["hello"].is<long>());
  41. REQUIRE("h3110"_s == obj["hello"].as<const char*>());
  42. }
  43. SECTION("array") {
  44. JsonDocument doc2;
  45. JsonArray arr = doc2.to<JsonArray>();
  46. obj["hello"] = arr;
  47. REQUIRE(arr == obj["hello"].as<JsonArray>());
  48. REQUIRE(true == obj["hello"].is<JsonArray>());
  49. REQUIRE(false == obj["hello"].is<JsonObject>());
  50. }
  51. SECTION("object") {
  52. JsonDocument doc2;
  53. JsonObject obj2 = doc2.to<JsonObject>();
  54. obj["hello"] = obj2;
  55. REQUIRE(obj2 == obj["hello"].as<JsonObject>());
  56. REQUIRE(true == obj["hello"].is<JsonObject>());
  57. REQUIRE(false == obj["hello"].is<JsonArray>());
  58. }
  59. SECTION("array subscript") {
  60. JsonDocument doc2;
  61. JsonArray arr = doc2.to<JsonArray>();
  62. arr.add(42);
  63. obj["a"] = arr[0];
  64. REQUIRE(42 == obj["a"]);
  65. }
  66. SECTION("object subscript") {
  67. JsonDocument doc2;
  68. JsonObject obj2 = doc2.to<JsonObject>();
  69. obj2["x"] = 42;
  70. obj["a"] = obj2["x"];
  71. REQUIRE(42 == obj["a"]);
  72. }
  73. SECTION("char key[]") { // issue #423
  74. char key[] = "hello";
  75. obj[key] = 42;
  76. REQUIRE(42 == obj[key]);
  77. }
  78. SECTION("should duplicate key and value strings") {
  79. obj["hello"] = "world";
  80. REQUIRE(spy.log() == AllocatorLog{
  81. Allocate(sizeofPool()),
  82. Allocate(sizeofString("hello")),
  83. Allocate(sizeofString("world")),
  84. });
  85. }
  86. SECTION("should ignore null key") {
  87. // object must have a value to make a call to strcmp()
  88. obj["dummy"] = 42;
  89. const char* null = 0;
  90. obj[null] = 666;
  91. REQUIRE(obj.size() == 1);
  92. REQUIRE(obj[null] == null);
  93. }
  94. SECTION("obj[key].to<JsonArray>()") {
  95. JsonArray arr = obj["hello"].to<JsonArray>();
  96. REQUIRE(arr.isNull() == false);
  97. }
  98. #if defined(HAS_VARIABLE_LENGTH_ARRAY) && \
  99. !defined(SUBSCRIPT_CONFLICTS_WITH_BUILTIN_OPERATOR)
  100. SECTION("obj[VLA] = str") {
  101. size_t i = 16;
  102. char vla[i];
  103. strcpy(vla, "hello");
  104. obj[vla] = "world";
  105. REQUIRE("world"_s == obj["hello"]);
  106. }
  107. SECTION("obj[str] = VLA") { // issue #416
  108. size_t i = 32;
  109. char vla[i];
  110. strcpy(vla, "world");
  111. obj["hello"] = vla;
  112. REQUIRE("world"_s == obj["hello"].as<const char*>());
  113. }
  114. SECTION("obj.set(VLA, str)") {
  115. size_t i = 16;
  116. char vla[i];
  117. strcpy(vla, "hello");
  118. obj[vla] = "world";
  119. REQUIRE("world"_s == obj["hello"]);
  120. }
  121. SECTION("obj.set(str, VLA)") {
  122. size_t i = 32;
  123. char vla[i];
  124. strcpy(vla, "world");
  125. obj["hello"].set(vla);
  126. REQUIRE("world"_s == obj["hello"].as<const char*>());
  127. }
  128. SECTION("obj[VLA]") {
  129. size_t i = 16;
  130. char vla[i];
  131. strcpy(vla, "hello");
  132. deserializeJson(doc, "{\"hello\":\"world\"}");
  133. obj = doc.as<JsonObject>();
  134. REQUIRE("world"_s == obj[vla]);
  135. }
  136. #endif
  137. SECTION("chain") {
  138. obj["hello"]["world"] = 123;
  139. REQUIRE(123 == obj["hello"]["world"].as<int>());
  140. REQUIRE(true == obj["hello"]["world"].is<int>());
  141. REQUIRE(false == obj["hello"]["world"].is<bool>());
  142. }
  143. SECTION("JsonVariant") {
  144. obj["hello"] = "world";
  145. obj["a\0b"_s] = "ABC";
  146. doc["key1"] = "hello";
  147. doc["key2"] = "a\0b"_s;
  148. doc["key3"] = "foo";
  149. REQUIRE(obj[obj["key1"]] == "world");
  150. REQUIRE(obj[obj["key2"]] == "ABC");
  151. REQUIRE(obj[obj["key3"]] == nullptr);
  152. REQUIRE(obj[obj["key4"]] == nullptr);
  153. }
  154. }