Skip to content

Commit a3c8642

Browse files
authored
Add test cases for Reader (open-source-parsers#1108)
* update testcase for reader * add a helper function * refactor structured error testing
1 parent 2983f5a commit a3c8642

File tree

1 file changed

+179
-132
lines changed

1 file changed

+179
-132
lines changed

src/test_lib_json/main.cpp

Lines changed: 179 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <json/config.h>
2222
#include <json/json.h>
2323
#include <limits>
24+
#include <memory>
2425
#include <sstream>
2526
#include <string>
2627

@@ -2641,167 +2642,213 @@ JSONTEST_FIXTURE_LOCAL(StreamWriterTest, unicode) {
26412642
"\"\\t\\n\\ud806\\udca1=\\u0133\\ud82c\\udd1b\\uff67\"\n}");
26422643
}
26432644

2644-
struct ReaderTest : JsonTest::TestCase {};
2645+
struct ReaderTest : JsonTest::TestCase {
2646+
void setStrictMode() {
2647+
reader = std::unique_ptr<Json::Reader>(
2648+
new Json::Reader(Json::Features{}.strictMode()));
2649+
}
26452650

2646-
JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithNoErrors) {
2647-
Json::Reader reader;
2651+
void checkStructuredErrors(
2652+
const std::vector<Json::Reader::StructuredError>& actual,
2653+
const std::vector<Json::Reader::StructuredError>& expected) {
2654+
JSONTEST_ASSERT_EQUAL(actual.size(), expected.size());
2655+
for (size_t i = 0; i < actual.size(); ++i) {
2656+
const auto& a = actual[i];
2657+
const auto& e = expected[i];
2658+
JSONTEST_ASSERT_EQUAL(a.offset_start, e.offset_start) << i;
2659+
JSONTEST_ASSERT_EQUAL(a.offset_limit, e.offset_limit) << i;
2660+
JSONTEST_ASSERT_EQUAL(a.message, e.message) << i;
2661+
}
2662+
}
2663+
2664+
template <typename Input> void checkParse(Input&& input) {
2665+
JSONTEST_ASSERT(reader->parse(input, root));
2666+
}
2667+
2668+
template <typename Input>
2669+
void
2670+
checkParse(Input&& input,
2671+
const std::vector<Json::Reader::StructuredError>& structured) {
2672+
JSONTEST_ASSERT(!reader->parse(input, root));
2673+
checkStructuredErrors(reader->getStructuredErrors(), structured);
2674+
}
2675+
2676+
template <typename Input>
2677+
void checkParse(Input&& input,
2678+
const std::vector<Json::Reader::StructuredError>& structured,
2679+
const std::string& formatted) {
2680+
checkParse(input, structured);
2681+
JSONTEST_ASSERT_EQUAL(reader->getFormattedErrorMessages(), formatted);
2682+
}
2683+
2684+
std::unique_ptr<Json::Reader> reader{new Json::Reader()};
26482685
Json::Value root;
2649-
bool ok = reader.parse("{ \"property\" : \"value\" }", root);
2650-
JSONTEST_ASSERT(ok);
2651-
JSONTEST_ASSERT(reader.getFormattedErrorMessages().empty());
2652-
JSONTEST_ASSERT(reader.getStructuredErrors().empty());
2686+
};
2687+
2688+
JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithNoErrors) {
2689+
checkParse(R"({ "property" : "value" })");
2690+
}
2691+
2692+
JSONTEST_FIXTURE_LOCAL(ReaderTest, parseObject) {
2693+
checkParse(R"({"property"})",
2694+
{{11, 12, "Missing ':' after object member name"}},
2695+
"* Line 1, Column 12\n Missing ':' after object member name\n");
2696+
checkParse(
2697+
R"({"property" : "value" )",
2698+
{{22, 22, "Missing ',' or '}' in object declaration"}},
2699+
"* Line 1, Column 23\n Missing ',' or '}' in object declaration\n");
2700+
checkParse(R"({"property" : "value", )",
2701+
{{23, 23, "Missing '}' or object member name"}},
2702+
"* Line 1, Column 24\n Missing '}' or object member name\n");
2703+
}
2704+
2705+
JSONTEST_FIXTURE_LOCAL(ReaderTest, parseArray) {
2706+
checkParse(
2707+
R"([ "value" )", {{10, 10, "Missing ',' or ']' in array declaration"}},
2708+
"* Line 1, Column 11\n Missing ',' or ']' in array declaration\n");
2709+
checkParse(
2710+
R"([ "value1" "value2" ] )",
2711+
{{11, 19, "Missing ',' or ']' in array declaration"}},
2712+
"* Line 1, Column 12\n Missing ',' or ']' in array declaration\n");
2713+
}
2714+
2715+
JSONTEST_FIXTURE_LOCAL(ReaderTest, parseString) {
2716+
checkParse(R"([ "\u8a2a" ])");
2717+
checkParse(
2718+
R"([ "\ud801" ])",
2719+
{{2, 10,
2720+
"additional six characters expected to parse unicode surrogate "
2721+
"pair."}},
2722+
"* Line 1, Column 3\n"
2723+
" additional six characters expected to parse unicode surrogate pair.\n"
2724+
"See Line 1, Column 10 for detail.\n");
2725+
checkParse(R"([ "\ud801\d1234" ])",
2726+
{{2, 16,
2727+
"expecting another \\u token to begin the "
2728+
"second half of a unicode surrogate pair"}},
2729+
"* Line 1, Column 3\n"
2730+
" expecting another \\u token to begin the "
2731+
"second half of a unicode surrogate pair\n"
2732+
"See Line 1, Column 12 for detail.\n");
2733+
checkParse(R"([ "\ua3t@" ])",
2734+
{{2, 10,
2735+
"Bad unicode escape sequence in string: "
2736+
"hexadecimal digit expected."}},
2737+
"* Line 1, Column 3\n"
2738+
" Bad unicode escape sequence in string: "
2739+
"hexadecimal digit expected.\n"
2740+
"See Line 1, Column 9 for detail.\n");
2741+
checkParse(
2742+
R"([ "\ua3t" ])",
2743+
{{2, 9, "Bad unicode escape sequence in string: four digits expected."}},
2744+
"* Line 1, Column 3\n"
2745+
" Bad unicode escape sequence in string: four digits expected.\n"
2746+
"See Line 1, Column 6 for detail.\n");
26532747
}
26542748

