add.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // ArduinoJson - https://arduinojson.org
  2. // Copyright © 2014-2024, Benoit BLANCHON
  3. // MIT License
  4. #define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
  5. #define ARDUINOJSON_ENABLE_PROGMEM 1
  6. #include <ArduinoJson.h>
  7. #include <catch.hpp>
  8. #include "Allocators.hpp"
  9. #include "Literals.hpp"
  10. using ArduinoJson::detail::sizeofArray;
  11. TEST_CASE("JsonDocument::add(T)") {
  12. SpyingAllocator spy;
  13. JsonDocument doc(&spy);
  14. SECTION("integer") {
  15. doc.add(42);
  16. REQUIRE(doc.as<std::string>() == "[42]");
  17. REQUIRE(spy.log() == AllocatorLog{
  18. Allocate(sizeofPool()),
  19. });
  20. }
  21. SECTION("const char*") {
  22. doc.add("hello");
  23. REQUIRE(doc.as<std::string>() == "[\"hello\"]");
  24. REQUIRE(spy.log() == AllocatorLog{
  25. Allocate(sizeofPool()),
  26. });
  27. }
  28. SECTION("std::string") {
  29. doc.add("example"_s);
  30. doc.add("example"_s);
  31. CHECK(doc[0].as<const char*>() == doc[1].as<const char*>());
  32. REQUIRE(spy.log() == AllocatorLog{
  33. Allocate(sizeofPool()),
  34. Allocate(sizeofString("example")),
  35. });
  36. }
  37. SECTION("char*") {
  38. char value[] = "example";
  39. doc.add(value);
  40. doc.add(value);
  41. CHECK(doc[0].as<const char*>() == doc[1].as<const char*>());
  42. REQUIRE(spy.log() == AllocatorLog{
  43. Allocate(sizeofPool()),
  44. Allocate(sizeofString("example")),
  45. });
  46. }
  47. SECTION("Arduino String") {
  48. doc.add(String("example"));
  49. doc.add(String("example"));
  50. CHECK(doc[0].as<const char*>() == doc[1].as<const char*>());
  51. REQUIRE(spy.log() == AllocatorLog{
  52. Allocate(sizeofPool()),
  53. Allocate(sizeofString("example")),
  54. });
  55. }
  56. SECTION("Flash string") {
  57. doc.add(F("example"));
  58. doc.add(F("example"));
  59. CHECK(doc[0].as<const char*>() == doc[1].as<const char*>());
  60. REQUIRE(spy.log() == AllocatorLog{
  61. Allocate(sizeofPool()),
  62. Allocate(sizeofString("example")),
  63. });
  64. }
  65. #ifdef HAS_VARIABLE_LENGTH_ARRAY
  66. SECTION("VLA") {
  67. size_t i = 16;
  68. char vla[i];
  69. strcpy(vla, "example");
  70. doc.add(vla);
  71. doc.add(vla);
  72. CHECK(doc[0].as<const char*>() == doc[1].as<const char*>());
  73. REQUIRE("example"_s == doc[0]);
  74. REQUIRE(spy.log() == AllocatorLog{
  75. Allocate(sizeofPool()),
  76. Allocate(sizeofString("example")),
  77. });
  78. }
  79. #endif
  80. }
  81. TEST_CASE("JsonDocument::add<T>()") {
  82. JsonDocument doc;
  83. SECTION("JsonArray") {
  84. JsonArray array = doc.add<JsonArray>();
  85. array.add(1);
  86. array.add(2);
  87. REQUIRE(doc.as<std::string>() == "[[1,2]]");
  88. }
  89. SECTION("JsonVariant") {
  90. JsonVariant variant = doc.add<JsonVariant>();
  91. variant.set(42);
  92. REQUIRE(doc.as<std::string>() == "[42]");
  93. }
  94. }
  95. TEST_CASE("JsonObject::add(JsonObject) ") {
  96. JsonDocument doc1;
  97. doc1["hello"_s] = "world"_s;
  98. TimebombAllocator allocator(10);
  99. SpyingAllocator spy(&allocator);
  100. JsonDocument doc2(&spy);
  101. SECTION("success") {
  102. bool result = doc2.add(doc1.as<JsonObject>());
  103. REQUIRE(result == true);
  104. REQUIRE(doc2.as<std::string>() == "[{\"hello\":\"world\"}]");
  105. REQUIRE(spy.log() == AllocatorLog{
  106. Allocate(sizeofPool()),
  107. Allocate(sizeofString("hello")),
  108. Allocate(sizeofString("world")),
  109. });
  110. }
  111. SECTION("partial failure") { // issue #2081
  112. allocator.setCountdown(2);
  113. bool result = doc2.add(doc1.as<JsonObject>());
  114. REQUIRE(result == false);
  115. REQUIRE(doc2.as<std::string>() == "[]");
  116. REQUIRE(spy.log() == AllocatorLog{
  117. Allocate(sizeofPool()),
  118. Allocate(sizeofString("hello")),
  119. AllocateFail(sizeofString("world")),
  120. Deallocate(sizeofString("hello")),
  121. });
  122. }
  123. SECTION("complete failure") {
  124. allocator.setCountdown(0);
  125. bool result = doc2.add(doc1.as<JsonObject>());
  126. REQUIRE(result == false);
  127. REQUIRE(doc2.as<std::string>() == "[]");
  128. REQUIRE(spy.log() == AllocatorLog{
  129. AllocateFail(sizeofPool()),
  130. });
  131. }
  132. }