added library json
This commit is contained in:
@ -0,0 +1,180 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2023, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <stdlib.h> // malloc, free
|
||||
#include <catch.hpp>
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
class SpyingAllocator {
|
||||
public:
|
||||
SpyingAllocator(const SpyingAllocator& src) : log_(src.log_) {}
|
||||
SpyingAllocator(std::ostream& log) : log_(log) {}
|
||||
SpyingAllocator& operator=(const SpyingAllocator& src) = delete;
|
||||
|
||||
void* allocate(size_t n) {
|
||||
log_ << "A" << n;
|
||||
return malloc(n);
|
||||
}
|
||||
void deallocate(void* p) {
|
||||
log_ << "F";
|
||||
free(p);
|
||||
}
|
||||
|
||||
private:
|
||||
std::ostream& log_;
|
||||
};
|
||||
|
||||
class ControllableAllocator {
|
||||
public:
|
||||
ControllableAllocator() : enabled_(true) {}
|
||||
|
||||
void* allocate(size_t n) {
|
||||
return enabled_ ? malloc(n) : 0;
|
||||
}
|
||||
|
||||
void deallocate(void* p) {
|
||||
free(p);
|
||||
}
|
||||
|
||||
void disable() {
|
||||
enabled_ = false;
|
||||
}
|
||||
|
||||
private:
|
||||
bool enabled_;
|
||||
};
|
||||
|
||||
TEST_CASE("BasicJsonDocument") {
|
||||
std::stringstream log;
|
||||
|
||||
SECTION("Construct/Destruct") {
|
||||
{ BasicJsonDocument<SpyingAllocator> doc(4096, log); }
|
||||
REQUIRE(log.str() == "A4096F");
|
||||
}
|
||||
|
||||
SECTION("Copy construct") {
|
||||
{
|
||||
BasicJsonDocument<SpyingAllocator> doc1(4096, log);
|
||||
doc1.set(std::string("The size of this string is 32!!"));
|
||||
|
||||
BasicJsonDocument<SpyingAllocator> doc2(doc1);
|
||||
|
||||
REQUIRE(doc1.as<std::string>() == "The size of this string is 32!!");
|
||||
REQUIRE(doc2.as<std::string>() == "The size of this string is 32!!");
|
||||
REQUIRE(doc2.capacity() == 4096);
|
||||
}
|
||||
REQUIRE(log.str() == "A4096A4096FF");
|
||||
}
|
||||
|
||||
SECTION("Move construct") {
|
||||
{
|
||||
BasicJsonDocument<SpyingAllocator> doc1(4096, log);
|
||||
doc1.set(std::string("The size of this string is 32!!"));
|
||||
|
||||
BasicJsonDocument<SpyingAllocator> doc2(std::move(doc1));
|
||||
|
||||
REQUIRE(doc2.as<std::string>() == "The size of this string is 32!!");
|
||||
REQUIRE(doc1.as<std::string>() == "null");
|
||||
REQUIRE(doc1.capacity() == 0);
|
||||
REQUIRE(doc2.capacity() == 4096);
|
||||
}
|
||||
REQUIRE(log.str() == "A4096F");
|
||||
}
|
||||
|
||||
SECTION("Copy assign larger") {
|
||||
{
|
||||
BasicJsonDocument<SpyingAllocator> doc1(4096, log);
|
||||
doc1.set(std::string("The size of this string is 32!!"));
|
||||
BasicJsonDocument<SpyingAllocator> doc2(8, log);
|
||||
|
||||
doc2 = doc1;
|
||||
|
||||
REQUIRE(doc1.as<std::string>() == "The size of this string is 32!!");
|
||||
REQUIRE(doc2.as<std::string>() == "The size of this string is 32!!");
|
||||
REQUIRE(doc2.capacity() == 4096);
|
||||
}
|
||||
REQUIRE(log.str() == "A4096A8FA4096FF");
|
||||
}
|
||||
|
||||
SECTION("Copy assign smaller") {
|
||||
{
|
||||
BasicJsonDocument<SpyingAllocator> doc1(1024, log);
|
||||
doc1.set(std::string("The size of this string is 32!!"));
|
||||
BasicJsonDocument<SpyingAllocator> doc2(4096, log);
|
||||
|
||||
doc2 = doc1;
|
||||
|
||||
REQUIRE(doc1.as<std::string>() == "The size of this string is 32!!");
|
||||
REQUIRE(doc2.as<std::string>() == "The size of this string is 32!!");
|
||||
REQUIRE(doc2.capacity() == 1024);
|
||||
}
|
||||
REQUIRE(log.str() == "A1024A4096FA1024FF");
|
||||
}
|
||||
|
||||
SECTION("Copy assign same size") {
|
||||
{
|
||||
BasicJsonDocument<SpyingAllocator> doc1(1024, log);
|
||||
doc1.set(std::string("The size of this string is 32!!"));
|
||||
BasicJsonDocument<SpyingAllocator> doc2(1024, log);
|
||||
|
||||
doc2 = doc1;
|
||||
|
||||
REQUIRE(doc1.as<std::string>() == "The size of this string is 32!!");
|
||||
REQUIRE(doc2.as<std::string>() == "The size of this string is 32!!");
|
||||
REQUIRE(doc2.capacity() == 1024);
|
||||
}
|
||||
REQUIRE(log.str() == "A1024A1024FF");
|
||||
}
|
||||
|
||||
SECTION("Move assign") {
|
||||
{
|
||||
BasicJsonDocument<SpyingAllocator> doc1(4096, log);
|
||||
doc1.set(std::string("The size of this string is 32!!"));
|
||||
BasicJsonDocument<SpyingAllocator> doc2(8, log);
|
||||
|
||||
doc2 = std::move(doc1);
|
||||
|
||||
REQUIRE(doc2.as<std::string>() == "The size of this string is 32!!");
|
||||
REQUIRE(doc1.as<std::string>() == "null");
|
||||
REQUIRE(doc1.capacity() == 0);
|
||||
REQUIRE(doc2.capacity() == 4096);
|
||||
}
|
||||
REQUIRE(log.str() == "A4096A8FF");
|
||||
}
|
||||
|
||||
SECTION("garbageCollect()") {
|
||||
BasicJsonDocument<ControllableAllocator> doc(4096);
|
||||
|
||||
SECTION("when allocation succeeds") {
|
||||
deserializeJson(doc, "{\"blanket\":1,\"dancing\":2}");
|
||||
REQUIRE(doc.capacity() == 4096);
|
||||
REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16);
|
||||
doc.remove("blanket");
|
||||
|
||||
bool result = doc.garbageCollect();
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 8);
|
||||
REQUIRE(doc.capacity() == 4096);
|
||||
REQUIRE(doc.as<std::string>() == "{\"dancing\":2}");
|
||||
}
|
||||
|
||||
SECTION("when allocation fails") {
|
||||
deserializeJson(doc, "{\"blanket\":1,\"dancing\":2}");
|
||||
REQUIRE(doc.capacity() == 4096);
|
||||
REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16);
|
||||
doc.remove("blanket");
|
||||
doc.allocator().disable();
|
||||
|
||||
bool result = doc.garbageCollect();
|
||||
|
||||
REQUIRE(result == false);
|
||||
REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(2) + 16);
|
||||
REQUIRE(doc.capacity() == 4096);
|
||||
REQUIRE(doc.as<std::string>() == "{\"dancing\":2}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
# ArduinoJson - https://arduinojson.org
|
||||
# Copyright © 2014-2023, Benoit BLANCHON
|
||||
# MIT License
|
||||
|
||||
add_executable(JsonDocumentTests
|
||||
add.cpp
|
||||
BasicJsonDocument.cpp
|
||||
cast.cpp
|
||||
compare.cpp
|
||||
containsKey.cpp
|
||||
createNested.cpp
|
||||
DynamicJsonDocument.cpp
|
||||
ElementProxy.cpp
|
||||
isNull.cpp
|
||||
issue1120.cpp
|
||||
MemberProxy.cpp
|
||||
nesting.cpp
|
||||
overflowed.cpp
|
||||
remove.cpp
|
||||
shrinkToFit.cpp
|
||||
size.cpp
|
||||
StaticJsonDocument.cpp
|
||||
subscript.cpp
|
||||
swap.cpp
|
||||
)
|
||||
|
||||
add_test(JsonDocument JsonDocumentTests)
|
||||
|
||||
set_tests_properties(JsonDocument
|
||||
PROPERTIES
|
||||
LABELS "Catch"
|
||||
)
|
||||
@ -0,0 +1,230 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2023, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
using ArduinoJson::detail::addPadding;
|
||||
|
||||
static void REQUIRE_JSON(JsonDocument& doc, const std::string& expected) {
|
||||
std::string json;
|
||||
serializeJson(doc, json);
|
||||
REQUIRE(json == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("DynamicJsonDocument") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
|
||||
SECTION("serializeJson()") {
|
||||
JsonObject obj = doc.to<JsonObject>();
|
||||
obj["hello"] = "world";
|
||||
|
||||
std::string json;
|
||||
serializeJson(doc, json);
|
||||
|
||||
REQUIRE(json == "{\"hello\":\"world\"}");
|
||||
}
|
||||
|
||||
SECTION("memoryUsage()") {
|
||||
SECTION("starts at zero") {
|
||||
REQUIRE(doc.memoryUsage() == 0);
|
||||
}
|
||||
|
||||
SECTION("JSON_ARRAY_SIZE(0)") {
|
||||
doc.to<JsonArray>();
|
||||
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(0));
|
||||
}
|
||||
|
||||
SECTION("JSON_ARRAY_SIZE(1)") {
|
||||
doc.to<JsonArray>().add(42);
|
||||
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(1));
|
||||
}
|
||||
|
||||
SECTION("JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(0)") {
|
||||
doc.to<JsonArray>().createNestedArray();
|
||||
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(1) + JSON_ARRAY_SIZE(0));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("capacity()") {
|
||||
SECTION("matches constructor argument") {
|
||||
DynamicJsonDocument doc2(256);
|
||||
REQUIRE(doc2.capacity() == 256);
|
||||
}
|
||||
|
||||
SECTION("rounds up constructor argument") {
|
||||
DynamicJsonDocument doc2(253);
|
||||
REQUIRE(doc2.capacity() == 256);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("memoryUsage()") {
|
||||
SECTION("Increases after adding value to array") {
|
||||
JsonArray arr = doc.to<JsonArray>();
|
||||
|
||||
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(0));
|
||||
arr.add(42);
|
||||
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(1));
|
||||
arr.add(43);
|
||||
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2));
|
||||
}
|
||||
|
||||
SECTION("Increases after adding value to object") {
|
||||
JsonObject obj = doc.to<JsonObject>();
|
||||
|
||||
REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0));
|
||||
obj["a"] = 1;
|
||||
REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(1));
|
||||
obj["b"] = 2;
|
||||
REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("DynamicJsonDocument constructor") {
|
||||
SECTION("Copy constructor") {
|
||||
DynamicJsonDocument doc1(1234);
|
||||
deserializeJson(doc1, "{\"hello\":\"world\"}");
|
||||
|
||||
DynamicJsonDocument doc2 = doc1;
|
||||
|
||||
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
|
||||
|
||||
REQUIRE(doc2.capacity() == doc1.capacity());
|
||||
}
|
||||
|
||||
SECTION("Construct from StaticJsonDocument") {
|
||||
StaticJsonDocument<200> doc1;
|
||||
deserializeJson(doc1, "{\"hello\":\"world\"}");
|
||||
|
||||
DynamicJsonDocument doc2 = doc1;
|
||||
|
||||
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
|
||||
REQUIRE(doc2.capacity() == doc1.capacity());
|
||||
}
|
||||
|
||||
SECTION("Construct from JsonObject") {
|
||||
StaticJsonDocument<200> doc1;
|
||||
JsonObject obj = doc1.to<JsonObject>();
|
||||
obj["hello"] = "world";
|
||||
|
||||
DynamicJsonDocument doc2 = obj;
|
||||
|
||||
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
|
||||
REQUIRE(doc2.capacity() == addPadding(doc1.memoryUsage()));
|
||||
}
|
||||
|
||||
SECTION("Construct from JsonArray") {
|
||||
StaticJsonDocument<200> doc1;
|
||||
JsonArray arr = doc1.to<JsonArray>();
|
||||
arr.add("hello");
|
||||
|
||||
DynamicJsonDocument doc2 = arr;
|
||||
|
||||
REQUIRE_JSON(doc2, "[\"hello\"]");
|
||||
REQUIRE(doc2.capacity() == addPadding(doc1.memoryUsage()));
|
||||
}
|
||||
|
||||
SECTION("Construct from JsonVariant") {
|
||||
StaticJsonDocument<200> doc1;
|
||||
deserializeJson(doc1, "42");
|
||||
|
||||
DynamicJsonDocument doc2 = doc1.as<JsonVariant>();
|
||||
|
||||
REQUIRE_JSON(doc2, "42");
|
||||
REQUIRE(doc2.capacity() == addPadding(doc1.memoryUsage()));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("DynamicJsonDocument assignment") {
|
||||
SECTION("Copy assignment reallocates when capacity is smaller") {
|
||||
DynamicJsonDocument doc1(1234);
|
||||
deserializeJson(doc1, "{\"hello\":\"world\"}");
|
||||
DynamicJsonDocument doc2(8);
|
||||
|
||||
doc2 = doc1;
|
||||
|
||||
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
|
||||
REQUIRE(doc2.capacity() == doc1.capacity());
|
||||
}
|
||||
|
||||
SECTION("Copy assignment reallocates when capacity is larger") {
|
||||
DynamicJsonDocument doc1(100);
|
||||
deserializeJson(doc1, "{\"hello\":\"world\"}");
|
||||
DynamicJsonDocument doc2(1234);
|
||||
|
||||
doc2 = doc1;
|
||||
|
||||
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
|
||||
REQUIRE(doc2.capacity() == doc1.capacity());
|
||||
}
|
||||
|
||||
SECTION("Assign from StaticJsonDocument") {
|
||||
StaticJsonDocument<200> doc1;
|
||||
deserializeJson(doc1, "{\"hello\":\"world\"}");
|
||||
DynamicJsonDocument doc2(4096);
|
||||
doc2.to<JsonVariant>().set(666);
|
||||
|
||||
doc2 = doc1;
|
||||
|
||||
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
|
||||
}
|
||||
|
||||
SECTION("Assign from JsonObject") {
|
||||
StaticJsonDocument<200> doc1;
|
||||
JsonObject obj = doc1.to<JsonObject>();
|
||||
obj["hello"] = "world";
|
||||
|
||||
DynamicJsonDocument doc2(4096);
|
||||
doc2 = obj;
|
||||
|
||||
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
|
||||
REQUIRE(doc2.capacity() == 4096);
|
||||
}
|
||||
|
||||
SECTION("Assign from JsonArray") {
|
||||
StaticJsonDocument<200> doc1;
|
||||
JsonArray arr = doc1.to<JsonArray>();
|
||||
arr.add("hello");
|
||||
|
||||
DynamicJsonDocument doc2(4096);
|
||||
doc2 = arr;
|
||||
|
||||
REQUIRE_JSON(doc2, "[\"hello\"]");
|
||||
REQUIRE(doc2.capacity() == 4096);
|
||||
}
|
||||
|
||||
SECTION("Assign from JsonVariant") {
|
||||
StaticJsonDocument<200> doc1;
|
||||
deserializeJson(doc1, "42");
|
||||
|
||||
DynamicJsonDocument doc2(4096);
|
||||
doc2 = doc1.as<JsonVariant>();
|
||||
|
||||
REQUIRE_JSON(doc2, "42");
|
||||
REQUIRE(doc2.capacity() == 4096);
|
||||
}
|
||||
|
||||
SECTION("Assign from MemberProxy") {
|
||||
StaticJsonDocument<200> doc1;
|
||||
doc1["value"] = 42;
|
||||
|
||||
DynamicJsonDocument doc2(4096);
|
||||
doc2 = doc1["value"];
|
||||
|
||||
REQUIRE_JSON(doc2, "42");
|
||||
REQUIRE(doc2.capacity() == 4096);
|
||||
}
|
||||
|
||||
SECTION("Assign from ElementProxy") {
|
||||
StaticJsonDocument<200> doc1;
|
||||
doc1[0] = 42;
|
||||
|
||||
DynamicJsonDocument doc2(4096);
|
||||
doc2 = doc1[0];
|
||||
|
||||
REQUIRE_JSON(doc2, "42");
|
||||
REQUIRE(doc2.capacity() == 4096);
|
||||
}
|
||||
}
|
||||
255
libraries/ArduinoJson/extras/tests/JsonDocument/ElementProxy.cpp
Normal file
255
libraries/ArduinoJson/extras/tests/JsonDocument/ElementProxy.cpp
Normal file
@ -0,0 +1,255 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2023, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
typedef ArduinoJson::detail::ElementProxy<JsonDocument&> ElementProxy;
|
||||
|
||||
TEST_CASE("ElementProxy::add()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc.add();
|
||||
ElementProxy ep = doc[0];
|
||||
|
||||
SECTION("add(int)") {
|
||||
ep.add(42);
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "[[42]]");
|
||||
}
|
||||
|
||||
SECTION("add(const char*)") {
|
||||
ep.add("world");
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "[[\"world\"]]");
|
||||
}
|
||||
|
||||
SECTION("set(char[])") {
|
||||
char s[] = "world";
|
||||
ep.add(s);
|
||||
strcpy(s, "!!!!!");
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "[[\"world\"]]");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ElementProxy::clear()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc.add();
|
||||
ElementProxy ep = doc[0];
|
||||
|
||||
SECTION("size goes back to zero") {
|
||||
ep.add(42);
|
||||
ep.clear();
|
||||
|
||||
REQUIRE(ep.size() == 0);
|
||||
}
|
||||
|
||||
SECTION("isNull() return true") {
|
||||
ep.add("hello");
|
||||
ep.clear();
|
||||
|
||||
REQUIRE(ep.isNull() == true);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ElementProxy::operator==()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
|
||||
SECTION("1 vs 1") {
|
||||
doc.add(1);
|
||||
doc.add(1);
|
||||
|
||||
REQUIRE(doc[0] <= doc[1]);
|
||||
REQUIRE(doc[0] == doc[1]);
|
||||
REQUIRE(doc[0] >= doc[1]);
|
||||
REQUIRE_FALSE(doc[0] != doc[1]);
|
||||
REQUIRE_FALSE(doc[0] < doc[1]);
|
||||
REQUIRE_FALSE(doc[0] > doc[1]);
|
||||
}
|
||||
|
||||
SECTION("1 vs 2") {
|
||||
doc.add(1);
|
||||
doc.add(2);
|
||||
|
||||
REQUIRE(doc[0] != doc[1]);
|
||||
REQUIRE(doc[0] < doc[1]);
|
||||
REQUIRE(doc[0] <= doc[1]);
|
||||
REQUIRE_FALSE(doc[0] == doc[1]);
|
||||
REQUIRE_FALSE(doc[0] > doc[1]);
|
||||
REQUIRE_FALSE(doc[0] >= doc[1]);
|
||||
}
|
||||
|
||||
SECTION("'abc' vs 'bcd'") {
|
||||
doc.add("abc");
|
||||
doc.add("bcd");
|
||||
|
||||
REQUIRE(doc[0] != doc[1]);
|
||||
REQUIRE(doc[0] < doc[1]);
|
||||
REQUIRE(doc[0] <= doc[1]);
|
||||
REQUIRE_FALSE(doc[0] == doc[1]);
|
||||
REQUIRE_FALSE(doc[0] > doc[1]);
|
||||
REQUIRE_FALSE(doc[0] >= doc[1]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ElementProxy::remove()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc.add();
|
||||
ElementProxy ep = doc[0];
|
||||
|
||||
SECTION("remove(int)") {
|
||||
ep.add(1);
|
||||
ep.add(2);
|
||||
ep.add(3);
|
||||
|
||||
ep.remove(1);
|
||||
|
||||
REQUIRE(ep.as<std::string>() == "[1,3]");
|
||||
}
|
||||
|
||||
SECTION("remove(const char *)") {
|
||||
ep["a"] = 1;
|
||||
ep["b"] = 2;
|
||||
|
||||
ep.remove("a");
|
||||
|
||||
REQUIRE(ep.as<std::string>() == "{\"b\":2}");
|
||||
}
|
||||
|
||||
SECTION("remove(std::string)") {
|
||||
ep["a"] = 1;
|
||||
ep["b"] = 2;
|
||||
|
||||
ep.remove(std::string("b"));
|
||||
|
||||
REQUIRE(ep.as<std::string>() == "{\"a\":1}");
|
||||
}
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("remove(vla)") {
|
||||
ep["a"] = 1;
|
||||
ep["b"] = 2;
|
||||
|
||||
size_t i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "b");
|
||||
ep.remove(vla);
|
||||
|
||||
REQUIRE(ep.as<std::string>() == "{\"a\":1}");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("ElementProxy::set()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
ElementProxy ep = doc[0];
|
||||
|
||||
SECTION("set(int)") {
|
||||
ep.set(42);
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "[42]");
|
||||
}
|
||||
|
||||
SECTION("set(const char*)") {
|
||||
ep.set("world");
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "[\"world\"]");
|
||||
}
|
||||
|
||||
SECTION("set(char[])") {
|
||||
char s[] = "world";
|
||||
ep.set(s);
|
||||
strcpy(s, "!!!!!");
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "[\"world\"]");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ElementProxy::size()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc.add();
|
||||
ElementProxy ep = doc[0];
|
||||
|
||||
SECTION("returns 0") {
|
||||
REQUIRE(ep.size() == 0);
|
||||
}
|
||||
|
||||
SECTION("as an array, returns 2") {
|
||||
ep.add(1);
|
||||
ep.add(2);
|
||||
REQUIRE(ep.size() == 2);
|
||||
}
|
||||
|
||||
SECTION("as an object, returns 2") {
|
||||
ep["a"] = 1;
|
||||
ep["b"] = 2;
|
||||
REQUIRE(ep.size() == 2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ElementProxy::memoryUsage()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc.add();
|
||||
ElementProxy ep = doc[0];
|
||||
|
||||
SECTION("returns 0 for null") {
|
||||
REQUIRE(ep.memoryUsage() == 0);
|
||||
}
|
||||
|
||||
SECTION("returns size for string") {
|
||||
ep.set(std::string("hello"));
|
||||
REQUIRE(ep.memoryUsage() == 6);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ElementProxy::operator[]") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
ElementProxy ep = doc[1];
|
||||
|
||||
SECTION("set member") {
|
||||
ep["world"] = 42;
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "[null,{\"world\":42}]");
|
||||
}
|
||||
|
||||
SECTION("set element") {
|
||||
ep[2] = 42;
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "[null,[null,null,42]]");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ElementProxy cast to JsonVariantConst") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc[0] = "world";
|
||||
|
||||
const ElementProxy ep = doc[0];
|
||||
|
||||
JsonVariantConst var = ep;
|
||||
|
||||
CHECK(var.as<std::string>() == "world");
|
||||
}
|
||||
|
||||
TEST_CASE("ElementProxy cast to JsonVariant") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc[0] = "world";
|
||||
|
||||
ElementProxy ep = doc[0];
|
||||
|
||||
JsonVariant var = ep;
|
||||
|
||||
CHECK(var.as<std::string>() == "world");
|
||||
|
||||
var.set("toto");
|
||||
|
||||
CHECK(doc.as<std::string>() == "[\"toto\"]");
|
||||
}
|
||||
|
||||
TEST_CASE("ElementProxy::shallowCopy()") {
|
||||
StaticJsonDocument<1024> doc1, doc2;
|
||||
doc2["hello"] = "world";
|
||||
doc1[0].shallowCopy(doc2);
|
||||
|
||||
CHECK(doc1.as<std::string>() == "[{\"hello\":\"world\"}]");
|
||||
}
|
||||
328
libraries/ArduinoJson/extras/tests/JsonDocument/MemberProxy.cpp
Normal file
328
libraries/ArduinoJson/extras/tests/JsonDocument/MemberProxy.cpp
Normal file
@ -0,0 +1,328 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2023, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
typedef ArduinoJson::detail::MemberProxy<JsonDocument&, const char*>
|
||||
MemberProxy;
|
||||
|
||||
TEST_CASE("MemberProxy::add()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
MemberProxy mp = doc["hello"];
|
||||
|
||||
SECTION("add(int)") {
|
||||
mp.add(42);
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "{\"hello\":[42]}");
|
||||
}
|
||||
|
||||
SECTION("add(const char*)") {
|
||||
mp.add("world");
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "{\"hello\":[\"world\"]}");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::clear()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
MemberProxy mp = doc["hello"];
|
||||
|
||||
SECTION("size goes back to zero") {
|
||||
mp.add(42);
|
||||
mp.clear();
|
||||
|
||||
REQUIRE(mp.size() == 0);
|
||||
}
|
||||
|
||||
SECTION("isNull() return true") {
|
||||
mp.add("hello");
|
||||
mp.clear();
|
||||
|
||||
REQUIRE(mp.isNull() == true);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::operator==()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
|
||||
SECTION("1 vs 1") {
|
||||
doc["a"] = 1;
|
||||
doc["b"] = 1;
|
||||
|
||||
REQUIRE(doc["a"] <= doc["b"]);
|
||||
REQUIRE(doc["a"] == doc["b"]);
|
||||
REQUIRE(doc["a"] >= doc["b"]);
|
||||
REQUIRE_FALSE(doc["a"] != doc["b"]);
|
||||
REQUIRE_FALSE(doc["a"] < doc["b"]);
|
||||
REQUIRE_FALSE(doc["a"] > doc["b"]);
|
||||
}
|
||||
|
||||
SECTION("1 vs 2") {
|
||||
doc["a"] = 1;
|
||||
doc["b"] = 2;
|
||||
|
||||
REQUIRE(doc["a"] != doc["b"]);
|
||||
REQUIRE(doc["a"] < doc["b"]);
|
||||
REQUIRE(doc["a"] <= doc["b"]);
|
||||
REQUIRE_FALSE(doc["a"] == doc["b"]);
|
||||
REQUIRE_FALSE(doc["a"] > doc["b"]);
|
||||
REQUIRE_FALSE(doc["a"] >= doc["b"]);
|
||||
}
|
||||
|
||||
SECTION("'abc' vs 'bcd'") {
|
||||
doc["a"] = "abc";
|
||||
doc["b"] = "bcd";
|
||||
|
||||
REQUIRE(doc["a"] != doc["b"]);
|
||||
REQUIRE(doc["a"] < doc["b"]);
|
||||
REQUIRE(doc["a"] <= doc["b"]);
|
||||
REQUIRE_FALSE(doc["a"] == doc["b"]);
|
||||
REQUIRE_FALSE(doc["a"] > doc["b"]);
|
||||
REQUIRE_FALSE(doc["a"] >= doc["b"]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::containsKey()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
MemberProxy mp = doc["hello"];
|
||||
|
||||
SECTION("containsKey(const char*)") {
|
||||
mp["key"] = "value";
|
||||
|
||||
REQUIRE(mp.containsKey("key") == true);
|
||||
REQUIRE(mp.containsKey("key") == true);
|
||||
}
|
||||
|
||||
SECTION("containsKey(std::string)") {
|
||||
mp["key"] = "value";
|
||||
|
||||
REQUIRE(mp.containsKey(std::string("key")) == true);
|
||||
REQUIRE(mp.containsKey(std::string("key")) == true);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::operator|()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
|
||||
SECTION("const char*") {
|
||||
doc["a"] = "hello";
|
||||
|
||||
REQUIRE((doc["a"] | "world") == std::string("hello"));
|
||||
REQUIRE((doc["b"] | "world") == std::string("world"));
|
||||
}
|
||||
|
||||
SECTION("Issue #1411") {
|
||||
doc["sensor"] = "gps";
|
||||
|
||||
const char* test = "test"; // <- the literal must be captured in a variable
|
||||
// to trigger the bug
|
||||
const char* sensor = doc["sensor"] | test; // "gps"
|
||||
|
||||
REQUIRE(sensor == std::string("gps"));
|
||||
}
|
||||
|
||||
SECTION("Issue #1415") {
|
||||
JsonObject object = doc.to<JsonObject>();
|
||||
object["hello"] = "world";
|
||||
|
||||
StaticJsonDocument<0> emptyDoc;
|
||||
JsonObject anotherObject = object["hello"] | emptyDoc.to<JsonObject>();
|
||||
|
||||
REQUIRE(anotherObject.isNull() == false);
|
||||
REQUIRE(anotherObject.size() == 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::remove()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
MemberProxy mp = doc["hello"];
|
||||
|
||||
SECTION("remove(int)") {
|
||||
mp.add(1);
|
||||
mp.add(2);
|
||||
mp.add(3);
|
||||
|
||||
mp.remove(1);
|
||||
|
||||
REQUIRE(mp.as<std::string>() == "[1,3]");
|
||||
}
|
||||
|
||||
SECTION("remove(const char *)") {
|
||||
mp["a"] = 1;
|
||||
mp["b"] = 2;
|
||||
|
||||
mp.remove("a");
|
||||
|
||||
REQUIRE(mp.as<std::string>() == "{\"b\":2}");
|
||||
}
|
||||
|
||||
SECTION("remove(std::string)") {
|
||||
mp["a"] = 1;
|
||||
mp["b"] = 2;
|
||||
|
||||
mp.remove(std::string("b"));
|
||||
|
||||
REQUIRE(mp.as<std::string>() == "{\"a\":1}");
|
||||
}
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("remove(vla)") {
|
||||
mp["a"] = 1;
|
||||
mp["b"] = 2;
|
||||
|
||||
size_t i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "b");
|
||||
mp.remove(vla);
|
||||
|
||||
REQUIRE(mp.as<std::string>() == "{\"a\":1}");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::set()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
MemberProxy mp = doc["hello"];
|
||||
|
||||
SECTION("set(int)") {
|
||||
mp.set(42);
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "{\"hello\":42}");
|
||||
}
|
||||
|
||||
SECTION("set(const char*)") {
|
||||
mp.set("world");
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "{\"hello\":\"world\"}");
|
||||
}
|
||||
|
||||
SECTION("set(char[])") { // issue #1191
|
||||
char s[] = "world";
|
||||
mp.set(s);
|
||||
strcpy(s, "!!!!!");
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "{\"hello\":\"world\"}");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::size()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
MemberProxy mp = doc["hello"];
|
||||
|
||||
SECTION("returns 0") {
|
||||
REQUIRE(mp.size() == 0);
|
||||
}
|
||||
|
||||
SECTION("as an array, return 2") {
|
||||
mp.add(1);
|
||||
mp.add(2);
|
||||
|
||||
REQUIRE(mp.size() == 2);
|
||||
}
|
||||
|
||||
SECTION("as an object, return 2") {
|
||||
mp["a"] = 1;
|
||||
mp["b"] = 2;
|
||||
|
||||
REQUIRE(mp.size() == 2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::memoryUsage()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
MemberProxy mp = doc["hello"];
|
||||
|
||||
SECTION("returns 0 when null") {
|
||||
REQUIRE(mp.memoryUsage() == 0);
|
||||
}
|
||||
|
||||
SECTION("return the size for a string") {
|
||||
mp.set(std::string("hello"));
|
||||
REQUIRE(mp.memoryUsage() == 6);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::operator[]") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
MemberProxy mp = doc["hello"];
|
||||
|
||||
SECTION("set member") {
|
||||
mp["world"] = 42;
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "{\"hello\":{\"world\":42}}");
|
||||
}
|
||||
|
||||
SECTION("set element") {
|
||||
mp[2] = 42;
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "{\"hello\":[null,null,42]}");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy cast to JsonVariantConst") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc["hello"] = "world";
|
||||
|
||||
const MemberProxy mp = doc["hello"];
|
||||
|
||||
JsonVariantConst var = mp;
|
||||
|
||||
CHECK(var.as<std::string>() == "world");
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy cast to JsonVariant") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc["hello"] = "world";
|
||||
|
||||
MemberProxy mp = doc["hello"];
|
||||
|
||||
JsonVariant var = mp;
|
||||
|
||||
CHECK(var.as<std::string>() == "world");
|
||||
|
||||
var.set("toto");
|
||||
|
||||
CHECK(doc.as<std::string>() == "{\"hello\":\"toto\"}");
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::createNestedArray()") {
|
||||
StaticJsonDocument<1024> doc;
|
||||
JsonArray arr = doc["items"].createNestedArray();
|
||||
arr.add(42);
|
||||
|
||||
CHECK(doc["items"][0][0] == 42);
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::createNestedArray(key)") {
|
||||
StaticJsonDocument<1024> doc;
|
||||
JsonArray arr = doc["weather"].createNestedArray("temp");
|
||||
arr.add(42);
|
||||
|
||||
CHECK(doc["weather"]["temp"][0] == 42);
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::createNestedObject()") {
|
||||
StaticJsonDocument<1024> doc;
|
||||
JsonObject obj = doc["items"].createNestedObject();
|
||||
obj["value"] = 42;
|
||||
|
||||
CHECK(doc["items"][0]["value"] == 42);
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::createNestedObject(key)") {
|
||||
StaticJsonDocument<1024> doc;
|
||||
JsonObject obj = doc["status"].createNestedObject("weather");
|
||||
obj["temp"] = 42;
|
||||
|
||||
CHECK(doc["status"]["weather"]["temp"] == 42);
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::shallowCopy()") {
|
||||
StaticJsonDocument<1024> doc1, doc2;
|
||||
doc2["hello"] = "world";
|
||||
doc1["obj"].shallowCopy(doc2);
|
||||
|
||||
CHECK(doc1.as<std::string>() == "{\"obj\":{\"hello\":\"world\"}}");
|
||||
}
|
||||
@ -0,0 +1,224 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2023, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
static void REQUIRE_JSON(JsonDocument& doc, const std::string& expected) {
|
||||
std::string json;
|
||||
serializeJson(doc, json);
|
||||
REQUIRE(json == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("StaticJsonDocument") {
|
||||
SECTION("capacity()") {
|
||||
SECTION("matches template argument") {
|
||||
StaticJsonDocument<256> doc;
|
||||
REQUIRE(doc.capacity() == 256);
|
||||
}
|
||||
|
||||
SECTION("rounds up template argument") {
|
||||
StaticJsonDocument<253> doc;
|
||||
REQUIRE(doc.capacity() == 256);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("serializeJson()") {
|
||||
StaticJsonDocument<200> doc;
|
||||
JsonObject obj = doc.to<JsonObject>();
|
||||
obj["hello"] = "world";
|
||||
|
||||
std::string json;
|
||||
serializeJson(doc, json);
|
||||
|
||||
REQUIRE(json == "{\"hello\":\"world\"}");
|
||||
}
|
||||
|
||||
SECTION("Copy assignment") {
|
||||
StaticJsonDocument<200> doc1, doc2;
|
||||
doc1.to<JsonVariant>().set(666);
|
||||
deserializeJson(doc2, "{\"hello\":\"world\"}");
|
||||
|
||||
doc1 = doc2;
|
||||
|
||||
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
|
||||
}
|
||||
|
||||
SECTION("Contructor") {
|
||||
SECTION("Copy constructor") {
|
||||
StaticJsonDocument<200> doc1;
|
||||
deserializeJson(doc1, "{\"hello\":\"world\"}");
|
||||
|
||||
StaticJsonDocument<200> doc2 = doc1;
|
||||
|
||||
deserializeJson(doc1, "{\"HELLO\":\"WORLD\"}");
|
||||
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
|
||||
}
|
||||
|
||||
SECTION("Construct from StaticJsonDocument of different size") {
|
||||
StaticJsonDocument<300> doc1;
|
||||
deserializeJson(doc1, "{\"hello\":\"world\"}");
|
||||
|
||||
StaticJsonDocument<200> doc2 = doc1;
|
||||
|
||||
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
|
||||
}
|
||||
|
||||
SECTION("Construct from DynamicJsonDocument") {
|
||||
DynamicJsonDocument doc1(4096);
|
||||
deserializeJson(doc1, "{\"hello\":\"world\"}");
|
||||
|
||||
StaticJsonDocument<200> doc2 = doc1;
|
||||
|
||||
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
|
||||
}
|
||||
|
||||
SECTION("Construct from JsonObject") {
|
||||
DynamicJsonDocument doc1(4096);
|
||||
deserializeJson(doc1, "{\"hello\":\"world\"}");
|
||||
|
||||
StaticJsonDocument<200> doc2 = doc1.as<JsonObject>();
|
||||
|
||||
deserializeJson(doc1, "{\"HELLO\":\"WORLD\"}");
|
||||
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
|
||||
}
|
||||
|
||||
SECTION("Construct from JsonArray") {
|
||||
DynamicJsonDocument doc1(4096);
|
||||
deserializeJson(doc1, "[\"hello\",\"world\"]");
|
||||
|
||||
StaticJsonDocument<200> doc2 = doc1.as<JsonArray>();
|
||||
|
||||
deserializeJson(doc1, "[\"HELLO\",\"WORLD\"]");
|
||||
REQUIRE_JSON(doc2, "[\"hello\",\"world\"]");
|
||||
}
|
||||
|
||||
SECTION("Construct from JsonVariant") {
|
||||
DynamicJsonDocument doc1(4096);
|
||||
deserializeJson(doc1, "42");
|
||||
|
||||
StaticJsonDocument<200> doc2 = doc1.as<JsonVariant>();
|
||||
|
||||
REQUIRE_JSON(doc2, "42");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Assignment") {
|
||||
SECTION("Copy assignment") {
|
||||
StaticJsonDocument<200> doc1, doc2;
|
||||
doc1.to<JsonVariant>().set(666);
|
||||
deserializeJson(doc1, "{\"hello\":\"world\"}");
|
||||
|
||||
doc2 = doc1;
|
||||
|
||||
deserializeJson(doc1, "{\"HELLO\":\"WORLD\"}");
|
||||
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
|
||||
}
|
||||
|
||||
SECTION("Assign from StaticJsonDocument of different capacity") {
|
||||
StaticJsonDocument<200> doc1;
|
||||
StaticJsonDocument<300> doc2;
|
||||
doc1.to<JsonVariant>().set(666);
|
||||
deserializeJson(doc1, "{\"hello\":\"world\"}");
|
||||
|
||||
doc2 = doc1;
|
||||
|
||||
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
|
||||
}
|
||||
|
||||
SECTION("Assign from DynamicJsonDocument") {
|
||||
StaticJsonDocument<200> doc1;
|
||||
DynamicJsonDocument doc2(4096);
|
||||
doc1.to<JsonVariant>().set(666);
|
||||
deserializeJson(doc1, "{\"hello\":\"world\"}");
|
||||
|
||||
doc2 = doc1;
|
||||
|
||||
deserializeJson(doc1, "{\"HELLO\":\"WORLD\"}");
|
||||
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
|
||||
}
|
||||
|
||||
SECTION("Assign from JsonArray") {
|
||||
StaticJsonDocument<200> doc1;
|
||||
DynamicJsonDocument doc2(4096);
|
||||
doc1.to<JsonVariant>().set(666);
|
||||
deserializeJson(doc1, "[\"hello\",\"world\"]");
|
||||
|
||||
doc2 = doc1.as<JsonArray>();
|
||||
|
||||
deserializeJson(doc1, "[\"HELLO\",\"WORLD\"]");
|
||||
REQUIRE_JSON(doc2, "[\"hello\",\"world\"]");
|
||||
}
|
||||
|
||||
SECTION("Assign from JsonArrayConst") {
|
||||
StaticJsonDocument<200> doc1;
|
||||
DynamicJsonDocument doc2(4096);
|
||||
doc1.to<JsonVariant>().set(666);
|
||||
deserializeJson(doc1, "[\"hello\",\"world\"]");
|
||||
|
||||
doc2 = doc1.as<JsonArrayConst>();
|
||||
|
||||
deserializeJson(doc1, "[\"HELLO\",\"WORLD\"]");
|
||||
REQUIRE_JSON(doc2, "[\"hello\",\"world\"]");
|
||||
}
|
||||
|
||||
SECTION("Assign from JsonObject") {
|
||||
StaticJsonDocument<200> doc1;
|
||||
DynamicJsonDocument doc2(4096);
|
||||
doc1.to<JsonVariant>().set(666);
|
||||
deserializeJson(doc1, "{\"hello\":\"world\"}");
|
||||
|
||||
doc2 = doc1.as<JsonObject>();
|
||||
|
||||
deserializeJson(doc1, "{\"HELLO\":\"WORLD\"}");
|
||||
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
|
||||
}
|
||||
|
||||
SECTION("Assign from JsonObjectConst") {
|
||||
StaticJsonDocument<200> doc1;
|
||||
DynamicJsonDocument doc2(4096);
|
||||
doc1.to<JsonVariant>().set(666);
|
||||
deserializeJson(doc1, "{\"hello\":\"world\"}");
|
||||
|
||||
doc2 = doc1.as<JsonObjectConst>();
|
||||
|
||||
deserializeJson(doc1, "{\"HELLO\":\"WORLD\"}");
|
||||
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
|
||||
}
|
||||
|
||||
SECTION("Assign from JsonVariant") {
|
||||
DynamicJsonDocument doc1(4096);
|
||||
doc1.to<JsonVariant>().set(666);
|
||||
deserializeJson(doc1, "42");
|
||||
|
||||
StaticJsonDocument<200> doc2;
|
||||
doc2 = doc1.as<JsonVariant>();
|
||||
|
||||
REQUIRE_JSON(doc2, "42");
|
||||
}
|
||||
|
||||
SECTION("Assign from JsonVariantConst") {
|
||||
DynamicJsonDocument doc1(4096);
|
||||
doc1.to<JsonVariant>().set(666);
|
||||
deserializeJson(doc1, "42");
|
||||
|
||||
StaticJsonDocument<200> doc2;
|
||||
doc2 = doc1.as<JsonVariantConst>();
|
||||
|
||||
REQUIRE_JSON(doc2, "42");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("garbageCollect()") {
|
||||
StaticJsonDocument<256> doc;
|
||||
doc[std::string("example")] = std::string("jukebox");
|
||||
doc.remove("example");
|
||||
REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 16);
|
||||
|
||||
doc.garbageCollect();
|
||||
|
||||
REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0));
|
||||
REQUIRE_JSON(doc, "{}");
|
||||
}
|
||||
}
|
||||
22
libraries/ArduinoJson/extras/tests/JsonDocument/add.cpp
Normal file
22
libraries/ArduinoJson/extras/tests/JsonDocument/add.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2023, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("JsonDocument::add()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
|
||||
SECTION("integer") {
|
||||
doc.add(42);
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "[42]");
|
||||
}
|
||||
|
||||
SECTION("const char*") {
|
||||
doc.add("hello");
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "[\"hello\"]");
|
||||
}
|
||||
}
|
||||
18
libraries/ArduinoJson/extras/tests/JsonDocument/cast.cpp
Normal file
18
libraries/ArduinoJson/extras/tests/JsonDocument/cast.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2023, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
TEST_CASE("Implicit cast to JsonVariant") {
|
||||
StaticJsonDocument<128> doc;
|
||||
|
||||
doc["hello"] = "world";
|
||||
|
||||
JsonVariant var = doc;
|
||||
|
||||
CHECK(var.as<std::string>() == "{\"hello\":\"world\"}");
|
||||
}
|
||||
103
libraries/ArduinoJson/extras/tests/JsonDocument/compare.cpp
Normal file
103
libraries/ArduinoJson/extras/tests/JsonDocument/compare.cpp
Normal file
@ -0,0 +1,103 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2023, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("DynamicJsonDocument::operator==(const DynamicJsonDocument&)") {
|
||||
DynamicJsonDocument doc1(4096);
|
||||
DynamicJsonDocument doc2(4096);
|
||||
|
||||
SECTION("Empty") {
|
||||
REQUIRE(doc1 == doc2);
|
||||
REQUIRE_FALSE(doc1 != doc2);
|
||||
}
|
||||
|
||||
SECTION("With same object") {
|
||||
doc1["hello"] = "world";
|
||||
doc2["hello"] = "world";
|
||||
REQUIRE(doc1 == doc2);
|
||||
REQUIRE_FALSE(doc1 != doc2);
|
||||
}
|
||||
SECTION("With different object") {
|
||||
doc1["hello"] = "world";
|
||||
doc2["world"] = "hello";
|
||||
REQUIRE_FALSE(doc1 == doc2);
|
||||
REQUIRE(doc1 != doc2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("DynamicJsonDocument::operator==(const StaticJsonDocument&)") {
|
||||
DynamicJsonDocument doc1(4096);
|
||||
StaticJsonDocument<256> doc2;
|
||||
|
||||
SECTION("Empty") {
|
||||
REQUIRE(doc1 == doc2);
|
||||
REQUIRE_FALSE(doc1 != doc2);
|
||||
}
|
||||
|
||||
SECTION("With same object") {
|
||||
doc1["hello"] = "world";
|
||||
doc2["hello"] = "world";
|
||||
REQUIRE(doc1 == doc2);
|
||||
REQUIRE_FALSE(doc1 != doc2);
|
||||
}
|
||||
|
||||
SECTION("With different object") {
|
||||
doc1["hello"] = "world";
|
||||
doc2["world"] = "hello";
|
||||
REQUIRE_FALSE(doc1 == doc2);
|
||||
REQUIRE(doc1 != doc2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("StaticJsonDocument::operator==(const DynamicJsonDocument&)") {
|
||||
StaticJsonDocument<256> doc1;
|
||||
DynamicJsonDocument doc2(4096);
|
||||
|
||||
SECTION("Empty") {
|
||||
REQUIRE(doc1 == doc2);
|
||||
REQUIRE_FALSE(doc1 != doc2);
|
||||
}
|
||||
|
||||
SECTION("With same object") {
|
||||
doc1["hello"] = "world";
|
||||
doc2["hello"] = "world";
|
||||
REQUIRE(doc1 == doc2);
|
||||
REQUIRE_FALSE(doc1 != doc2);
|
||||
}
|
||||
|
||||
SECTION("With different object") {
|
||||
doc1["hello"] = "world";
|
||||
doc2["world"] = "hello";
|
||||
REQUIRE_FALSE(doc1 == doc2);
|
||||
REQUIRE(doc1 != doc2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JsonDocument::operator==(const JsonDocument&)") {
|
||||
StaticJsonDocument<256> doc1;
|
||||
StaticJsonDocument<256> doc2;
|
||||
const JsonDocument& ref1 = doc1;
|
||||
const JsonDocument& ref2 = doc2;
|
||||
|
||||
SECTION("Empty") {
|
||||
REQUIRE(ref1 == ref2);
|
||||
REQUIRE_FALSE(ref1 != ref2);
|
||||
}
|
||||
|
||||
SECTION("With same object") {
|
||||
doc1["hello"] = "world";
|
||||
doc2["hello"] = "world";
|
||||
REQUIRE(ref1 == ref2);
|
||||
REQUIRE_FALSE(ref1 != ref2);
|
||||
}
|
||||
|
||||
SECTION("With different object") {
|
||||
doc1["hello"] = "world";
|
||||
doc2["world"] = "hello";
|
||||
REQUIRE_FALSE(ref1 == ref2);
|
||||
REQUIRE(ref1 != ref2);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2023, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("JsonDocument::containsKey()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
|
||||
SECTION("returns true on object") {
|
||||
doc["hello"] = "world";
|
||||
|
||||
REQUIRE(doc.containsKey("hello") == true);
|
||||
}
|
||||
|
||||
SECTION("returns true when value is null") {
|
||||
doc["hello"] = static_cast<const char*>(0);
|
||||
|
||||
REQUIRE(doc.containsKey("hello") == true);
|
||||
}
|
||||
|
||||
SECTION("returns true when key is a std::string") {
|
||||
doc["hello"] = "world";
|
||||
|
||||
REQUIRE(doc.containsKey(std::string("hello")) == true);
|
||||
}
|
||||
|
||||
SECTION("returns false on object") {
|
||||
doc["world"] = "hello";
|
||||
|
||||
REQUIRE(doc.containsKey("hello") == false);
|
||||
}
|
||||
|
||||
SECTION("returns false on array") {
|
||||
doc.add("hello");
|
||||
|
||||
REQUIRE(doc.containsKey("hello") == false);
|
||||
}
|
||||
|
||||
SECTION("returns false on null") {
|
||||
REQUIRE(doc.containsKey("hello") == false);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,66 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2023, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("JsonDocument::createNestedArray()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
|
||||
SECTION("promotes to array") {
|
||||
doc.createNestedArray();
|
||||
|
||||
REQUIRE(doc.is<JsonArray>());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JsonDocument::createNestedArray(key)") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
|
||||
SECTION("key is const char*") {
|
||||
SECTION("promotes to object") {
|
||||
doc.createNestedArray("hello");
|
||||
|
||||
REQUIRE(doc.is<JsonObject>());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("key is std::string") {
|
||||
SECTION("promotes to object") {
|
||||
doc.createNestedArray(std::string("hello"));
|
||||
|
||||
REQUIRE(doc.is<JsonObject>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JsonDocument::createNestedObject()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
|
||||
SECTION("promotes to array") {
|
||||
doc.createNestedObject();
|
||||
|
||||
REQUIRE(doc.is<JsonArray>());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JsonDocument::createNestedObject(key)") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
|
||||
SECTION("key is const char*") {
|
||||
SECTION("promotes to object") {
|
||||
doc.createNestedObject("hello");
|
||||
|
||||
REQUIRE(doc.is<JsonObject>());
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("key is std::string") {
|
||||
SECTION("promotes to object") {
|
||||
doc.createNestedObject(std::string("hello"));
|
||||
|
||||
REQUIRE(doc.is<JsonObject>());
|
||||
}
|
||||
}
|
||||
}
|
||||
39
libraries/ArduinoJson/extras/tests/JsonDocument/isNull.cpp
Normal file
39
libraries/ArduinoJson/extras/tests/JsonDocument/isNull.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2023, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("JsonDocument::isNull()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
|
||||
SECTION("returns true if uninitialized") {
|
||||
REQUIRE(doc.isNull() == true);
|
||||
}
|
||||
|
||||
SECTION("returns false after to<JsonObject>()") {
|
||||
doc.to<JsonObject>();
|
||||
REQUIRE(doc.isNull() == false);
|
||||
}
|
||||
|
||||
SECTION("returns false after to<JsonArray>()") {
|
||||
doc.to<JsonArray>();
|
||||
REQUIRE(doc.isNull() == false);
|
||||
}
|
||||
|
||||
SECTION("returns true after to<JsonVariant>()") {
|
||||
REQUIRE(doc.isNull() == true);
|
||||
}
|
||||
|
||||
SECTION("returns false after set()") {
|
||||
doc.to<JsonVariant>().set(42);
|
||||
REQUIRE(doc.isNull() == false);
|
||||
}
|
||||
|
||||
SECTION("returns true after clear()") {
|
||||
doc.to<JsonObject>();
|
||||
doc.clear();
|
||||
REQUIRE(doc.isNull() == true);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("Issue #1120") {
|
||||
StaticJsonDocument<500> doc;
|
||||
constexpr char str[] =
|
||||
"{\"contents\":[{\"module\":\"Packet\"},{\"module\":\"Analog\"}]}";
|
||||
deserializeJson(doc, str);
|
||||
|
||||
SECTION("MemberProxy<std::string>::isNull()") {
|
||||
SECTION("returns false") {
|
||||
auto value = doc[std::string("contents")];
|
||||
CHECK(value.isNull() == false);
|
||||
}
|
||||
|
||||
SECTION("returns true") {
|
||||
auto value = doc[std::string("zontents")];
|
||||
CHECK(value.isNull() == true);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("ElementProxy<MemberProxy<const char*> >::isNull()") {
|
||||
SECTION("returns false") { // Issue #1120
|
||||
auto value = doc["contents"][1];
|
||||
CHECK(value.isNull() == false);
|
||||
}
|
||||
|
||||
SECTION("returns true") {
|
||||
auto value = doc["contents"][2];
|
||||
CHECK(value.isNull() == true);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("MemberProxy<ElementProxy<MemberProxy>, const char*>::isNull()") {
|
||||
SECTION("returns false") {
|
||||
auto value = doc["contents"][1]["module"];
|
||||
CHECK(value.isNull() == false);
|
||||
}
|
||||
|
||||
SECTION("returns true") {
|
||||
auto value = doc["contents"][1]["zodule"];
|
||||
CHECK(value.isNull() == true);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("MemberProxy<ElementProxy<MemberProxy>, std::string>::isNull()") {
|
||||
SECTION("returns false") {
|
||||
auto value = doc["contents"][1][std::string("module")];
|
||||
CHECK(value.isNull() == false);
|
||||
}
|
||||
|
||||
SECTION("returns true") {
|
||||
auto value = doc["contents"][1][std::string("zodule")];
|
||||
CHECK(value.isNull() == true);
|
||||
}
|
||||
}
|
||||
}
|
||||
30
libraries/ArduinoJson/extras/tests/JsonDocument/nesting.cpp
Normal file
30
libraries/ArduinoJson/extras/tests/JsonDocument/nesting.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2023, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("JsonDocument::nesting()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
|
||||
SECTION("return 0 if uninitialized") {
|
||||
REQUIRE(doc.nesting() == 0);
|
||||
}
|
||||
|
||||
SECTION("returns 0 for string") {
|
||||
JsonVariant var = doc.to<JsonVariant>();
|
||||
var.set("hello");
|
||||
REQUIRE(doc.nesting() == 0);
|
||||
}
|
||||
|
||||
SECTION("returns 1 for empty object") {
|
||||
doc.to<JsonObject>();
|
||||
REQUIRE(doc.nesting() == 1);
|
||||
}
|
||||
|
||||
SECTION("returns 1 for empty array") {
|
||||
doc.to<JsonArray>();
|
||||
REQUIRE(doc.nesting() == 1);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,85 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2023, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("JsonDocument::overflowed()") {
|
||||
SECTION("returns false on a fresh object") {
|
||||
StaticJsonDocument<0> doc;
|
||||
CHECK(doc.overflowed() == false);
|
||||
}
|
||||
|
||||
SECTION("returns true after a failed insertion") {
|
||||
StaticJsonDocument<0> doc;
|
||||
doc.add(0);
|
||||
CHECK(doc.overflowed() == true);
|
||||
}
|
||||
|
||||
SECTION("returns false after successful insertion") {
|
||||
StaticJsonDocument<JSON_ARRAY_SIZE(1)> doc;
|
||||
doc.add(0);
|
||||
CHECK(doc.overflowed() == false);
|
||||
}
|
||||
|
||||
SECTION("returns true after a failed string copy") {
|
||||
StaticJsonDocument<JSON_ARRAY_SIZE(1)> doc;
|
||||
doc.add(std::string("example"));
|
||||
CHECK(doc.overflowed() == true);
|
||||
}
|
||||
|
||||
SECTION("returns false after a successful string copy") {
|
||||
StaticJsonDocument<JSON_ARRAY_SIZE(1) + 8> doc;
|
||||
doc.add(std::string("example"));
|
||||
CHECK(doc.overflowed() == false);
|
||||
}
|
||||
|
||||
SECTION("returns true after a failed member add") {
|
||||
StaticJsonDocument<1> doc;
|
||||
doc["example"] = true;
|
||||
CHECK(doc.overflowed() == true);
|
||||
}
|
||||
|
||||
SECTION("returns true after a failed deserialization") {
|
||||
StaticJsonDocument<JSON_ARRAY_SIZE(1)> doc;
|
||||
deserializeJson(doc, "[\"example\"]");
|
||||
CHECK(doc.overflowed() == true);
|
||||
}
|
||||
|
||||
SECTION("returns false after a successful deserialization") {
|
||||
StaticJsonDocument<JSON_ARRAY_SIZE(1) + 8> doc;
|
||||
deserializeJson(doc, "[\"example\"]");
|
||||
CHECK(doc.overflowed() == false);
|
||||
}
|
||||
|
||||
SECTION("returns false after clear()") {
|
||||
StaticJsonDocument<0> doc;
|
||||
doc.add(0);
|
||||
doc.clear();
|
||||
CHECK(doc.overflowed() == false);
|
||||
}
|
||||
|
||||
SECTION("remains false after shrinkToFit()") {
|
||||
DynamicJsonDocument doc(JSON_ARRAY_SIZE(1));
|
||||
doc.add(0);
|
||||
doc.shrinkToFit();
|
||||
CHECK(doc.overflowed() == false);
|
||||
}
|
||||
|
||||
SECTION("remains true after shrinkToFit()") {
|
||||
DynamicJsonDocument doc(JSON_ARRAY_SIZE(1));
|
||||
doc.add(0);
|
||||
doc.add(0);
|
||||
doc.shrinkToFit();
|
||||
CHECK(doc.overflowed() == true);
|
||||
}
|
||||
|
||||
SECTION("return false after garbageCollect()") {
|
||||
DynamicJsonDocument doc(JSON_ARRAY_SIZE(1));
|
||||
doc.add(0);
|
||||
doc.add(0);
|
||||
doc.garbageCollect();
|
||||
CHECK(doc.overflowed() == false);
|
||||
}
|
||||
}
|
||||
52
libraries/ArduinoJson/extras/tests/JsonDocument/remove.cpp
Normal file
52
libraries/ArduinoJson/extras/tests/JsonDocument/remove.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2023, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("JsonDocument::remove()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
|
||||
SECTION("remove(int)") {
|
||||
doc.add(1);
|
||||
doc.add(2);
|
||||
doc.add(3);
|
||||
|
||||
doc.remove(1);
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "[1,3]");
|
||||
}
|
||||
|
||||
SECTION("remove(const char *)") {
|
||||
doc["a"] = 1;
|
||||
doc["b"] = 2;
|
||||
|
||||
doc.remove("a");
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "{\"b\":2}");
|
||||
}
|
||||
|
||||
SECTION("remove(std::string)") {
|
||||
doc["a"] = 1;
|
||||
doc["b"] = 2;
|
||||
|
||||
doc.remove(std::string("b"));
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "{\"a\":1}");
|
||||
}
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("remove(vla)") {
|
||||
doc["a"] = 1;
|
||||
doc["b"] = 2;
|
||||
|
||||
size_t i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "b");
|
||||
doc.remove(vla);
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "{\"a\":1}");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
152
libraries/ArduinoJson/extras/tests/JsonDocument/shrinkToFit.cpp
Normal file
152
libraries/ArduinoJson/extras/tests/JsonDocument/shrinkToFit.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2023, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <stdlib.h> // malloc, free
|
||||
#include <string>
|
||||
|
||||
class ArmoredAllocator {
|
||||
public:
|
||||
ArmoredAllocator() : ptr_(0), size_(0) {}
|
||||
|
||||
void* allocate(size_t size) {
|
||||
ptr_ = malloc(size);
|
||||
size_ = size;
|
||||
return ptr_;
|
||||
}
|
||||
|
||||
void deallocate(void* ptr) {
|
||||
REQUIRE(ptr == ptr_);
|
||||
free(ptr);
|
||||
ptr_ = 0;
|
||||
size_ = 0;
|
||||
}
|
||||
|
||||
void* reallocate(void* ptr, size_t new_size) {
|
||||
REQUIRE(ptr == ptr_);
|
||||
// don't call realloc, instead alloc a new buffer and erase the old one
|
||||
// this way we make sure we support relocation
|
||||
void* new_ptr = malloc(new_size);
|
||||
memcpy(new_ptr, ptr_, std::min(new_size, size_));
|
||||
memset(ptr_, '#', size_); // erase
|
||||
free(ptr_);
|
||||
ptr_ = new_ptr;
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
void* ptr_;
|
||||
size_t size_;
|
||||
};
|
||||
|
||||
typedef BasicJsonDocument<ArmoredAllocator> ShrinkToFitTestDocument;
|
||||
|
||||
void testShrinkToFit(ShrinkToFitTestDocument& doc, std::string expected_json,
|
||||
size_t expected_size) {
|
||||
// test twice: shrinkToFit() should be idempotent
|
||||
for (int i = 0; i < 2; i++) {
|
||||
doc.shrinkToFit();
|
||||
|
||||
REQUIRE(doc.capacity() == expected_size);
|
||||
REQUIRE(doc.memoryUsage() == expected_size);
|
||||
|
||||
std::string json;
|
||||
serializeJson(doc, json);
|
||||
REQUIRE(json == expected_json);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("BasicJsonDocument::shrinkToFit()") {
|
||||
ShrinkToFitTestDocument doc(4096);
|
||||
|
||||
SECTION("null") {
|
||||
testShrinkToFit(doc, "null", 0);
|
||||
}
|
||||
|
||||
SECTION("empty object") {
|
||||
deserializeJson(doc, "{}");
|
||||
testShrinkToFit(doc, "{}", JSON_OBJECT_SIZE(0));
|
||||
}
|
||||
|
||||
SECTION("empty array") {
|
||||
deserializeJson(doc, "[]");
|
||||
testShrinkToFit(doc, "[]", JSON_ARRAY_SIZE(0));
|
||||
}
|
||||
|
||||
SECTION("linked string") {
|
||||
doc.set("hello");
|
||||
testShrinkToFit(doc, "\"hello\"", 0);
|
||||
}
|
||||
|
||||
SECTION("owned string") {
|
||||
doc.set(std::string("abcdefg"));
|
||||
testShrinkToFit(doc, "\"abcdefg\"", 8);
|
||||
}
|
||||
|
||||
SECTION("linked raw") {
|
||||
doc.set(serialized("[{},123]"));
|
||||
testShrinkToFit(doc, "[{},123]", 0);
|
||||
}
|
||||
|
||||
SECTION("owned raw") {
|
||||
doc.set(serialized(std::string("[{},12]")));
|
||||
testShrinkToFit(doc, "[{},12]", 8);
|
||||
}
|
||||
|
||||
SECTION("linked key") {
|
||||
doc["key"] = 42;
|
||||
testShrinkToFit(doc, "{\"key\":42}", JSON_OBJECT_SIZE(1));
|
||||
}
|
||||
|
||||
SECTION("owned key") {
|
||||
doc[std::string("abcdefg")] = 42;
|
||||
testShrinkToFit(doc, "{\"abcdefg\":42}", JSON_OBJECT_SIZE(1) + 8);
|
||||
}
|
||||
|
||||
SECTION("linked string in array") {
|
||||
doc.add("hello");
|
||||
testShrinkToFit(doc, "[\"hello\"]", JSON_ARRAY_SIZE(1));
|
||||
}
|
||||
|
||||
SECTION("owned string in array") {
|
||||
doc.add(std::string("abcdefg"));
|
||||
testShrinkToFit(doc, "[\"abcdefg\"]", JSON_ARRAY_SIZE(1) + 8);
|
||||
}
|
||||
|
||||
SECTION("linked string in object") {
|
||||
doc["key"] = "hello";
|
||||
testShrinkToFit(doc, "{\"key\":\"hello\"}", JSON_OBJECT_SIZE(1));
|
||||
}
|
||||
|
||||
SECTION("owned string in object") {
|
||||
doc["key"] = std::string("abcdefg");
|
||||
testShrinkToFit(doc, "{\"key\":\"abcdefg\"}", JSON_ARRAY_SIZE(1) + 8);
|
||||
}
|
||||
|
||||
SECTION("unaligned") {
|
||||
doc.add(std::string("?")); // two bytes in the string pool
|
||||
REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 2);
|
||||
|
||||
doc.shrinkToFit();
|
||||
|
||||
// the new capacity should be padded to align the pointers
|
||||
REQUIRE(doc.capacity() == JSON_OBJECT_SIZE(1) + sizeof(void*));
|
||||
REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 2);
|
||||
REQUIRE(doc[0] == "?");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("DynamicJsonDocument::shrinkToFit()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
|
||||
deserializeJson(doc, "{\"hello\":[\"world\"]");
|
||||
|
||||
doc.shrinkToFit();
|
||||
|
||||
std::string json;
|
||||
serializeJson(doc, json);
|
||||
REQUIRE(json == "{\"hello\":[\"world\"]}");
|
||||
}
|
||||
28
libraries/ArduinoJson/extras/tests/JsonDocument/size.cpp
Normal file
28
libraries/ArduinoJson/extras/tests/JsonDocument/size.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2023, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("JsonDocument::size()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
|
||||
SECTION("returns 0") {
|
||||
REQUIRE(doc.size() == 0);
|
||||
}
|
||||
|
||||
SECTION("as an array, return 2") {
|
||||
doc.add(1);
|
||||
doc.add(2);
|
||||
|
||||
REQUIRE(doc.size() == 2);
|
||||
}
|
||||
|
||||
SECTION("as an object, return 2") {
|
||||
doc["a"] = 1;
|
||||
doc["b"] = 2;
|
||||
|
||||
REQUIRE(doc.size() == 2);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2023, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("JsonDocument::operator[]") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
const JsonDocument& cdoc = doc;
|
||||
|
||||
SECTION("object") {
|
||||
deserializeJson(doc, "{\"hello\":\"world\"}");
|
||||
|
||||
SECTION("const char*") {
|
||||
REQUIRE(doc["hello"] == "world");
|
||||
REQUIRE(cdoc["hello"] == "world");
|
||||
}
|
||||
|
||||
SECTION("std::string") {
|
||||
REQUIRE(doc[std::string("hello")] == "world");
|
||||
REQUIRE(cdoc[std::string("hello")] == "world");
|
||||
}
|
||||
|
||||
SECTION("supports operator|") {
|
||||
REQUIRE((doc["hello"] | "nope") == std::string("world"));
|
||||
REQUIRE((doc["world"] | "nope") == std::string("nope"));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("array") {
|
||||
deserializeJson(doc, "[\"hello\",\"world\"]");
|
||||
|
||||
REQUIRE(doc[1] == "world");
|
||||
REQUIRE(cdoc[1] == "world");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JsonDocument automatically promotes to object") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
|
||||
doc["one"]["two"]["three"] = 4;
|
||||
|
||||
REQUIRE(doc["one"]["two"]["three"] == 4);
|
||||
}
|
||||
|
||||
TEST_CASE("JsonDocument automatically promotes to array") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
|
||||
doc[2] = 2;
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "[null,null,2]");
|
||||
}
|
||||
27
libraries/ArduinoJson/extras/tests/JsonDocument/swap.cpp
Normal file
27
libraries/ArduinoJson/extras/tests/JsonDocument/swap.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
#include <catch.hpp>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
using namespace std;
|
||||
|
||||
TEST_CASE("std::swap") {
|
||||
SECTION("DynamicJsonDocument*") {
|
||||
DynamicJsonDocument *p1, *p2;
|
||||
swap(p1, p2); // issue #1678
|
||||
}
|
||||
|
||||
SECTION("DynamicJsonDocument") {
|
||||
DynamicJsonDocument doc1(0x10), doc2(0x20);
|
||||
doc1.set("hello");
|
||||
doc2.set("world");
|
||||
|
||||
swap(doc1, doc2);
|
||||
|
||||
CHECK(doc1.capacity() == 0x20);
|
||||
CHECK(doc1.as<string>() == "world");
|
||||
CHECK(doc2.capacity() == 0x10);
|
||||
CHECK(doc2.as<string>() == "hello");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user