added library json

This commit is contained in:
hidaba
2023-05-14 11:02:22 +02:00
parent c60123ce97
commit ab8de582d8
421 changed files with 51080 additions and 6 deletions

View File

@ -0,0 +1,37 @@
# ArduinoJson - https://arduinojson.org
# Copyright © 2014-2023, Benoit BLANCHON
# MIT License
add_executable(JsonVariantTests
add.cpp
as.cpp
clear.cpp
compare.cpp
containsKey.cpp
converters.cpp
copy.cpp
createNested.cpp
is.cpp
isnull.cpp
memoryUsage.cpp
misc.cpp
nesting.cpp
nullptr.cpp
or.cpp
overflow.cpp
remove.cpp
set.cpp
shallowCopy.cpp
size.cpp
stl_containers.cpp
subscript.cpp
types.cpp
unbound.cpp
)
add_test(JsonVariant JsonVariantTests)
set_tests_properties(JsonVariant
PROPERTIES
LABELS "Catch"
)

View File

@ -0,0 +1,46 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <stdint.h>
#include <catch.hpp>
TEST_CASE("JsonVariant::add()") {
DynamicJsonDocument doc(4096);
JsonVariant var = doc.to<JsonVariant>();
SECTION("add integer to new variant") {
var.add(42);
REQUIRE(var.as<std::string>() == "[42]");
}
SECTION("add const char* to new variant") {
var.add("hello");
REQUIRE(var.as<std::string>() == "[\"hello\"]");
}
SECTION("add std::string to new variant") {
var.add(std::string("hello"));
REQUIRE(var.as<std::string>() == "[\"hello\"]");
}
SECTION("add integer to integer") {
var.set(123);
var.add(456); // no-op
REQUIRE(var.as<std::string>() == "123");
}
SECTION("add integer to object") {
var["val"] = 123;
var.add(456); // no-op
REQUIRE(var.as<std::string>() == "{\"val\":123}");
}
}

View File

@ -0,0 +1,270 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <stdint.h>
#include <catch.hpp>
namespace my {
using ArduinoJson::detail::isinf;
} // namespace my
enum MY_ENUM { ONE = 1, TWO = 2 };
TEST_CASE("JsonVariant::as()") {
static const char* null = 0;
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
SECTION("not set") {
REQUIRE(false == variant.as<bool>());
REQUIRE(0 == variant.as<int>());
REQUIRE(0.0f == variant.as<float>());
REQUIRE(0 == variant.as<const char*>());
REQUIRE("null" == variant.as<std::string>());
REQUIRE(variant.as<JsonString>().isNull());
}
SECTION("set(4.2)") {
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<unsigned>() == 4U);
REQUIRE(variant.as<JsonString>().isNull());
}
SECTION("set(0.0)") {
variant.set(0.0);
REQUIRE(variant.as<bool>() == false);
REQUIRE(variant.as<long>() == 0L);
REQUIRE(variant.as<JsonString>().isNull());
}
SECTION("set(false)") {
variant.set(false);
REQUIRE(false == variant.as<bool>());
REQUIRE(variant.as<double>() == 0.0);
REQUIRE(variant.as<long>() == 0L);
REQUIRE(variant.as<std::string>() == "false");
REQUIRE(variant.as<JsonString>().isNull());
}
SECTION("set(true)") {
variant.set(true);
REQUIRE(variant.as<bool>());
REQUIRE(variant.as<double>() == 1.0);
REQUIRE(variant.as<long>() == 1L);
REQUIRE(variant.as<std::string>() == "true");
REQUIRE(variant.as<JsonString>().isNull());
}
SECTION("set(42)") {
variant.set(42);
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<JsonString>().isNull());
}
SECTION("set(42L)") {
variant.set(42L);
REQUIRE(variant.as<bool>() == true);
REQUIRE(variant.as<double>() == 42.0);
REQUIRE(variant.as<std::string>() == "42");
REQUIRE(variant.as<JsonString>().isNull());
}
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);
REQUIRE(variant.as<bool>() == true);
REQUIRE(variant.as<double>() == 42.0);
REQUIRE(variant.as<std::string>() == "42");
REQUIRE(variant.as<JsonString>().isNull());
}
SECTION("set(0L)") {
variant.set(0L);
REQUIRE(variant.as<bool>() == false);
REQUIRE(variant.as<double>() == 0.0);
REQUIRE(variant.as<std::string>() == "0");
REQUIRE(variant.as<JsonString>().isNull());
}
SECTION("set(0UL)") {
variant.set(0UL);
REQUIRE(variant.as<bool>() == false);
REQUIRE(variant.as<double>() == 0.0);
REQUIRE(variant.as<std::string>() == "0");
REQUIRE(variant.as<JsonString>().isNull());
}
SECTION("set(null)") {
variant.set(null);
REQUIRE(variant.as<bool>() == false);
REQUIRE(variant.as<double>() == 0.0);
REQUIRE(variant.as<long>() == 0L);
REQUIRE(variant.as<std::string>() == "null");
REQUIRE(variant.as<JsonString>().isNull());
}
SECTION("set(\"42\")") {
variant.set("42");
REQUIRE(variant.as<long>() == 42L);
REQUIRE(variant.as<JsonString>() == "42");
REQUIRE(variant.as<JsonString>().isLinked() == true);
}
SECTION("set(\"hello\")") {
variant.set("hello");
REQUIRE(variant.as<bool>() == true);
REQUIRE(variant.as<long>() == 0L);
REQUIRE(variant.as<const char*>() == std::string("hello"));
REQUIRE(variant.as<const char*>() == std::string("hello"));
REQUIRE(variant.as<std::string>() == std::string("hello"));
REQUIRE(variant.as<JsonString>() == "hello");
}
SECTION("set(std::string(\"4.2\"))") {
variant.set(std::string("4.2"));
REQUIRE(variant.as<bool>() == true);
REQUIRE(variant.as<long>() == 4L);
REQUIRE(variant.as<double>() == 4.2);
REQUIRE(variant.as<const char*>() == std::string("4.2"));
REQUIRE(variant.as<std::string>() == std::string("4.2"));
REQUIRE(variant.as<JsonString>() == "4.2");
REQUIRE(variant.as<JsonString>().isLinked() == false);
}
SECTION("set(\"true\")") {
variant.set("true");
REQUIRE(variant.as<bool>() == true);
REQUIRE(variant.as<int>() == 0);
REQUIRE(variant.as<JsonString>() == "true");
}
SECTION("set(-1e300)") {
variant.set(-1e300);
REQUIRE(variant.as<bool>() == true);
REQUIRE(variant.as<double>() == -1e300);
REQUIRE(variant.as<float>() < 0);
REQUIRE(my::isinf(variant.as<float>()));
REQUIRE(variant.as<JsonString>().isNull());
}
SECTION("set(1e300)") {
variant.set(1e300);
REQUIRE(variant.as<bool>() == true);
REQUIRE(variant.as<double>() == 1e300);
REQUIRE(variant.as<float>() > 0);
REQUIRE(my::isinf(variant.as<float>()));
REQUIRE(variant.as<JsonString>().isNull());
}
SECTION("set(1e-300)") {
variant.set(1e-300);
REQUIRE(variant.as<bool>() == true);
REQUIRE(variant.as<double>() == 1e-300);
REQUIRE(variant.as<float>() == 0);
REQUIRE(variant.as<JsonString>().isNull());
}
SECTION("to<JsonObject>()") {
JsonObject obj = variant.to<JsonObject>();
obj["key"] = "value";
SECTION("as<bool>()") {
REQUIRE(variant.as<bool>() == true);
}
SECTION("as<std::string>()") {
REQUIRE(variant.as<std::string>() == std::string("{\"key\":\"value\"}"));
}
SECTION("ObjectAsJsonObject") {
JsonObject o = variant.as<JsonObject>();
REQUIRE(o.size() == 1);
REQUIRE(o["key"] == std::string("value"));
}
}
SECTION("to<JsonArray>()") {
JsonArray arr = variant.to<JsonArray>();
arr.add(4);
arr.add(2);
SECTION("as<bool>()") {
REQUIRE(variant.as<bool>() == true);
}
SECTION("as<std::string>()") {
REQUIRE(variant.as<std::string>() == std::string("[4,2]"));
}
SECTION("as<JsonArray>()") {
JsonArray a = variant.as<JsonArray>();
REQUIRE(a.size() == 2);
REQUIRE(a[0] == 4);
REQUIRE(a[1] == 2);
}
}
#if ARDUINOJSON_USE_LONG_LONG
SECTION("Smallest int64 negative") {
variant.set("-9223372036854775808");
REQUIRE(variant.as<long long>() == -9223372036854775807 - 1);
}
SECTION("Biggerst int64 positive") {
variant.set("9223372036854775807");
REQUIRE(variant.as<long long>() == 9223372036854775807);
}
#endif
SECTION("should work on JsonVariantConst") {
variant.set("hello");
JsonVariantConst cvar = variant;
REQUIRE(cvar.as<bool>() == true);
REQUIRE(cvar.as<long>() == 0L);
REQUIRE(cvar.as<const char*>() == std::string("hello"));
REQUIRE(cvar.as<std::string>() == std::string("hello"));
}
SECTION("as<enum>()") {
variant.set(1);
REQUIRE(variant.as<MY_ENUM>() == ONE);
}
}

