Update to ArduinoJson 7.0.4

This commit is contained in:
iranl
2024-04-19 14:44:01 +02:00
parent 1378732081
commit 81be0a689a
444 changed files with 10842 additions and 9422 deletions

View File

@@ -1,11 +1,16 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// Copyright © 2014-2024, Benoit BLANCHON
// MIT License
#define ARDUINOJSON_DECODE_UNICODE 1
#include <ArduinoJson.h>
#include <catch.hpp>
#include "Allocators.hpp"
using ArduinoJson::detail::sizeofArray;
using ArduinoJson::detail::sizeofObject;
TEST_CASE("Valid JSON strings value") {
struct TestCase {
const char* input;
@@ -35,7 +40,7 @@ TEST_CASE("Valid JSON strings value") {
};
const size_t testCount = sizeof(testCases) / sizeof(testCases[0]);
DynamicJsonDocument doc(4096);
JsonDocument doc;
for (size_t i = 0; i < testCount; i++) {
const TestCase& testCase = testCases[i];
@@ -47,7 +52,7 @@ TEST_CASE("Valid JSON strings value") {
}
TEST_CASE("\\u0000") {
StaticJsonDocument<200> doc;
JsonDocument doc;
DeserializationError err = deserializeJson(doc, "\"wx\\u0000yz\"");
REQUIRE(err == DeserializationError::Ok);
@@ -68,7 +73,7 @@ TEST_CASE("Truncated JSON string") {
const char* testCases[] = {"\"hello", "\'hello", "'\\u", "'\\u00", "'\\u000"};
const size_t testCount = sizeof(testCases) / sizeof(testCases[0]);
DynamicJsonDocument doc(4096);
JsonDocument doc;
for (size_t i = 0; i < testCount; i++) {
const char* input = testCases[i];
@@ -83,7 +88,7 @@ TEST_CASE("Invalid JSON string") {
"'\\u000G'", "'\\u000/'", "'\\x1234'"};
const size_t testCount = sizeof(testCases) / sizeof(testCases[0]);
DynamicJsonDocument doc(4096);
JsonDocument doc;
for (size_t i = 0; i < testCount; i++) {
const char* input = testCases[i];
@@ -92,41 +97,102 @@ TEST_CASE("Invalid JSON string") {
}
}
TEST_CASE("Not enough room to save the key") {
DynamicJsonDocument doc(JSON_OBJECT_SIZE(1) + 8);
TEST_CASE("Allocation of the key fails") {
TimebombAllocator timebomb(0);
SpyingAllocator spy(&timebomb);
JsonDocument doc(&spy);
SECTION("Quoted string") {
SECTION("Quoted string, first member") {
REQUIRE(deserializeJson(doc, "{\"example\":1}") ==
DeserializationError::Ok);
REQUIRE(deserializeJson(doc, "{\"accuracy\":1}") ==
DeserializationError::NoMemory);
REQUIRE(deserializeJson(doc, "{\"hello\":1,\"world\"}") ==
DeserializationError::NoMemory); // fails in the second string
REQUIRE(spy.log() == AllocatorLog{
AllocateFail(sizeofStringBuffer()),
});
}
SECTION("Non-quoted string") {
REQUIRE(deserializeJson(doc, "{example:1}") == DeserializationError::Ok);
REQUIRE(deserializeJson(doc, "{accuracy:1}") ==
SECTION("Quoted string, second member") {
timebomb.setCountdown(3);
REQUIRE(deserializeJson(doc, "{\"hello\":1,\"world\"}") ==
DeserializationError::NoMemory);
REQUIRE(spy.log() ==
AllocatorLog{
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("hello")),
Allocate(sizeofPool()),
AllocateFail(sizeofStringBuffer()),
ReallocateFail(sizeofPool(), sizeofObject(1)),
});
}
SECTION("Non-Quoted string, first member") {
REQUIRE(deserializeJson(doc, "{example:1}") ==
DeserializationError::NoMemory);
REQUIRE(spy.log() == AllocatorLog{
AllocateFail(sizeofStringBuffer()),
});
}
SECTION("Non-Quoted string, second member") {
timebomb.setCountdown(3);
REQUIRE(deserializeJson(doc, "{hello:1,world}") ==
DeserializationError::NoMemory); // fails in the second string
DeserializationError::NoMemory);
REQUIRE(spy.log() ==
AllocatorLog{
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("hello")),
Allocate(sizeofPool()),
AllocateFail(sizeofStringBuffer()),
ReallocateFail(sizeofPool(), sizeofObject(1)),
});
}
}
TEST_CASE("Empty memory pool") {
// NOLINTNEXTLINE(clang-analyzer-optin.portability.UnixAPI)
DynamicJsonDocument doc(0);
TEST_CASE("String allocation fails") {
SpyingAllocator spy(FailingAllocator::instance());
JsonDocument doc(&spy);
SECTION("Input is const char*") {
REQUIRE(deserializeJson(doc, "\"hello\"") ==
DeserializationError::NoMemory);
REQUIRE(deserializeJson(doc, "\"\"") == DeserializationError::NoMemory);
}
SECTION("Input is const char*") {
char hello[] = "\"hello\"";
REQUIRE(deserializeJson(doc, hello) == DeserializationError::Ok);
char empty[] = "\"hello\"";
REQUIRE(deserializeJson(doc, empty) == DeserializationError::Ok);
REQUIRE(spy.log() == AllocatorLog{
AllocateFail(sizeofStringBuffer()),
});
}
}
TEST_CASE("Deduplicate values") {
SpyingAllocator spy;
JsonDocument doc(&spy);
deserializeJson(doc, "[\"example\",\"example\"]");
CHECK(doc[0].as<const char*>() == doc[1].as<const char*>());
REQUIRE(spy.log() ==
AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("example")),
Allocate(sizeofStringBuffer()),
Deallocate(sizeofStringBuffer()),
Reallocate(sizeofPool(), sizeofArray(2)),
});
}
TEST_CASE("Deduplicate keys") {
SpyingAllocator spy;
JsonDocument doc(&spy);
deserializeJson(doc, "[{\"example\":1},{\"example\":2}]");
const char* key1 = doc[0].as<JsonObject>().begin()->key().c_str();
const char* key2 = doc[1].as<JsonObject>().begin()->key().c_str();
CHECK(key1 == key2);
REQUIRE(spy.log() ==
AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("example")),
Allocate(sizeofStringBuffer()),
Deallocate(sizeofStringBuffer()),
Reallocate(sizeofPool(), sizeofArray(2) + 2 * sizeofObject(1)),
});
}