1
0
mirror of https://github.com/nlohmann/json.git synced 2025-07-22 15:21:52 +03:00

🔨 removed a logic error and improved coverage

This commit is contained in:
Niels Lohmann
2018-02-25 17:10:30 +01:00
parent 922f7a3d0e
commit 8c7f46f7d0
4 changed files with 156 additions and 53 deletions

View File

@ -34,9 +34,8 @@ using nlohmann::json;
#include <iostream>
#include <valarray>
class SaxEventLogger : public nlohmann::json::SAX
struct SaxEventLogger : public nlohmann::json::SAX
{
public:
bool null() override
{
events.push_back("null()");
@ -132,6 +131,47 @@ class SaxEventLogger : public nlohmann::json::SAX
std::vector<std::string> events;
};
struct SaxEventLoggerExitAfterStartObject : public SaxEventLogger
{
bool start_object(std::size_t elements) override
{
if (elements == -1)
{
events.push_back("start_object()");
}
else
{
events.push_back("start_object(" + std::to_string(elements) + ")");
}
return false;
}
};
struct SaxEventLoggerExitAfterKey : public SaxEventLogger
{
bool key(const std::string& val) override
{
events.push_back("key(" + val + ")");
return false;
}
};
struct SaxEventLoggerExitAfterStartArray : public SaxEventLogger
{
bool start_array(std::size_t elements) override
{
if (elements == -1)
{
events.push_back("start_array()");
}
else
{
events.push_back("start_array(" + std::to_string(elements) + ")");
}
return false;
}
};
TEST_CASE("deserialization")
{
SECTION("successful deserialization")
@ -148,13 +188,13 @@ TEST_CASE("deserialization")
SaxEventLogger l;
CHECK(json::sax_parse(ss3, &l));
CHECK(l.events.size() == 10);
CHECK(l.events.size() == 11);
CHECK(l.events == std::vector<std::string>(
{
"start_array()", "string(foo)",
"number_unsigned(1)", "number_unsigned(2)", "number_unsigned(3)",
"boolean(false)", "start_object()",
"number_unsigned(1)", "end_object()", "end_array()"
"start_array()", "string(foo)", "number_unsigned(1)",
"number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
"start_object()", "key(one)", "number_unsigned(1)",
"end_object()", "end_array()"
}));
}
@ -167,13 +207,13 @@ TEST_CASE("deserialization")
SaxEventLogger l;
CHECK(json::sax_parse(s, &l));
CHECK(l.events.size() == 10);
CHECK(l.events.size() == 11);
CHECK(l.events == std::vector<std::string>(
{
"start_array()", "string(foo)",
"number_unsigned(1)", "number_unsigned(2)", "number_unsigned(3)",
"boolean(false)", "start_object()",
"number_unsigned(1)", "end_object()", "end_array()"
"start_array()", "string(foo)", "number_unsigned(1)",
"number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
"start_object()", "key(one)", "number_unsigned(1)",
"end_object()", "end_array()"
}));
}
@ -186,13 +226,13 @@ TEST_CASE("deserialization")
SaxEventLogger l;
CHECK(json::sax_parse(s, &l));
CHECK(l.events.size() == 10);
CHECK(l.events.size() == 11);
CHECK(l.events == std::vector<std::string>(
{
"start_array()", "string(foo)",
"number_unsigned(1)", "number_unsigned(2)", "number_unsigned(3)",
"boolean(false)", "start_object()",
"number_unsigned(1)", "end_object()", "end_array()"
"start_array()", "string(foo)", "number_unsigned(1)",
"number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
"start_object()", "key(one)", "number_unsigned(1)",
"end_object()", "end_array()"
}));
}
@ -241,13 +281,13 @@ TEST_CASE("deserialization")
SaxEventLogger l;
CHECK(not json::sax_parse(ss5, &l));
CHECK(l.events.size() == 10);
CHECK(l.events.size() == 11);
CHECK(l.events == std::vector<std::string>(
{
"start_array()", "string(foo)",
"number_unsigned(1)", "number_unsigned(2)", "number_unsigned(3)",
"boolean(false)", "start_object()",
"number_unsigned(1)", "end_object()", "parse_error(29)"
"start_array()", "string(foo)", "number_unsigned(1)",
"number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
"start_object()", "key(one)", "number_unsigned(1)",
"end_object()", "parse_error(29)"
}));
}
@ -265,13 +305,13 @@ TEST_CASE("deserialization")
SaxEventLogger l;
CHECK(not json::sax_parse(s, &l));
CHECK(l.events.size() == 10);
CHECK(l.events.size() == 11);
CHECK(l.events == std::vector<std::string>(
{
"start_array()", "string(foo)",
"number_unsigned(1)", "number_unsigned(2)", "number_unsigned(3)",
"boolean(false)", "start_object()",
"number_unsigned(1)", "end_object()", "parse_error(29)"
"start_array()", "string(foo)", "number_unsigned(1)",
"number_unsigned(2)", "number_unsigned(3)", "boolean(false)",
"start_object()", "key(one)", "number_unsigned(1)",
"end_object()", "parse_error(29)"
}));
}
@ -746,10 +786,10 @@ TEST_CASE("deserialization")
SaxEventLogger l;
CHECK(not json::sax_parse(std::begin(v), std::end(v), &l));
CHECK(l.events.size() == 3);
CHECK(l.events.size() == 4);
CHECK(l.events == std::vector<std::string>(
{
"start_object()", "number_unsigned(11)",
"start_object()", "key()", "number_unsigned(11)",
"parse_error(7)"
}));
}
@ -912,4 +952,49 @@ TEST_CASE("deserialization")
CHECK(j == 456);
}
}
SECTION("SAX and early abort")
{
std::string s = "[1, [\"string\", 43.12], null, {\"key1\": true, \"key2\": false}]";
SaxEventLogger default_logger;
SaxEventLoggerExitAfterStartObject exit_after_start_object;
SaxEventLoggerExitAfterKey exit_after_key;
SaxEventLoggerExitAfterStartArray exit_after_start_array;
json::sax_parse(s, &default_logger);
CHECK(default_logger.events.size() == 14);
CHECK(default_logger.events == std::vector<std::string>(
{
"start_array()", "number_unsigned(1)", "start_array()",
"string(string)", "number_float(43.12)", "end_array()", "null()",
"start_object()", "key(key1)", "boolean(true)", "key(key2)",
"boolean(false)", "end_object()", "end_array()"
}));
json::sax_parse(s, &exit_after_start_object);
CHECK(exit_after_start_object.events.size() == 8);
CHECK(exit_after_start_object.events == std::vector<std::string>(
{
"start_array()", "number_unsigned(1)", "start_array()",
"string(string)", "number_float(43.12)", "end_array()", "null()",
"start_object()"
}));
json::sax_parse(s, &exit_after_key);
CHECK(exit_after_key.events.size() == 9);
CHECK(exit_after_key.events == std::vector<std::string>(
{
"start_array()", "number_unsigned(1)", "start_array()",
"string(string)", "number_float(43.12)", "end_array()", "null()",
"start_object()", "key(key1)"
}));
json::sax_parse(s, &exit_after_start_array);
CHECK(exit_after_start_array.events.size() == 1);
CHECK(exit_after_start_array.events == std::vector<std::string>(
{
"start_array()"
}));
}
}