View File

@ -0,0 +1,26 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <stdint.h>
#include <catch.hpp>
TEST_CASE("JsonVariant::clear()") {
DynamicJsonDocument doc(4096);
JsonVariant var = doc.to<JsonVariant>();
SECTION("size goes back to zero") {
var.add(42);
var.clear();
REQUIRE(var.size() == 0);
}
SECTION("isNull() return true") {
var.add("hello");
var.clear();
REQUIRE(var.isNull() == true);
}
}

View File

@ -0,0 +1,316 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
// Most code is already covered by arithmeticCompare.cpp.
// Here, we're just filling the holes
TEST_CASE("Compare JsonVariant with value") {
StaticJsonDocument<256> doc;
JsonVariant a = doc.add();
SECTION("null vs (char*)0") {
char* b = 0;
CHECK(a == b);
CHECK(a <= b);
CHECK(a >= b);
CHECK_FALSE(a != b);
CHECK_FALSE(a < b);
CHECK_FALSE(a > b);
}
SECTION("42 vs 42") {
a.set(42);
int b = 42;
CHECK(a == b);
CHECK(a <= b);
CHECK(a >= b);
CHECK_FALSE(a != b);
CHECK_FALSE(a < b);
CHECK_FALSE(a > b);
}
}
TEST_CASE("Compare JsonVariant with JsonVariant") {
StaticJsonDocument<256> doc;
JsonVariant a = doc.add();
JsonVariant b = doc.add();
SECTION("'abc' vs 'abc'") {
a.set("abc");
b.set("abc");
CHECK(a == b);
CHECK(a <= b);
CHECK(a >= b);
CHECK_FALSE(a != b);
CHECK_FALSE(a < b);
CHECK_FALSE(a > b);
}
SECTION("'abc' vs 'bcd'") {
a.set("abc");
b.set("bcd");
CHECK(a != b);
CHECK(a < b);
CHECK(a <= b);
CHECK_FALSE(a == b);
CHECK_FALSE(a > b);
CHECK_FALSE(a >= b);
}
SECTION("'bcd' vs 'abc'") {
a.set("bcd");
b.set("abc");
CHECK(a != b);
CHECK(a > b);
CHECK(a >= b);
CHECK_FALSE(a < b);
CHECK_FALSE(a <= b);
CHECK_FALSE(a == b);
}
SECTION("serialized('abc') vs serialized('abc')") {
a.set(serialized("abc"));
b.set(serialized("abc"));
CHECK(a == b);
CHECK(a <= b);
CHECK(a >= b);
CHECK_FALSE(a != b);
CHECK_FALSE(a < b);
CHECK_FALSE(a > b);
}
SECTION("serialized('abc') vs serialized('bcd')") {
a.set(serialized("abc"));
b.set(serialized("bcd"));
CHECK(a != b);
CHECK(a < b);
CHECK(a <= b);
CHECK_FALSE(a == b);
CHECK_FALSE(a > b);
CHECK_FALSE(a >= b);
}
SECTION("serialized('bcd') vs serialized('abc')") {
a.set(serialized("bcd"));
b.set(serialized("abc"));
CHECK(a != b);
CHECK(a > b);
CHECK(a >= b);
CHECK_FALSE(a < b);
CHECK_FALSE(a <= b);
CHECK_FALSE(a == b);
}
SECTION("false vs true") {
a.set(false);
b.set(true);
CHECK(a != b);
CHECK(a < b);
CHECK(a <= b);
CHECK_FALSE(a == b);
CHECK_FALSE(a > b);
CHECK_FALSE(a >= b);
}
SECTION("false vs -1") {
a.set(false);
b.set(-1);
CHECK(a != b);
CHECK(a > b);
CHECK(a >= b);
CHECK_FALSE(a < b);
CHECK_FALSE(a <= b);
CHECK_FALSE(a == b);
}
SECTION("null vs null") {
CHECK(a == b);
CHECK(a <= b);
CHECK(a >= b);
CHECK_FALSE(a != b);
CHECK_FALSE(a < b);
CHECK_FALSE(a > b);
}
SECTION("42 vs 42") {
a.set(42);
b.set(42);
CHECK(a == b);
CHECK(a <= b);
CHECK(a >= b);
CHECK_FALSE(a != b);
CHECK_FALSE(a < b);
CHECK_FALSE(a > b);
}
SECTION("42 vs 42U") {
a.set(42);
b.set(42U);
CHECK(a == b);
CHECK(a <= b);
CHECK(a >= b);
CHECK_FALSE(a != b);
CHECK_FALSE(a < b);
CHECK_FALSE(a > b);
}
SECTION("42 vs 42.0") {
a.set(42);
b.set(42.0);
CHECK(a == b);
CHECK(a <= b);
CHECK(a >= b);
CHECK_FALSE(a != b);
CHECK_FALSE(a < b);
CHECK_FALSE(a > b);
}
SECTION("42.0 vs 42") {
a.set(42.0);
b.set(42);
CHECK(a == b);
CHECK(a <= b);
CHECK(a >= b);
CHECK_FALSE(a != b);
CHECK_FALSE(a < b);
CHECK_FALSE(a > b);
}
SECTION("-42 vs -42") {
a.set(-42);
b.set(-42);
CHECK(a == b);
CHECK(a <= b);
CHECK(a >= b);
CHECK_FALSE(a != b);
CHECK_FALSE(a < b);
CHECK_FALSE(a > b);
}
SECTION("-42 vs 42") {
a.set(-42);
b.set(42);
CHECK(a != b);
CHECK(a < b);
CHECK(a <= b);
CHECK_FALSE(a == b);
CHECK_FALSE(a > b);
CHECK_FALSE(a >= b);
}
SECTION("42 vs -42") {
a.set(42);
b.set(-42);
CHECK(a != b);
CHECK(a > b);
CHECK(a >= b);
CHECK_FALSE(a < b);
CHECK_FALSE(a <= b);
CHECK_FALSE(a == b);
}
SECTION("42.0 vs -42") {
a.set(42.0);
b.set(-42);
CHECK(a != b);
CHECK(a > b);
CHECK(a >= b);
CHECK_FALSE(a < b);
CHECK_FALSE(a <= b);
CHECK_FALSE(a == b);
}
SECTION("42U vs 42U") {
a.set(42U);
b.set(42U);
CHECK(a == b);
CHECK(a <= b);
CHECK(a >= b);
CHECK_FALSE(a != b);
CHECK_FALSE(a < b);
CHECK_FALSE(a > b);
}
SECTION("42U vs 42") {
a.set(42U);
b.set(42);
CHECK(a == b);
CHECK(a <= b);
CHECK(a >= b);
CHECK_FALSE(a != b);
CHECK_FALSE(a < b);
CHECK_FALSE(a > b);
}
SECTION("[1] vs [1]") {
a.add(1);
b.add(1);
CHECK(a <= b);
CHECK(a == b);
CHECK(a >= b);
CHECK_FALSE(a != b);
CHECK_FALSE(a < b);
CHECK_FALSE(a > b);
}
SECTION("[1] vs [2]") {
a.add(1);
b.add(2);
CHECK(a != b);
CHECK_FALSE(a < b);
CHECK_FALSE(a <= b);
CHECK_FALSE(a == b);
CHECK_FALSE(a > b);
CHECK_FALSE(a >= b);
}
SECTION("{x:1} vs {x:1}") {
a["x"] = 1;
b["x"] = 1;
CHECK(a <= b);
CHECK(a == b);
CHECK(a >= b);
CHECK_FALSE(a != b);
CHECK_FALSE(a < b);
CHECK_FALSE(a > b);
}
SECTION("{x:1} vs {x:2}") {
a["x"] = 1;
b["x"] = 2;
CHECK(a != b);
CHECK_FALSE(a < b);
CHECK_FALSE(a <= b);
CHECK_FALSE(a == b);
CHECK_FALSE(a > b);
CHECK_FALSE(a >= b);
}
}

View File

@ -0,0 +1,42 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <stdint.h>
#include <catch.hpp>
TEST_CASE("JsonVariant::containsKey()") {
DynamicJsonDocument doc(4096);
JsonVariant var = doc.to<JsonVariant>();
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(std::string("hello")) == true);
REQUIRE(var.containsKey(std::string("world")) == false);
}
}
TEST_CASE("JsonVariantConst::containsKey()") {
DynamicJsonDocument doc(4096);
doc["hello"] = "world";
JsonVariantConst cvar = doc.as<JsonVariant>();
SECTION("containsKey(const char*) returns true") {
REQUIRE(cvar.containsKey("hello") == true);
REQUIRE(cvar.containsKey("world") == false);
}
SECTION("containsKey(std::string) returns true") {
REQUIRE(cvar.containsKey(std::string("hello")) == true);
REQUIRE(cvar.containsKey(std::string("world")) == false);
}
}