26552749
JSONTEST_FIXTURE_LOCAL(ReaderTest, parseComment) {
2656-
Json::Reader reader;
2657-
Json::Value root;
2658-
bool ok = reader.parse("{ /*commentBeforeValue*/"
2659-
" \"property\" : \"value\" }"
2660-
"//commentAfterValue\n",
2661-
root);
2662-
JSONTEST_ASSERT(ok);
2663-
JSONTEST_ASSERT(reader.getFormattedErrorMessages().empty());
2664-
JSONTEST_ASSERT(reader.getStructuredErrors().empty());
2750+
checkParse(
2751+
R"({ /*commentBeforeValue*/ "property" : "value" }//commentAfterValue)"
2752+
"\n");
2753+
checkParse(" true //comment1\n//comment2\r//comment3\r\n");
26652754
}
26662755

26672756
JSONTEST_FIXTURE_LOCAL(ReaderTest, streamParseWithNoErrors) {
2668-
Json::Reader reader;
2669-
std::string styled = "{ \"property\" : \"value\" }";
2757+
std::string styled = R"({ "property" : "value" })";
26702758
std::istringstream iss(styled);
2671-
Json::Value root;
2672-
bool ok = reader.parse(iss, root);
2673-
JSONTEST_ASSERT(ok);
2674-
JSONTEST_ASSERT(reader.getFormattedErrorMessages().empty());
2675-
JSONTEST_ASSERT(reader.getStructuredErrors().empty());
2759+
checkParse(iss);
26762760
}
26772761

