Initial commit of Arduino libraries
This commit is contained in:
26
ArduinoJson/extras/tests/ResourceManager/CMakeLists.txt
Normal file
26
ArduinoJson/extras/tests/ResourceManager/CMakeLists.txt
Normal file
@@ -0,0 +1,26 @@
|
||||
# ArduinoJson - https://arduinojson.org
|
||||
# Copyright © 2014-2025, Benoit BLANCHON
|
||||
# MIT License
|
||||
|
||||
add_executable(ResourceManagerTests
|
||||
allocVariant.cpp
|
||||
clear.cpp
|
||||
saveString.cpp
|
||||
shrinkToFit.cpp
|
||||
size.cpp
|
||||
StringBuffer.cpp
|
||||
StringBuilder.cpp
|
||||
swap.cpp
|
||||
)
|
||||
|
||||
add_compile_definitions(ResourceManagerTests
|
||||
ARDUINOJSON_SLOT_ID_SIZE=1 # require less RAM for overflow tests
|
||||
ARDUINOJSON_POOL_CAPACITY=16
|
||||
)
|
||||
|
||||
add_test(ResourceManager ResourceManagerTests)
|
||||
|
||||
set_tests_properties(ResourceManager
|
||||
PROPERTIES
|
||||
LABELS "Catch"
|
||||
)
|
||||
50
ArduinoJson/extras/tests/ResourceManager/StringBuffer.cpp
Normal file
50
ArduinoJson/extras/tests/ResourceManager/StringBuffer.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2025, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/StringBuffer.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
#include "Literals.hpp"
|
||||
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
TEST_CASE("StringBuffer") {
|
||||
SpyingAllocator spy;
|
||||
ResourceManager resources(&spy);
|
||||
StringBuffer sb(&resources);
|
||||
VariantData variant;
|
||||
|
||||
SECTION("Tiny string") {
|
||||
auto ptr = sb.reserve(3);
|
||||
strcpy(ptr, "hi!");
|
||||
sb.save(&variant);
|
||||
|
||||
REQUIRE(variant.type() == VariantType::TinyString);
|
||||
REQUIRE(variant.asString() == "hi!");
|
||||
}
|
||||
|
||||
SECTION("Tiny string can't contain NUL") {
|
||||
auto ptr = sb.reserve(3);
|
||||
memcpy(ptr, "a\0b", 3);
|
||||
sb.save(&variant);
|
||||
|
||||
REQUIRE(variant.type() == VariantType::OwnedString);
|
||||
|
||||
auto str = variant.asString();
|
||||
REQUIRE(str.size() == 3);
|
||||
REQUIRE(str.c_str()[0] == 'a');
|
||||
REQUIRE(str.c_str()[1] == 0);
|
||||
REQUIRE(str.c_str()[2] == 'b');
|
||||
}
|
||||
|
||||
SECTION("Tiny string can't have 4 characters") {
|
||||
auto ptr = sb.reserve(4);
|
||||
strcpy(ptr, "alfa");
|
||||
sb.save(&variant);
|
||||
|
||||
REQUIRE(variant.type() == VariantType::OwnedString);
|
||||
REQUIRE(variant.asString() == "alfa");
|
||||
}
|
||||
}
|
||||
184
ArduinoJson/extras/tests/ResourceManager/StringBuilder.cpp
Normal file
184
ArduinoJson/extras/tests/ResourceManager/StringBuilder.cpp
Normal file
@@ -0,0 +1,184 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2025, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/StringBuilder.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
using namespace ArduinoJson;
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
TEST_CASE("StringBuilder") {
|
||||
KillswitchAllocator killswitch;
|
||||
SpyingAllocator spyingAllocator(&killswitch);
|
||||
ResourceManager resources(&spyingAllocator);
|
||||
|
||||
SECTION("Empty string") {
|
||||
StringBuilder str(&resources);
|
||||
VariantData data;
|
||||
|
||||
str.startString();
|
||||
str.save(&data);
|
||||
|
||||
REQUIRE(resources.overflowed() == false);
|
||||
REQUIRE(spyingAllocator.log() == AllocatorLog{
|
||||
Allocate(sizeofStringBuffer()),
|
||||
});
|
||||
REQUIRE(data.type() == VariantType::TinyString);
|
||||
}
|
||||
|
||||
SECTION("Tiny string") {
|
||||
StringBuilder str(&resources);
|
||||
|
||||
str.startString();
|
||||
str.append("url");
|
||||
|
||||
REQUIRE(str.isValid() == true);
|
||||
REQUIRE(str.str() == "url");
|
||||
REQUIRE(spyingAllocator.log() == AllocatorLog{
|
||||
Allocate(sizeofStringBuffer()),
|
||||
});
|
||||
|
||||
VariantData data;
|
||||
str.save(&data);
|
||||
|
||||
REQUIRE(resources.overflowed() == false);
|
||||
REQUIRE(data.type() == VariantType::TinyString);
|
||||
REQUIRE(data.asString() == "url");
|
||||
}
|
||||
|
||||
SECTION("Short string fits in first allocation") {
|
||||
StringBuilder str(&resources);
|
||||
|
||||
str.startString();
|
||||
str.append("hello");
|
||||
|
||||
REQUIRE(str.isValid() == true);
|
||||
REQUIRE(str.str() == "hello");
|
||||
REQUIRE(resources.overflowed() == false);
|
||||
REQUIRE(spyingAllocator.log() == AllocatorLog{
|
||||
Allocate(sizeofStringBuffer()),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("Long string needs reallocation") {
|
||||
StringBuilder str(&resources);
|
||||
const char* lorem =
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do "
|
||||
"eiusmod tempor incididunt ut labore et dolore magna aliqua.";
|
||||
|
||||
str.startString();
|
||||
str.append(lorem);
|
||||
|
||||
REQUIRE(str.isValid() == true);
|
||||
REQUIRE(str.str() == lorem);
|
||||
REQUIRE(resources.overflowed() == false);
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofStringBuffer(1)),
|
||||
Reallocate(sizeofStringBuffer(1), sizeofStringBuffer(2)),
|
||||
Reallocate(sizeofStringBuffer(2), sizeofStringBuffer(3)),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("Realloc fails") {
|
||||
StringBuilder str(&resources);
|
||||
|
||||
str.startString();
|
||||
killswitch.on();
|
||||
str.append(
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do "
|
||||
"eiusmod tempor incididunt ut labore et dolore magna aliqua.");
|
||||
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofStringBuffer()),
|
||||
ReallocateFail(sizeofStringBuffer(), sizeofStringBuffer(2)),
|
||||
Deallocate(sizeofStringBuffer()),
|
||||
});
|
||||
REQUIRE(str.isValid() == false);
|
||||
REQUIRE(resources.overflowed() == true);
|
||||
}
|
||||
|
||||
SECTION("Initial allocation fails") {
|
||||
StringBuilder str(&resources);
|
||||
|
||||
killswitch.on();
|
||||
str.startString();
|
||||
|
||||
REQUIRE(str.isValid() == false);
|
||||
REQUIRE(resources.overflowed() == true);
|
||||
REQUIRE(spyingAllocator.log() == AllocatorLog{
|
||||
AllocateFail(sizeofStringBuffer()),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static JsonString saveString(StringBuilder& builder, const char* s) {
|
||||
VariantData data;
|
||||
builder.startString();
|
||||
builder.append(s);
|
||||
builder.save(&data);
|
||||
return data.asString();
|
||||
}
|
||||
|
||||
TEST_CASE("StringBuilder::save() deduplicates strings") {
|
||||
SpyingAllocator spy;
|
||||
ResourceManager resources(&spy);
|
||||
StringBuilder builder(&resources);
|
||||
|
||||
SECTION("Basic") {
|
||||
auto s1 = saveString(builder, "hello");
|
||||
auto s2 = saveString(builder, "world");
|
||||
auto s3 = saveString(builder, "hello");
|
||||
|
||||
REQUIRE(s1 == "hello");
|
||||
REQUIRE(s2 == "world");
|
||||
REQUIRE(+s1.c_str() == +s3.c_str()); // same address
|
||||
|
||||
REQUIRE(spy.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofStringBuffer()),
|
||||
Reallocate(sizeofStringBuffer(), sizeofString("hello")),
|
||||
Allocate(sizeofStringBuffer()),
|
||||
Reallocate(sizeofStringBuffer(), sizeofString("world")),
|
||||
Allocate(sizeofStringBuffer()),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("Requires terminator") {
|
||||
auto s1 = saveString(builder, "hello world");
|
||||
auto s2 = saveString(builder, "hello");
|
||||
|
||||
REQUIRE(s1 == "hello world");
|
||||
REQUIRE(s2 == "hello");
|
||||
REQUIRE(+s2.c_str() != +s1.c_str()); // different address
|
||||
|
||||
REQUIRE(spy.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofStringBuffer()),
|
||||
Reallocate(sizeofStringBuffer(), sizeofString("hello world")),
|
||||
Allocate(sizeofStringBuffer()),
|
||||
Reallocate(sizeofStringBuffer(), sizeofString("hello")),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("Don't overrun") {
|
||||
auto s1 = saveString(builder, "hello world");
|
||||
auto s2 = saveString(builder, "worl");
|
||||
|
||||
REQUIRE(s1 == "hello world");
|
||||
REQUIRE(s2 == "worl");
|
||||
REQUIRE(s2.c_str() != s1.c_str()); // different address
|
||||
|
||||
REQUIRE(spy.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofStringBuffer()),
|
||||
Reallocate(sizeofStringBuffer(), sizeofString("hello world")),
|
||||
Allocate(sizeofStringBuffer()),
|
||||
Reallocate(sizeofStringBuffer(), sizeofString("worl")),
|
||||
});
|
||||
}
|
||||
}
|
||||
92
ArduinoJson/extras/tests/ResourceManager/allocVariant.cpp
Normal file
92
ArduinoJson/extras/tests/ResourceManager/allocVariant.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2025, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
TEST_CASE("ResourceManager::allocVariant()") {
|
||||
SECTION("Returns different pointer") {
|
||||
ResourceManager resources;
|
||||
|
||||
auto s1 = resources.allocVariant();
|
||||
REQUIRE(s1.ptr() != nullptr);
|
||||
auto s2 = resources.allocVariant();
|
||||
REQUIRE(s2.ptr() != nullptr);
|
||||
|
||||
REQUIRE(s1.ptr() != s2.ptr());
|
||||
}
|
||||
|
||||
SECTION("Returns the same slot after calling freeVariant()") {
|
||||
ResourceManager resources;
|
||||
|
||||
auto s1 = resources.allocVariant();
|
||||
auto s2 = resources.allocVariant();
|
||||
resources.freeVariant(s1);
|
||||
resources.freeVariant(s2);
|
||||
auto s3 = resources.allocVariant();
|
||||
auto s4 = resources.allocVariant();
|
||||
auto s5 = resources.allocVariant();
|
||||
|
||||
REQUIRE(s2.id() != s1.id());
|
||||
REQUIRE(s3.id() == s2.id());
|
||||
REQUIRE(s4.id() == s1.id());
|
||||
REQUIRE(s5.id() != s1.id());
|
||||
REQUIRE(s5.id() != s2.id());
|
||||
}
|
||||
|
||||
SECTION("Returns aligned pointers") {
|
||||
ResourceManager resources;
|
||||
|
||||
REQUIRE(isAligned(resources.allocVariant().ptr()));
|
||||
REQUIRE(isAligned(resources.allocVariant().ptr()));
|
||||
}
|
||||
|
||||
SECTION("Returns null if pool list allocation fails") {
|
||||
ResourceManager resources(FailingAllocator::instance());
|
||||
|
||||
auto variant = resources.allocVariant();
|
||||
REQUIRE(variant.id() == NULL_SLOT);
|
||||
REQUIRE(variant.ptr() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("Returns null if pool allocation fails") {
|
||||
ResourceManager resources(FailingAllocator::instance());
|
||||
|
||||
resources.allocVariant();
|
||||
|
||||
auto variant = resources.allocVariant();
|
||||
REQUIRE(variant.id() == NULL_SLOT);
|
||||
REQUIRE(variant.ptr() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("Try overflow pool counter") {
|
||||
ResourceManager resources;
|
||||
|
||||
// this test assumes SlotId is 8-bit; otherwise it consumes a lot of memory
|
||||
// tyhe GitHub Workflow gets killed
|
||||
REQUIRE(NULL_SLOT == 255);
|
||||
|
||||
// fill all the pools
|
||||
for (SlotId i = 0; i < NULL_SLOT; i++) {
|
||||
auto slot = resources.allocVariant();
|
||||
REQUIRE(slot.id() == i); // or != NULL_SLOT
|
||||
REQUIRE(slot.ptr() != nullptr);
|
||||
}
|
||||
|
||||
REQUIRE(resources.overflowed() == false);
|
||||
|
||||
// now all allocations should fail
|
||||
for (int i = 0; i < 10; i++) {
|
||||
auto slot = resources.allocVariant();
|
||||
REQUIRE(slot.id() == NULL_SLOT);
|
||||
REQUIRE(slot.ptr() == nullptr);
|
||||
}
|
||||
|
||||
REQUIRE(resources.overflowed() == true);
|
||||
}
|
||||
}
|
||||
30
ArduinoJson/extras/tests/ResourceManager/clear.cpp
Normal file
30
ArduinoJson/extras/tests/ResourceManager/clear.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2025, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManagerImpl.hpp>
|
||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
TEST_CASE("ResourceManager::clear()") {
|
||||
ResourceManager resources;
|
||||
|
||||
SECTION("Discards allocated variants") {
|
||||
resources.allocVariant();
|
||||
|
||||
resources.clear();
|
||||
REQUIRE(resources.size() == 0);
|
||||
}
|
||||
|
||||
SECTION("Discards allocated strings") {
|
||||
resources.saveString(adaptString("123456789"));
|
||||
REQUIRE(resources.size() == sizeofString(9));
|
||||
|
||||
resources.clear();
|
||||
|
||||
REQUIRE(resources.size() == 0);
|
||||
}
|
||||
}
|
||||
70
ArduinoJson/extras/tests/ResourceManager/saveString.cpp
Normal file
70
ArduinoJson/extras/tests/ResourceManager/saveString.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2025, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
static StringNode* saveString(ResourceManager& resources, const char* s) {
|
||||
return resources.saveString(adaptString(s));
|
||||
}
|
||||
|
||||
static StringNode* saveString(ResourceManager& resources, const char* s,
|
||||
size_t n) {
|
||||
return resources.saveString(adaptString(s, n));
|
||||
}
|
||||
|
||||
TEST_CASE("ResourceManager::saveString()") {
|
||||
ResourceManager resources;
|
||||
|
||||
SECTION("Duplicates different strings") {
|
||||
auto a = saveString(resources, "hello");
|
||||
auto b = saveString(resources, "world");
|
||||
REQUIRE(+a->data != +b->data);
|
||||
REQUIRE(a->length == 5);
|
||||
REQUIRE(b->length == 5);
|
||||
REQUIRE(a->references == 1);
|
||||
REQUIRE(b->references == 1);
|
||||
REQUIRE(resources.size() == sizeofString("hello") + sizeofString("world"));
|
||||
}
|
||||
|
||||
SECTION("Deduplicates identical strings") {
|
||||
auto a = saveString(resources, "hello");
|
||||
auto b = saveString(resources, "hello");
|
||||
REQUIRE(a == b);
|
||||
REQUIRE(a->length == 5);
|
||||
REQUIRE(a->references == 2);
|
||||
REQUIRE(resources.size() == sizeofString("hello"));
|
||||
}
|
||||
|
||||
SECTION("Deduplicates identical strings that contain NUL") {
|
||||
auto a = saveString(resources, "hello\0world", 11);
|
||||
auto b = saveString(resources, "hello\0world", 11);
|
||||
REQUIRE(a == b);
|
||||
REQUIRE(a->length == 11);
|
||||
REQUIRE(a->references == 2);
|
||||
REQUIRE(resources.size() == sizeofString("hello world"));
|
||||
}
|
||||
|
||||
SECTION("Don't stop on first NUL") {
|
||||
auto a = saveString(resources, "hello");
|
||||
auto b = saveString(resources, "hello\0world", 11);
|
||||
REQUIRE(a != b);
|
||||
REQUIRE(a->length == 5);
|
||||
REQUIRE(b->length == 11);
|
||||
REQUIRE(a->references == 1);
|
||||
REQUIRE(b->references == 1);
|
||||
REQUIRE(resources.size() ==
|
||||
sizeofString("hello") + sizeofString("hello world"));
|
||||
}
|
||||
|
||||
SECTION("Returns NULL when allocation fails") {
|
||||
ResourceManager pool2(FailingAllocator::instance());
|
||||
REQUIRE(saveString(pool2, "a") == nullptr);
|
||||
}
|
||||
}
|
||||
57
ArduinoJson/extras/tests/ResourceManager/shrinkToFit.cpp
Normal file
57
ArduinoJson/extras/tests/ResourceManager/shrinkToFit.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2025, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManagerImpl.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
TEST_CASE("ResourceManager::shrinkToFit()") {
|
||||
SpyingAllocator spyingAllocator;
|
||||
ResourceManager resources(&spyingAllocator);
|
||||
|
||||
SECTION("empty") {
|
||||
resources.shrinkToFit();
|
||||
|
||||
REQUIRE(spyingAllocator.log() == AllocatorLog{});
|
||||
}
|
||||
|
||||
SECTION("only one pool") {
|
||||
resources.allocVariant();
|
||||
|
||||
resources.shrinkToFit();
|
||||
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofPool()),
|
||||
Reallocate(sizeofPool(), sizeofPool(1)),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("more pools than initial count") {
|
||||
for (size_t i = 0;
|
||||
i < ARDUINOJSON_POOL_CAPACITY * ARDUINOJSON_INITIAL_POOL_COUNT + 1;
|
||||
i++)
|
||||
resources.allocVariant();
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofPool()) * ARDUINOJSON_INITIAL_POOL_COUNT,
|
||||
Allocate(sizeofPoolList(ARDUINOJSON_INITIAL_POOL_COUNT * 2)),
|
||||
Allocate(sizeofPool()),
|
||||
});
|
||||
|
||||
spyingAllocator.clearLog();
|
||||
resources.shrinkToFit();
|
||||
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog{
|
||||
Reallocate(sizeofPool(), sizeofPool(1)),
|
||||
Reallocate(sizeofPoolList(ARDUINOJSON_INITIAL_POOL_COUNT * 2),
|
||||
sizeofPoolList(ARDUINOJSON_INITIAL_POOL_COUNT + 1)),
|
||||
});
|
||||
}
|
||||
}
|
||||
31
ArduinoJson/extras/tests/ResourceManager/size.cpp
Normal file
31
ArduinoJson/extras/tests/ResourceManager/size.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2025, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManagerImpl.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
TEST_CASE("ResourceManager::size()") {
|
||||
TimebombAllocator timebomb(0);
|
||||
ResourceManager resources(&timebomb);
|
||||
|
||||
SECTION("Initial size is 0") {
|
||||
REQUIRE(0 == resources.size());
|
||||
}
|
||||
|
||||
SECTION("Doesn't grow when allocation of second pool fails") {
|
||||
timebomb.setCountdown(1);
|
||||
for (size_t i = 0; i < ARDUINOJSON_POOL_CAPACITY; i++)
|
||||
resources.allocVariant();
|
||||
size_t size = resources.size();
|
||||
|
||||
resources.allocVariant();
|
||||
|
||||
REQUIRE(size == resources.size());
|
||||
}
|
||||
}
|
||||
96
ArduinoJson/extras/tests/ResourceManager/swap.cpp
Normal file
96
ArduinoJson/extras/tests/ResourceManager/swap.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2025, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/Alignment.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManagerImpl.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
static void fullPreallocatedPools(ResourceManager& resources) {
|
||||
for (int i = 0;
|
||||
i < ARDUINOJSON_INITIAL_POOL_COUNT * ARDUINOJSON_POOL_CAPACITY; i++)
|
||||
resources.allocVariant();
|
||||
}
|
||||
|
||||
TEST_CASE("ResourceManager::swap()") {
|
||||
SECTION("Both using preallocated pool list") {
|
||||
SpyingAllocator spy;
|
||||
ResourceManager a(&spy);
|
||||
ResourceManager b(&spy);
|
||||
|
||||
auto a1 = a.allocVariant();
|
||||
auto b1 = b.allocVariant();
|
||||
|
||||
swap(a, b);
|
||||
|
||||
REQUIRE(a1.ptr() == b.getVariant(a1.id()));
|
||||
REQUIRE(b1.ptr() == a.getVariant(b1.id()));
|
||||
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofPool()) * 2,
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("Only left using preallocated pool list") {
|
||||
SpyingAllocator spy;
|
||||
ResourceManager a(&spy);
|
||||
ResourceManager b(&spy);
|
||||
fullPreallocatedPools(b);
|
||||
|
||||
auto a1 = a.allocVariant();
|
||||
auto b1 = b.allocVariant();
|
||||
swap(a, b);
|
||||
|
||||
REQUIRE(a1.ptr() == b.getVariant(a1.id()));
|
||||
REQUIRE(b1.ptr() == a.getVariant(b1.id()));
|
||||
|
||||
REQUIRE(spy.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofPool()) * (ARDUINOJSON_INITIAL_POOL_COUNT + 1),
|
||||
Allocate(sizeofPoolList(ARDUINOJSON_INITIAL_POOL_COUNT * 2)),
|
||||
Allocate(sizeofPool()),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("Only right using preallocated pool list") {
|
||||
SpyingAllocator spy;
|
||||
ResourceManager a(&spy);
|
||||
fullPreallocatedPools(a);
|
||||
ResourceManager b(&spy);
|
||||
|
||||
auto a1 = a.allocVariant();
|
||||
auto b1 = b.allocVariant();
|
||||
swap(a, b);
|
||||
|
||||
REQUIRE(a1.ptr() == b.getVariant(a1.id()));
|
||||
REQUIRE(b1.ptr() == a.getVariant(b1.id()));
|
||||
|
||||
REQUIRE(spy.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofPool()) * ARDUINOJSON_INITIAL_POOL_COUNT,
|
||||
Allocate(sizeofPoolList(ARDUINOJSON_INITIAL_POOL_COUNT * 2)),
|
||||
Allocate(sizeofPool()) * 2,
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("None is using preallocated pool list") {
|
||||
SpyingAllocator spy;
|
||||
ResourceManager a(&spy);
|
||||
fullPreallocatedPools(a);
|
||||
ResourceManager b(&spy);
|
||||
fullPreallocatedPools(b);
|
||||
|
||||
auto a1 = a.allocVariant();
|
||||
auto b1 = b.allocVariant();
|
||||
|
||||
swap(a, b);
|
||||
|
||||
REQUIRE(a1.ptr() == b.getVariant(a1.id()));
|
||||
REQUIRE(b1.ptr() == a.getVariant(b1.id()));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user