forked from bblanchon/ArduinoJson
Store the strings in the heap
This commit is contained in:
@ -5,11 +5,30 @@
|
||||
#include <ArduinoJson/StringStorage/StringCopier.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
TEST_CASE("StringCopier") {
|
||||
SECTION("Works when buffer is big enough") {
|
||||
MemoryPool pool(addPadding(sizeofString(5)));
|
||||
ControllableAllocator controllableAllocator;
|
||||
SpyingAllocator spyingAllocator(&controllableAllocator);
|
||||
MemoryPool pool(0, &spyingAllocator);
|
||||
|
||||
SECTION("Empty string") {
|
||||
StringCopier str(&pool);
|
||||
|
||||
str.startString();
|
||||
str.save();
|
||||
|
||||
REQUIRE(pool.size() == sizeofString(0));
|
||||
REQUIRE(pool.overflowed() == false);
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofString(31))
|
||||
<< AllocatorLog::Reallocate(sizeofString(31),
|
||||
sizeofString(0)));
|
||||
}
|
||||
|
||||
SECTION("Short string fits in first allocation") {
|
||||
StringCopier str(&pool);
|
||||
|
||||
str.startString();
|
||||
@ -18,38 +37,60 @@ TEST_CASE("StringCopier") {
|
||||
REQUIRE(str.isValid() == true);
|
||||
REQUIRE(str.str() == "hello");
|
||||
REQUIRE(pool.overflowed() == false);
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofString(31)));
|
||||
}
|
||||
|
||||
SECTION("Returns null when too small") {
|
||||
MemoryPool pool(sizeof(void*));
|
||||
SECTION("Long string needs reallocation") {
|
||||
StringCopier str(&pool);
|
||||
|
||||
str.startString();
|
||||
str.append("hello world!");
|
||||
str.append(
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do "
|
||||
"eiusmod tempor incididunt ut labore et dolore magna aliqua.");
|
||||
|
||||
REQUIRE(str.isValid() == false);
|
||||
REQUIRE(pool.overflowed() == true);
|
||||
}
|
||||
|
||||
SECTION("Increases size of memory pool") {
|
||||
MemoryPool pool(addPadding(sizeofString(6)));
|
||||
StringCopier str(&pool);
|
||||
|
||||
str.startString();
|
||||
str.save();
|
||||
|
||||
REQUIRE(1 == pool.size());
|
||||
REQUIRE(str.isValid() == true);
|
||||
REQUIRE(str.str() ==
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do "
|
||||
"eiusmod tempor incididunt ut labore et dolore magna aliqua.");
|
||||
REQUIRE(pool.overflowed() == false);
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::Allocate(sizeofString(31))
|
||||
<< AllocatorLog::Reallocate(sizeofString(31),
|
||||
sizeofString(63))
|
||||
<< AllocatorLog::Reallocate(sizeofString(63),
|
||||
sizeofString(127)));
|
||||
}
|
||||
|
||||
SECTION("Works when memory pool is 0 bytes") {
|
||||
MemoryPool pool(0);
|
||||
SECTION("Realloc fails") {
|
||||
StringCopier str(&pool);
|
||||
|
||||
str.startString();
|
||||
controllableAllocator.disable();
|
||||
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() << AllocatorLog::Allocate(sizeofString(31))
|
||||
<< AllocatorLog::ReallocateFail(sizeofString(31),
|
||||
sizeofString(63))
|
||||
<< AllocatorLog::Deallocate(sizeofString(31)));
|
||||
REQUIRE(str.isValid() == false);
|
||||
REQUIRE(pool.overflowed() == true);
|
||||
}
|
||||
|
||||
SECTION("Initial allocation fails") {
|
||||
StringCopier str(&pool);
|
||||
|
||||
controllableAllocator.disable();
|
||||
str.startString();
|
||||
|
||||
REQUIRE(str.isValid() == false);
|
||||
REQUIRE(pool.overflowed() == true);
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog() << AllocatorLog::AllocateFail(sizeofString(31)));
|
||||
}
|
||||
}
|
||||
|
||||
static const char* addStringToPool(MemoryPool& pool, const char* s) {
|
||||
|
@ -39,13 +39,6 @@ TEST_CASE("MemoryPool::saveString()") {
|
||||
const char* a = saveString(pool, "hello\0world", 11);
|
||||
const char* b = saveString(pool, "hello\0world", 11);
|
||||
REQUIRE(a == b);
|
||||
}
|
||||
|
||||
SECTION("Reuse part of a string if it ends with NUL") {
|
||||
const char* a = saveString(pool, "hello\0world", 11);
|
||||
const char* b = saveString(pool, "hello");
|
||||
REQUIRE(a == b);
|
||||
REQUIRE(pool.size() == 12);
|
||||
REQUIRE(pool.size() == sizeofString(11));
|
||||
}
|
||||
|
||||
@ -56,52 +49,8 @@ TEST_CASE("MemoryPool::saveString()") {
|
||||
REQUIRE(pool.size() == sizeofString(5) + sizeofString(11));
|
||||
}
|
||||
|
||||
SECTION("Returns NULL when full") {
|
||||
REQUIRE(pool.capacity() == 32);
|
||||
|
||||
const void* p1 = saveString(pool, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
REQUIRE(p1 != 0);
|
||||
REQUIRE(pool.size() == 32);
|
||||
|
||||
const void* p2 = saveString(pool, "b");
|
||||
REQUIRE(p2 == 0);
|
||||
}
|
||||
|
||||
SECTION("Returns NULL when pool is too small") {
|
||||
const void* p = saveString(pool, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
REQUIRE(0 == p);
|
||||
}
|
||||
|
||||
SECTION("Returns NULL when buffer is NULL") {
|
||||
SECTION("Returns NULL when allocation fails") {
|
||||
MemoryPool pool2(32, FailingAllocator::instance());
|
||||
REQUIRE(0 == saveString(pool2, "a"));
|
||||
}
|
||||
|
||||
SECTION("Returns NULL when capacity is 0") {
|
||||
MemoryPool pool2(0);
|
||||
REQUIRE(0 == saveString(pool2, "a"));
|
||||
}
|
||||
|
||||
SECTION("Returns same address after clear()") {
|
||||
const void* a = saveString(pool, "hello");
|
||||
pool.clear();
|
||||
const void* b = saveString(pool, "world");
|
||||
|
||||
REQUIRE(a == b);
|
||||
}
|
||||
|
||||
SECTION("Can use full capacity when fresh") {
|
||||
const void* a = saveString(pool, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
|
||||
REQUIRE(a != 0);
|
||||
}
|
||||
|
||||
SECTION("Can use full capacity after clear") {
|
||||
saveString(pool, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
|
||||
pool.clear();
|
||||
|
||||
const void* a = saveString(pool, "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
|
||||
|
||||
REQUIRE(a != 0);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user