View File

@ -0,0 +1,154 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <stdint.h>
#include <catch.hpp>
namespace {
struct Date {
int day;
int month;
int year;
};
void convertToJson(const Date& src, JsonVariant dst) {
dst["day"] = src.day;
dst["month"] = src.month;
dst["year"] = src.year;
}
void convertFromJson(JsonVariantConst src, Date& dst) {
dst.day = src["day"];
dst.month = src["month"];
dst.year = src["year"];
}
bool canConvertFromJson(JsonVariantConst src, const Date&) {
return src["day"].is<int>() && src["month"].is<int>() &&
src["year"].is<int>();
}
} // namespace
TEST_CASE("Custom converter with overloading") {
DynamicJsonDocument doc(4096);
SECTION("convert JSON to Date") {
doc["date"]["day"] = 2;
doc["date"]["month"] = 3;
doc["date"]["year"] = 2021;
Date date = doc["date"];
REQUIRE(date.day == 2);
REQUIRE(date.month == 3);
REQUIRE(date.year == 2021);
}
SECTION("is<Date>() returns true") {
doc["date"]["day"] = 2;
doc["date"]["month"] = 3;
doc["date"]["year"] = 2021;
REQUIRE(doc["date"].is<Date>());
}
SECTION("is<Date>() returns false") {
doc["date"]["day"] = 2;
doc["date"]["month"] = 3;
doc["date"]["year"] = "2021";
REQUIRE(doc["date"].is<Date>() == false);
}
SECTION("convert Date to JSON") {
Date date = {19, 3, 2021};
doc["date"] = date;
REQUIRE(doc["date"]["day"] == 19);
REQUIRE(doc["date"]["month"] == 3);
REQUIRE(doc["date"]["year"] == 2021);
}
}
class Complex {
public:
explicit Complex(double r, double i) : real_(r), imag_(i) {}
double real() const {
return real_;
}
double imag() const {
return imag_;
}
private:
double real_, imag_;
};
namespace ArduinoJson {
template <>
struct Converter<Complex> {
static void toJson(const Complex& src, JsonVariant dst) {
dst["real"] = src.real();
dst["imag"] = src.imag();
}
static Complex fromJson(JsonVariantConst src) {
return Complex(src["real"], src["imag"]);
}
static bool checkJson(JsonVariantConst src) {
return src["real"].is<double>() && src["imag"].is<double>();
}
};
} // namespace ArduinoJson
TEST_CASE("Custom converter with specialization") {
DynamicJsonDocument doc(4096);
SECTION("convert JSON to Complex") {
doc["value"]["real"] = 2;
doc["value"]["imag"] = 3;
Complex value = doc["value"];
REQUIRE(value.real() == 2);
REQUIRE(value.imag() == 3);
}
SECTION("is<Complex>() returns true") {
doc["value"]["real"] = 2;
doc["value"]["imag"] = 3;
REQUIRE(doc["value"].is<Complex>());
}
SECTION("is<Complex>() returns false") {
doc["value"]["real"] = 2;
doc["value"]["imag"] = "3";
REQUIRE(doc["value"].is<Complex>() == false);
}
SECTION("convert value to JSON") {
doc["value"] = Complex(19, 3);
REQUIRE(doc["value"]["real"] == 19);
REQUIRE(doc["value"]["imag"] == 3);
}
}
TEST_CASE("ConverterNeedsWriteableRef") {
using namespace ArduinoJson::detail;
CHECK(ConverterNeedsWriteableRef<int>::value == false);
CHECK(ConverterNeedsWriteableRef<float>::value == false);
CHECK(ConverterNeedsWriteableRef<JsonVariant>::value == true);
CHECK(ConverterNeedsWriteableRef<JsonVariantConst>::value == false);
CHECK(ConverterNeedsWriteableRef<JsonObject>::value == true);
CHECK(ConverterNeedsWriteableRef<JsonObjectConst>::value == false);
CHECK(ConverterNeedsWriteableRef<JsonArray>::value == true);
CHECK(ConverterNeedsWriteableRef<JsonArrayConst>::value == false);
}

View File

@ -0,0 +1,95 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonVariant::set(JsonVariant)") {
DynamicJsonDocument doc1(4096);
DynamicJsonDocument doc2(4096);
JsonVariant var1 = doc1.to<JsonVariant>();
JsonVariant var2 = doc2.to<JsonVariant>();
SECTION("stores JsonArray by copy") {
JsonArray arr = doc2.to<JsonArray>();
JsonObject obj = arr.createNestedObject();
obj["hello"] = "world";
var1.set(arr);
arr[0] = 666;
REQUIRE(var1.as<std::string>() == "[{\"hello\":\"world\"}]");
}
SECTION("stores JsonObject by copy") {
JsonObject obj = doc2.to<JsonObject>();
JsonArray arr = obj.createNestedArray("value");
arr.add(42);
var1.set(obj);
obj["value"] = 666;
REQUIRE(var1.as<std::string>() == "{\"value\":[42]}");
}
SECTION("stores const char* by reference") {
var1.set("hello!!");
var2.set(var1);
REQUIRE(doc1.memoryUsage() == 0);
REQUIRE(doc2.memoryUsage() == 0);
}
SECTION("stores char* by copy") {
char str[] = "hello!!";
var1.set(str);
var2.set(var1);
REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(7));
REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(7));
}
SECTION("stores std::string by copy") {
var1.set(std::string("hello!!"));
var2.set(var1);
REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(7));
REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(7));
}
SECTION("stores Serialized<const char*> by reference") {
var1.set(serialized("hello!!", 8));
var2.set(var1);
REQUIRE(doc1.memoryUsage() == 0);
REQUIRE(doc2.memoryUsage() == 0);
}
SECTION("stores Serialized<char*> by copy") {
char str[] = "hello!!";
var1.set(serialized(str, 7));
var2.set(var1);
REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(7));
REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(7));
}
SECTION("stores Serialized<std::string> by copy") {
var1.set(serialized(std::string("hello!!")));
var2.set(var1);
REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(7));
REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(7));
}
SECTION("destination is unbound") {
JsonVariant unboundVariant;
unboundVariant.set(var1);
REQUIRE(unboundVariant.isUnbound());
REQUIRE(unboundVariant.isNull());
}
}

View File

@ -0,0 +1,58 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <stdint.h>
#include <catch.hpp>
TEST_CASE("JsonVariant::createNestedObject()") {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
SECTION("promotes to array") {
JsonObject obj = variant.createNestedObject();
obj["value"] = 42;
REQUIRE(variant.is<JsonArray>() == true);
REQUIRE(variant[0]["value"] == 42);
REQUIRE(obj.isNull() == false);
}
}
TEST_CASE("JsonVariant::createNestedArray()") {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
SECTION("promotes to array") {
JsonArray arr = variant.createNestedArray();
REQUIRE(variant.is<JsonArray>() == true);
REQUIRE(arr.isNull() == false);
}
}
TEST_CASE("JsonVariant::createNestedObject(key)") {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
SECTION("promotes to object") {
JsonObject obj = variant.createNestedObject("weather");
obj["temp"] = 42;
REQUIRE(variant.is<JsonObject>() == true);
REQUIRE(variant["weather"]["temp"] == 42);
}
}
TEST_CASE("JsonVariant::createNestedArray(key)") {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
SECTION("promotes to object") {
JsonArray arr = variant.createNestedArray("items");
REQUIRE(variant.is<JsonObject>() == true);
REQUIRE(arr.isNull() == false);
}
}

View File

