Update deps (#482)
This commit is contained in:
@@ -16,9 +16,10 @@ endif()
|
||||
|
||||
add_executable(DeprecatedTests
|
||||
add.cpp
|
||||
BasicJsonDocument.cpp
|
||||
containsKey.cpp
|
||||
createNestedArray.cpp
|
||||
createNestedObject.cpp
|
||||
BasicJsonDocument.cpp
|
||||
DynamicJsonDocument.cpp
|
||||
macros.cpp
|
||||
memoryUsage.cpp
|
||||
|
||||
210
lib/ArduinoJson/extras/tests/Deprecated/containsKey.cpp
Normal file
210
lib/ArduinoJson/extras/tests/Deprecated/containsKey.cpp
Normal file
@@ -0,0 +1,210 @@
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::containsKey()") {
|
||||
JsonDocument doc;
|
||||
auto mp = doc["hello"];
|
||||
|
||||
SECTION("containsKey(const char*)") {
|
||||
mp["key"] = "value";
|
||||
|
||||
REQUIRE(mp.containsKey("key") == true);
|
||||
REQUIRE(mp.containsKey("key") == true);
|
||||
}
|
||||
|
||||
SECTION("containsKey(std::string)") {
|
||||
mp["key"] = "value";
|
||||
|
||||
REQUIRE(mp.containsKey("key"_s) == true);
|
||||
REQUIRE(mp.containsKey("key"_s) == true);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JsonObject::containsKey()") {
|
||||
JsonDocument doc;
|
||||
JsonObject obj = doc.to<JsonObject>();
|
||||
obj["hello"] = 42;
|
||||
|
||||
SECTION("returns true only if key is present") {
|
||||
REQUIRE(false == obj.containsKey("world"));
|
||||
REQUIRE(true == obj.containsKey("hello"));
|
||||
}
|
||||
|
||||
SECTION("returns false after remove()") {
|
||||
obj.remove("hello");
|
||||
|
||||
REQUIRE(false == obj.containsKey("hello"));
|
||||
}
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("key is a VLA") {
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "hello");
|
||||
|
||||
REQUIRE(true == obj.containsKey(vla));
|
||||
}
|
||||
#endif
|
||||
|
||||
SECTION("key is a JsonVariant") {
|
||||
doc["key"] = "hello";
|
||||
REQUIRE(true == obj.containsKey(obj["key"]));
|
||||
REQUIRE(false == obj.containsKey(obj["hello"]));
|
||||
}
|
||||
|
||||
SECTION("std::string") {
|
||||
REQUIRE(true == obj.containsKey("hello"_s));
|
||||
}
|
||||
|
||||
SECTION("unsigned char[]") {
|
||||
unsigned char key[] = "hello";
|
||||
REQUIRE(true == obj.containsKey(key));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JsonObjectConst::containsKey()") {
|
||||
JsonDocument doc;
|
||||
doc["hello"] = 42;
|
||||
auto obj = doc.as<JsonObjectConst>();
|
||||
|
||||
SECTION("supports const char*") {
|
||||
REQUIRE(false == obj.containsKey("world"));
|
||||
REQUIRE(true == obj.containsKey("hello"));
|
||||
}
|
||||
|
||||
SECTION("supports std::string") {
|
||||
REQUIRE(false == obj.containsKey("world"_s));
|
||||
REQUIRE(true == obj.containsKey("hello"_s));
|
||||
}
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("supports VLA") {
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "hello");
|
||||
|
||||
REQUIRE(true == obj.containsKey(vla));
|
||||
}
|
||||
#endif
|
||||
|
||||
SECTION("supports JsonVariant") {
|
||||
doc["key"] = "hello";
|
||||
REQUIRE(true == obj.containsKey(obj["key"]));
|
||||
REQUIRE(false == obj.containsKey(obj["hello"]));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JsonVariant::containsKey()") {
|
||||
JsonDocument doc;
|
||||
JsonVariant var = doc.to<JsonVariant>();
|
||||
|
||||
SECTION("returns false is unbound") {
|
||||
CHECK_FALSE(JsonVariant().containsKey("hello"));
|
||||
}
|
||||
|
||||
SECTION("containsKey(const char*)") {
|
||||
var["hello"] = "world";
|
||||
|
||||
REQUIRE(var.containsKey("hello") == true);
|
||||
REQUIRE(var.containsKey("world") == false);
|
||||
}
|
||||
|
||||
SECTION("containsKey(std::string)") {
|
||||
var["hello"] = "world";
|
||||
|
||||
REQUIRE(var.containsKey("hello"_s) == true);
|
||||
REQUIRE(var.containsKey("world"_s) == false);
|
||||
}
|
||||
|
||||
SECTION("containsKey(JsonVariant)") {
|
||||
var["hello"] = "world";
|
||||
var["key"] = "hello";
|
||||
|
||||
REQUIRE(var.containsKey(doc["key"]) == true);
|
||||
REQUIRE(var.containsKey(doc["foo"]) == false);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JsonVariantConst::containsKey()") {
|
||||
JsonDocument doc;
|
||||
doc["hello"] = "world";
|
||||
JsonVariantConst var = doc.as<JsonVariant>();
|
||||
|
||||
SECTION("support const char*") {
|
||||
REQUIRE(var.containsKey("hello") == true);
|
||||
REQUIRE(var.containsKey("world") == false);
|
||||
}
|
||||
|
||||
SECTION("support std::string") {
|
||||
REQUIRE(var.containsKey("hello"_s) == true);
|
||||
REQUIRE(var.containsKey("world"_s) == false);
|
||||
}
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("supports VLA") {
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "hello");
|
||||
|
||||
REQUIRE(true == var.containsKey(vla));
|
||||
}
|
||||
#endif
|
||||
|
||||
SECTION("support JsonVariant") {
|
||||
doc["key"] = "hello";
|
||||
REQUIRE(var.containsKey(var["key"]) == true);
|
||||
REQUIRE(var.containsKey(var["foo"]) == false);
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Memory/Allocator.hpp>
|
||||
#include <ArduinoJson/Memory/MemoryPool.hpp>
|
||||
#include <ArduinoJson/Memory/StringBuilder.hpp>
|
||||
#include <ArduinoJson/Memory/VariantPool.hpp>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
@@ -265,12 +265,14 @@ class TimebombAllocator : public ArduinoJson::Allocator {
|
||||
} // namespace
|
||||
|
||||
inline size_t sizeofPoolList(size_t n = ARDUINOJSON_INITIAL_POOL_COUNT) {
|
||||
return sizeof(ArduinoJson::detail::VariantPool) * n;
|
||||
using namespace ArduinoJson::detail;
|
||||
return sizeof(MemoryPool<VariantData>) * n;
|
||||
}
|
||||
|
||||
inline size_t sizeofPool(
|
||||
ArduinoJson::detail::SlotCount n = ARDUINOJSON_POOL_CAPACITY) {
|
||||
return ArduinoJson::detail::VariantPool::slotsToBytes(n);
|
||||
using namespace ArduinoJson::detail;
|
||||
return MemoryPool<VariantData>::slotsToBytes(n);
|
||||
}
|
||||
|
||||
inline size_t sizeofStringBuffer(size_t iteration = 1) {
|
||||
|
||||
@@ -68,6 +68,12 @@ TEST_CASE("JsonArray::remove()") {
|
||||
REQUIRE(array[1] == 2);
|
||||
}
|
||||
|
||||
SECTION("remove end()") {
|
||||
array.remove(array.end());
|
||||
|
||||
REQUIRE(3 == array.size());
|
||||
}
|
||||
|
||||
SECTION("In a loop") {
|
||||
for (JsonArray::iterator it = array.begin(); it != array.end(); ++it) {
|
||||
if (*it == 2)
|
||||
|
||||
@@ -69,14 +69,32 @@ TEST_CASE("deserialize JSON array") {
|
||||
REQUIRE(arr[1] == 84);
|
||||
}
|
||||
|
||||
SECTION("Double") {
|
||||
SECTION("Float") {
|
||||
DeserializationError err = deserializeJson(doc, "[4.2,1e2]");
|
||||
JsonArray arr = doc.as<JsonArray>();
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
REQUIRE(2 == arr.size());
|
||||
REQUIRE(arr[0] == 4.2);
|
||||
REQUIRE(arr[1] == 1e2);
|
||||
REQUIRE(arr[0].as<float>() == Approx(4.2f));
|
||||
REQUIRE(arr[1] == 1e2f);
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofPool()),
|
||||
Reallocate(sizeofPool(), sizeofPool(2)),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("Double") {
|
||||
DeserializationError err = deserializeJson(doc, "[4.2123456,-7E89]");
|
||||
JsonArray arr = doc.as<JsonArray>();
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
REQUIRE(2 == arr.size());
|
||||
REQUIRE(arr[0].as<double>() == Approx(4.2123456));
|
||||
REQUIRE(arr[1] == -7E89);
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofPool()),
|
||||
Reallocate(sizeofPool(), sizeofPool(4)),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("Unsigned long") {
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
TEST_CASE("deserializeJson() returns IncompleteInput") {
|
||||
const char* testCases[] = {
|
||||
// strings
|
||||
@@ -118,3 +120,43 @@ TEST_CASE("deserializeJson() returns NoMemory if string length overflows") {
|
||||
REQUIRE(err == DeserializationError::NoMemory);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("deserializeJson() returns NoMemory if extension allocation fails") {
|
||||
JsonDocument doc(FailingAllocator::instance());
|
||||
|
||||
SECTION("uint32_t should pass") {
|
||||
auto err = deserializeJson(doc, "4294967295");
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
}
|
||||
|
||||
SECTION("uint64_t should fail") {
|
||||
auto err = deserializeJson(doc, "18446744073709551615");
|
||||
|
||||
REQUIRE(err == DeserializationError::NoMemory);
|
||||
}
|
||||
|
||||
SECTION("int32_t should pass") {
|
||||
auto err = deserializeJson(doc, "-2147483648");
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
}
|
||||
|
||||
SECTION("int64_t should fail") {
|
||||
auto err = deserializeJson(doc, "-9223372036854775808");
|
||||
|
||||
REQUIRE(err == DeserializationError::NoMemory);
|
||||
}
|
||||
|
||||
SECTION("float should pass") {
|
||||
auto err = deserializeJson(doc, "3.402823e38");
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
}
|
||||
|
||||
SECTION("double should fail") {
|
||||
auto err = deserializeJson(doc, "1.7976931348623157e308");
|
||||
|
||||
REQUIRE(err == DeserializationError::NoMemory);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,15 +155,27 @@ TEST_CASE("deserialize JSON object") {
|
||||
REQUIRE(obj["key2"] == -42);
|
||||
}
|
||||
|
||||
SECTION("Double") {
|
||||
SECTION("Float") {
|
||||
DeserializationError err =
|
||||
deserializeJson(doc, "{\"key1\":12.345,\"key2\":-7E89}");
|
||||
deserializeJson(doc, "{\"key1\":12.345,\"key2\":-7E3}");
|
||||
JsonObject obj = doc.as<JsonObject>();
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
REQUIRE(doc.is<JsonObject>());
|
||||
REQUIRE(obj.size() == 2);
|
||||
REQUIRE(obj["key1"] == 12.345);
|
||||
REQUIRE(obj["key1"].as<float>() == Approx(12.345f));
|
||||
REQUIRE(obj["key2"] == -7E3f);
|
||||
}
|
||||
|
||||
SECTION("Double") {
|
||||
DeserializationError err =
|
||||
deserializeJson(doc, "{\"key1\":12.3456789,\"key2\":-7E89}");
|
||||
JsonObject obj = doc.as<JsonObject>();
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
REQUIRE(doc.is<JsonObject>());
|
||||
REQUIRE(obj.size() == 2);
|
||||
REQUIRE(obj["key1"].as<double>() == Approx(12.3456789));
|
||||
REQUIRE(obj["key2"] == -7E89);
|
||||
}
|
||||
|
||||
@@ -308,12 +320,12 @@ TEST_CASE("deserialize JSON object") {
|
||||
REQUIRE(doc["a"] == 2);
|
||||
}
|
||||
|
||||
SECTION("NUL in keys") { // we don't support NULs in keys
|
||||
SECTION("NUL in keys") {
|
||||
DeserializationError err =
|
||||
deserializeJson(doc, "{\"x\\u0000a\":1,\"x\\u0000b\":2}");
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
REQUIRE(doc.as<std::string>() == "{\"x\":2}");
|
||||
REQUIRE(doc.as<std::string>() == "{\"x\\u0000a\":1,\"x\\u0000b\":2}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +83,22 @@ TEST_CASE("Truncated JSON string") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Escape single quote in single quoted string") {
|
||||
JsonDocument doc;
|
||||
|
||||
DeserializationError err = deserializeJson(doc, "'ab\\\'cd'");
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
CHECK(doc.as<std::string>() == "ab\'cd");
|
||||
}
|
||||
|
||||
TEST_CASE("Escape double quote in double quoted string") {
|
||||
JsonDocument doc;
|
||||
|
||||
DeserializationError err = deserializeJson(doc, "'ab\\\"cd'");
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
CHECK(doc.as<std::string>() == "ab\"cd");
|
||||
}
|
||||
|
||||
TEST_CASE("Invalid JSON string") {
|
||||
const char* testCases[] = {"'\\u'", "'\\u000g'", "'\\u000'",
|
||||
"'\\u000G'", "'\\u000/'", "'\\x1234'"};
|
||||
|
||||
@@ -9,7 +9,6 @@ add_executable(JsonDocumentTests
|
||||
clear.cpp
|
||||
compare.cpp
|
||||
constructor.cpp
|
||||
containsKey.cpp
|
||||
ElementProxy.cpp
|
||||
isNull.cpp
|
||||
issue1120.cpp
|
||||
|
||||
@@ -93,25 +93,6 @@ TEST_CASE("MemberProxy::operator==()") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::containsKey()") {
|
||||
JsonDocument doc;
|
||||
MemberProxy mp = doc["hello"];
|
||||
|
||||
SECTION("containsKey(const char*)") {
|
||||
mp["key"] = "value";
|
||||
|
||||
REQUIRE(mp.containsKey("key") == true);
|
||||
REQUIRE(mp.containsKey("key") == true);
|
||||
}
|
||||
|
||||
SECTION("containsKey(std::string)") {
|
||||
mp["key"] = "value";
|
||||
|
||||
REQUIRE(mp.containsKey("key"_s) == true);
|
||||
REQUIRE(mp.containsKey("key"_s) == true);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::operator|()") {
|
||||
JsonDocument doc;
|
||||
|
||||
@@ -345,12 +326,12 @@ TEST_CASE("Deduplicate keys") {
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy under memory constraints") {
|
||||
KillswitchAllocator killswitch;
|
||||
SpyingAllocator spy(&killswitch);
|
||||
TimebombAllocator timebomb(1);
|
||||
SpyingAllocator spy(&timebomb);
|
||||
JsonDocument doc(&spy);
|
||||
|
||||
SECTION("key allocation fails") {
|
||||
killswitch.on();
|
||||
SECTION("key slot allocation fails") {
|
||||
timebomb.setCountdown(0);
|
||||
|
||||
doc["hello"_s] = "world";
|
||||
|
||||
@@ -358,6 +339,38 @@ TEST_CASE("MemberProxy under memory constraints") {
|
||||
REQUIRE(doc.size() == 0);
|
||||
REQUIRE(doc.overflowed() == true);
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
AllocateFail(sizeofPool()),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("value slot allocation fails") {
|
||||
timebomb.setCountdown(1);
|
||||
|
||||
// fill the pool entirely, but leave one slot for the key
|
||||
doc["foo"][ARDUINOJSON_POOL_CAPACITY - 4] = 1;
|
||||
REQUIRE(doc.overflowed() == false);
|
||||
|
||||
doc["hello"_s] = "world";
|
||||
|
||||
REQUIRE(doc.is<JsonObject>());
|
||||
REQUIRE(doc.size() == 1);
|
||||
REQUIRE(doc.overflowed() == true);
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofPool()),
|
||||
AllocateFail(sizeofPool()),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("key string allocation fails") {
|
||||
timebomb.setCountdown(1);
|
||||
|
||||
doc["hello"_s] = "world";
|
||||
|
||||
REQUIRE(doc.is<JsonObject>());
|
||||
REQUIRE(doc.size() == 0);
|
||||
REQUIRE(doc.overflowed() == true);
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofPool()),
|
||||
AllocateFail(sizeofString("hello")),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ TEST_CASE("JsonDocument assignment") {
|
||||
REQUIRE(doc2.as<std::string>() == "{\"hello\":\"world\"}");
|
||||
|
||||
REQUIRE(spyingAllocator.log() == AllocatorLog{
|
||||
Allocate(sizeofString("hello")),
|
||||
Allocate(sizeofPool()),
|
||||
Allocate(sizeofString("hello")),
|
||||
Allocate(sizeofString("world")),
|
||||
});
|
||||
}
|
||||
@@ -54,8 +54,8 @@ TEST_CASE("JsonDocument assignment") {
|
||||
|
||||
REQUIRE(doc2.as<std::string>() == "{\"hello\":\"world\"}");
|
||||
REQUIRE(spyingAllocator.log() == AllocatorLog{
|
||||
Allocate(sizeofString("hello")),
|
||||
Allocate(sizeofPool()),
|
||||
Allocate(sizeofString("hello")),
|
||||
Allocate(sizeofString("world")),
|
||||
});
|
||||
}
|
||||
@@ -72,8 +72,8 @@ TEST_CASE("JsonDocument assignment") {
|
||||
REQUIRE(doc1.as<std::string>() == "null");
|
||||
}
|
||||
REQUIRE(spyingAllocator.log() == AllocatorLog{
|
||||
Allocate(sizeofString("hello")),
|
||||
Allocate(sizeofPool()),
|
||||
Allocate(sizeofString("hello")),
|
||||
Allocate(sizeofString("world")),
|
||||
Deallocate(sizeofString("hello")),
|
||||
Deallocate(sizeofString("world")),
|
||||
|
||||
@@ -122,8 +122,8 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
|
||||
REQUIRE(doc.as<std::string>() == "{\"abcdefg\":42}");
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofString("abcdefg")),
|
||||
Allocate(sizeofPool()),
|
||||
Allocate(sizeofString("abcdefg")),
|
||||
Reallocate(sizeofPool(), sizeofObject(1)),
|
||||
});
|
||||
}
|
||||
@@ -178,7 +178,7 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
|
||||
AllocatorLog{
|
||||
Allocate(sizeofPool()),
|
||||
Allocate(sizeofString("abcdefg")),
|
||||
Reallocate(sizeofPool(), sizeofPool(1)),
|
||||
Reallocate(sizeofPool(), sizeofPool(2)),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
add_executable(JsonObjectTests
|
||||
clear.cpp
|
||||
compare.cpp
|
||||
containsKey.cpp
|
||||
equals.cpp
|
||||
isNull.cpp
|
||||
iterator.cpp
|
||||
|
||||
@@ -52,8 +52,8 @@ TEST_CASE("JsonObject::set()") {
|
||||
REQUIRE(success == true);
|
||||
REQUIRE(obj2["hello"] == "world"_s);
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofString("hello")),
|
||||
Allocate(sizeofPool()),
|
||||
Allocate(sizeofString("hello")),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -66,8 +66,8 @@ TEST_CASE("JsonObject::set()") {
|
||||
REQUIRE(success == true);
|
||||
REQUIRE(obj2["hello"] == "world"_s);
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofString("hello")),
|
||||
Allocate(sizeofPool()),
|
||||
Allocate(sizeofString("hello")),
|
||||
Allocate(sizeofString("world")),
|
||||
});
|
||||
}
|
||||
@@ -81,8 +81,8 @@ TEST_CASE("JsonObject::set()") {
|
||||
REQUIRE(success == true);
|
||||
REQUIRE(obj2["hello"] == "world"_s);
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofString("hello")),
|
||||
Allocate(sizeofPool()),
|
||||
Allocate(sizeofString("hello")),
|
||||
Allocate(sizeofString("world")),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -34,13 +34,6 @@ TEST_CASE("std::string") {
|
||||
REQUIRE("value"_s == obj["key"_s]);
|
||||
}
|
||||
|
||||
SECTION("containsKey()") {
|
||||
char json[] = "{\"key\":\"value\"}";
|
||||
deserializeJson(doc, json);
|
||||
JsonObject obj = doc.as<JsonObject>();
|
||||
REQUIRE(true == obj.containsKey("key"_s));
|
||||
}
|
||||
|
||||
SECTION("remove()") {
|
||||
JsonObject obj = doc.to<JsonObject>();
|
||||
obj["key"] = "value";
|
||||
|
||||
@@ -118,16 +118,16 @@ TEST_CASE("JsonObject::operator[]") {
|
||||
SECTION("should duplicate char* key") {
|
||||
obj[const_cast<char*>("hello")] = "world";
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofString("hello")),
|
||||
Allocate(sizeofPool()),
|
||||
Allocate(sizeofString("hello")),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("should duplicate char* key&value") {
|
||||
obj[const_cast<char*>("hello")] = const_cast<char*>("world");
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofString("hello")),
|
||||
Allocate(sizeofPool()),
|
||||
Allocate(sizeofString("hello")),
|
||||
Allocate(sizeofString("world")),
|
||||
});
|
||||
}
|
||||
@@ -143,16 +143,16 @@ TEST_CASE("JsonObject::operator[]") {
|
||||
SECTION("should duplicate std::string key") {
|
||||
obj["hello"_s] = "world";
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofString("hello")),
|
||||
Allocate(sizeofPool()),
|
||||
Allocate(sizeofString("hello")),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("should duplicate std::string key&value") {
|
||||
obj["hello"_s] = "world"_s;
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofString("hello")),
|
||||
Allocate(sizeofPool()),
|
||||
Allocate(sizeofString("hello")),
|
||||
Allocate(sizeofString("world")),
|
||||
});
|
||||
}
|
||||
@@ -160,8 +160,8 @@ TEST_CASE("JsonObject::operator[]") {
|
||||
SECTION("should duplicate a non-static JsonString key") {
|
||||
obj[JsonString("hello", JsonString::Copied)] = "world";
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofString("hello")),
|
||||
Allocate(sizeofPool()),
|
||||
Allocate(sizeofString("hello")),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
# MIT License
|
||||
|
||||
add_executable(JsonObjectConstTests
|
||||
containsKey.cpp
|
||||
equals.cpp
|
||||
isNull.cpp
|
||||
iterator.cpp
|
||||
|
||||
@@ -46,6 +46,10 @@ TEST_CASE("serializeJson(JsonVariant)") {
|
||||
check("fifty/fifty"_s, "\"fifty/fifty\"");
|
||||
}
|
||||
|
||||
SECTION("Don't escape single quote") {
|
||||
check("hello'world"_s, "\"hello'world\"");
|
||||
}
|
||||
|
||||
SECTION("Escape backspace") {
|
||||
check("hello\bworld"_s, "\"hello\\bworld\"");
|
||||
}
|
||||
@@ -83,6 +87,11 @@ TEST_CASE("serializeJson(JsonVariant)") {
|
||||
check(3.1415927, "3.1415927");
|
||||
}
|
||||
|
||||
SECTION("Float") {
|
||||
REQUIRE(sizeof(float) == 4);
|
||||
check(3.1415927f, "3.141593");
|
||||
}
|
||||
|
||||
SECTION("Zero") {
|
||||
check(0, "0");
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ add_executable(JsonVariantTests
|
||||
as.cpp
|
||||
clear.cpp
|
||||
compare.cpp
|
||||
containsKey.cpp
|
||||
converters.cpp
|
||||
copy.cpp
|
||||
is.cpp
|
||||
|
||||
@@ -31,13 +31,28 @@ TEST_CASE("JsonVariant::as()") {
|
||||
REQUIRE(variant.as<MsgPackExtension>().data() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("set(4.2)") {
|
||||
SECTION("set(float)") {
|
||||
variant.set(4.2f);
|
||||
|
||||
REQUIRE(variant.as<bool>());
|
||||
REQUIRE(0 == variant.as<const char*>());
|
||||
REQUIRE(variant.as<std::string>() == "4.2");
|
||||
REQUIRE(variant.as<long>() == 4L);
|
||||
REQUIRE(variant.as<float>() == 4.2f);
|
||||
REQUIRE(variant.as<unsigned>() == 4U);
|
||||
REQUIRE(variant.as<JsonString>().isNull());
|
||||
REQUIRE(variant.as<MsgPackBinary>().data() == nullptr);
|
||||
REQUIRE(variant.as<MsgPackExtension>().data() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("set(double)") {
|
||||
variant.set(4.2);
|
||||
|
||||
REQUIRE(variant.as<bool>());
|
||||
REQUIRE(0 == variant.as<const char*>());
|
||||
REQUIRE(variant.as<std::string>() == "4.2");
|
||||
REQUIRE(variant.as<long>() == 4L);
|
||||
REQUIRE(variant.as<double>() == 4.2);
|
||||
REQUIRE(variant.as<unsigned>() == 4U);
|
||||
REQUIRE(variant.as<JsonString>().isNull());
|
||||
REQUIRE(variant.as<MsgPackBinary>().data() == nullptr);
|
||||
@@ -78,43 +93,62 @@ TEST_CASE("JsonVariant::as()") {
|
||||
REQUIRE(variant.as<MsgPackExtension>().data() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("set(42)") {
|
||||
variant.set(42);
|
||||
SECTION("set(uint32_t)") {
|
||||
variant.set(4294967295U);
|
||||
|
||||
REQUIRE(variant.as<bool>() == true);
|
||||
REQUIRE(variant.as<double>() == 42.0);
|
||||
REQUIRE(variant.as<int>() == 42);
|
||||
REQUIRE(variant.as<unsigned int>() == 42U); // issue #1601
|
||||
REQUIRE(variant.as<std::string>() == "42");
|
||||
REQUIRE(variant.as<double>() == 4294967295.0);
|
||||
REQUIRE(variant.as<int32_t>() == 0);
|
||||
REQUIRE(variant.as<uint32_t>() == 4294967295U);
|
||||
REQUIRE(variant.as<uint64_t>() == 4294967295U);
|
||||
REQUIRE(variant.as<std::string>() == "4294967295");
|
||||
REQUIRE(variant.as<JsonString>().isNull());
|
||||
REQUIRE(variant.as<MsgPackBinary>().data() == nullptr);
|
||||
REQUIRE(variant.as<MsgPackExtension>().data() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("set(42L)") {
|
||||
variant.set(42L);
|
||||
SECTION("set(int32_t)") {
|
||||
variant.set(-2147483648LL);
|
||||
|
||||
REQUIRE(variant.as<bool>() == true);
|
||||
REQUIRE(variant.as<double>() == 42.0);
|
||||
REQUIRE(variant.as<std::string>() == "42");
|
||||
REQUIRE(variant.as<double>() == -2147483648LL);
|
||||
REQUIRE(variant.as<int32_t>() == -2147483648LL);
|
||||
REQUIRE(variant.as<int64_t>() == -2147483648LL);
|
||||
REQUIRE(variant.as<uint32_t>() == 0);
|
||||
REQUIRE(variant.as<uint64_t>() == 0);
|
||||
REQUIRE(variant.as<std::string>() == "-2147483648");
|
||||
REQUIRE(variant.as<JsonString>().isNull());
|
||||
REQUIRE(variant.as<MsgPackBinary>().data() == nullptr);
|
||||
REQUIRE(variant.as<MsgPackExtension>().data() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("set(-42L)") {
|
||||
variant.set(-42L);
|
||||
|
||||
REQUIRE(variant.as<double>() == -42.0);
|
||||
REQUIRE(variant.as<std::string>() == "-42");
|
||||
REQUIRE(variant.as<JsonString>().isNull());
|
||||
}
|
||||
|
||||
SECTION("set(42UL)") {
|
||||
variant.set(42UL);
|
||||
SECTION("set(uint64_t)") {
|
||||
variant.set(4294967296U);
|
||||
|
||||
REQUIRE(variant.as<bool>() == true);
|
||||
REQUIRE(variant.as<double>() == 42.0);
|
||||
REQUIRE(variant.as<std::string>() == "42");
|
||||
REQUIRE(variant.as<double>() == 4294967296.0);
|
||||
REQUIRE(variant.as<int32_t>() == 0);
|
||||
REQUIRE(variant.as<uint32_t>() == 0);
|
||||
REQUIRE(variant.as<uint64_t>() == 4294967296U);
|
||||
REQUIRE(variant.as<std::string>() == "4294967296");
|
||||
REQUIRE(variant.as<JsonString>().isNull());
|
||||
REQUIRE(variant.as<MsgPackBinary>().data() == nullptr);
|
||||
REQUIRE(variant.as<MsgPackExtension>().data() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("set(int64_t)") {
|
||||
variant.set(-2147483649LL);
|
||||
|
||||
REQUIRE(variant.as<bool>() == true);
|
||||
REQUIRE(variant.as<double>() == -2147483649LL);
|
||||
REQUIRE(variant.as<int32_t>() == 0);
|
||||
REQUIRE(variant.as<int64_t>() == -2147483649LL);
|
||||
REQUIRE(variant.as<uint32_t>() == 0);
|
||||
REQUIRE(variant.as<uint64_t>() == 0);
|
||||
REQUIRE(variant.as<std::string>() == "-2147483649");
|
||||
REQUIRE(variant.as<JsonString>().isNull());
|
||||
REQUIRE(variant.as<MsgPackBinary>().data() == nullptr);
|
||||
REQUIRE(variant.as<MsgPackExtension>().data() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("set(0L)") {
|
||||
@@ -169,7 +203,7 @@ TEST_CASE("JsonVariant::as()") {
|
||||
|
||||
REQUIRE(variant.as<bool>() == true);
|
||||
REQUIRE(variant.as<long>() == 4L);
|
||||
REQUIRE(variant.as<double>() == 4.2);
|
||||
REQUIRE(variant.as<double>() == Approx(4.2));
|
||||
REQUIRE(variant.as<const char*>() == "4.2"_s);
|
||||
REQUIRE(variant.as<std::string>() == "4.2"_s);
|
||||
REQUIRE(variant.as<JsonString>() == "4.2");
|
||||
|
||||
@@ -13,7 +13,8 @@ using ArduinoJson::detail::sizeofObject;
|
||||
enum ErrorCode { ERROR_01 = 1, ERROR_10 = 10 };
|
||||
|
||||
TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
JsonDocument doc;
|
||||
SpyingAllocator spy;
|
||||
JsonDocument doc(&spy);
|
||||
JsonVariant variant = doc.to<JsonVariant>();
|
||||
|
||||
SECTION("const char*") {
|
||||
@@ -25,6 +26,7 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant == "world"); // stores by pointer
|
||||
REQUIRE(spy.log() == AllocatorLog{});
|
||||
}
|
||||
|
||||
SECTION("(const char*)0") {
|
||||
@@ -32,6 +34,7 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant.isNull());
|
||||
REQUIRE(spy.log() == AllocatorLog{});
|
||||
}
|
||||
|
||||
SECTION("char*") {
|
||||
@@ -43,6 +46,9 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant == "hello"); // stores by copy
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofString("hello")),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("(char*)0") {
|
||||
@@ -50,6 +56,7 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant.isNull());
|
||||
REQUIRE(spy.log() == AllocatorLog{});
|
||||
}
|
||||
|
||||
SECTION("unsigned char*") {
|
||||
@@ -61,6 +68,9 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant == "hello"); // stores by copy
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofString("hello")),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("signed char*") {
|
||||
@@ -72,6 +82,9 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant == "hello"); // stores by copy
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofString("hello")),
|
||||
});
|
||||
}
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
@@ -85,6 +98,9 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant == "hello"); // stores by copy
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofString("hello")),
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -97,6 +113,9 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant == "hello"); // stores by copy
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofString("hello")),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("static JsonString") {
|
||||
@@ -108,6 +127,7 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant == "world"); // stores by pointer
|
||||
REQUIRE(spy.log() == AllocatorLog{});
|
||||
}
|
||||
|
||||
SECTION("non-static JsonString") {
|
||||
@@ -119,6 +139,9 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant == "hello"); // stores by copy
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofString("hello")),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("enum") {
|
||||
@@ -129,6 +152,89 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant.is<int>() == true);
|
||||
REQUIRE(variant.as<int>() == 10);
|
||||
REQUIRE(spy.log() == AllocatorLog{});
|
||||
}
|
||||
|
||||
SECTION("float") {
|
||||
bool result = variant.set(1.2f);
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant.is<float>() == true);
|
||||
REQUIRE(variant.as<float>() == 1.2f);
|
||||
REQUIRE(spy.log() == AllocatorLog{});
|
||||
}
|
||||
|
||||
SECTION("double") {
|
||||
bool result = variant.set(1.2);
|
||||
doc.shrinkToFit();
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant.is<double>() == true);
|
||||
REQUIRE(variant.as<double>() == 1.2);
|
||||
REQUIRE(spy.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofPool()),
|
||||
Reallocate(sizeofPool(), sizeofPool(1)), // one extension slot
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("int32_t") {
|
||||
bool result = variant.set(int32_t(42));
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant.is<int32_t>() == true);
|
||||
REQUIRE(variant.as<int32_t>() == 42);
|
||||
REQUIRE(spy.log() == AllocatorLog{});
|
||||
}
|
||||
|
||||
SECTION("int64_t") {
|
||||
bool result = variant.set(int64_t(-2147483649LL));
|
||||
doc.shrinkToFit();
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant.is<int64_t>() == true);
|
||||
REQUIRE(variant.as<int64_t>() == -2147483649LL);
|
||||
REQUIRE(spy.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofPool()),
|
||||
Reallocate(sizeofPool(), sizeofPool(1)), // one extension slot
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("uint32_t") {
|
||||
bool result = variant.set(uint32_t(42));
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant.is<uint32_t>() == true);
|
||||
REQUIRE(variant.as<uint32_t>() == 42);
|
||||
REQUIRE(spy.log() == AllocatorLog{});
|
||||
}
|
||||
|
||||
SECTION("uint64_t") {
|
||||
bool result = variant.set(uint64_t(4294967296));
|
||||
doc.shrinkToFit();
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant.is<uint64_t>() == true);
|
||||
REQUIRE(variant.as<uint64_t>() == 4294967296);
|
||||
REQUIRE(spy.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofPool()),
|
||||
Reallocate(sizeofPool(), sizeofPool(1)), // one extension slot
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("JsonDocument") {
|
||||
JsonDocument doc1;
|
||||
doc1["hello"] = "world";
|
||||
|
||||
// Should copy the doc
|
||||
variant.set(doc1);
|
||||
doc1.clear();
|
||||
|
||||
std::string json;
|
||||
serializeJson(doc, json);
|
||||
REQUIRE(json == "{\"hello\":\"world\"}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,22 +264,48 @@ TEST_CASE("JsonVariant::set() with not enough memory") {
|
||||
REQUIRE(result == false);
|
||||
REQUIRE(v.isNull());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JsonVariant::set(JsonDocument)") {
|
||||
JsonDocument doc1;
|
||||
doc1["hello"] = "world";
|
||||
SECTION("float") {
|
||||
bool result = v.set(1.2f);
|
||||
|
||||
JsonDocument doc2;
|
||||
JsonVariant v = doc2.to<JsonVariant>();
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(v.is<float>());
|
||||
}
|
||||
|
||||
// Should copy the doc
|
||||
v.set(doc1);
|
||||
doc1.clear();
|
||||
SECTION("double") {
|
||||
bool result = v.set(1.2);
|
||||
|
||||
std::string json;
|
||||
serializeJson(doc2, json);
|
||||
REQUIRE(json == "{\"hello\":\"world\"}");
|
||||
REQUIRE(result == false);
|
||||
REQUIRE(v.isNull());
|
||||
}
|
||||
|
||||
SECTION("int32_t") {
|
||||
bool result = v.set(-42);
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(v.is<int32_t>());
|
||||
}
|
||||
|
||||
SECTION("int64_t") {
|
||||
bool result = v.set(-2147483649LL);
|
||||
|
||||
REQUIRE(result == false);
|
||||
REQUIRE(v.isNull());
|
||||
}
|
||||
|
||||
SECTION("uint32_t") {
|
||||
bool result = v.set(42);
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(v.is<uint32_t>());
|
||||
}
|
||||
|
||||
SECTION("uint64_t") {
|
||||
bool result = v.set(4294967296U);
|
||||
|
||||
REQUIRE(result == false);
|
||||
REQUIRE(v.isNull());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JsonVariant::set() releases the previous value") {
|
||||
@@ -220,3 +352,34 @@ TEST_CASE("JsonVariant::set() releases the previous value") {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JsonVariant::set() reuses extension slot") {
|
||||
SpyingAllocator spy;
|
||||
JsonDocument doc(&spy);
|
||||
JsonVariant variant = doc.to<JsonVariant>();
|
||||
|
||||
variant.set(1.2);
|
||||
doc.shrinkToFit();
|
||||
spy.clearLog();
|
||||
|
||||
SECTION("double") {
|
||||
bool result = variant.set(3.4);
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(spy.log() == AllocatorLog{});
|
||||
}
|
||||
|
||||
SECTION("int64_t") {
|
||||
bool result = variant.set(-2147483649LL);
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(spy.log() == AllocatorLog{});
|
||||
}
|
||||
|
||||
SECTION("uint64_t") {
|
||||
bool result = variant.set(4294967296U);
|
||||
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(spy.log() == AllocatorLog{});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,10 +73,6 @@ TEST_CASE("Unbound JsonVariant") {
|
||||
CHECK_FALSE(variant["key"_s].set(1));
|
||||
}
|
||||
|
||||
SECTION("containsKey()") {
|
||||
CHECK_FALSE(variant.containsKey("hello"));
|
||||
}
|
||||
|
||||
SECTION("remove()") {
|
||||
variant.remove(0);
|
||||
variant.remove("hello");
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
add_executable(JsonVariantConstTests
|
||||
as.cpp
|
||||
containsKey.cpp
|
||||
is.cpp
|
||||
isnull.cpp
|
||||
nesting.cpp
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
add_executable(MiscTests
|
||||
arithmeticCompare.cpp
|
||||
conflicts.cpp
|
||||
FloatParts.cpp
|
||||
issue1967.cpp
|
||||
JsonString.cpp
|
||||
NoArduinoHeader.cpp
|
||||
|
||||
@@ -176,15 +176,6 @@ TEST_CASE("unsigned char[]") {
|
||||
}
|
||||
#endif
|
||||
|
||||
SECTION("containsKey()") {
|
||||
unsigned char key[] = "hello";
|
||||
|
||||
JsonDocument doc;
|
||||
deserializeJson(doc, "{\"hello\":\"world\"}");
|
||||
JsonObject obj = doc.as<JsonObject>();
|
||||
REQUIRE(true == obj.containsKey(key));
|
||||
}
|
||||
|
||||
SECTION("remove()") {
|
||||
unsigned char key[] = "hello";
|
||||
|
||||
|
||||
@@ -3,15 +3,65 @@
|
||||
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("ARDUINOJSON_USE_DOUBLE == 0") {
|
||||
JsonDocument doc;
|
||||
JsonObject root = doc.to<JsonObject>();
|
||||
namespace my {
|
||||
using ArduinoJson::detail::isinf;
|
||||
} // namespace my
|
||||
|
||||
root["pi"] = 3.14;
|
||||
root["e"] = 2.72;
|
||||
|
||||
std::string json;
|
||||
serializeJson(doc, json);
|
||||
|
||||
REQUIRE(json == "{\"pi\":3.14,\"e\":2.72}");
|
||||
void checkFloat(const char* input, float expected) {
|
||||
using ArduinoJson::detail::NumberType;
|
||||
using ArduinoJson::detail::parseNumber;
|
||||
CAPTURE(input);
|
||||
auto result = parseNumber(input);
|
||||
REQUIRE(result.type() == NumberType::Float);
|
||||
REQUIRE(result.asFloat() == Approx(expected));
|
||||
}
|
||||
|
||||
TEST_CASE("ARDUINOJSON_USE_DOUBLE == 0") {
|
||||
SECTION("serializeJson()") {
|
||||
JsonDocument doc;
|
||||
JsonObject root = doc.to<JsonObject>();
|
||||
|
||||
root["pi"] = 3.14;
|
||||
root["e"] = 2.72;
|
||||
|
||||
std::string json;
|
||||
serializeJson(doc, json);
|
||||
|
||||
REQUIRE(json == "{\"pi\":3.14,\"e\":2.72}");
|
||||
}
|
||||
|
||||
SECTION("parseNumber()") {
|
||||
using ArduinoJson::detail::NumberType;
|
||||
using ArduinoJson::detail::parseNumber;
|
||||
|
||||
SECTION("Large positive number") {
|
||||
auto result = parseNumber("1e300");
|
||||
REQUIRE(result.type() == NumberType::Float);
|
||||
REQUIRE(result.asFloat() > 0);
|
||||
REQUIRE(my::isinf(result.asFloat()));
|
||||
}
|
||||
|
||||
SECTION("Large negative number") {
|
||||
auto result = parseNumber("-1e300");
|
||||
REQUIRE(result.type() == NumberType::Float);
|
||||
REQUIRE(result.asFloat() < 0);
|
||||
REQUIRE(my::isinf(result.asFloat()));
|
||||
}
|
||||
|
||||
SECTION("Too small to be represented") {
|
||||
auto result = parseNumber("1e-300");
|
||||
REQUIRE(result.type() == NumberType::Float);
|
||||
REQUIRE(result.asFloat() == 0);
|
||||
}
|
||||
|
||||
SECTION("MantissaTooLongToFit") {
|
||||
checkFloat("0.340282346638528861111111111111", 0.34028234663852886f);
|
||||
checkFloat("34028234663852886.11111111111111", 34028234663852886.0f);
|
||||
checkFloat("34028234.66385288611111111111111", 34028234.663852886f);
|
||||
|
||||
checkFloat("-0.340282346638528861111111111111", -0.34028234663852886f);
|
||||
checkFloat("-34028234663852886.11111111111111", -34028234663852886.0f);
|
||||
checkFloat("-34028234.66385288611111111111111", -34028234.663852886f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,11 +32,7 @@ TEST_CASE("ARDUINOJSON_USE_LONG_LONG == 0") {
|
||||
deserializeMsgPack(doc, "\xcf\x00\x00\x00\x01\x00\x00\x00\x00"_s);
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
#if defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ >= 8
|
||||
REQUIRE(doc.as<JsonInteger>() == 0x100000000);
|
||||
#else
|
||||
REQUIRE(doc.isNull());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,3 +199,44 @@ TEST_CASE(
|
||||
REQUIRE(err == DeserializationError::NoMemory);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"deserializeMsgPack() returns NoMemory if extension allocation fails") {
|
||||
JsonDocument doc(FailingAllocator::instance());
|
||||
|
||||
SECTION("uint32_t should pass") {
|
||||
auto err = deserializeMsgPack(doc, "\xceXXXX");
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
}
|
||||
|
||||
SECTION("uint64_t should fail") {
|
||||
auto err = deserializeMsgPack(doc, "\xcfXXXXXXXX");
|
||||
|
||||
REQUIRE(err == DeserializationError::NoMemory);
|
||||
}
|
||||
|
||||
SECTION("int32_t should pass") {
|
||||
auto err = deserializeMsgPack(doc, "\xd2XXXX");
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
}
|
||||
|
||||
SECTION("int64_t should fail") {
|
||||
auto err = deserializeMsgPack(doc, "\xd3XXXXXXXX");
|
||||
|
||||
REQUIRE(err == DeserializationError::NoMemory);
|
||||
}
|
||||
|
||||
SECTION("float should pass") {
|
||||
auto err = deserializeMsgPack(doc, "\xcaXXXX");
|
||||
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
}
|
||||
|
||||
SECTION("double should fail") {
|
||||
auto err = deserializeMsgPack(doc, "\xcbXXXXXXXX");
|
||||
|
||||
REQUIRE(err == DeserializationError::NoMemory);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
|
||||
add_executable(NumbersTests
|
||||
convertNumber.cpp
|
||||
parseFloat.cpp
|
||||
decomposeFloat.cpp
|
||||
parseDouble.cpp
|
||||
parseFloat.cpp
|
||||
parseInteger.cpp
|
||||
parseNumber.cpp
|
||||
)
|
||||
|
||||
42
lib/ArduinoJson/extras/tests/Numbers/decomposeFloat.cpp
Normal file
42
lib/ArduinoJson/extras/tests/Numbers/decomposeFloat.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2024, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Numbers/FloatParts.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
TEST_CASE("decomposeFloat()") {
|
||||
SECTION("1.7976931348623157E+308") {
|
||||
auto parts = decomposeFloat(1.7976931348623157E+308, 9);
|
||||
REQUIRE(parts.integral == 1);
|
||||
REQUIRE(parts.decimal == 797693135);
|
||||
REQUIRE(parts.decimalPlaces == 9);
|
||||
REQUIRE(parts.exponent == 308);
|
||||
}
|
||||
|
||||
SECTION("4.94065645841247e-324") {
|
||||
auto parts = decomposeFloat(4.94065645841247e-324, 9);
|
||||
REQUIRE(parts.integral == 4);
|
||||
REQUIRE(parts.decimal == 940656458);
|
||||
REQUIRE(parts.decimalPlaces == 9);
|
||||
REQUIRE(parts.exponent == -324);
|
||||
}
|
||||
|
||||
SECTION("3.4E+38") {
|
||||
auto parts = decomposeFloat(3.4E+38f, 6);
|
||||
REQUIRE(parts.integral == 3);
|
||||
REQUIRE(parts.decimal == 4);
|
||||
REQUIRE(parts.decimalPlaces == 1);
|
||||
REQUIRE(parts.exponent == 38);
|
||||
}
|
||||
|
||||
SECTION("1.17549435e−38") {
|
||||
auto parts = decomposeFloat(1.17549435e-38f, 6);
|
||||
REQUIRE(parts.integral == 1);
|
||||
REQUIRE(parts.decimal == 175494);
|
||||
REQUIRE(parts.decimalPlaces == 6);
|
||||
REQUIRE(parts.exponent == -38);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
// Copyright © 2014-2024, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#define ARDUINOJSON_USE_DOUBLE 0
|
||||
#define ARDUINOJSON_ENABLE_NAN 1
|
||||
#define ARDUINOJSON_ENABLE_INFINITY 1
|
||||
|
||||
@@ -13,7 +12,9 @@ using namespace ArduinoJson::detail;
|
||||
|
||||
void checkFloat(const char* input, float expected) {
|
||||
CAPTURE(input);
|
||||
REQUIRE(parseNumber<float>(input) == Approx(expected));
|
||||
auto result = parseNumber(input);
|
||||
REQUIRE(result.type() == NumberType::Float);
|
||||
REQUIRE(result.asFloat() == Approx(expected));
|
||||
}
|
||||
|
||||
void checkFloatNaN(const char* input) {
|
||||
@@ -59,27 +60,15 @@ TEST_CASE("parseNumber<float>()") {
|
||||
|
||||
SECTION("VeryLong") {
|
||||
checkFloat("0.00000000000000000000000000000001", 1e-32f);
|
||||
checkFloat("100000000000000000000000000000000.0", 1e+32f);
|
||||
checkFloat(
|
||||
"100000000000000000000000000000000.00000000000000000000000000000",
|
||||
1e+32f);
|
||||
}
|
||||
|
||||
SECTION("MantissaTooLongToFit") {
|
||||
checkFloat("0.340282346638528861111111111111", 0.34028234663852886f);
|
||||
checkFloat("34028234663852886.11111111111111", 34028234663852886.0f);
|
||||
checkFloat("34028234.66385288611111111111111", 34028234.663852886f);
|
||||
|
||||
checkFloat("-0.340282346638528861111111111111", -0.34028234663852886f);
|
||||
checkFloat("-34028234663852886.11111111111111", -34028234663852886.0f);
|
||||
checkFloat("-34028234.66385288611111111111111", -34028234.663852886f);
|
||||
}
|
||||
|
||||
SECTION("ExponentTooBig") {
|
||||
checkFloatInf("1e39", false);
|
||||
checkFloatInf("-1e39", true);
|
||||
checkFloatInf("1e255", false);
|
||||
checkFloat("1e-255", 0.0f);
|
||||
// The following don't work because they have many digits so parseNumber()
|
||||
// treats them as double. But it's not an issue because JsonVariant will use
|
||||
// a float to store them.
|
||||
//
|
||||
// checkFloat("100000000000000000000000000000000.0", 1e+32f);
|
||||
// checkFloat(
|
||||
// "100000000000000000000000000000000.00000000000000000000000000000",
|
||||
// 1e+32f);
|
||||
}
|
||||
|
||||
SECTION("NaN") {
|
||||
@@ -94,8 +83,5 @@ TEST_CASE("parseNumber<float>()") {
|
||||
checkFloatInf("inf", false);
|
||||
checkFloatInf("+inf", false);
|
||||
checkFloatInf("-inf", true);
|
||||
|
||||
checkFloatInf("1e300", false);
|
||||
checkFloatInf("-1e300", true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,45 +9,55 @@ using namespace ArduinoJson;
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
TEST_CASE("Test unsigned integer overflow") {
|
||||
VariantData first, second;
|
||||
Number first, second;
|
||||
|
||||
// Avoids MSVC warning C4127 (conditional expression is constant)
|
||||
size_t integerSize = sizeof(JsonInteger);
|
||||
|
||||
if (integerSize == 8) {
|
||||
parseNumber("18446744073709551615", first);
|
||||
parseNumber("18446744073709551616", second);
|
||||
first = parseNumber("18446744073709551615");
|
||||
second = parseNumber("18446744073709551616");
|
||||
} else {
|
||||
parseNumber("4294967295", first);
|
||||
parseNumber("4294967296", second);
|
||||
first = parseNumber("4294967295");
|
||||
second = parseNumber("4294967296");
|
||||
}
|
||||
|
||||
REQUIRE(first.type() == uint8_t(VALUE_IS_UNSIGNED_INTEGER));
|
||||
REQUIRE(second.type() == uint8_t(VALUE_IS_FLOAT));
|
||||
REQUIRE(first.type() == NumberType::UnsignedInteger);
|
||||
REQUIRE(second.type() == NumberType::Double);
|
||||
}
|
||||
|
||||
TEST_CASE("Test signed integer overflow") {
|
||||
VariantData first, second;
|
||||
Number first, second;
|
||||
|
||||
// Avoids MSVC warning C4127 (conditional expression is constant)
|
||||
size_t integerSize = sizeof(JsonInteger);
|
||||
|
||||
if (integerSize == 8) {
|
||||
parseNumber("-9223372036854775808", first);
|
||||
parseNumber("-9223372036854775809", second);
|
||||
first = parseNumber("-9223372036854775808");
|
||||
second = parseNumber("-9223372036854775809");
|
||||
} else {
|
||||
parseNumber("-2147483648", first);
|
||||
parseNumber("-2147483649", second);
|
||||
first = parseNumber("-2147483648");
|
||||
second = parseNumber("-2147483649");
|
||||
}
|
||||
|
||||
REQUIRE(first.type() == uint8_t(VALUE_IS_SIGNED_INTEGER));
|
||||
REQUIRE(second.type() == uint8_t(VALUE_IS_FLOAT));
|
||||
REQUIRE(first.type() == NumberType::SignedInteger);
|
||||
REQUIRE(second.type() == NumberType::Double);
|
||||
}
|
||||
|
||||
TEST_CASE("Invalid value") {
|
||||
VariantData result;
|
||||
auto result = parseNumber("6a3");
|
||||
|
||||
parseNumber("6a3", result);
|
||||
|
||||
REQUIRE(result.type() == uint8_t(VALUE_IS_NULL));
|
||||
REQUIRE(result.type() == NumberType::Invalid);
|
||||
}
|
||||
|
||||
TEST_CASE("float") {
|
||||
auto result = parseNumber("3.402823e38");
|
||||
|
||||
REQUIRE(result.type() == NumberType::Float);
|
||||
}
|
||||
|
||||
TEST_CASE("double") {
|
||||
auto result = parseNumber("1.7976931348623157e308");
|
||||
|
||||
REQUIRE(result.type() == NumberType::Double);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/StringBuilder.hpp>
|
||||
#include <ArduinoJson/Memory/VariantPoolImpl.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
@@ -9,28 +9,28 @@
|
||||
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
TEST_CASE("ResourceManager::allocSlot()") {
|
||||
TEST_CASE("ResourceManager::allocVariant()") {
|
||||
SECTION("Returns different pointer") {
|
||||
ResourceManager resources;
|
||||
|
||||
VariantSlot* s1 = resources.allocSlot();
|
||||
REQUIRE(s1 != 0);
|
||||
VariantSlot* s2 = resources.allocSlot();
|
||||
REQUIRE(s2 != 0);
|
||||
auto s1 = resources.allocVariant();
|
||||
REQUIRE(s1.ptr() != nullptr);
|
||||
auto s2 = resources.allocVariant();
|
||||
REQUIRE(s2.ptr() != nullptr);
|
||||
|
||||
REQUIRE(s1 != s2);
|
||||
REQUIRE(s1.ptr() != s2.ptr());
|
||||
}
|
||||
|
||||
SECTION("Returns the same slot after calling freeSlot()") {
|
||||
SECTION("Returns the same slot after calling freeVariant()") {
|
||||
ResourceManager resources;
|
||||
|
||||
auto s1 = resources.allocSlot();
|
||||
auto s2 = resources.allocSlot();
|
||||
resources.freeSlot(s1);
|
||||
resources.freeSlot(s2);
|
||||
auto s3 = resources.allocSlot();
|
||||
auto s4 = resources.allocSlot();
|
||||
auto s5 = resources.allocSlot();
|
||||
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());
|
||||
@@ -42,26 +42,26 @@ TEST_CASE("ResourceManager::allocSlot()") {
|
||||
SECTION("Returns aligned pointers") {
|
||||
ResourceManager resources;
|
||||
|
||||
REQUIRE(isAligned(resources.allocSlot().operator VariantSlot*()));
|
||||
REQUIRE(isAligned(resources.allocSlot().operator VariantSlot*()));
|
||||
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.allocSlot();
|
||||
auto variant = resources.allocVariant();
|
||||
REQUIRE(variant.id() == NULL_SLOT);
|
||||
REQUIRE(static_cast<VariantSlot*>(variant) == nullptr);
|
||||
REQUIRE(variant.ptr() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("Returns null if pool allocation fails") {
|
||||
ResourceManager resources(FailingAllocator::instance());
|
||||
|
||||
resources.allocSlot();
|
||||
resources.allocVariant();
|
||||
|
||||
auto variant = resources.allocSlot();
|
||||
auto variant = resources.allocVariant();
|
||||
REQUIRE(variant.id() == NULL_SLOT);
|
||||
REQUIRE(static_cast<VariantSlot*>(variant) == nullptr);
|
||||
REQUIRE(variant.ptr() == nullptr);
|
||||
}
|
||||
|
||||
SECTION("Try overflow pool counter") {
|
||||
@@ -73,18 +73,18 @@ TEST_CASE("ResourceManager::allocSlot()") {
|
||||
|
||||
// fill all the pools
|
||||
for (SlotId i = 0; i < NULL_SLOT; i++) {
|
||||
auto slot = resources.allocSlot();
|
||||
auto slot = resources.allocVariant();
|
||||
REQUIRE(slot.id() == i); // or != NULL_SLOT
|
||||
REQUIRE(static_cast<VariantSlot*>(slot) != nullptr);
|
||||
REQUIRE(slot.ptr() != nullptr);
|
||||
}
|
||||
|
||||
REQUIRE(resources.overflowed() == false);
|
||||
|
||||
// now all allocations should fail
|
||||
for (int i = 0; i < 10; i++) {
|
||||
auto slot = resources.allocSlot();
|
||||
auto slot = resources.allocVariant();
|
||||
REQUIRE(slot.id() == NULL_SLOT);
|
||||
REQUIRE(static_cast<VariantSlot*>(slot) == nullptr);
|
||||
REQUIRE(slot.ptr() == nullptr);
|
||||
}
|
||||
|
||||
REQUIRE(resources.overflowed() == true);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Memory/VariantPoolImpl.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManagerImpl.hpp>
|
||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
@@ -13,7 +13,7 @@ TEST_CASE("ResourceManager::clear()") {
|
||||
ResourceManager resources;
|
||||
|
||||
SECTION("Discards allocated variants") {
|
||||
resources.allocSlot();
|
||||
resources.allocVariant();
|
||||
|
||||
resources.clear();
|
||||
REQUIRE(resources.size() == 0);
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Memory/VariantPoolImpl.hpp>
|
||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Memory/VariantPoolImpl.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManagerImpl.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
@@ -21,14 +21,14 @@ TEST_CASE("ResourceManager::shrinkToFit()") {
|
||||
}
|
||||
|
||||
SECTION("only one pool") {
|
||||
resources.allocSlot();
|
||||
resources.allocVariant();
|
||||
|
||||
resources.shrinkToFit();
|
||||
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofPool()),
|
||||
Reallocate(sizeofPool(), sizeof(VariantSlot)),
|
||||
Reallocate(sizeofPool(), sizeofPool(1)),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ TEST_CASE("ResourceManager::shrinkToFit()") {
|
||||
for (size_t i = 0;
|
||||
i < ARDUINOJSON_POOL_CAPACITY * ARDUINOJSON_INITIAL_POOL_COUNT + 1;
|
||||
i++)
|
||||
resources.allocSlot();
|
||||
resources.allocVariant();
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofPool()) * ARDUINOJSON_INITIAL_POOL_COUNT,
|
||||
@@ -49,7 +49,7 @@ TEST_CASE("ResourceManager::shrinkToFit()") {
|
||||
|
||||
REQUIRE(spyingAllocator.log() ==
|
||||
AllocatorLog{
|
||||
Reallocate(sizeofPool(), sizeof(VariantSlot)),
|
||||
Reallocate(sizeofPool(), sizeofPool(1)),
|
||||
Reallocate(sizeofPoolList(ARDUINOJSON_INITIAL_POOL_COUNT * 2),
|
||||
sizeofPoolList(ARDUINOJSON_INITIAL_POOL_COUNT + 1)),
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Memory/VariantPoolImpl.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManagerImpl.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
@@ -21,10 +21,10 @@ TEST_CASE("ResourceManager::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.allocSlot();
|
||||
resources.allocVariant();
|
||||
size_t size = resources.size();
|
||||
|
||||
resources.allocSlot();
|
||||
resources.allocVariant();
|
||||
|
||||
REQUIRE(size == resources.size());
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include <ArduinoJson/Memory/Alignment.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Memory/VariantPoolImpl.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManagerImpl.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include "Allocators.hpp"
|
||||
@@ -14,7 +14,7 @@ using namespace ArduinoJson::detail;
|
||||
static void fullPreallocatedPools(ResourceManager& resources) {
|
||||
for (int i = 0;
|
||||
i < ARDUINOJSON_INITIAL_POOL_COUNT * ARDUINOJSON_POOL_CAPACITY; i++)
|
||||
resources.allocSlot();
|
||||
resources.allocVariant();
|
||||
}
|
||||
|
||||
TEST_CASE("ResourceManager::swap()") {
|
||||
@@ -23,13 +23,13 @@ TEST_CASE("ResourceManager::swap()") {
|
||||
ResourceManager a(&spy);
|
||||
ResourceManager b(&spy);
|
||||
|
||||
auto a1 = a.allocSlot();
|
||||
auto b1 = b.allocSlot();
|
||||
auto a1 = a.allocVariant();
|
||||
auto b1 = b.allocVariant();
|
||||
|
||||
swap(a, b);
|
||||
|
||||
REQUIRE(a1->data() == b.getSlot(a1.id())->data());
|
||||
REQUIRE(b1->data() == a.getSlot(b1.id())->data());
|
||||
REQUIRE(a1.ptr() == b.getVariant(a1.id()));
|
||||
REQUIRE(b1.ptr() == a.getVariant(b1.id()));
|
||||
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofPool()) * 2,
|
||||
@@ -42,12 +42,12 @@ TEST_CASE("ResourceManager::swap()") {
|
||||
ResourceManager b(&spy);
|
||||
fullPreallocatedPools(b);
|
||||
|
||||
auto a1 = a.allocSlot();
|
||||
auto b1 = b.allocSlot();
|
||||
auto a1 = a.allocVariant();
|
||||
auto b1 = b.allocVariant();
|
||||
swap(a, b);
|
||||
|
||||
REQUIRE(a1->data() == b.getSlot(a1.id())->data());
|
||||
REQUIRE(b1->data() == a.getSlot(b1.id())->data());
|
||||
REQUIRE(a1.ptr() == b.getVariant(a1.id()));
|
||||
REQUIRE(b1.ptr() == a.getVariant(b1.id()));
|
||||
|
||||
REQUIRE(spy.log() ==
|
||||
AllocatorLog{
|
||||
@@ -63,12 +63,12 @@ TEST_CASE("ResourceManager::swap()") {
|
||||
fullPreallocatedPools(a);
|
||||
ResourceManager b(&spy);
|
||||
|
||||
auto a1 = a.allocSlot();
|
||||
auto b1 = b.allocSlot();
|
||||
auto a1 = a.allocVariant();
|
||||
auto b1 = b.allocVariant();
|
||||
swap(a, b);
|
||||
|
||||
REQUIRE(a1->data() == b.getSlot(a1.id())->data());
|
||||
REQUIRE(b1->data() == a.getSlot(b1.id())->data());
|
||||
REQUIRE(a1.ptr() == b.getVariant(a1.id()));
|
||||
REQUIRE(b1.ptr() == a.getVariant(b1.id()));
|
||||
|
||||
REQUIRE(spy.log() ==
|
||||
AllocatorLog{
|
||||
@@ -85,12 +85,12 @@ TEST_CASE("ResourceManager::swap()") {
|
||||
ResourceManager b(&spy);
|
||||
fullPreallocatedPools(b);
|
||||
|
||||
auto a1 = a.allocSlot();
|
||||
auto b1 = b.allocSlot();
|
||||
auto a1 = a.allocVariant();
|
||||
auto b1 = b.allocVariant();
|
||||
|
||||
swap(a, b);
|
||||
|
||||
REQUIRE(a1->data() == b.getSlot(a1.id())->data());
|
||||
REQUIRE(b1->data() == a.getSlot(b1.id())->data());
|
||||
REQUIRE(a1.ptr() == b.getVariant(a1.id()));
|
||||
REQUIRE(b1.ptr() == a.getVariant(b1.id()));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user