Added support for non zero-terminated strings (fixes #704)

This commit is contained in:
Benoit Blanchon
2018-05-14 17:12:59 +02:00
parent 4c9c047ddf
commit ccb54136a2
54 changed files with 2234 additions and 1401 deletions

View File

@ -12,6 +12,7 @@ add_executable(JsonArrayTests
remove.cpp
set.cpp
size.cpp
std_string.cpp
subscript.cpp
)

View File

@ -0,0 +1,39 @@
// 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") {
DynamicJsonDocument doc;
JsonArray &array = doc.to<JsonArray>();
SECTION("add()") {
std::string value("hello");
array.add(value);
eraseString(value);
REQUIRE(std::string("hello") == array[0]);
}
SECTION("set()") {
std::string value("world");
array.add("hello");
array.set(0, value);
eraseString(value);
REQUIRE(std::string("world") == array[0]);
}
SECTION("operator[]") {
std::string value("world");
array.add("hello");
array[0] = value;
eraseString(value);
REQUIRE(std::string("world") == array[0]);
}
}

View File

@ -10,6 +10,8 @@ add_executable(JsonDeserializerTests
deserializeJsonValue.cpp
JsonError.cpp
nestingLimit.cpp
std_istream.cpp
std_string.cpp
)
target_link_libraries(JsonDeserializerTests catch)

View File

