diff options
| author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-03-03 14:34:14 +0100 | 
|---|---|---|
| committer | Andreas Stöckel <andreas@somweyr.de> | 2015-03-03 14:34:14 +0100 | 
| commit | fb8d4cdf01909b61e4e5d0806ec6de178ff0058c (patch) | |
| tree | 8a38d4d6ab5966c0ce0e8f62c92b24c93b42d031 /test | |
| parent | 21aa94db203c0b1bcab18bc4858edcdb2afc894d (diff) | |
Finished stack and adapted all unit tests
Diffstat (limited to 'test')
| -rw-r--r-- | test/core/parser/stack/StackTest.cpp | 772 | 
1 files changed, 443 insertions, 329 deletions
| diff --git a/test/core/parser/stack/StackTest.cpp b/test/core/parser/stack/StackTest.cpp index 8f6c4df..a831c32 100644 --- a/test/core/parser/stack/StackTest.cpp +++ b/test/core/parser/stack/StackTest.cpp @@ -70,6 +70,16 @@ struct Tracker {  	bool fieldStartResult;  	bool dataResult; +	Variant::mapType startCommandArgs; +	Variant::mapType startAnnotationArgs; + +	bool fieldStartReturnValue; +	size_t fieldStartIdx; +	bool fieldStartIsDefault; +	bool fieldStartSetIsDefault; + +	Variant dataData; +  	Tracker() { reset(); }  	void reset() @@ -89,6 +99,15 @@ struct Tracker {  		endTokenResult = Handler::EndTokenResult::ENDED_THIS;  		fieldStartResult = true;  		dataResult = true; + +		startCommandArgs = Variant::mapType{}; +		startAnnotationArgs = Variant::mapType{}; + +		fieldStartIdx = 0; +		fieldStartIsDefault = false; +		fieldStartSetIsDefault = false; + +		dataData = Variant{};  	}  	void expect(int startCommandCount, int endCount, int fieldStartCount, @@ -115,13 +134,20 @@ private:  public:  	bool startCommand(Variant::mapType &args) override  	{ +		tracker.startCommandArgs = args;  		tracker.startCommandCount++; +		if (!tracker.startCommandResult) { +			logger().error( +			    "TestHandler was told not to allow a command start. " +			    "TestHandler always obeys its master."); +		}  		return tracker.startCommandResult;  	}  	bool startAnnotation(Variant::mapType &args,  	                     AnnotationType annotationType) override  	{ +		tracker.startAnnotationArgs = args;  		tracker.startAnnotationCount++;  		return tracker.startAnnotationResult;  	} @@ -142,6 +168,11 @@ public:  	bool fieldStart(bool &isDefault, size_t fieldIdx) override  	{ +		tracker.fieldStartIsDefault = isDefault; +		tracker.fieldStartIdx = fieldIdx; +		if (tracker.fieldStartSetIsDefault) { +			isDefault = true; +		}  		tracker.fieldStartCount++;  		return tracker.fieldStartResult;  	} @@ -150,6 +181,7 @@ public:  	bool data() override  	{ +		tracker.dataData = readData();  		tracker.dataCount++;  		return tracker.dataResult;  	} @@ -199,456 +231,518 @@ TEST(Stack, basicTest)  		EXPECT_EQ("", s.currentCommandName());  		EXPECT_EQ(&States::None, &s.currentState()); -		s.commandStart("document", {}, true); +		s.commandStart("document", {});  		s.fieldStart(true);  		s.data("test1");  		EXPECT_EQ("document", s.currentCommandName());  		EXPECT_EQ(&States::Document, &s.currentState()); -		tracker.expect(1, 0, 1, 0, 1);  // scc, ec, fsc, fse, dc, sac, stc, etc +		tracker.expect(1, 0, 1, 0, 1);  // scc, ec, fsc, fec, dc, sac, stc, etc -		s.commandStart("body", {}, true); +		s.commandStart("body", {});  		s.fieldStart(true);  		s.data("test2");  		EXPECT_EQ("body", s.currentCommandName());  		EXPECT_EQ(&States::Body, &s.currentState()); -		tracker.expect(2, 0, 2, 0, 2);  // scc, ec, fsc, fse, dc, sac, stc, etc +		tracker.expect(2, 0, 2, 0, 2);  // scc, ec, fsc, fec, dc, sac, stc, etc -		s.commandStart("inner", {}, true); +		s.commandStart("inner", {});  		s.fieldStart(true);  		EXPECT_EQ("inner", s.currentCommandName());  		EXPECT_EQ(&States::BodyChildren, &s.currentState());  		s.fieldEnd(); -		tracker.expect(3, 0, 3, 1, 2);  // scc, ec, fsc, fse, dc, sac, stc, etc +		tracker.expect(3, 0, 3, 1, 2);  // scc, ec, fsc, fec, dc, sac, stc, etc  		s.fieldEnd();  		EXPECT_EQ("body", s.currentCommandName());  		EXPECT_EQ(&States::Body, &s.currentState()); -		tracker.expect(3, 1, 3, 2, 2);  // scc, ec, fsc, fse, dc, sac, stc, etc +		tracker.expect(3, 1, 3, 2, 2);  // scc, ec, fsc, fec, dc, sac, stc, etc -		s.commandStart("body", {}, true); +		s.commandStart("body", {});  		EXPECT_EQ("body", s.currentCommandName());  		EXPECT_EQ(&States::Body, &s.currentState()); -		tracker.expect(4, 2, 3, 2, 2);  // scc, ec, fsc, fse, dc, sac, stc, etc +		tracker.expect(4, 2, 3, 2, 2);  // scc, ec, fsc, fec, dc, sac, stc, etc  		s.fieldStart(true);  		s.data("test3");  		EXPECT_EQ("body", s.currentCommandName());  		EXPECT_EQ(&States::Body, &s.currentState());  		s.fieldEnd(); -		tracker.expect(4, 2, 4, 3, 3);  // scc, ec, fsc, fse, dc, sac, stc, etc +		tracker.expect(4, 2, 4, 3, 3);  // scc, ec, fsc, fec, dc, sac, stc, etc  		EXPECT_EQ("body", s.currentCommandName());  		EXPECT_EQ(&States::Body, &s.currentState());  		s.fieldEnd(); -		tracker.expect(4, 3, 4, 4, 3);  // scc, ec, fsc, fse, dc, sac, stc, etc +		tracker.expect(4, 3, 4, 4, 3);  // scc, ec, fsc, fec, dc, sac, stc, etc  		EXPECT_EQ("document", s.currentCommandName());  		EXPECT_EQ(&States::Document, &s.currentState());  	} -	tracker.expect(4, 4, 4, 4, 3);  // scc, ec, fsc, fse, dc, sac, stc, etc +	tracker.expect(4, 4, 4, 4, 3);  // scc, ec, fsc, fec, dc, sac, stc, etc  	ASSERT_FALSE(logger.hasError());  } -/* + +TEST(Stack, basicTestRangeCommands) +{ +	tracker.reset(); +	logger.reset(); +	{ +		Stack s{parser, env.context, States::TestHandlers}; + +		EXPECT_EQ("", s.currentCommandName()); +		EXPECT_EQ(&States::None, &s.currentState()); + +		s.commandStart("document", {}, true); +		EXPECT_EQ("document", s.currentCommandName()); +		EXPECT_EQ(&States::Document, &s.currentState()); +		tracker.expect(1, 0, 0, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc + +		s.data("test1"); +		tracker.expect(1, 0, 1, 0, 1);  // scc, ec, fsc, fec, dc, sac, stc, etc + +		s.commandStart("body", {}, true); +		tracker.expect(2, 0, 1, 0, 1);  // scc, ec, fsc, fec, dc, sac, stc, etc +		s.data("test2"); +		tracker.expect(2, 0, 2, 0, 2);  // scc, ec, fsc, fec, dc, sac, stc, etc +		EXPECT_EQ("body", s.currentCommandName()); +		EXPECT_EQ(&States::Body, &s.currentState()); + +		s.commandStart("inner", {}, true); +		tracker.expect(3, 0, 2, 0, 2);  // scc, ec, fsc, fec, dc, sac, stc, etc +		EXPECT_EQ("inner", s.currentCommandName()); +		EXPECT_EQ(&States::BodyChildren, &s.currentState()); +		s.rangeEnd(); +		tracker.expect(3, 1, 3, 1, 2);  // scc, ec, fsc, fec, dc, sac, stc, etc +		EXPECT_EQ("body", s.currentCommandName()); +		EXPECT_EQ(&States::Body, &s.currentState()); +		s.rangeEnd(); +		tracker.expect(3, 2, 3, 2, 2);  // scc, ec, fsc, fec, dc, sac, stc, etc + +		s.commandStart("body", {}, true); +		EXPECT_EQ("body", s.currentCommandName()); +		EXPECT_EQ(&States::Body, &s.currentState()); +		tracker.expect(4, 2, 3, 2, 2);  // scc, ec, fsc, fse, dc, sac, stc, etc +		s.fieldStart(true); +		tracker.expect(4, 2, 4, 2, 2);  // scc, ec, fsc, fec, dc, sac, stc, etc +		s.data("test3"); +		tracker.expect(4, 2, 4, 2, 3);  // scc, ec, fsc, fec, dc, sac, stc, etc +		EXPECT_EQ("body", s.currentCommandName()); +		EXPECT_EQ(&States::Body, &s.currentState()); +		s.fieldEnd(); +		tracker.expect(4, 2, 4, 3, 3);  // scc, ec, fsc, fec, dc, sac, stc, etc +		EXPECT_EQ("body", s.currentCommandName()); +		EXPECT_EQ(&States::Body, &s.currentState()); +		s.rangeEnd(); +		tracker.expect(4, 3, 4, 3, 3);  // scc, ec, fsc, fec, dc, sac, stc, etc + +		EXPECT_EQ("document", s.currentCommandName()); +		EXPECT_EQ(&States::Document, &s.currentState()); +		s.rangeEnd(); +		tracker.expect(4, 4, 4, 4, 3);  // scc, ec, fsc, fec, dc, sac, stc, etc +	} +	tracker.expect(4, 4, 4, 4, 3);  // scc, ec, fsc, fec, dc, sac, stc, etc +	ASSERT_FALSE(logger.hasError()); +} +  TEST(Stack, errorInvalidCommands)  { -    Stack s{env.context, States::TestHandlers}; -    tracker.reset(); -    EXPECT_THROW(s.command("body", {}), LoggableException); -    s.command("document", {}); -    s.fieldStart(true); -    EXPECT_THROW(s.command("document", {}), LoggableException); -    s.command("empty", {}); -    s.fieldStart(true); -    EXPECT_THROW(s.command("body", {}), LoggableException); -    s.command("special", {}); -    s.fieldStart(true); -    s.fieldEnd(); -    s.fieldEnd(); -    s.fieldEnd(); +	Stack s{parser, env.context, States::TestHandlers}; +	tracker.reset(); +	EXPECT_THROW(s.commandStart("body", {}), LoggableException); +	s.commandStart("document", {}); +	s.fieldStart(true); +	EXPECT_THROW(s.commandStart("document", {}), LoggableException); +	s.commandStart("empty", {}); +	s.fieldStart(true); +	EXPECT_THROW(s.commandStart("body", {}), LoggableException); +	s.commandStart("special", {}); +	s.fieldStart(true); +	s.fieldEnd(); +	s.fieldEnd(); +	s.fieldEnd(); -    logger.reset(); -    s.fieldEnd(); -    ASSERT_TRUE(logger.hasError()); +	logger.reset(); +	s.fieldEnd(); +	ASSERT_TRUE(logger.hasError()); -    EXPECT_THROW(s.data("test"), LoggableException); -    EXPECT_EQ(&States::None, &s.currentState()); +	EXPECT_THROW(s.data("test"), LoggableException); +	EXPECT_EQ(&States::None, &s.currentState());  }  TEST(Stack, validation)  { -    Stack s{env.context, States::TestHandlers}; -    tracker.reset(); -    logger.reset(); +	Stack s{parser, env.context, States::TestHandlers}; +	tracker.reset(); +	logger.reset(); -    s.command("arguments", {}); -    EXPECT_TRUE(logger.hasError()); -    s.fieldStart(true); -    s.fieldEnd(); +	s.commandStart("arguments", {}); +	EXPECT_TRUE(logger.hasError()); +	s.fieldStart(true); +	s.fieldEnd(); -    logger.reset(); -    s.command("arguments", {{"a", 5}}); -    EXPECT_TRUE(logger.hasError()); -    s.fieldStart(true); -    s.fieldEnd(); +	logger.reset(); +	s.commandStart("arguments", {{"a", 5}}, false); +	EXPECT_TRUE(logger.hasError()); +	s.fieldStart(true); +	s.fieldEnd(); -    logger.reset(); -    s.command("arguments", {{"a", 5}, {"b", "test"}}); -    EXPECT_FALSE(logger.hasError()); -    s.fieldStart(true); -    s.fieldEnd(); +	logger.reset(); +	s.commandStart("arguments", {{"a", 5}, {"b", "test"}}, false); +	EXPECT_FALSE(logger.hasError()); +	s.fieldStart(true); +	s.fieldEnd();  }  TEST(Stack, invalidCommandName)  { -    tracker.reset(); -    logger.reset(); +	tracker.reset(); +	logger.reset(); -    Stack s{env.context, States::AnyHandlers}; -    s.command("a", {}); -    tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -    s.fieldStart(true); -    s.fieldEnd(); -    tracker.expect(1, 0, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc - -    s.command("a_", {}); -    tracker.expect(2, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -    s.fieldStart(true); -    s.fieldEnd(); -    tracker.expect(2, 1, 2, 2, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc - -    s.command("a_:b", {}); -    tracker.expect(3, 2, 2, 2, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -    s.fieldStart(true); -    s.fieldEnd(); -    tracker.expect(3, 2, 3, 3, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc - -    ASSERT_THROW(s.command("_a", {}), LoggableException); -    tracker.expect(3, 3, 3, 3, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc - -    ASSERT_THROW(s.command("a:", {}), LoggableException); -    tracker.expect(3, 3, 3, 3, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc - -    ASSERT_THROW(s.command("a:_b", {}), LoggableException); -    tracker.expect(3, 3, 3, 3, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	Stack s{parser, env.context, States::AnyHandlers}; +	s.commandStart("a", {}); +	tracker.expect(1, 0, 0, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +	s.fieldStart(true); +	s.fieldEnd(); +	tracker.expect(1, 0, 1, 1, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc + +	s.commandStart("a_", {}); +	tracker.expect(2, 1, 1, 1, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +	s.fieldStart(true); +	s.fieldEnd(); +	tracker.expect(2, 1, 2, 2, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc + +	s.commandStart("a_:b", {}); +	tracker.expect(3, 2, 2, 2, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +	s.fieldStart(true); +	s.fieldEnd(); +	tracker.expect(3, 2, 3, 3, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc + +	ASSERT_THROW(s.commandStart("_a", {}), LoggableException); +	tracker.expect(3, 3, 3, 3, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc + +	ASSERT_THROW(s.commandStart("a:", {}), LoggableException); +	tracker.expect(3, 3, 3, 3, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc + +	ASSERT_THROW(s.commandStart("a:_b", {}), LoggableException); +	tracker.expect(3, 3, 3, 3, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc  }  TEST(Stack, multipleFields)  { -    tracker.reset(); -    logger.reset(); -    { -        Stack s{env.context, States::AnyHandlers}; +	tracker.reset(); +	logger.reset(); +	{ +		Stack s{parser, env.context, States::AnyHandlers}; -        s.command("a", {{"a", false}}); -        tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -        EXPECT_EQ("a", s.currentCommandName()); -        EXPECT_EQ(Variant::mapType({{"a", false}}), tracker.startArgs); +		s.commandStart("a", {{"a", false}}, false); +		tracker.expect(1, 0, 0, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +		EXPECT_EQ("a", s.currentCommandName()); +		EXPECT_EQ(Variant::mapType({{"a", false}}), tracker.startCommandArgs); -        s.fieldStart(false); -        tracker.expect(1, 0, 1, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -        EXPECT_FALSE(tracker.fieldStartIsDefault); -        EXPECT_EQ(0U, tracker.fieldStartIdx); +		s.fieldStart(false); +		tracker.expect(1, 0, 1, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +		EXPECT_FALSE(tracker.fieldStartIsDefault); +		EXPECT_EQ(0U, tracker.fieldStartIdx); -        s.data("test"); -        tracker.expect(1, 0, 1, 0, 0, 0, 1);  // sc, ec, fsc, fse, asc, aec, dc -        EXPECT_EQ("test", tracker.dataData.text().asString()); +		s.data("test"); +		tracker.expect(1, 0, 1, 0, 1);  // scc, ec, fsc, fec, dc, sac, stc, etc +		EXPECT_EQ("test", tracker.dataData.asString()); -        s.fieldEnd(); -        tracker.expect(1, 0, 1, 1, 0, 0, 1);  // sc, ec, fsc, fse, asc, aec, dc +		s.fieldEnd(); +		tracker.expect(1, 0, 1, 1, 1);  // scc, ec, fsc, fec, dc, sac, stc, etc -        s.fieldStart(false); -        tracker.expect(1, 0, 2, 1, 0, 0, 1);  // sc, ec, fsc, fse, asc, aec, dc -        EXPECT_FALSE(tracker.fieldStartIsDefault); -        EXPECT_EQ(1U, tracker.fieldStartIdx); +		s.fieldStart(false); +		tracker.expect(1, 0, 2, 1, 1);  // scc, ec, fsc, fec, dc, sac, stc, etc +		EXPECT_FALSE(tracker.fieldStartIsDefault); +		EXPECT_EQ(1U, tracker.fieldStartIdx); -        s.data("test2"); -        tracker.expect(1, 0, 2, 1, 0, 0, 2);  // sc, ec, fsc, fse, asc, aec, dc -        EXPECT_EQ("test2", tracker.dataData.text().asString()); +		s.data("test2"); +		tracker.expect(1, 0, 2, 1, 2);  // scc, ec, fsc, fec, dc, sac, stc, etc +		EXPECT_EQ("test2", tracker.dataData.asString()); -        s.fieldEnd(); -        tracker.expect(1, 0, 2, 2, 0, 0, 2);  // sc, ec, fsc, fse, asc, aec, dc +		s.fieldEnd(); +		tracker.expect(1, 0, 2, 2, 2);  // scc, ec, fsc, fec, dc, sac, stc, etc -        s.fieldStart(true); -        tracker.expect(1, 0, 3, 2, 0, 0, 2);  // sc, ec, fsc, fse, asc, aec, dc -        EXPECT_TRUE(tracker.fieldStartIsDefault); -        EXPECT_EQ(2U, tracker.fieldStartIdx); +		s.fieldStart(true); +		tracker.expect(1, 0, 3, 2, 2);  // scc, ec, fsc, fec, dc, sac, stc, etc +		EXPECT_TRUE(tracker.fieldStartIsDefault); +		EXPECT_EQ(2U, tracker.fieldStartIdx); -        s.data("test3"); -        tracker.expect(1, 0, 3, 2, 0, 0, 3);  // sc, ec, fsc, fse, asc, aec, dc -        EXPECT_EQ("test3", tracker.dataData.text().asString()); +		s.data("test3"); +		tracker.expect(1, 0, 3, 2, 3);  // scc, ec, fsc, fec, dc, sac, stc, etc +		EXPECT_EQ("test3", tracker.dataData.asString()); -        s.fieldEnd(); -        tracker.expect(1, 0, 3, 3, 0, 0, 3);  // sc, ec, fsc, fse, asc, aec, dc -    } -    tracker.expect(1, 1, 3, 3, 0, 0, 3);  // sc, ec, fsc, fse, asc, aec, dc -    ASSERT_FALSE(logger.hasError()); +		s.fieldEnd(); +		tracker.expect(1, 0, 3, 3, 3);  // scc, ec, fsc, fec, dc, sac, stc, etc +	} +	tracker.expect(1, 1, 3, 3, 3);  // scc, ec, fsc, fec, dc, sac, stc, etc +	ASSERT_FALSE(logger.hasError());  }  TEST(Stack, implicitDefaultFieldOnNewCommand)  { -    tracker.reset(); -    logger.reset(); -    { -        Stack s{env.context, States::AnyHandlers}; +	tracker.reset(); +	logger.reset(); +	{ +		Stack s{parser, env.context, States::AnyHandlers}; -        s.command("a", {}); -        tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +		s.commandStart("a", {}); +		tracker.expect(1, 0, 0, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc -        s.command("b", {}); -        tracker.expect(2, 0, 1, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -    } -    tracker.expect(2, 2, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -    ASSERT_FALSE(logger.hasError()); +		s.commandStart("b", {}); +		tracker.expect(2, 0, 1, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +	} +	tracker.expect(2, 2, 1, 1, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +	ASSERT_FALSE(logger.hasError());  }  TEST(Stack, implicitDefaultFieldOnNewCommandWithExplicitDefaultField)  { -    tracker.reset(); -    logger.reset(); -    { -        Stack s{env.context, States::AnyHandlers}; +	tracker.reset(); +	logger.reset(); +	{ +		Stack s{parser, env.context, States::AnyHandlers}; -        s.command("a", {}); -        tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -        ASSERT_EQ("a", s.currentCommandName()); +		s.commandStart("a", {}); +		tracker.expect(1, 0, 0, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +		ASSERT_EQ("a", s.currentCommandName()); -        s.command("b", {}); -        tracker.expect(2, 0, 1, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -        ASSERT_EQ("b", s.currentCommandName()); -        s.fieldStart(true); -        s.fieldEnd(); -        tracker.expect(2, 0, 2, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -        ASSERT_EQ("b", s.currentCommandName()); -    } -    tracker.expect(2, 2, 2, 2, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -    ASSERT_FALSE(logger.hasError()); +		s.commandStart("b", {}); +		tracker.expect(2, 0, 1, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +		ASSERT_EQ("b", s.currentCommandName()); +		s.fieldStart(true); +		s.fieldEnd(); +		tracker.expect(2, 0, 2, 1, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +		ASSERT_EQ("b", s.currentCommandName()); +	} +	tracker.expect(2, 2, 2, 2, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +	ASSERT_FALSE(logger.hasError());  }  TEST(Stack, noImplicitDefaultFieldOnIncompatibleCommand)  { -    tracker.reset(); -    logger.reset(); -    { -        Stack s{env.context, States::AnyHandlers}; +	tracker.reset(); +	logger.reset(); +	{ +		Stack s{parser, env.context, States::AnyHandlers}; -        s.command("a", {}); -        tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -        ASSERT_EQ("a", s.currentCommandName()); +		s.commandStart("a", {}); +		tracker.expect(1, 0, 0, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +		ASSERT_EQ("a", s.currentCommandName()); -        tracker.fieldStartResult = false; -        s.command("b", {}); -        tracker.expect(2, 1, 1, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -        ASSERT_EQ("b", s.currentCommandName()); -    } -    tracker.expect(2, 2, 1, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -    ASSERT_FALSE(logger.hasError()); +		tracker.fieldStartResult = false; +		s.commandStart("b", {}); +		tracker.expect(2, 1, 1, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +		ASSERT_EQ("b", s.currentCommandName()); +	} +	tracker.expect(2, 2, 1, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +	ASSERT_FALSE(logger.hasError());  }  TEST(Stack, noImplicitDefaultFieldIfDefaultFieldGiven)  { -    tracker.reset(); -    logger.reset(); -    { -        Stack s{env.context, States::AnyHandlers}; +	tracker.reset(); +	logger.reset(); +	{ +		Stack s{parser, env.context, States::AnyHandlers}; -        s.command("a", {}); -        tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -        ASSERT_EQ("a", s.currentCommandName()); -        s.fieldStart(true); -        tracker.expect(1, 0, 1, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -        ASSERT_EQ("a", s.currentCommandName()); -        s.fieldEnd(); -        tracker.expect(1, 0, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -        ASSERT_EQ("a", s.currentCommandName()); +		s.commandStart("a", {}); +		tracker.expect(1, 0, 0, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +		ASSERT_EQ("a", s.currentCommandName()); +		s.fieldStart(true); +		tracker.expect(1, 0, 1, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +		ASSERT_EQ("a", s.currentCommandName()); +		s.fieldEnd(); +		tracker.expect(1, 0, 1, 1, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +		ASSERT_EQ("a", s.currentCommandName()); -        s.command("b", {}); -        tracker.expect(2, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -        ASSERT_EQ("b", s.currentCommandName()); -    } -    tracker.expect(2, 2, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -    ASSERT_FALSE(logger.hasError()); +		s.commandStart("b", {}); +		tracker.expect(2, 1, 1, 1, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +		ASSERT_EQ("b", s.currentCommandName()); +	} +	tracker.expect(2, 2, 1, 1, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +	ASSERT_FALSE(logger.hasError());  }  TEST(Stack, noEndIfStartFails)  { -    tracker.reset(); -    logger.reset(); -    { -        Stack s{env.context, States::AnyHandlers}; +	tracker.reset(); +	logger.reset(); +	{ +		Stack s{parser, env.context, States::AnyHandlers}; -        s.command("a", {}); -        tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -        ASSERT_EQ("a", s.currentCommandName()); +		s.commandStart("a", {}); +		tracker.expect(1, 0, 0, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +		ASSERT_EQ("a", s.currentCommandName()); -        tracker.startResult = false; -        s.command("b", {}); -        tracker.expect(3, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -        ASSERT_EQ("b", s.currentCommandName()); -    } -    tracker.expect(3, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -    ASSERT_TRUE(logger.hasError()); +		tracker.startCommandResult = false; +		s.commandStart("b", {}); +		tracker.expect(3, 1, 1, 1, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +		EXPECT_EQ(&States::None, &s.currentState()); +	} +	tracker.expect(3, 1, 1, 1, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +	ASSERT_TRUE(logger.hasError());  }  TEST(Stack, implicitDefaultFieldOnData)  { -    tracker.reset(); -    logger.reset(); -    { -        Stack s{env.context, States::AnyHandlers}; +	tracker.reset(); +	logger.reset(); +	{ +		Stack s{parser, env.context, States::AnyHandlers}; -        s.command("a", {}); -        tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +		s.commandStart("a", {}); +		tracker.expect(1, 0, 0, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc -        s.data("test"); -        tracker.expect(1, 0, 1, 0, 0, 0, 1);  // sc, ec, fsc, fse, asc, aec, dc -    } -    tracker.expect(1, 1, 1, 1, 0, 0, 1);  // sc, ec, fsc, fse, asc, aec, dc -    ASSERT_FALSE(logger.hasError()); +		s.data("test"); +		tracker.expect(1, 0, 1, 0, 1);  // scc, ec, fsc, fec, dc, sac, stc, etc +	} +	tracker.expect(1, 1, 1, 1, 1);  // scc, ec, fsc, fec, dc, sac, stc, etc +	ASSERT_FALSE(logger.hasError());  }  TEST(Stack, autoFieldEnd)  { -    tracker.reset(); -    logger.reset(); +	tracker.reset(); +	logger.reset(); -    { -        Stack s{env.context, States::AnyHandlers}; -        s.command("a", {}); -        tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -    } -    tracker.expect(1, 1, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -    ASSERT_FALSE(logger.hasError()); +	{ +		Stack s{parser, env.context, States::AnyHandlers}; +		s.commandStart("a", {}); +		tracker.expect(1, 0, 0, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +	} +	tracker.expect(1, 1, 0, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +	ASSERT_FALSE(logger.hasError());  }  TEST(Stack, autoImplicitFieldEnd)  { -    tracker.reset(); -    logger.reset(); +	tracker.reset(); +	logger.reset(); -    { -        Stack s{env.context, States::AnyHandlers}; -        s.command("a", {}); -        s.command("b", {}); -        s.command("c", {}); -        s.command("d", {}); -        s.command("e", {}); -        s.fieldStart(true); -        s.fieldEnd(); -        tracker.expect(5, 0, 5, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -    } -    tracker.expect(5, 5, 5, 5, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -    ASSERT_FALSE(logger.hasError()); +	{ +		Stack s{parser, env.context, States::AnyHandlers}; +		s.commandStart("a", {}); +		s.commandStart("b", {}); +		s.commandStart("c", {}); +		s.commandStart("d", {}); +		s.commandStart("e", {}); +		s.fieldStart(true); +		s.fieldEnd(); +		tracker.expect(5, 0, 5, 1, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +	} +	tracker.expect(5, 5, 5, 5, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +	ASSERT_FALSE(logger.hasError());  }  TEST(Stack, invalidDefaultField)  { -    tracker.reset(); -    logger.reset(); +	tracker.reset(); +	logger.reset(); -    { -        Stack s{env.context, States::AnyHandlers}; -        s.command("a", {}); -        tracker.fieldStartResult = false; -        s.fieldStart(true); -        s.fieldEnd(); -        tracker.expect(1, 0, 1, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -    } -    tracker.expect(1, 1, 1, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -    ASSERT_FALSE(logger.hasError()); +	{ +		Stack s{parser, env.context, States::AnyHandlers}; +		s.commandStart("a", {}); +		tracker.fieldStartResult = false; +		s.fieldStart(true); +		s.fieldEnd(); +		tracker.expect(1, 0, 1, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +	} +	tracker.expect(1, 1, 1, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +	ASSERT_FALSE(logger.hasError());  }  TEST(Stack, errorInvalidDefaultFieldData)  { -    tracker.reset(); -    logger.reset(); +	tracker.reset(); +	logger.reset(); -    { -        Stack s{env.context, States::AnyHandlers}; -        s.command("a", {}); -        tracker.fieldStartResult = false; -        s.fieldStart(true); -        ASSERT_FALSE(logger.hasError()); -        s.data("test"); -        ASSERT_TRUE(logger.hasError()); -        s.fieldEnd(); -        tracker.expect(1, 0, 1, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -    } -    tracker.expect(1, 1, 1, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	{ +		Stack s{parser, env.context, States::AnyHandlers}; +		s.commandStart("a", {}); +		tracker.fieldStartResult = false; +		s.fieldStart(true); +		ASSERT_FALSE(logger.hasError()); +		s.data("test"); +		ASSERT_TRUE(logger.hasError()); +		s.fieldEnd(); +		tracker.expect(1, 0, 1, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +	} +	tracker.expect(1, 1, 1, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc  }  TEST(Stack, errorInvalidFieldData)  { -    tracker.reset(); -    logger.reset(); +	tracker.reset(); +	logger.reset(); -    { -        Stack s{env.context, States::AnyHandlers}; -        s.command("a", {}); -        tracker.fieldStartResult = false; -        ASSERT_FALSE(logger.hasError()); -        s.fieldStart(false); -        ASSERT_TRUE(logger.hasError()); -        s.data("test"); -        s.fieldEnd(); -        tracker.expect(1, 0, 1, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -    } -    tracker.expect(1, 1, 1, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	{ +		Stack s{parser, env.context, States::AnyHandlers}; +		s.commandStart("a", {}); +		tracker.fieldStartResult = false; +		ASSERT_FALSE(logger.hasError()); +		s.fieldStart(false); +		ASSERT_TRUE(logger.hasError()); +		s.data("test"); +		s.fieldEnd(); +		tracker.expect(1, 0, 1, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +	} +	tracker.expect(1, 1, 1, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc  }  TEST(Stack, errorFieldStartNoCommand)  { -    tracker.reset(); -    logger.reset(); +	tracker.reset(); +	logger.reset(); -    Stack s{env.context, States::AnyHandlers}; -    ASSERT_THROW(s.fieldStart(false), LoggableException); -    ASSERT_THROW(s.fieldStart(true), LoggableException); -    tracker.expect(0, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	Stack s{parser, env.context, States::AnyHandlers}; +	ASSERT_THROW(s.fieldStart(false), LoggableException); +	ASSERT_THROW(s.fieldStart(true), LoggableException); +	tracker.expect(0, 0, 0, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc  }  TEST(Stack, errorMultipleFieldStarts)  { -    tracker.reset(); -    logger.reset(); +	tracker.reset(); +	logger.reset(); -    { -        Stack s{env.context, States::AnyHandlers}; -        s.command("a", {}); -        tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	{ +		Stack s{parser, env.context, States::AnyHandlers}; +		s.commandStart("a", {}); +		tracker.expect(1, 0, 0, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc -        s.fieldStart(false); -        ASSERT_FALSE(logger.hasError()); -        s.fieldStart(false); -        ASSERT_TRUE(logger.hasError()); -        tracker.expect(1, 0, 1, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +		s.fieldStart(false); +		ASSERT_FALSE(logger.hasError()); +		s.fieldStart(false); +		ASSERT_TRUE(logger.hasError()); +		tracker.expect(1, 0, 1, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc -        s.fieldEnd(); -        tracker.expect(1, 0, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -    } -    tracker.expect(1, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +		s.fieldEnd(); +		tracker.expect(1, 0, 1, 1, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +	} +	tracker.expect(1, 1, 1, 1, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc  }  TEST(Stack, errorMultipleFieldEnds)  { -    tracker.reset(); -    logger.reset(); +	tracker.reset(); +	logger.reset(); -    { -        Stack s{env.context, States::AnyHandlers}; -        s.command("a", {}); -        tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +	{ +		Stack s{parser, env.context, States::AnyHandlers}; +		s.commandStart("a", {}); +		tracker.expect(1, 0, 0, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc -        s.fieldStart(false); -        s.fieldEnd(); -        ASSERT_FALSE(logger.hasError()); -        tracker.expect(1, 0, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -        s.fieldEnd(); -        ASSERT_TRUE(logger.hasError()); -        tracker.expect(1, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc -    } -    tracker.expect(1, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +		s.fieldStart(false); +		s.fieldEnd(); +		ASSERT_FALSE(logger.hasError()); +		tracker.expect(1, 0, 1, 1, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +		s.fieldEnd(); +		ASSERT_TRUE(logger.hasError()); +		tracker.expect(1, 1, 1, 1, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +	} +	tracker.expect(1, 1, 1, 1, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc  }  TEST(Stack, errorOpenField) @@ -657,15 +751,15 @@ TEST(Stack, errorOpenField)      logger.reset();      { -        Stack s{env.context, States::AnyHandlers}; -        s.command("a", {}); -        tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +        Stack s{parser, env.context, States::AnyHandlers}; +        s.commandStart("a", {}); +        tracker.expect(1, 0, 0, 0, 0); // scc, ec, fsc, fec, dc, sac, stc, etc          s.fieldStart(false);          ASSERT_FALSE(logger.hasError());      }      ASSERT_TRUE(logger.hasError()); -    tracker.expect(1, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +    tracker.expect(1, 1, 1, 1, 0); // scc, ec, fsc, fec, dc, sac, stc, etc  }  TEST(Stack, fieldEndWhenImplicitDefaultFieldOpen) @@ -674,15 +768,15 @@ TEST(Stack, fieldEndWhenImplicitDefaultFieldOpen)      logger.reset();      { -        Stack s{env.context, States::AnyHandlers}; -        s.command("a", {}); +        Stack s{parser, env.context, States::AnyHandlers}; +        s.commandStart("a", {});          s.fieldStart(true); -        s.command("b", {}); +        s.commandStart("b", {});          s.data("test");          s.fieldEnd(); -        tracker.expect(2, 1, 2, 2, 0, 0, 1);  // sc, ec, fsc, fse, asc, aec, dc +        tracker.expect(2, 1, 2, 2, 1);  // scc, ec, fsc, fec, dc, sac, stc, etc      } -    tracker.expect(2, 2, 2, 2, 0, 0, 1);  // sc, ec, fsc, fse, asc, aec, dc +    tracker.expect(2, 2, 2, 2, 1);  // scc, ec, fsc, fec, dc, sac, stc, etc      ASSERT_FALSE(logger.hasError());  } @@ -692,46 +786,66 @@ TEST(Stack, fieldAfterDefaultField)      logger.reset();      { -        Stack s{env.context, States::AnyHandlers}; -        s.command("a", {}); -        tracker.expect(1, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +        Stack s{parser, env.context, States::AnyHandlers}; +        s.commandStart("a", {}); +        tracker.expect(1, 0, 0, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc          s.fieldStart(true); -        tracker.expect(1, 0, 1, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +        tracker.expect(1, 0, 1, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc -        s.command("b", {}); -        tracker.expect(2, 0, 1, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +        s.commandStart("b", {}); +        tracker.expect(2, 0, 1, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc          s.fieldStart(false); -        tracker.expect(2, 0, 2, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc +        tracker.expect(2, 0, 2, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc          s.data("f1"); -        tracker.expect(2, 0, 2, 0, 0, 0, 1);  // sc, ec, fsc, fse, asc, aec, dc +        tracker.expect(2, 0, 2, 0, 1);  // scc, ec, fsc, fec, dc, sac, stc, etc          s.fieldEnd(); -        tracker.expect(2, 0, 2, 1, 0, 0, 1);  // sc, ec, fsc, fse, asc, aec, dc +        tracker.expect(2, 0, 2, 1, 1);  // scc, ec, fsc, fec, dc, sac, stc, etc          tracker.fieldStartSetIsDefault = true;          s.fieldStart(false);          tracker.fieldStartSetIsDefault = false; -        tracker.expect(2, 0, 3, 1, 0, 0, 1);  // sc, ec, fsc, fse, asc, aec, dc +        tracker.expect(2, 0, 3, 1, 1);  // scc, ec, fsc, fec, dc, sac, stc, etc          s.data("f2"); -        tracker.expect(2, 0, 3, 1, 0, 0, 2);  // sc, ec, fsc, fse, asc, aec, dc +        tracker.expect(2, 0, 3, 1, 2);  // scc, ec, fsc, fec, dc, sac, stc, etc          s.fieldEnd(); -        tracker.expect(2, 0, 3, 2, 0, 0, 2);  // sc, ec, fsc, fse, asc, aec, dc +        tracker.expect(2, 0, 3, 2, 2);  // scc, ec, fsc, fec, dc, sac, stc, etc          ASSERT_FALSE(logger.hasError());          s.fieldStart(false);          ASSERT_TRUE(logger.hasError());          logger.reset(); -        tracker.expect(2, 0, 3, 2, 0, 0, 2);  // sc, ec, fsc, fse, asc, aec, dc +        tracker.expect(2, 0, 3, 2, 2);  // scc, ec, fsc, fec, dc, sac, stc, etc          s.data("f3"); -        tracker.expect(2, 0, 3, 2, 0, 0, 2);  // sc, ec, fsc, fse, asc, aec, dc +        tracker.expect(2, 0, 3, 2, 2);  // scc, ec, fsc, fec, dc, sac, stc, etc          s.fieldEnd(); -        tracker.expect(2, 0, 3, 2, 0, 0, 2);  // sc, ec, fsc, fse, asc, aec, dc +        tracker.expect(2, 0, 3, 2, 2);  // scc, ec, fsc, fec, dc, sac, stc, etc          s.fieldEnd(); -        tracker.expect(2, 1, 3, 3, 0, 0, 2);  // sc, ec, fsc, fse, asc, aec, dc +        tracker.expect(2, 1, 3, 3, 2);  // scc, ec, fsc, fec, dc, sac, stc, etc      } -    tracker.expect(2, 2, 3, 3, 0, 0, 2);  // sc, ec, fsc, fse, asc, aec, dc +    tracker.expect(2, 2, 3, 3, 2);  // scc, ec, fsc, fec, dc, sac, stc, etc      ASSERT_FALSE(logger.hasError()); -}*/ +} + +TEST(Stack, rangeCommandUnranged) +{ +    tracker.reset(); +    logger.reset(); + +    { +        Stack s{parser, env.context, States::AnyHandlers}; +        tracker.expect(0, 0, 0, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +        s.commandStart("a", {}, true); +        tracker.expect(1, 0, 0, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +        s.commandStart("b", {}); +        tracker.expect(2, 0, 1, 0, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +        s.rangeEnd(); +        tracker.expect(2, 2, 1, 1, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +    } +    tracker.expect(2, 2, 1, 1, 0);  // scc, ec, fsc, fec, dc, sac, stc, etc +    ASSERT_FALSE(logger.hasError()); +} +  }  } | 
