add arduino json lib

#182
This commit is contained in:
1technophile committed 2018-03-07 20:52:36 +01:00
1 parent f0546fab8c
commit 3b4c9d2d98
209 files changed
+25587

No files matched your search

+76
View File
@@ -0,0 +1,76 @@
# ArduinoJson - arduinojson.org
# Copyright Benoit Blanchon 2014-2018
# MIT License
if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
add_compile_options(
-pedantic
-Wall
-Wcast-align
-Wcast-qual
-Wconversion
-Wctor-dtor-privacy
-Wdisabled-optimization
-Werror
-Wextra
-Wformat=2
-Winit-self
-Wmissing-include-dirs
-Wnon-virtual-dtor
-Wold-style-cast
-Woverloaded-virtual
-Wparentheses
-Wredundant-decls
-Wshadow
-Wsign-promo
-Wstrict-aliasing
-Wstrict-overflow=5
-Wundef
)
if(NOT MINGW)
add_compile_options(
-std=c++98
)
endif()
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
add_compile_options(
-Wstrict-null-sentinel
)
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.5)
add_compile_options(-Wlogical-op) # the flag exists in 4.4 but is buggy
endif()
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.6)
add_compile_options(-Wnoexcept)
endif()
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(
-Wc++11-compat
-Wdeprecated-register
)
endif()
if(MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
add_compile_options(
/W4 # Set warning level
/WX # Treats all compiler warnings as errors.
)
endif()
add_subdirectory(DynamicJsonBuffer)
add_subdirectory(IntegrationTests)
add_subdirectory(JsonArray)
add_subdirectory(JsonBuffer)
add_subdirectory(JsonObject)
add_subdirectory(JsonVariant)
add_subdirectory(JsonWriter)
add_subdirectory(Misc)
add_subdirectory(Polyfills)
add_subdirectory(StaticJsonBuffer)
@@ -0,0 +1,15 @@
# ArduinoJson - arduinojson.org
# Copyright Benoit Blanchon 2014-2018
# MIT License
add_executable(DynamicJsonBufferTests
alloc.cpp
createArray.cpp
createObject.cpp
no_memory.cpp
size.cpp
startString.cpp
)
target_link_libraries(DynamicJsonBufferTests catch)
add_test(DynamicJsonBuffer DynamicJsonBufferTests)
@@ -0,0 +1,77 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
#include <sstream>
using namespace ArduinoJson::Internals;
static bool isAligned(void* ptr) {
const size_t mask = sizeof(void*) - 1;
size_t addr = reinterpret_cast<size_t>(ptr);
return (addr & mask) == 0;
}
std::stringstream allocatorLog;
struct SpyingAllocator : DefaultAllocator {
void* allocate(size_t n) {
allocatorLog << "A" << (n - DynamicJsonBuffer::EmptyBlockSize);
return DefaultAllocator::allocate(n);
}
void deallocate(void* p) {
allocatorLog << "F";
return DefaultAllocator::deallocate(p);
}
};
TEST_CASE("DynamicJsonBuffer::alloc()") {
SECTION("Returns different pointers") {
DynamicJsonBuffer buffer;
void* p1 = buffer.alloc(1);
void* p2 = buffer.alloc(2);
REQUIRE(p1 != p2);
}
SECTION("Doubles allocation size when full") {
allocatorLog.str("");
{
DynamicJsonBufferBase<SpyingAllocator> buffer(1);
buffer.alloc(1);
buffer.alloc(1);
}
REQUIRE(allocatorLog.str() == "A1A2FF");
}
SECTION("Resets allocation size after clear()") {
allocatorLog.str("");
{
DynamicJsonBufferBase<SpyingAllocator> buffer(1);
buffer.alloc(1);
buffer.alloc(1);
buffer.clear();
buffer.alloc(1);
}
REQUIRE(allocatorLog.str() == "A1A2FFA1F");
}
SECTION("Makes a big allocation when needed") {
allocatorLog.str("");
{
DynamicJsonBufferBase<SpyingAllocator> buffer(1);
buffer.alloc(42);
}
REQUIRE(allocatorLog.str() == "A42F");
}
SECTION("Alignment") {
// make room for two but not three
DynamicJsonBuffer tinyBuf(2 * sizeof(void*) + 1);
REQUIRE(isAligned(tinyBuf.alloc(1))); // this on is aligned by design
REQUIRE(isAligned(tinyBuf.alloc(1))); // this one fits in the first block
REQUIRE(isAligned(tinyBuf.alloc(1))); // this one requires a new block
}
}
@@ -0,0 +1,28 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("DynamicJsonBuffer::createArray()") {
DynamicJsonBuffer jsonBuffer;
JsonArray &array = jsonBuffer.createArray();
SECTION("GrowsWithArray") {
REQUIRE(JSON_ARRAY_SIZE(0) == jsonBuffer.size());
array.add("hello");
REQUIRE(JSON_ARRAY_SIZE(1) == jsonBuffer.size());
array.add("world");
REQUIRE(JSON_ARRAY_SIZE(2) == jsonBuffer.size());
}
SECTION("CanAdd1000Values") {
for (size_t i = 1; i <= 1000; i++) {
array.add("hello");
REQUIRE(array.size() == i);
}
}
}
@@ -0,0 +1,22 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("DynamicJsonBuffer::createObject()") {
DynamicJsonBuffer json;
JsonObject &obj = json.createObject();
REQUIRE(JSON_OBJECT_SIZE(0) == json.size());
obj["hello"] = 1;
REQUIRE(JSON_OBJECT_SIZE(1) == json.size());
obj["world"] = 2;
REQUIRE(JSON_OBJECT_SIZE(2) == json.size());
obj["world"] = 3; // <- same key, should not grow
REQUIRE(JSON_OBJECT_SIZE(2) == json.size());
}
@@ -0,0 +1,49 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
using namespace ArduinoJson::Internals;
struct NoMemoryAllocator {
void* allocate(size_t) {
return NULL;
}
void deallocate(void*) {}
};
TEST_CASE("DynamicJsonBuffer no memory") {
DynamicJsonBufferBase<NoMemoryAllocator> _jsonBuffer;
SECTION("FixCodeCoverage") {
// call this function to fix code coverage
NoMemoryAllocator().deallocate(NULL);
}
SECTION("createArray()") {
REQUIRE_FALSE(_jsonBuffer.createArray().success());
}
SECTION("createObject()") {
REQUIRE_FALSE(_jsonBuffer.createObject().success());
}
SECTION("parseArray()") {
char json[] = "[]";
REQUIRE_FALSE(_jsonBuffer.parseArray(json).success());
}
SECTION("parseObject()") {
char json[] = "{}";
REQUIRE_FALSE(_jsonBuffer.parseObject(json).success());
}
SECTION("startString()") {
DynamicJsonBufferBase<NoMemoryAllocator>::String str =
_jsonBuffer.startString();
str.append('!');
REQUIRE(0 == str.c_str());
}
}
@@ -0,0 +1,27 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("DynamicJsonBuffer::size()") {
DynamicJsonBuffer buffer;
SECTION("Initial size is 0") {
REQUIRE(0 == buffer.size());
}
SECTION("Increases after alloc()") {
buffer.alloc(1);
REQUIRE(1U <= buffer.size());
buffer.alloc(1);
REQUIRE(2U <= buffer.size());
}
SECTION("Goes back to 0 after clear()") {
buffer.alloc(1);
buffer.clear();
REQUIRE(0 == buffer.size());
}
}
@@ -0,0 +1,47 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("DynamicJsonBuffer::startString()") {
SECTION("WorksWhenBufferIsBigEnough") {
DynamicJsonBuffer jsonBuffer(6);
DynamicJsonBuffer::String str = jsonBuffer.startString();
str.append('h');
str.append('e');
str.append('l');
str.append('l');
str.append('o');
REQUIRE(std::string("hello") == str.c_str());
}
SECTION("GrowsWhenBufferIsTooSmall") {
DynamicJsonBuffer jsonBuffer(5);
DynamicJsonBuffer::String str = jsonBuffer.startString();
str.append('h');
str.append('e');
str.append('l');
str.append('l');
str.append('o');
REQUIRE(std::string("hello") == str.c_str());
}
SECTION("SizeIncreases") {
DynamicJsonBuffer jsonBuffer(5);
DynamicJsonBuffer::String str = jsonBuffer.startString();
REQUIRE(0 == jsonBuffer.size());
str.append('h');
REQUIRE(1 == jsonBuffer.size());
str.c_str();
REQUIRE(2 == jsonBuffer.size());
}
}
@@ -0,0 +1,18 @@
# ArduinoJson - arduinojson.org
# Copyright Benoit Blanchon 2014-2018
# MIT License
add_executable(IntegrationTests
gbathree.cpp
round_trip.cpp
)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
target_compile_options(IntegrationTests
PUBLIC
-fsingle-precision-constant # issue 544
)
endif()
target_link_libraries(IntegrationTests catch)
add_test(IntegrationTests IntegrationTests)
@@ -0,0 +1,208 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("Gbathree") {
DynamicJsonBuffer _buffer;
const JsonObject& _object = _buffer.parseObject(
"{\"protocol_name\":\"fluorescence\",\"repeats\":1,\"wait\":0,"
"\"averages\":1,\"measurements\":3,\"meas2_light\":15,\"meas1_"
"baseline\":0,\"act_light\":20,\"pulsesize\":25,\"pulsedistance\":"
"10000,\"actintensity1\":50,\"actintensity2\":255,\"measintensity\":"
"255,\"calintensity\":255,\"pulses\":[50,50,50],\"act\":[2,1,2,2],"
"\"red\":[2,2,2,2],\"detectors\":[[34,34,34,34],[34,34,34,34],[34,"
"34,34,34],[34,34,34,34]],\"alta\":[2,2,2,2],\"altb\":[2,2,2,2],"
"\"measlights\":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,"
"15,15]],\"measlights2\":[[15,15,15,15],[15,15,15,15],[15,15,15,15],"
"[15,15,15,15]],\"altc\":[2,2,2,2],\"altd\":[2,2,2,2]}");
SECTION("Success") {
REQUIRE(_object.success());
}
SECTION("ProtocolName") {
REQUIRE("fluorescence" == _object["protocol_name"]);
}
SECTION("Repeats") {
REQUIRE(1 == _object["repeats"]);
}
SECTION("Wait") {
REQUIRE(0 == _object["wait"]);
}
SECTION("Measurements") {
REQUIRE(3 == _object["measurements"]);
}
SECTION("Meas2_Light") {
REQUIRE(15 == _object["meas2_light"]);
}
SECTION("Meas1_Baseline") {
REQUIRE(0 == _object["meas1_baseline"]);
}
SECTION("Act_Light") {
REQUIRE(20 == _object["act_light"]);
}
SECTION("Pulsesize") {
REQUIRE(25 == _object["pulsesize"]);
}
SECTION("Pulsedistance") {
REQUIRE(10000 == _object["pulsedistance"]);
}
SECTION("Actintensity1") {
REQUIRE(50 == _object["actintensity1"]);
}
SECTION("Actintensity2") {
REQUIRE(255 == _object["actintensity2"]);
}
SECTION("Measintensity") {
REQUIRE(255 == _object["measintensity"]);
}
SECTION("Calintensity") {
REQUIRE(255 == _object["calintensity"]);
}
SECTION("Pulses") {
// "pulses":[50,50,50]
JsonArray& array = _object["pulses"];
REQUIRE(array.success());
REQUIRE(3 == array.size());
for (size_t i = 0; i < 3; i++) {
REQUIRE(50 == array[i]);
}
}
SECTION("Act") {
// "act":[2,1,2,2]
JsonArray& array = _object["act"];
REQUIRE(array.success());
REQUIRE(4 == array.size());
REQUIRE(2 == array[0]);
REQUIRE(1 == array[1]);
REQUIRE(2 == array[2]);
REQUIRE(2 == array[3]);
}
SECTION("Detectors") {
// "detectors":[[34,34,34,34],[34,34,34,34],[34,34,34,34],[34,34,34,34]]
JsonArray& array = _object["detectors"];
REQUIRE(array.success());
REQUIRE(4 == array.size());
for (size_t i = 0; i < 4; i++) {
JsonArray& nestedArray = array[i];
REQUIRE(4 == nestedArray.size());
for (size_t j = 0; j < 4; j++) {
REQUIRE(34 == nestedArray[j]);
}
}
}
SECTION("Alta") {
// alta:[2,2,2,2]
JsonArray& array = _object["alta"];
REQUIRE(array.success());
REQUIRE(4 == array.size());
for (size_t i = 0; i < 4; i++) {
REQUIRE(2 == array[i]);
}
}
SECTION("Altb") {
// altb:[2,2,2,2]
JsonArray& array = _object["altb"];
REQUIRE(array.success());
REQUIRE(4 == array.size());
for (size_t i = 0; i < 4; i++) {
REQUIRE(2 == array[i]);
}
}
SECTION("Measlights") {
// "measlights":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]]
JsonArray& array = _object["measlights"];
REQUIRE(array.success());
REQUIRE(4 == array.size());
for (size_t i = 0; i < 4; i++) {
JsonArray& nestedArray = array[i];
REQUIRE(4 == nestedArray.size());
for (size_t j = 0; j < 4; j++) {
REQUIRE(15 == nestedArray[j]);
}
}
}
SECTION("Measlights2") {
// "measlights2":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]]
JsonArray& array = _object["measlights2"];
REQUIRE(array.success());
REQUIRE(4 == array.size());
for (size_t i = 0; i < 4; i++) {
JsonArray& nestedArray = array[i];
REQUIRE(4 == nestedArray.size());
for (size_t j = 0; j < 4; j++) {
REQUIRE(15 == nestedArray[j]);
}
}
}
SECTION("Altc") {
// altc:[2,2,2,2]
JsonArray& array = _object["altc"];
REQUIRE(array.success());
REQUIRE(4 == array.size());
for (size_t i = 0; i < 4; i++) {
REQUIRE(2 == array[i]);
}
}
SECTION("Altd") {
// altd:[2,2,2,2]
JsonArray& array = _object["altd"];
REQUIRE(array.success());
REQUIRE(4 == array.size());
for (size_t i = 0; i < 4; i++) {
REQUIRE(2 == array[i]);
}
}
}
@@ -0,0 +1,80 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
void check(std::string originalJson) {
DynamicJsonBuffer jb;
std::string prettyJson;
jb.parseObject(originalJson).prettyPrintTo(prettyJson);
std::string finalJson;
jb.parseObject(prettyJson).printTo(finalJson);
REQUIRE(originalJson == finalJson);
}
TEST_CASE("Round Trip: parse -> prettyPrint -> parse -> print") {
SECTION("OpenWeatherMap") {
check(
"{\"coord\":{\"lon\":145.77,\"lat\":-16.92},\"sys\":{\"type\":1,\"id\":"
"8166,\"message\":0.1222,\"country\":\"AU\",\"sunrise\":1414784325,"
"\"sunset\":1414830137},\"weather\":[{\"id\":801,\"main\":\"Clouds\","
"\"description\":\"few clouds\",\"icon\":\"02n\"}],\"base\":\"cmc "
"stations\",\"main\":{\"temp\":296.15,\"pressure\":1014,\"humidity\":"
"83,\"temp_min\":296.15,\"temp_max\":296.15},\"wind\":{\"speed\":2.22,"
"\"deg\":114.501},\"clouds\":{\"all\":20},\"dt\":1414846800,\"id\":"
"2172797,\"name\":\"Cairns\",\"cod\":200}");
}
SECTION("YahooQueryLanguage") {
check(
"{\"query\":{\"count\":40,\"created\":\"2014-11-01T14:16:49Z\","
"\"lang\":\"fr-FR\",\"results\":{\"item\":[{\"title\":\"Burkina army "
"backs Zida as interim leader\"},{\"title\":\"British jets intercept "
"Russian bombers\"},{\"title\":\"Doubts chip away at nation's most "
"trusted agencies\"},{\"title\":\"Cruise ship stuck off Norway, no "
"damage\"},{\"title\":\"U.S. military launches 10 air strikes in "
"Syria, Iraq\"},{\"title\":\"Blackout hits Bangladesh as line from "
"India fails\"},{\"title\":\"Burkina Faso president in Ivory Coast "
"after ouster\"},{\"title\":\"Kurds in Turkey rally to back city "
"besieged by IS\"},{\"title\":\"A majority of Scots would vote for "
"independence now:poll\"},{\"title\":\"Tunisia elections possible "
"model for region\"},{\"title\":\"Islamic State kills 85 more members "
"of Iraqi tribe\"},{\"title\":\"Iraqi officials:IS extremists line "
"up, kill 50\"},{\"title\":\"Burkina Faso army backs presidential "
"guard official to lead transition\"},{\"title\":\"Kurdish peshmerga "
"arrive with weapons in Syria's Kobani\"},{\"title\":\"Driver sought "
"in crash that killed 3 on Halloween\"},{\"title\":\"Ex-Marine arrives "
"in US after release from Mexico jail\"},{\"title\":\"UN panel "
"scrambling to finish climate report\"},{\"title\":\"Investigators, "
"Branson go to spacecraft crash site\"},{\"title\":\"Soldiers vie for "
"power after Burkina Faso president quits\"},{\"title\":\"For a man "
"without a party, turnout is big test\"},{\"title\":\"'We just had a "
"hunch':US marshals nab Eric Frein\"},{\"title\":\"Boko Haram leader "
"threatens to kill German hostage\"},{\"title\":\"Nurse free to move "
"about as restrictions eased\"},{\"title\":\"Former Burkina president "
"Compaore arrives in Ivory Coast:sources\"},{\"title\":\"Libyan port "
"rebel leader refuses to hand over oil ports to rival "
"group\"},{\"title\":\"Iraqi peshmerga fighters prepare for Syria "
"battle\"},{\"title\":\"1 Dem Senate candidate welcoming Obama's "
"help\"},{\"title\":\"Bikers cancel party after police recover "
"bar\"},{\"title\":\"New question in Texas:Can Davis survive "
"defeat?\"},{\"title\":\"Ukraine rebels to hold election, despite "
"criticism\"},{\"title\":\"Iraqi officials say Islamic State group "
"lines up, kills 50 tribesmen, women in Anbar "
"province\"},{\"title\":\"James rebounds, leads Cavaliers past "
"Bulls\"},{\"title\":\"UK warns travelers they could be terror "
"targets\"},{\"title\":\"Hello Kitty celebrates 40th "
"birthday\"},{\"title\":\"A look at people killed during space "
"missions\"},{\"title\":\"Nigeria's purported Boko Haram leader says "
"has 'married off' girls:AFP\"},{\"title\":\"Mexico orders immediate "
"release of Marine veteran\"},{\"title\":\"As election closes in, "
"Obama on center stage\"},{\"title\":\"Body of Zambian president "
"arrives home\"},{\"title\":\"South Africa arrests 2 Vietnamese for "
"poaching\"}]}}}");
}
}
@@ -0,0 +1,21 @@
# ArduinoJson - arduinojson.org
# Copyright Benoit Blanchon 2014-2018
# MIT License
add_executable(JsonArrayTests
add.cpp
basics.cpp
copyFrom.cpp
copyTo.cpp
invalid.cpp
iterator.cpp
prettyPrintTo.cpp
printTo.cpp
remove.cpp
set.cpp
size.cpp
subscript.cpp
)
target_link_libraries(JsonArrayTests catch)
add_test(JsonArray JsonArrayTests)
+110
View File
@@ -0,0 +1,110 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonArray::add()") {
DynamicJsonBuffer _jsonBuffer;
JsonArray& _array = _jsonBuffer.createArray();
SECTION("int") {
_array.add(123);
REQUIRE(123 == _array[0].as<int>());
REQUIRE(_array[0].is<int>());
REQUIRE(_array[0].is<double>());
}
SECTION("double") {
_array.add(123.45);
REQUIRE(123.45 == _array[0].as<double>());
REQUIRE(_array[0].is<double>());
REQUIRE_FALSE(_array[0].is<bool>());
}
SECTION("bool") {
_array.add(true);
REQUIRE(true == _array[0].as<bool>());
REQUIRE(_array[0].is<bool>());
REQUIRE_FALSE(_array[0].is<int>());
}
SECTION("const char*") {
const char* str = "hello";
_array.add(str);
REQUIRE(str == _array[0].as<std::string>());
REQUIRE(_array[0].is<const char*>());
REQUIRE_FALSE(_array[0].is<int>());
}
SECTION("nested array") {
JsonArray& arr = _jsonBuffer.createArray();
_array.add(arr);
REQUIRE(&arr == &_array[0].as<JsonArray&>());
REQUIRE(_array[0].is<JsonArray&>());
REQUIRE_FALSE(_array[0].is<int>());
}
SECTION("nested object") {
JsonObject& obj = _jsonBuffer.createObject();
_array.add(obj);
REQUIRE(&obj == &_array[0].as<JsonObject&>());
REQUIRE(_array[0].is<JsonObject&>());
REQUIRE_FALSE(_array[0].is<int>());
}
SECTION("array subscript") {
const char* str = "hello";
JsonArray& arr = _jsonBuffer.createArray();
arr.add(str);
_array.add(arr[0]);
REQUIRE(str == _array[0]);
}
SECTION("object subscript") {
const char* str = "hello";
JsonObject& obj = _jsonBuffer.createObject();
obj["x"] = str;
_array.add(obj["x"]);
REQUIRE(str == _array[0]);
}
SECTION("should not duplicate const char*") {
_array.add("world");
const size_t expectedSize = JSON_ARRAY_SIZE(1);
REQUIRE(expectedSize == _jsonBuffer.size());
}
SECTION("should duplicate char*") {
_array.add(const_cast<char*>("world"));
const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6;
REQUIRE(expectedSize == _jsonBuffer.size());
}
SECTION("should duplicate std::string") {
_array.add(std::string("world"));
const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6;
REQUIRE(expectedSize == _jsonBuffer.size());
}
SECTION("should not duplicate RawJson(const char*)") {
_array.add(RawJson("{}"));
const size_t expectedSize = JSON_ARRAY_SIZE(1);
REQUIRE(expectedSize == _jsonBuffer.size());
}
SECTION("should duplicate RawJson(char*)") {
_array.add(RawJson(const_cast<char*>("{}")));
const size_t expectedSize = JSON_ARRAY_SIZE(1) + 3;
REQUIRE(expectedSize == _jsonBuffer.size());
}
}
+29
View File
@@ -0,0 +1,29 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonArray basics") {
DynamicJsonBuffer jb;
JsonArray& array = jb.createArray();
SECTION("SuccessIsTrue") {
REQUIRE(array.success());
}
SECTION("InitialSizeIsZero") {
REQUIRE(0U == array.size());
}
SECTION("CreateNestedArray") {
JsonArray& arr = array.createNestedArray();
REQUIRE(&arr == &array[0].as<JsonArray&>());
}
SECTION("CreateNestedObject") {
JsonObject& obj = array.createNestedObject();
REQUIRE(&obj == &array[0].as<JsonObject&>());
}
}
@@ -0,0 +1,63 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonArray::copyFrom()") {
SECTION("OneDimension") {
DynamicJsonBuffer jsonBuffer;
JsonArray& array = jsonBuffer.createArray();
char json[32];
int source[] = {1, 2, 3};
bool ok = array.copyFrom(source);
REQUIRE(ok);
array.printTo(json, sizeof(json));
REQUIRE(std::string("[1,2,3]") == json);
}
SECTION("OneDimension_JsonBufferTooSmall") {
const size_t SIZE = JSON_ARRAY_SIZE(2);
StaticJsonBuffer<SIZE> jsonBuffer;
JsonArray& array = jsonBuffer.createArray();
char json[32];
int source[] = {1, 2, 3};
bool ok = array.copyFrom(source);
REQUIRE_FALSE(ok);
array.printTo(json, sizeof(json));
REQUIRE(std::string("[1,2]") == json);
}
SECTION("TwoDimensions") {
DynamicJsonBuffer jsonBuffer;
JsonArray& array = jsonBuffer.createArray();
char json[32];
int source[][3] = {{1, 2, 3}, {4, 5, 6}};
bool ok = array.copyFrom(source);
REQUIRE(ok);
array.printTo(json, sizeof(json));
REQUIRE(std::string("[[1,2,3],[4,5,6]]") == json);
}
SECTION("TwoDimensions_JsonBufferTooSmall") {
const size_t SIZE =
JSON_ARRAY_SIZE(2) + JSON_ARRAY_SIZE(3) + JSON_ARRAY_SIZE(2);
StaticJsonBuffer<SIZE> jsonBuffer;
JsonArray& array = jsonBuffer.createArray();
char json[32];
int source[][3] = {{1, 2, 3}, {4, 5, 6}};
bool ok = array.copyFrom(source);
REQUIRE_FALSE(ok);
array.printTo(json, sizeof(json));
REQUIRE(std::string("[[1,2,3],[4,5]]") == json);
}
}
+52
View File
@@ -0,0 +1,52 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonArray::copyTo()") {
DynamicJsonBuffer jsonBuffer;
SECTION("BiggerOneDimensionIntegerArray") {
char json[] = "[1,2,3]";
JsonArray& array = jsonBuffer.parseArray(json);
int destination[4] = {0};
size_t result = array.copyTo(destination);
REQUIRE(3 == result);
REQUIRE(1 == destination[0]);
REQUIRE(2 == destination[1]);
REQUIRE(3 == destination[2]);
REQUIRE(0 == destination[3]);
}
SECTION("SmallerOneDimensionIntegerArray") {
char json[] = "[1,2,3]";
JsonArray& array = jsonBuffer.parseArray(json);
int destination[2] = {0};
size_t result = array.copyTo(destination);
REQUIRE(2 == result);
REQUIRE(1 == destination[0]);
REQUIRE(2 == destination[1]);
}
SECTION("TwoOneDimensionIntegerArray") {
char json[] = "[[1,2],[3],[4]]";
JsonArray& array = jsonBuffer.parseArray(json);
int destination[3][2] = {{0}};
array.copyTo(destination);
REQUIRE(1 == destination[0][0]);
REQUIRE(2 == destination[0][1]);
REQUIRE(3 == destination[1][0]);
REQUIRE(0 == destination[1][1]);
REQUIRE(4 == destination[2][0]);
REQUIRE(0 == destination[2][1]);
}
}
@@ -0,0 +1,34 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
using namespace Catch::Matchers;
TEST_CASE("JsonArray::invalid()") {
SECTION("SubscriptFails") {
REQUIRE_FALSE(JsonArray::invalid()[0].success());
}
SECTION("AddFails") {
JsonArray& array = JsonArray::invalid();
array.add(1);
REQUIRE(0 == array.size());
}
SECTION("CreateNestedArrayFails") {
REQUIRE_FALSE(JsonArray::invalid().createNestedArray().success());
}
SECTION("CreateNestedObjectFails") {
REQUIRE_FALSE(JsonArray::invalid().createNestedObject().success());
}
SECTION("PrintToWritesBrackets") {
char buffer[32];
JsonArray::invalid().printTo(buffer, sizeof(buffer));
REQUIRE_THAT(buffer, Equals("[]"));
}
}
@@ -0,0 +1,38 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
template <typename TIterator>
static void run_iterator_test() {
StaticJsonBuffer<JSON_ARRAY_SIZE(2)> jsonBuffer;
JsonArray &array = jsonBuffer.createArray();
array.add(12);
array.add(34);
TIterator it = array.begin();
TIterator end = array.end();
REQUIRE(end != it);
REQUIRE(12 == it->template as<int>());
REQUIRE(12 == static_cast<int>(*it));
++it;
REQUIRE(end != it);
REQUIRE(34 == it->template as<int>());
REQUIRE(34 == static_cast<int>(*it));
++it;
REQUIRE(end == it);
}
TEST_CASE("JsonArray::begin()/end()") {
SECTION("Mutable") {
run_iterator_test<JsonArray::iterator>();
}
SECTION("Const") {
run_iterator_test<JsonArray::const_iterator>();
}
}
@@ -0,0 +1,75 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
static void check(JsonArray& array, std::string expected) {
std::string actual;
size_t actualLen = array.prettyPrintTo(actual);
size_t measuredLen = array.measurePrettyLength();
CHECK(actualLen == expected.size());
CHECK(measuredLen == expected.size());
REQUIRE(expected == actual);
}
TEST_CASE("JsonArray::prettyPrintTo()") {
DynamicJsonBuffer jb;
JsonArray& array = jb.createArray();
SECTION("Empty") {
check(array, "[]");
}
SECTION("OneElement") {
array.add(1);
check(array,
"[\r\n"
" 1\r\n"
"]");
}
SECTION("TwoElements") {
array.add(1);
array.add(2);
check(array,
"[\r\n"
" 1,\r\n"
" 2\r\n"
"]");
}
SECTION("EmptyNestedArrays") {
array.createNestedArray();
array.createNestedArray();
check(array,
"[\r\n"
" [],\r\n"
" []\r\n"
"]");
}
SECTION("NestedArrays") {
JsonArray& nested1 = array.createNestedArray();
nested1.add(1);
nested1.add(2);
JsonObject& nested2 = array.createNestedObject();
nested2["key"] = 3;
check(array,
"[\r\n"
" [\r\n"
" 1,\r\n"
" 2\r\n"
" ],\r\n"
" {\r\n"
" \"key\": 3\r\n"
" }\r\n"
"]");
}
}
+132
View File
@@ -0,0 +1,132 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
static void check(JsonArray &array, std::string expected) {
std::string actual;
size_t actualLen = array.printTo(actual);
REQUIRE(expected == actual);
REQUIRE(actualLen == expected.size());
size_t measuredLen = array.measureLength();
REQUIRE(measuredLen == expected.size());
}
TEST_CASE("JsonArray::printTo()") {
StaticJsonBuffer<JSON_ARRAY_SIZE(2)> jb;
JsonArray &array = jb.createArray();
SECTION("Empty") {
check(array, "[]");
}
SECTION("Null") {
array.add(static_cast<char *>(0));
check(array, "[null]");
}
SECTION("OneString") {
array.add("hello");
check(array, "[\"hello\"]");
}
SECTION("TwoStrings") {
array.add("hello");
array.add("world");
check(array, "[\"hello\",\"world\"]");
}
SECTION("OneStringOverCapacity") {
array.add("hello");
array.add("world");
array.add("lost");
check(array, "[\"hello\",\"world\"]");
}
SECTION("One double") {
array.add(3.1415927);
check(array, "[3.1415927]");
}
SECTION("OneInteger") {
array.add(1);
check(array, "[1]");
}
SECTION("TwoIntegers") {
array.add(1);
array.add(2);
check(array, "[1,2]");
}
SECTION("RawJson(const char*)") {
array.add(RawJson("{\"key\":\"value\"}"));
check(array, "[{\"key\":\"value\"}]");
}
SECTION("RawJson(char*)") {
DynamicJsonBuffer jb2;
JsonArray &arr = jb2.createArray();
char tmp[] = "{\"key\":\"value\"}";
arr.add(RawJson(tmp));
check(arr, "[{\"key\":\"value\"}]");
}
SECTION("OneIntegerOverCapacity") {
array.add(1);
array.add(2);
array.add(3);
check(array, "[1,2]");
}
SECTION("OneTrue") {
array.add(true);
check(array, "[true]");
}
SECTION("OneFalse") {
array.add(false);
check(array, "[false]");
}
SECTION("TwoBooleans") {
array.add(false);
array.add(true);
check(array, "[false,true]");
}
SECTION("OneBooleanOverCapacity") {
array.add(false);
array.add(true);
array.add(false);
check(array, "[false,true]");
}
SECTION("OneEmptyNestedArray") {
array.createNestedArray();
check(array, "[[]]");
}
SECTION("OneEmptyNestedHash") {
array.createNestedObject();
check(array, "[{}]");
}
}
+68
View File
@@ -0,0 +1,68 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonArray::remove()") {
DynamicJsonBuffer _jsonBuffer;
JsonArray& _array = _jsonBuffer.createArray();
_array.add(1);
_array.add(2);
_array.add(3);
SECTION("RemoveFirstByIndex") {
_array.remove(0);
REQUIRE(2 == _array.size());
REQUIRE(_array[0] == 2);
REQUIRE(_array[1] == 3);
}
SECTION("RemoveMiddleByIndex") {
_array.remove(1);
REQUIRE(2 == _array.size());
REQUIRE(_array[0] == 1);
REQUIRE(_array[1] == 3);
}
SECTION("RemoveLastByIndex") {
_array.remove(2);
REQUIRE(2 == _array.size());
REQUIRE(_array[0] == 1);
REQUIRE(_array[1] == 2);
}
SECTION("RemoveFirstByIterator") {
JsonArray::iterator it = _array.begin();
_array.remove(it);
REQUIRE(2 == _array.size());
REQUIRE(_array[0] == 2);
REQUIRE(_array[1] == 3);
}
SECTION("RemoveMiddleByIterator") {
JsonArray::iterator it = _array.begin();
++it;
_array.remove(it);
REQUIRE(2 == _array.size());
REQUIRE(_array[0] == 1);
REQUIRE(_array[1] == 3);
}
SECTION("RemoveLastByIterator") {
JsonArray::iterator it = _array.begin();
++it;
++it;
_array.remove(it);
REQUIRE(2 == _array.size());
REQUIRE(_array[0] == 1);
REQUIRE(_array[1] == 2);
}
}
+98
View File
@@ -0,0 +1,98 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
using namespace Catch::Matchers;
TEST_CASE("JsonArray::set()") {
DynamicJsonBuffer _jsonBuffer;
JsonArray& _array = _jsonBuffer.createArray();
_array.add(0);
SECTION("int") {
_array.set(0, 123);
REQUIRE(123 == _array[0].as<int>());
REQUIRE(_array[0].is<int>());
REQUIRE_FALSE(_array[0].is<bool>());
}
SECTION("double") {
_array.set(0, 123.45);
REQUIRE(123.45 == _array[0].as<double>());
REQUIRE(_array[0].is<double>());
REQUIRE_FALSE(_array[0].is<int>());
}
SECTION("bool") {
_array.set(0, true);
REQUIRE(true == _array[0].as<bool>());
REQUIRE(_array[0].is<bool>());
REQUIRE_FALSE(_array[0].is<int>());
}
SECTION("const char*") {
_array.set(0, "hello");
REQUIRE_THAT(_array[0].as<const char*>(), Equals("hello"));
REQUIRE(_array[0].is<const char*>());
REQUIRE_FALSE(_array[0].is<int>());
}
SECTION("nested array") {
JsonArray& arr = _jsonBuffer.createArray();
_array.set(0, arr);
REQUIRE(&arr == &_array[0].as<JsonArray&>());
REQUIRE(_array[0].is<JsonArray&>());
REQUIRE_FALSE(_array[0].is<int>());
}
SECTION("nested object") {
JsonObject& obj = _jsonBuffer.createObject();
_array.set(0, obj);
REQUIRE(&obj == &_array[0].as<JsonObject&>());
REQUIRE(_array[0].is<JsonObject&>());
REQUIRE_FALSE(_array[0].is<int>());
}
SECTION("array subscript") {
JsonArray& arr = _jsonBuffer.createArray();
arr.add("hello");
_array.set(0, arr[0]);
REQUIRE_THAT(_array[0].as<char*>(), Equals("hello"));
}
SECTION("object subscript") {
JsonObject& obj = _jsonBuffer.createObject();
obj["x"] = "hello";
_array.set(0, obj["x"]);
REQUIRE_THAT(_array[0].as<char*>(), Equals("hello"));
}
SECTION("should not duplicate const char*") {
_array.set(0, "world");
const size_t expectedSize = JSON_ARRAY_SIZE(1);
REQUIRE(expectedSize == _jsonBuffer.size());
}
SECTION("should duplicate char*") {
_array.set(0, const_cast<char*>("world"));
const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6;
REQUIRE(expectedSize == _jsonBuffer.size());
}
SECTION("should duplicate std::string") {
_array.set(0, std::string("world"));
const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6;
REQUIRE(expectedSize == _jsonBuffer.size());
}
}
+35
View File
@@ -0,0 +1,35 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonArray::size()") {
DynamicJsonBuffer _jsonBuffer;
JsonArray& _array = _jsonBuffer.createArray();
SECTION("increases after add()") {
_array.add("hello");
REQUIRE(1U == _array.size());
_array.add("world");
REQUIRE(2U == _array.size());
}
SECTION("remains the same after set()") {
_array.add("hello");
REQUIRE(1U == _array.size());
_array.set(0, "hello");
REQUIRE(1U == _array.size());
}
SECTION("remains the same after assigment") {
_array.add("hello");
REQUIRE(1U == _array.size());
_array[0] = "hello";
REQUIRE(1U == _array.size());
}
}
@@ -0,0 +1,119 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <stdint.h>
#include <catch.hpp>
TEST_CASE("JsonArray::operator[]") {
DynamicJsonBuffer _jsonBuffer;
JsonArray& _array = _jsonBuffer.createArray();
_array.add(0);
SECTION("int") {
_array[0] = 123;
REQUIRE(123 == _array[0].as<int>());
REQUIRE(true == _array[0].is<int>());
REQUIRE(false == _array[0].is<bool>());
}
#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64
SECTION("long long") {
_array[0] = 9223372036854775807;
REQUIRE(9223372036854775807 == _array[0].as<long long>());
REQUIRE(true == _array[0].is<int>());
REQUIRE(false == _array[0].is<bool>());
}
#endif
SECTION("double") {
_array[0] = 123.45;
REQUIRE(123.45 == _array[0].as<double>());
REQUIRE(true == _array[0].is<double>());
REQUIRE(false == _array[0].is<int>());
}
SECTION("bool") {
_array[0] = true;
REQUIRE(true == _array[0].as<bool>());
REQUIRE(true == _array[0].is<bool>());
REQUIRE(false == _array[0].is<int>());
}
SECTION("const char*") {
const char* str = "hello";
_array[0] = str;
REQUIRE(str == _array[0].as<const char*>());
REQUIRE(str == _array[0].as<char*>()); // <- short hand
REQUIRE(true == _array[0].is<const char*>());
REQUIRE(false == _array[0].is<int>());
}
SECTION("nested array") {
JsonArray& arr = _jsonBuffer.createArray();
_array[0] = arr;
REQUIRE(&arr == &_array[0].as<JsonArray&>());
REQUIRE(&arr == &_array[0].as<JsonArray>()); // <- short hand
REQUIRE(&arr == &_array[0].as<const JsonArray&>());
REQUIRE(&arr == &_array[0].as<const JsonArray>()); // <- short hand
REQUIRE(true == _array[0].is<JsonArray&>());
REQUIRE(false == _array[0].is<int>());
}
SECTION("nested object") {
JsonObject& obj = _jsonBuffer.createObject();
_array[0] = obj;
REQUIRE(&obj == &_array[0].as<JsonObject&>());
REQUIRE(&obj == &_array[0].as<JsonObject>()); // <- short hand
REQUIRE(&obj == &_array[0].as<const JsonObject&>());
REQUIRE(&obj == &_array[0].as<const JsonObject>()); // <- short hand
REQUIRE(true == _array[0].is<JsonObject&>());
REQUIRE(false == _array[0].is<int>());
}
SECTION("array subscript") {
JsonArray& arr = _jsonBuffer.createArray();
const char* str = "hello";
arr.add(str);
_array[0] = arr[0];
REQUIRE(str == _array[0]);
}
SECTION("object subscript") {
JsonObject& obj = _jsonBuffer.createObject();
const char* str = "hello";
obj["x"] = str;
_array[0] = obj["x"];
REQUIRE(str == _array[0]);
}
SECTION("should not duplicate const char*") {
_array[0] = "world";
const size_t expectedSize = JSON_ARRAY_SIZE(1);
REQUIRE(expectedSize == _jsonBuffer.size());
}
SECTION("should duplicate char*") {
_array[0] = const_cast<char*>("world");
const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6;
REQUIRE(expectedSize == _jsonBuffer.size());
}
SECTION("should duplicate std::string") {
_array[0] = std::string("world");
const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6;
REQUIRE(expectedSize == _jsonBuffer.size());
}
}
@@ -0,0 +1,14 @@
# ArduinoJson - arduinojson.org
# Copyright Benoit Blanchon 2014-2018
# MIT License
add_executable(JsonBufferTests
nested.cpp
nestingLimit.cpp
parse.cpp
parseArray.cpp
parseObject.cpp
)
target_link_libraries(JsonBufferTests catch)
add_test(JsonBuffer JsonBufferTests)
@@ -0,0 +1,63 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonBuffer nested objects") {
SECTION("ArrayNestedInObject") {
DynamicJsonBuffer jsonBuffer;
char jsonString[] = " { \"ab\" : [ 1 , 2 ] , \"cd\" : [ 3 , 4 ] } ";
JsonObject &object = jsonBuffer.parseObject(jsonString);
JsonArray &array1 = object["ab"];
const JsonArray &array2 = object["cd"];
JsonArray &array3 = object["ef"];
REQUIRE(true == object.success());
REQUIRE(true == array1.success());
REQUIRE(true == array2.success());
REQUIRE(false == array3.success());
REQUIRE(2 == array1.size());
REQUIRE(2 == array2.size());
REQUIRE(0 == array3.size());
REQUIRE(1 == array1[0].as<int>());
REQUIRE(2 == array1[1].as<int>());
REQUIRE(3 == array2[0].as<int>());
REQUIRE(4 == array2[1].as<int>());
REQUIRE(0 == array3[0].as<int>());
}
SECTION("ObjectNestedInArray") {
DynamicJsonBuffer jsonBuffer;
char jsonString[] =
" [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] ";
JsonArray &array = jsonBuffer.parseArray(jsonString);
JsonObject &object1 = array[0];
const JsonObject &object2 = array[1];
JsonObject &object3 = array[2];
REQUIRE(true == array.success());
REQUIRE(true == object1.success());
REQUIRE(true == object2.success());
REQUIRE(false == object3.success());
REQUIRE(2 == object1.size());
REQUIRE(2 == object2.size());
REQUIRE(0 == object3.size());
REQUIRE(1 == object1["a"].as<int>());
REQUIRE(2 == object1["b"].as<int>());
REQUIRE(3 == object2["c"].as<int>());
REQUIRE(4 == object2["d"].as<int>());
REQUIRE(0 == object3["e"].as<int>());
}
}
@@ -0,0 +1,48 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
bool tryParseArray(const char *json, uint8_t nestingLimit) {
DynamicJsonBuffer buffer;
return buffer.parseArray(json, nestingLimit).success();
}
bool tryParseObject(const char *json, uint8_t nestingLimit) {
DynamicJsonBuffer buffer;
return buffer.parseObject(json, nestingLimit).success();
}
TEST_CASE("JsonParser nestingLimit") {
SECTION("ParseArrayWithNestingLimit0") {
REQUIRE(true == tryParseArray("[]", 0));
REQUIRE(false == tryParseArray("[[]]", 0));
}
SECTION("ParseArrayWithNestingLimit1") {
REQUIRE(true == tryParseArray("[[]]", 1));
REQUIRE(false == tryParseArray("[[[]]]", 1));
}
SECTION("ParseArrayWithNestingLimit2") {
REQUIRE(true == tryParseArray("[[[]]]", 2));
REQUIRE(false == tryParseArray("[[[[]]]]", 2));
}
SECTION("ParseObjectWithNestingLimit0") {
REQUIRE(true == tryParseObject("{}", 0));
REQUIRE(false == tryParseObject("{\"key\":{}}", 0));
}
SECTION("ParseObjectWithNestingLimit1") {
REQUIRE(true == tryParseObject("{\"key\":{}}", 1));
REQUIRE(false == tryParseObject("{\"key\":{\"key\":{}}}", 1));
}
SECTION("ParseObjectWithNestingLimit2") {
REQUIRE(true == tryParseObject("{\"key\":{\"key\":{}}}", 2));
REQUIRE(false == tryParseObject("{\"key\":{\"key\":{\"key\":{}}}}", 2));
}
}
+80
View File
@@ -0,0 +1,80 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
using namespace Catch::Matchers;
TEST_CASE("JsonBuffer::parse()") {
DynamicJsonBuffer jb;
SECTION("EmptyObject") {
JsonVariant variant = jb.parse("{}");
REQUIRE(variant.success());
REQUIRE(variant.is<JsonObject>());
}
SECTION("EmptyArray") {
JsonVariant variant = jb.parse("[]");
REQUIRE(variant.success());
REQUIRE(variant.is<JsonArray>());
}
SECTION("Integer") {
JsonVariant variant = jb.parse("-42");
REQUIRE(variant.success());
REQUIRE(variant.is<int>());
REQUIRE_FALSE(variant.is<bool>());
REQUIRE(variant == -42);
}
SECTION("Double") {
JsonVariant variant = jb.parse("-1.23e+4");
REQUIRE(variant.success());
REQUIRE_FALSE(variant.is<int>());
REQUIRE(variant.is<double>());
REQUIRE(variant.as<double>() == Approx(-1.23e+4));
}
SECTION("Double quoted string") {
JsonVariant variant = jb.parse("\"hello world\"");
REQUIRE(variant.success());
REQUIRE(variant.is<char*>());
REQUIRE_THAT(variant.as<char*>(), Equals("hello world"));
}
SECTION("Single quoted string") {
JsonVariant variant = jb.parse("\'hello world\'");
REQUIRE(variant.success());
REQUIRE(variant.is<char*>());
REQUIRE_THAT(variant.as<char*>(), Equals("hello world"));
}
SECTION("True") {
JsonVariant variant = jb.parse("true");
REQUIRE(variant.success());
REQUIRE(variant.is<bool>());
REQUIRE(variant == true);
}
SECTION("False") {
JsonVariant variant = jb.parse("false");
REQUIRE(variant.success());
REQUIRE(variant.is<bool>());
REQUIRE(variant == false);
}
SECTION("OpenBrace") {
JsonVariant variant = jb.parse("{");
REQUIRE_FALSE(variant.success());
}
SECTION("Incomplete string") {
JsonVariant variant = jb.parse("\"hello");
REQUIRE(variant.success());
REQUIRE(variant.is<char*>());
REQUIRE_THAT(variant.as<char*>(), Equals("hello"));
}
}
@@ -0,0 +1,318 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonBuffer::parseArray()") {
DynamicJsonBuffer jb;
SECTION("EmptyArray") {
JsonArray& arr = jb.parseArray("[]");
REQUIRE(arr.success());
REQUIRE(0 == arr.size());
}
SECTION("MissingOpeningBracket") {
JsonArray& arr = jb.parseArray("]");
REQUIRE_FALSE(arr.success());
}
SECTION("ArrayWithNoEnd") {
JsonArray& arr = jb.parseArray("[");
REQUIRE_FALSE(arr.success());
}
SECTION("EmptyArrayWithLeadingSpaces") {
JsonArray& arr = jb.parseArray(" []");
REQUIRE(arr.success());
REQUIRE(0 == arr.size());
}
SECTION("Garbage") {
JsonArray& arr = jb.parseArray("%*$£¤");
REQUIRE_FALSE(arr.success());
}
SECTION("OneInteger") {
JsonArray& arr = jb.parseArray("[42]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == 42);
}
SECTION("OneIntegerWithSpacesBefore") {
JsonArray& arr = jb.parseArray("[ \t\r\n42]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == 42);
}
SECTION("OneIntegerWithSpaceAfter") {
JsonArray& arr = jb.parseArray("[42 \t\r\n]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == 42);
}
SECTION("TwoIntegers") {
JsonArray& arr = jb.parseArray("[42,84]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == 42);
REQUIRE(arr[1] == 84);
}
SECTION("TwoDoubles") {
JsonArray& arr = jb.parseArray("[4.2,1e2]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == 4.2);
REQUIRE(arr[1] == 1e2);
}
SECTION("UnsignedLong") {
JsonArray& arr = jb.parseArray("[4294967295]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == 4294967295UL);
}
SECTION("TwoBooleans") {
JsonArray& arr = jb.parseArray("[true,false]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == true);
REQUIRE(arr[1] == false);
}
SECTION("TwoNulls") {
JsonArray& arr = jb.parseArray("[null,null]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0].as<char*>() == 0);
REQUIRE(arr[1].as<char*>() == 0);
}
SECTION("TwoStringsDoubleQuotes") {
JsonArray& arr = jb.parseArray("[ \"hello\" , \"world\" ]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("TwoStringsSingleQuotes") {
JsonArray& arr = jb.parseArray("[ 'hello' , 'world' ]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("TwoStringsNoQuotes") {
JsonArray& arr = jb.parseArray("[ hello , world ]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("EmptyStringsDoubleQuotes") {
JsonArray& arr = jb.parseArray("[\"\",\"\"]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "");
REQUIRE(arr[1] == "");
}
SECTION("EmptyStringSingleQuotes") {
JsonArray& arr = jb.parseArray("[\'\',\'\']");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "");
REQUIRE(arr[1] == "");
}
SECTION("EmptyStringNoQuotes") {
JsonArray& arr = jb.parseArray("[,]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "");
REQUIRE(arr[1] == "");
}
SECTION("ClosingDoubleQuoteMissing") {
JsonArray& arr = jb.parseArray("[\"]");
REQUIRE_FALSE(arr.success());
}
SECTION("ClosingSignleQuoteMissing") {
JsonArray& arr = jb.parseArray("[\']");
REQUIRE_FALSE(arr.success());
}
SECTION("StringWithEscapedChars") {
JsonArray& arr = jb.parseArray("[\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "1\"2\\3/4\b5\f6\n7\r8\t9");
}
SECTION("StringWithUnterminatedEscapeSequence") {
JsonArray& arr = jb.parseArray("\"\\\0\"", 4);
REQUIRE_FALSE(arr.success());
}
SECTION("CCommentBeforeOpeningBracket") {
JsonArray& arr = jb.parseArray("/*COMMENT*/ [\"hello\"]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CCommentAfterOpeningBracket") {
JsonArray& arr = jb.parseArray("[/*COMMENT*/ \"hello\"]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CCommentBeforeClosingBracket") {
JsonArray& arr = jb.parseArray("[\"hello\"/*COMMENT*/]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CCommentAfterClosingBracket") {
JsonArray& arr = jb.parseArray("[\"hello\"]/*COMMENT*/");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CCommentBeforeComma") {
JsonArray& arr = jb.parseArray("[\"hello\"/*COMMENT*/,\"world\"]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("CCommentAfterComma") {
JsonArray& arr = jb.parseArray("[\"hello\",/*COMMENT*/ \"world\"]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("CppCommentBeforeOpeningBracket") {
JsonArray& arr = jb.parseArray("//COMMENT\n\t[\"hello\"]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CppCommentAfterOpeningBracket") {
JsonArray& arr = jb.parseArray("[//COMMENT\n\"hello\"]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CppCommentBeforeClosingBracket") {
JsonArray& arr = jb.parseArray("[\"hello\"//COMMENT\r\n]");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CppCommentAfterClosingBracket") {
JsonArray& arr = jb.parseArray("[\"hello\"]//COMMENT\n");
REQUIRE(arr.success());
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "hello");
}
SECTION("CppCommentBeforeComma") {
JsonArray& arr = jb.parseArray("[\"hello\"//COMMENT\n,\"world\"]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("CppCommentAfterComma") {
JsonArray& arr = jb.parseArray("[\"hello\",//COMMENT\n\"world\"]");
REQUIRE(arr.success());
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == "hello");
REQUIRE(arr[1] == "world");
}
SECTION("InvalidCppComment") {
JsonArray& arr = jb.parseArray("[/COMMENT\n]");
REQUIRE_FALSE(arr.success());
}
SECTION("InvalidComment") {
JsonArray& arr = jb.parseArray("[/*/\n]");
REQUIRE_FALSE(arr.success());
}
SECTION("UnfinishedCComment") {
JsonArray& arr = jb.parseArray("[/*COMMENT]");
REQUIRE_FALSE(arr.success());
}
SECTION("EndsInCppComment") {
JsonArray& arr = jb.parseArray("[//COMMENT");
REQUIRE_FALSE(arr.success());
}
SECTION("AfterClosingStar") {
JsonArray& arr = jb.parseArray("[/*COMMENT*");
REQUIRE_FALSE(arr.success());
}
SECTION("DeeplyNested") {
JsonArray& arr =
jb.parseArray("[[[[[[[[[[[[[[[[[[[\"Not too deep\"]]]]]]]]]]]]]]]]]]]");
REQUIRE(arr.success());
}
}
@@ -0,0 +1,170 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonBuffer::parseObject()") {
DynamicJsonBuffer jb;
SECTION("An empty object") {
JsonObject& obj = jb.parseObject("{}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 0);
}
SECTION("Quotes") {
SECTION("Double quotes") {
JsonObject& obj = jb.parseObject("{\"key\":\"value\"}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value");
}
SECTION("Single quotes") {
JsonObject& obj = jb.parseObject("{'key':'value'}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value");
}
SECTION("No quotes") {
JsonObject& obj = jb.parseObject("{key:value}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value");
}
SECTION("No quotes, allow underscore in key") {
JsonObject& obj = jb.parseObject("{_k_e_y_:42}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 1);
REQUIRE(obj["_k_e_y_"] == 42);
}
}
SECTION("Spaces") {
SECTION("Before the key") {
JsonObject& obj = jb.parseObject("{ \"key\":\"value\"}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value");
}
SECTION("After the key") {
JsonObject& obj = jb.parseObject("{\"key\" :\"value\"}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value");
}
SECTION("Before the value") {
JsonObject& obj = jb.parseObject("{\"key\": \"value\"}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value");
}
SECTION("After the value") {
JsonObject& obj = jb.parseObject("{\"key\":\"value\" }");
REQUIRE(obj.success());
REQUIRE(obj.size() == 1);
REQUIRE(obj["key"] == "value");
}
SECTION("Before the colon") {
JsonObject& obj =
jb.parseObject("{\"key1\":\"value1\" ,\"key2\":\"value2\"}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == "value1");
REQUIRE(obj["key2"] == "value2");
}
SECTION("After the colon") {
JsonObject& obj =
jb.parseObject("{\"key1\":\"value1\" ,\"key2\":\"value2\"}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == "value1");
REQUIRE(obj["key2"] == "value2");
}
}
SECTION("Values types") {
SECTION("String") {
JsonObject& obj =
jb.parseObject("{\"key1\":\"value1\",\"key2\":\"value2\"}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == "value1");
REQUIRE(obj["key2"] == "value2");
}
SECTION("Integer") {
JsonObject& obj = jb.parseObject("{\"key1\":42,\"key2\":-42}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == 42);
REQUIRE(obj["key2"] == -42);
}
SECTION("Double") {
JsonObject& obj = jb.parseObject("{\"key1\":12.345,\"key2\":-7E89}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == 12.345);
REQUIRE(obj["key2"] == -7E89);
}
SECTION("Booleans") {
JsonObject& obj = jb.parseObject("{\"key1\":true,\"key2\":false}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"] == true);
REQUIRE(obj["key2"] == false);
}
SECTION("Null") {
JsonObject& obj = jb.parseObject("{\"key1\":null,\"key2\":null}");
REQUIRE(obj.success());
REQUIRE(obj.size() == 2);
REQUIRE(obj["key1"].as<char*>() == 0);
REQUIRE(obj["key2"].as<char*>() == 0);
}
}
SECTION("Misc") {
SECTION("The opening brace is missing") {
JsonObject& obj = jb.parseObject("}");
REQUIRE_FALSE(obj.success());
}
SECTION("The closing brace is missing") {
JsonObject& obj = jb.parseObject("{");
REQUIRE_FALSE(obj.success());
}
SECTION("A quoted key without value") {
JsonObject& obj = jb.parseObject("{\"key\"}");
REQUIRE_FALSE(obj.success());
}
SECTION("A non-quoted key without value") {
JsonObject& obj = jb.parseObject("{key}");
REQUIRE_FALSE(obj.success());
}
SECTION("A dangling comma") {
JsonObject& obj = jb.parseObject("{\"key1\":\"value1\",}");
REQUIRE_FALSE(obj.success());
REQUIRE(obj.size() == 0);
}
SECTION("null as a key") {
JsonObject& obj = jb.parseObject("null:\"value\"}");
REQUIRE_FALSE(obj.success());
}
}
}
@@ -0,0 +1,20 @@
# ArduinoJson - arduinojson.org
# Copyright Benoit Blanchon 2014-2018
# MIT License
add_executable(JsonObjectTests
basics.cpp
containsKey.cpp
get.cpp
invalid.cpp
iterator.cpp
prettyPrintTo.cpp
printTo.cpp
remove.cpp
set.cpp
size.cpp
subscript.cpp
)
target_link_libraries(JsonObjectTests catch)
add_test(JsonObject JsonObjectTests)
@@ -0,0 +1,19 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonObject basics") {
DynamicJsonBuffer _jsonBuffer;
JsonObject& _object = _jsonBuffer.createObject();
SECTION("InitialSizeIsZero") {
REQUIRE(0 == _object.size());
}
SECTION("SuccessIsTrue") {
REQUIRE(_object.success());
}
}
@@ -0,0 +1,30 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonObject::containsKey()") {
DynamicJsonBuffer _jsonBuffer;
JsonObject& _object = _jsonBuffer.createObject();
SECTION("ContainsKeyReturnsFalseForNonExistingKey") {
_object.set("hello", 42);
REQUIRE(false == _object.containsKey("world"));
}
SECTION("ContainsKeyReturnsTrueForDefinedValue") {
_object.set("hello", 42);
REQUIRE(true == _object.containsKey("hello"));
}
SECTION("ContainsKeyReturnsFalseAfterRemove") {
_object.set("hello", 42);
_object.remove("hello");
REQUIRE(false == _object.containsKey("hello"));
}
}
+19
View File
@@ -0,0 +1,19 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
using namespace Catch::Matchers;
TEST_CASE("JsonObject::get()") {
DynamicJsonBuffer jb;
JsonObject& obj = jb.createObject();
SECTION("GetConstCharPointer_GivenStringLiteral") {
obj.set("hello", "world");
const char* value = obj.get<const char*>("hello");
REQUIRE_THAT(value, Equals("world"));
}
}
@@ -0,0 +1,35 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
using namespace Catch::Matchers;
TEST_CASE("JsonObject::invalid()") {
JsonObject& obj = JsonObject::invalid();
SECTION("SubscriptFails") {
REQUIRE_FALSE(obj["key"].success());
}
SECTION("AddFails") {
obj.set("hello", "world");
REQUIRE(0 == obj.size());
}
SECTION("CreateNestedArrayFails") {
REQUIRE_FALSE(obj.createNestedArray("hello").success());
}
SECTION("CreateNestedObjectFails") {
REQUIRE_FALSE(obj.createNestedObject("world").success());
}
SECTION("PrintToWritesBraces") {
char buffer[32];
obj.printTo(buffer, sizeof(buffer));
REQUIRE_THAT(buffer, Equals("{}"));
}
}
@@ -0,0 +1,51 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
using namespace Catch::Matchers;
TEST_CASE("JsonObject::begin()/end()") {
StaticJsonBuffer<JSON_OBJECT_SIZE(2)> jb;
JsonObject& obj = jb.createObject();
obj["ab"] = 12;
obj["cd"] = 34;
SECTION("NonConstIterator") {
JsonObject::iterator it = obj.begin();
REQUIRE(obj.end() != it);
REQUIRE_THAT(it->key, Equals("ab"));
REQUIRE(12 == it->value);
it->key = "a.b";
it->value = 1.2;
++it;
REQUIRE(obj.end() != it);
REQUIRE_THAT(it->key, Equals("cd"));
REQUIRE(34 == it->value);
it->key = "c.d";
it->value = 3.4;
++it;
REQUIRE(obj.end() == it);
REQUIRE(2 == obj.size());
REQUIRE(1.2 == obj["a.b"]);
REQUIRE(3.4 == obj["c.d"]);
}
SECTION("ConstIterator") {
const JsonObject& const_object = obj;
JsonObject::const_iterator it = const_object.begin();
REQUIRE(const_object.end() != it);
REQUIRE_THAT(it->key, Equals("ab"));
REQUIRE(12 == it->value);
++it;
REQUIRE(const_object.end() != it);
REQUIRE_THAT(it->key, Equals("cd"));
REQUIRE(34 == it->value);
++it;
REQUIRE(const_object.end() == it);
}
}
@@ -0,0 +1,76 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
#include <string>
void check(const JsonObject &obj, const std::string expected) {
char json[256];
size_t actualLen = obj.prettyPrintTo(json);
size_t measuredLen = obj.measurePrettyLength();
REQUIRE(json == expected);
REQUIRE(expected.size() == actualLen);
REQUIRE(expected.size() == measuredLen);
}
TEST_CASE("JsonObject::prettyPrintTo()") {
DynamicJsonBuffer jb;
JsonObject &obj = jb.createObject();
SECTION("EmptyObject") {
check(obj, "{}");
}
SECTION("OneMember") {
obj["key"] = "value";
check(obj,
"{\r\n"
" \"key\": \"value\"\r\n"
"}");
}
SECTION("TwoMembers") {
obj["key1"] = "value1";
obj["key2"] = "value2";
check(obj,
"{\r\n"
" \"key1\": \"value1\",\r\n"
" \"key2\": \"value2\"\r\n"
"}");
}
SECTION("EmptyNestedContainers") {
obj.createNestedObject("key1");
obj.createNestedArray("key2");
check(obj,
"{\r\n"
" \"key1\": {},\r\n"
" \"key2\": []\r\n"
"}");
}
SECTION("NestedContainers") {
JsonObject &nested1 = obj.createNestedObject("key1");
nested1["a"] = 1;
JsonArray &nested2 = obj.createNestedArray("key2");
nested2.add(2);
check(obj,
"{\r\n"
" \"key1\": {\r\n"
" \"a\": 1\r\n"
" },\r\n"
" \"key2\": [\r\n"
" 2\r\n"
" ]\r\n"
"}");
}
}
+109
View File
@@ -0,0 +1,109 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
#include <string>
void check(const JsonObject &obj, const std::string &expected) {
char actual[256];
size_t actualLen = obj.printTo(actual);
size_t measuredLen = obj.measureLength();
REQUIRE(expected == actual);
REQUIRE(expected.size() == actualLen);
REQUIRE(expected.size() == measuredLen);
}
TEST_CASE("JsonObject::printTo()") {
DynamicJsonBuffer _jsonBuffer;
JsonObject &obj = _jsonBuffer.createObject();
SECTION("EmptyObject") {
check(obj, "{}");
}
SECTION("TwoStrings") {
obj["key1"] = "value1";
obj.set("key2", "value2");
check(obj, "{\"key1\":\"value1\",\"key2\":\"value2\"}");
}
SECTION("RemoveFirst") {
obj["key1"] = "value1";
obj["key2"] = "value2";
obj.remove("key1");
check(obj, "{\"key2\":\"value2\"}");
}
SECTION("RemoveLast") {
obj["key1"] = "value1";
obj["key2"] = "value2";
obj.remove("key2");
check(obj, "{\"key1\":\"value1\"}");
}
SECTION("RemoveUnexistingKey") {
obj["key1"] = "value1";
obj["key2"] = "value2";
obj.remove("key3");
check(obj, "{\"key1\":\"value1\",\"key2\":\"value2\"}");
}
SECTION("ReplaceExistingKey") {
obj["key"] = "value1";
obj["key"] = "value2";
check(obj, "{\"key\":\"value2\"}");
}
SECTION("TwoIntegers") {
obj["a"] = 1;
obj.set("b", 2);
check(obj, "{\"a\":1,\"b\":2}");
}
SECTION("RawJson") {
obj["a"] = RawJson("[1,2]");
obj.set("b", RawJson("[4,5]"));
check(obj, "{\"a\":[1,2],\"b\":[4,5]}");
}
SECTION("Two doubles") {
obj["a"] = 12.34;
obj.set("b", 56.78);
check(obj, "{\"a\":12.34,\"b\":56.78}");
}
SECTION("TwoNull") {
obj["a"] = static_cast<char *>(0);
obj.set("b", static_cast<char *>(0));
check(obj, "{\"a\":null,\"b\":null}");
}
SECTION("TwoBooleans") {
obj["a"] = true;
obj.set("b", false);
check(obj, "{\"a\":true,\"b\":false}");
}
SECTION("ThreeNestedArrays") {
obj.createNestedArray("a");
obj["b"] = _jsonBuffer.createArray();
obj.set("c", _jsonBuffer.createArray());
check(obj, "{\"a\":[],\"b\":[],\"c\":[]}");
}
SECTION("ThreeNestedObjects") {
obj.createNestedObject("a");
obj["b"] = _jsonBuffer.createObject();
obj.set("c", _jsonBuffer.createObject());
check(obj, "{\"a\":{},\"b\":{},\"c\":{}}");
}
}
@@ -0,0 +1,41 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
#include <string>
TEST_CASE("JsonObject::remove()") {
DynamicJsonBuffer jb;
SECTION("SizeDecreased_WhenValuesAreRemoved") {
JsonObject& obj = jb.createObject();
obj["hello"] = 1;
obj.remove("hello");
REQUIRE(0 == obj.size());
}
SECTION("SizeUntouched_WhenRemoveIsCalledWithAWrongKey") {
JsonObject& obj = jb.createObject();
obj["hello"] = 1;
obj.remove("world");
REQUIRE(1 == obj.size());
}
SECTION("RemoveByIterator") {
JsonObject& obj = jb.parseObject("{\"a\":0,\"b\":1,\"c\":2}");
for (JsonObject::iterator it = obj.begin(); it != obj.end(); ++it) {
if (it->value == 1) obj.remove(it);
}
std::string result;
obj.printTo(result);
REQUIRE("{\"a\":0,\"c\":2}" == result);
}
}
+138
View File
@@ -0,0 +1,138 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
#include <string>
TEST_CASE("JsonObject::set()") {
DynamicJsonBuffer jb;
JsonObject& _object = jb.createObject();
SECTION("int") {
_object.set("hello", 123);
REQUIRE(123 == _object["hello"].as<int>());
REQUIRE(_object["hello"].is<int>());
REQUIRE_FALSE(_object["hello"].is<bool>());
}
SECTION("double") {
_object.set("hello", 123.45);
REQUIRE(123.45 == _object["hello"].as<double>());
REQUIRE(_object["hello"].is<double>());
REQUIRE_FALSE(_object["hello"].is<bool>());
}
SECTION("bool") {
_object.set("hello", true);
REQUIRE(_object["hello"].as<bool>());
REQUIRE(_object["hello"].is<bool>());
REQUIRE_FALSE(_object["hello"].is<long>());
}
SECTION("const char*") {
_object.set("hello", "h3110");
REQUIRE(std::string("h3110") == _object["hello"].as<const char*>());
REQUIRE(_object["hello"].is<const char*>());
REQUIRE_FALSE(_object["hello"].is<long>());
}
SECTION("nested array") {
JsonArray& arr = jb.createArray();
_object.set("hello", arr);
REQUIRE(&arr == &_object["hello"].as<JsonArray>());
REQUIRE(_object["hello"].is<JsonArray&>());
REQUIRE_FALSE(_object["hello"].is<JsonObject&>());
}
SECTION("nested object") {
JsonObject& obj = jb.createObject();
_object.set("hello", obj);
REQUIRE(&obj == &_object["hello"].as<JsonObject>());
REQUIRE(_object["hello"].is<JsonObject&>());
REQUIRE_FALSE(_object["hello"].is<JsonArray&>());
}
SECTION("array subscript") {
JsonArray& arr = jb.createArray();
arr.add(42);
_object.set("a", arr[0]);
REQUIRE(42 == _object["a"]);
}
SECTION("object subscript") {
JsonObject& obj = jb.createObject();
obj.set("x", 42);
_object.set("a", obj["x"]);
REQUIRE(42 == _object["a"]);
}
SECTION("returns true when allocation succeeds") {
StaticJsonBuffer<JSON_OBJECT_SIZE(1) + 15> jsonBuffer;
JsonObject& obj = jsonBuffer.createObject();
REQUIRE(true == obj.set(std::string("hello"), std::string("world")));
}
SECTION("returns false when allocation fails") {
StaticJsonBuffer<JSON_OBJECT_SIZE(1) + 10> jsonBuffer;
JsonObject& obj = jsonBuffer.createObject();
REQUIRE(false == obj.set(std::string("hello"), std::string("world")));
}
SECTION("should not duplicate const char*") {
_object.set("hello", "world");
const size_t expectedSize = JSON_OBJECT_SIZE(1);
REQUIRE(expectedSize == jb.size());
}
SECTION("should duplicate char* value") {
_object.set("hello", const_cast<char*>("world"));
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6;
REQUIRE(expectedSize == jb.size());
}
SECTION("should duplicate char* key") {
_object.set(const_cast<char*>("hello"), "world");
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6;
REQUIRE(expectedSize == jb.size());
}
SECTION("should duplicate char* key&value") {
_object.set(const_cast<char*>("hello"), const_cast<char*>("world"));
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12;
REQUIRE(expectedSize <= jb.size());
}
SECTION("should duplicate std::string value") {
_object.set("hello", std::string("world"));
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6;
REQUIRE(expectedSize == jb.size());
}
SECTION("should duplicate std::string key") {
_object.set(std::string("hello"), "world");
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6;
REQUIRE(expectedSize == jb.size());
}
SECTION("should duplicate std::string key&value") {
_object.set(std::string("hello"), std::string("world"));
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12;
REQUIRE(expectedSize <= jb.size());
}
}
+23
View File
@@ -0,0 +1,23 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
#include <string>
TEST_CASE("JsonObject::size()") {
DynamicJsonBuffer jb;
JsonObject& _object = jb.createObject();
SECTION("increases when values are added") {
_object.set("hello", 42);
REQUIRE(1 == _object.size());
}
SECTION("doesn't increase when the smae key is added twice") {
_object["hello"] = 1;
_object["hello"] = 2;
REQUIRE(1 == _object.size());
}
}
@@ -0,0 +1,152 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonObject::operator[]") {
DynamicJsonBuffer _jsonBuffer;
JsonObject& _object = _jsonBuffer.createObject();
SECTION("int") {
_object["hello"] = 123;
REQUIRE(123 == _object["hello"].as<int>());
REQUIRE(true == _object["hello"].is<int>());
REQUIRE(false == _object["hello"].is<bool>());
}
SECTION("volatile int") { // issue #415
volatile int i = 123;
_object["hello"] = i;
REQUIRE(123 == _object["hello"].as<int>());
REQUIRE(true == _object["hello"].is<int>());
REQUIRE(false == _object["hello"].is<bool>());
}
SECTION("double") {
_object["hello"] = 123.45;
REQUIRE(true == _object["hello"].is<double>());
REQUIRE(false == _object["hello"].is<long>());
REQUIRE(123.45 == _object["hello"].as<double>());
}
SECTION("bool") {
_object["hello"] = true;
REQUIRE(true == _object["hello"].is<bool>());
REQUIRE(false == _object["hello"].is<long>());
REQUIRE(true == _object["hello"].as<bool>());
}
SECTION("const char*") {
_object["hello"] = "h3110";
REQUIRE(true == _object["hello"].is<const char*>());
REQUIRE(false == _object["hello"].is<long>());
REQUIRE(std::string("h3110") == _object["hello"].as<const char*>());
REQUIRE(std::string("h3110") ==
_object["hello"].as<char*>()); // <- short hand
}
SECTION("array") {
JsonArray& arr = _jsonBuffer.createArray();
_object["hello"] = arr;
REQUIRE(&arr == &_object["hello"].as<JsonArray&>());
REQUIRE(&arr == &_object["hello"].as<JsonArray>()); // <- short hand
REQUIRE(&arr == &_object["hello"].as<const JsonArray&>());
REQUIRE(&arr == &_object["hello"].as<const JsonArray>()); // <- short hand
REQUIRE(true == _object["hello"].is<JsonArray&>());
REQUIRE(true == _object["hello"].is<JsonArray>());
REQUIRE(true == _object["hello"].is<const JsonArray&>());
REQUIRE(true == _object["hello"].is<const JsonArray>());
REQUIRE(false == _object["hello"].is<JsonObject&>());
}
SECTION("object") {
JsonObject& obj = _jsonBuffer.createObject();
_object["hello"] = obj;
REQUIRE(&obj == &_object["hello"].as<JsonObject&>());
REQUIRE(&obj == &_object["hello"].as<JsonObject>()); // <- short hand
REQUIRE(&obj == &_object["hello"].as<const JsonObject&>());
REQUIRE(&obj == &_object["hello"].as<const JsonObject>()); // <- short hand
REQUIRE(true == _object["hello"].is<JsonObject&>());
REQUIRE(true == _object["hello"].is<JsonObject>());
REQUIRE(true == _object["hello"].is<const JsonObject&>());
REQUIRE(true == _object["hello"].is<const JsonObject>());
REQUIRE(false == _object["hello"].is<JsonArray&>());
}
SECTION("array subscript") {
JsonArray& arr = _jsonBuffer.createArray();
arr.add(42);
_object["a"] = arr[0];
REQUIRE(42 == _object["a"]);
}
SECTION("object subscript") {
JsonObject& obj = _jsonBuffer.createObject();
obj.set("x", 42);
_object["a"] = obj["x"];
REQUIRE(42 == _object["a"]);
}
SECTION("char key[]") { // issue #423
char key[] = "hello";
_object[key] = 42;
REQUIRE(42 == _object[key]);
}
SECTION("should not duplicate const char*") {
_object["hello"] = "world";
const size_t expectedSize = JSON_OBJECT_SIZE(1);
REQUIRE(expectedSize == _jsonBuffer.size());
}
SECTION("should duplicate char* value") {
_object["hello"] = const_cast<char*>("world");
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6;
REQUIRE(expectedSize == _jsonBuffer.size());
}
SECTION("should duplicate char* key") {
_object[const_cast<char*>("hello")] = "world";
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6;
REQUIRE(expectedSize == _jsonBuffer.size());
}
SECTION("should duplicate char* key&value") {
_object[const_cast<char*>("hello")] = const_cast<char*>("world");
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12;
REQUIRE(expectedSize <= _jsonBuffer.size());
}
SECTION("should duplicate std::string value") {
_object["hello"] = std::string("world");
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6;
REQUIRE(expectedSize == _jsonBuffer.size());
}
SECTION("should duplicate std::string key") {
_object[std::string("hello")] = "world";
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6;
REQUIRE(expectedSize == _jsonBuffer.size());
}
SECTION("should duplicate std::string key&value") {
_object[std::string("hello")] = std::string("world");
const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12;
REQUIRE(expectedSize <= _jsonBuffer.size());
}
}
@@ -0,0 +1,19 @@
# ArduinoJson - arduinojson.org
# Copyright Benoit Blanchon 2014-2018
# MIT License
add_executable(JsonVariantTests
as.cpp
compare.cpp
copy.cpp
is.cpp
or.cpp
printTo.cpp
set_get.cpp
subscript.cpp
success.cpp
undefined.cpp
)
target_link_libraries(JsonVariantTests catch)
add_test(JsonVariant JsonVariantTests)
+232
View File
@@ -0,0 +1,232 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <stdint.h>
#include <catch.hpp>
static const char* null = 0;
TEST_CASE("JsonVariant::as()") {
SECTION("DoubleAsBool") {
JsonVariant variant = 4.2;
REQUIRE(variant.as<bool>());
}
SECTION("DoubleAsCstr") {
JsonVariant variant = 4.2;
REQUIRE_FALSE(variant.as<const char*>());
}
SECTION("DoubleAsString") {
JsonVariant variant = 4.2;
REQUIRE(std::string("4.2") == variant.as<std::string>());
}
SECTION("DoubleAsLong") {
JsonVariant variant = 4.2;
REQUIRE(4L == variant.as<long>());
}
SECTION("DoubleAsUnsigned") {
JsonVariant variant = 4.2;
REQUIRE(4U == variant.as<unsigned>());
}
SECTION("DoubleZeroAsBool") {
JsonVariant variant = 0.0;
REQUIRE_FALSE(variant.as<bool>());
}
SECTION("DoubleZeroAsLong") {
JsonVariant variant = 0.0;
REQUIRE(0L == variant.as<long>());
}
SECTION("FalseAsBool") {
JsonVariant variant = false;
REQUIRE_FALSE(variant.as<bool>());
}
SECTION("FalseAsDouble") {
JsonVariant variant = false;
REQUIRE(0.0 == variant.as<double>());
}
SECTION("FalseAsLong") {
JsonVariant variant = false;
REQUIRE(0L == variant.as<long>());
}
SECTION("FalseAsString") {
JsonVariant variant = false;
REQUIRE(std::string("false") == variant.as<std::string>());
}
SECTION("TrueAsBool") {
JsonVariant variant = true;
REQUIRE(variant.as<bool>());
}
SECTION("TrueAsDouble") {
JsonVariant variant = true;
REQUIRE(1.0 == variant.as<double>());
}
SECTION("TrueAsLong") {
JsonVariant variant = true;
REQUIRE(1L == variant.as<long>());
}
SECTION("TrueAsString") {
JsonVariant variant = true;
REQUIRE(std::string("true") == variant.as<std::string>());
}
SECTION("LongAsBool") {
JsonVariant variant = 42L;
REQUIRE(variant.as<bool>());
}
SECTION("LongZeroAsBool") {
JsonVariant variant = 0L;
REQUIRE_FALSE(variant.as<bool>());
}
SECTION("PositiveLongAsDouble") {
JsonVariant variant = 42L;
REQUIRE(42.0 == variant.as<double>());
}
SECTION("NegativeLongAsDouble") {
JsonVariant variant = -42L;
REQUIRE(-42.0 == variant.as<double>());
}
SECTION("LongAsString") {
JsonVariant variant = 42L;
REQUIRE(std::string("42") == variant.as<std::string>());
}
SECTION("LongZeroAsDouble") {
JsonVariant variant = 0L;
REQUIRE(0.0 == variant.as<double>());
}
SECTION("NullAsBool") {
JsonVariant variant = null;
REQUIRE_FALSE(variant.as<bool>());
}
SECTION("NullAsDouble") {
JsonVariant variant = null;
REQUIRE(0.0 == variant.as<double>());
}
SECTION("NullAsLong") {
JsonVariant variant = null;
REQUIRE(0L == variant.as<long>());
}
SECTION("NullAsString") {
JsonVariant variant = null;
REQUIRE(std::string("null") == variant.as<std::string>());
}
SECTION("NumberStringAsBool") {
JsonVariant variant = "42";
REQUIRE(variant.as<bool>());
}
SECTION("NumberStringAsLong") {
JsonVariant variant = "42";
REQUIRE(42L == variant.as<long>());
}
#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64
SECTION("NumberStringAsInt64Negative") {
JsonVariant variant = "-9223372036854775808";
REQUIRE(-9223372036854775807 - 1 == variant.as<long long>());
}
SECTION("NumberStringAsInt64Positive") {
JsonVariant variant = "9223372036854775807";
REQUIRE(9223372036854775807 == variant.as<long long>());
}
#endif
SECTION("RandomStringAsBool") {
JsonVariant variant = "hello";
REQUIRE_FALSE(variant.as<bool>());
}
SECTION("RandomStringAsLong") {
JsonVariant variant = "hello";
REQUIRE(0L == variant.as<long>());
}
SECTION("RandomStringAsConstCharPtr") {
JsonVariant variant = "hello";
REQUIRE(std::string("hello") == variant.as<const char*>());
}
SECTION("RandomStringAsCharPtr") {
JsonVariant variant = "hello";
REQUIRE(std::string("hello") == variant.as<char*>());
}
SECTION("RandomStringAsString") {
JsonVariant variant = "hello";
REQUIRE(std::string("hello") == variant.as<std::string>());
}
SECTION("TrueStringAsBool") {
JsonVariant variant = "true";
REQUIRE(variant.as<bool>());
}
SECTION("TrueStringAsLong") {
JsonVariant variant = "true";
REQUIRE(1L == variant.as<long>());
}
SECTION("ObjectAsString") {
DynamicJsonBuffer buffer;
JsonObject& obj = buffer.createObject();
obj["key"] = "value";
JsonVariant variant = obj;
REQUIRE(std::string("{\"key\":\"value\"}") == variant.as<std::string>());
}
SECTION("ArrayAsString") {
DynamicJsonBuffer buffer;
JsonArray& arr = buffer.createArray();
arr.add(4);
arr.add(2);
JsonVariant variant = arr;
REQUIRE(std::string("[4,2]") == variant.as<std::string>());
}
SECTION("ArrayAsJsonArray") {
DynamicJsonBuffer buffer;
JsonArray& arr = buffer.createArray();
JsonVariant variant = arr;
REQUIRE(&arr == &variant.as<JsonArray&>());
REQUIRE(&arr == &variant.as<JsonArray>()); // <- shorthand
}
SECTION("ObjectAsJsonObject") {
DynamicJsonBuffer buffer;
JsonObject& arr = buffer.createObject();
JsonVariant variant = arr;
REQUIRE(&arr == &variant.as<JsonObject&>());
REQUIRE(&arr == &variant.as<JsonObject>()); // <- shorthand
}
}
@@ -0,0 +1,232 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
template <typename T>
void checkEquals(JsonVariant a, T b) {
REQUIRE(b == a);
REQUIRE(a == b);
REQUIRE(b <= a);
REQUIRE(a <= b);
REQUIRE(b >= a);
REQUIRE(a >= b);
REQUIRE_FALSE(b != a);
REQUIRE_FALSE(a != b);
REQUIRE_FALSE(b > a);
REQUIRE_FALSE(a > b);
REQUIRE_FALSE(b < a);
REQUIRE_FALSE(a < b);
}
template <typename T>
void checkGreater(JsonVariant a, T b) {
REQUIRE(a > b);
REQUIRE(b < a);
REQUIRE(a != b);
REQUIRE(b != a);
REQUIRE_FALSE(a < b);
REQUIRE_FALSE(b > a);
REQUIRE_FALSE(a == b);
REQUIRE_FALSE(b == a);
}
template <typename T>
void checkLower(JsonVariant a, T b) {
REQUIRE(a < b);
REQUIRE(b > a);
REQUIRE(a != b);
REQUIRE(b != a);
REQUIRE_FALSE(a > b);
REQUIRE_FALSE(b < a);
REQUIRE_FALSE(a == b);
REQUIRE_FALSE(b == a);
}
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("StringLiteral") {
DynamicJsonBuffer jsonBuffer;
JsonVariant variant = jsonBuffer.parse("\"hello\"");
REQUIRE(variant == "hello");
REQUIRE_FALSE(variant != "hello");
REQUIRE(variant != "world");
REQUIRE_FALSE(variant == "world");
REQUIRE("hello" == variant);
REQUIRE_FALSE("hello" != variant);
REQUIRE("world" != variant);
REQUIRE_FALSE("world" == variant);
}
SECTION("String") {
DynamicJsonBuffer jsonBuffer;
JsonVariant variant = jsonBuffer.parse("\"hello\"");
REQUIRE(variant == std::string("hello"));
REQUIRE_FALSE(variant != std::string("hello"));
REQUIRE(variant != std::string("world"));
REQUIRE_FALSE(variant == std::string("world"));
REQUIRE(std::string("hello") == variant);
REQUIRE_FALSE(std::string("hello") != variant);
REQUIRE(std::string("world") != variant);
REQUIRE_FALSE(std::string("world") == variant);
}
SECTION("IntegerInVariant") {
JsonVariant variant1 = 42;
JsonVariant variant2 = 42;
JsonVariant variant3 = 666;
REQUIRE(variant1 == variant2);
REQUIRE_FALSE(variant1 != variant2);
REQUIRE(variant1 != variant3);
REQUIRE_FALSE(variant1 == variant3);
}
SECTION("StringInVariant") {
JsonVariant variant1 = "0hello" + 1; // make sure they have
JsonVariant variant2 = "1hello" + 1; // different addresses
JsonVariant variant3 = "world";
REQUIRE(variant1 == variant2);
REQUIRE_FALSE(variant1 != variant2);
REQUIRE(variant1 != variant3);
REQUIRE_FALSE(variant1 == variant3);
}
SECTION("DoubleInVariant") {
JsonVariant variant1 = 42.0;
JsonVariant variant2 = 42.0;
JsonVariant variant3 = 666.0;
REQUIRE(variant1 == variant2);
REQUIRE_FALSE(variant1 != variant2);
REQUIRE(variant1 != variant3);
REQUIRE_FALSE(variant1 == variant3);
}
SECTION("BoolInVariant") {
JsonVariant variant1 = true;
JsonVariant variant2 = true;
JsonVariant variant3 = false;
REQUIRE(variant1 == variant2);
REQUIRE_FALSE(variant1 != variant2);
REQUIRE(variant1 != variant3);
REQUIRE_FALSE(variant1 == variant3);
}
SECTION("ArrayInVariant") {
DynamicJsonBuffer jsonBuffer;
JsonArray& array1 = jsonBuffer.createArray();
JsonArray& array2 = jsonBuffer.createArray();
JsonVariant variant1 = array1;
JsonVariant variant2 = array1;
JsonVariant variant3 = array2;
REQUIRE(variant1 == variant2);
REQUIRE_FALSE(variant1 != variant2);
REQUIRE(variant1 != variant3);
REQUIRE_FALSE(variant1 == variant3);
}
SECTION("ObjectInVariant") {
DynamicJsonBuffer jsonBuffer;
JsonObject& obj1 = jsonBuffer.createObject();
JsonObject& obj2 = jsonBuffer.createObject();
JsonVariant variant1 = obj1;
JsonVariant variant2 = obj1;
JsonVariant variant3 = obj2;
REQUIRE(variant1 == variant2);
REQUIRE_FALSE(variant1 != variant2);
REQUIRE(variant1 != variant3);
REQUIRE_FALSE(variant1 == variant3);
}
SECTION("VariantsOfDifferentTypes") {
DynamicJsonBuffer jsonBuffer;
JsonVariant variants[] = {
true,
42,
666.667,
"hello",
jsonBuffer.createArray(),
jsonBuffer.createObject(),
};
size_t n = sizeof(variants) / sizeof(variants[0]);
for (size_t i = 0; i < n; i++) {
for (size_t j = i + 1; j < n; j++) {
REQUIRE(variants[i] != variants[j]);
REQUIRE_FALSE(variants[i] == variants[j]);
}
}
}
}
+64
View File
@@ -0,0 +1,64 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonVariant copy") {
DynamicJsonBuffer _jsonBuffer;
JsonVariant _variant1;
JsonVariant _variant2;
SECTION("IntegersAreCopiedByValue") {
_variant1 = 123;
_variant2 = _variant1;
_variant1 = 456;
REQUIRE(123 == _variant2.as<int>());
}
SECTION("DoublesAreCopiedByValue") {
_variant1 = 123.45;
_variant2 = _variant1;
_variant1 = 456.78;
REQUIRE(123.45 == _variant2.as<double>());
}
SECTION("BooleansAreCopiedByValue") {
_variant1 = true;
_variant2 = _variant1;
_variant1 = false;
REQUIRE(_variant2.as<bool>());
}
SECTION("StringsAreCopiedByValue") {
_variant1 = "hello";
_variant2 = _variant1;
_variant1 = "world";
REQUIRE(std::string("hello") == _variant2.as<const char *>());
}
SECTION("ObjectsAreCopiedByReference") {
JsonObject &object = _jsonBuffer.createObject();
_variant1 = object;
object["hello"] = "world";
REQUIRE(1 == _variant1.as<JsonObject>().size());
}
SECTION("ArraysAreCopiedByReference") {
JsonArray &array = _jsonBuffer.createArray();
_variant1 = array;
array.add("world");
REQUIRE(1 == _variant1.as<JsonArray>().size());
}
}
+115
View File
@@ -0,0 +1,115 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
void checkIsArray(JsonVariant var) {
REQUIRE(var.is<JsonArray>());
REQUIRE(var.is<JsonArray&>());
REQUIRE(var.is<const JsonArray>());
REQUIRE(var.is<const JsonArray&>());
REQUIRE_FALSE(var.is<bool>());
REQUIRE_FALSE(var.is<double>());
REQUIRE_FALSE(var.is<float>());
REQUIRE_FALSE(var.is<int>());
REQUIRE_FALSE(var.is<long>());
REQUIRE_FALSE(var.is<const char*>());
REQUIRE_FALSE(var.is<JsonObject>());
}
void checkIsBool(JsonVariant var) {
REQUIRE(var.is<bool>());
REQUIRE_FALSE(var.is<double>());
REQUIRE_FALSE(var.is<float>());
REQUIRE_FALSE(var.is<int>());
REQUIRE_FALSE(var.is<long>());
REQUIRE_FALSE(var.is<const char*>());
REQUIRE_FALSE(var.is<JsonArray>());
REQUIRE_FALSE(var.is<JsonObject>());
}
void checkIsFloat(JsonVariant var) {
REQUIRE(var.is<double>());
REQUIRE(var.is<float>());
REQUIRE_FALSE(var.is<bool>());
REQUIRE_FALSE(var.is<int>());
REQUIRE_FALSE(var.is<long>());
REQUIRE_FALSE(var.is<const char*>());
REQUIRE_FALSE(var.is<JsonArray>());
REQUIRE_FALSE(var.is<JsonObject>());
}
void checkIsInteger(JsonVariant var) {
REQUIRE(var.is<long>());
REQUIRE(var.is<int>());
REQUIRE(var.is<float>());
REQUIRE(var.is<double>());
REQUIRE_FALSE(var.is<bool>());
REQUIRE_FALSE(var.is<const char*>());
REQUIRE_FALSE(var.is<JsonArray>());
REQUIRE_FALSE(var.is<JsonObject>());
}
void checkIsString(JsonVariant var) {
REQUIRE(var.is<const char*>());
REQUIRE_FALSE(var.is<bool>());
REQUIRE_FALSE(var.is<int>());
REQUIRE_FALSE(var.is<double>());
REQUIRE_FALSE(var.is<float>());
REQUIRE_FALSE(var.is<long>());
REQUIRE_FALSE(var.is<JsonArray>());
REQUIRE_FALSE(var.is<JsonObject>());
}
TEST_CASE("JsonVariant::is()") {
DynamicJsonBuffer jsonBuffer;
SECTION("JsonArray") {
checkIsArray(jsonBuffer.createArray());
}
SECTION("bool") {
checkIsBool(true);
checkIsBool(false);
}
SECTION("double") {
checkIsFloat(4.2);
}
SECTION("int") {
checkIsInteger(42);
}
SECTION("long") {
checkIsInteger(42L);
}
SECTION("string") {
checkIsString("42");
}
SECTION("unparsed bool") {
checkIsBool(RawJson("true"));
checkIsBool(RawJson("false"));
}
SECTION("unparsed int") {
checkIsInteger(RawJson("42"));
}
SECTION("unparsed float") {
checkIsFloat(RawJson("4.2e-10"));
}
SECTION("unparsed null") {
checkIsString(RawJson("null"));
}
}
+83
View File
@@ -0,0 +1,83 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
static const JsonVariant undefined;
static const JsonVariant null = static_cast<const char*>(0);
TEST_CASE("JsonVariant::operator|()") {
SECTION("undefined | const char*") {
std::string result = undefined | "default";
REQUIRE(result == "default");
}
SECTION("undefined | int") {
int result = undefined | 42;
REQUIRE(result == 42);
}
SECTION("undefined | bool") {
bool result = undefined | true;
REQUIRE(result == true);
}
SECTION("null | const char*") {
std::string result = null | "default";
REQUIRE(result == "default");
}
SECTION("null | int") {
int result = null | 42;
REQUIRE(result == 42);
}
SECTION("null | bool") {
bool result = null | true;
REQUIRE(result == true);
}
SECTION("int | const char*") {
JsonVariant variant = 42;
std::string result = variant | "default";
REQUIRE(result == "default");
}
SECTION("int | int") {
JsonVariant variant = 0;
int result = variant | 666;
REQUIRE(result == 0);
}
SECTION("double | int") {
JsonVariant variant = 42.0;
int result = variant | 666;
REQUIRE(result == 42);
}
SECTION("bool | bool") {
JsonVariant variant = false;
bool result = variant | true;
REQUIRE(result == false);
}
SECTION("int | bool") {
JsonVariant variant = 0;
bool result = variant | true;
REQUIRE(result == true);
}
SECTION("const char* | const char*") {
JsonVariant variant = "not default";
std::string result = variant | "default";
REQUIRE(result == "not default");
}
SECTION("const char* | int") {
JsonVariant variant = "not default";
int result = variant | 42;
REQUIRE(result == 42);
}
}
@@ -0,0 +1,66 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
#include <limits>
void check(JsonVariant variant, const std::string &expected) {
char buffer[256] = "";
size_t returnValue = variant.printTo(buffer, sizeof(buffer));
REQUIRE(expected == buffer);
REQUIRE(expected.size() == returnValue);
}
TEST_CASE("JsonVariant::printTo()") {
SECTION("Empty") {
check(JsonVariant(), "");
}
SECTION("Null") {
check(static_cast<char *>(0), "null");
}
SECTION("String") {
check("hello", "\"hello\"");
}
SECTION("Double") {
check(3.1415927, "3.1415927");
}
SECTION("Integer") {
check(42, "42");
}
SECTION("NegativeLong") {
check(-42, "-42");
}
SECTION("UnsignedLong") {
check(4294967295UL, "4294967295");
}
SECTION("True") {
check(true, "true");
}
SECTION("OneFalse") {
check(false, "false");
}
#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64
SECTION("NegativeInt64") {
check(-9223372036854775807 - 1, "-9223372036854775808");
}
SECTION("PositiveInt64") {
check(9223372036854775807, "9223372036854775807");
}
SECTION("UInt64") {
check(18446744073709551615U, "18446744073709551615");
}
#endif
}
@@ -0,0 +1,130 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <stdint.h>
#include <catch.hpp>
#include <limits>
template <typename T>
void checkValue(T expected) {
JsonVariant variant = 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() {
T min = std::numeric_limits<T>::min();
T max = std::numeric_limits<T>::max();
JsonVariant variantMin(min);
JsonVariant variantMax(max);
REQUIRE(min == variantMin.as<T>());
REQUIRE(max == variantMax.as<T>());
}
TEST_CASE("JsonVariant set()/get()") {
#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64
SECTION("SizeOfJsonInteger") {
REQUIRE(8 == sizeof(Internals::JsonInteger));
}
#endif
SECTION("Null") {
checkValue<const char *>(NULL);
}
SECTION("String") {
checkValue<const char *>("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 || ARDUINOJSON_USE_INT64
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 || ARDUINOJSON_USE_INT64
SECTION("Int64") {
checkNumericType<int64_t>();
}
SECTION("Uint64") {
checkNumericType<uint64_t>();
}
#endif
SECTION("CanStoreObject") {
DynamicJsonBuffer jsonBuffer;
JsonObject &object = jsonBuffer.createObject();
checkReference(object);
}
}
@@ -0,0 +1,77 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonVariant::operator[]") {
DynamicJsonBuffer _jsonBuffer;
SECTION("Array") {
JsonArray &array = _jsonBuffer.createArray();
array.add("element at index 0");
array.add("element at index 1");
JsonVariant var = array;
REQUIRE(2 == var.size());
REQUIRE(std::string("element at index 0") == var[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_FALSE(var[666].success());
REQUIRE_FALSE(var[3].success());
REQUIRE_FALSE(var["0"].success());
}
SECTION("Object") {
JsonObject &object = _jsonBuffer.createObject();
object["a"] = "element at key \"a\"";
object["b"] = "element at key \"b\"";
JsonVariant var = object;
REQUIRE(2 == var.size());
REQUIRE(std::string("element at key \"a\"") == var["a"]);
REQUIRE(std::string("element at key \"b\"") == var["b"]);
REQUIRE_FALSE(var["c"].success());
REQUIRE_FALSE(var[0].success());
}
SECTION("Undefined") {
JsonVariant var = JsonVariant();
REQUIRE(0 == var.size());
REQUIRE_FALSE(var["0"].success());
REQUIRE_FALSE(var[0].success());
}
SECTION("String") {
JsonVariant var = "hello world";
REQUIRE(0 == var.size());
REQUIRE_FALSE(var["0"].success());
REQUIRE_FALSE(var[0].success());
}
SECTION("ObjectSetValue") {
JsonVariant var = _jsonBuffer.createObject();
var["hello"] = "world";
REQUIRE(1 == var.size());
REQUIRE(std::string("world") == var["hello"]);
}
SECTION("ArraySetValue") {
JsonVariant var = _jsonBuffer.parseArray("[\"hello\"]");
var[0] = "world";
REQUIRE(1 == var.size());
REQUIRE(std::string("world") == var[0]);
}
SECTION("NestedObjectSetValue") {
JsonVariant var = _jsonBuffer.parseArray("[{}]");
var[0]["hello"] = "world";
REQUIRE(1 == var.size());
REQUIRE(1 == var[0].size());
REQUIRE(std::string("world") == var[0]["hello"]);
}
}
@@ -0,0 +1,42 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonVariant::success()") {
SECTION("ReturnsFalse_WhenUndefined") {
JsonVariant variant;
REQUIRE(false == variant.success());
}
SECTION("ReturnsTrue_WhenInteger") {
JsonVariant variant = 0;
REQUIRE(true == variant.success());
}
SECTION("ReturnsTrue_WhenEmptyArray") {
DynamicJsonBuffer jsonBuffer;
JsonVariant variant = jsonBuffer.createArray();
REQUIRE(true == variant.success());
}
SECTION("ReturnsTrue_WhenEmptyObject") {
DynamicJsonBuffer jsonBuffer;
JsonVariant variant = jsonBuffer.createObject();
REQUIRE(true == variant.success());
}
SECTION("ReturnsFalse_WhenInvalidArray") {
JsonVariant variant = JsonArray::invalid();
REQUIRE(false == variant.success());
}
SECTION("ReturnsFalse_WhenInvalidObject") {
JsonVariant variant = JsonObject::invalid();
REQUIRE(false == variant.success());
}
}
@@ -0,0 +1,54 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonVariant undefined") {
JsonVariant variant;
SECTION("AsLongReturns0") {
REQUIRE(0 == variant.as<long>());
}
SECTION("AsUnsignedReturns0") {
REQUIRE(0 == variant.as<unsigned>());
}
SECTION("AsStringReturnsNull") {
REQUIRE(0 == variant.as<char*>());
}
SECTION("AsDoubleReturns0") {
REQUIRE(0 == variant.as<double>());
}
SECTION("AsBoolReturnsFalse") {
REQUIRE(false == variant.as<bool>());
}
SECTION("AsArrayReturnInvalid") {
REQUIRE(JsonArray::invalid() == variant.as<JsonArray&>());
}
SECTION("AsConstArrayReturnInvalid") {
REQUIRE(JsonArray::invalid() == variant.as<const JsonArray&>());
}
SECTION("AsObjectReturnInvalid") {
REQUIRE(JsonObject::invalid() == variant.as<JsonObject&>());
}
SECTION("AsConstObjectReturnInvalid") {
REQUIRE(JsonObject::invalid() == variant.as<const JsonObject&>());
}
SECTION("AsArrayWrapperReturnInvalid") {
REQUIRE(JsonArray::invalid() == variant.as<JsonArray>());
}
SECTION("AsObjectWrapperReturnInvalid") {
REQUIRE(JsonObject::invalid() == variant.as<JsonObject>());
}
}
@@ -0,0 +1,11 @@
# ArduinoJson - arduinojson.org
# Copyright Benoit Blanchon 2014-2018
# MIT License
add_executable(JsonWriterTests
writeFloat.cpp
writeString.cpp
)
target_link_libraries(JsonWriterTests catch)
add_test(JsonWriter JsonWriterTests)
@@ -0,0 +1,117 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <catch.hpp>
#include <limits>
#include <string>
#include <ArduinoJson/Serialization/DynamicStringBuilder.hpp>
#include <ArduinoJson/Serialization/JsonWriter.hpp>
using namespace ArduinoJson::Internals;
template <typename TFloat>
void check(TFloat input, const std::string& expected) {
std::string output;
DynamicStringBuilder<std::string> sb(output);
JsonWriter<DynamicStringBuilder<std::string> > writer(sb);
writer.writeFloat(input);
REQUIRE(writer.bytesWritten() == output.size());
CHECK(expected == output);
}
TEST_CASE("JsonWriter::writeFloat(double)") {
SECTION("Pi") {
check<double>(3.14159265359, "3.141592654");
}
SECTION("Signaling NaN") {
double nan = std::numeric_limits<double>::signaling_NaN();
check<double>(nan, "NaN");
}
SECTION("Quiet NaN") {
double nan = std::numeric_limits<double>::quiet_NaN();
check<double>(nan, "NaN");
}
SECTION("Infinity") {
double inf = std::numeric_limits<double>::infinity();
check<double>(inf, "Infinity");
check<double>(-inf, "-Infinity");
}
SECTION("Zero") {
check<double>(0.0, "0");
check<double>(-0.0, "0");
}
SECTION("Espilon") {
check<double>(2.2250738585072014E-308, "2.225073859e-308");
check<double>(-2.2250738585072014E-308, "-2.225073859e-308");
}
SECTION("Max double") {
check<double>(1.7976931348623157E+308, "1.797693135e308");
check<double>(-1.7976931348623157E+308, "-1.797693135e308");
}
SECTION("Big exponent") {
// this test increases coverage of normalize()
check<double>(1e255, "1e255");
check<double>(1e-255, "1e-255");
}
SECTION("Exponentation when <= 1e-5") {
check<double>(1e-4, "0.0001");
check<double>(1e-5, "1e-5");
check<double>(-1e-4, "-0.0001");
check<double>(-1e-5, "-1e-5");
}
SECTION("Exponentation when >= 1e7") {
check<double>(9999999.999, "9999999.999");
check<double>(10000000.0, "1e7");
check<double>(-9999999.999, "-9999999.999");
check<double>(-10000000.0, "-1e7");
}
SECTION("Rounding when too many decimals") {
check<double>(0.000099999999999, "0.0001");
check<double>(0.0000099999999999, "1e-5");
check<double>(0.9999999996, "1");
}
SECTION("9 decimal places") {
check<double>(0.100000001, "0.100000001");
check<double>(0.999999999, "0.999999999");
check<double>(9.000000001, "9.000000001");
check<double>(9.999999999, "9.999999999");
}
SECTION("10 decimal places") {
check<double>(0.1000000001, "0.1");
check<double>(0.9999999999, "1");
check<double>(9.0000000001, "9");
check<double>(9.9999999999, "10");
}
}
TEST_CASE("JsonWriter::writeFloat(float)") {
SECTION("Pi") {
check<float>(3.14159265359f, "3.141593");
}
SECTION("999.9") { // issue #543
check<float>(999.9f, "999.9");
}
SECTION("24.3") { // # issue #588
check<float>(24.3f, "24.3");
}
}
@@ -0,0 +1,61 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <catch.hpp>
#include <ArduinoJson/Serialization/JsonWriter.hpp>
#include <ArduinoJson/Serialization/StaticStringBuilder.hpp>
using namespace ArduinoJson::Internals;
void check(const char* input, std::string expected) {
char output[1024];
StaticStringBuilder sb(output, sizeof(output));
JsonWriter<StaticStringBuilder> writer(sb);
writer.writeString(input);
REQUIRE(expected == output);
REQUIRE(writer.bytesWritten() == expected.size());
}
TEST_CASE("JsonWriter::writeString()") {
SECTION("Null") {
check(0, "null");
}
SECTION("EmptyString") {
check("", "\"\"");
}
SECTION("QuotationMark") {
check("\"", "\"\\\"\"");
}
SECTION("ReverseSolidus") {
check("\\", "\"\\\\\"");
}
SECTION("Solidus") {
check("/", "\"/\""); // but the JSON format allows \/
}
SECTION("Backspace") {
check("\b", "\"\\b\"");
}
SECTION("Formfeed") {
check("\f", "\"\\f\"");
}
SECTION("Newline") {
check("\n", "\"\\n\"");
}
SECTION("CarriageReturn") {
check("\r", "\"\\r\"");
}
SECTION("HorizontalTab") {
check("\t", "\"\\t\"");
}
}
+18
View File
@@ -0,0 +1,18 @@
# ArduinoJson - arduinojson.org
# Copyright Benoit Blanchon 2014-2018
# MIT License
add_executable(MiscTests
deprecated.cpp
FloatParts.cpp
std_stream.cpp
std_string.cpp
StringBuilder.cpp
StringTraits.cpp
TypeTraits.cpp
unsigned_char.cpp
vla.cpp
)
target_link_libraries(MiscTests catch)
add_test(Misc MiscTests)
+44
View File
@@ -0,0 +1,44 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson/Serialization/FloatParts.hpp>
#include <catch.hpp>
using namespace ArduinoJson::Internals;
TEST_CASE("FloatParts<double>") {
SECTION("1.7976931348623157E+308") {
FloatParts<double> parts(1.7976931348623157E+308);
REQUIRE(parts.integral == 1);
REQUIRE(parts.decimal == 797693135);
REQUIRE(parts.decimalPlaces == 9);
REQUIRE(parts.exponent == 308);
}
SECTION("4.94065645841247e-324") {
FloatParts<double> parts(4.94065645841247e-324);
REQUIRE(parts.integral == 4);
REQUIRE(parts.decimal == 940656458);
REQUIRE(parts.decimalPlaces == 9);
REQUIRE(parts.exponent == -324);
}
}
TEST_CASE("FloatParts<float>") {
SECTION("3.4E+38") {
FloatParts<float> parts(3.4E+38f);
REQUIRE(parts.integral == 3);
REQUIRE(parts.decimal == 4);
REQUIRE(parts.decimalPlaces == 1);
REQUIRE(parts.exponent == 38);
}
SECTION("1.17549435e−38") {
FloatParts<float> parts(1.17549435e-38f);
REQUIRE(parts.integral == 1);
REQUIRE(parts.decimal == 175494);
REQUIRE(parts.decimalPlaces == 6);
REQUIRE(parts.exponent == -38);
}
}
@@ -0,0 +1,50 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
using namespace ArduinoJson::Internals;
template <typename StringBuilder, typename String>
void common_tests(StringBuilder& sb, const String& output) {
SECTION("InitialState") {
REQUIRE(std::string("") == output);
}
SECTION("EmptyString") {
REQUIRE(0 == sb.print(""));
REQUIRE(std::string("") == output);
}
SECTION("OneString") {
REQUIRE(4 == sb.print("ABCD"));
REQUIRE(std::string("ABCD") == output);
}
SECTION("TwoStrings") {
REQUIRE(4 == sb.print("ABCD"));
REQUIRE(4 == sb.print("EFGH"));
REQUIRE(std::string("ABCDEFGH") == output);
}
}
TEST_CASE("StaticStringBuilder") {
char output[20];
StaticStringBuilder sb(output, sizeof(output));
common_tests(sb, static_cast<const char*>(output));
SECTION("OverCapacity") {
REQUIRE(19 == sb.print("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
REQUIRE(0 == sb.print("ABC"));
REQUIRE(std::string("ABCDEFGHIJKLMNOPQRS") == output);
}
}
TEST_CASE("DynamicStringBuilder") {
std::string output;
DynamicStringBuilder<std::string> sb(output);
common_tests(sb, output);
}
@@ -0,0 +1,22 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
using namespace ArduinoJson::Internals;
template <typename String>
bool should_duplicate() {
return StringTraits<String>::should_duplicate;
}
TEST_CASE("StringTraits") {
SECTION("should_duplicate") {
REQUIRE(false == should_duplicate<const char*>());
REQUIRE(true == should_duplicate<char*>());
REQUIRE(true == should_duplicate<RawJsonString<char*> >());
REQUIRE(false == should_duplicate<RawJsonString<const char*> >());
}
}
+37
View File
@@ -0,0 +1,37 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
using namespace ArduinoJson::Internals;
TEST_CASE("TypeTraits") {
SECTION("IsBaseOf") {
REQUIRE_FALSE(
static_cast<bool>(IsBaseOf<std::istream, std::ostringstream>::value));
REQUIRE(
static_cast<bool>(IsBaseOf<std::istream, std::istringstream>::value));
REQUIRE(static_cast<bool>(
IsBaseOf<JsonVariantBase<JsonObjectSubscript<const char*> >,
JsonObjectSubscript<const char*> >::value));
}
SECTION("IsArray") {
REQUIRE_FALSE((IsArray<const char*>::value));
REQUIRE((IsArray<const char[]>::value));
REQUIRE((IsArray<const char[10]>::value));
}
SECTION("IsVariant") {
REQUIRE(
static_cast<bool>(IsVariant<JsonObjectSubscript<const char*> >::value));
REQUIRE(static_cast<bool>(IsVariant<JsonVariant>::value));
}
SECTION("IsConst") {
REQUIRE_FALSE((IsConst<char>::value));
REQUIRE((IsConst<const char>::value));
}
}
+140
View File
@@ -0,0 +1,140 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#define ARDUINOJSON_ENABLE_DEPRECATED 1
#include <ArduinoJson.h>
#include <catch.hpp>
#if defined(__clang__)
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#elif defined(_MSC_VER)
#pragma warning(disable : 4996)
#endif
TEST_CASE("Deprecated functions") {
DynamicJsonBuffer jsonBuffer;
SECTION("JsonVariant::asArray()") {
JsonVariant variant = jsonBuffer.createArray();
REQUIRE(variant.asArray().success());
}
SECTION("JsonVariant::asObject()") {
JsonVariant variant = jsonBuffer.createObject();
REQUIRE(variant.asObject().success());
}
SECTION("JsonVariant::asString()") {
JsonVariant variant = "hello";
REQUIRE(std::string("hello") == variant.asString());
}
SECTION("JsonArray::removeAt()") {
JsonArray& arr = jsonBuffer.createArray();
arr.removeAt(0);
}
SECTION("JsonVariant::JsonVariant(float, uint8_t)") {
JsonVariant variant(3.14f, 2);
REQUIRE(variant == 3.14f);
}
SECTION("JsonVariant::JsonVariant(double, uint8_t)") {
JsonVariant variant(3.14, 2);
REQUIRE(variant == 3.14);
}
SECTION("float_with_n_digits()") {
JsonVariant variant = float_with_n_digits(3.14f, 4);
REQUIRE(variant == 3.14f);
}
SECTION("double_with_n_digits()") {
JsonVariant variant = double_with_n_digits(3.14f, 4);
REQUIRE(variant == 3.14f);
}
SECTION("JsonArraySubscript::set(double, uint8_t)") {
JsonArray& arr = jsonBuffer.createArray();
arr.add(666);
arr[0].set(123.45, 2);
REQUIRE(123.45 == arr[0].as<double>());
REQUIRE(true == arr[0].is<double>());
REQUIRE(false == arr[0].is<int>());
}
SECTION("JsonArray::add(double, uint8_t)") {
JsonArray& arr = jsonBuffer.createArray();
arr.add(3.14159265358979323846, 4);
}
SECTION("JsonArray::add(float, uint8_t)") {
JsonArray& arr = jsonBuffer.createArray();
arr.add(3.14159265358979323846f, 4);
}
SECTION("JsonObject::set(unsigned char[], double, uint8_t)") {
unsigned char key[] = "hello";
JsonObject& obj = jsonBuffer.createObject();
obj.set(key, 3.14, 2);
REQUIRE(3.14 == obj["hello"]);
}
SECTION("JsonObject::set(const char*, double, uint8_t)") {
JsonObject& obj = jsonBuffer.createObject();
obj.set("hello", 123.45, 2);
REQUIRE(123.45 == obj["hello"].as<double>());
REQUIRE(obj["hello"].is<double>());
REQUIRE_FALSE(obj["hello"].is<long>());
}
SECTION("JsonObjectSubscript::set(double, uint8_t)") {
JsonObject& obj = jsonBuffer.createObject();
obj["hello"].set(123.45, 2);
REQUIRE(true == obj["hello"].is<double>());
REQUIRE(false == obj["hello"].is<long>());
REQUIRE(123.45 == obj["hello"].as<double>());
}
}
TEST_CASE("DynamicJsonBuffer::strdup()") {
DynamicJsonBuffer buffer;
SECTION("char*") {
char original[] = "hello";
const char* copy = buffer.strdup(original);
strcpy(original, "world");
REQUIRE(std::string("hello") == copy);
}
SECTION("unsigned char*") {
unsigned char value[] = "world";
DynamicJsonBuffer jsonBuffer;
const char* dup = jsonBuffer.strdup(value);
REQUIRE(static_cast<const void*>(value) != static_cast<const void*>(dup));
REQUIRE(std::string("world") == dup);
}
SECTION("std::string") {
std::string original("hello");
const char* copy = buffer.strdup(original);
original[0] = 'w';
REQUIRE(std::string("hello") == copy);
}
SECTION("NULL") {
const char* original = NULL;
const char* copy = buffer.strdup(original);
REQUIRE(0 == copy);
}
}
+84
View File
@@ -0,0 +1,84 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
#include <sstream>
TEST_CASE("std::stream") {
SECTION("JsonVariantFalse") {
std::ostringstream os;
JsonVariant variant = false;
os << variant;
REQUIRE("false" == os.str());
}
SECTION("JsonVariantString") {
std::ostringstream os;
JsonVariant variant = "coucou";
os << variant;
REQUIRE("\"coucou\"" == os.str());
}
SECTION("JsonObject") {
std::ostringstream os;
DynamicJsonBuffer jsonBuffer;
JsonObject& object = jsonBuffer.createObject();
object["key"] = "value";
os << object;
REQUIRE("{\"key\":\"value\"}" == os.str());
}
SECTION("JsonObjectSubscript") {
std::ostringstream os;
DynamicJsonBuffer jsonBuffer;
JsonObject& object = jsonBuffer.createObject();
object["key"] = "value";
os << object["key"];
REQUIRE("\"value\"" == os.str());
}
SECTION("JsonArray") {
std::ostringstream os;
DynamicJsonBuffer jsonBuffer;
JsonArray& array = jsonBuffer.createArray();
array.add("value");
os << array;
REQUIRE("[\"value\"]" == os.str());
}
SECTION("JsonArraySubscript") {
std::ostringstream os;
DynamicJsonBuffer jsonBuffer;
JsonArray& array = jsonBuffer.createArray();
array.add("value");
os << array[0];
REQUIRE("\"value\"" == os.str());
}
SECTION("ParseArray") {
std::istringstream json(" [ 42 /* comment */ ] ");
DynamicJsonBuffer jsonBuffer;
JsonArray& arr = jsonBuffer.parseArray(json);
REQUIRE(true == arr.success());
REQUIRE(1 == arr.size());
REQUIRE(42 == arr[0]);
}
SECTION("ParseObject") {
std::istringstream json(" { hello : world // comment\n }");
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.parseObject(json);
REQUIRE(true == obj.success());
REQUIRE(1 == obj.size());
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("ShouldNotReadPastTheEnd") {
std::istringstream json("{}123");
DynamicJsonBuffer jsonBuffer;
jsonBuffer.parseObject(json);
REQUIRE('1' == json.get());
}
}
+243
View File
@@ -0,0 +1,243 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
static void eraseString(std::string &str) {
char *p = const_cast<char *>(str.c_str());
while (*p) *p++ = '*';
}
TEST_CASE("std::string") {
DynamicJsonBuffer jb;
SECTION("JsonBuffer_ParseArray") {
std::string json("[\"hello\"]");
JsonArray &array = jb.parseArray(json);
eraseString(json);
REQUIRE(true == array.success());
REQUIRE(std::string("hello") == array[0]);
}
SECTION("JsonBuffer_ParseObject") {
std::string json("{\"hello\":\"world\"}");
JsonObject &object = jb.parseObject(json);
eraseString(json);
REQUIRE(true == object.success());
REQUIRE(std::string("world") == object["hello"]);
}
SECTION("JsonObject_Subscript") {
char json[] = "{\"key\":\"value\"}";
JsonObject &object = jb.parseObject(json);
REQUIRE(std::string("value") == object[std::string("key")]);
}
SECTION("JsonObject_ConstSubscript") {
char json[] = "{\"key\":\"value\"}";
const JsonObject &object = jb.parseObject(json);
REQUIRE(std::string("value") == object[std::string("key")]);
}
SECTION("JsonObject_SetKey") {
JsonObject &object = jb.createObject();
std::string key("hello");
object.set(key, "world");
eraseString(key);
REQUIRE(std::string("world") == object["hello"]);
}
SECTION("JsonObject_SetValue") {
JsonObject &object = jb.createObject();
std::string value("world");
object.set("hello", value);
eraseString(value);
REQUIRE(std::string("world") == object["hello"]);
}
SECTION("JsonObject_SetKeyValue") {
JsonObject &object = jb.createObject();
std::string key("hello");
std::string value("world");
object.set(key, value);
eraseString(key);
eraseString(value);
REQUIRE(std::string("world") == object["hello"]);
}
SECTION("JsonObject_SetToArraySubscript") {
JsonArray &arr = jb.createArray();
arr.add("world");
JsonObject &object = jb.createObject();
object.set(std::string("hello"), arr[0]);
REQUIRE(std::string("world") == object["hello"]);
}
SECTION("JsonObject_SetToObjectSubscript") {
JsonObject &arr = jb.createObject();
arr.set("x", "world");
JsonObject &object = jb.createObject();
object.set(std::string("hello"), arr["x"]);
REQUIRE(std::string("world") == object["hello"]);
}
SECTION("JsonObject_Get") {
char json[] = "{\"key\":\"value\"}";
const JsonObject &object = jb.parseObject(json);
REQUIRE(std::string("value") ==
object.get<const char *>(std::string("key")));
}
SECTION("JsonObject_GetT") {
char json[] = "{\"key\":\"value\"}";
const JsonObject &object = jb.parseObject(json);
REQUIRE(std::string("value") ==
object.get<const char *>(std::string("key")));
}
SECTION("JsonObject_IsT") {
char json[] = "{\"key\":\"value\"}";
const JsonObject &object = jb.parseObject(json);
REQUIRE(true == object.is<const char *>(std::string("key")));
}
SECTION("JsonObject_CreateNestedObject") {
std::string key = "key";
char json[64];
JsonObject &object = jb.createObject();
object.createNestedObject(key);
eraseString(key);
object.printTo(json, sizeof(json));
REQUIRE(std::string("{\"key\":{}}") == json);
}
SECTION("JsonObject_CreateNestedArray") {
std::string key = "key";
char json[64];
JsonObject &object = jb.createObject();
object.createNestedArray(key);
eraseString(key);
object.printTo(json, sizeof(json));
REQUIRE(std::string("{\"key\":[]}") == json);
}
SECTION("JsonObject_ContainsKey") {
char json[] = "{\"key\":\"value\"}";
const JsonObject &object = jb.parseObject(json);
REQUIRE(true == object.containsKey(std::string("key")));
}
SECTION("JsonObject_Remove") {
char json[] = "{\"key\":\"value\"}";
JsonObject &object = jb.parseObject(json);
REQUIRE(1 == object.size());
object.remove(std::string("key"));
REQUIRE(0 == object.size());
}
SECTION("JsonObjectSubscript_SetKey") {
JsonObject &object = jb.createObject();
std::string key("hello");
object[key] = "world";
eraseString(key);
REQUIRE(std::string("world") == object["hello"]);
}
SECTION("JsonObjectSubscript_SetValue") {
JsonObject &object = jb.createObject();
std::string value("world");
object["hello"] = value;
eraseString(value);
REQUIRE(std::string("world") == object["hello"]);
}
SECTION("JsonArray_Add") {
JsonArray &array = jb.createArray();
std::string value("hello");
array.add(value);
eraseString(value);
REQUIRE(std::string("hello") == array[0]);
}
SECTION("JsonArray_Set") {
JsonArray &array = jb.createArray();
std::string value("world");
array.add("hello");
array.set(0, value);
eraseString(value);
REQUIRE(std::string("world") == array[0]);
}
SECTION("JsonArraySubscript") {
JsonArray &array = jb.createArray();
std::string value("world");
array.add("hello");
array[0] = value;
eraseString(value);
REQUIRE(std::string("world") == array[0]);
}
SECTION("JsonArray_PrintTo") {
JsonArray &array = jb.createArray();
array.add(4);
array.add(2);
std::string json;
array.printTo(json);
REQUIRE(std::string("[4,2]") == json);
}
SECTION("JsonArray_PrettyPrintTo") {
JsonArray &array = jb.createArray();
array.add(4);
array.add(2);
std::string json;
array.prettyPrintTo(json);
REQUIRE(std::string("[\r\n 4,\r\n 2\r\n]") == json);
}
SECTION("JsonObject_PrintTo") {
JsonObject &object = jb.createObject();
object["key"] = "value";
std::string json;
object.printTo(json);
REQUIRE(std::string("{\"key\":\"value\"}") == json);
}
SECTION("JsonObject_PrettyPrintTo") {
JsonObject &object = jb.createObject();
object["key"] = "value";
std::string json;
object.prettyPrintTo(json);
REQUIRE(std::string("{\r\n \"key\": \"value\"\r\n}") == json);
}
SECTION("JsonBuffer_GrowWhenAddingNewKey") {
JsonObject &object = jb.createObject();
std::string key1("hello"), key2("world");
object[key1] = 1;
size_t sizeBefore = jb.size();
object[key2] = 2;
size_t sizeAfter = jb.size();
REQUIRE(sizeAfter - sizeBefore >= key2.size());
}
SECTION("JsonBuffer_DontGrowWhenReusingKey") {
JsonObject &object = jb.createObject();
std::string key("hello");
object[key] = 1;
size_t sizeBefore = jb.size();
object[key] = 2;
size_t sizeAfter = jb.size();
REQUIRE(sizeBefore == sizeAfter);
}
}
+262
View File
@@ -0,0 +1,262 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
#if defined(__clang__)
#define CONFLICTS_WITH_BUILTIN_OPERATOR
#endif
TEST_CASE("unsigned char string") {
SECTION("JsonBuffer::parseArray") {
unsigned char json[] = "[42]";
StaticJsonBuffer<JSON_ARRAY_SIZE(1)> jsonBuffer;
JsonArray& arr = jsonBuffer.parseArray(json);
REQUIRE(true == arr.success());
}
SECTION("JsonBuffer::parseObject") {
unsigned char json[] = "{\"a\":42}";
StaticJsonBuffer<JSON_OBJECT_SIZE(1)> jsonBuffer;
JsonObject& obj = jsonBuffer.parseObject(json);
REQUIRE(true == obj.success());
}
SECTION("JsonVariant constructor") {
unsigned char value[] = "42";
JsonVariant variant(value);
REQUIRE(42 == variant.as<int>());
}
SECTION("JsonVariant assignment operator") {
unsigned char value[] = "42";
JsonVariant variant(666);
variant = value;
REQUIRE(42 == variant.as<int>());
}
#ifndef CONFLICTS_WITH_BUILTIN_OPERATOR
SECTION("JsonVariant::operator[]") {
unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer;
JsonVariant variant = jsonBuffer.parseObject("{\"hello\":\"world\"}");
REQUIRE(std::string("world") == variant[key]);
}
#endif
#ifndef CONFLICTS_WITH_BUILTIN_OPERATOR
SECTION("JsonVariant::operator[] const") {
unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer;
const JsonVariant variant = jsonBuffer.parseObject("{\"hello\":\"world\"}");
REQUIRE(std::string("world") == variant[key]);
}
#endif
SECTION("JsonVariant::operator==") {
unsigned char comparand[] = "hello";
DynamicJsonBuffer jsonBuffer;
const JsonVariant variant = "hello";
REQUIRE(comparand == variant);
REQUIRE(variant == comparand);
REQUIRE_FALSE(comparand != variant);
REQUIRE_FALSE(variant != comparand);
}
SECTION("JsonVariant::operator!=") {
unsigned char comparand[] = "hello";
DynamicJsonBuffer jsonBuffer;
const JsonVariant variant = "world";
REQUIRE(comparand != variant);
REQUIRE(variant != comparand);
REQUIRE_FALSE(comparand == variant);
REQUIRE_FALSE(variant == comparand);
}
#ifndef CONFLICTS_WITH_BUILTIN_OPERATOR
SECTION("JsonObject::operator[]") {
unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.createObject();
obj[key] = "world";
REQUIRE(std::string("world") == obj["hello"]);
}
#endif
SECTION("JsonObjectSubscript::operator=") { // issue #416
unsigned char value[] = "world";
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.createObject();
obj["hello"] = value;
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("JsonObjectSubscript::set()") {
unsigned char value[] = "world";
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.createObject();
obj["hello"].set(value);
REQUIRE(std::string("world") == obj["hello"]);
}
#ifndef CONFLICTS_WITH_BUILTIN_OPERATOR
SECTION("JsonObject::operator[] const") {
unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer;
const JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}");
REQUIRE(std::string("world") == obj[key]);
}
#endif
SECTION("JsonObject::get()") {
unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}");
REQUIRE(std::string("world") == obj.get<char*>(key));
}
SECTION("JsonObject::set() key") {
unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.createObject();
obj.set(key, "world");
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("JsonObject::set() value") {
unsigned char value[] = "world";
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.createObject();
obj.set("hello", value);
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("JsonObject::set key&value") {
unsigned char key[] = "world";
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.createObject();
obj.set(key, key);
REQUIRE(std::string("world") == obj["world"]);
}
SECTION("JsonObject::containsKey()") {
unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer;
const JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}");
REQUIRE(true == obj.containsKey(key));
}
SECTION("JsonObject::remove()") {
unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}");
obj.remove(key);
REQUIRE(0 == obj.size());
}
SECTION("JsonObject::is()") {
unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.parseObject("{\"hello\":42}");
REQUIRE(true == obj.is<int>(key));
}
SECTION("JsonObject::createNestedArray()") {
unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.createObject();
obj.createNestedArray(key);
}
SECTION("JsonObject::createNestedObject()") {
unsigned char key[] = "hello";
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.createObject();
obj.createNestedObject(key);
}
SECTION("JsonArray::add()") {
unsigned char value[] = "world";
DynamicJsonBuffer jsonBuffer;
JsonArray& arr = jsonBuffer.createArray();
arr.add(value);
REQUIRE(std::string("world") == arr[0]);
}
SECTION("JsonArray::set()") {
unsigned char value[] = "world";
DynamicJsonBuffer jsonBuffer;
JsonArray& arr = jsonBuffer.createArray();
arr.add("hello");
arr.set(0, value);
REQUIRE(std::string("world") == arr[0]);
}
SECTION("JsonArraySubscript::set()") {
unsigned char value[] = "world";
DynamicJsonBuffer jsonBuffer;
JsonArray& arr = jsonBuffer.createArray();
arr.add("hello");
arr[0].set(value);
REQUIRE(std::string("world") == arr[0]);
}
SECTION("JsonArraySubscript::operator=") {
unsigned char value[] = "world";
DynamicJsonBuffer jsonBuffer;
JsonArray& arr = jsonBuffer.createArray();
arr.add("hello");
arr[0] = value;
REQUIRE(std::string("world") == arr[0]);
}
}
+331
View File
@@ -0,0 +1,331 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
#if defined(__clang__)
#pragma clang diagnostic ignored "-Wvla-extension"
#define CONFLICTS_WITH_BUILTIN_OPERATOR
#elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wvla"
#else
#define VLA_NOT_SUPPORTED
#endif
#ifndef VLA_NOT_SUPPORTED
TEST_CASE("Variable Length Array") {
SECTION("ParseArray") {
int i = 8;
char vla[i];
strcpy(vla, "[42]");
StaticJsonBuffer<JSON_ARRAY_SIZE(1)> jsonBuffer;
JsonArray& arr = jsonBuffer.parseArray(vla);
REQUIRE(true == arr.success());
}
SECTION("ParseObject") {
int i = 16;
char vla[i];
strcpy(vla, "{\"a\":42}");
StaticJsonBuffer<JSON_OBJECT_SIZE(1)> jsonBuffer;
JsonObject& obj = jsonBuffer.parseObject(vla);
REQUIRE(true == obj.success());
}
SECTION("Parse") {
int i = 16;
char vla[i];
strcpy(vla, "42");
StaticJsonBuffer<1> jsonBuffer;
JsonVariant variant = jsonBuffer.parse(vla);
REQUIRE(42 == variant.as<int>());
}
SECTION("JsonVariant_Constructor") {
int i = 16;
char vla[i];
strcpy(vla, "42");
JsonVariant variant(vla);
REQUIRE(42 == variant.as<int>());
}
SECTION("JsonVariant_Assign") {
int i = 16;
char vla[i];
strcpy(vla, "42");
JsonVariant variant(666);
variant = vla;
REQUIRE(42 == variant.as<int>());
}
#ifndef CONFLICTS_WITH_BUILTIN_OPERATOR
SECTION("JsonVariant_Subscript") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer;
JsonVariant variant = jsonBuffer.parseObject("{\"hello\":\"world\"}");
REQUIRE(std::string("world") == variant[vla]);
}
#endif
#ifndef CONFLICTS_WITH_BUILTIN_OPERATOR
SECTION("JsonVariant_Subscript_Const") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer;
const JsonVariant variant = jsonBuffer.parseObject("{\"hello\":\"world\"}");
REQUIRE(std::string("world") == variant[vla]);
}
#endif
SECTION("JsonVariant_Equals") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer;
const JsonVariant variant = "hello";
REQUIRE((vla == variant));
REQUIRE((variant == vla));
REQUIRE_FALSE((vla != variant));
REQUIRE_FALSE((variant != vla));
}
SECTION("JsonVariant_Differs") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer;
const JsonVariant variant = "world";
REQUIRE((vla != variant));
REQUIRE((variant != vla));
REQUIRE_FALSE((vla == variant));
REQUIRE_FALSE((variant == vla));
}
#ifndef CONFLICTS_WITH_BUILTIN_OPERATOR
SECTION("JsonObject_Subscript") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.createObject();
obj[vla] = "world";
REQUIRE(std::string("world") == obj["hello"]);
}
#endif
SECTION("JsonObject_Subscript_Assign") { // issue #416
int i = 32;
char vla[i];
strcpy(vla, "world");
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.createObject();
obj["hello"] = vla;
REQUIRE(std::string("world") == obj["hello"].as<char*>());
}
SECTION("JsonObject_Subscript_Set") {
int i = 32;
char vla[i];
strcpy(vla, "world");
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.createObject();
obj["hello"].set(vla);
REQUIRE(std::string("world") == obj["hello"].as<char*>());
}
#ifndef CONFLICTS_WITH_BUILTIN_OPERATOR
SECTION("JsonObject_Subscript_Const") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer;
const JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}");
REQUIRE(std::string("world") == obj[vla]);
}
#endif
SECTION("JsonObject_Get") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}");
REQUIRE(std::string("world") == obj.get<char*>(vla));
}
SECTION("JsonObject_Set_Key") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.createObject();
obj.set(vla, "world");
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("JsonObject_Set_Value") {
int i = 16;
char vla[i];
strcpy(vla, "world");
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.createObject();
obj.set("hello", vla);
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("JsonObject_Set_KeyAndValue") {
int i = 16;
char vla[i];
strcpy(vla, "world");
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.createObject();
obj.set(vla, vla);
REQUIRE(std::string("world") == obj["world"]);
}
SECTION("JsonObject_ContainsKey") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer;
const JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}");
REQUIRE(true == obj.containsKey(vla));
}
SECTION("JsonObject_Remove") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}");
obj.remove(vla);
REQUIRE(0 == obj.size());
}
SECTION("JsonObject_Is") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.parseObject("{\"hello\":42}");
REQUIRE(true == obj.is<int>(vla));
}
SECTION("JsonObject_CreateNestedArray") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.createObject();
obj.createNestedArray(vla);
}
SECTION("JsonObject_CreateNestedObject") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonBuffer jsonBuffer;
JsonObject& obj = jsonBuffer.createObject();
obj.createNestedObject(vla);
}
SECTION("JsonArray_Add") {
int i = 16;
char vla[i];
strcpy(vla, "world");
DynamicJsonBuffer jsonBuffer;
JsonArray& arr = jsonBuffer.createArray();
arr.add(vla);
REQUIRE(std::string("world") == arr[0]);
}
SECTION("JsonArray_Set") {
int i = 16;
char vla[i];
strcpy(vla, "world");
DynamicJsonBuffer jsonBuffer;
JsonArray& arr = jsonBuffer.createArray();
arr.add("hello");
arr.set(0, vla);
REQUIRE(std::string("world") == arr[0]);
}
SECTION("JsonArraySubscript_Set") {
int i = 16;
char vla[i];
strcpy(vla, "world");
DynamicJsonBuffer jsonBuffer;
JsonArray& arr = jsonBuffer.createArray();
arr.add("hello");
arr[0].set(vla);
REQUIRE(std::string("world") == arr[0]);
}
SECTION("JsonArraySubscript_Assign") {
int i = 16;
char vla[i];
strcpy(vla, "world");
DynamicJsonBuffer jsonBuffer;
JsonArray& arr = jsonBuffer.createArray();
arr.add("hello");
arr[0] = vla;
REQUIRE(std::string("world") == arr[0]);
}
}
#endif
@@ -0,0 +1,13 @@
# ArduinoJson - arduinojson.org
# Copyright Benoit Blanchon 2014-2018
# MIT License
add_executable(PolyfillsTests
isFloat.cpp
isInteger.cpp
parseFloat.cpp
parseInteger.cpp
)
target_link_libraries(PolyfillsTests catch)
add_test(Polyfills PolyfillsTests)
@@ -0,0 +1,76 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson/Polyfills/isFloat.hpp>
#include <catch.hpp>
using namespace ArduinoJson::Internals;
TEST_CASE("isFloat()") {
SECTION("Input is NULL") {
REQUIRE(isFloat(NULL) == false);
}
SECTION("NoExponent") {
REQUIRE(isFloat("3.14"));
REQUIRE(isFloat("-3.14"));
REQUIRE(isFloat("+3.14"));
}
SECTION("IntegralPartMissing") {
REQUIRE(isFloat(".14"));
REQUIRE(isFloat("-.14"));
REQUIRE(isFloat("+.14"));
}
SECTION("FractionalPartMissing") {
REQUIRE(isFloat("3."));
REQUIRE(isFloat("-3.e14"));
REQUIRE(isFloat("+3.e-14"));
}
SECTION("NoDot") {
REQUIRE(isFloat("3e14"));
REQUIRE(isFloat("3e-14"));
REQUIRE(isFloat("3e+14"));
}
SECTION("Integer") {
REQUIRE(isFloat("14"));
REQUIRE(isFloat("-14"));
REQUIRE(isFloat("+14"));
}
SECTION("ExponentMissing") {
REQUIRE_FALSE(isFloat("3.14e"));
REQUIRE_FALSE(isFloat("3.14e-"));
REQUIRE_FALSE(isFloat("3.14e+"));
}
SECTION("JustASign") {
REQUIRE_FALSE(isFloat("-"));
REQUIRE_FALSE(isFloat("+"));
}
SECTION("Empty") {
REQUIRE_FALSE(isFloat(""));
}
SECTION("NaN") {
REQUIRE(isFloat("NaN"));
REQUIRE_FALSE(isFloat("n"));
REQUIRE_FALSE(isFloat("N"));
REQUIRE_FALSE(isFloat("nan"));
REQUIRE_FALSE(isFloat("-NaN"));
REQUIRE_FALSE(isFloat("+NaN"));
}
SECTION("Infinity") {
REQUIRE(isFloat("Infinity"));
REQUIRE(isFloat("+Infinity"));
REQUIRE(isFloat("-Infinity"));
REQUIRE_FALSE(isFloat("infinity"));
REQUIRE_FALSE(isFloat("Inf"));
}
}
@@ -0,0 +1,36 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson/Polyfills/isInteger.hpp>
#include <catch.hpp>
using namespace ArduinoJson::Internals;
TEST_CASE("isInteger()") {
SECTION("Null") {
REQUIRE_FALSE(isInteger(NULL));
}
SECTION("FloatNotInteger") {
REQUIRE_FALSE(isInteger("3.14"));
REQUIRE_FALSE(isInteger("-3.14"));
REQUIRE_FALSE(isInteger("+3.14"));
}
SECTION("Spaces") {
REQUIRE_FALSE(isInteger("42 "));
REQUIRE_FALSE(isInteger(" 42"));
}
SECTION("Valid") {
REQUIRE(isInteger("42"));
REQUIRE(isInteger("-42"));
REQUIRE(isInteger("+42"));
}
SECTION("ExtraSign") {
REQUIRE_FALSE(isInteger("--42"));
REQUIRE_FALSE(isInteger("++42"));
}
}
@@ -0,0 +1,177 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson/Polyfills/parseFloat.hpp>
#include <catch.hpp>
using namespace ArduinoJson::Internals;
template <typename T>
void check(const char* input, T expected) {
CAPTURE(input);
REQUIRE(parseFloat<T>(input) == Approx(expected));
}
template <typename T>
void checkNaN(const char* input) {
CAPTURE(input);
T result = parseFloat<T>(input);
REQUIRE(result != result);
}
template <typename T>
void checkInf(const char* input, bool negative) {
CAPTURE(input);
T x = parseFloat<T>(input);
if (negative)
REQUIRE(x < 0);
else
REQUIRE(x > 0);
REQUIRE(x == x); // not a NaN
REQUIRE(x * 2 == x); // a property of infinity
}
TEST_CASE("parseFloat<float>()") {
SECTION("Null") {
check<float>(NULL, 0);
}
SECTION("Float_Short_NoExponent") {
check<float>("3.14", 3.14f);
check<float>("-3.14", -3.14f);
check<float>("+3.14", +3.14f);
}
SECTION("Short_NoDot") {
check<float>("1E+38", 1E+38f);
check<float>("-1E+38", -1E+38f);
check<float>("+1E-38", +1E-38f);
check<float>("+1e+38", +1e+38f);
check<float>("-1e-38", -1e-38f);
}
SECTION("Max") {
check<float>("340.2823e+36", 3.402823e+38f);
check<float>("34.02823e+37", 3.402823e+38f);
check<float>("3.402823e+38", 3.402823e+38f);
check<float>("0.3402823e+39", 3.402823e+38f);
check<float>("0.03402823e+40", 3.402823e+38f);
check<float>("0.003402823e+41", 3.402823e+38f);
}
SECTION("VeryLong") {
check<float>("0.00000000000000000000000000000001", 1e-32f);
check<float>("100000000000000000000000000000000.0", 1e+32f);
check<float>(
"100000000000000000000000000000000.00000000000000000000000000000",
1e+32f);
}
SECTION("MantissaTooLongToFit") {
check<float>("0.340282346638528861111111111111", 0.34028234663852886f);
check<float>("34028234663852886.11111111111111", 34028234663852886.0f);
check<float>("34028234.66385288611111111111111", 34028234.663852886f);
check<float>("-0.340282346638528861111111111111", -0.34028234663852886f);
check<float>("-34028234663852886.11111111111111", -34028234663852886.0f);
check<float>("-34028234.66385288611111111111111", -34028234.663852886f);
}
SECTION("ExponentTooBig") {
checkInf<float>("1e39", false);
checkInf<float>("-1e39", true);
checkInf<float>("1e255", false);
check<float>("1e-255", 0.0f);
}
SECTION("NaN") {
checkNaN<float>("NaN");
checkNaN<float>("nan");
}
SECTION("Infinity") {
checkInf<float>("Infinity", false);
checkInf<float>("+Infinity", false);
checkInf<float>("-Infinity", true);
checkInf<float>("inf", false);
checkInf<float>("+inf", false);
checkInf<float>("-inf", true);
}
SECTION("Boolean") {
check<float>("false", 0.0f);
check<float>("true", 1.0f);
}
}
TEST_CASE("parseFloat<double>()") {
SECTION("Null") {
check<double>(NULL, 0);
}
SECTION("Short_NoExponent") {
check<double>("3.14", 3.14);
check<double>("-3.14", -3.14);
check<double>("+3.14", +3.14);
}
SECTION("Short_NoDot") {
check<double>("1E+308", 1E+308);
check<double>("-1E+308", -1E+308);
check<double>("+1E-308", +1E-308);
check<double>("+1e+308", +1e+308);
check<double>("-1e-308", -1e-308);
}
SECTION("Max") {
check<double>(".017976931348623147e+310", 1.7976931348623147e+308);
check<double>(".17976931348623147e+309", 1.7976931348623147e+308);
check<double>("1.7976931348623147e+308", 1.7976931348623147e+308);
check<double>("17.976931348623147e+307", 1.7976931348623147e+308);
check<double>("179.76931348623147e+306", 1.7976931348623147e+308);
}
SECTION("Min") {
check<double>(".022250738585072014e-306", 2.2250738585072014e-308);
check<double>(".22250738585072014e-307", 2.2250738585072014e-308);
check<double>("2.2250738585072014e-308", 2.2250738585072014e-308);
check<double>("22.250738585072014e-309", 2.2250738585072014e-308);
check<double>("222.50738585072014e-310", 2.2250738585072014e-308);
}
SECTION("VeryLong") {
check<double>("0.00000000000000000000000000000001", 1e-32);
check<double>("100000000000000000000000000000000.0", 1e+32);
check<double>(
"100000000000000000000000000000000.00000000000000000000000000000",
1e+32);
}
SECTION("MantissaTooLongToFit") {
check<double>("0.179769313486231571111111111111", 0.17976931348623157);
check<double>("17976931348623157.11111111111111", 17976931348623157.0);
check<double>("1797693.134862315711111111111111", 1797693.1348623157);
check<double>("-0.179769313486231571111111111111", -0.17976931348623157);
check<double>("-17976931348623157.11111111111111", -17976931348623157.0);
check<double>("-1797693.134862315711111111111111", -1797693.1348623157);
}
SECTION("ExponentTooBig") {
checkInf<double>("1e309", false);
checkInf<double>("-1e309", true);
checkInf<double>("1e65535", false);
check<double>("1e-65535", 0.0);
}
SECTION("NaN") {
checkNaN<double>("NaN");
checkNaN<double>("nan");
}
SECTION("Boolean") {
check<double>("false", 0.0);
check<double>("true", 1.0);
}
}
@@ -0,0 +1,79 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <stdint.h>
#include <ArduinoJson/Polyfills/parseInteger.hpp>
#include <catch.hpp>
using namespace ArduinoJson::Internals;
template <typename T>
void check(const char* input, T expected) {
CAPTURE(input);
T actual = parseInteger<T>(input);
REQUIRE(expected == actual);
}
TEST_CASE("parseInteger<int8_t>()") {
check<int8_t>("-128", -128);
check<int8_t>("127", 127);
check<int8_t>("+127", 127);
check<int8_t>("3.14", 3);
check<int8_t>("x42", 0);
check<int8_t>("128", -128);
check<int8_t>("-129", 127);
check<int8_t>(NULL, 0);
check<int8_t>("true", 1);
check<int8_t>("false", 0);
}
TEST_CASE("parseInteger<int16_t>()") {
check<int16_t>("-32768", -32768);
check<int16_t>("32767", 32767);
check<int16_t>("+32767", 32767);
check<int16_t>("3.14", 3);
check<int16_t>("x42", 0);
check<int16_t>("-32769", 32767);
check<int16_t>("32768", -32768);
check<int16_t>(NULL, 0);
check<int16_t>("true", 1);
check<int16_t>("false", 0);
}
TEST_CASE("parseInteger<int32_t>()") {
check<int32_t>("-2147483648", (-2147483647 - 1));
check<int32_t>("2147483647", 2147483647);
check<int32_t>("+2147483647", 2147483647);
check<int32_t>("3.14", 3);
check<int32_t>("x42", 0);
check<int32_t>("-2147483649", 2147483647);
check<int32_t>("2147483648", (-2147483647 - 1));
check<int32_t>("true", 1);
check<int32_t>("false", 0);
}
TEST_CASE("parseInteger<uint8_t>()") {
check<uint8_t>("0", 0);
check<uint8_t>("255", 255);
check<uint8_t>("+255", 255);
check<uint8_t>("3.14", 3);
check<uint8_t>("x42", 0);
check<uint8_t>("-1", 255);
check<uint8_t>("256", 0);
check<uint8_t>("true", 1);
check<uint8_t>("false", 0);
}
TEST_CASE("parseInteger<uint16_t>()") {
check<uint16_t>("0", 0);
check<uint16_t>("65535", 65535);
check<uint16_t>("+65535", 65535);
check<uint16_t>("3.14", 3);
// check<uint16_t>(" 42", 0);
check<uint16_t>("x42", 0);
check<uint16_t>("-1", 65535);
check<uint16_t>("65536", 0);
check<uint16_t>("true", 1);
check<uint16_t>("false", 0);
}
@@ -0,0 +1,16 @@
# ArduinoJson - arduinojson.org
# Copyright Benoit Blanchon 2014-2018
# MIT License
add_executable(StaticJsonBufferTests
alloc.cpp
createArray.cpp
createObject.cpp
parseArray.cpp
parseObject.cpp
size.cpp
startString.cpp
)
target_link_libraries(StaticJsonBufferTests catch)
add_test(StaticJsonBuffer StaticJsonBufferTests)
@@ -0,0 +1,52 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
static bool isAligned(void *ptr) {
const size_t mask = sizeof(void *) - 1;
size_t addr = reinterpret_cast<size_t>(ptr);
return (addr & mask) == 0;
}
TEST_CASE("StaticJsonBuffer::alloc()") {
StaticJsonBuffer<64> buffer;
SECTION("Returns different addresses") {
void *p1 = buffer.alloc(1);
void *p2 = buffer.alloc(1);
REQUIRE(p1 != p2);
}
SECTION("Returns non-NULL when using full capacity") {
void *p = buffer.alloc(64);
REQUIRE(0 != p);
}
SECTION("Returns NULL when full") {
buffer.alloc(64);
void *p = buffer.alloc(1);
REQUIRE(0 == p);
}
SECTION("Returns NULL when buffer is too small") {
void *p = buffer.alloc(65);
REQUIRE(0 == p);
}
SECTION("Returns aligned pointers") {
for (size_t size = 1; size <= sizeof(void *); size++) {
void *p = buffer.alloc(1);
REQUIRE(isAligned(p));
}
}
SECTION("Returns same address after clear()") {
void *p1 = buffer.alloc(1);
buffer.clear();
void *p2 = buffer.alloc(1);
REQUIRE(p1 == p2);
}
}
@@ -0,0 +1,45 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("StaticJsonBuffer::createArray()") {
SECTION("GrowsWithArray") {
StaticJsonBuffer<JSON_ARRAY_SIZE(2)> json;
JsonArray &array = json.createArray();
REQUIRE(JSON_ARRAY_SIZE(0) == json.size());
array.add("hello");
REQUIRE(JSON_ARRAY_SIZE(1) == json.size());
array.add("world");
REQUIRE(JSON_ARRAY_SIZE(2) == json.size());
}
SECTION("SucceedWhenBigEnough") {
StaticJsonBuffer<JSON_ARRAY_SIZE(0)> json;
JsonArray &array = json.createArray();
REQUIRE(array.success());
}
SECTION("FailsWhenTooSmall") {
StaticJsonBuffer<JSON_ARRAY_SIZE(0) - 1> json;
JsonArray &array = json.createArray();
REQUIRE_FALSE(array.success());
}
SECTION("ArrayDoesntGrowWhenFull") {
StaticJsonBuffer<JSON_ARRAY_SIZE(1)> json;
JsonArray &array = json.createArray();
array.add("hello");
array.add("world");
REQUIRE(1 == array.size());
}
}
@@ -0,0 +1,56 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("StaticJsonBuffer::createObject()") {
SECTION("GrowsWithObject") {
StaticJsonBuffer<JSON_OBJECT_SIZE(3)> buffer;
JsonObject &obj = buffer.createObject();
REQUIRE(JSON_OBJECT_SIZE(0) == buffer.size());
obj["hello"];
REQUIRE(JSON_OBJECT_SIZE(0) == buffer.size());
obj["hello"] = 1;
REQUIRE(JSON_OBJECT_SIZE(1) == buffer.size());
obj["world"] = 2;
REQUIRE(JSON_OBJECT_SIZE(2) == buffer.size());
obj["world"] = 3; // <- same key, should not grow
REQUIRE(JSON_OBJECT_SIZE(2) == buffer.size());
}
SECTION("SucceedWhenBigEnough") {
StaticJsonBuffer<JSON_OBJECT_SIZE(0)> buffer;
JsonObject &object = buffer.createObject();
REQUIRE(object.success());
}
SECTION("FailsWhenTooSmall") {
StaticJsonBuffer<JSON_OBJECT_SIZE(0) - 1> buffer;
JsonObject &object = buffer.createObject();
REQUIRE_FALSE(object.success());
}
SECTION("ObjectDoesntGrowWhenFull") {
StaticJsonBuffer<JSON_OBJECT_SIZE(1)> buffer;
JsonObject &obj = buffer.createObject();
obj["hello"] = 1;
obj["world"] = 2;
REQUIRE(JSON_OBJECT_SIZE(1) == buffer.size());
REQUIRE(1 == obj.size());
char json[64];
obj.printTo(json, sizeof(json));
REQUIRE(std::string("{\"hello\":1}") == json);
}
}
@@ -0,0 +1,71 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("StaticJsonBuffer::parseArray()") {
SECTION("TooSmallBufferForEmptyArray") {
StaticJsonBuffer<JSON_ARRAY_SIZE(0) - 1> bufferTooSmall;
char input[] = "[]";
JsonArray& arr = bufferTooSmall.parseArray(input);
REQUIRE_FALSE(arr.success());
}
SECTION("BufferOfTheRightSizeForEmptyArray") {
StaticJsonBuffer<JSON_ARRAY_SIZE(0)> bufferOfRightSize;
char input[] = "[]";
JsonArray& arr = bufferOfRightSize.parseArray(input);
REQUIRE(arr.success());
}
SECTION("TooSmallBufferForArrayWithOneValue") {
StaticJsonBuffer<JSON_ARRAY_SIZE(1) - 1> bufferTooSmall;
char input[] = "[1]";
JsonArray& arr = bufferTooSmall.parseArray(input);
REQUIRE_FALSE(arr.success());
}
SECTION("BufferOfTheRightSizeForArrayWithOneValue") {
StaticJsonBuffer<JSON_ARRAY_SIZE(1)> bufferOfRightSize;
char input[] = "[1]";
JsonArray& arr = bufferOfRightSize.parseArray(input);
REQUIRE(arr.success());
}
SECTION("TooSmallBufferForArrayWithNestedObject") {
StaticJsonBuffer<JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(0) - 1>
bufferTooSmall;
char input[] = "[{}]";
JsonArray& arr = bufferTooSmall.parseArray(input);
REQUIRE_FALSE(arr.success());
}
SECTION("BufferOfTheRightSizeForArrayWithNestedObject") {
StaticJsonBuffer<JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(0)>
bufferOfRightSize;
char input[] = "[{}]";
JsonArray& arr = bufferOfRightSize.parseArray(input);
REQUIRE(arr.success());
}
SECTION("CharPtrNull") {
REQUIRE_FALSE(
StaticJsonBuffer<100>().parseArray(static_cast<char*>(0)).success());
}
SECTION("ConstCharPtrNull") {
REQUIRE_FALSE(StaticJsonBuffer<100>()
.parseArray(static_cast<const char*>(0))
.success());
}
SECTION("CopyStringNotSpaces") {
StaticJsonBuffer<100> jsonBuffer;
jsonBuffer.parseArray(" [ \"1234567\" ] ");
REQUIRE(JSON_ARRAY_SIZE(1) + sizeof("1234567") == jsonBuffer.size());
// note we use a string of 8 bytes to be sure that the StaticJsonBuffer
// will not insert bytes to enforce alignement
}
}
@@ -0,0 +1,62 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("StaticJsonBuffer::parseObject()") {
SECTION("TooSmallBufferForEmptyObject") {
StaticJsonBuffer<JSON_OBJECT_SIZE(0) - 1> bufferTooSmall;
char input[] = "{}";
JsonObject& obj = bufferTooSmall.parseObject(input);
REQUIRE_FALSE(obj.success());
}
SECTION("BufferOfTheRightSizeForEmptyObject") {
StaticJsonBuffer<JSON_OBJECT_SIZE(0)> bufferOfRightSize;
char input[] = "{}";
JsonObject& obj = bufferOfRightSize.parseObject(input);
REQUIRE(obj.success());
}
SECTION("TooSmallBufferForObjectWithOneValue") {
StaticJsonBuffer<JSON_OBJECT_SIZE(1) - 1> bufferTooSmall;
char input[] = "{\"a\":1}";
JsonObject& obj = bufferTooSmall.parseObject(input);
REQUIRE_FALSE(obj.success());
}
SECTION("BufferOfTheRightSizeForObjectWithOneValue") {
StaticJsonBuffer<JSON_OBJECT_SIZE(1)> bufferOfRightSize;
char input[] = "{\"a\":1}";
JsonObject& obj = bufferOfRightSize.parseObject(input);
REQUIRE(obj.success());
}
SECTION("TooSmallBufferForObjectWithNestedObject") {
StaticJsonBuffer<JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(0) - 1>
bufferTooSmall;
char input[] = "{\"a\":[]}";
JsonObject& obj = bufferTooSmall.parseObject(input);
REQUIRE_FALSE(obj.success());
}
SECTION("BufferOfTheRightSizeForObjectWithNestedObject") {
StaticJsonBuffer<JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(0)>
bufferOfRightSize;
char input[] = "{\"a\":[]}";
JsonObject& obj = bufferOfRightSize.parseObject(input);
REQUIRE(obj.success());
}
SECTION("CharPtrNull") {
REQUIRE_FALSE(
StaticJsonBuffer<100>().parseObject(static_cast<char*>(0)).success());
}
SECTION("ConstCharPtrNull") {
REQUIRE_FALSE(StaticJsonBuffer<100>()
.parseObject(static_cast<const char*>(0))
.success());
}
}
@@ -0,0 +1,42 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("StaticJsonBuffer::size()") {
StaticJsonBuffer<64> buffer;
SECTION("Capacity equals template parameter") {
REQUIRE(64 == buffer.capacity());
}
SECTION("Initial size is 0") {
REQUIRE(0 == buffer.size());
}
SECTION("Increases after alloc()") {
buffer.alloc(1);
REQUIRE(1U <= buffer.size());
buffer.alloc(1);
REQUIRE(2U <= buffer.size());
}
SECTION("Doesn't grow when buffer is full") {
buffer.alloc(64);
buffer.alloc(1);
REQUIRE(64 == buffer.size());
}
SECTION("Does't grow when buffer is too small for alloc") {
buffer.alloc(65);
REQUIRE(0 == buffer.size());
}
SECTION("Goes back to zero after clear()") {
buffer.alloc(1);
buffer.clear();
REQUIRE(0 == buffer.size());
}
}
@@ -0,0 +1,49 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
using namespace ArduinoJson::Internals;
TEST_CASE("StaticJsonBuffer::startString()") {
SECTION("WorksWhenBufferIsBigEnough") {
StaticJsonBuffer<6> jsonBuffer;
StaticJsonBufferBase::String str = jsonBuffer.startString();
str.append('h');
str.append('e');
str.append('l');
str.append('l');
str.append('o');
REQUIRE(std::string("hello") == str.c_str());
}
SECTION("ReturnsNullWhenTooSmall") {
StaticJsonBuffer<5> jsonBuffer;
StaticJsonBufferBase::String str = jsonBuffer.startString();
str.append('h');
str.append('e');
str.append('l');
str.append('l');
str.append('o');
REQUIRE(0 == str.c_str());
}
SECTION("SizeIncreases") {
StaticJsonBuffer<5> jsonBuffer;
StaticJsonBufferBase::String str = jsonBuffer.startString();
REQUIRE(0 == jsonBuffer.size());
str.append('h');
REQUIRE(1 == jsonBuffer.size());
str.c_str();
REQUIRE(2 == jsonBuffer.size());
}
}