Update ArduinoJSON

This commit is contained in:
iranl
2025-01-06 22:27:44 +01:00
parent 565a887c95
commit a379b30c11
82 changed files with 1098 additions and 1500 deletions

View File

@@ -5,37 +5,60 @@
#include <ArduinoJson.h>
#include <catch.hpp>
#include "Allocators.hpp"
#include "Literals.hpp"
using ElementProxy = ArduinoJson::detail::ElementProxy<JsonDocument&>;
TEST_CASE("ElementProxy::add()") {
JsonDocument doc;
SpyingAllocator spy;
JsonDocument doc(&spy);
doc.add<JsonVariant>();
ElementProxy ep = doc[0];
const ElementProxy& ep = doc[0];
SECTION("add(int)") {
SECTION("integer") {
ep.add(42);
REQUIRE(doc.as<std::string>() == "[[42]]");
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
});
}
SECTION("add(const char*)") {
SECTION("string literal") {
ep.add("world");
REQUIRE(doc.as<std::string>() == "[[\"world\"]]");
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
});
}
SECTION("add(char[])") {
SECTION("const char*") {
const char* s = "world";
ep.add(s);
REQUIRE(doc.as<std::string>() == "[[\"world\"]]");
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("world")),
});
}
SECTION("char[]") {
char s[] = "world";
ep.add(s);
strcpy(s, "!!!!!");
REQUIRE(doc.as<std::string>() == "[[\"world\"]]");
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("world")),
});
}
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("set(vla)") {
SECTION("VLA") {
size_t i = 8;
char vla[i];
strcpy(vla, "world");
@@ -43,6 +66,10 @@ TEST_CASE("ElementProxy::add()") {
ep.add(vla);
REQUIRE(doc.as<std::string>() == "[[\"world\"]]");
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("world")),
});
}
#endif
}
@@ -50,7 +77,7 @@ TEST_CASE("ElementProxy::add()") {
TEST_CASE("ElementProxy::clear()") {
JsonDocument doc;
doc.add<JsonVariant>();
ElementProxy ep = doc[0];
const ElementProxy& ep = doc[0];
SECTION("size goes back to zero") {
ep.add(42);
@@ -110,7 +137,7 @@ TEST_CASE("ElementProxy::operator==()") {
TEST_CASE("ElementProxy::remove()") {
JsonDocument doc;
doc.add<JsonVariant>();
ElementProxy ep = doc[0];
const ElementProxy& ep = doc[0];
SECTION("remove(int)") {
ep.add(1);
@@ -157,7 +184,7 @@ TEST_CASE("ElementProxy::remove()") {
TEST_CASE("ElementProxy::set()") {
JsonDocument doc;
ElementProxy ep = doc[0];
const ElementProxy& ep = doc[0];
SECTION("set(int)") {
ep.set(42);
@@ -195,7 +222,7 @@ TEST_CASE("ElementProxy::set()") {
TEST_CASE("ElementProxy::size()") {
JsonDocument doc;
doc.add<JsonVariant>();
ElementProxy ep = doc[0];
const ElementProxy& ep = doc[0];
SECTION("returns 0") {
REQUIRE(ep.size() == 0);
@@ -216,7 +243,7 @@ TEST_CASE("ElementProxy::size()") {
TEST_CASE("ElementProxy::operator[]") {
JsonDocument doc;
ElementProxy ep = doc[1];
const ElementProxy& ep = doc[1];
SECTION("set member") {
ep["world"] = 42;
@@ -247,7 +274,7 @@ TEST_CASE("ElementProxy cast to JsonVariantConst") {
JsonDocument doc;
doc[0] = "world";
const ElementProxy ep = doc[0];
const ElementProxy& ep = doc[0];
JsonVariantConst var = ep;
@@ -258,7 +285,7 @@ TEST_CASE("ElementProxy cast to JsonVariant") {
JsonDocument doc;
doc[0] = "world";
ElementProxy ep = doc[0];
const ElementProxy& ep = doc[0];
JsonVariant var = ep;

View File

@@ -14,27 +14,54 @@
using ArduinoJson::detail::sizeofArray;
using ArduinoJson::detail::sizeofObject;
using MemberProxy =
ArduinoJson::detail::MemberProxy<JsonDocument&, const char*>;
TEST_CASE("MemberProxy::add()") {
JsonDocument doc;
MemberProxy mp = doc["hello"];
SpyingAllocator spy;
JsonDocument doc(&spy);
const auto& mp = doc["hello"];
SECTION("add(int)") {
SECTION("integer") {
mp.add(42);
REQUIRE(doc.as<std::string>() == "{\"hello\":[42]}");
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
});
}
SECTION("add(const char*)") {
SECTION("string literal") {
mp.add("world");
REQUIRE(doc.as<std::string>() == "{\"hello\":[\"world\"]}");
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
});
}
SECTION("const char*") {
const char* temp = "world";
mp.add(temp);
REQUIRE(doc.as<std::string>() == "{\"hello\":[\"world\"]}");
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("world")),
});
}
SECTION("char[]") {
char temp[] = "world";
mp.add(temp);
REQUIRE(doc.as<std::string>() == "{\"hello\":[\"world\"]}");
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("world")),
});
}
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("add(vla)") {
SECTION("VLA") {
size_t i = 16;
char vla[i];
strcpy(vla, "world");
@@ -42,13 +69,17 @@ TEST_CASE("MemberProxy::add()") {
mp.add(vla);
REQUIRE(doc.as<std::string>() == "{\"hello\":[\"world\"]}");
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("world")),
});
}
#endif
}
TEST_CASE("MemberProxy::clear()") {
JsonDocument doc;
MemberProxy mp = doc["hello"];
const auto& mp = doc["hello"];
SECTION("size goes back to zero") {
mp.add(42);
@@ -139,7 +170,7 @@ TEST_CASE("MemberProxy::operator|()") {
TEST_CASE("MemberProxy::remove()") {
JsonDocument doc;
MemberProxy mp = doc["hello"];
const auto& mp = doc["hello"];
SECTION("remove(int)") {
mp.add(1);
@@ -186,7 +217,7 @@ TEST_CASE("MemberProxy::remove()") {
TEST_CASE("MemberProxy::set()") {
JsonDocument doc;
MemberProxy mp = doc["hello"];
const auto& mp = doc["hello"];
SECTION("set(int)") {
mp.set(42);
@@ -223,7 +254,7 @@ TEST_CASE("MemberProxy::set()") {
TEST_CASE("MemberProxy::size()") {
JsonDocument doc;
MemberProxy mp = doc["hello"];
const auto& mp = doc["hello"];
SECTION("returns 0") {
REQUIRE(mp.size() == 0);
@@ -246,7 +277,7 @@ TEST_CASE("MemberProxy::size()") {
TEST_CASE("MemberProxy::operator[]") {
JsonDocument doc;
MemberProxy mp = doc["hello"];
const auto& mp = doc["hello"];
SECTION("set member") {
mp["world"] = 42;
@@ -265,7 +296,7 @@ TEST_CASE("MemberProxy cast to JsonVariantConst") {
JsonDocument doc;
doc["hello"] = "world";
const MemberProxy mp = doc["hello"];
const auto& mp = doc["hello"];
JsonVariantConst var = mp;
@@ -276,7 +307,7 @@ TEST_CASE("MemberProxy cast to JsonVariant") {
JsonDocument doc;
doc["hello"] = "world";
MemberProxy mp = doc["hello"];
const auto& mp = doc["hello"];
JsonVariant var = mp;

View File

@@ -26,7 +26,7 @@ TEST_CASE("JsonDocument::add(T)") {
});
}
SECTION("const char*") {
SECTION("string literal") {
doc.add("hello");
REQUIRE(doc.as<std::string>() == "[\"hello\"]");
@@ -35,6 +35,17 @@ TEST_CASE("JsonDocument::add(T)") {
});
}
SECTION("const char*") {
const char* value = "hello";
doc.add(value);
REQUIRE(doc.as<std::string>() == "[\"hello\"]");
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("hello")),
});
}
SECTION("std::string") {
doc.add("example"_s);
doc.add("example"_s);

View File

@@ -1,54 +0,0 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
#include "Literals.hpp"
TEST_CASE("JsonDocument::containsKey()") {
JsonDocument doc;
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("hello"_s) == 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);
}
SECTION("support JsonVariant") {
doc["hello"] = "world";
doc["key"] = "hello";
REQUIRE(doc.containsKey(doc["key"]) == true);
REQUIRE(doc.containsKey(doc["foo"]) == false);
}
}

View File

@@ -12,49 +12,41 @@ TEST_CASE("Issue #1120") {
SECTION("MemberProxy<std::string>::isNull()") {
SECTION("returns false") {
auto value = doc["contents"_s];
CHECK(value.isNull() == false);
CHECK(doc["contents"_s].isNull() == false);
}
SECTION("returns true") {
auto value = doc["zontents"_s];
CHECK(value.isNull() == true);
CHECK(doc["zontents"_s].isNull() == true);
}
}
SECTION("ElementProxy<MemberProxy<const char*> >::isNull()") {
SECTION("returns false") { // Issue #1120
auto value = doc["contents"][1];
CHECK(value.isNull() == false);
CHECK(doc["contents"][1].isNull() == false);
}
SECTION("returns true") {
auto value = doc["contents"][2];
CHECK(value.isNull() == true);
CHECK(doc["contents"][2].isNull() == true);
}
}
SECTION("MemberProxy<ElementProxy<MemberProxy>, const char*>::isNull()") {
SECTION("returns false") {
auto value = doc["contents"][1]["module"];
CHECK(value.isNull() == false);
CHECK(doc["contents"][1]["module"].isNull() == false);
}
SECTION("returns true") {
auto value = doc["contents"][1]["zodule"];
CHECK(value.isNull() == true);
CHECK(doc["contents"][1]["zodule"].isNull() == true);
}
}
SECTION("MemberProxy<ElementProxy<MemberProxy>, std::string>::isNull()") {
SECTION("returns false") {
auto value = doc["contents"][1]["module"_s];
CHECK(value.isNull() == false);
CHECK(doc["contents"][1]["module"_s].isNull() == false);
}
SECTION("returns true") {
auto value = doc["contents"][1]["zodule"_s];
CHECK(value.isNull() == true);
CHECK(doc["contents"][1]["zodule"_s].isNull() == true);
}
}
}

View File

@@ -20,11 +20,21 @@ TEST_CASE("JsonDocument::remove()") {
REQUIRE(doc.as<std::string>() == "[1,3]");
}
SECTION("string literal") {
doc["a"] = 1;
doc["a\0b"_s] = 2;
doc["b"] = 3;
doc.remove("a\0b");
REQUIRE(doc.as<std::string>() == "{\"a\":1,\"b\":3}");
}
SECTION("remove(const char *)") {
doc["a"] = 1;
doc["b"] = 2;
doc.remove("a");
doc.remove(static_cast<const char*>("a"));
REQUIRE(doc.as<std::string>() == "{\"b\":2}");
}

View File

@@ -11,6 +11,21 @@ TEST_CASE("JsonDocument::set()") {
SpyingAllocator spy;
JsonDocument doc(&spy);
SECTION("nullptr") {
doc.set(nullptr);
REQUIRE(doc.isNull());
REQUIRE(spy.log() == AllocatorLog{});
}
SECTION("integer&") {
int toto = 42;
doc.set(toto);
REQUIRE(doc.as<std::string>() == "42");
REQUIRE(spy.log() == AllocatorLog{});
}
SECTION("integer") {
doc.set(42);
@@ -18,13 +33,23 @@ TEST_CASE("JsonDocument::set()") {
REQUIRE(spy.log() == AllocatorLog{});
}
SECTION("const char*") {
SECTION("string literal") {
doc.set("example");
REQUIRE(doc.as<const char*>() == "example"_s);
REQUIRE(spy.log() == AllocatorLog{});
}
SECTION("const char*") {
const char* value = "example";
doc.set(value);
REQUIRE(doc.as<const char*>() == "example"_s);
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofString("example")),
});
}
SECTION("std::string") {
doc.set("example"_s);

View File

@@ -5,6 +5,7 @@
#include <ArduinoJson.h>
#include <catch.hpp>
#include "Allocators.hpp"
#include "Literals.hpp"
TEST_CASE("JsonDocument::operator[]") {
@@ -16,8 +17,16 @@ TEST_CASE("JsonDocument::operator[]") {
doc["abc\0d"_s] = "ABCD";
SECTION("const char*") {
const char* key = "abc";
REQUIRE(doc[key] == "ABC");
REQUIRE(cdoc[key] == "ABC");
}
SECTION("string literal") {
REQUIRE(doc["abc"] == "ABC");
REQUIRE(cdoc["abc"] == "ABC");
REQUIRE(doc["abc\0d"] == "ABCD");
REQUIRE(cdoc["abc\0d"] == "ABCD");
}
SECTION("std::string") {
@@ -94,3 +103,65 @@ TEST_CASE("JsonDocument automatically promotes to array") {
REQUIRE(doc.as<std::string>() == "[null,null,2]");
}
TEST_CASE("JsonDocument::operator[] key storage") {
SpyingAllocator spy;
JsonDocument doc(&spy);
SECTION("string literal") {
doc["hello"] = 0;
REQUIRE(doc.as<std::string>() == "{\"hello\":0}");
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
});
}
SECTION("const char*") {
const char* key = "hello";
doc[key] = 0;
REQUIRE(doc.as<std::string>() == "{\"hello\":0}");
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("hello")),
});
}
SECTION("char[]") {
char key[] = "hello";
doc[key] = 0;
REQUIRE(doc.as<std::string>() == "{\"hello\":0}");
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("hello")),
});
}
SECTION("std::string") {
doc["hello"_s] = 0;
REQUIRE(doc.as<std::string>() == "{\"hello\":0}");
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("hello")),
});
}
#if defined(HAS_VARIABLE_LENGTH_ARRAY) && \
!defined(SUBSCRIPT_CONFLICTS_WITH_BUILTIN_OPERATOR)
SECTION("VLA") {
size_t i = 16;
char vla[i];
strcpy(vla, "hello");
doc[vla] = 0;
REQUIRE(doc.as<std::string>() == "{\"hello\":0}");
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("hello")),
});
}
#endif
}