Moved ancillary files to extras/ (fixes #1011)

This commit is contained in:
Benoit Blanchon
2019-09-03 15:11:05 +02:00
parent ed18e77655
commit b47ac27ac6
226 changed files with 19 additions and 54 deletions

View File

@ -0,0 +1,28 @@
# ArduinoJson - arduinojson.org
# Copyright Benoit Blanchon 2014-2019
# MIT License
add_executable(JsonVariantTests
add.cpp
as.cpp
clear.cpp
compare.cpp
containsKey.cpp
copy.cpp
createNested.cpp
is.cpp
isnull.cpp
memoryUsage.cpp
misc.cpp
nesting.cpp
or.cpp
overflow.cpp
remove.cpp
set.cpp
subscript.cpp
types.cpp
undefined.cpp
)
target_link_libraries(JsonVariantTests catch)
add_test(JsonVariant JsonVariantTests)

View File

@ -0,0 +1,32 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#include <ArduinoJson.h>
#include <stdint.h>
#include <catch.hpp>
static const char* null = 0;
TEST_CASE("JsonVariant::add()") {
DynamicJsonDocument doc(4096);
JsonVariant var = doc.to<JsonVariant>();
SECTION("integer") {
var.add(42);
REQUIRE(var.as<std::string>() == "[42]");
}
SECTION("const char*") {
var.add("hello");
REQUIRE(var.as<std::string>() == "[\"hello\"]");
}
SECTION("std::string") {
var.add(std::string("hello"));
REQUIRE(var.as<std::string>() == "[\"hello\"]");
}
}

View File

@ -0,0 +1,215 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#include <ArduinoJson.h>
#include <stdint.h>
#include <catch.hpp>
namespace my {
using ARDUINOJSON_NAMESPACE::isinf;
} // namespace my
static const char* null = 0;
TEST_CASE("JsonVariant::as()") {
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<char*>());
REQUIRE("null" == variant.as<std::string>());
}
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);
}
SECTION("set(0.0)") {
variant.set(0.0);
REQUIRE(variant.as<bool>() == false);
REQUIRE(variant.as<long>() == 0L);
}
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");
}
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");
}
SECTION("set(42L)") {
variant.set(42L);
REQUIRE(variant.as<bool>() == true);
REQUIRE(variant.as<double>() == 42.0);
REQUIRE(variant.as<std::string>() == "42");
}
SECTION("set(-42L)") {
variant.set(-42L);
REQUIRE(variant.as<double>() == -42.0);
REQUIRE(variant.as<std::string>() == "-42");
}
SECTION("set(0L)") {
variant.set(0L);
REQUIRE(variant.as<bool>() == false);
REQUIRE(variant.as<double>() == 0.0);
}
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");
}
SECTION("set(\"42\")") {
variant.set("42");
REQUIRE(variant.as<long>() == 42L);
}
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<char*>() == std::string("hello"));
REQUIRE(variant.as<std::string>() == std::string("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<char*>() == std::string("4.2"));
REQUIRE(variant.as<std::string>() == std::string("4.2"));
}
SECTION("set(\"true\")") {
variant.set("true");
REQUIRE(variant.as<bool>() == true);
REQUIRE(variant.as<int>() == 0);
}
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>()));
}
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>()));
}
SECTION("set(1e-300)") {
variant.set(1e-300);
REQUIRE(variant.as<bool>() == true);
REQUIRE(variant.as<double>() == 1e-300);
REQUIRE(variant.as<float>() == 0);
}
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<char*>() == std::string("hello"));
// REQUIRE(cvar.as<std::string>() == std::string("hello"));
}
}

View File

