Commit e3c4b339 authored by thebusytypist's avatar thebusytypist

Add unittests for state transition.

parent 692904b7
...@@ -799,7 +799,7 @@ private: ...@@ -799,7 +799,7 @@ private:
cIterativeParsingTokenCount cIterativeParsingTokenCount
}; };
IterativeParsingToken GuessToken(Ch c) { IterativeParsingToken Tokenize(Ch c) {
switch (c) { switch (c) {
case '[': return IterativeParsingLeftBracketToken; case '[': return IterativeParsingLeftBracketToken;
case ']': return IterativeParsingRightBracketToken; case ']': return IterativeParsingRightBracketToken;
...@@ -815,7 +815,7 @@ private: ...@@ -815,7 +815,7 @@ private:
} }
} }
IterativeParsingState Deduce(IterativeParsingState state, IterativeParsingToken token) { IterativeParsingState Predict(IterativeParsingState state, IterativeParsingToken token) {
// current state x one lookahead token -> new state // current state x one lookahead token -> new state
static const IterativeParsingState G[cIterativeParsingStateCount][cIterativeParsingTokenCount] = { static const IterativeParsingState G[cIterativeParsingStateCount][cIterativeParsingTokenCount] = {
// Start // Start
...@@ -1127,8 +1127,8 @@ private: ...@@ -1127,8 +1127,8 @@ private:
SkipWhitespace(is); SkipWhitespace(is);
while (is.Peek() != '\0') { while (is.Peek() != '\0') {
IterativeParsingToken t = GuessToken(is.Peek()); IterativeParsingToken t = Tokenize(is.Peek());
IterativeParsingState n = Deduce(state, t); IterativeParsingState n = Predict(state, t);
IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler); IterativeParsingState d = Transit<parseFlags>(state, t, n, is, handler);
if (d == IterativeParsingErrorState) { if (d == IterativeParsingErrorState) {
......
...@@ -730,6 +730,147 @@ TEST(Reader, IterativeParsing_ErrorHandling) { ...@@ -730,6 +730,147 @@ TEST(Reader, IterativeParsing_ErrorHandling) {
TESTERRORHANDLING("[1 2 3]", kParseErrorArrayMissCommaOrSquareBracket); TESTERRORHANDLING("[1 2 3]", kParseErrorArrayMissCommaOrSquareBracket);
} }
// Test iterative parsing.
template<typename Encoding = UTF8<> >
struct IterativeParsingReaderHandler {
typedef typename Encoding::Ch Ch;
IterativeParsingReaderHandler() :
IsNullTriggered(false),
IsBoolTriggered(false),
IsIntTriggered(false),
IsUintTriggered(false),
IsInt64Triggered(false),
IsUint64Triggered(false),
IsDoubleTriggered(false),
IsStringTriggered(false),
IsStartObjectTriggered(false),
IsEndObjectTriggered(false),
MemberCount(0),
IsStartArrayTriggered(false),
ElementCount(0) {
}
bool IsNullTriggered;
void Null() { IsNullTriggered = true; }
bool IsBoolTriggered;
void Bool(bool) { IsBoolTriggered = true; }
bool IsIntTriggered;
void Int(int) { IsIntTriggered = true; }
bool IsUintTriggered;
void Uint(unsigned) { IsUintTriggered = true; }
bool IsInt64Triggered;
void Int64(int64_t) { IsInt64Triggered = true; }
bool IsUint64Triggered;
void Uint64(uint64_t) { IsUint64Triggered = true; }
bool IsDoubleTriggered;
void Double(double) { IsDoubleTriggered = true; }
bool IsStringTriggered;
void String(const Ch*, SizeType, bool) { IsStringTriggered = true; }
bool IsStartObjectTriggered;
void StartObject() { IsStartObjectTriggered = true; }
bool IsEndObjectTriggered;
SizeType MemberCount;
void EndObject(SizeType c) { IsEndObjectTriggered = true; MemberCount = c; }
bool IsStartArrayTriggered;
void StartArray() { IsStartArrayTriggered = true; }
bool IsEndArrayTriggered;
SizeType ElementCount;
void EndArray(SizeType c) { IsEndArrayTriggered = true; ElementCount = c; }
};
TEST(Reader, IterativeParsing_StateTransition_Start) {
// Start->ArrayInitial
{
IterativeParsingReaderHandler<> handler;
Reader reader;
StringStream is("[");
Reader::IterativeParsingState n = reader.Predict(Reader::IterativeParsingStartState, Reader::IterativeParsingLeftBracketToken);
Reader::IterativeParsingState d = reader.Transit<kParseIterativeFlag>(Reader::IterativeParsingStartState, Reader::IterativeParsingLeftBracketToken, n, is, handler);
EXPECT_FALSE(reader.HasParseError());
EXPECT_EQ(Reader::IterativeParsingArrayInitialState, d);
EXPECT_TRUE(handler.IsStartArrayTriggered);
}
// Start->ObjectInitial
{
IterativeParsingReaderHandler<> handler;
Reader reader;
StringStream is("{");
Reader::IterativeParsingState n = reader.Predict(Reader::IterativeParsingStartState, Reader::IterativeParsingLeftCurlyBracketToken);
Reader::IterativeParsingState d = reader.Transit<kParseIterativeFlag>(Reader::IterativeParsingStartState, Reader::IterativeParsingLeftCurlyBracketToken, n, is, handler);
EXPECT_FALSE(reader.HasParseError());
EXPECT_EQ(Reader::IterativeParsingObjectInitialState, d);
EXPECT_TRUE(handler.IsStartObjectTriggered);
}
}
TEST(Reader, IterativeParsing_StateTransition_ObjectInitial) {
// ObjectInitial -> ObjectFinish -> Finish
{
IterativeParsingReaderHandler<> handler;
Reader reader;
StringStream is("{}");
Reader::IterativeParsingState s = reader.Transit<kParseIterativeFlag>(
Reader::IterativeParsingStartState,
Reader::IterativeParsingLeftCurlyBracketToken,
Reader::IterativeParsingObjectInitialState,
is, handler);
EXPECT_EQ(Reader::IterativeParsingObjectInitialState, s);
Reader::IterativeParsingState d = reader.Transit<kParseIterativeFlag>(
s,
Reader::IterativeParsingRightCurlyBracketToken,
Reader::IterativeParsingObjectFinishState,
is, handler);
EXPECT_FALSE(reader.HasParseError());
EXPECT_EQ(Reader::IterativeParsingFinishState, d);
EXPECT_TRUE(handler.IsEndObjectTriggered);
EXPECT_EQ(0, handler.MemberCount);
}
// ObjectInitial -> MemberKey
{
IterativeParsingReaderHandler<> handler;
Reader reader;
StringStream is("{\"key\"");
Reader::IterativeParsingState s = reader.Transit<kParseIterativeFlag>(
Reader::IterativeParsingStartState,
Reader::IterativeParsingLeftCurlyBracketToken,
Reader::IterativeParsingObjectInitialState,
is, handler);
EXPECT_EQ(Reader::IterativeParsingObjectInitialState, s);
Reader::IterativeParsingState d = reader.Transit<kParseIterativeFlag>(
s,
Reader::IterativeParsingStringToken,
Reader::IterativeParsingMemberKeyState,
is, handler);
EXPECT_FALSE(reader.HasParseError());
EXPECT_EQ(Reader::IterativeParsingMemberKeyState, d);
EXPECT_TRUE(handler.IsStringTriggered);
}
}
#ifdef __GNUC__ #ifdef __GNUC__
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment