Skip to content

Commit 82a423d

Browse files
StilesCrisisStilesCrisis
authored andcommitted
Added unit test for pull parsing
New unit test which ensures that IterativeParseNext always generates exactly one element at a time, and that calling IterativeParseNext on a complete document is harmless and generates zero events.
1 parent 116f659 commit 82a423d

File tree

1 file changed

+73
-28
lines changed

1 file changed

+73
-28
lines changed

test/unittest/readertest.cpp

Lines changed: 73 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,22 +1157,22 @@ template<typename Encoding = UTF8<> >
11571157
struct IterativeParsingReaderHandler {
11581158
typedef typename Encoding::Ch Ch;
11591159

1160-
const static int LOG_NULL = -1;
1161-
const static int LOG_BOOL = -2;
1162-
const static int LOG_INT = -3;
1163-
const static int LOG_UINT = -4;
1164-
const static int LOG_INT64 = -5;
1165-
const static int LOG_UINT64 = -6;
1166-
const static int LOG_DOUBLE = -7;
1167-
const static int LOG_STRING = -8;
1168-
const static int LOG_STARTOBJECT = -9;
1169-
const static int LOG_KEY = -10;
1170-
const static int LOG_ENDOBJECT = -11;
1171-
const static int LOG_STARTARRAY = -12;
1172-
const static int LOG_ENDARRAY = -13;
1160+
const static uint32_t LOG_NULL = 0x10000000;
1161+
const static uint32_t LOG_BOOL = 0x20000000;
1162+
const static uint32_t LOG_INT = 0x30000000;
1163+
const static uint32_t LOG_UINT = 0x40000000;
1164+
const static uint32_t LOG_INT64 = 0x50000000;
1165+
const static uint32_t LOG_UINT64 = 0x60000000;
1166+
const static uint32_t LOG_DOUBLE = 0x70000000;
1167+
const static uint32_t LOG_STRING = 0x80000000;
1168+
const static uint32_t LOG_STARTOBJECT = 0x90000000;
1169+
const static uint32_t LOG_KEY = 0xA0000000;
1170+
const static uint32_t LOG_ENDOBJECT = 0xB0000000;
1171+
const static uint32_t LOG_STARTARRAY = 0xC0000000;
1172+
const static uint32_t LOG_ENDARRAY = 0xD0000000;
11731173

11741174
const static size_t LogCapacity = 256;
1175-
int Logs[LogCapacity];
1175+
uint32_t Logs[LogCapacity];
11761176
size_t LogCount;
11771177

11781178
IterativeParsingReaderHandler() : LogCount(0) {
@@ -1202,17 +1202,17 @@ struct IterativeParsingReaderHandler {
12021202

12031203
bool EndObject(SizeType c) {
12041204
RAPIDJSON_ASSERT(LogCount < LogCapacity);
1205-
Logs[LogCount++] = LOG_ENDOBJECT;
1206-
Logs[LogCount++] = static_cast<int>(c);
1205+
RAPIDJSON_ASSERT((static_cast<uint32_t>(c) & 0xF0000000) == 0);
1206+
Logs[LogCount++] = LOG_ENDOBJECT | static_cast<uint32_t>(c);
12071207
return true;
12081208
}
12091209

12101210
bool StartArray() { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_STARTARRAY; return true; }
12111211

12121212
bool EndArray(SizeType c) {
12131213
RAPIDJSON_ASSERT(LogCount < LogCapacity);
1214-
Logs[LogCount++] = LOG_ENDARRAY;
1215-
Logs[LogCount++] = static_cast<int>(c);
1214+
RAPIDJSON_ASSERT((static_cast<uint32_t>(c) & 0xF0000000) == 0);
1215+
Logs[LogCount++] = LOG_ENDARRAY | static_cast<uint32_t>(c);
12161216
return true;
12171217
}
12181218
};
@@ -1228,22 +1228,22 @@ TEST(Reader, IterativeParsing_General) {
12281228
EXPECT_FALSE(r.IsError());
12291229
EXPECT_FALSE(reader.HasParseError());
12301230

1231-
int e[] = {
1231+
uint32_t e[] = {
12321232
handler.LOG_STARTARRAY,
12331233
handler.LOG_INT,
12341234
handler.LOG_STARTOBJECT,
12351235
handler.LOG_KEY,
12361236
handler.LOG_STARTARRAY,
12371237
handler.LOG_INT,
12381238
handler.LOG_INT,
1239-
handler.LOG_ENDARRAY, 2,
1240-
handler.LOG_ENDOBJECT, 1,
1239+
handler.LOG_ENDARRAY | 2,
1240+
handler.LOG_ENDOBJECT | 1,
12411241
handler.LOG_NULL,
12421242
handler.LOG_BOOL,
12431243
handler.LOG_BOOL,
12441244
handler.LOG_STRING,
12451245
handler.LOG_DOUBLE,
1246-
handler.LOG_ENDARRAY, 7
1246+
handler.LOG_ENDARRAY | 7
12471247
};
12481248

12491249
EXPECT_EQ(sizeof(e) / sizeof(int), handler.LogCount);
@@ -1265,20 +1265,20 @@ TEST(Reader, IterativeParsing_Count) {
12651265
EXPECT_FALSE(r.IsError());
12661266
EXPECT_FALSE(reader.HasParseError());
12671267

1268-
int e[] = {
1268+
uint32_t e[] = {
12691269
handler.LOG_STARTARRAY,
12701270
handler.LOG_STARTOBJECT,
1271-
handler.LOG_ENDOBJECT, 0,
1271+
handler.LOG_ENDOBJECT | 0,
12721272
handler.LOG_STARTOBJECT,
12731273
handler.LOG_KEY,
12741274
handler.LOG_INT,
1275-
handler.LOG_ENDOBJECT, 1,
1275+
handler.LOG_ENDOBJECT | 1,
12761276
handler.LOG_STARTARRAY,
12771277
handler.LOG_INT,
1278-
handler.LOG_ENDARRAY, 1,
1278+
handler.LOG_ENDARRAY | 1,
12791279
handler.LOG_STARTARRAY,
1280-
handler.LOG_ENDARRAY, 0,
1281-
handler.LOG_ENDARRAY, 4
1280+
handler.LOG_ENDARRAY | 0,
1281+
handler.LOG_ENDARRAY | 4
12821282
};
12831283

12841284
EXPECT_EQ(sizeof(e) / sizeof(int), handler.LogCount);
@@ -1289,6 +1289,51 @@ TEST(Reader, IterativeParsing_Count) {
12891289
}
12901290
}
12911291

1292+
TEST(Reader, IterativePullParsing_General) {
1293+
{
1294+
IterativeParsingReaderHandler<> handler;
1295+
uint32_t e[] = {
1296+
handler.LOG_STARTARRAY,
1297+
handler.LOG_INT,
1298+
handler.LOG_STARTOBJECT,
1299+
handler.LOG_KEY,
1300+
handler.LOG_STARTARRAY,
1301+
handler.LOG_INT,
1302+
handler.LOG_INT,
1303+
handler.LOG_ENDARRAY | 2,
1304+
handler.LOG_ENDOBJECT | 1,
1305+
handler.LOG_NULL,
1306+
handler.LOG_BOOL,
1307+
handler.LOG_BOOL,
1308+
handler.LOG_STRING,
1309+
handler.LOG_DOUBLE,
1310+
handler.LOG_ENDARRAY | 7
1311+
};
1312+
1313+
StringStream is("[1, {\"k\": [1, 2]}, null, false, true, \"string\", 1.2]");
1314+
Reader reader;
1315+
1316+
reader.IterativeParseInit();
1317+
while (!reader.IterativeParseComplete()) {
1318+
size_t oldLogCount = handler.LogCount;
1319+
EXPECT_TRUE(oldLogCount < sizeof(e) / sizeof(int)) << "overrun";
1320+
1321+
EXPECT_TRUE(reader.IterativeParseNext<kParseDefaultFlags>(is, handler)) << "parse fail";
1322+
EXPECT_EQ(handler.LogCount, oldLogCount + 1) << "handler should be invoked exactly once each time";
1323+
EXPECT_EQ(e[oldLogCount], handler.Logs[oldLogCount]) << "wrong event returned";
1324+
}
1325+
1326+
EXPECT_FALSE(reader.HasParseError());
1327+
EXPECT_EQ(sizeof(e) / sizeof(int), handler.LogCount) << "handler invoked wrong number of times";
1328+
1329+
// The handler should not be invoked when the JSON has been fully read, but it should not fail
1330+
size_t oldLogCount = handler.LogCount;
1331+
EXPECT_TRUE(reader.IterativeParseNext<kParseDefaultFlags>(is, handler)) << "parse-next past complete is allowed";
1332+
EXPECT_EQ(handler.LogCount, oldLogCount) << "parse-next past complete should not invoke handler";
1333+
EXPECT_FALSE(reader.HasParseError()) << "parse-next past complete should not generate parse error";
1334+
}
1335+
}
1336+
12921337
// Test iterative parsing on kParseErrorTermination.
12931338
struct HandlerTerminateAtStartObject : public IterativeParsingReaderHandler<> {
12941339
bool StartObject() { return false; }

0 commit comments

Comments
 (0)