26782762
JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithNoErrorsTestingOffsets) {
2679-
Json::Reader reader;
2680-
Json::Value root;
2681-
bool ok = reader.parse("{ \"property\" : [\"value\", \"value2\"], \"obj\" : "
2682-
"{ \"nested\" : -6.2e+15, \"bool\" : true}, \"null\" :"
2683-
" null, \"false\" : false }",
2684-
root);
2685-
JSONTEST_ASSERT(ok);
2686-
JSONTEST_ASSERT(reader.getFormattedErrorMessages().empty());
2687-
JSONTEST_ASSERT(reader.getStructuredErrors().empty());
2688-
JSONTEST_ASSERT(root["property"].getOffsetStart() == 15);
2689-
JSONTEST_ASSERT(root["property"].getOffsetLimit() == 34);
2690-
JSONTEST_ASSERT(root["property"][0].getOffsetStart() == 16);
2691-
JSONTEST_ASSERT(root["property"][0].getOffsetLimit() == 23);
2692-
JSONTEST_ASSERT(root["property"][1].getOffsetStart() == 25);
2693-
JSONTEST_ASSERT(root["property"][1].getOffsetLimit() == 33);
2694-
JSONTEST_ASSERT(root["obj"].getOffsetStart() == 44);
2695-
JSONTEST_ASSERT(root["obj"].getOffsetLimit() == 81);
2696-
JSONTEST_ASSERT(root["obj"]["nested"].getOffsetStart() == 57);
2697-
JSONTEST_ASSERT(root["obj"]["nested"].getOffsetLimit() == 65);
2698-
JSONTEST_ASSERT(root["obj"]["bool"].getOffsetStart() == 76);
2699-
JSONTEST_ASSERT(root["obj"]["bool"].getOffsetLimit() == 80);
2700-
JSONTEST_ASSERT(root["null"].getOffsetStart() == 92);
2701-
JSONTEST_ASSERT(root["null"].getOffsetLimit() == 96);
2702-
JSONTEST_ASSERT(root["false"].getOffsetStart() == 108);
2703-
JSONTEST_ASSERT(root["false"].getOffsetLimit() == 113);
2704-
JSONTEST_ASSERT(root.getOffsetStart() == 0);
2705-
JSONTEST_ASSERT(root.getOffsetLimit() == 115);
2763+
checkParse(R"({)"
2764+
R"( "property" : ["value", "value2"],)"
2765+
R"( "obj" : { "nested" : -6.2e+15, "bool" : true},)"
2766+
R"( "null" : null,)"
2767+
R"( "false" : false)"
2768+
R"( })");
2769+
auto checkOffsets = [&](const Json::Value& v, int start, int limit) {
2770+
JSONTEST_ASSERT_EQUAL(v.getOffsetStart(), start);
2771+
JSONTEST_ASSERT_EQUAL(v.getOffsetLimit(), limit);
2772+
};
2773+
checkOffsets(root, 0, 115);
2774+
checkOffsets(root["property"], 15, 34);
2775+
checkOffsets(root["property"][0], 16, 23);
2776+
checkOffsets(root["property"][1], 25, 33);
2777+
checkOffsets(root["obj"], 44, 81);
2778+
checkOffsets(root["obj"]["nested"], 57, 65);
2779+
checkOffsets(root["obj"]["bool"], 76, 80);
2780+
checkOffsets(root["null"], 92, 96);
2781+
checkOffsets(root["false"], 108, 113);
27062782
}
27072783

27082784
JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithOneError) {
2709-
Json::Reader reader;
2710-
Json::Value root;
2711-
bool ok = reader.parse("{ \"property\" :: \"value\" }", root);
2712-
JSONTEST_ASSERT(!ok);
2713-
JSONTEST_ASSERT(reader.getFormattedErrorMessages() ==
2714-
"* Line 1, Column 15\n Syntax error: value, object or array "
2715-
"expected.\n");
2716-
std::vector<Json::Reader::StructuredError> errors =
2717-
reader.getStructuredErrors();
2718-
JSONTEST_ASSERT(errors.size() == 1);
2719-
JSONTEST_ASSERT(errors.at(0).offset_start == 14);
2720-
JSONTEST_ASSERT(errors.at(0).offset_limit == 15);
2721-
JSONTEST_ASSERT(errors.at(0).message ==
2722-
"Syntax error: value, object or array expected.");
2785+
checkParse(R"({ "property" :: "value" })",
2786+
{{14, 15, "Syntax error: value, object or array expected."}},
2787+
"* Line 1, Column 15\n Syntax error: value, object or array "
2788+
"expected.\n");
2789+
checkParse("s", {{0, 1, "Syntax error: value, object or array expected."}},
2790+
"* Line 1, Column 1\n Syntax error: value, object or array "
2791+
"expected.\n");
2792+
}
2793+
2794+
JSONTEST_FIXTURE_LOCAL(ReaderTest, parseSpecialFloat) {
2795+
checkParse(R"({ "a" : Infi })",
2796+
{{8, 9, "Syntax error: value, object or array expected."}},
2797+
"* Line 1, Column 9\n Syntax error: value, object or array "
2798+
"expected.\n");
2799+
checkParse(R"({ "a" : Infiniaa })",
2800+
{{8, 9, "Syntax error: value, object or array expected."}},
2801+
"* Line 1, Column 9\n Syntax error: value, object or array "
2802+
"expected.\n");
27232803
}
27242804

27252805
JSONTEST_FIXTURE_LOCAL(ReaderTest, strictModeParseNumber) {
2726-
Json::Features feature;
2727-
Json::Reader reader(feature.strictMode());
2728-
Json::Value root;
2729-
bool ok = reader.parse("123", root);
2730-
JSONTEST_ASSERT(!ok);
2731-
JSONTEST_ASSERT(reader.getFormattedErrorMessages() ==
2732-
"* Line 1, Column 1\n"
2733-
" A valid JSON document must be either an array or"
2734-
" an object value.\n");
2735-
std::vector<Json::Reader::StructuredError> errors =
2736-
reader.getStructuredErrors();
2737-
JSONTEST_ASSERT(errors.size() == 1);
2738-
JSONTEST_ASSERT(errors.at(0).offset_start == 0);
2739-
JSONTEST_ASSERT(errors.at(0).offset_limit == 3);
2740-
JSONTEST_ASSERT(errors.at(0).message ==
2741-
"A valid JSON document must be either an array or"
2742-
" an object value.");
2806+
setStrictMode();
2807+
checkParse(
2808+
"123",
2809+
{{0, 3,
2810+
"A valid JSON document must be either an array or an object value."}},
2811+
"* Line 1, Column 1\n"
2812+
" A valid JSON document must be either an array or an object value.\n");
27432813
}
27442814

27452815
JSONTEST_FIXTURE_LOCAL(ReaderTest, parseChineseWithOneError) {
2746-
Json::Reader reader;
2747-
Json::Value root;
2748-
bool ok = reader.parse("{ \"pr佐藤erty\" :: \"value\" }", root);
2749-
JSONTEST_ASSERT(!ok);
2750-
JSONTEST_ASSERT(reader.getFormattedErrorMessages() ==
2751-
"* Line 1, Column 19\n Syntax error: value, object or array "
2752-
"expected.\n");
2753-
std::vector<Json::Reader::StructuredError> errors =
2754-
reader.getStructuredErrors();
2755-
JSONTEST_ASSERT(errors.size() == 1);
2756-
JSONTEST_ASSERT(errors.at(0).offset_start == 18);
2757-
JSONTEST_ASSERT(errors.at(0).offset_limit == 19);
2758-
JSONTEST_ASSERT(errors.at(0).message ==
2759-
"Syntax error: value, object or array expected.");
2816+
// \u4f50\u85e4 佐藤
2817+
checkParse(R"({ "pr)"
2818+
"佐藤"
2819+
R"(erty" :: "value" })",
2820+
{{18, 19, "Syntax error: value, object or array expected."}},
2821+
"* Line 1, Column 19\n Syntax error: value, object or array "
2822+
"expected.\n");
27602823
}
27612824

