set.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. // ArduinoJson - https://arduinojson.org
  2. // Copyright © 2014-2024, Benoit BLANCHON
  3. // MIT License
  4. #include <ArduinoJson.h>
  5. #include <catch.hpp>
  6. #include "Allocators.hpp"
  7. using ArduinoJson::detail::sizeofObject;
  8. enum ErrorCode { ERROR_01 = 1, ERROR_10 = 10 };
  9. TEST_CASE("JsonVariant::set() when there is enough memory") {
  10. JsonDocument doc;
  11. JsonVariant variant = doc.to<JsonVariant>();
  12. SECTION("const char*") {
  13. char str[16];
  14. strcpy(str, "hello");
  15. bool result = variant.set(static_cast<const char*>(str));
  16. strcpy(str, "world");
  17. REQUIRE(result == true);
  18. REQUIRE(variant == "world"); // stores by pointer
  19. }
  20. SECTION("(const char*)0") {
  21. bool result = variant.set(static_cast<const char*>(0));
  22. REQUIRE(result == true);
  23. REQUIRE(variant.isNull());
  24. }
  25. SECTION("char*") {
  26. char str[16];
  27. strcpy(str, "hello");
  28. bool result = variant.set(str);
  29. strcpy(str, "world");
  30. REQUIRE(result == true);
  31. REQUIRE(variant == "hello"); // stores by copy
  32. }
  33. SECTION("(char*)0") {
  34. bool result = variant.set(static_cast<char*>(0));
  35. REQUIRE(result == true);
  36. REQUIRE(variant.isNull());
  37. }
  38. SECTION("unsigned char*") {
  39. char str[16];
  40. strcpy(str, "hello");
  41. bool result = variant.set(reinterpret_cast<unsigned char*>(str));
  42. strcpy(str, "world");
  43. REQUIRE(result == true);
  44. REQUIRE(variant == "hello"); // stores by copy
  45. }
  46. SECTION("signed char*") {
  47. char str[16];
  48. strcpy(str, "hello");
  49. bool result = variant.set(reinterpret_cast<signed char*>(str));
  50. strcpy(str, "world");
  51. REQUIRE(result == true);
  52. REQUIRE(variant == "hello"); // stores by copy
  53. }
  54. #ifdef HAS_VARIABLE_LENGTH_ARRAY
  55. SECTION("VLA") {
  56. size_t n = 16;
  57. char str[n];
  58. strcpy(str, "hello");
  59. bool result = variant.set(str);
  60. strcpy(str, "world");
  61. REQUIRE(result == true);
  62. REQUIRE(variant == "hello"); // stores by copy
  63. }
  64. #endif
  65. SECTION("std::string") {
  66. std::string str;
  67. str = "hello";
  68. bool result = variant.set(str);
  69. str.replace(0, 5, "world");
  70. REQUIRE(result == true);
  71. REQUIRE(variant == "hello"); // stores by copy
  72. }
  73. SECTION("static JsonString") {
  74. char str[16];
  75. strcpy(str, "hello");
  76. bool result = variant.set(JsonString(str, JsonString::Linked));
  77. strcpy(str, "world");
  78. REQUIRE(result == true);
  79. REQUIRE(variant == "world"); // stores by pointer
  80. }
  81. SECTION("non-static JsonString") {
  82. char str[16];
  83. strcpy(str, "hello");
  84. bool result = variant.set(JsonString(str, JsonString::Copied));
  85. strcpy(str, "world");
  86. REQUIRE(result == true);
  87. REQUIRE(variant == "hello"); // stores by copy
  88. }
  89. SECTION("enum") {
  90. ErrorCode code = ERROR_10;
  91. bool result = variant.set(code);
  92. REQUIRE(result == true);
  93. REQUIRE(variant.is<int>() == true);
  94. REQUIRE(variant.as<int>() == 10);
  95. }
  96. }
  97. TEST_CASE("JsonVariant::set() with not enough memory") {
  98. JsonDocument doc(FailingAllocator::instance());
  99. JsonVariant v = doc.to<JsonVariant>();
  100. SECTION("std::string") {
  101. bool result = v.set(std::string("hello world!!"));
  102. REQUIRE(result == false);
  103. REQUIRE(v.isNull());
  104. }
  105. SECTION("Serialized<std::string>") {
  106. bool result = v.set(serialized(std::string("hello world!!")));
  107. REQUIRE(result == false);
  108. REQUIRE(v.isNull());
  109. }
  110. SECTION("char*") {
  111. char s[] = "hello world!!";
  112. bool result = v.set(s);
  113. REQUIRE(result == false);
  114. REQUIRE(v.isNull());
  115. }
  116. }
  117. TEST_CASE("JsonVariant::set(JsonDocument)") {
  118. JsonDocument doc1;
  119. doc1["hello"] = "world";
  120. JsonDocument doc2;
  121. JsonVariant v = doc2.to<JsonVariant>();
  122. // Should copy the doc
  123. v.set(doc1);
  124. doc1.clear();
  125. std::string json;
  126. serializeJson(doc2, json);
  127. REQUIRE(json == "{\"hello\":\"world\"}");
  128. }
  129. TEST_CASE("JsonVariant::set() releases the previous value") {
  130. SpyingAllocator spy;
  131. JsonDocument doc(&spy);
  132. doc["hello"] = std::string("world");
  133. spy.clearLog();
  134. JsonVariant v = doc["hello"];
  135. SECTION("int") {
  136. v.set(42);
  137. REQUIRE(spy.log() == AllocatorLog{
  138. Deallocate(sizeofString("world")),
  139. });
  140. }
  141. SECTION("bool") {
  142. v.set(false);
  143. REQUIRE(spy.log() == AllocatorLog{
  144. Deallocate(sizeofString("world")),
  145. });
  146. }
  147. SECTION("const char*") {
  148. v.set("hello");
  149. REQUIRE(spy.log() == AllocatorLog{
  150. Deallocate(sizeofString("world")),
  151. });
  152. }
  153. SECTION("float") {
  154. v.set(1.2);
  155. REQUIRE(spy.log() == AllocatorLog{
  156. Deallocate(sizeofString("world")),
  157. });
  158. }
  159. SECTION("Serialized<const char*>") {
  160. v.set(serialized("[]"));
  161. REQUIRE(spy.log() == AllocatorLog{
  162. Deallocate(sizeofString("world")),
  163. Allocate(sizeofString("[]")),
  164. });
  165. }
  166. }