diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-15 00:29:11 +0100 |
---|---|---|
committer | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-15 00:29:11 +0100 |
commit | e99a307bf76689e4e86f8ac1a4c545bcebbdb7ab (patch) | |
tree | b0365ed915763418dbe35485ad74ceb2f3649abc | |
parent | f7326c640690cf5cfee89340db5569ef9b44a652 (diff) |
Using Arguments class in ParserStack for validation
-rw-r--r-- | src/core/parser/ParserStack.cpp | 17 | ||||
-rw-r--r-- | src/core/parser/ParserStack.hpp | 30 | ||||
-rw-r--r-- | test/core/parser/ParserStackTest.cpp | 82 |
3 files changed, 76 insertions, 53 deletions
diff --git a/src/core/parser/ParserStack.cpp b/src/core/parser/ParserStack.cpp index ff2647d..691b9d0 100644 --- a/src/core/parser/ParserStack.cpp +++ b/src/core/parser/ParserStack.cpp @@ -47,17 +47,14 @@ void Handler::child(std::shared_ptr<Handler> handler) HandlerInstance HandlerDescriptor::create(const ParserContext &ctx, std::string name, State parentState, bool isChild, - const Variant &args) const + Variant::mapType &args) const { Handler *h = ctor(ctx, name, targetState, parentState, isChild); // Canonicalize the arguments - Variant arguments = args; - if (argsType != nullptr) { - argsType->build(arguments, ctx.logger); - } + arguments.validateMap(args, ctx.logger, true); - h->start(arguments); + h->start(args); return HandlerInstance(h, this); } @@ -95,7 +92,7 @@ std::set<std::string> ParserStack::expectedCommands(State state) return res; } -void ParserStack::start(std::string name, const Variant &args) +void ParserStack::start(std::string name, Variant::mapType &args) { // Fetch the current handler and the current state const HandlerInstance *h = stack.empty() ? nullptr : &stack.top(); @@ -126,6 +123,12 @@ void ParserStack::start(std::string name, const Variant &args) stack.emplace(descr->create(ctx, name, curState, isChild, args)); } +void ParserStack::start(std::string name, const Variant::mapType &args) +{ + Variant::mapType argsCopy(args); + start(name, argsCopy); +} + void ParserStack::end() { // Check whether the current command could be ended diff --git a/src/core/parser/ParserStack.hpp b/src/core/parser/ParserStack.hpp index 93180b4..7602139 100644 --- a/src/core/parser/ParserStack.hpp +++ b/src/core/parser/ParserStack.hpp @@ -39,7 +39,7 @@ #include <core/common/Variant.hpp> #include <core/common/Logger.hpp> -#include <core/model/Typesystem.hpp> +#include <core/common/Argument.hpp> #include "Parser.hpp" @@ -128,7 +128,7 @@ public: * * @param args is a map from strings to variants (argument name and value). */ - virtual void start(const Variant &args) = 0; + virtual void start(const Variant::mapType &args) = 0; /** * Called whenever the command for which this handler is defined ends. @@ -212,10 +212,10 @@ struct HandlerDescriptor { const bool arbitraryChildren; /** - * Pointer pointing at a StructType describing the layout of the given when - * a new Handler instance is instantiated. + * Reference at an argument descriptor that should be used for validating + * the incomming arguments. */ - const Rooted<model::StructType> argsType; + const Arguments arguments; /** * Constructor of the HandlerDescriptor class. @@ -228,17 +228,17 @@ struct HandlerDescriptor { * instantiating an in instance of the described Handler instances. * @param arbitraryChildren allows the Handler instance to handle any child * node. - * @param argsType is a struct type describing the arguments that can be - * passed to the Handler or nullptr if no check should be performed. + * @param arguments is an optional argument descriptor used for validating + * the arguments that are passed to the instantiation of a handler function. */ HandlerDescriptor(std::set<State> parentStates, HandlerConstructor ctor, State targetState, bool arbitraryChildren = false, - Handle<model::StructType> argsType = nullptr) + Arguments arguments = Arguments::None) : parentStates(std::move(parentStates)), ctor(ctor), targetState(targetState), arbitraryChildren(arbitraryChildren), - argsType(argsType) + arguments(std::move(arguments)) { } @@ -248,7 +248,7 @@ struct HandlerDescriptor { */ HandlerInstance create(const ParserContext &ctx, std::string name, State parentState, bool isChild, - const Variant &args) const; + Variant::mapType &args) const; }; /** @@ -338,7 +338,15 @@ public: * @param name is the name of the command. * @param args is a map from strings to variants (argument name and value). */ - void start(std::string name, const Variant &args); + void start(std::string name, Variant::mapType &args); + + /** + * Function that should be called whenever a new command starts. + * + * @param name is the name of the command. + * @param args is a map from strings to variants (argument name and value). + */ + void start(std::string name, const Variant::mapType &args); /** * Function called whenever a command ends. diff --git a/test/core/parser/ParserStackTest.cpp b/test/core/parser/ParserStackTest.cpp index a0a4033..08c0548 100644 --- a/test/core/parser/ParserStackTest.cpp +++ b/test/core/parser/ParserStackTest.cpp @@ -36,44 +36,35 @@ static int dataCount = 0; static int childCount = 0; class TestHandler : public Handler { - public: using Handler::Handler; - void start(const Variant &args) override - { - startCount++; - } - - void end() override - { - endCount++; - } + void start(const Variant::mapType &args) override { startCount++; } - void data(const std::string &data, int field) override - { - dataCount++; - } + void end() override { endCount++; } - void child(std::shared_ptr<Handler> handler) override - { - childCount++; - } + void data(const std::string &data, int field) override { dataCount++; } + void child(std::shared_ptr<Handler> handler) override { childCount++; } }; -static Handler* createTestHandler(const ParserContext &ctx, - std::string name, State state, - State parentState, bool isChild) +static Handler *createTestHandler(const ParserContext &ctx, std::string name, + State state, State parentState, bool isChild) { return new TestHandler(ctx, name, state, parentState, isChild); } static const std::multimap<std::string, HandlerDescriptor> TEST_HANDLERS{ - {"document", {{STATE_NONE}, createTestHandler, STATE_DOCUMENT}}, - {"body", {{STATE_DOCUMENT}, createTestHandler, STATE_BODY, true}}, - {"empty", {{STATE_DOCUMENT}, createTestHandler, STATE_EMPTY}}, - {"special", {{STATE_ALL}, createTestHandler, STATE_EMPTY}}, + {"document", {{STATE_NONE}, createTestHandler, STATE_DOCUMENT}}, + {"body", {{STATE_DOCUMENT}, createTestHandler, STATE_BODY, true}}, + {"empty", {{STATE_DOCUMENT}, createTestHandler, STATE_EMPTY}}, + {"special", {{STATE_ALL}, createTestHandler, STATE_EMPTY}}, + {"arguments", + {{STATE_NONE}, + createTestHandler, + STATE_EMPTY, + false, + {Argument::Int("a"), Argument::String("b")}}}, }; TEST(ParserStack, simpleTest) @@ -89,7 +80,7 @@ TEST(ParserStack, simpleTest) ASSERT_EQ("", s.currentName()); ASSERT_EQ(STATE_NONE, s.currentState()); - s.start("document", nullptr); + s.start("document", {}); s.data("test1"); ASSERT_EQ("document", s.currentName()); @@ -97,14 +88,14 @@ TEST(ParserStack, simpleTest) ASSERT_EQ(1, startCount); ASSERT_EQ(1, dataCount); - s.start("body", nullptr); + s.start("body", {}); s.data("test2"); ASSERT_EQ("body", s.currentName()); ASSERT_EQ(STATE_BODY, s.currentState()); ASSERT_EQ(2, startCount); ASSERT_EQ(2, dataCount); - s.start("inner", nullptr); + s.start("inner", {}); ASSERT_EQ("inner", s.currentName()); ASSERT_EQ(STATE_BODY, s.currentState()); s.end(); @@ -119,7 +110,7 @@ TEST(ParserStack, simpleTest) ASSERT_EQ("document", s.currentName()); ASSERT_EQ(STATE_DOCUMENT, s.currentState()); - s.start("body", nullptr); + s.start("body", {}); s.data("test3"); ASSERT_EQ("body", s.currentName()); ASSERT_EQ(STATE_BODY, s.currentState()); @@ -144,12 +135,12 @@ TEST(ParserStack, errorHandling) StandaloneParserContext ctx; ParserStack s{ctx, TEST_HANDLERS}; - ASSERT_THROW(s.start("body", nullptr), OusiaException); - s.start("document", nullptr); - ASSERT_THROW(s.start("document", nullptr), OusiaException); - s.start("empty", nullptr); - ASSERT_THROW(s.start("body", nullptr), OusiaException); - s.start("special", nullptr); + ASSERT_THROW(s.start("body", {}), OusiaException); + s.start("document", {}); + ASSERT_THROW(s.start("document", {}), OusiaException); + s.start("empty", {}); + ASSERT_THROW(s.start("body", {}), OusiaException); + s.start("special", {}); s.end(); s.end(); s.end(); @@ -158,6 +149,27 @@ TEST(ParserStack, errorHandling) ASSERT_THROW(s.data("test", 1), OusiaException); } +TEST(ParserStack, validation) +{ + ConcreteLogger logger; + StandaloneParserContext ctx(logger); + ParserStack s{ctx, TEST_HANDLERS}; + + s.start("arguments", {}); + ASSERT_TRUE(logger.hasError()); + logger.reset(); + s.end(); + + s.start("arguments", {{"a", 5}}); + ASSERT_TRUE(logger.hasError()); + logger.reset(); + s.end(); + + s.start("arguments", {{"a", 5}, {"b", "test"}}); + ASSERT_FALSE(logger.hasError()); + s.end(); +} + } } |