@ -0,0 +1,28 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#include <ArduinoJson.h>
#include <stdint.h>
#include <catch.hpp>
static const char* null = 0;
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,464 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
static const char* null = 0;
template <typename T>
void checkEquals(T a, T b) {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
variant.set(a);
REQUIRE(b == variant);
REQUIRE(variant == b);
REQUIRE(b <= variant);
REQUIRE(variant <= b);
REQUIRE(b >= variant);
REQUIRE(variant >= b);
REQUIRE_FALSE(b != variant);
REQUIRE_FALSE(variant != b);
REQUIRE_FALSE(b > variant);
REQUIRE_FALSE(variant > b);
REQUIRE_FALSE(b < variant);
REQUIRE_FALSE(variant < b);
}
template <typename T>
void checkGreater(T a, T b) {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
variant.set(a);
REQUIRE(variant > b);
REQUIRE(b < variant);
REQUIRE(variant != b);
REQUIRE(b != variant);
REQUIRE_FALSE(variant < b);
REQUIRE_FALSE(b > variant);
REQUIRE_FALSE(variant == b);
REQUIRE_FALSE(b == variant);
}
template <typename T>
void checkLower(T a, T b) {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
variant.set(a);
REQUIRE(variant < b);
REQUIRE(b > variant);
REQUIRE(variant != b);
REQUIRE(b != variant);
REQUIRE_FALSE(variant > b);
REQUIRE_FALSE(b < variant);
REQUIRE_FALSE(variant == b);
REQUIRE_FALSE(b == variant);
}
template <typename T>
void checkComparisons(T low, T mid, T high) {
checkEquals(mid, mid);
checkGreater(mid, low);
checkLower(mid, high);
}
TEST_CASE("JsonVariant comparisons") {
SECTION("Double") {
checkComparisons<double>(123.44, 123.45, 123.46);
}
SECTION("Float") {
checkComparisons<float>(123.44f, 123.45f, 123.46f);
}
SECTION("SChar") {
checkComparisons<signed char>(122, 123, 124);
}
SECTION("SInt") {
checkComparisons<signed int>(122, 123, 124);
}
SECTION("SLong") {
checkComparisons<signed long>(122L, 123L, 124L);
}
SECTION("SShort") {
checkComparisons<signed short>(122, 123, 124);
}
SECTION("UChar") {
checkComparisons<unsigned char>(122, 123, 124);
}
SECTION("UInt") {
checkComparisons<unsigned int>(122, 123, 124);
}
SECTION("ULong") {
checkComparisons<unsigned long>(122L, 123L, 124L);
}
SECTION("UShort") {
checkComparisons<unsigned short>(122, 123, 124);
}
SECTION("null") {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
variant.set(null);
REQUIRE(variant == variant);
REQUIRE_FALSE(variant != variant);
REQUIRE(variant == null);
REQUIRE_FALSE(variant != null);
REQUIRE(variant != "null");
REQUIRE_FALSE(variant == "null");
}
SECTION("StringLiteral") {
DynamicJsonDocument doc(4096);
deserializeJson(doc, "\"hello\"");
JsonVariant variant = doc.as<JsonVariant>();
REQUIRE(variant == variant);
REQUIRE_FALSE(variant != variant);
REQUIRE(variant == "hello");
REQUIRE_FALSE(variant != "hello");
REQUIRE(variant != "world");
REQUIRE_FALSE(variant == "world");
REQUIRE(variant != null);
REQUIRE_FALSE(variant == null);
REQUIRE("hello" == variant);
REQUIRE_FALSE("hello" != variant);
REQUIRE("world" != variant);
REQUIRE_FALSE("world" == variant);
REQUIRE(null != variant);
REQUIRE_FALSE(null == variant);
}
SECTION("String") {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
variant.set("hello");
REQUIRE(variant == variant);
REQUIRE_FALSE(variant != variant);
REQUIRE(variant == std::string("hello"));
REQUIRE_FALSE(variant != std::string("hello"));
REQUIRE(variant != std::string("world"));
REQUIRE_FALSE(variant == std::string("world"));
REQUIRE(variant != null);
REQUIRE_FALSE(variant == null);
REQUIRE(std::string("hello") == variant);
REQUIRE_FALSE(std::string("hello") != variant);
REQUIRE(std::string("world") != variant);
REQUIRE_FALSE(std::string("world") == variant);
REQUIRE(null != variant);
REQUIRE_FALSE(null == variant);
}
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("VLA equals") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
variant.set("hello");
REQUIRE((vla == variant));
REQUIRE((variant == vla));
REQUIRE_FALSE((vla != variant));
REQUIRE_FALSE((variant != vla));
}
SECTION("VLA differs") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
variant.set("world");
REQUIRE((vla != variant));
REQUIRE((variant != vla));
REQUIRE_FALSE((vla == variant));
REQUIRE_FALSE((variant == vla));
}
#endif
DynamicJsonDocument doc1(4096), doc2(4096), doc3(4096);
JsonVariant variant1 = doc1.to<JsonVariant>();
JsonVariant variant2 = doc2.to<JsonVariant>();
JsonVariant variant3 = doc3.to<JsonVariant>();
SECTION("Variants containing integers") {
variant1.set(42);
variant2.set(42);
variant3.set(666);
REQUIRE(variant1 == variant2);
REQUIRE_FALSE(variant1 != variant2);
REQUIRE(variant1 != variant3);
REQUIRE_FALSE(variant1 == variant3);
}
SECTION("Variants containing linked strings") {
// create two identical strings at different addresses
char hello1[] = "hello";
char hello2[] = "hello";
REQUIRE(hello1 != hello2);
variant1.set(hello1);
variant2.set(hello2);
variant3.set("world");
REQUIRE(variant1 == variant2);
REQUIRE_FALSE(variant1 != variant2);
REQUIRE(variant1 != variant3);
REQUIRE_FALSE(variant1 == variant3);
}
SECTION("Variants containing owned strings") {
variant1.set(std::string("hello"));
variant2.set(std::string("hello"));
variant3.set(std::string("world"));
REQUIRE(variant1 == variant2);
REQUIRE_FALSE(variant1 != variant2);
REQUIRE(variant1 != variant3);
REQUIRE_FALSE(variant1 == variant3);
}
SECTION("Variants containing linked raws") {
// create two identical strings at different addresses
char hello1[] = "hello";
char hello2[] = "hello";
REQUIRE(hello1 != hello2);
variant1.set(serialized(hello1));
variant2.set(serialized(hello2));
variant3.set(serialized("world"));
REQUIRE(variant1 == variant2);
REQUIRE_FALSE(variant1 != variant2);
REQUIRE(variant1 != variant3);
REQUIRE_FALSE(variant1 == variant3);
}
SECTION("Variants containing owned raws") {
variant1.set(serialized(std::string("hello")));
variant2.set(serialized(std::string("hello")));
variant3.set(serialized(std::string("world")));
REQUIRE(variant1 == variant2);
REQUIRE_FALSE(variant1 != variant2);
REQUIRE(variant1 != variant3);
REQUIRE_FALSE(variant1 == variant3);
}
SECTION("Variants containing mixed strings (issue #1051)") {
variant1.set("hello");
variant2.set(std::string("hello"));
REQUIRE(variant1 == variant2);
REQUIRE_FALSE(variant1 != variant2);
REQUIRE(variant2 == variant1);
REQUIRE_FALSE(variant2 != variant1);
}
SECTION("Variants containing double") {
variant1.set(42.0);
variant2.set(42.0);
variant3.set(666.0);
REQUIRE(variant1 == variant2);
REQUIRE_FALSE(variant1 != variant2);
REQUIRE(variant1 != variant3);
REQUIRE_FALSE(variant1 == variant3);
}
SECTION("BoolInVariant") {
variant1.set(true);
variant2.set(true);
variant3.set(false);
REQUIRE(variant1 == variant2);
REQUIRE_FALSE(variant1 != variant2);
REQUIRE(variant1 != variant3);
REQUIRE_FALSE(variant1 == variant3);
}
SECTION("ArrayInVariant") {
JsonArray array1 = variant1.to<JsonArray>();
JsonArray array2 = variant2.to<JsonArray>();
array1.add(42);
array2.add(42);
REQUIRE(variant1 == variant2);
REQUIRE_FALSE(variant1 != variant2);
REQUIRE(variant1 != variant3);
REQUIRE_FALSE(variant1 == variant3);
}
SECTION("ObjectInVariant") {
JsonObject obj1 = variant1.to<JsonObject>();
JsonObject obj2 = variant2.to<JsonObject>();
obj1["hello"] = "world";
obj2["hello"] = "world";
REQUIRE(variant1 == variant2);
REQUIRE_FALSE(variant1 != variant2);
REQUIRE(variant1 != variant3);
REQUIRE_FALSE(variant1 == variant3);
}
}
class VariantComparisionFixture {
private:
StaticJsonDocument<256> doc;
JsonVariant variant;
public:
VariantComparisionFixture() : variant(doc.to<JsonVariant>()) {}
protected:
template <typename T>
void setValue(const T& value) {
variant.set(value);
}
template <typename T>
void assertEqualsTo(const T& value) {
REQUIRE(variant == value);
REQUIRE(value == variant);
REQUIRE_FALSE(variant != value);
REQUIRE_FALSE(value != variant);
}
template <typename T>
void assertDiffersFrom(const T& value) {
REQUIRE(variant != value);
REQUIRE(value != variant);
REQUIRE_FALSE(variant == value);
REQUIRE_FALSE(value == variant);
}
template <typename T>
void assertGreaterThan(const T& value) {
REQUIRE((variant > value));
REQUIRE((variant >= value));
REQUIRE(value < variant);
REQUIRE(value <= variant);
REQUIRE_FALSE((variant < value));
REQUIRE_FALSE((variant <= value));
REQUIRE_FALSE(value > variant);
REQUIRE_FALSE(value >= variant);
}
template <typename T>
void assertLowerThan(const T& value) {
REQUIRE(variant < value);
REQUIRE(variant <= value);
REQUIRE(value > variant);
REQUIRE(value >= variant);
REQUIRE_FALSE(variant > value);
REQUIRE_FALSE(variant >= value);
REQUIRE_FALSE(value < variant);
REQUIRE_FALSE(value <= variant);
}
};
TEST_CASE_METHOD(VariantComparisionFixture,
"Compare variant with another type") {
SECTION("null") {
assertDiffersFrom(3);
assertDiffersFrom("world");
}
SECTION("string") {
setValue("hello");
assertEqualsTo("hello");
assertDiffersFrom(3);
assertDiffersFrom("world");
assertGreaterThan("helln");
assertLowerThan("hellp");
}
SECTION("positive integer") {
setValue(42);
assertEqualsTo(42);
assertDiffersFrom(43);
assertGreaterThan(41);
assertLowerThan(43);
assertDiffersFrom("world");
}
SECTION("negative integer") {
setValue(-42);
assertEqualsTo(-42);
assertDiffersFrom(42);
assertGreaterThan(-43);
assertLowerThan(-41);
assertDiffersFrom("world");
}
SECTION("double") {
setValue(42.0);
assertEqualsTo(42.0);
assertDiffersFrom(42.1);
assertGreaterThan(41.0);
assertLowerThan(43.0);
assertDiffersFrom("42.0");
}
SECTION("true") {
setValue(true);
assertEqualsTo(true);
assertDiffersFrom(false);
assertDiffersFrom(1);
assertDiffersFrom("true");
assertDiffersFrom(1.0);
assertGreaterThan(false);
}
}