@ -25,6 +25,7 @@ TEST_CASE("JsonError") {
TEST_STRINGIFICATION(TooDeep);
TEST_STRINGIFICATION(NoMemory);
TEST_STRINGIFICATION(InvalidInput);
TEST_STRINGIFICATION(IncompleteInput);
}
SECTION("as boolean") {
@ -32,6 +33,7 @@ TEST_CASE("JsonError") {
TEST_BOOLIFICATION(TooDeep, true);
TEST_BOOLIFICATION(NoMemory, true);
TEST_BOOLIFICATION(InvalidInput, true);
TEST_BOOLIFICATION(IncompleteInput, true);
}
SECTION("ostream") {

View File

@ -164,13 +164,13 @@ TEST_CASE("deserialize JSON array") {
SECTION("Closing single quotes missing") {
JsonError err = deserializeJson(doc, "[\"]");
REQUIRE(err == JsonError::InvalidInput);
REQUIRE(err == JsonError::IncompleteInput);
}
SECTION("Closing double quotes missing") {
JsonError err = deserializeJson(doc, "[\']");
REQUIRE(err == JsonError::InvalidInput);
REQUIRE(err == JsonError::IncompleteInput);
}
}
@ -233,21 +233,21 @@ TEST_CASE("deserialize JSON array") {
SECTION("/*/") {
JsonError err = deserializeJson(doc, "[/*/\n]");
REQUIRE(err == JsonError::InvalidInput);
REQUIRE(err == JsonError::IncompleteInput);
}
SECTION("Unfinished comment") {
JsonError err = deserializeJson(doc, "[/*COMMENT]");
REQUIRE(err == JsonError::InvalidInput);
REQUIRE(err == JsonError::IncompleteInput);
}
SECTION("Final slash missing") {
JsonError err = deserializeJson(doc, "[/*COMMENT*]");
REQUIRE(err == JsonError::InvalidInput);
REQUIRE(err == JsonError::IncompleteInput);
}
}
SECTION("Line comments") {
SECTION("Trailing comments") {
SECTION("Before opening bracket") {
JsonError err = deserializeJson(doc, "//COMMENT\n\t[\"hello\"]");
JsonArray& arr = doc.as<JsonArray>();
@ -311,39 +311,53 @@ TEST_CASE("deserialize JSON array") {
SECTION("End document with comment") {
JsonError err = deserializeJson(doc, "[//COMMENT");
REQUIRE(err == JsonError::InvalidInput);
REQUIRE(err == JsonError::IncompleteInput);
}
}
SECTION("Premature null-terminator") {
SECTION("After opening bracket") {
JsonError err = deserializeJson(doc, "[");
REQUIRE(err == JsonError::IncompleteInput);
}
SECTION("After value") {
JsonError err = deserializeJson(doc, "[1");
REQUIRE(err == JsonError::IncompleteInput);
}
SECTION("After comma") {
JsonError err = deserializeJson(doc, "[1,");
REQUIRE(err == JsonError::IncompleteInput);
}
}
SECTION("Premature end of input") {
const char* input = "[1,2]";
SECTION("After opening bracket") {
JsonError err = deserializeJson(doc, input, 1);
REQUIRE(err == JsonError::IncompleteInput);
}
SECTION("After value") {
JsonError err = deserializeJson(doc, input, 2);
REQUIRE(err == JsonError::IncompleteInput);
}
SECTION("After comma") {
JsonError err = deserializeJson(doc, input, 3);
REQUIRE(err == JsonError::IncompleteInput);
}
}
SECTION("Misc") {
SECTION("Garbage") {
JsonError err = deserializeJson(doc, "%*$£¤");
REQUIRE(err == JsonError::InvalidInput);
}
SECTION("The opening bracket is missing") {
JsonError err = deserializeJson(doc, "]");
REQUIRE(err == JsonError::InvalidInput);
}
SECTION("The closing bracket is missing") {
JsonError err = deserializeJson(doc, "[");
REQUIRE(err == JsonError::InvalidInput);
}
SECTION("Escape sequences") {
JsonError err =
deserializeJson(doc, "[\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"]");
JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok);
REQUIRE(1 == arr.size());
REQUIRE(arr[0] == "1\"2\\3/4\b5\f6\n7\r8\t9");
}
SECTION("Nested objects") {
char jsonString[] =
" [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] ";

View File

@ -21,7 +21,7 @@ TEST_CASE("deserialize JSON array with a StaticJsonDocument") {
JsonError err = deserializeJson(doc, input);
REQUIRE(err != JsonError::Ok);
REQUIRE(err == JsonError::NoMemory);
}
SECTION("BufferOfTheRightSizeForArrayWithOneValue") {
@ -39,7 +39,7 @@ TEST_CASE("deserialize JSON array with a StaticJsonDocument") {
JsonError err = deserializeJson(doc, input);
REQUIRE(err != JsonError::Ok);
REQUIRE(err == JsonError::NoMemory);
}
SECTION("BufferOfTheRightSizeForArrayWithNestedObject") {
@ -51,22 +51,6 @@ TEST_CASE("deserialize JSON array with a StaticJsonDocument") {
REQUIRE(err == JsonError::Ok);
}
SECTION("CharPtrNull") {
StaticJsonDocument<100> doc;
JsonError err = deserializeJson(doc, static_cast<char*>(0));
REQUIRE(err != JsonError::Ok);
}
SECTION("ConstCharPtrNull") {
StaticJsonDocument<100> doc;
JsonError err = deserializeJson(doc, static_cast<const char*>(0));
REQUIRE(err != JsonError::Ok);
}
SECTION("CopyStringNotSpaces") {
StaticJsonDocument<100> doc;

View File

@ -212,19 +212,39 @@ TEST_CASE("deserialize JSON object") {
}
}
SECTION("Misc") {
SECTION("The opening brace is missing") {
JsonError err = deserializeJson(doc, "}");
SECTION("Premature null terminator") {
SECTION("After opening brace") {
JsonError err = deserializeJson(doc, "{");
REQUIRE(err == JsonError::InvalidInput);
REQUIRE(err == JsonError::IncompleteInput);
}
SECTION("The closing brace is missing") {
SECTION("After key") {
JsonError err = deserializeJson(doc, "{\"hello\"");
REQUIRE(err == JsonError::IncompleteInput);
}
SECTION("After colon") {
JsonError err = deserializeJson(doc, "{\"hello\":");
REQUIRE(err == JsonError::IncompleteInput);
}
SECTION("After value") {
JsonError err = deserializeJson(doc, "{\"hello\":\"world\"");
REQUIRE(err == JsonError::InvalidInput);
REQUIRE(err == JsonError::IncompleteInput);
}
SECTION("After comma") {
JsonError err = deserializeJson(doc, "{\"hello\":\"world\",");
REQUIRE(err == JsonError::IncompleteInput);
}
}
SECTION("Misc") {
SECTION("A quoted key without value") {
JsonError err = deserializeJson(doc, "{\"key\"}");
@ -250,6 +270,200 @@ TEST_CASE("deserialize JSON object") {
}
}
SECTION("Block comments") {
SECTION("Before opening brace") {
JsonError err = deserializeJson(doc, "/*COMMENT*/ {\"hello\":\"world\"}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("After opening brace") {
JsonError err = deserializeJson(doc, "{/*COMMENT*/\"hello\":\"world\"}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("Before colon") {
JsonError err = deserializeJson(doc, "{\"hello\"/*COMMENT*/:\"world\"}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("After colon") {
JsonError err = deserializeJson(doc, "{\"hello\":/*COMMENT*/\"world\"}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("Before closing brace") {
JsonError err = deserializeJson(doc, "{\"hello\":\"world\"/*COMMENT*/}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("After closing brace") {
JsonError err = deserializeJson(doc, "{\"hello\":\"world\"}/*COMMENT*/");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("Before comma") {
JsonError err = deserializeJson(
doc, "{\"hello\":\"world\"/*COMMENT*/,\"answer\":42}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok);
REQUIRE(obj["hello"] == "world");
REQUIRE(obj["answer"] == 42);
}
SECTION("After comma") {
JsonError err = deserializeJson(
doc, "{\"hello\":\"world\",/*COMMENT*/\"answer\":42}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok);
REQUIRE(obj["hello"] == "world");
REQUIRE(obj["answer"] == 42);
}
}
SECTION("Trailing comments") {
SECTION("Before opening brace") {
JsonError err = deserializeJson(doc, "//COMMENT\n {\"hello\":\"world\"}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("After opening brace") {
JsonError err = deserializeJson(doc, "{//COMMENT\n\"hello\":\"world\"}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("Before colon") {
JsonError err = deserializeJson(doc, "{\"hello\"//COMMENT\n:\"world\"}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("After colon") {
JsonError err = deserializeJson(doc, "{\"hello\"://COMMENT\n\"world\"}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("Before closing brace") {
JsonError err = deserializeJson(doc, "{\"hello\":\"world\"//COMMENT\n}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("After closing brace") {
JsonError err = deserializeJson(doc, "{\"hello\":\"world\"}//COMMENT\n");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("Before comma") {
JsonError err = deserializeJson(
doc, "{\"hello\":\"world\"//COMMENT\n,\"answer\":42}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok);
REQUIRE(obj["hello"] == "world");
REQUIRE(obj["answer"] == 42);
}
SECTION("After comma") {
JsonError err = deserializeJson(
doc, "{\"hello\":\"world\",//COMMENT\n\"answer\":42}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok);
REQUIRE(obj["hello"] == "world");
REQUIRE(obj["answer"] == 42);
}
}
SECTION("Dangling slash") {
SECTION("Before opening brace") {
JsonError err = deserializeJson(doc, "/{\"hello\":\"world\"}");
REQUIRE(err == JsonError::InvalidInput);
}
SECTION("After opening brace") {
JsonError err = deserializeJson(doc, "{/\"hello\":\"world\"}");
REQUIRE(err == JsonError::InvalidInput);
}
SECTION("Before colon") {
JsonError err = deserializeJson(doc, "{\"hello\"/:\"world\"}");
REQUIRE(err == JsonError::InvalidInput);
}
SECTION("After colon") {
JsonError err = deserializeJson(doc, "{\"hello\":/\"world\"}");
REQUIRE(err == JsonError::InvalidInput);
}
SECTION("Before closing brace") {
JsonError err = deserializeJson(doc, "{\"hello\":\"world\"/}");
REQUIRE(err == JsonError::InvalidInput);
}
SECTION("After closing brace") {
JsonError err = deserializeJson(doc, "{\"hello\":\"world\"}/");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok);
REQUIRE(obj["hello"] == "world");
}
SECTION("Before comma") {
JsonError err =
deserializeJson(doc, "{\"hello\":\"world\"/,\"answer\":42}");
REQUIRE(err == JsonError::InvalidInput);
}
SECTION("After comma") {
JsonError err =
deserializeJson(doc, "{\"hello\":\"world\",/\"answer\":42}");
REQUIRE(err == JsonError::InvalidInput);
}
}
SECTION("Should clear the JsonObject") {
deserializeJson(doc, "{\"hello\":\"world\"}");
deserializeJson(doc, "{}");

View File

@ -21,7 +21,7 @@ TEST_CASE("deserialize JSON object with StaticJsonDocument") {
JsonError err = deserializeJson(doc, input);
REQUIRE(err != JsonError::Ok);
REQUIRE(err == JsonError::NoMemory);
}
SECTION("BufferOfTheRightSizeForObjectWithOneValue") {
@ -39,7 +39,7 @@ TEST_CASE("deserialize JSON object with StaticJsonDocument") {
JsonError err = deserializeJson(doc, input);
REQUIRE(err != JsonError::Ok);
REQUIRE(err == JsonError::NoMemory);
}
SECTION("BufferOfTheRightSizeForObjectWithNestedObject") {
@ -51,22 +51,6 @@ TEST_CASE("deserialize JSON object with StaticJsonDocument") {
REQUIRE(err == JsonError::Ok);
}
SECTION("CharPtrNull") {
StaticJsonDocument<100> doc;
JsonError err = deserializeJson(doc, static_cast<char*>(0));
REQUIRE(err != JsonError::Ok);
}
SECTION("ConstCharPtrNull") {
StaticJsonDocument<100> doc;
JsonError err = deserializeJson(doc, static_cast<const char*>(0));
REQUIRE(err != JsonError::Ok);
}
SECTION("Should clear the JsonObject") {
StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc;
char input[] = "{\"hello\":\"world\"}";

View File

@ -10,18 +10,16 @@ using namespace Catch::Matchers;
TEST_CASE("deserializeJson(DynamicJsonDocument&)") {
DynamicJsonDocument doc;
SECTION("EmptyObject") {
JsonError err = deserializeJson(doc, "{}");
SECTION("null char*") {
JsonError err = deserializeJson(doc, static_cast<char*>(0));
REQUIRE(err == JsonError::Ok);
REQUIRE(doc.is<JsonObject>());
REQUIRE(err != JsonError::Ok);
}
SECTION("EmptyArray") {
JsonError err = deserializeJson(doc, "[]");
SECTION("null const char*") {
JsonError err = deserializeJson(doc, static_cast<const char*>(0));
REQUIRE(err == JsonError::Ok);
REQUIRE(doc.is<JsonArray>());
REQUIRE(err != JsonError::Ok);
}
SECTION("Integer") {
@ -58,6 +56,14 @@ TEST_CASE("deserializeJson(DynamicJsonDocument&)") {
REQUIRE_THAT(doc.as<char*>(), Equals("hello world"));
}
SECTION("Escape sequences") {
JsonError err =
deserializeJson(doc, "\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"");
REQUIRE(err == JsonError::Ok);
REQUIRE(doc.as<std::string>() == "1\"2\\3/4\b5\f6\n7\r8\t9");
}
SECTION("True") {
JsonError err = deserializeJson(doc, "true");
@ -74,25 +80,6 @@ TEST_CASE("deserializeJson(DynamicJsonDocument&)") {
REQUIRE(doc.as<bool>() == false);
}
SECTION("OpenBrace") {
JsonError err = deserializeJson(doc, "{");
REQUIRE(err != JsonError::Ok);
}
SECTION("Incomplete string") {
JsonError err = deserializeJson(doc, "\"hello");
REQUIRE(err == JsonError::Ok);
REQUIRE(doc.is<char*>());
REQUIRE_THAT(doc.as<char*>(), Equals("hello"));
}
SECTION("Unterminated escape sequence") {
JsonError err = deserializeJson(doc, "\"\\\0\"");
REQUIRE(err == JsonError::InvalidInput);
}
SECTION("Should clear the JsonVariant") {
deserializeJson(doc, "[1,2,3]");
deserializeJson(doc, "{}");
@ -100,4 +87,86 @@ TEST_CASE("deserializeJson(DynamicJsonDocument&)") {
REQUIRE(doc.is<JsonObject>());
REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0));
}
SECTION("Empty input") {
JsonError err = deserializeJson(doc, "");
REQUIRE(err == JsonError::IncompleteInput);
}
SECTION("Just a trailing comment") {
JsonError err = deserializeJson(doc, "// comment");
REQUIRE(err == JsonError::IncompleteInput);
}
SECTION("Just a block comment") {
JsonError err = deserializeJson(doc, "/*comment*/");
REQUIRE(err == JsonError::IncompleteInput);
}
SECTION("Just a slash") {
JsonError err = deserializeJson(doc, "/");
REQUIRE(err == JsonError::InvalidInput);
}
SECTION("Garbage") {
JsonError err = deserializeJson(doc, "%*$£¤");
REQUIRE(err == JsonError::InvalidInput);
}
SECTION("Premature null-terminator") {
SECTION("In escape sequence") {
JsonError err = deserializeJson(doc, "\"\\");
REQUIRE(err == JsonError::IncompleteInput);
}
SECTION("In block comment") {
JsonError err = deserializeJson(doc, "/* comment");
REQUIRE(err == JsonError::IncompleteInput);
}
SECTION("In double quoted string") {
JsonError err = deserializeJson(doc, "\"hello");
REQUIRE(err == JsonError::IncompleteInput);
}
SECTION("In single quoted string") {
JsonError err = deserializeJson(doc, "'hello");
REQUIRE(err == JsonError::IncompleteInput);
}
}
SECTION("Premature end of input") {
SECTION("In escape sequence") {
JsonError err = deserializeJson(doc, "\"\\n\"", 2);
REQUIRE(err == JsonError::IncompleteInput);
}
SECTION("In block comment") {
JsonError err = deserializeJson(doc, "/* comment */", 10);
REQUIRE(err == JsonError::IncompleteInput);
}
SECTION("In double quoted string") {
JsonError err = deserializeJson(doc, "\"hello\"", 6);
REQUIRE(err == JsonError::IncompleteInput);
}
SECTION("In single quoted string") {
JsonError err = deserializeJson(doc, "'hello'", 6);
REQUIRE(err == JsonError::IncompleteInput);
}
}
}

View File

@ -0,0 +1,73 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
#include <sstream>
TEST_CASE("deserializeJson(std::istream&)") {
DynamicJsonDocument doc;
SECTION("array") {
std::istringstream json(" [ 42 /* comment */ ] ");
JsonError err = deserializeJson(doc, json);
JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok);
REQUIRE(1 == arr.size());
REQUIRE(42 == arr[0]);
}
SECTION("object") {
std::istringstream json(" { hello : world // comment\n }");
JsonError err = deserializeJson(doc, json);
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok);
REQUIRE(1 == obj.size());
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("Should not read after the closing brace of an empty object") {
std::istringstream json("{}123");
deserializeJson(doc, json);
REQUIRE('1' == char(json.get()));
}
SECTION("Should not read after the closing brace") {
std::istringstream json("{\"hello\":\"world\"}123");
deserializeJson(doc, json);
REQUIRE('1' == char(json.get()));
}
SECTION("Should not read after the closing bracket of an empty array") {
std::istringstream json("[]123");
deserializeJson(doc, json);
REQUIRE('1' == char(json.get()));
}
SECTION("Should not read after the closing bracket") {
std::istringstream json("[\"hello\",\"world\"]123");
deserializeJson(doc, json);
REQUIRE('1' == char(json.get()));
}
SECTION("Should not read after the closing quote") {
std::istringstream json("\"hello\"123");
deserializeJson(doc, json);
REQUIRE('1' == char(json.get()));
}
}

View File

@ -0,0 +1,35 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("deserializeJson(const std::string&)") {
DynamicJsonDocument doc;
SECTION("should accept const string") {
const std::string input("[42]");
JsonError err = deserializeJson(doc, input);
REQUIRE(err == JsonError::Ok);
}
SECTION("should accept temporary string") {
JsonError err = deserializeJson(doc, std::string("[42]"));
REQUIRE(err == JsonError::Ok);
}
SECTION("should duplicate content") {
std::string input("[\"hello\"]");
JsonError err = deserializeJson(doc, input);
input[2] = 'X'; // alter the string tomake sure we made a copy
JsonArray &array = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok);
REQUIRE(std::string("hello") == array[0]);
}
}

View File

@ -11,6 +11,7 @@ add_executable(JsonObjectTests
remove.cpp
set.cpp
size.cpp
std_string.cpp
subscript.cpp
)

View File

@ -0,0 +1,173 @@
// 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") {
DynamicJsonDocument doc;
SECTION("operator[]") {
char json[] = "{\"key\":\"value\"}";
deserializeJson(doc, json);
JsonObject &obj = doc.as<JsonObject>();
REQUIRE(std::string("value") == obj[std::string("key")]);
}
SECTION("operator[] const") {
char json[] = "{\"key\":\"value\"}";
deserializeJson(doc, json);
JsonObject &obj = doc.as<JsonObject>();
REQUIRE(std::string("value") == obj[std::string("key")]);
}
SECTION("set(key)") {
JsonObject &obj = doc.to<JsonObject>();
std::string key("hello");
obj.set(key, "world");
eraseString(key);
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("set(value)") {
JsonObject &obj = doc.to<JsonObject>();
std::string value("world");
obj.set("hello", value);
eraseString(value);
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("set(key,value)") {
JsonObject &obj = doc.to<JsonObject>();
std::string key("hello");
std::string value("world");
obj.set(key, value);
eraseString(key);
eraseString(value);
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("set(JsonArraySubscript)") {
JsonObject &obj = doc.to<JsonObject>();
DynamicJsonDocument doc2;
JsonArray &arr = doc2.to<JsonArray>();
arr.add("world");
obj.set(std::string("hello"), arr[0]);
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("set(JsonObjectSubscript)") {
JsonObject &obj = doc.to<JsonObject>();
DynamicJsonDocument doc2;
JsonObject &obj2 = doc2.to<JsonObject>();
obj2.set("x", "world");
obj.set(std::string("hello"), obj2["x"]);
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("get<T>()") {
char json[] = "{\"key\":\"value\"}";
deserializeJson(doc, json);
JsonObject &obj = doc.as<JsonObject>();
REQUIRE(std::string("value") == obj.get<const char *>(std::string("key")));
}
SECTION("is<T>()") {
char json[] = "{\"key\":\"value\"}";
deserializeJson(doc, json);
JsonObject &obj = doc.as<JsonObject>();
REQUIRE(true == obj.is<const char *>(std::string("key")));
}
SECTION("createNestedObject()") {
JsonObject &obj = doc.to<JsonObject>();
std::string key = "key";
char json[64];
obj.createNestedObject(key);
eraseString(key);
serializeJson(doc, json, sizeof(json));
REQUIRE(std::string("{\"key\":{}}") == json);
}
SECTION("createNestedArray()") {
JsonObject &obj = doc.to<JsonObject>();
std::string key = "key";
char json[64];
obj.createNestedArray(key);
eraseString(key);
serializeJson(doc, json, sizeof(json));
REQUIRE(std::string("{\"key\":[]}") == json);
}
SECTION("containsKey()") {
char json[] = "{\"key\":\"value\"}";
deserializeJson(doc, json);
JsonObject &obj = doc.as<JsonObject>();
REQUIRE(true == obj.containsKey(std::string("key")));
}
SECTION("remove()") {
JsonObject &obj = doc.to<JsonObject>();
obj["key"] = "value";
obj.remove(std::string("key"));
REQUIRE(0 == obj.size());
}
SECTION("operator[], set key") {
std::string key("hello");
JsonObject &obj = doc.to<JsonObject>();
obj[key] = "world";
eraseString(key);
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("operator[], set value") {
std::string value("world");
JsonObject &obj = doc.to<JsonObject>();
obj["hello"] = value;
eraseString(value);
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("memoryUsage() increases when adding a new key") {
std::string key1("hello"), key2("world");
JsonObject &obj = doc.to<JsonObject>();
obj[key1] = 1;
size_t sizeBefore = doc.memoryUsage();
obj[key2] = 2;
size_t sizeAfter = doc.memoryUsage();
REQUIRE(sizeAfter - sizeBefore >= key2.size());
}
SECTION("memoryUsage() remains when adding the same key") {
std::string key("hello");
JsonObject &obj = doc.to<JsonObject>();
obj[key] = 1;
size_t sizeBefore = doc.memoryUsage();
obj[key] = 2;
size_t sizeAfter = doc.memoryUsage();
REQUIRE(sizeBefore == sizeAfter);
}
}

View File

@ -8,6 +8,8 @@ add_executable(JsonSerializerTests
JsonObject.cpp
JsonObjectPretty.cpp
JsonVariant.cpp
std_stream.cpp
std_string.cpp
)
target_link_libraries(JsonSerializerTests catch)

View File

@ -0,0 +1,64 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
#include <sstream>
TEST_CASE("operator<<(std::ostream)") {
DynamicJsonDocument doc;
std::ostringstream os;
SECTION("JsonVariant containing false") {
JsonVariant variant = false;
os << variant;
REQUIRE("false" == os.str());
}
SECTION("JsonVariant containing string") {
JsonVariant variant = "coucou";
os << variant;
REQUIRE("\"coucou\"" == os.str());
}
SECTION("JsonObject") {
JsonObject& object = doc.to<JsonObject>();
object["key"] = "value";
os << object;
REQUIRE("{\"key\":\"value\"}" == os.str());
}
SECTION("JsonObjectSubscript") {
JsonObject& object = doc.to<JsonObject>();
object["key"] = "value";
os << object["key"];
REQUIRE("\"value\"" == os.str());
}
SECTION("JsonArray") {
JsonArray& array = doc.to<JsonArray>();
array.add("value");
os << array;
REQUIRE("[\"value\"]" == os.str());
}
SECTION("JsonArraySubscript") {
JsonArray& array = doc.to<JsonArray>();
array.add("value");
os << array[0];
REQUIRE("\"value\"" == os.str());
}
}

View File

@ -0,0 +1,47 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("serialize JsonArray to std::string") {
DynamicJsonDocument doc;
JsonArray &array = doc.to<JsonArray>();
array.add(4);
array.add(2);
SECTION("serializeJson()") {
std::string json;
serializeJson(array, json);
REQUIRE(std::string("[4,2]") == json);
}
SECTION("serializeJsonPretty") {
std::string json;
serializeJsonPretty(array, json);
REQUIRE(std::string("[\r\n 4,\r\n 2\r\n]") == json);
}
}
TEST_CASE("serialize JsonObject to std::string") {
DynamicJsonDocument doc;
JsonObject &obj = doc.to<JsonObject>();
obj["key"] = "value";
SECTION("object") {
std::string json;
serializeJson(doc, json);
REQUIRE(std::string("{\"key\":\"value\"}") == json);
}
SECTION("serializeJsonPretty") {
std::string json;
serializeJsonPretty(doc, json);
REQUIRE(std::string("{\r\n \"key\": \"value\"\r\n}") == json);
}
}

View File

@ -2,10 +2,8 @@
# Copyright Benoit Blanchon 2014-2018
# MIT License
add_executable(MiscTests
add_executable(MiscTests
FloatParts.cpp
std_stream.cpp
std_string.cpp
StringBuilder.cpp
StringTraits.cpp
TypeTraits.cpp

View File

@ -1,88 +0,0 @@
// 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;
DynamicJsonDocument doc;
JsonObject& object = doc.to<JsonObject>();
object["key"] = "value";
os << object;
REQUIRE("{\"key\":\"value\"}" == os.str());
}
SECTION("JsonObjectSubscript") {
std::ostringstream os;
DynamicJsonDocument doc;
JsonObject& object = doc.to<JsonObject>();
object["key"] = "value";
os << object["key"];
REQUIRE("\"value\"" == os.str());
}
SECTION("JsonArray") {
std::ostringstream os;
DynamicJsonDocument doc;
JsonArray& array = doc.to<JsonArray>();
array.add("value");
os << array;
REQUIRE("[\"value\"]" == os.str());
}
SECTION("JsonArraySubscript") {
std::ostringstream os;
DynamicJsonDocument doc;
JsonArray& array = doc.to<JsonArray>();
array.add("value");
os << array[0];
REQUIRE("\"value\"" == os.str());
}
SECTION("ParseArray") {
std::istringstream json(" [ 42 /* comment */ ] ");
DynamicJsonDocument doc;
JsonError err = deserializeJson(doc, json);
JsonArray& arr = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok);
REQUIRE(1 == arr.size());
REQUIRE(42 == arr[0]);
}
SECTION("ParseObject") {
std::istringstream json(" { hello : world // comment\n }");
DynamicJsonDocument doc;
JsonError err = deserializeJson(doc, json);
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(err == JsonError::Ok);
REQUIRE(1 == obj.size());
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("ShouldNotReadPastTheEnd") {
std::istringstream json("{}123");
DynamicJsonDocument doc;
deserializeJson(doc, json);
REQUIRE('1' == json.get());
}
}

View File

@ -1,259 +0,0 @@
// 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") {
SECTION("deserializeJson duplicates content") {
std::string json("[\"hello\"]");
DynamicJsonDocument doc;
JsonError err = deserializeJson(doc, json);
eraseString(json);
JsonArray &array = doc.as<JsonArray>();
REQUIRE(err == JsonError::Ok);
REQUIRE(std::string("hello") == array[0]);
}
SECTION("JsonArray") {
DynamicJsonDocument doc;
JsonArray &array = doc.to<JsonArray>();
SECTION("add()") {
std::string value("hello");
array.add(value);
eraseString(value);
REQUIRE(std::string("hello") == array[0]);
}
SECTION("set()") {
std::string value("world");
array.add("hello");
array.set(0, value);
eraseString(value);
REQUIRE(std::string("world") == array[0]);
}
SECTION("operator[]") {
std::string value("world");
array.add("hello");
array[0] = value;
eraseString(value);
REQUIRE(std::string("world") == array[0]);
}
SECTION("serializeJson()") {
array.add(4);
array.add(2);
std::string json;
serializeJson(array, json);
REQUIRE(std::string("[4,2]") == json);
}
SECTION("serializeJsonPretty()") {
array.add(4);
array.add(2);
std::string json;
serializeJsonPretty(array, json);
REQUIRE(std::string("[\r\n 4,\r\n 2\r\n]") == json);
}
}
SECTION("JsonObject") {
DynamicJsonDocument doc;
SECTION("deserializeJson()") {
std::string json("{\"hello\":\"world\"}");
JsonError err = deserializeJson(doc, json);
JsonObject &obj = doc.as<JsonObject>();
eraseString(json);
REQUIRE(err == JsonError::Ok);
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("operator[]") {
char json[] = "{\"key\":\"value\"}";
deserializeJson(doc, json);
JsonObject &obj = doc.as<JsonObject>();
REQUIRE(std::string("value") == obj[std::string("key")]);
}
SECTION("operator[] const") {
char json[] = "{\"key\":\"value\"}";
deserializeJson(doc, json);
JsonObject &obj = doc.as<JsonObject>();
REQUIRE(std::string("value") == obj[std::string("key")]);
}
SECTION("set(key)") {
JsonObject &obj = doc.to<JsonObject>();
std::string key("hello");
obj.set(key, "world");
eraseString(key);
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("set(value)") {
JsonObject &obj = doc.to<JsonObject>();
std::string value("world");
obj.set("hello", value);
eraseString(value);
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("set(key,value)") {
JsonObject &obj = doc.to<JsonObject>();
std::string key("hello");
std::string value("world");
obj.set(key, value);
eraseString(key);
eraseString(value);
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("set(JsonArraySubscript)") {
JsonObject &obj = doc.to<JsonObject>();
DynamicJsonDocument doc2;
JsonArray &arr = doc2.to<JsonArray>();
arr.add("world");
obj.set(std::string("hello"), arr[0]);
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("set(JsonObjectSubscript)") {
JsonObject &obj = doc.to<JsonObject>();
DynamicJsonDocument doc2;
JsonObject &obj2 = doc2.to<JsonObject>();
obj2.set("x", "world");
obj.set(std::string("hello"), obj2["x"]);
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("get<T>()") {
char json[] = "{\"key\":\"value\"}";
deserializeJson(doc, json);
JsonObject &obj = doc.as<JsonObject>();
REQUIRE(std::string("value") ==
obj.get<const char *>(std::string("key")));
}
SECTION("is<T>()") {
char json[] = "{\"key\":\"value\"}";
deserializeJson(doc, json);
JsonObject &obj = doc.as<JsonObject>();
REQUIRE(true == obj.is<const char *>(std::string("key")));
}
SECTION("createNestedObject()") {
JsonObject &obj = doc.to<JsonObject>();
std::string key = "key";
char json[64];
obj.createNestedObject(key);
eraseString(key);
serializeJson(doc, json, sizeof(json));
REQUIRE(std::string("{\"key\":{}}") == json);
}
SECTION("createNestedArray()") {
JsonObject &obj = doc.to<JsonObject>();
std::string key = "key";
char json[64];
obj.createNestedArray(key);
eraseString(key);
serializeJson(doc, json, sizeof(json));
REQUIRE(std::string("{\"key\":[]}") == json);
}
SECTION("containsKey()") {
char json[] = "{\"key\":\"value\"}";
deserializeJson(doc, json);
JsonObject &obj = doc.as<JsonObject>();
REQUIRE(true == obj.containsKey(std::string("key")));
}
SECTION("remove()") {
JsonObject &obj = doc.to<JsonObject>();
obj["key"] = "value";
obj.remove(std::string("key"));
REQUIRE(0 == obj.size());
}
SECTION("operator[], set key") {
std::string key("hello");
JsonObject &obj = doc.to<JsonObject>();
obj[key] = "world";
eraseString(key);
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("operator[], set value") {
std::string value("world");
JsonObject &obj = doc.to<JsonObject>();
obj["hello"] = value;
eraseString(value);
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("serializeJson()") {
JsonObject &obj = doc.to<JsonObject>();
obj["key"] = "value";
std::string json;
serializeJson(doc, json);
REQUIRE(std::string("{\"key\":\"value\"}") == json);
}
SECTION("serializeJsonPretty()") {
JsonObject &obj = doc.to<JsonObject>();
obj["key"] = "value";
std::string json;
serializeJsonPretty(doc, json);
REQUIRE(std::string("{\r\n \"key\": \"value\"\r\n}") == json);
}
SECTION("memoryUsage() increases when adding a new key") {
std::string key1("hello"), key2("world");
JsonObject &obj = doc.to<JsonObject>();
obj[key1] = 1;
size_t sizeBefore = doc.memoryUsage();
obj[key2] = 2;
size_t sizeAfter = doc.memoryUsage();
REQUIRE(sizeAfter - sizeBefore >= key2.size());
}
SECTION("memoryUsage() remains when adding the same key") {
std::string key("hello");
JsonObject &obj = doc.to<JsonObject>();
obj[key] = 1;
size_t sizeBefore = doc.memoryUsage();
obj[key] = 2;
size_t sizeAfter = doc.memoryUsage();
REQUIRE(sizeBefore == sizeAfter);
}
}
}

View File

@ -9,259 +9,267 @@
#define CONFLICTS_WITH_BUILTIN_OPERATOR
#endif
TEST_CASE("unsigned char string") {
SECTION("JsonBuffer::parseArray") {
unsigned char json[] = "[42]";
StaticJsonDocument<JSON_ARRAY_SIZE(1)> doc;
JsonError err = deserializeJson(doc, json);
REQUIRE(err == JsonError::Ok);
}
SECTION("JsonBuffer::parseObject") {
unsigned char json[] = "{\"a\":42}";
TEST_CASE("unsigned char[]") {
SECTION("deserializeJson()") {
unsigned char input[] = "{\"a\":42}";
StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc;
JsonError err = deserializeJson(doc, json);
JsonError err = deserializeJson(doc, input);
REQUIRE(err == JsonError::Ok);
}
SECTION("JsonVariant constructor") {
unsigned char value[] = "42";
SECTION("deserializeMsgPack()") {
unsigned char input[] = "\xDE\x00\x01\xA5Hello\xA5world";
JsonVariant variant(value);
StaticJsonDocument<JSON_OBJECT_SIZE(2)> doc;
MsgPackError err = deserializeMsgPack(doc, input);
REQUIRE(42 == variant.as<int>());
REQUIRE(err == MsgPackError::Ok);
}
SECTION("JsonVariant assignment operator") {
unsigned char value[] = "42";
SECTION("JsonVariant") {
SECTION("constructor") {
unsigned char value[] = "42";
JsonVariant variant(666);
variant = value;
JsonVariant variant(value);
REQUIRE(42 == variant.as<int>());
}
REQUIRE(42 == variant.as<int>());
}
SECTION("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";
SECTION("operator[]") {
unsigned char key[] = "hello";
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
JsonVariant variant = doc.as<JsonVariant>();
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
JsonVariant variant = doc.as<JsonVariant>();
REQUIRE(std::string("world") == variant[key]);
}
REQUIRE(std::string("world") == variant[key]);
}
#endif
#ifndef CONFLICTS_WITH_BUILTIN_OPERATOR
SECTION("JsonVariant::operator[] const") {
unsigned char key[] = "hello";
SECTION("operator[] const") {
unsigned char key[] = "hello";
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
const JsonVariant variant = doc.as<JsonVariant>();
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
const JsonVariant variant = doc.as<JsonVariant>();
REQUIRE(std::string("world") == variant[key]);
}
REQUIRE(std::string("world") == variant[key]);
}
#endif
SECTION("JsonVariant::operator==") {
unsigned char comparand[] = "hello";
SECTION("operator==") {
unsigned char comparand[] = "hello";
JsonVariant variant;
variant = "hello";
JsonVariant variant;
variant = "hello";
REQUIRE(comparand == variant);
REQUIRE(variant == comparand);
REQUIRE_FALSE(comparand != variant);
REQUIRE_FALSE(variant != comparand);
}
SECTION("JsonVariant::operator!=") {
unsigned char comparand[] = "hello";
JsonVariant variant;
variant = "world";
REQUIRE(comparand != variant);
REQUIRE(variant != comparand);
REQUIRE_FALSE(comparand == variant);
REQUIRE_FALSE(variant == comparand);
REQUIRE(comparand == variant);
REQUIRE(variant == comparand);
REQUIRE_FALSE(comparand != variant);
REQUIRE_FALSE(variant != comparand);
}
SECTION("operator!=") {
unsigned char comparand[] = "hello";
JsonVariant variant;
variant = "world";
REQUIRE(comparand != variant);
REQUIRE(variant != comparand);
REQUIRE_FALSE(comparand == variant);
REQUIRE_FALSE(variant == comparand);
}
}
SECTION("JsonObject") {
#ifndef CONFLICTS_WITH_BUILTIN_OPERATOR
SECTION("JsonObject::operator[]") {
unsigned char key[] = "hello";
SECTION("operator[]") {
unsigned char key[] = "hello";
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj[key] = "world";
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj[key] = "world";
REQUIRE(std::string("world") == obj["hello"]);
}
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("JsonObject::operator[] const") {
unsigned char key[] = "hello";
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(std::string("world") == obj[key]);
}
#endif
SECTION("JsonObjectSubscript::operator=") { // issue #416
unsigned char value[] = "world";
SECTION("get()") {
unsigned char key[] = "hello";
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj["hello"] = value;
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(std::string("world") == obj.get<char*>(key));
}
REQUIRE(std::string("world") == obj["hello"]);
SECTION("set() key") {
unsigned char key[] = "hello";
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj.set(key, "world");
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("set() value") {
unsigned char value[] = "world";
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj.set("hello", value);
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("set() key&value") {
unsigned char key[] = "world";
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj.set(key, key);
REQUIRE(std::string("world") == obj["world"]);
}
SECTION("containsKey()") {
unsigned char key[] = "hello";
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(true == obj.containsKey(key));
}
SECTION("remove()") {
unsigned char key[] = "hello";
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
JsonObject& obj = doc.as<JsonObject>();
obj.remove(key);
REQUIRE(0 == obj.size());
}
SECTION("is()") {
unsigned char key[] = "hello";
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":42}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(true == obj.is<int>(key));
}
SECTION("createNestedArray()") {
unsigned char key[] = "hello";
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj.createNestedArray(key);
}
SECTION("createNestedObject()") {
unsigned char key[] = "hello";
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj.createNestedObject(key);
}
}
SECTION("JsonObjectSubscript::set()") {
unsigned char value[] = "world";
SECTION("JsonObjectSubscript") {
SECTION("operator=") { // issue #416
unsigned char value[] = "world";
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj["hello"].set(value);
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj["hello"] = value;
REQUIRE(std::string("world") == obj["hello"]);
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("set()") {
unsigned char value[] = "world";
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj["hello"].set(value);
REQUIRE(std::string("world") == obj["hello"]);
}
}
#ifndef CONFLICTS_WITH_BUILTIN_OPERATOR
SECTION("JsonObject::operator[] const") {
unsigned char key[] = "hello";
SECTION("JsonArray") {
SECTION("add()") {
unsigned char value[] = "world";
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
DynamicJsonDocument doc;
JsonArray& arr = doc.to<JsonArray>();
arr.add(value);
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(std::string("world") == obj[key]);
}
#endif
REQUIRE(std::string("world") == arr[0]);
}
SECTION("JsonObject::get()") {
unsigned char key[] = "hello";
SECTION("set()") {
unsigned char value[] = "world";
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(std::string("world") == obj.get<char*>(key));
DynamicJsonDocument doc;
JsonArray& arr = doc.to<JsonArray>();
arr.add("hello");
arr.set(0, value);
REQUIRE(std::string("world") == arr[0]);
}
}
SECTION("JsonObject::set() key") {
unsigned char key[] = "hello";
SECTION("JsonArraySubscript") {
SECTION("set()") {
unsigned char value[] = "world";
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj.set(key, "world");
DynamicJsonDocument doc;
JsonArray& arr = doc.to<JsonArray>();
arr.add("hello");
arr[0].set(value);
REQUIRE(std::string("world") == obj["hello"]);
}
REQUIRE(std::string("world") == arr[0]);
}
SECTION("JsonObject::set() value") {
unsigned char value[] = "world";
SECTION("operator=") {
unsigned char value[] = "world";
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj.set("hello", value);
DynamicJsonDocument doc;
JsonArray& arr = doc.to<JsonArray>();
arr.add("hello");
arr[0] = value;
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("JsonObject::set key&value") {
unsigned char key[] = "world";
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj.set(key, key);
REQUIRE(std::string("world") == obj["world"]);
}
SECTION("JsonObject::containsKey()") {
unsigned char key[] = "hello";
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(true == obj.containsKey(key));
}
SECTION("JsonObject::remove()") {
unsigned char key[] = "hello";
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
JsonObject& obj = doc.as<JsonObject>();
obj.remove(key);
REQUIRE(0 == obj.size());
}
SECTION("JsonObject::is()") {
unsigned char key[] = "hello";
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":42}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(true == obj.is<int>(key));
}
SECTION("JsonObject::createNestedArray()") {
unsigned char key[] = "hello";
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj.createNestedArray(key);
}
SECTION("JsonObject::createNestedObject()") {
unsigned char key[] = "hello";
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj.createNestedObject(key);
}
SECTION("JsonArray::add()") {
unsigned char value[] = "world";
DynamicJsonDocument doc;
JsonArray& arr = doc.to<JsonArray>();
arr.add(value);
REQUIRE(std::string("world") == arr[0]);
}
SECTION("JsonArray::set()") {
unsigned char value[] = "world";
DynamicJsonDocument doc;
JsonArray& arr = doc.to<JsonArray>();
arr.add("hello");
arr.set(0, value);
REQUIRE(std::string("world") == arr[0]);
}
SECTION("JsonArraySubscript::set()") {
unsigned char value[] = "world";
DynamicJsonDocument doc;
JsonArray& arr = doc.to<JsonArray>();
arr.add("hello");
arr[0].set(value);
REQUIRE(std::string("world") == arr[0]);
}
SECTION("JsonArraySubscript::operator=") {
unsigned char value[] = "world";
DynamicJsonDocument doc;
JsonArray& arr = doc.to<JsonArray>();
arr.add("hello");
arr[0] = value;
REQUIRE(std::string("world") == arr[0]);
REQUIRE(std::string("world") == arr[0]);
}
}
}

View File

@ -17,322 +17,321 @@
#ifndef VLA_NOT_SUPPORTED
TEST_CASE("Variable Length Array") {
SECTION("ParseArray") {
int i = 8;
SECTION("deserializeJson()") {
int i = 9;
char vla[i];
strcpy(vla, "[42]");
strcpy(vla, "{\"a\":42}");
StaticJsonDocument<JSON_ARRAY_SIZE(1)> doc;
StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc;
JsonError err = deserializeJson(doc, vla);
REQUIRE(err == JsonError::Ok);
}
SECTION("ParseObject") {
SECTION("deserializeMsgPack()") {
int i = 16;
char vla[i];
strcpy(vla, "{\"a\":42}");
memcpy(vla, "\xDE\x00\x01\xA5Hello\xA5world", 15);
StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc;
JsonError error = deserializeJson(doc, vla);
MsgPackError err = deserializeMsgPack(doc, vla);
REQUIRE(error == JsonError::Ok);
REQUIRE(err == MsgPackError::Ok);
}
SECTION("Parse") {
int i = 16;
char vla[i];
strcpy(vla, "42");
SECTION("JsonVariant") {
SECTION("constructor") {
int i = 16;
char vla[i];
strcpy(vla, "42");
StaticJsonDocument<> variant;
deserializeJson(variant, vla);
JsonVariant variant(vla);
REQUIRE(42 == variant.as<int>());
}
REQUIRE(42 == variant.as<int>());
}
SECTION("JsonVariant_Constructor") {
int i = 16;
char vla[i];
strcpy(vla, "42");
SECTION("operator=") {
int i = 16;
char vla[i];
strcpy(vla, "42");
JsonVariant variant(vla);
JsonVariant variant(666);
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>());
}
REQUIRE(42 == variant.as<int>());
}
#ifndef CONFLICTS_WITH_BUILTIN_OPERATOR
SECTION("JsonVariant_Subscript") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
SECTION("operator[]") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
JsonVariant variant = doc.as<JsonVariant>();
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
JsonVariant variant = doc.as<JsonVariant>();
REQUIRE(std::string("world") == variant[vla]);
}
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");
SECTION("operator[] const") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
const JsonVariant variant = doc.as<JsonVariant>();
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
const JsonVariant variant = doc.as<JsonVariant>();
REQUIRE(std::string("world") == variant[vla]);
}
REQUIRE(std::string("world") == variant[vla]);
}
#endif
SECTION("JsonVariant_Equals") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
SECTION("operator==") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
JsonVariant variant;
variant = "hello";
JsonVariant variant;
variant = "hello";
REQUIRE((vla == variant));
REQUIRE((variant == vla));
REQUIRE_FALSE((vla != variant));
REQUIRE_FALSE((variant != vla));
REQUIRE((vla == variant));
REQUIRE((variant == vla));
REQUIRE_FALSE((vla != variant));
REQUIRE_FALSE((variant != vla));
}
SECTION("operator!=") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
JsonVariant variant;
variant = "world";
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");
SECTION("JsonObject") {
#ifndef CONFLICTS_WITH_BUILTIN_OPERATOR
SECTION("operator[]") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
JsonVariant variant;
variant = "world";
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj[vla] = "world";
REQUIRE((vla != variant));
REQUIRE((variant != vla));
REQUIRE_FALSE((vla == variant));
REQUIRE_FALSE((variant == vla));
}
REQUIRE(std::string("world") == obj["hello"]);
}
#endif
#ifndef CONFLICTS_WITH_BUILTIN_OPERATOR
SECTION("JsonObject_Subscript") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
SECTION("operator[] const") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj[vla] = "world";
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
REQUIRE(std::string("world") == obj["hello"]);
}
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(std::string("world") == obj[vla]);
}
#endif
SECTION("JsonObject_Subscript_Assign") { // issue #416
int i = 32;
char vla[i];
strcpy(vla, "world");
SECTION("get()") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj["hello"] = vla;
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
REQUIRE(std::string("world") == obj["hello"].as<char*>());
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(std::string("world") == obj.get<char*>(vla));
}
SECTION("set() key") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj.set(vla, "world");
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("set() value") {
int i = 16;
char vla[i];
strcpy(vla, "world");
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj.set("hello", vla);
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("set() key&value") {
int i = 16;
char vla[i];
strcpy(vla, "world");
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj.set(vla, vla);
REQUIRE(std::string("world") == obj["world"]);
}
SECTION("containsKey()") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(true == obj.containsKey(vla));
}
SECTION("remove()") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
JsonObject& obj = doc.as<JsonObject>();
obj.remove(vla);
REQUIRE(0 == obj.size());
}
SECTION("is<T>()") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":42}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(true == obj.is<int>(vla));
}
SECTION("createNestedArray()") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj.createNestedArray(vla);
}
SECTION("createNestedObject()") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj.createNestedObject(vla);
}
}
SECTION("JsonObject_Subscript_Set") {
int i = 32;
char vla[i];
strcpy(vla, "world");
SECTION("JsonObjectSubscript") {
SECTION("operator=") { // issue #416
int i = 32;
char vla[i];
strcpy(vla, "world");
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj["hello"].set(vla);
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj["hello"] = vla;
REQUIRE(std::string("world") == obj["hello"].as<char*>());
REQUIRE(std::string("world") == obj["hello"].as<char*>());
}
SECTION("set()") {
int i = 32;
char vla[i];
strcpy(vla, "world");
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
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");
SECTION("JsonArray") {
SECTION("add()") {
int i = 16;
char vla[i];
strcpy(vla, "world");
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
DynamicJsonDocument doc;
JsonArray& arr = doc.to<JsonArray>();
arr.add(vla);
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(std::string("world") == obj[vla]);
}
#endif
REQUIRE(std::string("world") == arr[0]);
}
SECTION("JsonObject_Get") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
SECTION("set()") {
int i = 16;
char vla[i];
strcpy(vla, "world");
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
DynamicJsonDocument doc;
JsonArray& arr = doc.to<JsonArray>();
arr.add("hello");
arr.set(0, vla);
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(std::string("world") == obj.get<char*>(vla));
REQUIRE(std::string("world") == arr[0]);
}
}
SECTION("JsonObject_Set_Key") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
SECTION("JsonArraySubscript") {
SECTION("set()") {
int i = 16;
char vla[i];
strcpy(vla, "world");
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj.set(vla, "world");
DynamicJsonDocument doc;
JsonArray& arr = doc.to<JsonArray>();
arr.add("hello");
arr[0].set(vla);
REQUIRE(std::string("world") == obj["hello"]);
}
REQUIRE(std::string("world") == arr[0]);
}
SECTION("JsonObject_Set_Value") {
int i = 16;
char vla[i];
strcpy(vla, "world");
SECTION("operator=") {
int i = 16;
char vla[i];
strcpy(vla, "world");
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj.set("hello", vla);
DynamicJsonDocument doc;
JsonArray& arr = doc.to<JsonArray>();
arr.add("hello");
arr[0] = vla;
REQUIRE(std::string("world") == obj["hello"]);
}
SECTION("JsonObject_Set_KeyAndValue") {
int i = 16;
char vla[i];
strcpy(vla, "world");
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj.set(vla, vla);
REQUIRE(std::string("world") == obj["world"]);
}
SECTION("JsonObject_ContainsKey") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(true == obj.containsKey(vla));
}
SECTION("JsonObject_Remove") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":\"world\"}");
JsonObject& obj = doc.as<JsonObject>();
obj.remove(vla);
REQUIRE(0 == obj.size());
}
SECTION("JsonObject_Is") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonDocument doc;
deserializeJson(doc, "{\"hello\":42}");
JsonObject& obj = doc.as<JsonObject>();
REQUIRE(true == obj.is<int>(vla));
}
SECTION("JsonObject_CreateNestedArray") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj.createNestedArray(vla);
}
SECTION("JsonObject_CreateNestedObject") {
int i = 16;
char vla[i];
strcpy(vla, "hello");
DynamicJsonDocument doc;
JsonObject& obj = doc.to<JsonObject>();
obj.createNestedObject(vla);
}
SECTION("JsonArray_Add") {
int i = 16;
char vla[i];
strcpy(vla, "world");
DynamicJsonDocument doc;
JsonArray& arr = doc.to<JsonArray>();
arr.add(vla);
REQUIRE(std::string("world") == arr[0]);
}
SECTION("JsonArray_Set") {
int i = 16;
char vla[i];
strcpy(vla, "world");
DynamicJsonDocument doc;
JsonArray& arr = doc.to<JsonArray>();
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");
DynamicJsonDocument doc;
JsonArray& arr = doc.to<JsonArray>();
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");
DynamicJsonDocument doc;
JsonArray& arr = doc.to<JsonArray>();
arr.add("hello");
arr[0] = vla;
REQUIRE(std::string("world") == arr[0]);
REQUIRE(std::string("world") == arr[0]);
}
}
}
#endif

View File

@ -3,13 +3,17 @@
# MIT License
add_executable(MsgPackTests
deserializationErrors.cpp
MsgPackError.cpp
deserializeArray.cpp
deserializeObject.cpp
deserializeVariant.cpp
deserializeStaticVariant.cpp
deserializeVariant.cpp
doubleToFloat.cpp
MsgPackError.cpp
incompleteInput.cpp
nestingLimit.cpp
notSupported.cpp
std_string.cpp
std_istream.cpp
)
target_link_libraries(MsgPackTests catch)

View File

@ -25,6 +25,7 @@ TEST_CASE("MsgPackError") {
TEST_STRINGIFICATION(NotSupported);
TEST_STRINGIFICATION(NoMemory);
TEST_STRINGIFICATION(TooDeep);
TEST_STRINGIFICATION(IncompleteInput);
}
SECTION("as boolean") {
@ -32,6 +33,7 @@ TEST_CASE("MsgPackError") {
TEST_BOOLIFICATION(NotSupported, true);
TEST_BOOLIFICATION(NoMemory, true);
TEST_BOOLIFICATION(TooDeep, true);
TEST_BOOLIFICATION(IncompleteInput, true);
}
SECTION("ostream") {

View File

@ -1,59 +0,0 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
static void check(const char* input, MsgPackError expected,
uint8_t nestingLimit = 10) {
DynamicJsonDocument doc;
doc.nestingLimit = nestingLimit;
MsgPackError error = deserializeMsgPack(doc, input);
REQUIRE(error == expected);
}
TEST_CASE("Errors returned by deserializeMsgPack()") {
SECTION("unsupported") {
check("\xc4", MsgPackError::NotSupported); // bin 8
check("\xc5", MsgPackError::NotSupported); // bin 16
check("\xc6", MsgPackError::NotSupported); // bin 32
check("\xc7", MsgPackError::NotSupported); // ext 8
check("\xc8", MsgPackError::NotSupported); // ext 16
check("\xc9", MsgPackError::NotSupported); // ext 32
check("\xd4", MsgPackError::NotSupported); // fixext 1
check("\xd5", MsgPackError::NotSupported); // fixext 2
check("\xd6", MsgPackError::NotSupported); // fixext 4
check("\xd7", MsgPackError::NotSupported); // fixext 8
check("\xd8", MsgPackError::NotSupported); // fixext 16
}
SECTION("unsupported in array") {
check("\x91\xc4", MsgPackError::NotSupported);
}
SECTION("unsupported in map") {
check("\x81\xc4\x00\xA1H", MsgPackError::NotSupported);
check("\x81\xA1H\xc4\x00", MsgPackError::NotSupported);
}
SECTION("integer as key") {
check("\x81\x01\xA1H", MsgPackError::NotSupported);
}
SECTION("object too deep") {
check("\x80", MsgPackError::TooDeep, 0); // {}
check("\x80", MsgPackError::Ok, 1); // {}
check("\x81\xA1H\x80", MsgPackError::TooDeep, 1); // {H:{}}
check("\x81\xA1H\x80", MsgPackError::Ok, 2); // {H:{}}
}
SECTION("array too deep") {
check("\x90", MsgPackError::TooDeep, 0); // []
check("\x90", MsgPackError::Ok, 1); // []
check("\x91\x90", MsgPackError::TooDeep, 1); // [[]]
check("\x91\x90", MsgPackError::Ok, 2); // [[]]
}
}

View File

@ -0,0 +1,106 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
MsgPackError deserialize(const char* input, size_t len) {
DynamicJsonDocument doc;
return deserializeMsgPack(doc, input, len);
}
void checkAllSizes(const char* input, size_t len) {
REQUIRE(deserialize(input, len) == MsgPackError::Ok);
while (--len) {
REQUIRE(deserialize(input, len) == MsgPackError::IncompleteInput);
}
}
TEST_CASE("deserializeMsgPack() returns IncompleteInput") {
SECTION("empty input") {
checkAllSizes("\x00", 1);
}
SECTION("fixarray") {
checkAllSizes("\x91\x01", 2);
}
SECTION("array 16") {
checkAllSizes("\xDC\x00\x01\x01", 4);
}
SECTION("array 32") {
checkAllSizes("\xDD\x00\x00\x00\x01\x01", 6);
}
SECTION("fixmap") {
checkAllSizes("\x81\xA3one\x01", 6);
}
SECTION("map 16") {
checkAllSizes("\xDE\x00\x01\xA3one\x01", 8);
}
SECTION("map 32") {
checkAllSizes("\xDF\x00\x00\x00\x01\xA3one\x01", 10);
}
SECTION("uint 8") {
checkAllSizes("\xcc\x01", 2);
}
SECTION("uint 16") {
checkAllSizes("\xcd\x00\x01", 3);
}
SECTION("uint 32") {
checkAllSizes("\xCE\x00\x00\x00\x01", 5);
}
SECTION("uint 64") {
checkAllSizes("\xCF\x00\x00\x00\x00\x00\x00\x00\x00", 9);
}
SECTION("int 8") {
checkAllSizes("\xD0\x01", 2);
}
SECTION("int 16") {
checkAllSizes("\xD1\x00\x01", 3);
}
SECTION("int 32") {
checkAllSizes("\xD2\x00\x00\x00\x01", 5);
}
SECTION("int 64") {
checkAllSizes("\xD3\x00\x00\x00\x00\x00\x00\x00\x00", 9);
}
SECTION("float 32") {
checkAllSizes("\xCA\x40\x48\xF5\xC3", 5);
}
SECTION("float 64") {
checkAllSizes("\xCB\x40\x09\x21\xCA\xC0\x83\x12\x6F", 9);
}
SECTION("fixstr") {
checkAllSizes("\xABhello world", 12);
}
SECTION("str 8") {
checkAllSizes("\xd9\x05hello", 7);
}
SECTION("str 16") {
checkAllSizes("\xda\x00\x05hello", 8);
}
SECTION("str 32") {
checkAllSizes("\xdb\x00\x00\x00\x05hello", 10);
}
}

View File

@ -0,0 +1,31 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
static void check(const char* input, MsgPackError expected, uint8_t limit) {
DynamicJsonDocument doc;
doc.nestingLimit = limit;
MsgPackError error = deserializeMsgPack(doc, input);
REQUIRE(error == expected);
}
TEST_CASE("Errors returned by deserializeMsgPack()") {
SECTION("object too deep") {
check("\x80", MsgPackError::TooDeep, 0); // {}
check("\x80", MsgPackError::Ok, 1); // {}
check("\x81\xA1H\x80", MsgPackError::TooDeep, 1); // {H:{}}
check("\x81\xA1H\x80", MsgPackError::Ok, 2); // {H:{}}
}
SECTION("array too deep") {
check("\x90", MsgPackError::TooDeep, 0); // []
check("\x90", MsgPackError::Ok, 1); // []
check("\x91\x90", MsgPackError::TooDeep, 1); // [[]]
check("\x91\x90", MsgPackError::Ok, 2); // [[]]
}
}

View File

@ -0,0 +1,73 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
static void checkNotSupported(const char* input) {
DynamicJsonDocument doc;
MsgPackError error = deserializeMsgPack(doc, input);
REQUIRE(error == MsgPackError::NotSupported);
}
TEST_CASE("deserializeMsgPack() return NotSupported") {
SECTION("bin 8") {
checkNotSupported("\xc4");
}
SECTION("bin 16") {
checkNotSupported("\xc5");
}
SECTION("bin 32") {
checkNotSupported("\xc6");
}
SECTION("ext 8") {
checkNotSupported("\xc7");
}
SECTION("ext 16") {
checkNotSupported("\xc8");
}
SECTION("ext 32") {
checkNotSupported("\xc9");
}
SECTION("fixext 1") {
checkNotSupported("\xd4");
}
SECTION("fixext 2") {
checkNotSupported("\xd5");
}
SECTION("fixext 4") {
checkNotSupported("\xd6");
}
SECTION("fixext 8") {
checkNotSupported("\xd7");
}
SECTION("fixext 16") {
checkNotSupported("\xd8");
}
SECTION("unsupported in array") {
checkNotSupported("\x91\xc4");
}
SECTION("unsupported in map") {
checkNotSupported("\x81\xc4\x00\xA1H");
checkNotSupported("\x81\xA1H\xc4\x00");
}
SECTION("integer as key") {
checkNotSupported("\x81\x01\xA1H");
}
}

View File

@ -0,0 +1,29 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("deserializeMsgPack(std::istream&)") {
DynamicJsonDocument doc;
SECTION("should accept a zero in input") {
std::istringstream input(std::string("\x92\x00\x02", 3));
MsgPackError err = deserializeMsgPack(doc, input);
REQUIRE(err == MsgPackError::Ok);
JsonArray& arr = doc.as<JsonArray>();
REQUIRE(arr[0] == 0);
REQUIRE(arr[1] == 2);
}
SECTION("should detect incomplete input") {
std::istringstream input("\x92\x00\x02");
MsgPackError err = deserializeMsgPack(doc, input);
REQUIRE(err == MsgPackError::IncompleteInput);
}
}

View File

@ -0,0 +1,44 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("deserializeMsgPack(const std::string&)") {
DynamicJsonDocument doc;
SECTION("should accept const string") {
const std::string input("\x92\x01\x02");
MsgPackError err = deserializeMsgPack(doc, input);
REQUIRE(err == MsgPackError::Ok);
}
SECTION("should accept temporary string") {
MsgPackError err = deserializeMsgPack(doc, std::string("\x92\x01\x02"));
REQUIRE(err == MsgPackError::Ok);
}
SECTION("should duplicate content") {
std::string input("\x91\xA5hello");
MsgPackError err = deserializeMsgPack(doc, input);
input[2] = 'X'; // alter the string tomake sure we made a copy
JsonArray& array = doc.as<JsonArray>();
REQUIRE(err == MsgPackError::Ok);
REQUIRE(std::string("hello") == array[0]);
}
SECTION("should accept a zero in input") {
MsgPackError err = deserializeMsgPack(doc, std::string("\x92\x00\x02", 3));
REQUIRE(err == MsgPackError::Ok);
JsonArray& arr = doc.as<JsonArray>();
REQUIRE(arr[0] == 0);
REQUIRE(arr[1] == 2);
}
}