forked from bblanchon/ArduinoJson
Added DeserializationOption::Filter (closes #959)
This commit is contained in:
1 parent
42b0d6a83d
commit
66b12da4e7
16 files changed
+1095
-69
No files matched your search
@@ -6,6 +6,7 @@ add_executable(IntegrationTests
|
||||
gbathree.cpp
|
||||
issue772.cpp
|
||||
round_trip.cpp
|
||||
openweathermap.cpp
|
||||
)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("OpenWeatherMap") {
|
||||
// clang-format off
|
||||
const char* filter_json ="{\"list\":["
|
||||
"{\"dt\":true,\"main\":{\"temp\":true},\"weather\":[{\"description\":true}]}"
|
||||
"]}";
|
||||
|
||||
const char* input_json = "{\"cod\":\"200\",\"message\":0,\"cnt\":40,\"list\":[{\"dt\":1581498000,\"main\":{\"temp\":3.23,\"feels_like\":-3.63,\"temp_min\":3.23,\"temp_max\":4.62,\"pressure\":1014,\"sea_level\":1014,\"grnd_level\":1010,\"humidity\":58,\"temp_kf\":-1.39},\"weather\":[{\"id\":800,\"main\":\"Clear\",\"description\":\"clear sky\",\"icon\":\"01d\"}],\"clouds\":{\"all\":0},\"wind\":{\"speed\":6.19,\"deg\":266},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-12 09:00:00\"},{\"dt\":1581508800,\"main\":{\"temp\":6.09,\"feels_like\":-1.07,\"temp_min\":6.09,\"temp_max\":7.13,\"pressure\":1015,\"sea_level\":1015,\"grnd_level\":1011,\"humidity\":48,\"temp_kf\":-1.04},\"weather\":[{\"id\":800,\"main\":\"Clear\",\"description\":\"clear sky\",\"icon\":\"01d\"}],\"clouds\":{\"all\":9},\"wind\":{\"speed\":6.64,\"deg\":268},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-12 12:00:00\"},{\"dt\":1581519600,\"main\":{\"temp\":6.82,\"feels_like\":0.47,\"temp_min\":6.82,\"temp_max\":7.52,\"pressure\":1015,\"sea_level\":1015,\"grnd_level\":1011,\"humidity\":47,\"temp_kf\":-0.7},\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04d\"}],\"clouds\":{\"all\":97},\"wind\":{\"speed\":5.55,\"deg\":267},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-12 15:00:00\"},{\"dt\":1581530400,\"main\":{\"temp\":5.76,\"feels_like\":1.84,\"temp_min\":5.76,\"temp_max\":6.11,\"pressure\":1015,\"sea_level\":1015,\"grnd_level\":1010,\"humidity\":57,\"temp_kf\":-0.35},\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04n\"}],\"clouds\":{\"all\":99},\"wind\":{\"speed\":2.35,\"deg\":232},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-12 18:00:00\"},{\"dt\":1581541200,\"main\":{\"temp\":5.7,\"feels_like\":1.34,\"temp_min\":5.7,\"temp_max\":5.7,\"pressure\":1012,\"sea_level\":1012,\"grnd_level\":1008,\"humidity\":71,\"temp_kf\":0},\"weather\":[{\"id\":804,\"main\":\"Clouds\",\"description\":\"overcast clouds\",\"icon\":\"04n\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":3.57,\"deg\":198},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-12 21:00:00\"},{\"dt\":1581552000,\"main\":{\"temp\":5.82,\"feels_like\":1.39,\"temp_min\":5.82,\"temp_max\":5.82,\"pressure\":1009,\"sea_level\":1009,\"grnd_level\":1004,\"humidity\":86,\"temp_kf\":0},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10n\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":4.35,\"deg\":169},\"rain\":{\"3h\":0.5},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-13 00:00:00\"},{\"dt\":1581562800,\"main\":{\"temp\":5.9,\"feels_like\":-0.85,\"temp_min\":5.9,\"temp_max\":5.9,\"pressure\":1000,\"sea_level\":1000,\"grnd_level\":997,\"humidity\":86,\"temp_kf\":0},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10n\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":7.69,\"deg\":178},\"rain\":{\"3h\":1.75},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-13 03:00:00\"},{\"dt\":1581573600,\"main\":{\"temp\":7.52,\"feels_like\":1.74,\"temp_min\":7.52,\"temp_max\":7.52,\"pressure\":993,\"sea_level\":993,\"grnd_level\":988,\"humidity\":88,\"temp_kf\":0},\"weather\":[{\"id\":501,\"main\":\"Rain\",\"description\":\"moderate rain\",\"icon\":\"10n\"}],\"clouds\":{\"all\":100},\"wind\":{\"speed\":6.84,\"deg\":184},\"rain\":{\"3h\":7.06},\"sys\":{\"pod\":\"n\"},\"dt_txt\":\"2020-02-13 06:00:00\"},{\"dt\":1581584400,\"main\":{\"temp\":7.23,\"feels_like\":0.81,\"temp_min\":7.23,\"temp_max\":7.23,\"pressure\":992,\"sea_level\":992,\"grnd_level\":988,\"humidity\":69,\"temp_kf\":0},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"}],\"clouds\":{\"all\":49},\"wind\":{\"speed\":6.77,\"deg\":239},\"rain\":{\"3h\":0.25},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-13 09:00:00\"},{\"dt\":1581595200,\"main\":{\"temp\":7.67,\"feels_like\":2.81,\"temp_min\":7.67,\"temp_max\":7.67,\"pressure\":991,\"sea_level\":991,\"grnd_level\":987,\"humidity\":75,\"temp_kf\":0},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"}],\"clouds\":{\"all\":73},\"wind\":{\"speed\":4.93,\"deg\":235},\"rain\":{\"3h\":0.75},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-13 12:00:00\"},{\"dt\":1581606000,\"main\":{\"temp\":8.83,\"feels_like\":3.23,\"temp_min\":8.83,\"temp_max\":8.83,\"pressure\":993,\"sea_level\":993,\"grnd_level\":990,\"humidity\":64,\"temp_kf\":0},\"weather\":[{\"id\":500,\"main\":\"Rain\",\"description\":\"light rain\",\"icon\":\"10d\"}],\"clouds\":{\"all\":83},\"wind\":{\"speed\":5.7,\"deg\":293},\"rain\":{\"3h\":0.38},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-13 15:00:00\"},{\"dt\":1581616800,\"main\":{\"temp\":7.42,\"feels_like\":1.77,\"temp_min\":7.42,\"temp_max\":7.42,\"pressure\":1000,\"sea_level\":1000,\"grnd_level\":996,\"humidity\":71,\"temp_kf\":0},\"weather\":[{\"id\":803,\"main\":\"Clouds\",\"description\":\"broken clouds\",\"icon\":\"04n\"}],\"clouds\":{\"all\":54},\"wind\":{\"speed\":5.81,\"dLine truncated
|
||||
|
||||
const char* expected_json = "{\"list\":["
|
||||
"{\"dt\":1581498000,\"main\":{\"temp\":3.23},\"weather\":[{\"description\":\"clear sky\"}]},"
|
||||
"{\"dt\":1581508800,\"main\":{\"temp\":6.09},\"weather\":[{\"description\":\"clear sky\"}]},"
|
||||
"{\"dt\":1581519600,\"main\":{\"temp\":6.82},\"weather\":[{\"description\":\"overcast clouds\"}]},"
|
||||
"{\"dt\":1581530400,\"main\":{\"temp\":5.76},\"weather\":[{\"description\":\"overcast clouds\"}]},"
|
||||
"{\"dt\":1581541200,\"main\":{\"temp\":5.7},\"weather\":[{\"description\":\"overcast clouds\"}]},"
|
||||
"{\"dt\":1581552000,\"main\":{\"temp\":5.82},\"weather\":[{\"description\":\"light rain\"}]},"
|
||||
"{\"dt\":1581562800,\"main\":{\"temp\":5.9},\"weather\":[{\"description\":\"light rain\"}]},"
|
||||
"{\"dt\":1581573600,\"main\":{\"temp\":7.52},\"weather\":[{\"description\":\"moderate rain\"}]},"
|
||||
"{\"dt\":1581584400,\"main\":{\"temp\":7.23},\"weather\":[{\"description\":\"light rain\"}]},"
|
||||
"{\"dt\":1581595200,\"main\":{\"temp\":7.67},\"weather\":[{\"description\":\"light rain\"}]},"
|
||||
"{\"dt\":1581606000,\"main\":{\"temp\":8.83},\"weather\":[{\"description\":\"light rain\"}]},"
|
||||
"{\"dt\":1581616800,\"main\":{\"temp\":7.42},\"weather\":[{\"description\":\"broken clouds\"}]},"
|
||||
"{\"dt\":1581627600,\"main\":{\"temp\":5.82},\"weather\":[{\"description\":\"clear sky\"}]},"
|
||||
"{\"dt\":1581638400,\"main\":{\"temp\":5.58},\"weather\":[{\"description\":\"scattered clouds\"}]},"
|
||||
"{\"dt\":1581649200,\"main\":{\"temp\":4.27},\"weather\":[{\"description\":\"broken clouds\"}]},"
|
||||
"{\"dt\":1581660000,\"main\":{\"temp\":3.91},\"weather\":[{\"description\":\"overcast clouds\"}]},"
|
||||
"{\"dt\":1581670800,\"main\":{\"temp\":4.77},\"weather\":[{\"description\":\"overcast clouds\"}]},"
|
||||
"{\"dt\":1581681600,\"main\":{\"temp\":9.03},\"weather\":[{\"description\":\"overcast clouds\"}]},"
|
||||
"{\"dt\":1581692400,\"main\":{\"temp\":9.86},\"weather\":[{\"description\":\"overcast clouds\"}]},"
|
||||
"{\"dt\":1581703200,\"main\":{\"temp\":9.48},\"weather\":[{\"description\":\"overcast clouds\"}]},"
|
||||
"{\"dt\":1581714000,\"main\":{\"temp\":10.03},\"weather\":[{\"description\":\"moderate rain\"}]},"
|
||||
"{\"dt\":1581724800,\"main\":{\"temp\":9.48},\"weather\":[{\"description\":\"light rain\"}]},"
|
||||
"{\"dt\":1581735600,\"main\":{\"temp\":9.12},\"weather\":[{\"description\":\"light rain\"}]},"
|
||||
"{\"dt\":1581746400,\"main\":{\"temp\":10.32},\"weather\":[{\"description\":\"light rain\"}]},"
|
||||
"{\"dt\":1581757200,\"main\":{\"temp\":11.57},\"weather\":[{\"description\":\"light rain\"}]},"
|
||||
"{\"dt\":1581768000,\"main\":{\"temp\":12.25},\"weather\":[{\"description\":\"light rain\"}]},"
|
||||
"{\"dt\":1581778800,\"main\":{\"temp\":12.19},\"weather\":[{\"description\":\"moderate rain\"}]},"
|
||||
"{\"dt\":1581789600,\"main\":{\"temp\":12.25},\"weather\":[{\"description\":\"moderate rain\"}]},"
|
||||
"{\"dt\":1581800400,\"main\":{\"temp\":12.64},\"weather\":[{\"description\":\"moderate rain\"}]},"
|
||||
"{\"dt\":1581811200,\"main\":{\"temp\":12.96},\"weather\":[{\"description\":\"moderate rain\"}]},"
|
||||
"{\"dt\":1581822000,\"main\":{\"temp\":13.13},\"weather\":[{\"description\":\"moderate rain\"}]},"
|
||||
"{\"dt\":1581832800,\"main\":{\"temp\":9.07},\"weather\":[{\"description\":\"light rain\"}]},"
|
||||
"{\"dt\":1581843600,\"main\":{\"temp\":8.05},\"weather\":[{\"description\":\"light rain\"}]},"
|
||||
"{\"dt\":1581854400,\"main\":{\"temp\":9.54},\"weather\":[{\"description\":\"overcast clouds\"}]},"
|
||||
"{\"dt\":1581865200,\"main\":{\"temp\":9.08},\"weather\":[{\"description\":\"light rain\"}]},"
|
||||
"{\"dt\":1581876000,\"main\":{\"temp\":7.41},\"weather\":[{\"description\":\"overcast clouds\"}]},"
|
||||
"{\"dt\":1581886800,\"main\":{\"temp\":6.42},\"weather\":[{\"description\":\"broken clouds\"}]},"
|
||||
"{\"dt\":1581897600,\"main\":{\"temp\":6.03},\"weather\":[{\"description\":\"scattered clouds\"}]},"
|
||||
"{\"dt\":1581908400,\"main\":{\"temp\":5.62},\"weather\":[{\"description\":\"clear sky\"}]},"
|
||||
"{\"dt\":1581919200,\"main\":{\"temp\":5.51},\"weather\":[{\"description\":\"scattered clouds\"}]}"
|
||||
"]}";
|
||||
// clang-format on
|
||||
|
||||
StaticJsonDocument<512> filter;
|
||||
|
||||
REQUIRE(deserializeJson(filter, filter_json) == DeserializationError::Ok);
|
||||
|
||||
DynamicJsonDocument doc(16384);
|
||||
|
||||
REQUIRE(
|
||||
deserializeJson(doc, input_json, DeserializationOption::Filter(filter)) ==
|
||||
DeserializationError::Ok);
|
||||
|
||||
REQUIRE(doc.as<std::string>() == expected_json);
|
||||
}
|
||||
@@ -6,12 +6,13 @@ add_executable(JsonDeserializerTests
|
||||
array.cpp
|
||||
array_static.cpp
|
||||
DeserializationError.cpp
|
||||
filter.cpp
|
||||
incomplete_input.cpp
|
||||
input_types.cpp
|
||||
number.cpp
|
||||
invalid_input.cpp
|
||||
misc.cpp
|
||||
nestingLimit.cpp
|
||||
number.cpp
|
||||
object.cpp
|
||||
object_static.cpp
|
||||
string.cpp
|
||||
|
||||
@@ -0,0 +1,577 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
TEST_CASE("Filtering") {
|
||||
struct TestCase {
|
||||
const char* input;
|
||||
const char* filter;
|
||||
uint8_t nestingLimit;
|
||||
DeserializationError error;
|
||||
const char* output;
|
||||
size_t memoryUsage;
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
TestCase testCases[] = {
|
||||
{
|
||||
"{\"hello\":\"world\"}", // 1. input
|
||||
"null", // 2. filter
|
||||
10, // 3. nestingLimit
|
||||
DeserializationError::Ok, // 4. error
|
||||
"null", // 5. output
|
||||
0 // 6. memoryUsage
|
||||
},
|
||||
{
|
||||
"{\"hello\":\"world\"}",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
"{\"abcdefg\":\"hijklmn\"}",
|
||||
"true",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"{\"abcdefg\":\"hijklmn\"}",
|
||||
JSON_OBJECT_SIZE(1) + 16
|
||||
},
|
||||
{
|
||||
"{\"hello\":\"world\"}",
|
||||
"{}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"{}",
|
||||
JSON_OBJECT_SIZE(0)
|
||||
},
|
||||
{
|
||||
// Input in an object, but filter wants an array
|
||||
"{\"hello\":\"world\"}",
|
||||
"[]",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// Input is an array, but filter wants an object
|
||||
"[\"hello\",\"world\"]",
|
||||
"{}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// Input is a bool, but filter wants an object
|
||||
"true",
|
||||
"{}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// Input is a string, but filter wants an object
|
||||
"\"hello\"",
|
||||
"{}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// skip an integer
|
||||
"{\"an_integer\":666,example:42}",
|
||||
"{\"example\":true}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"{\"example\":42}",
|
||||
JSON_OBJECT_SIZE(1) + 8
|
||||
},
|
||||
{
|
||||
// skip a float
|
||||
"{\"a_float\":12.34e-6,example:42}",
|
||||
"{\"example\":true}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"{\"example\":42}",
|
||||
JSON_OBJECT_SIZE(1) + 8
|
||||
},
|
||||
{
|
||||
// can skip a boolean
|
||||
"{\"a_bool\":false,example:42}",
|
||||
"{\"example\":true}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"{\"example\":42}",
|
||||
JSON_OBJECT_SIZE(1) + 8
|
||||
},
|
||||
{
|
||||
// can skip a double-quoted string
|
||||
"{\"a_double_quoted_string\":\"hello\",example:42}",
|
||||
"{\"example\":true}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"{\"example\":42}",
|
||||
JSON_OBJECT_SIZE(1) + 8
|
||||
},
|
||||
{
|
||||
// can skip a single-quoted string
|
||||
"{\"a_single_quoted_string\":'hello',example:42}",
|
||||
"{\"example\":true}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"{\"example\":42}",
|
||||
JSON_OBJECT_SIZE(1) + 8
|
||||
},
|
||||
{
|
||||
// can skip an empty array
|
||||
"{\"an_empty_array\":[],example:42}",
|
||||
"{\"example\":true}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"{\"example\":42}",
|
||||
JSON_OBJECT_SIZE(1) + 8
|
||||
},
|
||||
{
|
||||
// can skip an empty array with spaces in it
|
||||
"{\"an_empty_array\":[\t],example:42}",
|
||||
"{\"example\":true}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"{\"example\":42}",
|
||||
JSON_OBJECT_SIZE(1) + 8
|
||||
},
|
||||
{
|
||||
// can skip an array
|
||||
"{\"an_array\":[1,2,3],example:42}",
|
||||
"{\"example\":true}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"{\"example\":42}",
|
||||
JSON_OBJECT_SIZE(1) + 8
|
||||
},
|
||||
{
|
||||
// can skip an array with spaces in it
|
||||
"{\"an_array\": [ 1 , 2 , 3 ] ,example:42}",
|
||||
"{\"example\":true}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"{\"example\":42}",
|
||||
JSON_OBJECT_SIZE(1) + 8
|
||||
},
|
||||
{
|
||||
// can skip an empty object
|
||||
"{\"an_empty_object\":{},example:42}",
|
||||
"{\"example\":true}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"{\"example\":42}",
|
||||
JSON_OBJECT_SIZE(1) + 8
|
||||
},
|
||||
{
|
||||
// can skip an empty object with spaces in it
|
||||
"{\"an_empty_object\":{ },example:42}",
|
||||
"{\"example\":true}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"{\"example\":42}",
|
||||
JSON_OBJECT_SIZE(1) + 8
|
||||
},
|
||||
{
|
||||
// can skip an object
|
||||
"{\"an_object\":{a:1,'b':2,\"c\":3},example:42}",
|
||||
"{\"example\":true}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"{\"example\":42}",
|
||||
JSON_OBJECT_SIZE(1) + 8
|
||||
},
|
||||
{
|
||||
// skip an object with spaces in it
|
||||
"{\"an_object\" : { a : 1 , 'b' : 2 , \"c\" : 3 } ,example:42}",
|
||||
"{\"example\":true}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"{\"example\":42}",
|
||||
JSON_OBJECT_SIZE(1) + 8
|
||||
},
|
||||
{
|
||||
"{\"an_integer\": 0,\"example\":{\"type\":\"int\",\"outcome\":42}}",
|
||||
"{\"example\":{\"outcome\":true}}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"{\"example\":{\"outcome\":42}}",
|
||||
2 * JSON_OBJECT_SIZE(1) + 16
|
||||
},
|
||||
{
|
||||
// only the first element of array counts
|
||||
"[1,2,3]",
|
||||
"[true, false]",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"[1,2,3]",
|
||||
JSON_ARRAY_SIZE(3)
|
||||
},
|
||||
{
|
||||
// only the first element of array counts
|
||||
"[1,2,3]",
|
||||
"[false, true]",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"[]",
|
||||
JSON_ARRAY_SIZE(0)
|
||||
},
|
||||
{
|
||||
// filter members of object in array
|
||||
"[{\"example\":1,\"ignore\":2},{\"example\":3,\"ignore\":4}]",
|
||||
"[{\"example\":true}]",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"[{\"example\":1},{\"example\":3}]",
|
||||
JSON_ARRAY_SIZE(2) + 2 * JSON_OBJECT_SIZE(1) + 16
|
||||
},
|
||||
{
|
||||
"[',2,3]",
|
||||
"[false,true]",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"[]",
|
||||
JSON_ARRAY_SIZE(0)
|
||||
},
|
||||
{
|
||||
"[\",2,3]",
|
||||
"[false,true]",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"[]",
|
||||
JSON_ARRAY_SIZE(0)
|
||||
},
|
||||
{
|
||||
// ignore errors in skipped value
|
||||
"[!,2,\\]",
|
||||
"[false]",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"[]",
|
||||
JSON_ARRAY_SIZE(0)
|
||||
},
|
||||
{
|
||||
// detect incomplete string event if it's skipped
|
||||
"\"ABC",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// detect incomplete string event if it's skipped
|
||||
"'ABC",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// handle escaped quotes
|
||||
"'A\\'BC'",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// handle escaped quotes
|
||||
"\"A\\\"BC\"",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// detect incomplete string in presence of escaped quotes
|
||||
"'A\\'BC",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// detect incomplete string in presence of escaped quotes
|
||||
"\"A\\\"BC",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// skip empty array
|
||||
"[]",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// skip empty array with spaces
|
||||
" [ ] ",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// bubble up element error even if array is skipped
|
||||
"[1,'2,3]",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// bubble up member error even if object is skipped
|
||||
"{'hello':'worl}",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// bubble up colon error even if object is skipped
|
||||
"{'hello','world'}",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// bubble up key error even if object is skipped
|
||||
"{'hello:1}",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// ignore invalid value in skipped object
|
||||
"{'hello':!}",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// ignore invalid value in skipped object
|
||||
"{'hello':\\}",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// check nesting limit even for ignored objects
|
||||
"{}",
|
||||
"false",
|
||||
0,
|
||||
DeserializationError::TooDeep,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// check nesting limit even for ignored objects
|
||||
"{'hello':{}}",
|
||||
"false",
|
||||
1,
|
||||
DeserializationError::TooDeep,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// check nesting limit even for ignored values in objects
|
||||
"{'hello':{}}",
|
||||
"{}",
|
||||
1,
|
||||
DeserializationError::TooDeep,
|
||||
"{}",
|
||||
JSON_OBJECT_SIZE(0)
|
||||
},
|
||||
{
|
||||
// check nesting limit even for ignored arrays
|
||||
"[]",
|
||||
"false",
|
||||
0,
|
||||
DeserializationError::TooDeep,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// check nesting limit even for ignored arrays
|
||||
"[[]]",
|
||||
"false",
|
||||
1,
|
||||
DeserializationError::TooDeep,
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// check nesting limit even for ignored values in arrays
|
||||
"[[]]",
|
||||
"[]",
|
||||
1,
|
||||
DeserializationError::TooDeep,
|
||||
"[]",
|
||||
JSON_ARRAY_SIZE(0)
|
||||
},
|
||||
}; // clang-format on
|
||||
|
||||
for (size_t i = 0; i < sizeof(testCases) / sizeof(testCases[0]); i++) {
|
||||
CAPTURE(i);
|
||||
|
||||
DynamicJsonDocument filter(256);
|
||||
DynamicJsonDocument doc(256);
|
||||
TestCase& tc = testCases[i];
|
||||
|
||||
CAPTURE(tc.filter);
|
||||
REQUIRE(deserializeJson(filter, tc.filter) == DeserializationError::Ok);
|
||||
|
||||
CAPTURE(tc.input);
|
||||
CAPTURE(tc.nestingLimit);
|
||||
CHECK(deserializeJson(doc, tc.input, DeserializationOption::Filter(filter),
|
||||
DeserializationOption::NestingLimit(
|
||||
tc.nestingLimit)) == tc.error);
|
||||
|
||||
CHECK(doc.as<std::string>() == tc.output);
|
||||
CHECK(doc.memoryUsage() == tc.memoryUsage);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Overloads") {
|
||||
StaticJsonDocument<256> doc;
|
||||
StaticJsonDocument<256> filter;
|
||||
|
||||
using namespace DeserializationOption;
|
||||
|
||||
// deserializeJson(..., Filter)
|
||||
|
||||
SECTION("const char*, Filter") {
|
||||
deserializeJson(doc, "{}", Filter(filter));
|
||||
}
|
||||
|
||||
SECTION("const char*, size_t, Filter") {
|
||||
deserializeJson(doc, "{}", 2, Filter(filter));
|
||||
}
|
||||
|
||||
SECTION("const std::string&, Filter") {
|
||||
deserializeJson(doc, std::string("{}"), Filter(filter));
|
||||
}
|
||||
|
||||
SECTION("std::istream&, Filter") {
|
||||
std::stringstream s("{}");
|
||||
deserializeJson(doc, s, Filter(filter));
|
||||
}
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("char[n], Filter") {
|
||||
int i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "{}");
|
||||
deserializeJson(doc, vla, Filter(filter));
|
||||
}
|
||||
#endif
|
||||
|
||||
// deserializeJson(..., Filter, NestingLimit)
|
||||
|
||||
SECTION("const char*, Filter, NestingLimit") {
|
||||
deserializeJson(doc, "{}", Filter(filter), NestingLimit(5));
|
||||
}
|
||||
|
||||
SECTION("const char*, size_t, Filter, NestingLimit") {
|
||||
deserializeJson(doc, "{}", 2, Filter(filter), NestingLimit(5));
|
||||
}
|
||||
|
||||
SECTION("const std::string&, Filter, NestingLimit") {
|
||||
deserializeJson(doc, std::string("{}"), Filter(filter), NestingLimit(5));
|
||||
}
|
||||
|
||||
SECTION("std::istream&, Filter, NestingLimit") {
|
||||
std::stringstream s("{}");
|
||||
deserializeJson(doc, s, Filter(filter), NestingLimit(5));
|
||||
}
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("char[n], Filter, NestingLimit") {
|
||||
int i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "{}");
|
||||
deserializeJson(doc, vla, Filter(filter), NestingLimit(5));
|
||||
}
|
||||
#endif
|
||||
|
||||
// deserializeJson(..., NestingLimit, Filter)
|
||||
|
||||
SECTION("const char*, NestingLimit, Filter") {
|
||||
deserializeJson(doc, "{}", NestingLimit(5), Filter(filter));
|
||||
}
|
||||
|
||||
SECTION("const char*, size_t, NestingLimit, Filter") {
|
||||
deserializeJson(doc, "{}", 2, NestingLimit(5), Filter(filter));
|
||||
}
|
||||
|
||||
SECTION("const std::string&, NestingLimit, Filter") {
|
||||
deserializeJson(doc, std::string("{}"), NestingLimit(5), Filter(filter));
|
||||
}
|
||||
|
||||
SECTION("std::istream&, NestingLimit, Filter") {
|
||||
std::stringstream s("{}");
|
||||
deserializeJson(doc, s, NestingLimit(5), Filter(filter));
|
||||
}
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("char[n], NestingLimit, Filter") {
|
||||
int i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "{}");
|
||||
deserializeJson(doc, vla, NestingLimit(5), Filter(filter));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_CASE("StringMover::reclaim()") {
|
||||
StaticJsonDocument<200> filter;
|
||||
filter["a"] = true;
|
||||
filter["c"] = true;
|
||||
char input[] = "{\"a\":1,\"b\":2,\"c\":1}";
|
||||
|
||||
StaticJsonDocument<200> doc;
|
||||
deserializeJson(doc, input, DeserializationOption::Filter(filter));
|
||||
|
||||
REQUIRE(doc.as<std::string>() == "{\"a\":1,\"c\":1}");
|
||||
|
||||
CHECK(input[0] == 'a');
|
||||
CHECK(input[1] == 0);
|
||||
CHECK(input[2] == 'c');
|
||||
CHECK(input[3] == 0);
|
||||
}
|
||||
Reference in new issue
Block a user