View File

@ -0,0 +1,28 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#include <ArduinoJson.h>
#include <stdint.h>
#include <catch.hpp>
static const char* null = 0;
TEST_CASE("JsonVariant::containsKey()") {
DynamicJsonDocument doc(4096);
JsonVariant var = doc.to<JsonVariant>();
SECTION("containsKey(const char*) returns true") {
var["hello"] = "world";
REQUIRE(var.containsKey("hello") == true);
REQUIRE(var.containsKey("world") == false);
}
SECTION("containsKey(std::string) returns true") {
var["hello"] = "world";
REQUIRE(var.containsKey(std::string("hello")) == true);
REQUIRE(var.containsKey(std::string("world")) == false);
}
}

View File

@ -0,0 +1,86 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// 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(8));
REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(8));
}
SECTION("stores std::string by copy") {
var1.set(std::string("hello!!"));
var2.set(var1);
REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(8));
REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(8));
}
SECTION("stores Serialized<const char*> by reference") {
var1.set(serialized("hello!!", JSON_STRING_SIZE(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, 8));
var2.set(var1);
REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(8));
REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(8));
}
SECTION("stores Serialized<std::string> by copy") {
var1.set(serialized(std::string("hello!!!")));
var2.set(var1);
REQUIRE(doc1.memoryUsage() == JSON_STRING_SIZE(8));
REQUIRE(doc2.memoryUsage() == JSON_STRING_SIZE(8));
}
}