@ -0,0 +1,319 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
enum MYENUM2 { ONE = 1, TWO = 2 };
TEST_CASE("JsonVariant::is<T>()") {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
SECTION("unbound") {
variant = JsonVariant();
CHECK(variant.is<JsonObject>() == false);
CHECK(variant.is<JsonArray>() == false);
CHECK(variant.is<JsonVariant>() == false);
CHECK(variant.is<JsonVariantConst>() == false);
CHECK(variant.is<bool>() == false);
CHECK(variant.is<const char*>() == false);
CHECK(variant.is<int>() == false);
CHECK(variant.is<std::string>() == false);
CHECK(variant.is<JsonString>() == false);
CHECK(variant.is<float>() == false);
CHECK(variant.is<MYENUM2>() == false);
CHECK(variant.is<JsonString>() == false);
}
SECTION("null") {
CHECK(variant.is<JsonVariant>() == true);
CHECK(variant.is<JsonVariantConst>() == true);
CHECK(variant.is<JsonObject>() == false);
CHECK(variant.is<JsonArray>() == false);
CHECK(variant.is<bool>() == false);
CHECK(variant.is<const char*>() == false);
CHECK(variant.is<int>() == false);
CHECK(variant.is<std::string>() == false);
CHECK(variant.is<JsonString>() == false);
CHECK(variant.is<float>() == false);
CHECK(variant.is<MYENUM2>() == false);
}
SECTION("true") {
variant.set(true);
CHECK(variant.is<bool>() == true);
CHECK(variant.is<JsonVariant>() == true);
CHECK(variant.is<JsonVariantConst>() == true);
CHECK(variant.is<JsonObject>() == false);
CHECK(variant.is<JsonArray>() == false);
CHECK(variant.is<const char*>() == false);
CHECK(variant.is<int>() == false);
CHECK(variant.is<std::string>() == false);
CHECK(variant.is<JsonString>() == false);
CHECK(variant.is<float>() == false);
CHECK(variant.is<MYENUM2>() == false);
}
SECTION("false") {
variant.set(false);
CHECK(variant.is<bool>() == true);
CHECK(variant.is<JsonVariant>() == true);
CHECK(variant.is<JsonVariantConst>() == true);
CHECK(variant.is<JsonObject>() == false);
CHECK(variant.is<JsonArray>() == false);
CHECK(variant.is<const char*>() == false);
CHECK(variant.is<int>() == false);
CHECK(variant.is<std::string>() == false);
CHECK(variant.is<JsonString>() == false);
CHECK(variant.is<float>() == false);
CHECK(variant.is<MYENUM2>() == false);
}
SECTION("int") {
variant.set(42);
CHECK(variant.is<int>() == true);
CHECK(variant.is<short>() == true);
CHECK(variant.is<long>() == true);
CHECK(variant.is<double>() == true);
CHECK(variant.is<float>() == true);
CHECK(variant.is<MYENUM2>() == true);
CHECK(variant.is<JsonVariant>() == true);
CHECK(variant.is<JsonVariantConst>() == true);
CHECK(variant.is<bool>() == false);
CHECK(variant.is<JsonObject>() == false);
CHECK(variant.is<JsonArray>() == false);
CHECK(variant.is<const char*>() == false);
CHECK(variant.is<std::string>() == false);
CHECK(variant.is<JsonString>() == false);
}
SECTION("double") {
variant.set(4.2);
CHECK(variant.is<double>() == true);
CHECK(variant.is<float>() == true);
CHECK(variant.is<JsonVariant>() == true);
CHECK(variant.is<JsonVariantConst>() == true);
CHECK(variant.is<bool>() == false);
CHECK(variant.is<JsonObject>() == false);
CHECK(variant.is<JsonArray>() == false);
CHECK(variant.is<const char*>() == false);
CHECK(variant.is<int>() == false);
CHECK(variant.is<std::string>() == false);
CHECK(variant.is<JsonString>() == false);
CHECK(variant.is<MYENUM2>() == false);
}
SECTION("const char*") {
variant.set("4.2");
CHECK(variant.is<const char*>() == true);
CHECK(variant.is<const char*>() == true);
CHECK(variant.is<std::string>() == true);
CHECK(variant.is<JsonString>() == true);
CHECK(variant.is<JsonVariant>() == true);
CHECK(variant.is<JsonVariantConst>() == true);
CHECK(variant.is<double>() == false);
CHECK(variant.is<float>() == false);
CHECK(variant.is<bool>() == false);
CHECK(variant.is<JsonObject>() == false);
CHECK(variant.is<JsonArray>() == false);
CHECK(variant.is<int>() == false);
CHECK(variant.is<MYENUM2>() == false);
}
SECTION("JsonArray") {
variant.to<JsonArray>();
CHECK(variant.is<JsonArray>() == true);
CHECK(variant.is<JsonArrayConst>() == true);
CHECK(variant.is<JsonVariant>() == true);
CHECK(variant.is<JsonVariantConst>() == true);
CHECK(variant.is<JsonObject>() == false);
CHECK(variant.is<JsonObjectConst>() == false);
CHECK(variant.is<int>() == false);
CHECK(variant.is<float>() == false);
CHECK(variant.is<bool>() == false);
CHECK(variant.is<const char*>() == false);
CHECK(variant.is<MYENUM2>() == false);
}
SECTION("JsonObject") {
variant.to<JsonObject>();
CHECK(variant.is<JsonObject>() == true);
CHECK(variant.is<JsonObjectConst>() == true);
CHECK(variant.is<JsonVariant>() == true);
CHECK(variant.is<JsonVariantConst>() == true);
CHECK(variant.is<JsonArray>() == false);
CHECK(variant.is<JsonArrayConst>() == false);
CHECK(variant.is<int>() == false);
CHECK(variant.is<float>() == false);
CHECK(variant.is<bool>() == false);
CHECK(variant.is<const char*>() == false);
CHECK(variant.is<MYENUM2>() == false);
CHECK(variant.is<JsonVariant>() == true);
CHECK(variant.is<JsonVariantConst>() == true);
}
}
TEST_CASE("JsonVariantConst::is<T>()") {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
JsonVariantConst cvariant = variant;
SECTION("unbound") {
cvariant = JsonVariantConst();
CHECK(cvariant.is<JsonArray>() == false);
CHECK(cvariant.is<JsonArrayConst>() == false);
CHECK(cvariant.is<JsonObject>() == false);
CHECK(cvariant.is<JsonObjectConst>() == false);
CHECK(cvariant.is<JsonVariant>() == false);
CHECK(cvariant.is<JsonVariantConst>() == false);
CHECK(cvariant.is<bool>() == false);
CHECK(cvariant.is<const char*>() == false);
CHECK(cvariant.is<int>() == false);
CHECK(cvariant.is<std::string>() == false);
CHECK(cvariant.is<JsonString>() == false);
CHECK(cvariant.is<float>() == false);
CHECK(cvariant.is<MYENUM2>() == false);
}
SECTION("null") {
CHECK(cvariant.is<JsonVariantConst>() == true);
CHECK(cvariant.is<JsonObject>() == false);
CHECK(cvariant.is<JsonArray>() == false);
CHECK(cvariant.is<JsonVariant>() == false);
CHECK(cvariant.is<bool>() == false);
CHECK(cvariant.is<const char*>() == false);
CHECK(cvariant.is<int>() == false);
CHECK(cvariant.is<std::string>() == false);
CHECK(cvariant.is<JsonString>() == false);
CHECK(cvariant.is<float>() == false);
CHECK(cvariant.is<MYENUM2>() == false);
}
SECTION("true") {
variant.set(true);
CHECK(cvariant.is<bool>() == true);
CHECK(cvariant.is<JsonVariantConst>() == true);
CHECK(cvariant.is<JsonVariant>() == false);
CHECK(cvariant.is<JsonObject>() == false);
CHECK(cvariant.is<JsonArray>() == false);
CHECK(cvariant.is<const char*>() == false);
CHECK(cvariant.is<int>() == false);
CHECK(cvariant.is<std::string>() == false);
CHECK(cvariant.is<JsonString>() == false);
CHECK(cvariant.is<float>() == false);
CHECK(cvariant.is<MYENUM2>() == false);
}
SECTION("false") {
variant.set(false);
CHECK(cvariant.is<bool>() == true);
CHECK(cvariant.is<JsonVariantConst>() == true);
CHECK(cvariant.is<JsonVariant>() == false);
CHECK(cvariant.is<JsonObject>() == false);
CHECK(cvariant.is<JsonArray>() == false);
CHECK(cvariant.is<const char*>() == false);
CHECK(cvariant.is<int>() == false);
CHECK(cvariant.is<std::string>() == false);
CHECK(cvariant.is<JsonString>() == false);
CHECK(cvariant.is<float>() == false);
CHECK(cvariant.is<MYENUM2>() == false);
}
SECTION("int") {
variant.set(42);
CHECK(cvariant.is<int>() == true);
CHECK(cvariant.is<short>() == true);
CHECK(cvariant.is<long>() == true);
CHECK(cvariant.is<double>() == true);
CHECK(cvariant.is<float>() == true);
CHECK(cvariant.is<MYENUM2>() == true);
CHECK(cvariant.is<JsonVariantConst>() == true);
CHECK(cvariant.is<bool>() == false);
CHECK(cvariant.is<JsonObject>() == false);
CHECK(cvariant.is<JsonArray>() == false);
CHECK(cvariant.is<JsonVariant>() == false);
CHECK(cvariant.is<const char*>() == false);
CHECK(cvariant.is<std::string>() == false);
CHECK(cvariant.is<JsonString>() == false);
}
SECTION("double") {
variant.set(4.2);
CHECK(cvariant.is<double>() == true);
CHECK(cvariant.is<float>() == true);
CHECK(cvariant.is<JsonVariantConst>() == true);
CHECK(cvariant.is<bool>() == false);
CHECK(cvariant.is<JsonObject>() == false);
CHECK(cvariant.is<JsonArray>() == false);
CHECK(cvariant.is<JsonVariant>() == false);
CHECK(cvariant.is<const char*>() == false);
CHECK(cvariant.is<int>() == false);
CHECK(cvariant.is<std::string>() == false);
CHECK(cvariant.is<JsonString>() == false);
CHECK(cvariant.is<MYENUM2>() == false);
}
SECTION("const char*") {
variant.set("4.2");
CHECK(cvariant.is<const char*>() == true);
CHECK(cvariant.is<const char*>() == true);
CHECK(cvariant.is<std::string>() == true);
CHECK(cvariant.is<JsonString>() == true);
CHECK(cvariant.is<double>() == false);
CHECK(cvariant.is<float>() == false);
CHECK(cvariant.is<bool>() == false);
CHECK(cvariant.is<JsonObject>() == false);
CHECK(cvariant.is<JsonArray>() == false);
CHECK(cvariant.is<JsonVariant>() == false);
CHECK(cvariant.is<int>() == false);
CHECK(cvariant.is<MYENUM2>() == false);
}
SECTION("JsonArray") {
variant.to<JsonArray>();
CHECK(cvariant.is<JsonArrayConst>() == true);
CHECK(cvariant.is<JsonVariantConst>() == true);
CHECK(cvariant.is<JsonArray>() == false);
CHECK(cvariant.is<JsonVariant>() == false);
CHECK(cvariant.is<JsonObject>() == false);
CHECK(cvariant.is<JsonObjectConst>() == false);
CHECK(cvariant.is<int>() == false);
CHECK(cvariant.is<float>() == false);
CHECK(cvariant.is<bool>() == false);
CHECK(cvariant.is<const char*>() == false);
CHECK(cvariant.is<MYENUM2>() == false);
}
SECTION("JsonObject") {
variant.to<JsonObject>();
CHECK(cvariant.is<JsonObjectConst>() == true);
CHECK(cvariant.is<JsonVariantConst>() == true);
CHECK(cvariant.is<JsonObject>() == false);
CHECK(cvariant.is<JsonVariant>() == false);
CHECK(cvariant.is<JsonArray>() == false);
CHECK(cvariant.is<JsonArrayConst>() == false);
CHECK(cvariant.is<int>() == false);
CHECK(cvariant.is<float>() == false);
CHECK(cvariant.is<bool>() == false);
CHECK(cvariant.is<const char*>() == false);
CHECK(cvariant.is<MYENUM2>() == false);
}
}