27622825
JSONTEST_FIXTURE_LOCAL(ReaderTest, parseWithDetailError) {
2763-
Json::Reader reader;
2764-
Json::Value root;
2765-
bool ok = reader.parse("{ \"property\" : \"v\\alue\" }", root);
2766-
JSONTEST_ASSERT(!ok);
2767-
JSONTEST_ASSERT(reader.getFormattedErrorMessages() ==
2768-
"* Line 1, Column 16\n Bad escape sequence in string\nSee "
2769-
"Line 1, Column 20 for detail.\n");
2770-
std::vector<Json::Reader::StructuredError> errors =
2771-
reader.getStructuredErrors();
2772-
JSONTEST_ASSERT(errors.size() == 1);
2773-
JSONTEST_ASSERT(errors.at(0).offset_start == 15);
2774-
JSONTEST_ASSERT(errors.at(0).offset_limit == 23);
2775-
JSONTEST_ASSERT(errors.at(0).message == "Bad escape sequence in string");
2826+
checkParse(R"({ "property" : "v\alue" })",
2827+
{{15, 23, "Bad escape sequence in string"}},
2828+
"* Line 1, Column 16\n"
2829+
" Bad escape sequence in string\n"
2830+
"See Line 1, Column 20 for detail.\n");
27762831
}
27772832

27782833
JSONTEST_FIXTURE_LOCAL(ReaderTest, pushErrorTest) {
2779-
Json::Reader reader;
2780-
Json::Value root;
2781-
{
2782-
bool ok = reader.parse("{ \"AUTHOR\" : 123 }", root);
2783-
JSONTEST_ASSERT(ok);
2784-
if (!root["AUTHOR"].isString()) {
2785-
ok = reader.pushError(root["AUTHOR"], "AUTHOR must be a string");
2786-
}
2787-
JSONTEST_ASSERT(ok);
2788-
JSONTEST_ASSERT(reader.getFormattedErrorMessages() ==
2789-
"* Line 1, Column 14\n"
2790-
" AUTHOR must be a string\n");
2834+
checkParse(R"({ "AUTHOR" : 123 })");
2835+
if (!root["AUTHOR"].isString()) {
2836+
JSONTEST_ASSERT(
2837+
reader->pushError(root["AUTHOR"], "AUTHOR must be a string"));
27912838
}
2792-
{
2793-
bool ok = reader.parse("{ \"AUTHOR\" : 123 }", root);
2794-
JSONTEST_ASSERT(ok);
2795-
if (!root["AUTHOR"].isString()) {
2796-
ok = reader.pushError(root["AUTHOR"], "AUTHOR must be a string",
2797-
root["AUTHOR"]);
2798-
}
2799-
JSONTEST_ASSERT(ok);
2800-
JSONTEST_ASSERT(reader.getFormattedErrorMessages() ==
2801-
"* Line 1, Column 14\n"
2802-
" AUTHOR must be a string\n"
2803-
"See Line 1, Column 14 for detail.\n");
2839+
JSONTEST_ASSERT_STRING_EQUAL(reader->getFormattedErrorMessages(),
2840+
"* Line 1, Column 14\n"
2841+
" AUTHOR must be a string\n");
2842+
2843+
checkParse(R"({ "AUTHOR" : 123 })");
2844+
if (!root["AUTHOR"].isString()) {
2845+
JSONTEST_ASSERT(reader->pushError(root["AUTHOR"], "AUTHOR must be a string",
2846+
root["AUTHOR"]));
28042847
}
2848+
JSONTEST_ASSERT_STRING_EQUAL(reader->getFormattedErrorMessages(),
2849+
"* Line 1, Column 14\n"
2850+
" AUTHOR must be a string\n"
2851+
"See Line 1, Column 14 for detail.\n");
28052852
}
28062853

28072854
struct CharReaderTest : JsonTest::TestCase {};

0 commit comments

Comments
 (0)