summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-02-16 00:18:37 +0100
committerAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-02-16 00:18:37 +0100
commit87793f331c632ee527915805a0c92a94a534ba37 (patch)
tree3e747075d819c07c2b6b59982108f60a5d8b8159
parentfbcdbd6ea539520826492501be87823bae1f475d (diff)
Fixed problem with fieldEnd closing implicit fields and added unit test
-rw-r--r--src/core/parser/stack/Stack.cpp20
-rw-r--r--test/core/parser/stack/StackTest.cpp24
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());
+}
+
}
}