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()); +} + } } |