View File

@ -0,0 +1,93 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonVariant::isNull()") {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
SECTION("returns true when Undefined") {
REQUIRE(variant.isNull() == true);
}
SECTION("returns false when Integer") {
variant.set(42);
REQUIRE(variant.isNull() == false);
}
SECTION("returns false when EmptyArray") {
DynamicJsonDocument doc2(4096);
JsonArray array = doc2.to<JsonArray>();
variant.set(array);
REQUIRE(variant.isNull() == false);
}
SECTION("returns false when EmptyObject") {
DynamicJsonDocument doc2(4096);
JsonObject obj = doc2.to<JsonObject>();
variant.set(obj);
REQUIRE(variant.isNull() == false);
}
SECTION("returns true after set(JsonArray())") {
variant.set(JsonArray());
REQUIRE(variant.isNull() == true);
}
SECTION("returns true after set(JsonObject())") {
variant.set(JsonObject());
REQUIRE(variant.isNull() == true);
}
SECTION("returns false after set('hello')") {
variant.set("hello");
REQUIRE(variant.isNull() == false);
}
SECTION("returns true after set((char*)0)") {
variant.set(static_cast<char*>(0));
REQUIRE(variant.isNull() == true);
}
SECTION("returns true after set((const char*)0)") {
variant.set(static_cast<const char*>(0));
REQUIRE(variant.isNull() == true);
}
SECTION("returns true after set(serialized((char*)0))") {
variant.set(serialized(static_cast<char*>(0)));
REQUIRE(variant.isNull() == true);
}
SECTION("returns true after set(serialized((const char*)0))") {
variant.set(serialized(static_cast<const char*>(0)));
REQUIRE(variant.isNull() == true);
}
SECTION("returns true for a shallow null copy") {
StaticJsonDocument<128> doc2;
variant.shallowCopy(doc2);
CHECK(variant.isNull() == true);
}
SECTION("returns false for a shallow array copy") {
StaticJsonDocument<128> doc2;
doc2[0] = 42;
variant.shallowCopy(doc2);
CHECK(variant.isNull() == false);
}
SECTION("works with JsonVariantConst") {
variant.set(42);
JsonVariantConst cvar = variant;
REQUIRE(cvar.isNull() == false);
}
}

View File

@ -0,0 +1,41 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
#include <string>
TEST_CASE("JsonVariant::memoryUsage()") {
DynamicJsonDocument doc(4096);
JsonVariant var = doc.to<JsonVariant>();
SECTION("returns 0 if uninitialized") {
JsonVariant unitialized;
REQUIRE(unitialized.memoryUsage() == 0);
}
SECTION("returns size of object") {
JsonObject obj = var.to<JsonObject>();
obj["hello"] = 42;
REQUIRE(var.memoryUsage() == JSON_OBJECT_SIZE(1));
}
SECTION("returns size of array") {
JsonArray arr = var.to<JsonArray>();
arr.add(42);
REQUIRE(var.memoryUsage() == JSON_ARRAY_SIZE(1));
}
SECTION("returns size of owned string") {
var.set(std::string("hello"));
REQUIRE(var.memoryUsage() == 6);
REQUIRE(var.memoryUsage() == doc.memoryUsage());
}
SECTION("returns size of owned raw") {
var.set(serialized(std::string("hello")));
REQUIRE(var.memoryUsage() == 6);
REQUIRE(var.memoryUsage() == doc.memoryUsage());
}
}

View File

@ -0,0 +1,55 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("VariantData") {
REQUIRE(std::is_standard_layout<ArduinoJson::detail::VariantData>::value ==
true);
}
TEST_CASE("JsonVariant from JsonArray") {
SECTION("JsonArray is null") {
JsonArray arr;
JsonVariant v = arr;
REQUIRE(v.isNull() == true);
}
SECTION("JsonArray is not null") {
DynamicJsonDocument doc(4096);
JsonArray arr = doc.to<JsonArray>();
arr.add(12);
arr.add(34);
JsonVariant v = arr;
REQUIRE(v.is<JsonArray>() == true);
REQUIRE(v.size() == 2);
REQUIRE(v[0] == 12);
REQUIRE(v[1] == 34);
}
}
TEST_CASE("JsonVariant from JsonObject") {
SECTION("JsonObject is null") {
JsonObject obj;
JsonVariant v = obj;
REQUIRE(v.isNull() == true);
}
SECTION("JsonObject is not null") {
DynamicJsonDocument doc(4096);
JsonObject obj = doc.to<JsonObject>();
obj["a"] = 12;
obj["b"] = 34;
JsonVariant v = obj;
REQUIRE(v.is<JsonObject>() == true);
REQUIRE(v.size() == 2);
REQUIRE(v["a"] == 12);
REQUIRE(v["b"] == 34);
}
}

View File

@ -0,0 +1,31 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonVariant::nesting()") {
DynamicJsonDocument doc(4096);
JsonVariant var = doc.to<JsonVariant>();
SECTION("return 0 if uninitialized") {
JsonVariant unitialized;
REQUIRE(unitialized.nesting() == 0);
}
SECTION("returns 0 for string") {
var.set("hello");
REQUIRE(var.nesting() == 0);
}
SECTION("returns 1 for empty object") {
var.to<JsonObject>();
REQUIRE(var.nesting() == 1);
}
SECTION("returns 1 for empty array") {
var.to<JsonArray>();
REQUIRE(var.nesting() == 1);
}
}

View File

@ -0,0 +1,43 @@
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("nullptr") {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
SECTION("JsonVariant == nullptr") {
REQUIRE(variant == nullptr);
REQUIRE_FALSE(variant != nullptr);
}
SECTION("JsonVariant != nullptr") {
variant.set(42);
REQUIRE_FALSE(variant == nullptr);
REQUIRE(variant != nullptr);
}
SECTION("JsonVariant.set(nullptr)") {
variant.set(42);
variant.set(nullptr);
REQUIRE(variant.isNull());
}
SECTION("JsonVariant.set(nullptr) with unbound reference") {
JsonVariant unboundReference;
unboundReference.set(nullptr);
REQUIRE(variant.isNull());
}
SECTION("JsonVariant.is<nullptr_t>()") {
variant.set(42);
REQUIRE(variant.is<std::nullptr_t>() == false);
variant.clear();
REQUIRE(variant.is<std::nullptr_t>() == true);
}
}

View File

