/*
Ousía
Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include
#include
#include
#include
namespace ousia {
static const State STATE_DOCUMENT = 0;
static const State STATE_BODY = 1;
static const State STATE_EMPTY = 2;
static int startCount = 0;
static int endCount = 0;
static int dataCount = 0;
static int childCount = 0;
class TestHandler : public Handler {
public:
using Handler::Handler;
void start(Variant::mapType &args) override { startCount++; }
void end() override { endCount++; }
void data(const std::string &data, int field) override { dataCount++; }
void child(std::shared_ptr handler) override { childCount++; }
};
static Handler *createTestHandler(const HandlerData &data)
{
return new TestHandler(data);
}
static const std::multimap 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}},
{"arguments",
{{STATE_NONE},
createTestHandler,
STATE_EMPTY,
false,
{Argument::Int("a"), Argument::String("b")}}},
};
TEST(ParserStack, simpleTest)
{
StandaloneParserContext ctx;
ParserStack s{ctx.context, TEST_HANDLERS};
startCount = 0;
endCount = 0;
dataCount = 0;
childCount = 0;
ASSERT_EQ("", s.currentName());
ASSERT_EQ(STATE_NONE, s.currentState());
s.start("document", {});
s.data("test1");
ASSERT_EQ("document", s.currentName());
ASSERT_EQ(STATE_DOCUMENT, s.currentState());
ASSERT_EQ(1, startCount);
ASSERT_EQ(1, dataCount);
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", {});
ASSERT_EQ("inner", s.currentName());
ASSERT_EQ(STATE_BODY, s.currentState());
s.end();
ASSERT_EQ(3, startCount);
ASSERT_EQ(1, childCount);
ASSERT_EQ(1, endCount);
s.end();
ASSERT_EQ(2, childCount);
ASSERT_EQ(2, endCount);
ASSERT_EQ("document", s.currentName());
ASSERT_EQ(STATE_DOCUMENT, s.currentState());
s.start("body", {});
s.data("test3");
ASSERT_EQ("body", s.currentName());
ASSERT_EQ(STATE_BODY, s.currentState());
s.end();
ASSERT_EQ(4, startCount);
ASSERT_EQ(3, dataCount);
ASSERT_EQ(3, childCount);
ASSERT_EQ(3, endCount);
ASSERT_EQ("document", s.currentName());
ASSERT_EQ(STATE_DOCUMENT, s.currentState());
s.end();
ASSERT_EQ(4, endCount);
ASSERT_EQ("", s.currentName());
ASSERT_EQ(STATE_NONE, s.currentState());
}
TEST(ParserStack, errorHandling)
{
StandaloneParserContext ctx;
ParserStack s{ctx.context, TEST_HANDLERS};
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();
ASSERT_EQ(STATE_NONE, s.currentState());
ASSERT_THROW(s.end(), OusiaException);
ASSERT_THROW(s.data("test", 1), OusiaException);
}
TEST(ParserStack, validation)
{
ConcreteLogger logger;
StandaloneParserContext ctx(logger);
ParserStack s{ctx.context, 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();
}
}