diff options
| author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-02-16 00:18:37 +0100 | 
|---|---|---|
| committer | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-02-16 00:18:37 +0100 | 
| commit | 87793f331c632ee527915805a0c92a94a534ba37 (patch) | |
| tree | 3e747075d819c07c2b6b59982108f60a5d8b8159 | |
| parent | fbcdbd6ea539520826492501be87823bae1f475d (diff) | |
Fixed problem with fieldEnd closing implicit fields and added unit test
| -rw-r--r-- | src/core/parser/stack/Stack.cpp | 20 | ||||
| -rw-r--r-- | test/core/parser/stack/StackTest.cpp | 24 | 
2 files changed, 36 insertions, 8 deletions
diff --git a/src/core/parser/stack/Stack.cpp b/src/core/parser/stack/Stack.cpp index 47f7d2c..905edb4 100644 --- a/src/core/parser/stack/Stack.cpp +++ b/src/core/parser/stack/Stack.cpp @@ -322,7 +322,8 @@ void Stack::command(const Variant &name, const Variant::mapType &args)  		// to create an empty default field, otherwise this is an exception  		const State *targetState = findTargetStateOrWildcard(name.asString());  		if (targetState == nullptr) { -			if (!currentInfo().inField) { +			HandlerInfo &info = currentInfo(); +			if (info.inImplicitDefaultField || !info.inField) {  				endCurrentHandler();  				continue;  			} else { @@ -397,7 +398,7 @@ void Stack::data(const Variant &data)  	while (true) {  		// Check whether there is any command the data can be sent to  		if (stack.empty()) { -			throw LoggableException("No command here to receive data."); +			throw LoggableException("No command here to receive data.", data);  		}  		// Fetch the current command handler information @@ -497,14 +498,23 @@ void Stack::fieldStart(bool isDefault)  void Stack::fieldEnd()  { -	// Make sure the current handler stack is not empty +	// Check whether there is any command the data can be sent to  	if (stack.empty()) { -		throw LoggableException("No command for which a field could be ended"); +		throw LoggableException("No command, but got end of field."); +	} + +	// Unroll the stack until the next explicitly open field +	while (!stack.empty()) { +		HandlerInfo &info = currentInfo(); +		if (info.inField && !info.inImplicitDefaultField) { +			break; +		} +		endCurrentHandler();  	}  	// Fetch the information attached to the current handler  	HandlerInfo &info = currentInfo(); -	if (!info.inField) { +	if (!info.inField || info.inImplicitDefaultField || stack.empty()) {  		logger().error(  		    "Got field end, but there is no command for which to end the "  		    "field."); diff --git a/test/core/parser/stack/StackTest.cpp b/test/core/parser/stack/StackTest.cpp index 321d471..59fdd59 100644 --- a/test/core/parser/stack/StackTest.cpp +++ b/test/core/parser/stack/StackTest.cpp @@ -602,7 +602,7 @@ TEST(Stack, errorFieldStartNoCommand)  	tracker.expect(0, 0, 0, 0, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc  } -TEST(Stack, errorMutlipleFieldStarts) +TEST(Stack, errorMultipleFieldStarts)  {  	tracker.reset();  	logger.reset(); @@ -624,7 +624,7 @@ TEST(Stack, errorMutlipleFieldStarts)  	tracker.expect(1, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc  } -TEST(Stack, errorMutlipleFieldEnds) +TEST(Stack, errorMultipleFieldEnds)  {  	tracker.reset();  	logger.reset(); @@ -640,7 +640,7 @@ TEST(Stack, errorMutlipleFieldEnds)  		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, 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  	}  	tracker.expect(1, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc  } @@ -661,6 +661,24 @@ TEST(Stack, errorOpenField)  	ASSERT_TRUE(logger.hasError());  	tracker.expect(1, 1, 1, 1, 0, 0, 0);  // sc, ec, fsc, fse, asc, aec, dc  } + +TEST(Stack, fieldEndWhenImplicitDefaultFieldOpen) +{ +	tracker.reset(); +	logger.reset(); + +	{ +		Stack s{env.context, States::AnyHandlers}; +		s.command("a", {}); +		s.fieldStart(true); +		s.command("b", {}); +		s.data("test"); +		s.fieldEnd(); +		tracker.expect(2, 2, 2, 2, 0, 0, 1);  // sc, ec, fsc, fse, asc, aec, dc +	} +	ASSERT_FALSE(logger.hasError()); +} +  }  }  | 
