enable_progmem_1.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // ArduinoJson - https://arduinojson.org
  2. // Copyright © 2014-2025, Benoit BLANCHON
  3. // MIT License
  4. #define ARDUINOJSON_ENABLE_PROGMEM 1
  5. #include <ArduinoJson.h>
  6. #include <catch.hpp>
  7. TEST_CASE("Flash strings") {
  8. JsonDocument doc;
  9. SECTION("deserializeJson()") {
  10. DeserializationError err = deserializeJson(doc, F("{'hello':'world'}"));
  11. REQUIRE(err == DeserializationError::Ok);
  12. REQUIRE(doc["hello"] == "world");
  13. }
  14. SECTION("JsonDocument::operator[]") {
  15. doc[F("hello")] = F("world");
  16. REQUIRE(doc["hello"] == "world");
  17. }
  18. SECTION("JsonDocument::add()") {
  19. doc.add(F("world"));
  20. REQUIRE(doc[0] == "world");
  21. }
  22. SECTION("JsonVariant::set()") {
  23. JsonVariant var = doc.to<JsonVariant>();
  24. var.set(F("world"));
  25. REQUIRE(var == "world");
  26. }
  27. SECTION("MemberProxy::operator==") {
  28. doc["hello"] = "world";
  29. REQUIRE(doc["hello"] == F("world"));
  30. }
  31. SECTION("ElementProxy::operator==") {
  32. doc.add("world");
  33. REQUIRE(doc[0] == F("world"));
  34. }
  35. }
  36. TEST_CASE("parseNumber()") { // tables are in Flash
  37. using ArduinoJson::detail::parseNumber;
  38. CHECK(parseNumber<float>("1") == 1.f);
  39. CHECK(parseNumber<float>("1.23") == 1.23f);
  40. CHECK(parseNumber<float>("-1.23e34") == -1.23e34f);
  41. }
  42. TEST_CASE("strlen_P") {
  43. CHECK(strlen_P(PSTR("")) == 0);
  44. CHECK(strlen_P(PSTR("a")) == 1);
  45. CHECK(strlen_P(PSTR("ac")) == 2);
  46. }
  47. TEST_CASE("strncmp_P") {
  48. CHECK(strncmp_P("a", PSTR("b"), 0) == 0);
  49. CHECK(strncmp_P("a", PSTR("b"), 1) == -1);
  50. CHECK(strncmp_P("b", PSTR("a"), 1) == 1);
  51. CHECK(strncmp_P("a", PSTR("a"), 0) == 0);
  52. CHECK(strncmp_P("a", PSTR("b"), 2) == -1);
  53. CHECK(strncmp_P("b", PSTR("a"), 2) == 1);
  54. CHECK(strncmp_P("a", PSTR("a"), 2) == 0);
  55. }
  56. TEST_CASE("strcmp_P") {
  57. CHECK(strcmp_P("a", PSTR("b")) == -1);
  58. CHECK(strcmp_P("b", PSTR("a")) == 1);
  59. CHECK(strcmp_P("a", PSTR("a")) == 0);
  60. CHECK(strcmp_P("aa", PSTR("ab")) == -1);
  61. CHECK(strcmp_P("ab", PSTR("aa")) == 1);
  62. CHECK(strcmp_P("aa", PSTR("aa")) == 0);
  63. }
  64. TEST_CASE("memcpy_P") {
  65. char dst[4];
  66. CHECK(memcpy_P(dst, PSTR("ABC"), 4) == dst);
  67. CHECK(dst[0] == 'A');
  68. CHECK(dst[1] == 'B');
  69. CHECK(dst[2] == 'C');
  70. CHECK(dst[3] == 0);
  71. }
  72. TEST_CASE("BoundedReader<const __FlashStringHelper*>") {
  73. using namespace ArduinoJson::detail;
  74. SECTION("read") {
  75. BoundedReader<const __FlashStringHelper*> reader(F("\x01\xFF"), 2);
  76. REQUIRE(reader.read() == 0x01);
  77. REQUIRE(reader.read() == 0xFF);
  78. REQUIRE(reader.read() == -1);
  79. REQUIRE(reader.read() == -1);
  80. }
  81. SECTION("readBytes() all at once") {
  82. BoundedReader<const __FlashStringHelper*> reader(F("ABCD"), 3);
  83. char buffer[8] = "abcd";
  84. REQUIRE(reader.readBytes(buffer, 4) == 3);
  85. REQUIRE(buffer[0] == 'A');
  86. REQUIRE(buffer[1] == 'B');
  87. REQUIRE(buffer[2] == 'C');
  88. REQUIRE(buffer[3] == 'd');
  89. }
  90. SECTION("readBytes() in two parts") {
  91. BoundedReader<const __FlashStringHelper*> reader(F("ABCDEF"), 6);
  92. char buffer[8] = "abcdefg";
  93. REQUIRE(reader.readBytes(buffer, 4) == 4);
  94. REQUIRE(reader.readBytes(buffer + 4, 4) == 2);
  95. REQUIRE(buffer[0] == 'A');
  96. REQUIRE(buffer[1] == 'B');
  97. REQUIRE(buffer[2] == 'C');
  98. REQUIRE(buffer[3] == 'D');
  99. REQUIRE(buffer[4] == 'E');
  100. REQUIRE(buffer[5] == 'F');
  101. REQUIRE(buffer[6] == 'g');
  102. }
  103. }
  104. TEST_CASE("Reader<const __FlashStringHelper*>") {
  105. using namespace ArduinoJson::detail;
  106. SECTION("read()") {
  107. Reader<const __FlashStringHelper*> reader(F("\x01\xFF\x00\x12"));
  108. REQUIRE(reader.read() == 0x01);
  109. REQUIRE(reader.read() == 0xFF);
  110. REQUIRE(reader.read() == 0);
  111. REQUIRE(reader.read() == 0x12);
  112. }
  113. SECTION("readBytes() all at once") {
  114. Reader<const __FlashStringHelper*> reader(F("ABCD"));
  115. char buffer[8] = "abcd";
  116. REQUIRE(reader.readBytes(buffer, 3) == 3);
  117. REQUIRE(buffer[0] == 'A');
  118. REQUIRE(buffer[1] == 'B');
  119. REQUIRE(buffer[2] == 'C');
  120. REQUIRE(buffer[3] == 'd');
  121. }
  122. SECTION("readBytes() in two parts") {
  123. Reader<const __FlashStringHelper*> reader(F("ABCDEF"));
  124. char buffer[8] = "abcdefg";
  125. REQUIRE(reader.readBytes(buffer, 4) == 4);
  126. REQUIRE(reader.readBytes(buffer + 4, 2) == 2);
  127. REQUIRE(buffer[0] == 'A');
  128. REQUIRE(buffer[1] == 'B');
  129. REQUIRE(buffer[2] == 'C');
  130. REQUIRE(buffer[3] == 'D');
  131. REQUIRE(buffer[4] == 'E');
  132. REQUIRE(buffer[5] == 'F');
  133. REQUIRE(buffer[6] == 'g');
  134. }
  135. }
  136. static void testStringification(DeserializationError error,
  137. std::string expected) {
  138. const __FlashStringHelper* s = error.f_str();
  139. CHECK(reinterpret_cast<const char*>(convertFlashToPtr(s)) == expected);
  140. }
  141. #define TEST_STRINGIFICATION(symbol) \
  142. testStringification(DeserializationError::symbol, #symbol)
  143. TEST_CASE("DeserializationError::f_str()") {
  144. TEST_STRINGIFICATION(Ok);
  145. TEST_STRINGIFICATION(EmptyInput);
  146. TEST_STRINGIFICATION(IncompleteInput);
  147. TEST_STRINGIFICATION(InvalidInput);
  148. TEST_STRINGIFICATION(NoMemory);
  149. TEST_STRINGIFICATION(TooDeep);
  150. }