View File

@ -0,0 +1,88 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#include <ArduinoJson.h>
#include <stdint.h>
#include <catch.hpp>
static const char* null = 0;
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);
}
SECTION("works on MemberProxy") {
JsonObject obj = variant["items"].createNestedObject();
obj["value"] = 42;
REQUIRE(variant["items"][0]["value"] == 42);
}
}
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);
}
SECTION("works on MemberProxy") {
JsonArray arr = variant["items"].createNestedArray();
arr.add(42);
REQUIRE(variant["items"][0][0] == 42);
}
}
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);
}
SECTION("works on MemberProxy") {
JsonObject obj = variant["status"].createNestedObject("weather");
obj["temp"] = 42;
REQUIRE(variant["status"]["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);
}
SECTION("works on MemberProxy") {
JsonArray arr = variant["weather"].createNestedArray("temp");
arr.add(42);
REQUIRE(variant["weather"]["temp"][0] == 42);
}
}

View File

@ -0,0 +1,162 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
template <typename TVariant>
void checkIsArray(TVariant var) {
REQUIRE(var.template is<JsonArray>());
REQUIRE_FALSE(var.template is<bool>());
REQUIRE_FALSE(var.template is<double>());
REQUIRE_FALSE(var.template is<float>());
REQUIRE_FALSE(var.template is<int>());
REQUIRE_FALSE(var.template is<long>());
REQUIRE_FALSE(var.template is<const char *>());
REQUIRE_FALSE(var.template is<JsonObject>());
}
void testArray(JsonArray value) {
DynamicJsonDocument doc(4096);
JsonVariant var = doc.to<JsonVariant>();
var.set(value);
checkIsArray(var);
JsonVariantConst cvar = var;
checkIsArray(cvar);
}
template <typename TVariant>
void checkIsBool(TVariant var) {
REQUIRE(var.template is<bool>());
REQUIRE_FALSE(var.template is<double>());
REQUIRE_FALSE(var.template is<float>());
REQUIRE_FALSE(var.template is<int>());
REQUIRE_FALSE(var.template is<long>());
REQUIRE_FALSE(var.template is<const char *>());
REQUIRE_FALSE(var.template is<JsonArray>());
REQUIRE_FALSE(var.template is<JsonObject>());
}
void testBool(bool value) {
DynamicJsonDocument doc(4096);
JsonVariant var = doc.to<JsonVariant>();
var.set(value);
checkIsBool(var);
checkIsBool(JsonVariantConst(var));
}
template <typename TVariant>
void checkIsFloat(TVariant var) {
REQUIRE(var.template is<double>());
REQUIRE(var.template is<float>());
REQUIRE_FALSE(var.template is<bool>());
REQUIRE_FALSE(var.template is<int>());
REQUIRE_FALSE(var.template is<long>());
REQUIRE_FALSE(var.template is<const char *>());
REQUIRE_FALSE(var.template is<JsonArray>());
REQUIRE_FALSE(var.template is<JsonObject>());
}
void testFloat(double value) {
DynamicJsonDocument doc(4096);
JsonVariant var = doc.to<JsonVariant>();
var.set(value);
checkIsFloat(var);
checkIsFloat(JsonVariantConst(var));
}
template <typename TVariant>
void checkIsInteger(TVariant var) {
REQUIRE(var.template is<long>());
REQUIRE(var.template is<int>());
REQUIRE(var.template is<float>());
REQUIRE(var.template is<double>());
REQUIRE_FALSE(var.template is<bool>());
REQUIRE_FALSE(var.template is<const char *>());
REQUIRE_FALSE(var.template is<JsonArray>());
REQUIRE_FALSE(var.template is<JsonObject>());
}
template <typename T>
void testInteger(T value) {
DynamicJsonDocument doc(4096);
JsonVariant var = doc.to<JsonVariant>();
var.set(value);
checkIsInteger(var);
checkIsInteger(JsonVariantConst(var));
}
template <typename TVariant>
void checkIsString(TVariant var) {
REQUIRE(var.template is<const char *>());
REQUIRE(var.template is<std::string>());
REQUIRE_FALSE(var.template is<bool>());
REQUIRE_FALSE(var.template is<int>());
REQUIRE_FALSE(var.template is<double>());
REQUIRE_FALSE(var.template is<float>());
REQUIRE_FALSE(var.template is<long>());
REQUIRE_FALSE(var.template is<JsonArray>());
REQUIRE_FALSE(var.template is<JsonObject>());
}
void testString(const char *value) {
DynamicJsonDocument doc(4096);
JsonVariant var = doc.to<JsonVariant>();
var.set(value);
checkIsString(var);
checkIsString(JsonVariantConst(var));
}
TEST_CASE("JsonVariant::is()") {
SECTION("JsonArray") {
DynamicJsonDocument doc(4096);
JsonArray array = doc.to<JsonArray>();
testArray(array);
}
SECTION("bool") {
testBool(true);
testBool(false);
}
SECTION("double") {
testFloat(4.2);
}
SECTION("int") {
testInteger(42);
}
SECTION("long") {
testInteger(42L);
}
SECTION("string") {
testString("42");
}
SECTION("null") {
DynamicJsonDocument doc(4096);
deserializeJson(doc, "[null]");
JsonVariant v = doc[0];
REQUIRE(v.is<bool>() == false);
REQUIRE(v.is<char *>() == false);
REQUIRE(v.is<int>() == false);
REQUIRE(v.is<std::string>() == false);
REQUIRE(v.is<float>() == false);
}
}

View File

@ -0,0 +1,80 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonVariant::isNull()") {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
SECTION("return true when Undefined") {
REQUIRE(variant.isNull() == true);
}
SECTION("return false when Integer") {
variant.set(42);
REQUIRE(variant.isNull() == false);
}
SECTION("return false when EmptyArray") {
DynamicJsonDocument doc2(4096);
JsonArray array = doc2.to<JsonArray>();
variant.set(array);
REQUIRE(variant.isNull() == false);
}
SECTION("return false when EmptyObject") {
DynamicJsonDocument doc2(4096);
JsonObject obj = doc2.to<JsonObject>();
variant.set(obj);
REQUIRE(variant.isNull() == false);
}
SECTION("return true after set(JsonArray())") {
variant.set(JsonArray());
REQUIRE(variant.isNull() == true);
}
SECTION("return true after set(JsonObject())") {
variant.set(JsonObject());
REQUIRE(variant.isNull() == true);
}
SECTION("return false after set('hello')") {
variant.set("hello");
REQUIRE(variant.isNull() == false);
}
SECTION("return true after set((char*)0)") {
variant.set(static_cast<char*>(0));
REQUIRE(variant.isNull() == true);
}
SECTION("return true after set((const char*)0)") {
variant.set(static_cast<const char*>(0));
REQUIRE(variant.isNull() == true);
}
SECTION("return true after set(serialized((char*)0))") {
variant.set(serialized(static_cast<char*>(0)));
REQUIRE(variant.isNull() == true);
}
SECTION("return true after set(serialized((const char*)0))") {
variant.set(serialized(static_cast<const char*>(0)));
REQUIRE(variant.isNull() == true);
}
SECTION("works with JsonVariantConst") {
variant.set(42);
JsonVariantConst cvar = variant;
REQUIRE(cvar.isNull() == false);
}
}

