summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/rapidjson/test/unittest/readertest.cpp
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2016-03-31 20:40:36 +0200
committer Miodrag Milanovic <mmicko@gmail.com>2016-03-31 20:40:36 +0200
commitbd2e14349beb065b7124d89d9d415d5cfb8b83d1 (patch)
treebc837234de77eccdfd46c26e7f2efcd9a07cdb49 /3rdparty/rapidjson/test/unittest/readertest.cpp
parent4172b54d844e4c1ff5626a8f22bf3f56e6c9dd94 (diff)
Update rapidjson (nw)
Diffstat (limited to '3rdparty/rapidjson/test/unittest/readertest.cpp')
-rw-r--r--3rdparty/rapidjson/test/unittest/readertest.cpp304
1 files changed, 263 insertions, 41 deletions
diff --git a/3rdparty/rapidjson/test/unittest/readertest.cpp b/3rdparty/rapidjson/test/unittest/readertest.cpp
index 32af8a86eec..3f11fec8be3 100644
--- a/3rdparty/rapidjson/test/unittest/readertest.cpp
+++ b/3rdparty/rapidjson/test/unittest/readertest.cpp
@@ -1,5 +1,5 @@
// Tencent is pleased to support the open source community by making RapidJSON available.
-//
+//
// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
//
// Licensed under the MIT License (the "License"); you may not use this file except
@@ -7,9 +7,9 @@
//
// http://opensource.org/licenses/MIT
//
-// Unless required by applicable law or agreed to in writing, software distributed
-// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// Unless required by applicable law or agreed to in writing, software distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
#include "unittest.h"
@@ -241,13 +241,13 @@ static void TestParseDouble() {
TEST_DOUBLE(fullPrecision, "0.017976931348623157e+310", 1.7976931348623157e+308); // Max double in another form
// Since
- // abs((2^-1022 - 2^-1074) - 2.2250738585072012e-308) = 3.109754131239141401123495768877590405345064751974375599... ¡Á 10^-324
- // abs((2^-1022) - 2.2250738585072012e-308) = 1.830902327173324040642192159804623318305533274168872044... ¡Á 10 ^ -324
+ // abs((2^-1022 - 2^-1074) - 2.2250738585072012e-308) = 3.109754131239141401123495768877590405345064751974375599... �� 10^-324
+ // abs((2^-1022) - 2.2250738585072012e-308) = 1.830902327173324040642192159804623318305533274168872044... �� 10 ^ -324
// So 2.2250738585072012e-308 should round to 2^-1022 = 2.2250738585072014e-308
TEST_DOUBLE(fullPrecision, "2.2250738585072012e-308", 2.2250738585072014e-308); // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
// More closer to normal/subnormal boundary
- // boundary = 2^-1022 - 2^-1075 = 2.225073858507201136057409796709131975934819546351645648... ¡Á 10^-308
+ // boundary = 2^-1022 - 2^-1075 = 2.225073858507201136057409796709131975934819546351645648... �� 10^-308
TEST_DOUBLE(fullPrecision, "2.22507385850720113605740979670913197593481954635164564e-308", 2.2250738585072009e-308);
TEST_DOUBLE(fullPrecision, "2.22507385850720113605740979670913197593481954635164565e-308", 2.2250738585072014e-308);
@@ -297,7 +297,7 @@ static void TestParseDouble() {
}
// Cover trimming
- TEST_DOUBLE(fullPrecision,
+ TEST_DOUBLE(fullPrecision,
"2.22507385850720113605740979670913197593481954635164564802342610972482222202107694551652952390813508"
"7914149158913039621106870086438694594645527657207407820621743379988141063267329253552286881372149012"
"9811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306"
@@ -306,7 +306,7 @@ static void TestParseDouble() {
"5722898802581825451803257070188608721131280795122334262883686223215037756666225039825343359745688844"
"2390026549819838548794829220689472168983109969836584681402285424333066033985088644580400103493397042"
"7567186443383770486037861622771738545623065874679014086723327636718751234567890123456789012345678901"
-"e-308",
+"e-308",
2.2250738585072014e-308);
{
@@ -457,12 +457,12 @@ template <typename Encoding>
struct ParseStringHandler : BaseReaderHandler<Encoding, ParseStringHandler<Encoding> > {
ParseStringHandler() : str_(0), length_(0), copy_() {}
~ParseStringHandler() { EXPECT_TRUE(str_ != 0); if (copy_) free(const_cast<typename Encoding::Ch*>(str_)); }
-
+
ParseStringHandler(const ParseStringHandler&);
ParseStringHandler& operator=(const ParseStringHandler&);
bool Default() { ADD_FAILURE(); return false; }
- bool String(const typename Encoding::Ch* str, size_t length, bool copy) {
+ bool String(const typename Encoding::Ch* str, size_t length, bool copy) {
EXPECT_EQ(0, str_);
if (copy) {
str_ = static_cast<typename Encoding::Ch*>(malloc((length + 1) * sizeof(typename Encoding::Ch)));
@@ -470,7 +470,7 @@ struct ParseStringHandler : BaseReaderHandler<Encoding, ParseStringHandler<Encod
}
else
str_ = str;
- length_ = length;
+ length_ = length;
copy_ = copy;
return true;
}
@@ -499,7 +499,7 @@ TEST(Reader, ParseString) {
EXPECT_EQ(StrLen(e), h2.length_); \
}
- // String constant L"\xXX" can only specify character code in bytes, which is not endianness-neutral.
+ // String constant L"\xXX" can only specify character code in bytes, which is not endianness-neutral.
// And old compiler does not support u"" and U"" string literal. So here specify string literal by array of Ch.
// In addition, GCC 4.8 generates -Wnarrowing warnings when character code >= 128 are assigned to signed integer types.
// Therefore, utype is added for declaring unsigned array, and then cast it to Encoding::Ch.
@@ -650,7 +650,7 @@ TEST(Reader, ParseString_Error) {
// http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt
- // 3 Malformed sequences
+ // 3 Malformed sequences
// 3.1 Unexpected continuation bytes
{
@@ -684,19 +684,19 @@ TEST(Reader, ParseString_Error) {
}
}
- // 4 Overlong sequences
+ // 4 Overlong sequences
// 4.1 Examples of an overlong ASCII character
TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xC0u, 0xAFu, '\"', ']', '\0'));
TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xE0u, 0x80u, 0xAFu, '\"', ']', '\0'));
TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xF0u, 0x80u, 0x80u, 0xAFu, '\"', ']', '\0'));
- // 4.2 Maximum overlong sequences
+ // 4.2 Maximum overlong sequences
TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xC1u, 0xBFu, '\"', ']', '\0'));
TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xE0u, 0x9Fu, 0xBFu, '\"', ']', '\0'));
TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xF0u, 0x8Fu, 0xBFu, 0xBFu, '\"', ']', '\0'));
- // 4.3 Overlong representation of the NUL character
+ // 4.3 Overlong representation of the NUL character
TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xC0u, 0x80u, '\"', ']', '\0'));
TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xE0u, 0x80u, 0x80u, '\"', ']', '\0'));
TEST_STRINGENCODING_ERROR(UTF8<>, UTF16<>, unsigned char, ARRAY('[', '\"', 0xF0u, 0x80u, 0x80u, 0x80u, '\"', ']', '\0'));
@@ -778,6 +778,10 @@ TEST(Reader, ParseArray_Error) {
TEST_ARRAY_ERROR(kParseErrorArrayMissCommaOrSquareBracket, "[1}", 2);
TEST_ARRAY_ERROR(kParseErrorArrayMissCommaOrSquareBracket, "[1 2]", 3);
+ // Array cannot have a trailing comma (without kParseTrailingCommasFlag);
+ // a value must follow a comma
+ TEST_ARRAY_ERROR(kParseErrorValueInvalid, "[1,]", 3);
+
#undef TEST_ARRAY_ERROR
}
@@ -786,14 +790,14 @@ struct ParseObjectHandler : BaseReaderHandler<UTF8<>, ParseObjectHandler> {
bool Default() { ADD_FAILURE(); return false; }
bool Null() { EXPECT_EQ(8u, step_); step_++; return true; }
- bool Bool(bool b) {
+ bool Bool(bool b) {
switch(step_) {
case 4: EXPECT_TRUE(b); step_++; return true;
case 6: EXPECT_FALSE(b); step_++; return true;
default: ADD_FAILURE(); return false;
}
}
- bool Int(int i) {
+ bool Int(int i) {
switch(step_) {
case 10: EXPECT_EQ(123, i); step_++; return true;
case 15: EXPECT_EQ(1, i); step_++; return true;
@@ -804,7 +808,7 @@ struct ParseObjectHandler : BaseReaderHandler<UTF8<>, ParseObjectHandler> {
}
bool Uint(unsigned i) { return Int(static_cast<int>(i)); }
bool Double(double d) { EXPECT_EQ(12u, step_); EXPECT_DOUBLE_EQ(3.1416, d); step_++; return true; }
- bool String(const char* str, size_t, bool) {
+ bool String(const char* str, size_t, bool) {
switch(step_) {
case 1: EXPECT_STREQ("hello", str); step_++; return true;
case 2: EXPECT_STREQ("world", str); step_++; return true;
@@ -978,6 +982,10 @@ TEST(Reader, ParseObject_Error) {
// Must be a comma or '}' after an object member
TEST_ERROR(kParseErrorObjectMissCommaOrCurlyBracket, "{\"a\":1]", 6);
+ // Object cannot have a trailing comma (without kParseTrailingCommasFlag);
+ // an object member name must follow a comma
+ TEST_ERROR(kParseErrorObjectMissName, "{\"a\":1,}", 7);
+
// This tests that MemoryStream is checking the length in Peek().
{
MemoryStream ms("{\"a\"", 1);
@@ -1037,7 +1045,7 @@ struct StreamTraits<CustomStringStream<Encoding> > {
};
} // namespace rapidjson
-#endif
+#endif
TEST(Reader, CustomStringStream) {
const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] } ";
@@ -1061,7 +1069,7 @@ public:
return c == std::char_traits<char>::eof() ? '\0' : static_cast<Ch>(c);
}
- Ch Take() {
+ Ch Take() {
int c = is_.get();
return c == std::char_traits<char>::eof() ? '\0' : static_cast<Ch>(c);
}
@@ -1089,7 +1097,7 @@ TEST(Reader, Parse_IStreamWrapper_StringStream) {
Reader reader;
ParseArrayHandler<4> h;
reader.Parse(is, h);
- EXPECT_FALSE(reader.HasParseError());
+ EXPECT_FALSE(reader.HasParseError());
}
// Test iterative parsing.
@@ -1119,6 +1127,16 @@ TEST(Reader, IterativeParsing_ErrorHandling) {
TESTERRORHANDLING("{\"a\": 1", kParseErrorObjectMissCommaOrCurlyBracket, 7u);
TESTERRORHANDLING("[1 2 3]", kParseErrorArrayMissCommaOrSquareBracket, 3u);
TESTERRORHANDLING("{\"a: 1", kParseErrorStringMissQuotationMark, 6u);
+ TESTERRORHANDLING("{\"a\":}", kParseErrorValueInvalid, 5u);
+ TESTERRORHANDLING("{\"a\":]", kParseErrorValueInvalid, 5u);
+ TESTERRORHANDLING("[1,2,}", kParseErrorValueInvalid, 5u);
+ TESTERRORHANDLING("[}]", kParseErrorValueInvalid, 1u);
+ TESTERRORHANDLING("[,]", kParseErrorValueInvalid, 1u);
+ TESTERRORHANDLING("[1,,]", kParseErrorValueInvalid, 3u);
+
+ // Trailing commas are not allowed without kParseTrailingCommasFlag
+ TESTERRORHANDLING("{\"a\": 1,}", kParseErrorObjectMissName, 8u);
+ TESTERRORHANDLING("[1,2,3,]", kParseErrorValueInvalid, 7u);
// Any JSON value can be a valid root element in RFC7159.
TESTERRORHANDLING("\"ab", kParseErrorStringMissQuotationMark, 3u);
@@ -1177,7 +1195,7 @@ struct IterativeParsingReaderHandler {
bool StartObject() { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_STARTOBJECT; return true; }
bool Key (const Ch*, SizeType, bool) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_KEY; return true; }
-
+
bool EndObject(SizeType c) {
RAPIDJSON_ASSERT(LogCount < LogCapacity);
Logs[LogCount++] = LOG_ENDOBJECT;
@@ -1428,7 +1446,7 @@ TEST(Reader, ParseEmptyOnelineComment) {
}
TEST(Reader, ParseMultipleCommentsInARow) {
- const char* json =
+ const char* json =
"{/* first comment *//* second */\n"
"/* third */ /*fourth*/// last one\n"
"\"hello\" : \"world\", \"t\" : true, \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3] }";
@@ -1523,7 +1541,8 @@ struct NumbersAsStringsHandler {
// 'str' is not null-terminated
bool RawNumber(const char* str, SizeType length, bool) {
EXPECT_TRUE(str != 0);
- EXPECT_TRUE(strncmp(str, "3.1416", length) == 0);
+ EXPECT_TRUE(expected_len_ == length);
+ EXPECT_TRUE(strncmp(str, expected_, length) == 0);
return true;
}
bool String(const char*, SizeType, bool) { return true; }
@@ -1532,24 +1551,227 @@ struct NumbersAsStringsHandler {
bool EndObject(SizeType) { return true; }
bool StartArray() { return true; }
bool EndArray(SizeType) { return true; }
+
+ NumbersAsStringsHandler(const char* expected)
+ : expected_(expected)
+ , expected_len_(strlen(expected)) {}
+
+ const char* expected_;
+ size_t expected_len_;
};
TEST(Reader, NumbersAsStrings) {
- {
- const char* json = "{ \"pi\": 3.1416 } ";
- StringStream s(json);
- NumbersAsStringsHandler h;
- Reader reader;
- EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
- }
- {
- char* json = StrDup("{ \"pi\": 3.1416 } ");
- InsituStringStream s(json);
- NumbersAsStringsHandler h;
- Reader reader;
- EXPECT_TRUE(reader.Parse<kParseInsituFlag|kParseNumbersAsStringsFlag>(s, h));
- free(json);
- }
+ {
+ const char* json = "{ \"pi\": 3.1416 } ";
+ StringStream s(json);
+ NumbersAsStringsHandler h("3.1416");
+ Reader reader;
+ EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
+ }
+ {
+ char* json = StrDup("{ \"pi\": 3.1416 } ");
+ InsituStringStream s(json);
+ NumbersAsStringsHandler h("3.1416");
+ Reader reader;
+ EXPECT_TRUE(reader.Parse<kParseInsituFlag|kParseNumbersAsStringsFlag>(s, h));
+ free(json);
+ }
+ {
+ const char* json = "{ \"gigabyte\": 1.0e9 } ";
+ StringStream s(json);
+ NumbersAsStringsHandler h("1.0e9");
+ Reader reader;
+ EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
+ }
+ {
+ char* json = StrDup("{ \"gigabyte\": 1.0e9 } ");
+ InsituStringStream s(json);
+ NumbersAsStringsHandler h("1.0e9");
+ Reader reader;
+ EXPECT_TRUE(reader.Parse<kParseInsituFlag|kParseNumbersAsStringsFlag>(s, h));
+ free(json);
+ }
+ {
+ const char* json = "{ \"pi\": 314.159e-2 } ";
+ StringStream s(json);
+ NumbersAsStringsHandler h("314.159e-2");
+ Reader reader;
+ EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
+ }
+ {
+ char* json = StrDup("{ \"gigabyte\": 314.159e-2 } ");
+ InsituStringStream s(json);
+ NumbersAsStringsHandler h("314.159e-2");
+ Reader reader;
+ EXPECT_TRUE(reader.Parse<kParseInsituFlag|kParseNumbersAsStringsFlag>(s, h));
+ free(json);
+ }
+ {
+ const char* json = "{ \"negative\": -1.54321 } ";
+ StringStream s(json);
+ NumbersAsStringsHandler h("-1.54321");
+ Reader reader;
+ EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
+ }
+ {
+ char* json = StrDup("{ \"negative\": -1.54321 } ");
+ InsituStringStream s(json);
+ NumbersAsStringsHandler h("-1.54321");
+ Reader reader;
+ EXPECT_TRUE(reader.Parse<kParseInsituFlag|kParseNumbersAsStringsFlag>(s, h));
+ free(json);
+ }
+ {
+ const char* json = "{ \"pi\": 314.159e-2 } ";
+ std::stringstream ss(json);
+ IStreamWrapper s(ss);
+ NumbersAsStringsHandler h("314.159e-2");
+ Reader reader;
+ EXPECT_TRUE(reader.Parse<kParseNumbersAsStringsFlag>(s, h));
+ }
+}
+
+template <unsigned extraFlags>
+void TestTrailingCommas() {
+ {
+ StringStream s("[1,2,3,]");
+ ParseArrayHandler<3> h;
+ Reader reader;
+ EXPECT_TRUE(reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h));
+ EXPECT_EQ(5u, h.step_);
+ }
+ {
+ const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false,"
+ "\"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3],}";
+ StringStream s(json);
+ ParseObjectHandler h;
+ Reader reader;
+ EXPECT_TRUE(reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h));
+ EXPECT_EQ(20u, h.step_);
+ }
+ {
+ // whitespace around trailing commas
+ const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false,"
+ "\"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3\n,\n]\n,\n} ";
+ StringStream s(json);
+ ParseObjectHandler h;
+ Reader reader;
+ EXPECT_TRUE(reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h));
+ EXPECT_EQ(20u, h.step_);
+ }
+ {
+ // comments around trailing commas
+ const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null,"
+ "\"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3/*test*/,/*test*/]/*test*/,/*test*/}";
+ StringStream s(json);
+ ParseObjectHandler h;
+ Reader reader;
+ EXPECT_TRUE(reader.Parse<extraFlags|kParseTrailingCommasFlag|kParseCommentsFlag>(s, h));
+ EXPECT_EQ(20u, h.step_);
+ }
+}
+
+TEST(Reader, TrailingCommas) {
+ TestTrailingCommas<kParseNoFlags>();
+}
+
+TEST(Reader, TrailingCommasIterative) {
+ TestTrailingCommas<kParseIterativeFlag>();
+}
+
+template <unsigned extraFlags>
+void TestMultipleTrailingCommaErrors() {
+ // only a single trailing comma is allowed.
+ {
+ StringStream s("[1,2,3,,]");
+ ParseArrayHandler<3> h;
+ Reader reader;
+ ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
+ EXPECT_TRUE(reader.HasParseError());
+ EXPECT_EQ(kParseErrorValueInvalid, r.Code());
+ EXPECT_EQ(7u, r.Offset());
+ }
+ {
+ const char* json = "{ \"hello\" : \"world\", \"t\" : true , \"f\" : false,"
+ "\"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3,],,}";
+ StringStream s(json);
+ ParseObjectHandler h;
+ Reader reader;
+ ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
+ EXPECT_TRUE(reader.HasParseError());
+ EXPECT_EQ(kParseErrorObjectMissName, r.Code());
+ EXPECT_EQ(95u, r.Offset());
+ }
+}
+
+TEST(Reader, MultipleTrailingCommaErrors) {
+ TestMultipleTrailingCommaErrors<kParseNoFlags>();
+}
+
+TEST(Reader, MultipleTrailingCommaErrorsIterative) {
+ TestMultipleTrailingCommaErrors<kParseIterativeFlag>();
+}
+
+template <unsigned extraFlags>
+void TestEmptyExceptForCommaErrors() {
+ // not allowed even with trailing commas enabled; the
+ // trailing comma must follow a value.
+ {
+ StringStream s("[,]");
+ ParseArrayHandler<3> h;
+ Reader reader;
+ ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
+ EXPECT_TRUE(reader.HasParseError());
+ EXPECT_EQ(kParseErrorValueInvalid, r.Code());
+ EXPECT_EQ(1u, r.Offset());
+ }
+ {
+ StringStream s("{,}");
+ ParseObjectHandler h;
+ Reader reader;
+ ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
+ EXPECT_TRUE(reader.HasParseError());
+ EXPECT_EQ(kParseErrorObjectMissName, r.Code());
+ EXPECT_EQ(1u, r.Offset());
+ }
+}
+
+TEST(Reader, EmptyExceptForCommaErrors) {
+ TestEmptyExceptForCommaErrors<kParseNoFlags>();
+}
+
+TEST(Reader, EmptyExceptForCommaErrorsIterative) {
+ TestEmptyExceptForCommaErrors<kParseIterativeFlag>();
+}
+
+template <unsigned extraFlags>
+void TestTrailingCommaHandlerTermination() {
+ {
+ HandlerTerminateAtEndArray h;
+ Reader reader;
+ StringStream s("[1,2,3,]");
+ ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
+ EXPECT_TRUE(reader.HasParseError());
+ EXPECT_EQ(kParseErrorTermination, r.Code());
+ EXPECT_EQ(7u, r.Offset());
+ }
+ {
+ HandlerTerminateAtEndObject h;
+ Reader reader;
+ StringStream s("{\"t\": true, \"f\": false,}");
+ ParseResult r = reader.Parse<extraFlags|kParseTrailingCommasFlag>(s, h);
+ EXPECT_TRUE(reader.HasParseError());
+ EXPECT_EQ(kParseErrorTermination, r.Code());
+ EXPECT_EQ(23u, r.Offset());
+ }
+}
+
+TEST(Reader, TrailingCommaHandlerTermination) {
+ TestTrailingCommaHandlerTermination<kParseNoFlags>();
+}
+
+TEST(Reader, TrailingCommaHandlerTerminationIterative) {
+ TestTrailingCommaHandlerTermination<kParseIterativeFlag>();
}
#ifdef __GNUC__