@ -0,0 +1,159 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonVariant::operator|()") {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc["value"].to<JsonVariant>();
SECTION("null") {
SECTION("null | const char*") {
std::string result = variant | "default";
REQUIRE(result == "default");
}
SECTION("null | int") {
int result = variant | 42;
REQUIRE(result == 42);
}
SECTION("null | bool") {
bool result = variant | true;
REQUIRE(result == true);
}
SECTION("null | ElementProxy") {
doc["array"][0] = 42;
JsonVariantConst result = variant | doc["array"][0];
REQUIRE(result == 42);
}
SECTION("null | MemberProxy") {
doc["other"] = 42;
JsonVariantConst result = variant | doc["other"];
REQUIRE(result == 42);
}
SECTION("ElementProxy | ElementProxy") {
doc["array"][0] = 42;
JsonVariantConst result = doc["array"][1] | doc["array"][0];
REQUIRE(result == 42);
}
}
SECTION("null") {
variant.set(static_cast<const char*>(0));
SECTION("null | const char*") {
std::string result = variant | "default";
REQUIRE(result == "default");
}
SECTION("null | int") {
int result = variant | 42;
REQUIRE(result == 42);
}
SECTION("null | bool") {
bool result = variant | true;
REQUIRE(result == true);
}
SECTION("null | ElementProxy") {
doc["array"][0] = 42;
JsonVariantConst result = variant | doc["array"][0];
REQUIRE(result == 42);
}
SECTION("null | MemberProxy") {
doc["other"] = 42;
JsonVariantConst result = variant | doc["other"];
REQUIRE(result == 42);
}
}
SECTION("int | const char*") {
variant.set(42);
std::string result = variant | "default";
REQUIRE(result == "default");
}
SECTION("int | uint8_t (out of range)") {
variant.set(666);
uint8_t result = variant | static_cast<uint8_t>(42);
REQUIRE(result == 42);
}
SECTION("int | ElementProxy") {
variant.set(42);
doc["array"][0] = 666;
JsonVariantConst result = variant | doc["array"][0];
REQUIRE(result == 42);
}
SECTION("int | MemberProxy") {
variant.set(42);
doc["other"] = 666;
JsonVariantConst result = variant | doc["other"];
REQUIRE(result == 42);
}
SECTION("int | int") {
variant.set(0);
int result = variant | 666;
REQUIRE(result == 0);
}
SECTION("double | int") {
// NOTE: changed the behavior to fix #981
variant.set(666.0);
int result = variant | 42;
REQUIRE(result == 42);
}
SECTION("bool | bool") {
variant.set(false);
bool result = variant | true;
REQUIRE(result == false);
}
SECTION("int | bool") {
variant.set(0);
bool result = variant | true;
REQUIRE(result == true);
}
SECTION("const char* | const char*") {
variant.set("not default");
std::string result = variant | "default";
REQUIRE(result == "not default");
}
SECTION("const char* | char*") {
char dflt[] = "default";
variant.set("not default");
std::string result = variant | dflt;
REQUIRE(result == "not default");
}
SECTION("int | char*") {
char dflt[] = "default";
variant.set(42);
std::string result = variant | dflt;
REQUIRE(result == "default");
}
SECTION("const char* | int") {
variant.set("not default");
int result = variant | 42;
REQUIRE(result == 42);
}
}

View File

@ -0,0 +1,72 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
template <typename TOut, typename TIn>
void shouldBeOk(TIn value) {
StaticJsonDocument<1> doc;
JsonVariant var = doc.to<JsonVariant>();
var.set(value);
REQUIRE(var.as<TOut>() == TOut(value));
}
template <typename TOut, typename TIn>
void shouldOverflow(TIn value) {
StaticJsonDocument<1> doc;
JsonVariant var = doc.to<JsonVariant>();
var.set(value);
REQUIRE(var.as<TOut>() == 0);
REQUIRE(var.is<TOut>() == false);
}
TEST_CASE("Handle integer overflow in stored integer") {
SECTION("int8_t") {
// ok
shouldBeOk<int8_t>(-128);
shouldBeOk<int8_t>(42.0);
shouldBeOk<int8_t>(127);
// too low
shouldOverflow<int8_t>(-128.1);
shouldOverflow<int8_t>(-129);
// too high
shouldOverflow<int8_t>(128);
shouldOverflow<int8_t>(127.1);
}
SECTION("int16_t") {
// ok
shouldBeOk<int16_t>(-32768);
shouldBeOk<int16_t>(-32767.9);
shouldBeOk<int16_t>(32766.9);
shouldBeOk<int16_t>(32767);
// too low
shouldOverflow<int16_t>(-32768.1);
shouldOverflow<int16_t>(-32769);
// too high
shouldOverflow<int16_t>(32767.1);
shouldOverflow<int16_t>(32768);
}
SECTION("uint8_t") {
// ok
shouldBeOk<uint8_t>(1);
shouldBeOk<uint8_t>(42.0);
shouldBeOk<uint8_t>(255);
// too low
shouldOverflow<uint8_t>(-1);
shouldOverflow<uint8_t>(-0.1);
// to high
shouldOverflow<uint8_t>(255.1);
shouldOverflow<uint8_t>(256);
shouldOverflow<uint8_t>(257);
}
}

View File

@ -0,0 +1,40 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <stdint.h>
#include <catch.hpp>
TEST_CASE("JsonVariant::remove()") {
DynamicJsonDocument doc(4096);
JsonVariant var = doc.to<JsonVariant>();
SECTION("remove(int)") {
var.add(1);
var.add(2);
var.add(3);
var.remove(1);
REQUIRE(var.as<std::string>() == "[1,3]");
}
SECTION("remove(const char *)") {
var["a"] = 1;
var["b"] = 2;
var.remove("a");
REQUIRE(var.as<std::string>() == "{\"b\":2}");
}
SECTION("remove(std::string)") {
var["a"] = 1;
var["b"] = 2;
var.remove(std::string("b"));
REQUIRE(var.as<std::string>() == "{\"a\":1}");
}
}

View File

@ -0,0 +1,172 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
enum ErrorCode { ERROR_01 = 1, ERROR_10 = 10 };
TEST_CASE("JsonVariant::set() when there is enough memory") {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
SECTION("const char*") {
char str[16];
strcpy(str, "hello");
bool result = variant.set(static_cast<const char*>(str));
strcpy(str, "world");
REQUIRE(result == true);
REQUIRE(variant == "world"); // stores by pointer
}
SECTION("(const char*)0") {
bool result = variant.set(static_cast<const char*>(0));
REQUIRE(result == true);
REQUIRE(variant.isNull());
}
SECTION("char*") {
char str[16];
strcpy(str, "hello");
bool result = variant.set(str);
strcpy(str, "world");
REQUIRE(result == true);
REQUIRE(variant == "hello"); // stores by copy
}
SECTION("(char*)0") {
bool result = variant.set(static_cast<char*>(0));
REQUIRE(result == true);
REQUIRE(variant.isNull());
}
SECTION("unsigned char*") {
char str[16];
strcpy(str, "hello");
bool result = variant.set(reinterpret_cast<unsigned char*>(str));
strcpy(str, "world");
REQUIRE(result == true);
REQUIRE(variant == "hello"); // stores by copy
}
SECTION("signed char*") {
char str[16];
strcpy(str, "hello");
bool result = variant.set(reinterpret_cast<signed char*>(str));
strcpy(str, "world");
REQUIRE(result == true);
REQUIRE(variant == "hello"); // stores by copy
}
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("VLA") {
size_t n = 16;
char str[n];
strcpy(str, "hello");
bool result = variant.set(str);
strcpy(str, "world");
REQUIRE(result == true);
REQUIRE(variant == "hello"); // stores by copy
}
#endif
SECTION("std::string") {
std::string str;
str = "hello";
bool result = variant.set(str);
str.replace(0, 5, "world");
REQUIRE(result == true);
REQUIRE(variant == "hello"); // stores by copy
}
SECTION("static JsonString") {
char str[16];
strcpy(str, "hello");
bool result = variant.set(JsonString(str, JsonString::Linked));
strcpy(str, "world");
REQUIRE(result == true);
REQUIRE(variant == "world"); // stores by pointer
}
SECTION("non-static JsonString") {
char str[16];
strcpy(str, "hello");
bool result = variant.set(JsonString(str, JsonString::Copied));
strcpy(str, "world");
REQUIRE(result == true);
REQUIRE(variant == "hello"); // stores by copy
}
SECTION("enum") {
ErrorCode code = ERROR_10;
bool result = variant.set(code);
REQUIRE(result == true);
REQUIRE(variant.is<int>() == true);
REQUIRE(variant.as<int>() == 10);
}
}
TEST_CASE("JsonVariant::set() with not enough memory") {
StaticJsonDocument<1> doc;
JsonVariant v = doc.to<JsonVariant>();
SECTION("std::string") {
bool result = v.set(std::string("hello world!!"));
REQUIRE(result == false);
REQUIRE(v.isNull());
}
SECTION("Serialized<std::string>") {
bool result = v.set(serialized(std::string("hello world!!")));
REQUIRE(result == false);
REQUIRE(v.isNull());
}
SECTION("char*") {
char s[] = "hello world!!";
bool result = v.set(s);
REQUIRE(result == false);
REQUIRE(v.isNull());
}
}
TEST_CASE("JsonVariant::set(DynamicJsonDocument)") {
DynamicJsonDocument doc1(1024);
doc1["hello"] = "world";
DynamicJsonDocument doc2(1024);
JsonVariant v = doc2.to<JsonVariant>();
// Should copy the doc
v.set(doc1);
doc1.clear();
std::string json;
serializeJson(doc2, json);
REQUIRE(json == "{\"hello\":\"world\"}");
}