View File

@ -0,0 +1,39 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// 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);
}
SECTION("returns size of owned raw") {
var.set(serialized(std::string("hello")));
REQUIRE(var.memoryUsage() == 5);
}
}

View File

@ -0,0 +1,50 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
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 - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// 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,96 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonVariant::operator|()") {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
SECTION("undefined") {
SECTION("undefined | const char*") {
std::string result = variant | "default";
REQUIRE(result == "default");
}
SECTION("undefined | int") {
int result = variant | 42;
REQUIRE(result == 42);
}
SECTION("undefined | bool") {
bool result = variant | true;
REQUIRE(result == true);
}
}
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("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 | 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* | int") {
variant.set("not default");
int result = variant | 42;
REQUIRE(result == 42);
}
}

View File

@ -0,0 +1,72 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// 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,42 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#include <ArduinoJson.h>
#include <stdint.h>
#include <catch.hpp>
static const char* null = 0;
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,126 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonVariant and strings") {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
SECTION("stores const char* by reference") {
char str[16];
strcpy(str, "hello");
variant.set(static_cast<const char *>(str));
strcpy(str, "world");
REQUIRE(variant == "world");
}
SECTION("stores char* by copy") {
char str[16];
strcpy(str, "hello");
variant.set(str);
strcpy(str, "world");
REQUIRE(variant == "hello");
}
SECTION("stores unsigned char* by copy") {
char str[16];
strcpy(str, "hello");
variant.set(reinterpret_cast<unsigned char *>(str));
strcpy(str, "world");
REQUIRE(variant == "hello");
}
SECTION("stores signed char* by copy") {
char str[16];
strcpy(str, "hello");
variant.set(reinterpret_cast<signed char *>(str));
strcpy(str, "world");
REQUIRE(variant == "hello");
}
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("stores VLA by copy") {
int n = 16;
char str[n];
strcpy(str, "hello");
variant.set(str);
strcpy(str, "world");
REQUIRE(variant == "hello");
}
#endif
SECTION("stores std::string by copy") {
std::string str;
str = "hello";
variant.set(str);
str.replace(0, 5, "world");
REQUIRE(variant == "hello");
}
SECTION("stores static JsonString by reference") {
char str[16];
strcpy(str, "hello");
variant.set(JsonString(str, true));
strcpy(str, "world");
REQUIRE(variant == "hello");
}
SECTION("stores non-static JsonString by copy") {
char str[16];
strcpy(str, "hello");
variant.set(JsonString(str, false));
strcpy(str, "world");
REQUIRE(variant == "hello");
}
}
TEST_CASE("JsonVariant with not enough memory") {
StaticJsonDocument<1> doc;
JsonVariant v = doc.to<JsonVariant>();
SECTION("std::string") {
v.set(std::string("hello world!!"));
REQUIRE(v.isNull());
}
SECTION("Serialized<std::string>") {
v.set(serialized(std::string("hello world!!")));
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,195 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonVariant::operator[]") {
DynamicJsonDocument doc(4096);
JsonVariant var = doc.to<JsonVariant>();
SECTION("The JsonVariant is undefined") {
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[0] = "world";
REQUIRE(1 == var.size());
REQUIRE(std::string("world") == var[0]);
}
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("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") {
int 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") {
int 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 undefined") {
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,140 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// 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("Char") {
checkNumericType<char>();
}
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);
}
}

