add.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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. }
  66. TEST_CASE("JsonDocument::add<T>()") {
  67. JsonDocument doc;
  68. SECTION("JsonArray") {
  69. JsonArray array = doc.add<JsonArray>();
  70. array.add(1);
  71. array.add(2);
  72. REQUIRE(doc.as<std::string>() == "[[1,2]]");
  73. }
  74. SECTION("JsonVariant") {
  75. JsonVariant variant = doc.add<JsonVariant>();
  76. variant.set(42);
  77. REQUIRE(doc.as<std::string>() == "[42]");
  78. }
  79. }
  80. TEST_CASE("JsonObject::add(JsonObject) ") {
  81. JsonDocument doc1;
  82. doc1["hello"_s] = "world"_s;
  83. TimebombAllocator allocator(10);
  84. SpyingAllocator spy(&allocator);
  85. JsonDocument doc2(&spy);
  86. SECTION("success") {
  87. bool result = doc2.add(doc1.as<JsonObject>());
  88. REQUIRE(result == true);
  89. REQUIRE(doc2.as<std::string>() == "[{\"hello\":\"world\"}]");
  90. REQUIRE(spy.log() == AllocatorLog{
  91. Allocate(sizeofPool()),
  92. Allocate(sizeofString("hello")),
  93. Allocate(sizeofString("world")),
  94. });
  95. }
  96. SECTION("partial failure") { // issue #2081
  97. allocator.setCountdown(2);
  98. bool result = doc2.add(doc1.as<JsonObject>());
  99. REQUIRE(result == false);
  100. REQUIRE(doc2.as<std::string>() == "[]");
  101. REQUIRE(spy.log() == AllocatorLog{
  102. Allocate(sizeofPool()),
  103. Allocate(sizeofString("hello")),
  104. AllocateFail(sizeofString("world")),
  105. Deallocate(sizeofString("hello")),
  106. });
  107. }
  108. SECTION("complete failure") {
  109. allocator.setCountdown(0);
  110. bool result = doc2.add(doc1.as<JsonObject>());
  111. REQUIRE(result == false);
  112. REQUIRE(doc2.as<std::string>() == "[]");
  113. REQUIRE(spy.log() == AllocatorLog{
  114. AllocateFail(sizeofPool()),
  115. });
  116. }
  117. }