View File

@ -0,0 +1,87 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonVariant::shallowCopy()") {
StaticJsonDocument<1024> doc1, doc2;
JsonVariant variant = doc1.to<JsonVariant>();
SECTION("JsonVariant::shallowCopy(JsonDocument&)") {
doc2["hello"] = "world";
variant.shallowCopy(doc2);
CHECK(variant.as<std::string>() == "{\"hello\":\"world\"}");
// altering the linked document should change the result
doc2["hello"] = "WORLD!";
CHECK(variant.as<std::string>() == "{\"hello\":\"WORLD!\"}");
}
SECTION("JsonVariant::shallowCopy(MemberProxy)") {
doc2["obj"]["hello"] = "world";
variant.shallowCopy(doc2["obj"]);
CHECK(variant.as<std::string>() == "{\"hello\":\"world\"}");
// altering the linked document should change the result
doc2["obj"]["hello"] = "WORLD!";
CHECK(variant.as<std::string>() == "{\"hello\":\"WORLD!\"}");
}
SECTION("JsonVariant::shallowCopy(ElementProxy)") {
doc2[0]["hello"] = "world";
variant.shallowCopy(doc2[0]);
CHECK(variant.as<std::string>() == "{\"hello\":\"world\"}");
// altering the linked document should change the result
doc2[0]["hello"] = "WORLD!";
CHECK(variant.as<std::string>() == "{\"hello\":\"WORLD!\"}");
}
SECTION("target is unbound") {
JsonVariant unbound;
variant["hello"] = "world";
variant.shallowCopy(unbound);
CHECK(variant.isUnbound() == false);
CHECK(variant.isNull() == true);
CHECK(variant.memoryUsage() == 0);
CHECK(variant.size() == 0);
}
SECTION("variant is unbound") {
JsonVariant unbound;
doc2["hello"] = "world";
unbound.shallowCopy(doc2);
CHECK(unbound.isUnbound() == true);
CHECK(unbound.isNull() == true);
CHECK(unbound.memoryUsage() == 0);
CHECK(unbound.size() == 0);
}
SECTION("preserves owned key bit") {
doc2.set(42);
doc1["a"].shallowCopy(doc2);
doc1[std::string("b")].shallowCopy(doc2);
JsonObject::iterator it = doc1.as<JsonObject>().begin();
CHECK(it->key().isLinked() == true);
++it;
CHECK(it->key().isLinked() == false);
}
}

View File

@ -0,0 +1,36 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonVariant::size()") {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
SECTION("unbound reference") {
JsonVariant unbound;
CHECK(unbound.size() == 0);
}
SECTION("int") {
variant.set(42);
CHECK(variant.size() == 0);
}
SECTION("string") {
variant.set("hello");
CHECK(variant.size() == 0);
}
SECTION("object") {
variant["a"] = 1;
variant["b"] = 2;
CHECK(variant.size() == 2);
}
}

View File

@ -0,0 +1,138 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <stdint.h>
#include <catch.hpp>
#include <array>
#include <string>
#include <vector>
namespace ArduinoJson {
template <typename T>
struct Converter<std::vector<T>> {
static void toJson(const std::vector<T>& src, JsonVariant dst) {
JsonArray array = dst.to<JsonArray>();
for (T item : src)
array.add(item);
}
static std::vector<T> fromJson(JsonVariantConst src) {
std::vector<T> dst;
for (T item : src.as<JsonArrayConst>())
dst.push_back(item);
return dst;
}
static bool checkJson(JsonVariantConst src) {
JsonArrayConst array = src;
bool result = array;
for (JsonVariantConst item : array)
result &= item.is<T>();
return result;
}
};
template <typename T, size_t N>
struct Converter<std::array<T, N>> {
static void toJson(const std::array<T, N>& src, JsonVariant dst) {
JsonArray array = dst.to<JsonArray>();
for (T item : src)
array.add(item);
}
static std::array<T, N> fromJson(JsonVariantConst src) {
std::array<T, N> dst;
dst.fill(0);
size_t idx = 0;
for (T item : src.as<JsonArrayConst>())
dst[idx++] = item;
return dst;
}
static bool checkJson(JsonVariantConst src) {
JsonArrayConst array = src;
bool result = array;
size_t size = 0;
for (JsonVariantConst item : array) {
result &= item.is<T>();
size++;
}
return result && size == N;
}
};
} // namespace ArduinoJson
TEST_CASE("vector<int>") {
SECTION("toJson") {
std::vector<int> v = {1, 2};
StaticJsonDocument<128> doc;
doc.set(v);
REQUIRE(doc.as<std::string>() == "[1,2]");
}
SECTION("fromJson") {
StaticJsonDocument<128> doc;
doc.add(1);
doc.add(2);
auto v = doc.as<std::vector<int>>();
REQUIRE(v.size() == 2);
CHECK(v[0] == 1);
CHECK(v[1] == 2);
}
SECTION("checkJson") {
StaticJsonDocument<128> doc;
CHECK(doc.is<std::vector<int>>() == false);
doc.add(1);
doc.add(2);
CHECK(doc.is<std::vector<int>>() == true);
doc.add("foo");
CHECK(doc.is<std::vector<int>>() == false);
}
}
TEST_CASE("array<int, 2>") {
typedef std::array<int, 2> array_type;
SECTION("toJson") {
array_type v;
v[0] = 1;
v[1] = 2;
StaticJsonDocument<128> doc;
doc.set(v);
REQUIRE(doc.as<std::string>() == "[1,2]");
}
SECTION("fromJson") {
StaticJsonDocument<128> doc;
doc.add(1);
doc.add(2);
auto v = doc.as<array_type>();
REQUIRE(v.size() == 2);
CHECK(v[0] == 1);
CHECK(v[1] == 2);
}
SECTION("checkJson") {
StaticJsonDocument<128> doc;
CHECK(doc.is<array_type>() == false);
doc.add(1);
CHECK(doc.is<array_type>() == false);
doc.add(2);
CHECK(doc.is<array_type>() == true);
doc[0] = "foo";
CHECK(doc.is<array_type>() == false);
}
}

View File