View File

@ -0,0 +1,70 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonVariant undefined") {
JsonVariant variant;
SECTION("as<T>()") {
SECTION("long") {
REQUIRE(variant.as<long>() == 0);
}
SECTION("unsigned") {
REQUIRE(variant.as<unsigned>() == 0);
}
SECTION("char*") {
REQUIRE(variant.as<char*>() == 0);
}
SECTION("double") {
REQUIRE(variant.as<double>() == 0);
}
SECTION("bool") {
REQUIRE(variant.as<bool>() == false);
}
SECTION("JsonArray") {
REQUIRE(variant.as<JsonArray>().isNull());
}
SECTION("JsonObject") {
REQUIRE(variant.as<JsonObject>().isNull());
}
}
SECTION("is<T>()") {
SECTION("long") {
REQUIRE(variant.is<long>() == false);
}
SECTION("unsigned") {
REQUIRE(variant.is<unsigned>() == false);
}
SECTION("char*") {
REQUIRE(variant.is<char*>() == false);
}
SECTION("double") {
REQUIRE(variant.is<double>() == false);
}
SECTION("bool") {
REQUIRE(variant.is<bool>() == false);
}
SECTION("JsonArray") {
REQUIRE(variant.is<JsonArray>() == false);
}
SECTION("JsonObject") {
REQUIRE(variant.is<JsonObject>() == false);
}
}
}