set.cpp 4.9 KB

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