@ -0,0 +1,204 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonVariant::operator[]") {
DynamicJsonDocument doc(4096);
JsonVariant var = doc.to<JsonVariant>();
SECTION("The JsonVariant is null") {
REQUIRE(0 == var.size());
REQUIRE(var["0"].isNull());
REQUIRE(var[0].isNull());
}
SECTION("The JsonVariant is a string") {
var.set("hello world");
REQUIRE(0 == var.size());
REQUIRE(var["0"].isNull());
REQUIRE(var[0].isNull());
}
SECTION("The JsonVariant is a JsonArray") {
JsonArray array = var.to<JsonArray>();
SECTION("get value") {
array.add("element at index 0");
array.add("element at index 1");
REQUIRE(2 == var.size());
var[0].as<std::string>();
// REQUIRE(std::string("element at index 0") == );
REQUIRE(std::string("element at index 1") == var[1]);
REQUIRE(std::string("element at index 0") ==
var[static_cast<unsigned char>(0)]); // issue #381
REQUIRE(var[666].isNull());
REQUIRE(var[3].isNull());
REQUIRE(var["0"].isNull());
}
SECTION("set value") {
array.add("hello");
var[1] = "world";
REQUIRE(var.size() == 2);
REQUIRE(std::string("world") == var[1]);
}
SECTION("set value in a nested object") {
array.createNestedObject();
var[0]["hello"] = "world";
REQUIRE(1 == var.size());
REQUIRE(1 == var[0].size());
REQUIRE(std::string("world") == var[0]["hello"]);
}
SECTION("variant[0] when variant contains an integer") {
var.set(123);
var[0] = 345; // no-op
REQUIRE(var.is<int>());
REQUIRE(var.as<int>() == 123);
}
}
SECTION("The JsonVariant is a JsonObject") {
JsonObject object = var.to<JsonObject>();
SECTION("get value") {
object["a"] = "element at key \"a\"";
object["b"] = "element at key \"b\"";
REQUIRE(2 == var.size());
REQUIRE(std::string("element at key \"a\"") == var["a"]);
REQUIRE(std::string("element at key \"b\"") == var["b"]);
REQUIRE(var["c"].isNull());
REQUIRE(var[0].isNull());
}
SECTION("set value, key is a const char*") {
var["hello"] = "world";
REQUIRE(1 == var.size());
REQUIRE(std::string("world") == var["hello"]);
}
SECTION("set value, key is a char[]") {
char key[] = "hello";
var[key] = "world";
key[0] = '!'; // make sure the key is duplicated
REQUIRE(1 == var.size());
REQUIRE(std::string("world") == var["hello"]);
}
SECTION("var[key].to<JsonArray>()") {
JsonArray arr = var["hello"].to<JsonArray>();
REQUIRE(arr.isNull() == false);
}
}
#if defined(HAS_VARIABLE_LENGTH_ARRAY) && \
!defined(SUBSCRIPT_CONFLICTS_WITH_BUILTIN_OPERATOR)
SECTION("key is a VLA") {
size_t i = 16;
char vla[i];
strcpy(vla, "hello");
deserializeJson(doc, "{\"hello\":\"world\"}");
JsonVariant variant = doc.as<JsonVariant>();
REQUIRE(std::string("world") == variant[vla]);
}
SECTION("key is a VLA, const JsonVariant") {
size_t i = 16;
char vla[i];
strcpy(vla, "hello");
deserializeJson(doc, "{\"hello\":\"world\"}");
const JsonVariant variant = doc.as<JsonVariant>();
REQUIRE(std::string("world") == variant[vla]);
}
#endif
}
TEST_CASE("JsonVariantConst::operator[]") {
DynamicJsonDocument doc(4096);
JsonVariant var = doc.to<JsonVariant>();
JsonVariantConst cvar = var;
SECTION("The JsonVariant is null") {
REQUIRE(0 == cvar.size());
REQUIRE(cvar["0"].isNull());
REQUIRE(cvar[0].isNull());
}
SECTION("The JsonVariant is a string") {
var.set("hello world");
REQUIRE(0 == cvar.size());
REQUIRE(cvar["0"].isNull());
REQUIRE(cvar[0].isNull());
}
SECTION("The JsonVariant is a JsonArray") {
JsonArray array = var.to<JsonArray>();
SECTION("get value") {
array.add("element at index 0");
array.add("element at index 1");
REQUIRE(2 == cvar.size());
REQUIRE(std::string("element at index 0") == cvar[0]);
REQUIRE(std::string("element at index 1") == cvar[1]);
REQUIRE(std::string("element at index 0") ==
var[static_cast<unsigned char>(0)]); // issue #381
REQUIRE(cvar[666].isNull());
REQUIRE(cvar[3].isNull());
REQUIRE(cvar["0"].isNull());
}
}
SECTION("The JsonVariant is a JsonObject") {
JsonObject object = var.to<JsonObject>();
SECTION("get value") {
object["a"] = "element at key \"a\"";
object["b"] = "element at key \"b\"";
REQUIRE(2 == cvar.size());
REQUIRE(std::string("element at key \"a\"") == cvar["a"]);
REQUIRE(std::string("element at key \"b\"") == cvar["b"]);
REQUIRE(cvar["c"].isNull());
REQUIRE(cvar[0].isNull());
}
}
SECTION("Auto promote null JsonVariant to JsonObject") {
var["hello"] = "world";
REQUIRE(var.is<JsonObject>() == true);
}
SECTION("Don't auto promote non-null JsonVariant to JsonObject") {
var.set(42);
var["hello"] = "world";
REQUIRE(var.is<JsonObject>() == false);
}
SECTION("Don't auto promote null JsonVariant to JsonObject when reading") {
const char* value = var["hello"];
REQUIRE(var.is<JsonObject>() == false);
REQUIRE(value == 0);
}
}

View File

@ -0,0 +1,163 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <stdint.h>
#include <catch.hpp>
#include <limits>
template <typename T>
void checkValue(T expected) {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
variant.set(expected);
REQUIRE(expected == variant.as<T>());
}
template <typename T>
void checkReference(T& expected) {
JsonVariant variant = expected;
REQUIRE(expected == variant.as<T&>());
}
template <typename T>
void checkNumericType() {
DynamicJsonDocument docMin(4096), docMax(4096);
JsonVariant variantMin = docMin.to<JsonVariant>();
JsonVariant variantMax = docMax.to<JsonVariant>();
T min = std::numeric_limits<T>::min();
T max = std::numeric_limits<T>::max();
variantMin.set(min);
variantMax.set(max);
REQUIRE(min == variantMin.as<T>());
REQUIRE(max == variantMax.as<T>());
}
TEST_CASE("JsonVariant set()/get()") {
#if ARDUINOJSON_USE_LONG_LONG
SECTION("SizeOfJsonInteger") {
REQUIRE(8 == sizeof(JsonInteger));
}
#endif
SECTION("Null") {
checkValue<const char*>(NULL);
}
SECTION("const char*") {
checkValue<const char*>("hello");
}
SECTION("std::string") {
checkValue<std::string>("hello");
}
SECTION("False") {
checkValue<bool>(false);
}
SECTION("True") {
checkValue<bool>(true);
}
SECTION("Double") {
checkNumericType<double>();
}
SECTION("Float") {
checkNumericType<float>();
}
SECTION("SChar") {
checkNumericType<signed char>();
}
SECTION("SInt") {
checkNumericType<signed int>();
}
SECTION("SLong") {
checkNumericType<signed long>();
}
SECTION("SShort") {
checkNumericType<signed short>();
}
SECTION("UChar") {
checkNumericType<unsigned char>();
}
SECTION("UInt") {
checkNumericType<unsigned int>();
}
SECTION("ULong") {
checkNumericType<unsigned long>();
}
SECTION("UShort") {
checkNumericType<unsigned short>();
}
#if ARDUINOJSON_USE_LONG_LONG
SECTION("LongLong") {
checkNumericType<unsigned long long>();
}
SECTION("ULongLong") {
checkNumericType<unsigned long long>();
}
#endif
SECTION("Int8") {
checkNumericType<int8_t>();
}
SECTION("Uint8") {
checkNumericType<uint8_t>();
}
SECTION("Int16") {
checkNumericType<int16_t>();
}
SECTION("Uint16") {
checkNumericType<uint16_t>();
}
SECTION("Int32") {
checkNumericType<int32_t>();
}
SECTION("Uint32") {
checkNumericType<uint32_t>();
}
#if ARDUINOJSON_USE_LONG_LONG
SECTION("Int64") {
checkNumericType<int64_t>();
}
SECTION("Uint64") {
checkNumericType<uint64_t>();
}
#endif
SECTION("CanStoreObject") {
DynamicJsonDocument doc(4096);
JsonObject object = doc.to<JsonObject>();
checkValue<JsonObject>(object);
}
}
TEST_CASE("volatile") {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
SECTION("volatile int") {
volatile int f = 42;
variant.set(f);
CHECK(variant.is<int>() == true);
CHECK(variant.as<int>() == 42);
}
SECTION("volatile float") { // issue #1557
volatile float f = 3.14f;
variant.set(f);
CHECK(variant.is<float>() == true);
CHECK(variant.as<float>() == 3.14f);
}
SECTION("volatile double") {
volatile double f = 3.14;
variant.set(f);
CHECK(variant.is<double>() == true);
CHECK(variant.as<double>() == 3.14);
}
}

View File

@ -0,0 +1,66 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("Unbound JsonVariant") {
JsonVariant variant;
SECTION("as<T>()") {
CHECK(variant.as<bool>() == false);
CHECK(variant.as<int>() == 0);
CHECK(variant.as<float>() == 0.0f);
CHECK(variant.as<const char*>() == 0);
CHECK(variant.as<std::string>() == "null");
CHECK(variant.as<JsonVariant>().isNull());
CHECK(variant.as<JsonVariantConst>().isNull());
CHECK(variant.as<JsonArray>().isNull());
CHECK(variant.as<JsonArrayConst>().isNull());
CHECK(variant.as<JsonObject>().isNull());
CHECK(variant.as<JsonObjectConst>().isNull());
CHECK(variant.as<JsonString>().isNull());
}
SECTION("is<T>()") {
CHECK_FALSE(variant.is<bool>());
CHECK_FALSE(variant.is<int>());
CHECK_FALSE(variant.is<float>());
CHECK_FALSE(variant.is<const char*>());
CHECK_FALSE(variant.is<std::string>());
CHECK_FALSE(variant.is<JsonVariant>());
CHECK_FALSE(variant.is<JsonVariantConst>());
CHECK_FALSE(variant.is<JsonArray>());
CHECK_FALSE(variant.is<JsonArrayConst>());
CHECK_FALSE(variant.is<JsonObject>());
CHECK_FALSE(variant.is<JsonObjectConst>());
CHECK_FALSE(variant.is<JsonString>());
}
SECTION("set()") {
CHECK_FALSE(variant.set("42"));
CHECK_FALSE(variant.set(42.0));
CHECK_FALSE(variant.set(42L));
CHECK_FALSE(variant.set(42U));
CHECK_FALSE(variant.set(serialized("42")));
CHECK_FALSE(variant.set(true));
}
SECTION("add()") {
CHECK_FALSE(variant.add("42"));
CHECK_FALSE(variant.add(42.0));
CHECK_FALSE(variant.add(42L));
CHECK_FALSE(variant.add(42U));
CHECK_FALSE(variant.add(serialized("42")));
CHECK_FALSE(variant.add(true));
}
SECTION("operator[]") {
CHECK(variant[0].isNull());
CHECK(variant["key"].isNull());
CHECK_FALSE(variant[0].set(1));
CHECK_FALSE(variant["key"].set(1));
CHECK_FALSE(variant[std::string("key")].set(1));
}
}