forked from bblanchon/ArduinoJson
Create more memory pools as needed (resolves #1074)
This commit is contained in:
@ -5,6 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Memory/Allocator.hpp>
|
||||
#include <ArduinoJson/Memory/VariantPool.hpp>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
@ -218,3 +219,12 @@ class TimebombAllocator : public ArduinoJson::Allocator {
|
||||
size_t countdown_ = 0;
|
||||
Allocator* upstream_;
|
||||
};
|
||||
|
||||
inline size_t sizeofPoolList(size_t n = ARDUINOJSON_INITIAL_POOL_COUNT) {
|
||||
return sizeof(ArduinoJson::detail::VariantPool) * n;
|
||||
}
|
||||
|
||||
inline size_t sizeofPool(
|
||||
ArduinoJson::detail::SlotCount n = ARDUINOJSON_POOL_CAPACITY) {
|
||||
return ArduinoJson::detail::VariantPool::slotsToBytes(n);
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
using ArduinoJson::detail::sizeofArray;
|
||||
|
||||
TEST_CASE("copyArray()") {
|
||||
@ -109,17 +111,12 @@ TEST_CASE("copyArray()") {
|
||||
}
|
||||
|
||||
SECTION("int[] -> JsonArray, but not enough memory") {
|
||||
const size_t SIZE = sizeofArray(2);
|
||||
JsonDocument doc(SIZE);
|
||||
JsonDocument doc(0, FailingAllocator::instance());
|
||||
JsonArray array = doc.to<JsonArray>();
|
||||
char json[32];
|
||||
int source[] = {1, 2, 3};
|
||||
|
||||
bool ok = copyArray(source, array);
|
||||
REQUIRE_FALSE(ok);
|
||||
|
||||
serializeJson(array, json);
|
||||
CHECK(std::string("[1,2]") == json);
|
||||
}
|
||||
|
||||
SECTION("int[][] -> JsonArray") {
|
||||
@ -160,20 +157,12 @@ TEST_CASE("copyArray()") {
|
||||
}
|
||||
|
||||
SECTION("int[][] -> JsonArray, but not enough memory") {
|
||||
const size_t SIZE = sizeofArray(2) + sizeofArray(3) + sizeofArray(2);
|
||||
JsonDocument doc(SIZE);
|
||||
JsonDocument doc(0, FailingAllocator::instance());
|
||||
JsonArray array = doc.to<JsonArray>();
|
||||
char json[32] = "";
|
||||
int source[][3] = {{1, 2, 3}, {4, 5, 6}};
|
||||
|
||||
CAPTURE(SIZE);
|
||||
|
||||
bool ok = copyArray(source, array);
|
||||
CAPTURE(doc.memoryUsage());
|
||||
CHECK_FALSE(ok);
|
||||
|
||||
serializeJson(array, json);
|
||||
CHECK(std::string("[[1,2,3],[4,5]]") == json);
|
||||
REQUIRE(ok == false);
|
||||
}
|
||||
|
||||
SECTION("JsonArray -> int[], with more space than needed") {
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
using ArduinoJson::detail::sizeofArray;
|
||||
using ArduinoJson::detail::sizeofObject;
|
||||
using ArduinoJson::detail::sizeofString;
|
||||
@ -257,8 +259,11 @@ TEST_CASE("deserialize JSON array") {
|
||||
}
|
||||
|
||||
TEST_CASE("deserialize JSON array under memory constraints") {
|
||||
SECTION("buffer of the right size for an empty array") {
|
||||
JsonDocument doc(sizeofArray(0));
|
||||
TimebombAllocator allocator(100);
|
||||
JsonDocument doc(0, &allocator);
|
||||
|
||||
SECTION("empty array requires no allocation") {
|
||||
allocator.setCountdown(0);
|
||||
char input[] = "[]";
|
||||
|
||||
DeserializationError err = deserializeJson(doc, input);
|
||||
@ -266,73 +271,39 @@ TEST_CASE("deserialize JSON array under memory constraints") {
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
}
|
||||
|
||||
SECTION("buffer too small for an array with one element") {
|
||||
JsonDocument doc(sizeofArray(0));
|
||||
SECTION("allocation of pool list fails") {
|
||||
allocator.setCountdown(0);
|
||||
char input[] = "[1]";
|
||||
|
||||
DeserializationError err = deserializeJson(doc, input);
|
||||
|
||||
REQUIRE(err == DeserializationError::NoMemory);
|
||||
REQUIRE(doc.as<std::string>() == "[]");
|
||||
}
|
||||
|
||||
SECTION("buffer of the right size for an array with one element") {
|
||||
JsonDocument doc(sizeofArray(1));
|
||||
SECTION("allocation of pool fails") {
|
||||
allocator.setCountdown(1);
|
||||
char input[] = "[1]";
|
||||
|
||||
DeserializationError err = deserializeJson(doc, input);
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
REQUIRE(err == DeserializationError::NoMemory);
|
||||
REQUIRE(doc.as<std::string>() == "[]");
|
||||
}
|
||||
|
||||
SECTION("buffer too small for an array with a nested object") {
|
||||
JsonDocument doc(sizeofArray(0) + sizeofObject(0));
|
||||
char input[] = "[{}]";
|
||||
SECTION("allocation of string fails in array") {
|
||||
allocator.setCountdown(2);
|
||||
char input[] = "[0,\"hi!\"]";
|
||||
|
||||
DeserializationError err = deserializeJson(doc, input);
|
||||
|
||||
REQUIRE(err == DeserializationError::NoMemory);
|
||||
}
|
||||
|
||||
SECTION("buffer of the right size for an array with a nested object") {
|
||||
JsonDocument doc(sizeofArray(1) + sizeofObject(0));
|
||||
char input[] = "[{}]";
|
||||
|
||||
DeserializationError err = deserializeJson(doc, input);
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
REQUIRE(doc.as<std::string>() == "[0,null]");
|
||||
}
|
||||
|
||||
SECTION("don't store space characters") {
|
||||
JsonDocument doc(100);
|
||||
|
||||
deserializeJson(doc, " [ \"1234567\" ] ");
|
||||
|
||||
REQUIRE(sizeofArray(1) + sizeofString(7) == doc.memoryUsage());
|
||||
}
|
||||
|
||||
SECTION("Should clear the JsonArray") {
|
||||
JsonDocument doc(sizeofArray(4));
|
||||
char input[] = "[1,2,3,4]";
|
||||
|
||||
deserializeJson(doc, input);
|
||||
deserializeJson(doc, "[]");
|
||||
|
||||
JsonArray arr = doc.as<JsonArray>();
|
||||
REQUIRE(arr.size() == 0);
|
||||
REQUIRE(doc.memoryUsage() == sizeofArray(0));
|
||||
}
|
||||
|
||||
SECTION("buffer of the right size for an array with two element") {
|
||||
JsonDocument doc(sizeofArray(2));
|
||||
char input[] = "[1,2]";
|
||||
|
||||
DeserializationError err = deserializeJson(doc, input);
|
||||
JsonArray arr = doc.as<JsonArray>();
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
REQUIRE(doc.is<JsonArray>());
|
||||
REQUIRE(doc.memoryUsage() == sizeofArray(2));
|
||||
REQUIRE(arr[0] == 1);
|
||||
REQUIRE(arr[1] == 2);
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
using ArduinoJson::detail::sizeofArray;
|
||||
using ArduinoJson::detail::sizeofObject;
|
||||
using ArduinoJson::detail::sizeofString;
|
||||
@ -320,59 +322,56 @@ TEST_CASE("deserialize JSON object") {
|
||||
}
|
||||
|
||||
TEST_CASE("deserialize JSON object under memory constraints") {
|
||||
SECTION("buffer for the right size for an empty object") {
|
||||
JsonDocument doc(sizeofObject(0));
|
||||
TimebombAllocator allocator(1024);
|
||||
JsonDocument doc(0, &allocator);
|
||||
|
||||
SECTION("empty object requires no allocation") {
|
||||
allocator.setCountdown(0);
|
||||
char input[] = "{}";
|
||||
|
||||
DeserializationError err = deserializeJson(doc, input);
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
REQUIRE(doc.as<std::string>() == "{}");
|
||||
}
|
||||
|
||||
SECTION("buffer too small for an empty object") {
|
||||
JsonDocument doc(sizeofObject(0));
|
||||
SECTION("key allocation fails") {
|
||||
allocator.setCountdown(0);
|
||||
char input[] = "{\"a\":1}";
|
||||
|
||||
DeserializationError err = deserializeJson(doc, input);
|
||||
|
||||
REQUIRE(err == DeserializationError::NoMemory);
|
||||
REQUIRE(doc.as<std::string>() == "{}");
|
||||
}
|
||||
|
||||
SECTION("buffer of the right size for an object with one member") {
|
||||
JsonDocument doc(sizeofObject(1));
|
||||
SECTION("pool list allocation fails") {
|
||||
allocator.setCountdown(2);
|
||||
char input[] = "{\"a\":1}";
|
||||
|
||||
DeserializationError err = deserializeJson(doc, input);
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
REQUIRE(err == DeserializationError::NoMemory);
|
||||
REQUIRE(doc.as<std::string>() == "{}");
|
||||
}
|
||||
|
||||
SECTION("buffer too small for an object with a nested array") {
|
||||
JsonDocument doc(sizeofObject(0) + sizeofArray(0));
|
||||
char input[] = "{\"a\":[]}";
|
||||
SECTION("pool allocation fails") {
|
||||
allocator.setCountdown(3);
|
||||
char input[] = "{\"a\":1}";
|
||||
|
||||
DeserializationError err = deserializeJson(doc, input);
|
||||
|
||||
REQUIRE(err == DeserializationError::NoMemory);
|
||||
REQUIRE(doc.as<std::string>() == "{}");
|
||||
}
|
||||
|
||||
SECTION("buffer of the right size for an object with a nested array") {
|
||||
JsonDocument doc(sizeofObject(1) + sizeofArray(0));
|
||||
char input[] = "{\"a\":[]}";
|
||||
SECTION("string allocation fails") {
|
||||
allocator.setCountdown(4);
|
||||
char input[] = "{\"a\":\"b\"}";
|
||||
|
||||
DeserializationError err = deserializeJson(doc, input);
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
}
|
||||
|
||||
SECTION("Should clear the JsonObject") {
|
||||
JsonDocument doc(sizeofObject(1));
|
||||
char input[] = "{\"hello\":\"world\"}";
|
||||
|
||||
deserializeJson(doc, input);
|
||||
deserializeJson(doc, "{}");
|
||||
|
||||
REQUIRE(doc.as<JsonObject>().size() == 0);
|
||||
REQUIRE(doc.memoryUsage() == sizeofObject(0));
|
||||
REQUIRE(err == DeserializationError::NoMemory);
|
||||
REQUIRE(doc.as<std::string>() == "{\"a\":null}");
|
||||
}
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ TEST_CASE("Invalid JSON string") {
|
||||
}
|
||||
|
||||
TEST_CASE("Allocation of the key fails") {
|
||||
TimebombAllocator timebombAllocator(1);
|
||||
TimebombAllocator timebombAllocator(0);
|
||||
SpyingAllocator spyingAllocator(&timebombAllocator);
|
||||
JsonDocument doc(1024, &spyingAllocator);
|
||||
|
||||
@ -107,19 +107,19 @@ TEST_CASE("Allocation of the key fails") {
|
||||
REQUIRE(deserializeJson(doc, "{\"example\":1}") ==
|
||||
DeserializationError::NoMemory);
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(1024)
|
||||
<< AllocatorLog::AllocateFail(sizeofString(31)));
|
||||
AllocatorLog() << AllocatorLog::AllocateFail(sizeofString(31)));
|
||||
}
|
||||
|
||||
SECTION("Quoted string, second member") {
|
||||
timebombAllocator.setCountdown(2);
|
||||
timebombAllocator.setCountdown(4);
|
||||
REQUIRE(deserializeJson(doc, "{\"hello\":1,\"world\"}") ==
|
||||
DeserializationError::NoMemory);
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(1024)
|
||||
<< AllocatorLog::Allocate(sizeofString(31))
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofString(31))
|
||||
<< AllocatorLog::Reallocate(sizeofString(31),
|
||||
sizeofString(5))
|
||||
<< AllocatorLog::Allocate(sizeofPoolList())
|
||||
<< AllocatorLog::Allocate(sizeofPool())
|
||||
<< AllocatorLog::AllocateFail(sizeofString(31)));
|
||||
}
|
||||
|
||||
@ -127,19 +127,19 @@ TEST_CASE("Allocation of the key fails") {
|
||||
REQUIRE(deserializeJson(doc, "{example:1}") ==
|
||||
DeserializationError::NoMemory);
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(1024)
|
||||
<< AllocatorLog::AllocateFail(sizeofString(31)));
|
||||
AllocatorLog() << AllocatorLog::AllocateFail(sizeofString(31)));
|
||||
}
|
||||
|
||||
SECTION("Non-Quoted string, second member") {
|
||||
timebombAllocator.setCountdown(2);
|
||||
timebombAllocator.setCountdown(4);
|
||||
REQUIRE(deserializeJson(doc, "{hello:1,world}") ==
|
||||
DeserializationError::NoMemory);
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(1024)
|
||||
<< AllocatorLog::Allocate(sizeofString(31))
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofString(31))
|
||||
<< AllocatorLog::Reallocate(sizeofString(31),
|
||||
sizeofString(5))
|
||||
<< AllocatorLog::Allocate(sizeofPoolList())
|
||||
<< AllocatorLog::Allocate(sizeofPool())
|
||||
<< AllocatorLog::AllocateFail(sizeofString(31)));
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,8 @@ TEST_CASE("JsonDocument assignment") {
|
||||
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofString(5)) // hello
|
||||
<< AllocatorLog::Allocate(sizeofPoolList())
|
||||
<< AllocatorLog::Allocate(sizeofPool())
|
||||
<< AllocatorLog::Allocate(sizeofString(5)) // world
|
||||
);
|
||||
}
|
||||
@ -41,8 +43,8 @@ TEST_CASE("JsonDocument assignment") {
|
||||
|
||||
REQUIRE(doc2.as<std::string>() == "[{\"hello\":\"world\"}]");
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Deallocate(sizeofArray(1))
|
||||
<< AllocatorLog::Allocate(capacity)
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofPoolList())
|
||||
<< AllocatorLog::Allocate(sizeofPool())
|
||||
<< AllocatorLog::Allocate(sizeofString(5)) // hello
|
||||
<< AllocatorLog::Allocate(sizeofString(5)) // world
|
||||
);
|
||||
@ -59,9 +61,9 @@ TEST_CASE("JsonDocument assignment") {
|
||||
|
||||
REQUIRE(doc2.as<std::string>() == "{\"hello\":\"world\"}");
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Deallocate(4096)
|
||||
<< AllocatorLog::Allocate(capacity1)
|
||||
<< AllocatorLog::Allocate(sizeofString(5)) // hello
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofString(5)) // hello
|
||||
<< AllocatorLog::Allocate(sizeofPoolList())
|
||||
<< AllocatorLog::Allocate(sizeofPool())
|
||||
<< AllocatorLog::Allocate(sizeofString(5)) // world
|
||||
);
|
||||
}
|
||||
@ -69,21 +71,24 @@ TEST_CASE("JsonDocument assignment") {
|
||||
SECTION("Move assign") {
|
||||
{
|
||||
JsonDocument doc1(4096, &spyingAllocator);
|
||||
doc1.set(std::string("The size of this string is 32!!"));
|
||||
doc1[std::string("hello")] = std::string("world");
|
||||
JsonDocument doc2(128, &spyingAllocator);
|
||||
|
||||
doc2 = std::move(doc1);
|
||||
|
||||
REQUIRE(doc2.as<std::string>() == "The size of this string is 32!!");
|
||||
REQUIRE(doc2.as<std::string>() == "{\"hello\":\"world\"}");
|
||||
REQUIRE(doc1.as<std::string>() == "null");
|
||||
}
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(4096)
|
||||
<< AllocatorLog::Allocate(sizeofString(31))
|
||||
<< AllocatorLog::Allocate(128)
|
||||
<< AllocatorLog::Deallocate(128)
|
||||
<< AllocatorLog::Deallocate(sizeofString(31))
|
||||
<< AllocatorLog::Deallocate(4096));
|
||||
REQUIRE(
|
||||
spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofString(5)) // hello
|
||||
<< AllocatorLog::Allocate(sizeofPoolList())
|
||||
<< AllocatorLog::Allocate(sizeofPool())
|
||||
<< AllocatorLog::Allocate(sizeofString(5)) // world
|
||||
<< AllocatorLog::Deallocate(sizeofString(5)) // hello
|
||||
<< AllocatorLog::Deallocate(sizeofString(5)) // world
|
||||
<< AllocatorLog::Deallocate(sizeofPool())
|
||||
<< AllocatorLog::Deallocate(sizeofPoolList()));
|
||||
}
|
||||
|
||||
SECTION("Assign from JsonObject") {
|
||||
|
@ -16,9 +16,7 @@ TEST_CASE("JsonDocument constructor") {
|
||||
|
||||
SECTION("JsonDocument(size_t)") {
|
||||
{ JsonDocument doc(4096, &spyingAllocator); }
|
||||
REQUIRE(spyingAllocator.log() == AllocatorLog()
|
||||
<< AllocatorLog::Allocate(4096)
|
||||
<< AllocatorLog::Deallocate(4096));
|
||||
REQUIRE(spyingAllocator.log() == AllocatorLog());
|
||||
}
|
||||
|
||||
SECTION("JsonDocument(const JsonDocument&)") {
|
||||
@ -33,14 +31,10 @@ TEST_CASE("JsonDocument constructor") {
|
||||
REQUIRE(doc2.as<std::string>() == "The size of this string is 32!!");
|
||||
}
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(capacity)
|
||||
<< AllocatorLog::Allocate(sizeofString(31))
|
||||
<< AllocatorLog::Allocate(capacity)
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofString(31))
|
||||
<< AllocatorLog::Allocate(sizeofString(31))
|
||||
<< AllocatorLog::Deallocate(sizeofString(31))
|
||||
<< AllocatorLog::Deallocate(capacity)
|
||||
<< AllocatorLog::Deallocate(sizeofString(31))
|
||||
<< AllocatorLog::Deallocate(capacity));
|
||||
<< AllocatorLog::Deallocate(sizeofString(31)));
|
||||
}
|
||||
|
||||
SECTION("JsonDocument(JsonDocument&&)") {
|
||||
@ -54,10 +48,8 @@ TEST_CASE("JsonDocument constructor") {
|
||||
REQUIRE(doc1.as<std::string>() == "null");
|
||||
}
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(4096)
|
||||
<< AllocatorLog::Allocate(sizeofString(31))
|
||||
<< AllocatorLog::Deallocate(sizeofString(31))
|
||||
<< AllocatorLog::Deallocate(4096));
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofString(31))
|
||||
<< AllocatorLog::Deallocate(sizeofString(31)));
|
||||
}
|
||||
|
||||
SECTION("JsonDocument(JsonObject)") {
|
||||
@ -69,7 +61,8 @@ TEST_CASE("JsonDocument constructor") {
|
||||
|
||||
REQUIRE(doc2.as<std::string>() == "{\"hello\":\"world\"}");
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofObject(1)));
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofPoolList())
|
||||
<< AllocatorLog::Allocate(sizeofPool()));
|
||||
}
|
||||
|
||||
SECTION("Construct from JsonArray") {
|
||||
@ -80,8 +73,9 @@ TEST_CASE("JsonDocument constructor") {
|
||||
JsonDocument doc2(arr, &spyingAllocator);
|
||||
|
||||
REQUIRE(doc2.as<std::string>() == "[\"hello\"]");
|
||||
REQUIRE(spyingAllocator.log() == AllocatorLog() << AllocatorLog::Allocate(
|
||||
addPadding(doc1.memoryUsage())));
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofPoolList())
|
||||
<< AllocatorLog::Allocate(sizeofPool()));
|
||||
}
|
||||
|
||||
SECTION("Construct from JsonVariant") {
|
||||
@ -92,8 +86,6 @@ TEST_CASE("JsonDocument constructor") {
|
||||
|
||||
REQUIRE(doc2.as<std::string>() == "hello");
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(
|
||||
sizeofString(5)) // TODO: remove
|
||||
<< AllocatorLog::Allocate(sizeofString(5)));
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofString(5)));
|
||||
}
|
||||
}
|
||||
|
@ -30,10 +30,12 @@ TEST_CASE("JsonDocument::garbageCollect()") {
|
||||
REQUIRE(doc.memoryUsage() == sizeofObject(1) + sizeofString(7));
|
||||
REQUIRE(doc.as<std::string>() == "{\"dancing\":2}");
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(capacity)
|
||||
<< AllocatorLog::Allocate(sizeofString(7))
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofString(7))
|
||||
<< AllocatorLog::Allocate(sizeofPoolList())
|
||||
<< AllocatorLog::Allocate(sizeofPool())
|
||||
<< AllocatorLog::Deallocate(sizeofString(7))
|
||||
<< AllocatorLog::Deallocate(capacity));
|
||||
<< AllocatorLog::Deallocate(sizeofPool())
|
||||
<< AllocatorLog::Deallocate(sizeofPoolList()));
|
||||
}
|
||||
|
||||
SECTION("when allocation fails") {
|
||||
@ -50,7 +52,6 @@ TEST_CASE("JsonDocument::garbageCollect()") {
|
||||
REQUIRE(doc.as<std::string>() == "{\"dancing\":2}");
|
||||
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::AllocateFail(capacity)
|
||||
<< AllocatorLog::AllocateFail(sizeofString(7)));
|
||||
AllocatorLog() << AllocatorLog::AllocateFail(sizeofString(7)));
|
||||
}
|
||||
}
|
||||
|
@ -10,80 +10,81 @@
|
||||
using ArduinoJson::detail::sizeofArray;
|
||||
|
||||
TEST_CASE("JsonDocument::overflowed()") {
|
||||
TimebombAllocator allocator(10);
|
||||
JsonDocument doc(0, &allocator);
|
||||
|
||||
SECTION("returns false on a fresh object") {
|
||||
JsonDocument doc(0);
|
||||
allocator.setCountdown(0);
|
||||
CHECK(doc.overflowed() == false);
|
||||
}
|
||||
|
||||
SECTION("returns true after a failed insertion") {
|
||||
JsonDocument doc(0);
|
||||
allocator.setCountdown(0);
|
||||
doc.add(0);
|
||||
CHECK(doc.overflowed() == true);
|
||||
}
|
||||
|
||||
SECTION("returns false after successful insertion") {
|
||||
JsonDocument doc(sizeofArray(1));
|
||||
allocator.setCountdown(2);
|
||||
doc.add(0);
|
||||
CHECK(doc.overflowed() == false);
|
||||
}
|
||||
|
||||
SECTION("returns true after a failed string copy") {
|
||||
ControllableAllocator allocator;
|
||||
JsonDocument doc(sizeofArray(1), &allocator);
|
||||
allocator.disable();
|
||||
allocator.setCountdown(0);
|
||||
doc.add(std::string("example"));
|
||||
CHECK(doc.overflowed() == true);
|
||||
}
|
||||
|
||||
SECTION("returns false after a successful string copy") {
|
||||
JsonDocument doc(sizeofArray(1));
|
||||
allocator.setCountdown(3);
|
||||
doc.add(std::string("example"));
|
||||
CHECK(doc.overflowed() == false);
|
||||
}
|
||||
|
||||
SECTION("returns true after a failed member add") {
|
||||
JsonDocument doc(1);
|
||||
allocator.setCountdown(0);
|
||||
doc["example"] = true;
|
||||
CHECK(doc.overflowed() == true);
|
||||
}
|
||||
|
||||
SECTION("returns true after a failed deserialization") {
|
||||
JsonDocument doc(sizeofArray(1));
|
||||
allocator.setCountdown(1);
|
||||
deserializeJson(doc, "[1, 2]");
|
||||
CHECK(doc.overflowed() == true);
|
||||
}
|
||||
|
||||
SECTION("returns false after a successful deserialization") {
|
||||
JsonDocument doc(sizeofArray(1));
|
||||
allocator.setCountdown(4);
|
||||
deserializeJson(doc, "[\"example\"]");
|
||||
CHECK(doc.overflowed() == false);
|
||||
}
|
||||
|
||||
SECTION("returns false after clear()") {
|
||||
JsonDocument doc(0);
|
||||
allocator.setCountdown(0);
|
||||
doc.add(0);
|
||||
doc.clear();
|
||||
CHECK(doc.overflowed() == false);
|
||||
}
|
||||
|
||||
SECTION("remains false after shrinkToFit()") {
|
||||
JsonDocument doc(sizeofArray(1));
|
||||
allocator.setCountdown(2);
|
||||
doc.add(0);
|
||||
allocator.setCountdown(2);
|
||||
doc.shrinkToFit();
|
||||
CHECK(doc.overflowed() == false);
|
||||
}
|
||||
|
||||
SECTION("remains true after shrinkToFit()") {
|
||||
JsonDocument doc(sizeofArray(1));
|
||||
doc.add(0);
|
||||
allocator.setCountdown(0);
|
||||
doc.add(0);
|
||||
allocator.setCountdown(2);
|
||||
doc.shrinkToFit();
|
||||
CHECK(doc.overflowed() == true);
|
||||
}
|
||||
|
||||
SECTION("return false after garbageCollect()") {
|
||||
JsonDocument doc(sizeofArray(1));
|
||||
doc.add(0);
|
||||
allocator.setCountdown(0);
|
||||
doc.add(0);
|
||||
doc.garbageCollect();
|
||||
CHECK(doc.overflowed() == false);
|
||||
|
@ -48,9 +48,7 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
|
||||
doc.shrinkToFit();
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "null");
|
||||
REQUIRE(spyingAllocator.log() == AllocatorLog()
|
||||
<< AllocatorLog::Allocate(4096)
|
||||
<< AllocatorLog::Reallocate(4096, 0));
|
||||
REQUIRE(spyingAllocator.log() == AllocatorLog());
|
||||
}
|
||||
|
||||
SECTION("empty object") {
|
||||
@ -59,9 +57,7 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
|
||||
doc.shrinkToFit();
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "{}");
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(4096)
|
||||
<< AllocatorLog::Reallocate(4096, sizeofObject(0)));
|
||||
REQUIRE(spyingAllocator.log() == AllocatorLog());
|
||||
}
|
||||
|
||||
SECTION("empty array") {
|
||||
@ -70,9 +66,7 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
|
||||
doc.shrinkToFit();
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "[]");
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(4096)
|
||||
<< AllocatorLog::Reallocate(4096, sizeofArray(0)));
|
||||
REQUIRE(spyingAllocator.log() == AllocatorLog());
|
||||
}
|
||||
|
||||
SECTION("linked string") {
|
||||
@ -81,9 +75,7 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
|
||||
doc.shrinkToFit();
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "hello");
|
||||
REQUIRE(spyingAllocator.log() == AllocatorLog()
|
||||
<< AllocatorLog::Allocate(4096)
|
||||
<< AllocatorLog::Reallocate(4096, 0));
|
||||
REQUIRE(spyingAllocator.log() == AllocatorLog());
|
||||
}
|
||||
|
||||
SECTION("owned string") {
|
||||
@ -94,9 +86,7 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "abcdefg");
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(4096)
|
||||
<< AllocatorLog::Allocate(sizeofString(7))
|
||||
<< AllocatorLog::Reallocate(4096, 0));
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofString(7)));
|
||||
}
|
||||
|
||||
SECTION("raw string") {
|
||||
@ -106,9 +96,7 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "[{},12]");
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(4096)
|
||||
<< AllocatorLog::Allocate(sizeofString(7))
|
||||
<< AllocatorLog::Reallocate(4096, 0));
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofString(7)));
|
||||
}
|
||||
|
||||
SECTION("linked key") {
|
||||
@ -118,8 +106,12 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "{\"key\":42}");
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(4096)
|
||||
<< AllocatorLog::Reallocate(4096, sizeofObject(1)));
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofPoolList())
|
||||
<< AllocatorLog::Allocate(sizeofPool())
|
||||
<< AllocatorLog::Reallocate(sizeofPool(),
|
||||
sizeofObject(1))
|
||||
<< AllocatorLog::Reallocate(sizeofPoolList(),
|
||||
sizeofPoolList(1)));
|
||||
}
|
||||
|
||||
SECTION("owned key") {
|
||||
@ -129,9 +121,13 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "{\"abcdefg\":42}");
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(4096)
|
||||
<< AllocatorLog::Allocate(sizeofString(7))
|
||||
<< AllocatorLog::Reallocate(4096, sizeofObject(1)));
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofString(7))
|
||||
<< AllocatorLog::Allocate(sizeofPoolList())
|
||||
<< AllocatorLog::Allocate(sizeofPool())
|
||||
<< AllocatorLog::Reallocate(sizeofPool(),
|
||||
sizeofObject(1))
|
||||
<< AllocatorLog::Reallocate(sizeofPoolList(),
|
||||
sizeofPoolList(1)));
|
||||
}
|
||||
|
||||
SECTION("linked string in array") {
|
||||
@ -140,9 +136,13 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
|
||||
doc.shrinkToFit();
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "[\"hello\"]");
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(4096)
|
||||
<< AllocatorLog::Reallocate(4096, sizeofArray(1)));
|
||||
REQUIRE(
|
||||
spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofPoolList())
|
||||
<< AllocatorLog::Allocate(sizeofPool())
|
||||
<< AllocatorLog::Reallocate(sizeofPool(), sizeofArray(1))
|
||||
<< AllocatorLog::Reallocate(sizeofPoolList(),
|
||||
sizeofPoolList(1)));
|
||||
}
|
||||
|
||||
SECTION("owned string in array") {
|
||||
@ -151,10 +151,14 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
|
||||
doc.shrinkToFit();
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "[\"abcdefg\"]");
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(4096)
|
||||
<< AllocatorLog::Allocate(sizeofString(7))
|
||||
<< AllocatorLog::Reallocate(4096, sizeofArray(1)));
|
||||
REQUIRE(
|
||||
spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofPoolList())
|
||||
<< AllocatorLog::Allocate(sizeofPool())
|
||||
<< AllocatorLog::Allocate(sizeofString(7))
|
||||
<< AllocatorLog::Reallocate(sizeofPool(), sizeofArray(1))
|
||||
<< AllocatorLog::Reallocate(sizeofPoolList(),
|
||||
sizeofPoolList(1)));
|
||||
}
|
||||
|
||||
SECTION("linked string in object") {
|
||||
@ -164,8 +168,12 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "{\"key\":\"hello\"}");
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(4096)
|
||||
<< AllocatorLog::Reallocate(4096, sizeofObject(1)));
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofPoolList())
|
||||
<< AllocatorLog::Allocate(sizeofPool())
|
||||
<< AllocatorLog::Reallocate(sizeofPool(),
|
||||
sizeofObject(1))
|
||||
<< AllocatorLog::Reallocate(sizeofPoolList(),
|
||||
sizeofPoolList(1)));
|
||||
}
|
||||
|
||||
SECTION("owned string in object") {
|
||||
@ -174,9 +182,13 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
|
||||
doc.shrinkToFit();
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "{\"key\":\"abcdefg\"}");
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(4096)
|
||||
<< AllocatorLog::Allocate(sizeofString(7))
|
||||
<< AllocatorLog::Reallocate(4096, sizeofObject(1)));
|
||||
REQUIRE(
|
||||
spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofPoolList())
|
||||
<< AllocatorLog::Allocate(sizeofPool())
|
||||
<< AllocatorLog::Allocate(sizeofString(7))
|
||||
<< AllocatorLog::Reallocate(sizeofPool(), sizeofPool(1))
|
||||
<< AllocatorLog::Reallocate(sizeofPoolList(),
|
||||
sizeofPoolList(1)));
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
using ArduinoJson::detail::sizeofObject;
|
||||
|
||||
TEST_CASE("JsonObject::set()") {
|
||||
@ -73,12 +75,13 @@ TEST_CASE("JsonObject::set()") {
|
||||
REQUIRE(obj2["hello"] == std::string("world"));
|
||||
}
|
||||
|
||||
SECTION("destination too small to store the key") {
|
||||
JsonDocument doc3(sizeofObject(1));
|
||||
SECTION("copy fails in the middle of an object") {
|
||||
TimebombAllocator allocator(3);
|
||||
JsonDocument doc3(0, &allocator);
|
||||
JsonObject obj3 = doc3.to<JsonObject>();
|
||||
|
||||
obj1["a"] = 1;
|
||||
obj1["b"] = 2;
|
||||
obj1[std::string("a")] = 1;
|
||||
obj1[std::string("b")] = 2;
|
||||
|
||||
bool success = obj3.set(obj1);
|
||||
|
||||
@ -86,16 +89,17 @@ TEST_CASE("JsonObject::set()") {
|
||||
REQUIRE(doc3.as<std::string>() == "{\"a\":1}");
|
||||
}
|
||||
|
||||
SECTION("destination too small to store the value") {
|
||||
JsonDocument doc3(sizeofObject(1));
|
||||
SECTION("copy fails in the middle of an array") {
|
||||
TimebombAllocator allocator(2);
|
||||
JsonDocument doc3(0, &allocator);
|
||||
JsonObject obj3 = doc3.to<JsonObject>();
|
||||
|
||||
obj1["hello"][1] = "world";
|
||||
obj1["hello"][0] = std::string("world");
|
||||
|
||||
bool success = obj3.set(obj1);
|
||||
|
||||
REQUIRE(success == false);
|
||||
REQUIRE(doc3.as<std::string>() == "{\"hello\":[]}");
|
||||
REQUIRE(doc3.as<std::string>() == "{\"hello\":[null]}");
|
||||
}
|
||||
|
||||
SECTION("destination is null") {
|
||||
|
@ -43,14 +43,6 @@ TEST_CASE("serializeJson(JsonArray)") {
|
||||
check(array, "[\"hello\",\"world\"]");
|
||||
}
|
||||
|
||||
SECTION("OneStringOverCapacity") {
|
||||
array.add("hello");
|
||||
array.add("world");
|
||||
array.add("lost");
|
||||
|
||||
check(array, "[\"hello\",\"world\"]");
|
||||
}
|
||||
|
||||
SECTION("One double") {
|
||||
array.add(3.1415927);
|
||||
check(array, "[3.1415927]");
|
||||
@ -82,14 +74,6 @@ TEST_CASE("serializeJson(JsonArray)") {
|
||||
check(array, "[{\"key\":\"value\"}]");
|
||||
}
|
||||
|
||||
SECTION("OneIntegerOverCapacity") {
|
||||
array.add(1);
|
||||
array.add(2);
|
||||
array.add(3);
|
||||
|
||||
check(array, "[1,2]");
|
||||
}
|
||||
|
||||
SECTION("OneTrue") {
|
||||
array.add(true);
|
||||
|
||||
@ -109,14 +93,6 @@ TEST_CASE("serializeJson(JsonArray)") {
|
||||
check(array, "[false,true]");
|
||||
}
|
||||
|
||||
SECTION("OneBooleanOverCapacity") {
|
||||
array.add(false);
|
||||
array.add(true);
|
||||
array.add(false);
|
||||
|
||||
check(array, "[false,true]");
|
||||
}
|
||||
|
||||
SECTION("OneEmptyNestedArray") {
|
||||
array.createNestedArray();
|
||||
|
||||
|
@ -178,33 +178,33 @@ TEST_CASE("deserializeMsgPack() under memory constaints") {
|
||||
}
|
||||
|
||||
SECTION("fixarray") {
|
||||
checkError(sizeofArray(0), 1, "\x90", DeserializationError::Ok); // []
|
||||
checkError(sizeofArray(0), 0, "\x90", DeserializationError::Ok); // []
|
||||
checkError(sizeofArray(0), 0, "\x91\x01",
|
||||
DeserializationError::NoMemory); // [1]
|
||||
checkError(sizeofArray(0), 1, "\x91\x01",
|
||||
DeserializationError::NoMemory); // [1]
|
||||
checkError(sizeofArray(1), 1, "\x91\x01",
|
||||
checkError(sizeofArray(1), 2, "\x91\x01",
|
||||
DeserializationError::Ok); // [1]
|
||||
checkError(sizeofArray(1), 1, "\x92\x01\x02",
|
||||
DeserializationError::NoMemory); // [1,2]
|
||||
}
|
||||
|
||||
SECTION("array 16") {
|
||||
checkError(sizeofArray(0), 1, "\xDC\x00\x00", DeserializationError::Ok);
|
||||
checkError(sizeofArray(0), 0, "\xDC\x00\x00", DeserializationError::Ok);
|
||||
checkError(sizeofArray(0), 0, "\xDC\x00\x01\x01",
|
||||
DeserializationError::NoMemory);
|
||||
checkError(sizeofArray(0), 1, "\xDC\x00\x01\x01",
|
||||
DeserializationError::NoMemory);
|
||||
checkError(sizeofArray(1), 1, "\xDC\x00\x01\x01", DeserializationError::Ok);
|
||||
checkError(sizeofArray(1), 1, "\xDC\x00\x02\x01\x02",
|
||||
DeserializationError::NoMemory);
|
||||
checkError(sizeofArray(1), 2, "\xDC\x00\x01\x01", DeserializationError::Ok);
|
||||
}
|
||||
|
||||
SECTION("array 32") {
|
||||
checkError(sizeofArray(0), 1, "\xDD\x00\x00\x00\x00",
|
||||
checkError(sizeofArray(0), 0, "\xDD\x00\x00\x00\x00",
|
||||
DeserializationError::Ok);
|
||||
checkError(sizeofArray(0), 1, "\xDD\x00\x00\x00\x01\x01",
|
||||
checkError(sizeofArray(0), 0, "\xDD\x00\x00\x00\x01\x01",
|
||||
DeserializationError::NoMemory);
|
||||
checkError(sizeofArray(1), 1, "\xDD\x00\x00\x00\x01\x01",
|
||||
DeserializationError::Ok);
|
||||
checkError(sizeofArray(1), 1, "\xDD\x00\x00\x00\x02\x01\x02",
|
||||
DeserializationError::NoMemory);
|
||||
checkError(sizeofArray(1), 2, "\xDD\x00\x00\x00\x01\x01",
|
||||
DeserializationError::Ok);
|
||||
}
|
||||
|
||||
SECTION("fixmap") {
|
||||
@ -214,13 +214,13 @@ TEST_CASE("deserializeMsgPack() under memory constaints") {
|
||||
SECTION("{H:1}") {
|
||||
checkError(sizeofObject(0), 0, "\x81\xA1H\x01",
|
||||
DeserializationError::NoMemory);
|
||||
checkError(sizeofObject(1) + sizeofString(2), 3, "\x81\xA1H\x01",
|
||||
checkError(sizeofObject(1) + sizeofString(2), 4, "\x81\xA1H\x01",
|
||||
DeserializationError::Ok);
|
||||
}
|
||||
SECTION("{H:1,W:2}") {
|
||||
checkError(sizeofObject(1) + sizeofString(2), 3, "\x82\xA1H\x01\xA1W\x02",
|
||||
checkError(sizeofObject(1) + sizeofString(2), 4, "\x82\xA1H\x01\xA1W\x02",
|
||||
DeserializationError::NoMemory);
|
||||
checkError(sizeofObject(2) + 2 * sizeofString(2), 5,
|
||||
checkError(sizeofObject(2) + 2 * sizeofString(2), 6,
|
||||
"\x82\xA1H\x01\xA1W\x02", DeserializationError::Ok);
|
||||
}
|
||||
}
|
||||
@ -230,16 +230,16 @@ TEST_CASE("deserializeMsgPack() under memory constaints") {
|
||||
checkError(sizeofObject(0), 0, "\xDE\x00\x00", DeserializationError::Ok);
|
||||
}
|
||||
SECTION("{H:1}") {
|
||||
checkError(sizeofObject(1) + sizeofString(2), 1, "\xDE\x00\x01\xA1H\x01",
|
||||
checkError(sizeofObject(1) + sizeofString(2), 2, "\xDE\x00\x01\xA1H\x01",
|
||||
DeserializationError::NoMemory);
|
||||
checkError(sizeofObject(1) + sizeofString(2), 3, "\xDE\x00\x01\xA1H\x01",
|
||||
checkError(sizeofObject(1) + sizeofString(2), 4, "\xDE\x00\x01\xA1H\x01",
|
||||
DeserializationError::Ok);
|
||||
}
|
||||
SECTION("{H:1,W:2}") {
|
||||
checkError(sizeofObject(1) + sizeofString(2), 3,
|
||||
checkError(sizeofObject(1) + sizeofString(2), 4,
|
||||
"\xDE\x00\x02\xA1H\x01\xA1W\x02",
|
||||
DeserializationError::NoMemory);
|
||||
checkError(sizeofObject(2) + 2 * sizeofObject(1), 5,
|
||||
checkError(sizeofObject(2) + 2 * sizeofObject(1), 6,
|
||||
"\xDE\x00\x02\xA1H\x01\xA1W\x02", DeserializationError::Ok);
|
||||
}
|
||||
}
|
||||
@ -250,17 +250,17 @@ TEST_CASE("deserializeMsgPack() under memory constaints") {
|
||||
DeserializationError::Ok);
|
||||
}
|
||||
SECTION("{H:1}") {
|
||||
checkError(sizeofObject(1) + sizeofString(2), 1,
|
||||
checkError(sizeofObject(1) + sizeofString(2), 2,
|
||||
"\xDF\x00\x00\x00\x01\xA1H\x01",
|
||||
DeserializationError::NoMemory);
|
||||
checkError(sizeofObject(1) + sizeofString(2), 3,
|
||||
checkError(sizeofObject(1) + sizeofString(2), 4,
|
||||
"\xDF\x00\x00\x00\x01\xA1H\x01", DeserializationError::Ok);
|
||||
}
|
||||
SECTION("{H:1,W:2}") {
|
||||
checkError(sizeofObject(1) + 2 * sizeofString(2), 3,
|
||||
checkError(sizeofObject(1) + 2 * sizeofString(2), 4,
|
||||
"\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02",
|
||||
DeserializationError::NoMemory);
|
||||
checkError(sizeofObject(2) + 2 * sizeofObject(1), 5,
|
||||
checkError(sizeofObject(2) + 2 * sizeofObject(1), 6,
|
||||
"\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02",
|
||||
DeserializationError::Ok);
|
||||
}
|
||||
|
@ -30,15 +30,7 @@ TEST_CASE("ResourceManager::allocSlot()") {
|
||||
REQUIRE(isAligned(resources.allocSlot().operator VariantSlot*()));
|
||||
}
|
||||
|
||||
SECTION("Returns zero if capacity is 0") {
|
||||
ResourceManager resources(0);
|
||||
|
||||
auto variant = resources.allocSlot();
|
||||
REQUIRE(variant.id() == NULL_SLOT);
|
||||
REQUIRE(static_cast<VariantSlot*>(variant) == nullptr);
|
||||
}
|
||||
|
||||
SECTION("Returns zero if buffer is null") {
|
||||
SECTION("Returns null if pool list allocation fails") {
|
||||
ResourceManager resources(4096, FailingAllocator::instance());
|
||||
|
||||
auto variant = resources.allocSlot();
|
||||
@ -46,8 +38,9 @@ TEST_CASE("ResourceManager::allocSlot()") {
|
||||
REQUIRE(static_cast<VariantSlot*>(variant) == nullptr);
|
||||
}
|
||||
|
||||
SECTION("Returns zero if capacity is insufficient") {
|
||||
ResourceManager resources(sizeof(VariantSlot));
|
||||
SECTION("Returns null if pool allocation fails") {
|
||||
TimebombAllocator allocator(1);
|
||||
ResourceManager resources(4096, &allocator);
|
||||
|
||||
resources.allocSlot();
|
||||
|
||||
|
@ -6,25 +6,21 @@
|
||||
#include <ArduinoJson/Memory/VariantPoolImpl.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
TEST_CASE("ResourceManager::capacity()") {
|
||||
const size_t capacity = 4 * sizeof(VariantSlot);
|
||||
ResourceManager resources(capacity);
|
||||
REQUIRE(capacity == resources.capacity());
|
||||
}
|
||||
|
||||
TEST_CASE("ResourceManager::size()") {
|
||||
ResourceManager resources(4096);
|
||||
TimebombAllocator allocator(0);
|
||||
ResourceManager resources(4096, &allocator);
|
||||
|
||||
SECTION("Initial size is 0") {
|
||||
REQUIRE(0 == resources.size());
|
||||
}
|
||||
|
||||
SECTION("Doesn't grow when memory pool is full") {
|
||||
const size_t variantCount = resources.capacity() / sizeof(VariantSlot);
|
||||
|
||||
for (size_t i = 0; i < variantCount; i++)
|
||||
SECTION("Doesn't grow when allocation of second pool fails") {
|
||||
allocator.setCountdown(2);
|
||||
for (size_t i = 0; i < ARDUINOJSON_POOL_CAPACITY; i++)
|
||||
resources.allocSlot();
|
||||
size_t size = resources.size();
|
||||
|
||||
|
Reference in New Issue
Block a user