summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/core/RangeSetTest.cpp10
-rw-r--r--test/core/StandaloneEnvironment.hpp4
-rw-r--r--test/core/common/UtilsTest.cpp58
-rw-r--r--test/core/model/DomainTest.cpp12
-rw-r--r--test/core/parser/ParserStackTest.cpp177
-rw-r--r--test/core/parser/ParserStateTest.cpp77
-rw-r--r--test/core/parser/stack/StackTest.cpp666
-rw-r--r--test/core/parser/stack/StateTest.cpp79
-rw-r--r--test/core/parser/utils/TokenTrieTest.cpp (renamed from test/formats/osdm/TokenTrieTest.cpp)2
-rw-r--r--test/core/parser/utils/TokenizerTest.cpp (renamed from test/formats/osdm/DynamicTokenizerTest.cpp)85
-rw-r--r--test/formats/osml/OsmlStreamParserTest.cpp (renamed from test/formats/osdm/OsdmStreamParserTest.cpp)794
-rw-r--r--test/formats/osxml/OsxmlEventParserTest.cpp217
-rw-r--r--test/formats/osxml/OsxmlParserTest.cpp (renamed from test/plugins/xml/XmlParserTest.cpp)28
-rw-r--r--test/plugins/css/CodeTokenizerTest.cpp (renamed from test/core/CodeTokenizerTest.cpp)0
-rw-r--r--test/plugins/css/TokenizerTest.cpp (renamed from test/core/TokenizerTest.cpp)0
15 files changed, 1622 insertions, 587 deletions
diff --git a/test/core/RangeSetTest.cpp b/test/core/RangeSetTest.cpp
index cbf8f59..446ee51 100644
--- a/test/core/RangeSetTest.cpp
+++ b/test/core/RangeSetTest.cpp
@@ -110,7 +110,7 @@ TEST(RangeSet, Merge)
s.merge(Range<int>(40, 50));
s.merge(Range<int>(60, 70));
{
- ASSERT_EQ(ranges.size(), 4);
+ ASSERT_EQ(ranges.size(), 4U);
auto it = ranges.begin();
ASSERT_EQ((*it).start, 0);
@@ -132,7 +132,7 @@ TEST(RangeSet, Merge)
// Now insert an element which spans the second and third element
s.merge(Range<int>(15, 55));
{
- ASSERT_EQ(ranges.size(), 3);
+ ASSERT_EQ(ranges.size(), 3U);
auto it = ranges.begin();
ASSERT_EQ((*it).start, 0);
@@ -150,7 +150,7 @@ TEST(RangeSet, Merge)
// Now insert an element which expands the first element
s.merge(Range<int>(-10, 11));
{
- ASSERT_EQ(ranges.size(), 3);
+ ASSERT_EQ(ranges.size(), 3U);
auto it = ranges.begin();
ASSERT_EQ((*it).start, -10);
@@ -168,7 +168,7 @@ TEST(RangeSet, Merge)
// Now insert an element which merges the last two elements
s.merge(Range<int>(13, 70));
{
- ASSERT_EQ(ranges.size(), 2);
+ ASSERT_EQ(ranges.size(), 2U);
auto it = ranges.begin();
ASSERT_EQ((*it).start, -10);
@@ -182,7 +182,7 @@ TEST(RangeSet, Merge)
// Now insert an element which merges the remaining elements
s.merge(Range<int>(-9, 12));
{
- ASSERT_EQ(ranges.size(), 1);
+ ASSERT_EQ(ranges.size(), 1U);
auto it = ranges.begin();
ASSERT_EQ((*it).start, -10);
diff --git a/test/core/StandaloneEnvironment.hpp b/test/core/StandaloneEnvironment.hpp
index a9dcdce..790bad4 100644
--- a/test/core/StandaloneEnvironment.hpp
+++ b/test/core/StandaloneEnvironment.hpp
@@ -31,6 +31,10 @@
namespace ousia {
+/**
+ * StandaloneEnvironment is a class used for quickly setting up an entire
+ * environment needed for running an Ousia instance.
+ */
struct StandaloneEnvironment {
ConcreteLogger &logger;
Manager manager;
diff --git a/test/core/common/UtilsTest.cpp b/test/core/common/UtilsTest.cpp
index 917f45c..7801296 100644
--- a/test/core/common/UtilsTest.cpp
+++ b/test/core/common/UtilsTest.cpp
@@ -24,22 +24,40 @@ namespace ousia {
TEST(Utils, isIdentifier)
{
- ASSERT_TRUE(Utils::isIdentifier("test"));
- ASSERT_TRUE(Utils::isIdentifier("t0-_est"));
- ASSERT_FALSE(Utils::isIdentifier("_t0-_EST"));
- ASSERT_FALSE(Utils::isIdentifier("-t0-_EST"));
- ASSERT_FALSE(Utils::isIdentifier("0t-_EST"));
- ASSERT_FALSE(Utils::isIdentifier("invalid key"));
+ EXPECT_TRUE(Utils::isIdentifier("test"));
+ EXPECT_TRUE(Utils::isIdentifier("t0-_est"));
+ EXPECT_FALSE(Utils::isIdentifier("_t0-_EST"));
+ EXPECT_FALSE(Utils::isIdentifier("-t0-_EST"));
+ EXPECT_FALSE(Utils::isIdentifier("0t-_EST"));
+ EXPECT_FALSE(Utils::isIdentifier("_A"));
+ EXPECT_FALSE(Utils::isIdentifier("invalid key"));
+ EXPECT_FALSE(Utils::isIdentifier(""));
}
-TEST(Utils, trim)
+
+TEST(Utils, isNamespacedIdentifier)
{
- ASSERT_EQ("hello world", Utils::trim("\t hello world \n\r\t"));
- ASSERT_EQ("hello world", Utils::trim("hello world \n\r\t"));
- ASSERT_EQ("hello world", Utils::trim(" hello world"));
- ASSERT_EQ("hello world", Utils::trim("hello world"));
+ EXPECT_TRUE(Utils::isNamespacedIdentifier("test"));
+ EXPECT_TRUE(Utils::isNamespacedIdentifier("t0-_est"));
+ EXPECT_FALSE(Utils::isNamespacedIdentifier("_t0-_EST"));
+ EXPECT_FALSE(Utils::isNamespacedIdentifier("-t0-_EST"));
+ EXPECT_FALSE(Utils::isNamespacedIdentifier("0t-_EST"));
+ EXPECT_FALSE(Utils::isNamespacedIdentifier("invalid key"));
+ EXPECT_FALSE(Utils::isNamespacedIdentifier("_A"));
+ EXPECT_FALSE(Utils::isNamespacedIdentifier(""));
+ EXPECT_FALSE(Utils::isNamespacedIdentifier(":"));
+ EXPECT_TRUE(Utils::isNamespacedIdentifier("test:a"));
+ EXPECT_TRUE(Utils::isNamespacedIdentifier("t0-_est:b"));
+ EXPECT_TRUE(Utils::isNamespacedIdentifier("test:test"));
+ EXPECT_TRUE(Utils::isNamespacedIdentifier("t0-_est:t0-_est"));
+ EXPECT_FALSE(Utils::isNamespacedIdentifier("test:_A"));
+ EXPECT_FALSE(Utils::isNamespacedIdentifier("test::a"));
+ EXPECT_FALSE(Utils::isNamespacedIdentifier(":test"));
+ EXPECT_FALSE(Utils::isNamespacedIdentifier("t0-_est:_t0-_EST"));
+ EXPECT_FALSE(Utils::isNamespacedIdentifier("t0-_est: b"));
}
+
TEST(Utils, split)
{
ASSERT_EQ(std::vector<std::string>({"ab"}), Utils::split("ab", '.'));
@@ -73,5 +91,23 @@ TEST(Utils, extractFileExtension)
ASSERT_EQ("ext", Utils::extractFileExtension("foo.bar/test.EXT"));
}
+TEST(Utils, startsWith)
+{
+ ASSERT_TRUE(Utils::startsWith("foobar", "foo"));
+ ASSERT_TRUE(Utils::startsWith("foo", "foo"));
+ ASSERT_FALSE(Utils::startsWith("foo", "foobar"));
+ ASSERT_FALSE(Utils::startsWith("foobar", "bar"));
+ ASSERT_TRUE(Utils::startsWith("foo", ""));
+}
+
+TEST(Utils, endsWith)
+{
+ ASSERT_FALSE(Utils::endsWith("foobar", "foo"));
+ ASSERT_TRUE(Utils::endsWith("foo", "foo"));
+ ASSERT_FALSE(Utils::endsWith("foo", "foobar"));
+ ASSERT_TRUE(Utils::endsWith("foobar", "bar"));
+ ASSERT_TRUE(Utils::endsWith("foo", ""));
+}
+
}
diff --git a/test/core/model/DomainTest.cpp b/test/core/model/DomainTest.cpp
index 8fcbdf2..4cb4331 100644
--- a/test/core/model/DomainTest.cpp
+++ b/test/core/model/DomainTest.cpp
@@ -242,7 +242,7 @@ TEST(Descriptor, getDefaultFields)
A->createPrimitiveFieldDescriptor(sys->getStringType(), logger);
// now we should find that.
auto fields = A->getDefaultFields();
- ASSERT_EQ(1, fields.size());
+ ASSERT_EQ(1U, fields.size());
ASSERT_EQ(A_prim_field, fields[0]);
// remove that field from A and add it to another class.
@@ -258,7 +258,7 @@ TEST(Descriptor, getDefaultFields)
// but we should find it again if we set B as superclass of A.
A->setSuperclass(B, logger);
fields = A->getDefaultFields();
- ASSERT_EQ(1, fields.size());
+ ASSERT_EQ(1U, fields.size());
ASSERT_EQ(A_prim_field, fields[0]);
// and we should not be able to find it if we override the field.
@@ -277,7 +277,7 @@ TEST(Descriptor, getDefaultFields)
// now we should find that.
fields = A->getDefaultFields();
- ASSERT_EQ(1, fields.size());
+ ASSERT_EQ(1U, fields.size());
ASSERT_EQ(C_field, fields[0]);
// add another transparent child class to A with a daughter class that has
@@ -296,7 +296,7 @@ TEST(Descriptor, getDefaultFields)
// now we should find both primitive fields, but the C field first.
fields = A->getDefaultFields();
- ASSERT_EQ(2, fields.size());
+ ASSERT_EQ(2U, fields.size());
ASSERT_EQ(C_field, fields[0]);
ASSERT_EQ(F_field, fields[1]);
}
@@ -321,7 +321,7 @@ TEST(Descriptor, getPermittedChildren)
* in between.
*/
NodeVector<StructuredClass> children = book->getPermittedChildren();
- ASSERT_EQ(3, children.size());
+ ASSERT_EQ(3U, children.size());
ASSERT_EQ(section, children[0]);
ASSERT_EQ(paragraph, children[1]);
ASSERT_EQ(text, children[2]);
@@ -331,7 +331,7 @@ TEST(Descriptor, getPermittedChildren)
mgr, "Subclass", domain, Cardinality::any(), text, true, false)};
// And that should be in the result list as well now.
children = book->getPermittedChildren();
- ASSERT_EQ(4, children.size());
+ ASSERT_EQ(4U, children.size());
ASSERT_EQ(section, children[0]);
ASSERT_EQ(paragraph, children[1]);
ASSERT_EQ(text, children[2]);
diff --git a/test/core/parser/ParserStackTest.cpp b/test/core/parser/ParserStackTest.cpp
deleted file mode 100644
index 3a0decb..0000000
--- a/test/core/parser/ParserStackTest.cpp
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- 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 <http://www.gnu.org/licenses/>.
-*/
-
-#include <iostream>
-
-#include <gtest/gtest.h>
-
-#include <core/parser/ParserStack.hpp>
-#include <core/StandaloneEnvironment.hpp>
-
-namespace ousia {
-
-ConcreteLogger logger;
-
-static int startCount = 0;
-static int endCount = 0;
-static int dataCount = 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++; }
-
- static Handler *create(const HandlerData &data)
- {
- return new TestHandler(data);
- }
-};
-
-namespace ParserStates {
-static const ParserState Document =
- ParserStateBuilder().parent(&None).elementHandler(TestHandler::create);
-static const ParserState Body = ParserStateBuilder()
- .parent(&Document)
- .elementHandler(TestHandler::create);
-static const ParserState Empty =
- ParserStateBuilder().parent(&Document).elementHandler(TestHandler::create);
-static const ParserState Special =
- ParserStateBuilder().parent(&All).elementHandler(TestHandler::create);
-static const ParserState Arguments =
- ParserStateBuilder()
- .parent(&None)
- .elementHandler(TestHandler::create)
- .arguments({Argument::Int("a"), Argument::String("b")});
-static const ParserState BodyChildren =
- ParserStateBuilder()
- .parent(&Body)
- .elementHandler(TestHandler::create);
-
-static const std::multimap<std::string, const ParserState *> TestHandlers{
- {"document", &Document},
- {"body", &Body},
- {"empty", &Empty},
- {"special", &Special},
- {"arguments", &Arguments},
- {"*", &BodyChildren}};
-}
-
-TEST(ParserStack, simpleTest)
-{
- StandaloneEnvironment env(logger);
- ParserStack s{env.context, ParserStates::TestHandlers};
-
- startCount = 0;
- endCount = 0;
- dataCount = 0;
-
- EXPECT_EQ("", s.currentCommandName());
- EXPECT_EQ(&ParserStates::None, &s.currentState());
-
- s.start("document", {});
- s.data("test1");
-
- EXPECT_EQ("document", s.currentCommandName());
- EXPECT_EQ(&ParserStates::Document, &s.currentState());
- EXPECT_EQ(1, startCount);
- EXPECT_EQ(1, dataCount);
-
- s.start("body", {});
- s.data("test2");
- EXPECT_EQ("body", s.currentCommandName());
- EXPECT_EQ(&ParserStates::Body, &s.currentState());
- EXPECT_EQ(2, startCount);
- EXPECT_EQ(2, dataCount);
-
- s.start("inner", {});
- EXPECT_EQ("inner", s.currentCommandName());
- EXPECT_EQ(&ParserStates::BodyChildren, &s.currentState());
- s.end();
- EXPECT_EQ(3, startCount);
- EXPECT_EQ(1, endCount);
-
- s.end();
- EXPECT_EQ(2, endCount);
-
- EXPECT_EQ("document", s.currentCommandName());
- EXPECT_EQ(&ParserStates::Document, &s.currentState());
-
- s.start("body", {});
- s.data("test3");
- EXPECT_EQ("body", s.currentCommandName());
- EXPECT_EQ(&ParserStates::Body, &s.currentState());
- s.end();
- EXPECT_EQ(4, startCount);
- EXPECT_EQ(3, dataCount);
- EXPECT_EQ(3, endCount);
-
- EXPECT_EQ("document", s.currentCommandName());
- EXPECT_EQ(&ParserStates::Document, &s.currentState());
-
- s.end();
- EXPECT_EQ(4, endCount);
-
- EXPECT_EQ("", s.currentCommandName());
- EXPECT_EQ(&ParserStates::None, &s.currentState());
-}
-
-TEST(ParserStack, errorHandling)
-{
- StandaloneEnvironment env(logger);
- ParserStack s{env.context, ParserStates::TestHandlers};
-
- EXPECT_THROW(s.start("body", {}), OusiaException);
- s.start("document", {});
- EXPECT_THROW(s.start("document", {}), OusiaException);
- s.start("empty", {});
- EXPECT_THROW(s.start("body", {}), OusiaException);
- s.start("special", {});
- s.end();
- s.end();
- s.end();
- EXPECT_EQ(&ParserStates::None, &s.currentState());
- ASSERT_THROW(s.end(), OusiaException);
- ASSERT_THROW(s.data("test", 1), OusiaException);
-}
-
-TEST(ParserStack, validation)
-{
- StandaloneEnvironment env(logger);
- ParserStack s{env.context, ParserStates::TestHandlers};
-
- logger.reset();
- s.start("arguments", {});
- EXPECT_TRUE(logger.hasError());
- s.end();
-
- s.start("arguments", {{"a", 5}});
- EXPECT_TRUE(logger.hasError());
- s.end();
-
- logger.reset();
- s.start("arguments", {{"a", 5}, {"b", "test"}});
- EXPECT_FALSE(logger.hasError());
- s.end();
-}
-}
-
diff --git a/test/core/parser/ParserStateTest.cpp b/test/core/parser/ParserStateTest.cpp
deleted file mode 100644
index 91d8dcd..0000000
--- a/test/core/parser/ParserStateTest.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- 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 <http://www.gnu.org/licenses/>.
-*/
-
-#include <gtest/gtest.h>
-
-#include <core/common/Rtti.hpp>
-#include <core/parser/ParserState.hpp>
-
-namespace ousia {
-
-static const Rtti t1;
-static const Rtti t2;
-static const Rtti t3;
-static const Rtti t4;
-static const Rtti t5;
-
-static const ParserState s1 = ParserStateBuilder().createdNodeType(&t1);
-static const ParserState s2a =
- ParserStateBuilder().parent(&s1).createdNodeType(&t2);
-static const ParserState s2b =
- ParserStateBuilder().parent(&s1).createdNodeType(&t2);
-static const ParserState s3 =
- ParserStateBuilder().parents({&s2a, &s1}).createdNodeType(&t3);
-static const ParserState s4 =
- ParserStateBuilder().parent(&s3).createdNodeType(&t4);
-static const ParserState s5 =
- ParserStateBuilder().parent(&s2b).createdNodeType(&t5);
-
-TEST(ParserStateDeductor, deduce)
-{
- using Result = std::vector<const ParserState *>;
- using Signature = std::vector<const Rtti *>;
- std::vector<const ParserState *> states{&s1, &s2a, &s2b, &s3, &s4, &s5};
-
- // Should not crash on empty signature
- ASSERT_EQ(Result{}, ParserStateDeductor(Signature{}, states).deduce());
-
- // Try repeating signature elements
- ASSERT_EQ(Result({&s1}),
- ParserStateDeductor(Signature({&t1}), states).deduce());
- ASSERT_EQ(Result({&s1}),
- ParserStateDeductor(Signature({&t1, &t1}), states).deduce());
- ASSERT_EQ(Result({&s1}),
- ParserStateDeductor(Signature({&t1, &t1, &t1}), states).deduce());
-
- // Go to another state
- ASSERT_EQ(Result({&s2a, &s2b}),
- ParserStateDeductor(Signature({&t1, &t1, &t2}), states).deduce());
- ASSERT_EQ(Result({&s4}),
- ParserStateDeductor(Signature({&t1, &t3, &t4}), states).deduce());
-
- // Skip one state
- ASSERT_EQ(Result({&s4}),
- ParserStateDeductor(Signature({&t2, &t4}), states).deduce());
-
- // Impossible signature
- ASSERT_EQ(Result({}),
- ParserStateDeductor(Signature({&t4, &t5}), states).deduce());
-
-}
-}
-
diff --git a/test/core/parser/stack/StackTest.cpp b/test/core/parser/stack/StackTest.cpp
new file mode 100644
index 0000000..321d471
--- /dev/null
+++ b/test/core/parser/stack/StackTest.cpp
@@ -0,0 +1,666 @@
+/*
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <iostream>
+
+#include <gtest/gtest.h>
+
+#include <core/frontend/TerminalLogger.hpp>
+#include <core/parser/stack/Handler.hpp>
+#include <core/parser/stack/Stack.hpp>
+#include <core/parser/stack/State.hpp>
+
+#include <core/StandaloneEnvironment.hpp>
+
+namespace ousia {
+namespace parser_stack {
+
+// Build an instance of the StandaloneEnvironment used for this unit test
+static TerminalLogger logger(std::cerr, true);
+// static ConcreteLogger logger;
+static StandaloneEnvironment env(logger);
+
+namespace {
+
+struct Tracker {
+ int startCount;
+ int endCount;
+ int fieldStartCount;
+ int fieldEndCount;
+ int annotationStartCount;
+ int annotationEndCount;
+ int dataCount;
+
+ Variant::mapType startArgs;
+ bool fieldStartIsDefault;
+ size_t fieldStartIdx;
+ Variant annotationStartClassName;
+ Variant::mapType annotationStartArgs;
+ Variant annotationEndClassName;
+ Variant annotationEndElementName;
+ Variant dataData;
+
+ bool startResult;
+ bool fieldStartSetIsDefault;
+ bool fieldStartResult;
+ bool annotationStartResult;
+ bool annotationEndResult;
+ bool dataResult;
+
+ Tracker() { reset(); }
+
+ void reset()
+ {
+ startCount = 0;
+ endCount = 0;
+ fieldStartCount = 0;
+ fieldEndCount = 0;
+ annotationStartCount = 0;
+ annotationEndCount = 0;
+ dataCount = 0;
+
+ startArgs = Variant::mapType{};
+ fieldStartIsDefault = false;
+ fieldStartIdx = 0;
+ annotationStartClassName = Variant::fromString(std::string{});
+ annotationStartArgs = Variant::mapType{};
+ annotationEndClassName = Variant::fromString(std::string{});
+ annotationEndElementName = Variant::fromString(std::string{});
+ dataData = Variant::fromString(std::string{});
+
+ startResult = true;
+ fieldStartSetIsDefault = false;
+ fieldStartResult = true;
+ annotationStartResult = true;
+ annotationEndResult = true;
+ dataResult = true;
+ }
+
+ void expect(int startCount, int endCount, int fieldStartCount,
+ int fieldEndCount, int annotationStartCount,
+ int annotationEndCount, int dataCount)
+ {
+ EXPECT_EQ(startCount, this->startCount);
+ EXPECT_EQ(endCount, this->endCount);
+ EXPECT_EQ(fieldStartCount, this->fieldStartCount);
+ EXPECT_EQ(fieldEndCount, this->fieldEndCount);
+ EXPECT_EQ(annotationStartCount, this->annotationStartCount);
+ EXPECT_EQ(annotationEndCount, this->annotationEndCount);
+ EXPECT_EQ(dataCount, this->dataCount);
+ }
+};
+
+static Tracker tracker;
+
+class TestHandler : public Handler {
+private:
+ TestHandler(const HandlerData &handlerData) : Handler(handlerData) {}
+
+public:
+ bool start(Variant::mapType &args) override
+ {
+ tracker.startCount++;
+ tracker.startArgs = args;
+ if (!tracker.startResult) {
+ logger().error(
+ "The TestHandler was told not to allow a field start. So it "
+ "doesn't. The TestHandler always obeys its master.");
+ }
+ return tracker.startResult;
+ }
+
+ void end() override { tracker.endCount++; }
+
+ bool fieldStart(bool &isDefault, size_t fieldIdx) override
+ {
+ tracker.fieldStartCount++;
+ tracker.fieldStartIsDefault = isDefault;
+ tracker.fieldStartIdx = fieldIdx;
+ if (tracker.fieldStartSetIsDefault) {
+ isDefault = true;
+ }
+ return tracker.fieldStartResult;
+ }
+
+ void fieldEnd() override { tracker.fieldEndCount++; }
+
+ bool annotationStart(const Variant &className,
+ Variant::mapType &args) override
+ {
+ tracker.annotationStartCount++;
+ tracker.annotationStartClassName = className;
+ tracker.annotationStartArgs = args;
+ return tracker.annotationStartResult;
+ }
+
+ bool annotationEnd(const Variant &className,
+ const Variant &elementName) override
+ {
+ tracker.annotationEndCount++;
+ tracker.annotationEndClassName = className;
+ tracker.annotationEndElementName = elementName;
+ return tracker.annotationEndResult;
+ }
+
+ bool data(Variant &data) override
+ {
+ tracker.dataCount++;
+ tracker.dataData = data;
+ return tracker.dataResult;
+ }
+
+ static Handler *create(const HandlerData &handlerData)
+ {
+ return new TestHandler(handlerData);
+ }
+};
+}
+
+namespace States {
+static const State Document =
+ StateBuilder().parent(&None).elementHandler(TestHandler::create);
+static const State Body =
+ StateBuilder().parent(&Document).elementHandler(TestHandler::create);
+static const State Empty =
+ StateBuilder().parent(&Document).elementHandler(TestHandler::create);
+static const State Special =
+ StateBuilder().parent(&All).elementHandler(TestHandler::create);
+static const State Arguments =
+ StateBuilder().parent(&None).elementHandler(TestHandler::create).arguments(
+ {Argument::Int("a"), Argument::String("b")});
+static const State BodyChildren =
+ StateBuilder().parent(&Body).elementHandler(TestHandler::create);
+static const State Any =
+ StateBuilder().parents({&None, &Any}).elementHandler(TestHandler::create);
+
+static const std::multimap<std::string, const State *> TestHandlers{
+ {"document", &Document},
+ {"body", &Body},
+ {"empty", &Empty},
+ {"special", &Special},
+ {"arguments", &Arguments},
+ {"*", &BodyChildren}};
+
+static const std::multimap<std::string, const State *> AnyHandlers{{"*", &Any}};
+}
+
+TEST(Stack, basicTest)
+{
+ tracker.reset();
+ logger.reset();
+ {
+ Stack s{env.context, States::TestHandlers};
+
+ EXPECT_EQ("", s.currentCommandName());
+ EXPECT_EQ(&States::None, &s.currentState());
+
+ s.command("document", {});
+ s.fieldStart(true);
+ s.data("test1");
+
+ EXPECT_EQ("document", s.currentCommandName());
+ EXPECT_EQ(&States::Document, &s.currentState());
+ tracker.expect(1, 0, 1, 0, 0, 0, 1); // sc, ec, fsc, fse, asc, aec, dc
+
+ s.command("body", {});
+ s.fieldStart(true);
+ s.data("test2");
+ EXPECT_EQ("body", s.currentCommandName());
+ EXPECT_EQ(&States::Body, &s.currentState());
+ tracker.expect(2, 0, 2, 0, 0, 0, 2); // sc, ec, fsc, fse, asc, aec, dc
+
+ s.command("inner", {});
+ s.fieldStart(true);
+ EXPECT_EQ("inner", s.currentCommandName());
+ EXPECT_EQ(&States::BodyChildren, &s.currentState());
+
+ s.fieldEnd();
+ tracker.expect(3, 1, 3, 1, 0, 0, 2); // sc, ec, fsc, fse, asc, aec, dc
+
+ s.fieldEnd();
+ EXPECT_EQ("document", s.currentCommandName());
+ EXPECT_EQ(&States::Document, &s.currentState());
+ tracker.expect(3, 2, 3, 2, 0, 0, 2); // sc, ec, fsc, fse, asc, aec, dc
+
+ s.command("body", {});
+ s.fieldStart(true);
+ s.data("test3");
+ EXPECT_EQ("body", s.currentCommandName());
+ EXPECT_EQ(&States::Body, &s.currentState());
+ s.fieldEnd();
+ tracker.expect(4, 3, 4, 3, 0, 0, 3); // sc, ec, fsc, fse, asc, aec, dc
+
+ EXPECT_EQ("document", s.currentCommandName());
+ EXPECT_EQ(&States::Document, &s.currentState());
+
+ s.fieldEnd();
+ tracker.expect(4, 4, 4, 4, 0, 0, 3); // sc, ec, fsc, fse, asc, aec, dc
+
+ EXPECT_EQ("", s.currentCommandName());
+ EXPECT_EQ(&States::None, &s.currentState());
+ }
+ ASSERT_FALSE(logger.hasError());
+}
+
+TEST(Stack, errorInvalidCommands)
+{
+ Stack s{env.context, States::TestHandlers};
+ tracker.reset();
+ EXPECT_THROW(s.command("body", {}), LoggableException);
+ s.command("document", {});
+ s.fieldStart(true);
+ EXPECT_THROW(s.command("document", {}), LoggableException);
+ s.command("empty", {});
+ s.fieldStart(true);
+ EXPECT_THROW(s.command("body", {}), LoggableException);
+ s.command("special", {});
+ s.fieldStart(true);
+ s.fieldEnd();
+ s.fieldEnd();
+ s.fieldEnd();
+ EXPECT_EQ(&States::None, &s.currentState());
+ ASSERT_THROW(s.fieldEnd(), LoggableException);
+ ASSERT_THROW(s.data("test"), LoggableException);
+}
+
+TEST(Stack, validation)
+{
+ Stack s{env.context, States::TestHandlers};
+ tracker.reset();
+ logger.reset();
+
+ s.command("arguments", {});
+ EXPECT_TRUE(logger.hasError());
+ s.fieldStart(true);
+ s.fieldEnd();
+
+ logger.reset();
+ s.command("arguments", {{"a", 5}});
+ EXPECT_TRUE(logger.hasError());
+ s.fieldStart(true);
+ s.fieldEnd();
+
+ logger.reset();
+ s.command("arguments", {{"a", 5}, {"b", "test"}});
+ EXPECT_FALSE(logger.hasError());
+ s.fieldStart(true);
+ s.fieldEnd();
+}
+
+TEST(Stack, invalidCommandName)
+{
+ Stack s{env.context, States::AnyHandlers};
+ tracker.reset();
+ logger.reset();
+
+ s.command("a", {});
+ s.fieldStart(true);
+ s.fieldEnd();
+ tracker.expect(1, 1, 1, 1, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+
+ s.command("a_", {});
+ s.fieldStart(true);
+ s.fieldEnd();
+ tracker.expect(2, 2, 2, 2, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+
+ s.command("a_:b", {});
+ s.fieldStart(true);
+ s.fieldEnd();
+ tracker.expect(3, 3, 3, 3, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+
+ ASSERT_THROW(s.command("_a", {}), LoggableException);
+ ASSERT_THROW(s.command("a:", {}), LoggableException);
+ ASSERT_THROW(s.command("a:_b", {}), LoggableException);
+ tracker.expect(3, 3, 3, 3, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+}
+
+TEST(Stack, multipleFields)
+{
+ tracker.reset();
+ logger.reset();
+ {
+ Stack s{env.context, States::AnyHandlers};
+
+ s.command("a", {{"a", false}});
+ tracker.expect(1, 0, 0, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ EXPECT_EQ("a", s.currentCommandName());
+ EXPECT_EQ(Variant::mapType({{"a", false}}), tracker.startArgs);
+
+ s.fieldStart(false);
+ tracker.expect(1, 0, 1, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ EXPECT_FALSE(tracker.fieldStartIsDefault);
+ EXPECT_EQ(0U, tracker.fieldStartIdx);
+
+ s.data("test");
+ tracker.expect(1, 0, 1, 0, 0, 0, 1); // sc, ec, fsc, fse, asc, aec, dc
+ EXPECT_EQ("test", tracker.dataData);
+
+ s.fieldEnd();
+ tracker.expect(1, 0, 1, 1, 0, 0, 1); // sc, ec, fsc, fse, asc, aec, dc
+
+ s.fieldStart(false);
+ tracker.expect(1, 0, 2, 1, 0, 0, 1); // sc, ec, fsc, fse, asc, aec, dc
+ EXPECT_FALSE(tracker.fieldStartIsDefault);
+ EXPECT_EQ(1U, tracker.fieldStartIdx);
+
+ s.data("test2");
+ tracker.expect(1, 0, 2, 1, 0, 0, 2); // sc, ec, fsc, fse, asc, aec, dc
+ EXPECT_EQ("test2", tracker.dataData);
+
+ s.fieldEnd();
+ tracker.expect(1, 0, 2, 2, 0, 0, 2); // sc, ec, fsc, fse, asc, aec, dc
+
+ s.fieldStart(true);
+ tracker.expect(1, 0, 3, 2, 0, 0, 2); // sc, ec, fsc, fse, asc, aec, dc
+ EXPECT_TRUE(tracker.fieldStartIsDefault);
+ EXPECT_EQ(2U, tracker.fieldStartIdx);
+
+ s.data("test3");
+ tracker.expect(1, 0, 3, 2, 0, 0, 3); // sc, ec, fsc, fse, asc, aec, dc
+ EXPECT_EQ("test3", tracker.dataData);
+
+ s.fieldEnd();
+ tracker.expect(1, 1, 3, 3, 0, 0, 3); // sc, ec, fsc, fse, asc, aec, dc
+ }
+ ASSERT_FALSE(logger.hasError());
+}
+
+TEST(Stack, implicitDefaultFieldOnNewCommand)
+{
+ tracker.reset();
+ logger.reset();
+ {
+ Stack s{env.context, States::AnyHandlers};
+
+ s.command("a", {});
+ tracker.expect(1, 0, 0, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+
+ s.command("b", {});
+ tracker.expect(2, 0, 1, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ }
+ tracker.expect(2, 2, 1, 1, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ ASSERT_FALSE(logger.hasError());
+}
+
+TEST(Stack, implicitDefaultFieldOnNewCommandWithExplicitDefaultField)
+{
+ tracker.reset();
+ logger.reset();
+ {
+ Stack s{env.context, States::AnyHandlers};
+
+ s.command("a", {});
+ tracker.expect(1, 0, 0, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ ASSERT_EQ("a", s.currentCommandName());
+
+ s.command("b", {});
+ tracker.expect(2, 0, 1, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ ASSERT_EQ("b", s.currentCommandName());
+ s.fieldStart(true);
+ s.fieldEnd();
+ tracker.expect(2, 1, 2, 1, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ ASSERT_EQ("a", s.currentCommandName());
+ }
+ tracker.expect(2, 2, 2, 2, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ ASSERT_FALSE(logger.hasError());
+}
+
+TEST(Stack, noImplicitDefaultFieldOnIncompatibleCommand)
+{
+ tracker.reset();
+ logger.reset();
+ {
+ Stack s{env.context, States::AnyHandlers};
+
+ s.command("a", {});
+ tracker.expect(1, 0, 0, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ ASSERT_EQ("a", s.currentCommandName());
+
+ tracker.fieldStartResult = false;
+ s.command("b", {});
+ tracker.expect(2, 1, 1, 1, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ ASSERT_EQ("b", s.currentCommandName());
+ }
+ tracker.expect(2, 2, 1, 1, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ ASSERT_FALSE(logger.hasError());
+}
+
+TEST(Stack, noImplicitDefaultFieldIfDefaultFieldGiven)
+{
+ tracker.reset();
+ logger.reset();
+ {
+ Stack s{env.context, States::AnyHandlers};
+
+ s.command("a", {});
+ tracker.expect(1, 0, 0, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ ASSERT_EQ("a", s.currentCommandName());
+ s.fieldStart(true);
+ tracker.expect(1, 0, 1, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ ASSERT_EQ("a", s.currentCommandName());
+ s.fieldEnd();
+ tracker.expect(1, 1, 1, 1, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ ASSERT_EQ("", s.currentCommandName());
+
+ s.command("b", {});
+ tracker.expect(2, 1, 1, 1, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ ASSERT_EQ("b", s.currentCommandName());
+ }
+ tracker.expect(2, 2, 1, 1, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ ASSERT_FALSE(logger.hasError());
+}
+
+TEST(Stack, noEndIfStartFails)
+{
+ tracker.reset();
+ logger.reset();
+ {
+ Stack s{env.context, States::AnyHandlers};
+
+ s.command("a", {});
+ tracker.expect(1, 0, 0, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ ASSERT_EQ("a", s.currentCommandName());
+
+ tracker.startResult = false;
+ s.command("b", {});
+ tracker.expect(3, 1, 1, 1, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ ASSERT_EQ("b", s.currentCommandName());
+ }
+ tracker.expect(3, 1, 1, 1, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ ASSERT_TRUE(logger.hasError());
+}
+
+TEST(Stack, implicitDefaultFieldOnData)
+{
+ tracker.reset();
+ logger.reset();
+ {
+ Stack s{env.context, States::AnyHandlers};
+
+ s.command("a", {});
+ tracker.expect(1, 0, 0, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+
+ s.data("test");
+ tracker.expect(1, 0, 1, 0, 0, 0, 1); // sc, ec, fsc, fse, asc, aec, dc
+ }
+ tracker.expect(1, 1, 1, 1, 0, 0, 1); // sc, ec, fsc, fse, asc, aec, dc
+ ASSERT_FALSE(logger.hasError());
+}
+
+TEST(Stack, autoFieldEnd)
+{
+ tracker.reset();
+ logger.reset();
+
+ {
+ Stack s{env.context, States::AnyHandlers};
+ s.command("a", {});
+ tracker.expect(1, 0, 0, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ }
+ tracker.expect(1, 1, 0, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ ASSERT_FALSE(logger.hasError());
+}
+
+TEST(Stack, autoImplicitFieldEnd)
+{
+ tracker.reset();
+ logger.reset();
+
+ {
+ Stack s{env.context, States::AnyHandlers};
+ s.command("a", {});
+ s.command("b", {});
+ s.command("c", {});
+ s.command("d", {});
+ s.command("e", {});
+ s.fieldStart(true);
+ s.fieldEnd();
+ tracker.expect(5, 1, 5, 1, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ }
+ tracker.expect(5, 5, 5, 5, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ ASSERT_FALSE(logger.hasError());
+}
+
+TEST(Stack, invalidDefaultField)
+{
+ tracker.reset();
+ logger.reset();
+
+ {
+ Stack s{env.context, States::AnyHandlers};
+ s.command("a", {});
+ tracker.fieldStartResult = false;
+ s.fieldStart(true);
+ s.fieldEnd();
+ 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
+ ASSERT_FALSE(logger.hasError());
+}
+
+TEST(Stack, errorInvalidDefaultFieldData)
+{
+ tracker.reset();
+ logger.reset();
+
+ {
+ Stack s{env.context, States::AnyHandlers};
+ s.command("a", {});
+ tracker.fieldStartResult = false;
+ s.fieldStart(true);
+ ASSERT_FALSE(logger.hasError());
+ s.data("test");
+ ASSERT_TRUE(logger.hasError());
+ s.fieldEnd();
+ 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
+}
+
+TEST(Stack, errorInvalidFieldData)
+{
+ tracker.reset();
+ logger.reset();
+
+ {
+ Stack s{env.context, States::AnyHandlers};
+ s.command("a", {});
+ tracker.fieldStartResult = false;
+ ASSERT_FALSE(logger.hasError());
+ s.fieldStart(false);
+ ASSERT_TRUE(logger.hasError());
+ s.data("test");
+ s.fieldEnd();
+ 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
+}
+
+TEST(Stack, errorFieldStartNoCommand)
+{
+ tracker.reset();
+ logger.reset();
+
+ Stack s{env.context, States::AnyHandlers};
+ ASSERT_THROW(s.fieldStart(false), LoggableException);
+ ASSERT_THROW(s.fieldStart(true), LoggableException);
+ tracker.expect(0, 0, 0, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+}
+
+TEST(Stack, errorMutlipleFieldStarts)
+{
+ tracker.reset();
+ logger.reset();
+
+ {
+ Stack s{env.context, States::AnyHandlers};
+ s.command("a", {});
+ tracker.expect(1, 0, 0, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+
+ s.fieldStart(false);
+ ASSERT_FALSE(logger.hasError());
+ s.fieldStart(false);
+ ASSERT_TRUE(logger.hasError());
+ tracker.expect(1, 0, 1, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+
+ s.fieldEnd();
+ 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
+}
+
+TEST(Stack, errorMutlipleFieldEnds)
+{
+ tracker.reset();
+ logger.reset();
+
+ {
+ Stack s{env.context, States::AnyHandlers};
+ s.command("a", {});
+ tracker.expect(1, 0, 0, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+
+ s.fieldStart(false);
+ s.fieldEnd();
+ ASSERT_FALSE(logger.hasError());
+ 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
+}
+
+TEST(Stack, errorOpenField)
+{
+ tracker.reset();
+ logger.reset();
+
+ {
+ Stack s{env.context, States::AnyHandlers};
+ s.command("a", {});
+ tracker.expect(1, 0, 0, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+
+ s.fieldStart(false);
+ ASSERT_FALSE(logger.hasError());
+ }
+ ASSERT_TRUE(logger.hasError());
+ tracker.expect(1, 1, 1, 1, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+}
+}
+}
+
diff --git a/test/core/parser/stack/StateTest.cpp b/test/core/parser/stack/StateTest.cpp
new file mode 100644
index 0000000..e503d30
--- /dev/null
+++ b/test/core/parser/stack/StateTest.cpp
@@ -0,0 +1,79 @@
+/*
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <gtest/gtest.h>
+
+#include <core/common/Rtti.hpp>
+#include <core/parser/stack/State.hpp>
+
+namespace ousia {
+namespace parser_stack {
+
+static const Rtti t1;
+static const Rtti t2;
+static const Rtti t3;
+static const Rtti t4;
+static const Rtti t5;
+
+static const State s1 = StateBuilder().createdNodeType(&t1);
+static const State s2a =
+ StateBuilder().parent(&s1).createdNodeType(&t2);
+static const State s2b =
+ StateBuilder().parent(&s1).createdNodeType(&t2);
+static const State s3 =
+ StateBuilder().parents({&s2a, &s1}).createdNodeType(&t3);
+static const State s4 =
+ StateBuilder().parent(&s3).createdNodeType(&t4);
+static const State s5 =
+ StateBuilder().parent(&s2b).createdNodeType(&t5);
+
+TEST(StateDeductor, deduce)
+{
+ using Result = std::vector<const State *>;
+ using Signature = std::vector<const Rtti *>;
+ std::vector<const State *> states{&s1, &s2a, &s2b, &s3, &s4, &s5};
+
+ // Should not crash on empty signature
+ ASSERT_EQ(Result{}, StateDeductor(Signature{}, states).deduce());
+
+ // Try repeating signature elements
+ ASSERT_EQ(Result({&s1}),
+ StateDeductor(Signature({&t1}), states).deduce());
+ ASSERT_EQ(Result({&s1}),
+ StateDeductor(Signature({&t1, &t1}), states).deduce());
+ ASSERT_EQ(Result({&s1}),
+ StateDeductor(Signature({&t1, &t1, &t1}), states).deduce());
+
+ // Go to another state
+ ASSERT_EQ(Result({&s2a, &s2b}),
+ StateDeductor(Signature({&t1, &t1, &t2}), states).deduce());
+ ASSERT_EQ(Result({&s4}),
+ StateDeductor(Signature({&t1, &t3, &t4}), states).deduce());
+
+ // Skip one state
+ ASSERT_EQ(Result({&s4}),
+ StateDeductor(Signature({&t2, &t4}), states).deduce());
+
+ // Impossible signature
+ ASSERT_EQ(Result({}),
+ StateDeductor(Signature({&t4, &t5}), states).deduce());
+
+}
+}
+}
+
diff --git a/test/formats/osdm/TokenTrieTest.cpp b/test/core/parser/utils/TokenTrieTest.cpp
index aacd6c0..087e6e6 100644
--- a/test/formats/osdm/TokenTrieTest.cpp
+++ b/test/core/parser/utils/TokenTrieTest.cpp
@@ -18,7 +18,7 @@
#include <gtest/gtest.h>
-#include <formats/osdm/TokenTrie.hpp>
+#include <core/parser/utils/TokenTrie.hpp>
namespace ousia {
diff --git a/test/formats/osdm/DynamicTokenizerTest.cpp b/test/core/parser/utils/TokenizerTest.cpp
index c1f8785..8565057 100644
--- a/test/formats/osdm/DynamicTokenizerTest.cpp
+++ b/test/core/parser/utils/TokenizerTest.cpp
@@ -19,13 +19,13 @@
#include <gtest/gtest.h>
#include <core/common/CharReader.hpp>
-#include <formats/osdm/DynamicTokenizer.hpp>
+#include <core/parser/utils/Tokenizer.hpp>
namespace ousia {
-TEST(DynamicTokenizer, tokenRegistration)
+TEST(Tokenizer, tokenRegistration)
{
- DynamicTokenizer tokenizer;
+ Tokenizer tokenizer;
ASSERT_EQ(EmptyToken, tokenizer.registerToken(""));
@@ -50,15 +50,15 @@ TEST(DynamicTokenizer, tokenRegistration)
ASSERT_EQ("d", tokenizer.getTokenString(1U));
}
-TEST(DynamicTokenizer, textTokenPreserveWhitespace)
+TEST(Tokenizer, textTokenPreserveWhitespace)
{
{
CharReader reader{" this \t is only a \n\n test text "};
// 012345 6789012345678 9 0123456789012345
// 0 1 2 3
- DynamicTokenizer tokenizer{WhitespaceMode::PRESERVE};
+ Tokenizer tokenizer{WhitespaceMode::PRESERVE};
- DynamicToken token;
+ Token token;
ASSERT_TRUE(tokenizer.read(reader, token));
ASSERT_EQ(TextToken, token.type);
ASSERT_EQ(" this \t is only a \n\n test text ", token.content);
@@ -74,9 +74,9 @@ TEST(DynamicTokenizer, textTokenPreserveWhitespace)
CharReader reader{"this \t is only a \n\n test text"};
// 01234 5678901234567 8 9012345678901
// 0 1 2 3
- DynamicTokenizer tokenizer{WhitespaceMode::PRESERVE};
+ Tokenizer tokenizer{WhitespaceMode::PRESERVE};
- DynamicToken token;
+ Token token;
ASSERT_TRUE(tokenizer.read(reader, token));
ASSERT_EQ(TextToken, token.type);
ASSERT_EQ("this \t is only a \n\n test text", token.content);
@@ -89,15 +89,15 @@ TEST(DynamicTokenizer, textTokenPreserveWhitespace)
}
}
-TEST(DynamicTokenizer, textTokenTrimWhitespace)
+TEST(Tokenizer, textTokenTrimWhitespace)
{
{
CharReader reader{" this \t is only a \n\n test text "};
// 012345 6789012345678 9 0123456789012345
// 0 1 2 3
- DynamicTokenizer tokenizer{WhitespaceMode::TRIM};
+ Tokenizer tokenizer{WhitespaceMode::TRIM};
- DynamicToken token;
+ Token token;
ASSERT_TRUE(tokenizer.read(reader, token));
ASSERT_EQ(TextToken, token.type);
ASSERT_EQ("this \t is only a \n\n test text", token.content);
@@ -113,9 +113,9 @@ TEST(DynamicTokenizer, textTokenTrimWhitespace)
CharReader reader{"this \t is only a \n\n test text"};
// 01234 5678901234567 8 9012345678901
// 0 1 2 3
- DynamicTokenizer tokenizer{WhitespaceMode::TRIM};
+ Tokenizer tokenizer{WhitespaceMode::TRIM};
- DynamicToken token;
+ Token token;
ASSERT_TRUE(tokenizer.read(reader, token));
ASSERT_EQ(TextToken, token.type);
ASSERT_EQ("this \t is only a \n\n test text", token.content);
@@ -128,15 +128,15 @@ TEST(DynamicTokenizer, textTokenTrimWhitespace)
}
}
-TEST(DynamicTokenizer, textTokenCollapseWhitespace)
+TEST(Tokenizer, textTokenCollapseWhitespace)
{
{
CharReader reader{" this \t is only a \n\n test text "};
// 012345 6789012345678 9 0123456789012345
// 0 1 2 3
- DynamicTokenizer tokenizer{WhitespaceMode::COLLAPSE};
+ Tokenizer tokenizer{WhitespaceMode::COLLAPSE};
- DynamicToken token;
+ Token token;
ASSERT_TRUE(tokenizer.read(reader, token));
ASSERT_EQ(TextToken, token.type);
ASSERT_EQ("this is only a test text", token.content);
@@ -152,9 +152,9 @@ TEST(DynamicTokenizer, textTokenCollapseWhitespace)
CharReader reader{"this \t is only a \n\n test text"};
// 01234 5678901234567 8 9012345678901
// 0 1 2 3
- DynamicTokenizer tokenizer{WhitespaceMode::COLLAPSE};
+ Tokenizer tokenizer{WhitespaceMode::COLLAPSE};
- DynamicToken token;
+ Token token;
ASSERT_TRUE(tokenizer.read(reader, token));
ASSERT_EQ(TextToken, token.type);
ASSERT_EQ("this is only a test text", token.content);
@@ -167,16 +167,16 @@ TEST(DynamicTokenizer, textTokenCollapseWhitespace)
}
}
-TEST(DynamicTokenizer, simpleReadToken)
+TEST(Tokenizer, simpleReadToken)
{
CharReader reader{"test1:test2"};
- DynamicTokenizer tokenizer;
+ Tokenizer tokenizer;
const TokenTypeId tid = tokenizer.registerToken(":");
ASSERT_EQ(0U, tid);
{
- DynamicToken token;
+ Token token;
ASSERT_TRUE(tokenizer.read(reader, token));
ASSERT_EQ(TextToken, token.type);
@@ -192,7 +192,7 @@ TEST(DynamicTokenizer, simpleReadToken)
}
{
- DynamicToken token;
+ Token token;
ASSERT_TRUE(tokenizer.read(reader, token));
ASSERT_EQ(tid, token.type);
@@ -208,7 +208,7 @@ TEST(DynamicTokenizer, simpleReadToken)
}
{
- DynamicToken token;
+ Token token;
ASSERT_TRUE(tokenizer.read(reader, token));
ASSERT_EQ(TextToken, token.type);
@@ -223,16 +223,16 @@ TEST(DynamicTokenizer, simpleReadToken)
}
}
-TEST(DynamicTokenizer, simplePeekToken)
+TEST(Tokenizer, simplePeekToken)
{
CharReader reader{"test1:test2"};
- DynamicTokenizer tokenizer;
+ Tokenizer tokenizer;
const TokenTypeId tid = tokenizer.registerToken(":");
ASSERT_EQ(0U, tid);
{
- DynamicToken token;
+ Token token;
ASSERT_TRUE(tokenizer.peek(reader, token));
ASSERT_EQ(TextToken, token.type);
@@ -246,7 +246,7 @@ TEST(DynamicTokenizer, simplePeekToken)
}
{
- DynamicToken token;
+ Token token;
ASSERT_TRUE(tokenizer.peek(reader, token));
ASSERT_EQ(tid, token.type);
@@ -260,7 +260,7 @@ TEST(DynamicTokenizer, simplePeekToken)
}
{
- DynamicToken token;
+ Token token;
ASSERT_TRUE(tokenizer.peek(reader, token));
ASSERT_EQ(TextToken, token.type);
@@ -274,7 +274,7 @@ TEST(DynamicTokenizer, simplePeekToken)
}
{
- DynamicToken token;
+ Token token;
ASSERT_TRUE(tokenizer.read(reader, token));
ASSERT_EQ(TextToken, token.type);
@@ -288,7 +288,7 @@ TEST(DynamicTokenizer, simplePeekToken)
}
{
- DynamicToken token;
+ Token token;
ASSERT_TRUE(tokenizer.read(reader, token));
ASSERT_EQ(tid, token.type);
@@ -302,7 +302,7 @@ TEST(DynamicTokenizer, simplePeekToken)
}
{
- DynamicToken token;
+ Token token;
ASSERT_TRUE(tokenizer.read(reader, token));
ASSERT_EQ(TextToken, token.type);
@@ -316,10 +316,10 @@ TEST(DynamicTokenizer, simplePeekToken)
}
}
-TEST(DynamicTokenizer, ambiguousTokens)
+TEST(Tokenizer, ambiguousTokens)
{
CharReader reader{"abc"};
- DynamicTokenizer tokenizer;
+ Tokenizer tokenizer;
TokenTypeId t1 = tokenizer.registerToken("abd");
TokenTypeId t2 = tokenizer.registerToken("bc");
@@ -327,7 +327,7 @@ TEST(DynamicTokenizer, ambiguousTokens)
ASSERT_EQ(0U, t1);
ASSERT_EQ(1U, t2);
- DynamicToken token;
+ Token token;
ASSERT_TRUE(tokenizer.read(reader, token));
ASSERT_EQ(TextToken, token.type);
@@ -349,18 +349,18 @@ TEST(DynamicTokenizer, ambiguousTokens)
ASSERT_FALSE(tokenizer.read(reader, token));
}
-TEST(DynamicTokenizer, commentTestWhitespacePreserve)
+TEST(Tokenizer, commentTestWhitespacePreserve)
{
CharReader reader{"Test/Test /* Block Comment */", 0};
// 012345678901234567890123456789
// 0 1 2
- DynamicTokenizer tokenizer(WhitespaceMode::PRESERVE);
+ Tokenizer tokenizer(WhitespaceMode::PRESERVE);
const TokenTypeId t1 = tokenizer.registerToken("/");
const TokenTypeId t2 = tokenizer.registerToken("/*");
const TokenTypeId t3 = tokenizer.registerToken("*/");
- std::vector<DynamicToken> expected = {
+ std::vector<Token> expected = {
{TextToken, "Test", SourceLocation{0, 0, 4}},
{t1, "/", SourceLocation{0, 4, 5}},
{TextToken, "Test ", SourceLocation{0, 5, 10}},
@@ -368,7 +368,7 @@ TEST(DynamicTokenizer, commentTestWhitespacePreserve)
{TextToken, " Block Comment ", SourceLocation{0, 12, 27}},
{t3, "*/", SourceLocation{0, 27, 29}}};
- DynamicToken t;
+ Token t;
for (auto &te : expected) {
EXPECT_TRUE(tokenizer.read(reader, t));
EXPECT_EQ(te.type, t.type);
@@ -380,18 +380,18 @@ TEST(DynamicTokenizer, commentTestWhitespacePreserve)
ASSERT_FALSE(tokenizer.read(reader, t));
}
-TEST(DynamicTokenizer, commentTestWhitespaceCollapse)
+TEST(Tokenizer, commentTestWhitespaceCollapse)
{
CharReader reader{"Test/Test /* Block Comment */", 0};
// 012345678901234567890123456789
// 0 1 2
- DynamicTokenizer tokenizer(WhitespaceMode::COLLAPSE);
+ Tokenizer tokenizer(WhitespaceMode::COLLAPSE);
const TokenTypeId t1 = tokenizer.registerToken("/");
const TokenTypeId t2 = tokenizer.registerToken("/*");
const TokenTypeId t3 = tokenizer.registerToken("*/");
- std::vector<DynamicToken> expected = {
+ std::vector<Token> expected = {
{TextToken, "Test", SourceLocation{0, 0, 4}},
{t1, "/", SourceLocation{0, 4, 5}},
{TextToken, "Test", SourceLocation{0, 5, 9}},
@@ -399,7 +399,7 @@ TEST(DynamicTokenizer, commentTestWhitespaceCollapse)
{TextToken, "Block Comment", SourceLocation{0, 13, 26}},
{t3, "*/", SourceLocation{0, 27, 29}}};
- DynamicToken t;
+ Token t;
for (auto &te : expected) {
EXPECT_TRUE(tokenizer.read(reader, t));
EXPECT_EQ(te.type, t.type);
@@ -410,6 +410,5 @@ TEST(DynamicTokenizer, commentTestWhitespaceCollapse)
}
ASSERT_FALSE(tokenizer.read(reader, t));
}
-
}
diff --git a/test/formats/osdm/OsdmStreamParserTest.cpp b/test/formats/osml/OsmlStreamParserTest.cpp
index 46f4cf6..d52fa5b 100644
--- a/test/formats/osdm/OsdmStreamParserTest.cpp
+++ b/test/formats/osml/OsmlStreamParserTest.cpp
@@ -23,95 +23,205 @@
#include <core/common/CharReader.hpp>
#include <core/frontend/TerminalLogger.hpp>
-#include <formats/osdm/OsdmStreamParser.hpp>
+#include <formats/osml/OsmlStreamParser.hpp>
namespace ousia {
static TerminalLogger logger(std::cerr, true);
+// static ConcreteLogger logger;
-TEST(OsdmStreamParser, empty)
+static void assertCommand(OsmlStreamParser &reader, const std::string &name,
+ SourceOffset start = InvalidSourceOffset,
+ SourceOffset end = InvalidSourceOffset)
+{
+ ASSERT_EQ(OsmlStreamParser::State::COMMAND, reader.parse());
+ EXPECT_EQ(name, reader.getCommandName().asString());
+ if (start != InvalidSourceOffset) {
+ EXPECT_EQ(start, reader.getCommandName().getLocation().getStart());
+ EXPECT_EQ(start, reader.getLocation().getStart());
+ }
+ if (end != InvalidSourceOffset) {
+ EXPECT_EQ(end, reader.getCommandName().getLocation().getEnd());
+ EXPECT_EQ(end, reader.getLocation().getEnd());
+ }
+}
+
+static void assertCommand(OsmlStreamParser &reader, const std::string &name,
+ const Variant::mapType &args,
+ SourceOffset start = InvalidSourceOffset,
+ SourceOffset end = InvalidSourceOffset)
+{
+ assertCommand(reader, name, start, end);
+ EXPECT_EQ(args, reader.getCommandArguments());
+}
+
+static void assertData(OsmlStreamParser &reader, const std::string &data,
+ SourceOffset start = InvalidSourceOffset,
+ SourceOffset end = InvalidSourceOffset)
+{
+ ASSERT_EQ(OsmlStreamParser::State::DATA, reader.parse());
+ EXPECT_EQ(data, reader.getData().asString());
+ if (start != InvalidSourceOffset) {
+ EXPECT_EQ(start, reader.getData().getLocation().getStart());
+ EXPECT_EQ(start, reader.getLocation().getStart());
+ }
+ if (end != InvalidSourceOffset) {
+ EXPECT_EQ(end, reader.getData().getLocation().getEnd());
+ EXPECT_EQ(end, reader.getLocation().getEnd());
+ }
+}
+
+static void assertFieldStart(OsmlStreamParser &reader, bool defaultField,
+ SourceOffset start = InvalidSourceOffset,
+ SourceOffset end = InvalidSourceOffset)
+{
+ ASSERT_EQ(OsmlStreamParser::State::FIELD_START, reader.parse());
+ EXPECT_EQ(defaultField, reader.inDefaultField());
+ if (start != InvalidSourceOffset) {
+ EXPECT_EQ(start, reader.getLocation().getStart());
+ }
+ if (end != InvalidSourceOffset) {
+ EXPECT_EQ(end, reader.getLocation().getEnd());
+ }
+}
+
+static void assertFieldEnd(OsmlStreamParser &reader,
+ SourceOffset start = InvalidSourceOffset,
+ SourceOffset end = InvalidSourceOffset)
+{
+ ASSERT_EQ(OsmlStreamParser::State::FIELD_END, reader.parse());
+ if (start != InvalidSourceOffset) {
+ EXPECT_EQ(start, reader.getLocation().getStart());
+ }
+ if (end != InvalidSourceOffset) {
+ EXPECT_EQ(end, reader.getLocation().getEnd());
+ }
+}
+
+static void assertAnnotationStart(OsmlStreamParser &reader,
+ const std::string &name,
+ SourceOffset start = InvalidSourceOffset,
+ SourceOffset end = InvalidSourceOffset)
+{
+ ASSERT_EQ(OsmlStreamParser::State::ANNOTATION_START, reader.parse());
+ EXPECT_EQ(name, reader.getCommandName().asString());
+ if (start != InvalidSourceOffset) {
+ EXPECT_EQ(start, reader.getCommandName().getLocation().getStart());
+ EXPECT_EQ(start, reader.getLocation().getStart());
+ }
+ if (end != InvalidSourceOffset) {
+ EXPECT_EQ(end, reader.getCommandName().getLocation().getEnd());
+ EXPECT_EQ(end, reader.getLocation().getEnd());
+ }
+}
+
+static void assertAnnotationStart(OsmlStreamParser &reader,
+ const std::string &name,
+ const Variant::mapType &args,
+ SourceOffset start = InvalidSourceOffset,
+ SourceOffset end = InvalidSourceOffset)
+{
+ assertAnnotationStart(reader, name, start, end);
+ EXPECT_EQ(args, reader.getCommandArguments());
+}
+
+static void assertAnnotationEnd(OsmlStreamParser &reader,
+ const std::string &name,
+ const std::string &elementName,
+ SourceOffset start = InvalidSourceOffset,
+ SourceOffset end = InvalidSourceOffset)
+{
+ ASSERT_EQ(OsmlStreamParser::State::ANNOTATION_END, reader.parse());
+ ASSERT_EQ(name, reader.getCommandName().asString());
+ if (!elementName.empty()) {
+ ASSERT_EQ(1U, reader.getCommandArguments().asMap().size());
+ ASSERT_EQ(1U, reader.getCommandArguments().asMap().count("name"));
+
+ auto it = reader.getCommandArguments().asMap().find("name");
+ ASSERT_EQ(elementName, it->second.asString());
+ }
+ if (start != InvalidSourceOffset) {
+ EXPECT_EQ(start, reader.getLocation().getStart());
+ }
+ if (end != InvalidSourceOffset) {
+ EXPECT_EQ(end, reader.getLocation().getEnd());
+ }
+}
+
+static void assertEnd(OsmlStreamParser &reader,
+ SourceOffset start = InvalidSourceOffset,
+ SourceOffset end = InvalidSourceOffset)
+{
+ ASSERT_EQ(OsmlStreamParser::State::END, reader.parse());
+ if (start != InvalidSourceOffset) {
+ EXPECT_EQ(start, reader.getLocation().getStart());
+ }
+ if (end != InvalidSourceOffset) {
+ EXPECT_EQ(end, reader.getLocation().getEnd());
+ }
+}
+
+TEST(OsmlStreamParser, empty)
{
const char *testString = "";
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
- ASSERT_EQ(OsdmStreamParser::State::END, reader.parse());
+ ASSERT_EQ(OsmlStreamParser::State::END, reader.parse());
}
-TEST(OsdmStreamParser, oneCharacter)
+TEST(OsmlStreamParser, oneCharacter)
{
const char *testString = "a";
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
-
- ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse());
- ASSERT_EQ("a", reader.getData().asString());
+ OsmlStreamParser reader(charReader, logger);
- SourceLocation loc = reader.getData().getLocation();
- ASSERT_EQ(0U, loc.getStart());
- ASSERT_EQ(1U, loc.getEnd());
+ assertData(reader, "a", 0, 1);
}
-TEST(OsdmStreamParser, whitespaceElimination)
+TEST(OsmlStreamParser, whitespaceElimination)
{
const char *testString = " hello \t world ";
// 0123456 78901234
// 0 1
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
-
- ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse());
- ASSERT_EQ("hello world", reader.getData().asString());
+ OsmlStreamParser reader(charReader, logger);
- SourceLocation loc = reader.getData().getLocation();
- ASSERT_EQ(1U, loc.getStart());
- ASSERT_EQ(14U, loc.getEnd());
+ assertData(reader, "hello world", 1, 14);
}
-TEST(OsdmStreamParser, whitespaceEliminationWithLinebreak)
+TEST(OsmlStreamParser, whitespaceEliminationWithLinebreak)
{
const char *testString = " hello \n world ";
// 0123456 78901234
// 0 1
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
-
- ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse());
- ASSERT_EQ("hello world", reader.getData().asString());
+ OsmlStreamParser reader(charReader, logger);
- SourceLocation loc = reader.getData().getLocation();
- ASSERT_EQ(1U, loc.getStart());
- ASSERT_EQ(14U, loc.getEnd());
- ASSERT_EQ(OsdmStreamParser::State::END, reader.parse());
+ assertData(reader, "hello world", 1, 14);
}
-TEST(OsdmStreamParser, escapeWhitespace)
+TEST(OsmlStreamParser, escapeWhitespace)
{
const char *testString = " hello\\ \\ world ";
// 012345 67 89012345
// 0 1
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
- ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse());
- ASSERT_EQ("hello world", reader.getData().asString());
-
- SourceLocation loc = reader.getData().getLocation();
- ASSERT_EQ(1U, loc.getStart());
- ASSERT_EQ(15U, loc.getEnd());
- ASSERT_EQ(OsdmStreamParser::State::END, reader.parse());
+ assertData(reader, "hello world", 1, 15);
}
static void testEscapeSpecialCharacter(const std::string &c)
{
CharReader charReader(std::string("\\") + c);
- OsdmStreamParser reader(charReader, logger);
- EXPECT_EQ(OsdmStreamParser::State::DATA, reader.parse());
+ OsmlStreamParser reader(charReader, logger);
+ EXPECT_EQ(OsmlStreamParser::State::DATA, reader.parse());
EXPECT_EQ(c, reader.getData().asString());
SourceLocation loc = reader.getData().getLocation();
@@ -119,32 +229,30 @@ static void testEscapeSpecialCharacter(const std::string &c)
EXPECT_EQ(1U + c.size(), loc.getEnd());
}
-TEST(OsdmStreamParser, escapeSpecialCharacters)
+TEST(OsmlStreamParser, escapeSpecialCharacters)
{
testEscapeSpecialCharacter("\\");
testEscapeSpecialCharacter("{");
testEscapeSpecialCharacter("}");
- testEscapeSpecialCharacter("<");
- testEscapeSpecialCharacter(">");
}
-TEST(OsdmStreamParser, simpleSingleLineComment)
+TEST(OsmlStreamParser, simpleSingleLineComment)
{
const char *testString = "% This is a single line comment";
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
- ASSERT_EQ(OsdmStreamParser::State::END, reader.parse());
+ OsmlStreamParser reader(charReader, logger);
+ ASSERT_EQ(OsmlStreamParser::State::END, reader.parse());
}
-TEST(OsdmStreamParser, singleLineComment)
+TEST(OsmlStreamParser, singleLineComment)
{
const char *testString = "a% This is a single line comment\nb";
// 01234567890123456789012345678901 23
// 0 1 2 3
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
{
- ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse());
+ ASSERT_EQ(OsmlStreamParser::State::DATA, reader.parse());
ASSERT_EQ("a", reader.getData().asString());
SourceLocation loc = reader.getData().getLocation();
ASSERT_EQ(0U, loc.getStart());
@@ -152,25 +260,25 @@ TEST(OsdmStreamParser, singleLineComment)
}
{
- ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse());
+ ASSERT_EQ(OsmlStreamParser::State::DATA, reader.parse());
ASSERT_EQ("b", reader.getData().asString());
SourceLocation loc = reader.getData().getLocation();
ASSERT_EQ(33U, loc.getStart());
ASSERT_EQ(34U, loc.getEnd());
}
- ASSERT_EQ(OsdmStreamParser::State::END, reader.parse());
+ ASSERT_EQ(OsmlStreamParser::State::END, reader.parse());
}
-TEST(OsdmStreamParser, multilineComment)
+TEST(OsmlStreamParser, multilineComment)
{
const char *testString = "a%{ This is a\n\n multiline line comment}%b";
// 0123456789012 3 456789012345678901234567890
// 0 1 2 3 4
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
{
- ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse());
+ ASSERT_EQ(OsmlStreamParser::State::DATA, reader.parse());
ASSERT_EQ("a", reader.getData().asString());
SourceLocation loc = reader.getData().getLocation();
ASSERT_EQ(0U, loc.getStart());
@@ -178,25 +286,25 @@ TEST(OsdmStreamParser, multilineComment)
}
{
- ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse());
+ ASSERT_EQ(OsmlStreamParser::State::DATA, reader.parse());
ASSERT_EQ("b", reader.getData().asString());
SourceLocation loc = reader.getData().getLocation();
ASSERT_EQ(40U, loc.getStart());
ASSERT_EQ(41U, loc.getEnd());
}
- ASSERT_EQ(OsdmStreamParser::State::END, reader.parse());
+ ASSERT_EQ(OsmlStreamParser::State::END, reader.parse());
}
-TEST(OsdmStreamParser, nestedMultilineComment)
+TEST(OsmlStreamParser, nestedMultilineComment)
{
const char *testString = "a%{%{Another\n\n}%multiline line comment}%b";
// 0123456789012 3 456789012345678901234567890
// 0 1 2 3 4
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
{
- ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse());
+ ASSERT_EQ(OsmlStreamParser::State::DATA, reader.parse());
ASSERT_EQ("a", reader.getData().asString());
SourceLocation loc = reader.getData().getLocation();
ASSERT_EQ(0U, loc.getStart());
@@ -204,23 +312,23 @@ TEST(OsdmStreamParser, nestedMultilineComment)
}
{
- ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse());
+ ASSERT_EQ(OsmlStreamParser::State::DATA, reader.parse());
ASSERT_EQ("b", reader.getData().asString());
SourceLocation loc = reader.getData().getLocation();
ASSERT_EQ(40U, loc.getStart());
ASSERT_EQ(41U, loc.getEnd());
}
- ASSERT_EQ(OsdmStreamParser::State::END, reader.parse());
+ ASSERT_EQ(OsmlStreamParser::State::END, reader.parse());
}
-TEST(OsdmStreamParser, simpleCommand)
+TEST(OsmlStreamParser, simpleCommand)
{
const char *testString = "\\test";
// 0 12345
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
- ASSERT_EQ(OsdmStreamParser::State::COMMAND, reader.parse());
+ OsmlStreamParser reader(charReader, logger);
+ ASSERT_EQ(OsmlStreamParser::State::COMMAND, reader.parse());
Variant commandName = reader.getCommandName();
ASSERT_EQ("test", commandName.asString());
@@ -230,16 +338,16 @@ TEST(OsdmStreamParser, simpleCommand)
ASSERT_EQ(5U, loc.getEnd());
ASSERT_EQ(0U, reader.getCommandArguments().asMap().size());
- ASSERT_EQ(OsdmStreamParser::State::END, reader.parse());
+ ASSERT_EQ(OsmlStreamParser::State::END, reader.parse());
}
-TEST(OsdmStreamParser, simpleCommandWithName)
+TEST(OsmlStreamParser, simpleCommandWithName)
{
const char *testString = "\\test#bla";
// 0 12345678
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
- ASSERT_EQ(OsdmStreamParser::State::COMMAND, reader.parse());
+ OsmlStreamParser reader(charReader, logger);
+ ASSERT_EQ(OsmlStreamParser::State::COMMAND, reader.parse());
Variant commandName = reader.getCommandName();
ASSERT_EQ("test", commandName.asString());
@@ -257,17 +365,17 @@ TEST(OsdmStreamParser, simpleCommandWithName)
ASSERT_EQ(5U, loc.getStart());
ASSERT_EQ(9U, loc.getEnd());
- ASSERT_EQ(OsdmStreamParser::State::END, reader.parse());
+ ASSERT_EQ(OsmlStreamParser::State::END, reader.parse());
}
-TEST(OsdmStreamParser, simpleCommandWithArguments)
+TEST(OsmlStreamParser, simpleCommandWithArguments)
{
const char *testString = "\\test[a=1,b=2,c=\"test\"]";
// 0 123456789012345 678901 2
// 0 1 2
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
- ASSERT_EQ(OsdmStreamParser::State::COMMAND, reader.parse());
+ OsmlStreamParser reader(charReader, logger);
+ ASSERT_EQ(OsmlStreamParser::State::COMMAND, reader.parse());
Variant commandName = reader.getCommandName();
ASSERT_EQ("test", commandName.asString());
@@ -297,17 +405,17 @@ TEST(OsdmStreamParser, simpleCommandWithArguments)
ASSERT_EQ(16U, loc.getStart());
ASSERT_EQ(22U, loc.getEnd());
- ASSERT_EQ(OsdmStreamParser::State::END, reader.parse());
+ ASSERT_EQ(OsmlStreamParser::State::END, reader.parse());
}
-TEST(OsdmStreamParser, simpleCommandWithArgumentsAndName)
+TEST(OsmlStreamParser, simpleCommandWithArgumentsAndName)
{
const char *testString = "\\test#bla[a=1,b=2,c=\"test\"]";
// 0 1234567890123456789 01234 56
// 0 1 2
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
- ASSERT_EQ(OsdmStreamParser::State::COMMAND, reader.parse());
+ OsmlStreamParser reader(charReader, logger);
+ ASSERT_EQ(OsmlStreamParser::State::COMMAND, reader.parse());
Variant commandName = reader.getCommandName();
ASSERT_EQ("test", commandName.asString());
@@ -343,126 +451,46 @@ TEST(OsdmStreamParser, simpleCommandWithArgumentsAndName)
ASSERT_EQ(5U, loc.getStart());
ASSERT_EQ(9U, loc.getEnd());
- ASSERT_EQ(OsdmStreamParser::State::END, reader.parse());
+ ASSERT_EQ(OsmlStreamParser::State::END, reader.parse());
}
-static void assertCommand(OsdmStreamParser &reader, const std::string &name,
- SourceOffset start = InvalidSourceOffset,
- SourceOffset end = InvalidSourceOffset)
-{
- ASSERT_EQ(OsdmStreamParser::State::COMMAND, reader.parse());
- EXPECT_EQ(name, reader.getCommandName().asString());
- if (start != InvalidSourceOffset) {
- EXPECT_EQ(start, reader.getCommandName().getLocation().getStart());
- EXPECT_EQ(start, reader.getLocation().getStart());
- }
- if (end != InvalidSourceOffset) {
- EXPECT_EQ(end, reader.getCommandName().getLocation().getEnd());
- EXPECT_EQ(end, reader.getLocation().getEnd());
- }
-}
-
-static void assertCommand(OsdmStreamParser &reader, const std::string &name,
- const Variant::mapType &args,
- SourceOffset start = InvalidSourceOffset,
- SourceOffset end = InvalidSourceOffset)
-{
- assertCommand(reader, name, start, end);
- EXPECT_EQ(args, reader.getCommandArguments());
-}
-
-static void assertData(OsdmStreamParser &reader, const std::string &data,
- SourceOffset start = InvalidSourceOffset,
- SourceOffset end = InvalidSourceOffset)
-{
- ASSERT_EQ(OsdmStreamParser::State::DATA, reader.parse());
- EXPECT_EQ(data, reader.getData().asString());
- if (start != InvalidSourceOffset) {
- EXPECT_EQ(start, reader.getData().getLocation().getStart());
- EXPECT_EQ(start, reader.getLocation().getStart());
- }
- if (end != InvalidSourceOffset) {
- EXPECT_EQ(end, reader.getData().getLocation().getEnd());
- EXPECT_EQ(end, reader.getLocation().getEnd());
- }
-}
-
-static void assertFieldStart(OsdmStreamParser &reader,
- SourceOffset start = InvalidSourceOffset,
- SourceOffset end = InvalidSourceOffset)
-{
- ASSERT_EQ(OsdmStreamParser::State::FIELD_START, reader.parse());
- if (start != InvalidSourceOffset) {
- EXPECT_EQ(start, reader.getLocation().getStart());
- }
- if (end != InvalidSourceOffset) {
- EXPECT_EQ(end, reader.getLocation().getEnd());
- }
-}
-
-static void assertFieldEnd(OsdmStreamParser &reader,
- SourceOffset start = InvalidSourceOffset,
- SourceOffset end = InvalidSourceOffset)
-{
- ASSERT_EQ(OsdmStreamParser::State::FIELD_END, reader.parse());
- if (start != InvalidSourceOffset) {
- EXPECT_EQ(start, reader.getLocation().getStart());
- }
- if (end != InvalidSourceOffset) {
- EXPECT_EQ(end, reader.getLocation().getEnd());
- }
-}
-
-static void assertEnd(OsdmStreamParser &reader,
- SourceOffset start = InvalidSourceOffset,
- SourceOffset end = InvalidSourceOffset)
-{
- ASSERT_EQ(OsdmStreamParser::State::END, reader.parse());
- if (start != InvalidSourceOffset) {
- EXPECT_EQ(start, reader.getLocation().getStart());
- }
- if (end != InvalidSourceOffset) {
- EXPECT_EQ(end, reader.getLocation().getEnd());
- }
-}
-
-TEST(OsdmStreamParser, fields)
+TEST(OsmlStreamParser, fields)
{
const char *testString = "\\test{a}{b}{c}";
// 01234567890123
// 0 1
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
assertCommand(reader, "test", 0, 5);
- assertFieldStart(reader, 5, 6);
+ assertFieldStart(reader, false, 5, 6);
assertData(reader, "a", 6, 7);
assertFieldEnd(reader, 7, 8);
- assertFieldStart(reader, 8, 9);
+ assertFieldStart(reader, false, 8, 9);
assertData(reader, "b", 9, 10);
assertFieldEnd(reader, 10, 11);
- assertFieldStart(reader, 11, 12);
+ assertFieldStart(reader, false, 11, 12);
assertData(reader, "c", 12, 13);
assertFieldEnd(reader, 13, 14);
assertEnd(reader, 14, 14);
}
-TEST(OsdmStreamParser, dataOutsideField)
+TEST(OsmlStreamParser, dataOutsideField)
{
const char *testString = "\\test{a}{b} c";
// 0123456789012
// 0 1
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
assertCommand(reader, "test", 0, 5);
- assertFieldStart(reader, 5, 6);
+ assertFieldStart(reader, false, 5, 6);
assertData(reader, "a", 6, 7);
assertFieldEnd(reader, 7, 8);
- assertFieldStart(reader, 8, 9);
+ assertFieldStart(reader, false, 8, 9);
assertData(reader, "b", 9, 10);
assertFieldEnd(reader, 10, 11);
@@ -470,24 +498,24 @@ TEST(OsdmStreamParser, dataOutsideField)
assertEnd(reader, 13, 13);
}
-TEST(OsdmStreamParser, nestedCommand)
+TEST(OsmlStreamParser, nestedCommand)
{
const char *testString = "\\test{a}{\\test2{b} c} d";
// 012345678 90123456789012
// 0 1 2
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
assertCommand(reader, "test", 0, 5);
- assertFieldStart(reader, 5, 6);
+ assertFieldStart(reader, false, 5, 6);
assertData(reader, "a", 6, 7);
assertFieldEnd(reader, 7, 8);
- assertFieldStart(reader, 8, 9);
+ assertFieldStart(reader, false, 8, 9);
{
assertCommand(reader, "test2", 9, 15);
- assertFieldStart(reader, 15, 16);
+ assertFieldStart(reader, false, 15, 16);
assertData(reader, "b", 16, 17);
assertFieldEnd(reader, 17, 18);
}
@@ -497,19 +525,19 @@ TEST(OsdmStreamParser, nestedCommand)
assertEnd(reader, 23, 23);
}
-TEST(OsdmStreamParser, nestedCommandImmediateEnd)
+TEST(OsmlStreamParser, nestedCommandImmediateEnd)
{
const char *testString = "\\test{\\test2{b}} d";
// 012345 678901234567
// 0 1
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
assertCommand(reader, "test", 0, 5);
- assertFieldStart(reader, 5, 6);
+ assertFieldStart(reader, false, 5, 6);
{
assertCommand(reader, "test2", 6, 12);
- assertFieldStart(reader, 12, 13);
+ assertFieldStart(reader, false, 12, 13);
assertData(reader, "b", 13, 14);
assertFieldEnd(reader, 14, 15);
}
@@ -518,27 +546,27 @@ TEST(OsdmStreamParser, nestedCommandImmediateEnd)
assertEnd(reader, 18, 18);
}
-TEST(OsdmStreamParser, nestedCommandNoData)
+TEST(OsmlStreamParser, nestedCommandNoData)
{
const char *testString = "\\test{\\test2}";
// 012345 6789012
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
assertCommand(reader, "test", 0, 5);
- assertFieldStart(reader, 5, 6);
+ assertFieldStart(reader, false, 5, 6);
assertCommand(reader, "test2", 6, 12);
assertFieldEnd(reader, 12, 13);
assertEnd(reader, 13, 13);
}
-TEST(OsdmStreamParser, multipleCommands)
+TEST(OsmlStreamParser, multipleCommands)
{
const char *testString = "\\a \\b \\c \\d";
// 012 345 678 90
// 0 1
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
assertCommand(reader, "a", 0, 2);
assertCommand(reader, "b", 3, 5);
@@ -547,33 +575,33 @@ TEST(OsdmStreamParser, multipleCommands)
assertEnd(reader, 11, 11);
}
-TEST(OsdmStreamParser, fieldsWithSpaces)
+TEST(OsmlStreamParser, fieldsWithSpaces)
{
const char *testString = "\\a {\\b \\c} \n\n {\\d}";
// 0123 456 789012 3 456 789
// 0 1
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
assertCommand(reader, "a", 0, 2);
- assertFieldStart(reader, 3, 4);
+ assertFieldStart(reader, false, 3, 4);
assertCommand(reader, "b", 4, 6);
assertCommand(reader, "c", 7, 9);
assertFieldEnd(reader, 9, 10);
- assertFieldStart(reader, 16, 17);
+ assertFieldStart(reader, false, 16, 17);
assertCommand(reader, "d", 17, 19);
assertFieldEnd(reader, 19, 20);
assertEnd(reader, 20, 20);
}
-TEST(OsdmStreamParser, errorNoFieldToStart)
+TEST(OsmlStreamParser, errorNoFieldToStart)
{
const char *testString = "\\a b {";
// 012345
// 0
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
logger.reset();
assertCommand(reader, "a", 0, 2);
@@ -583,14 +611,14 @@ TEST(OsdmStreamParser, errorNoFieldToStart)
ASSERT_TRUE(logger.hasError());
}
-TEST(OsdmStreamParser, errorNoFieldToEnd)
+TEST(OsmlStreamParser, errorNoFieldToEnd)
{
const char *testString = "\\a b }";
// 012345
// 0
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
logger.reset();
assertCommand(reader, "a", 0, 2);
@@ -600,20 +628,20 @@ TEST(OsdmStreamParser, errorNoFieldToEnd)
ASSERT_TRUE(logger.hasError());
}
-TEST(OsdmStreamParser, errorNoFieldEndNested)
+TEST(OsmlStreamParser, errorNoFieldEndNested)
{
const char *testString = "\\test{\\test2{}}}";
// 012345 6789012345
// 0 1
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
logger.reset();
assertCommand(reader, "test", 0, 5);
- assertFieldStart(reader, 5, 6);
+ assertFieldStart(reader, false, 5, 6);
assertCommand(reader, "test2", 6, 12);
- assertFieldStart(reader, 12, 13);
+ assertFieldStart(reader, false, 12, 13);
assertFieldEnd(reader, 13, 14);
assertFieldEnd(reader, 14, 15);
ASSERT_FALSE(logger.hasError());
@@ -621,20 +649,20 @@ TEST(OsdmStreamParser, errorNoFieldEndNested)
ASSERT_TRUE(logger.hasError());
}
-TEST(OsdmStreamParser, errorNoFieldEndNestedData)
+TEST(OsmlStreamParser, errorNoFieldEndNestedData)
{
const char *testString = "\\test{\\test2{}}a}";
// 012345 67890123456
// 0 1
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
logger.reset();
assertCommand(reader, "test", 0, 5);
- assertFieldStart(reader, 5, 6);
+ assertFieldStart(reader, false, 5, 6);
assertCommand(reader, "test2", 6, 12);
- assertFieldStart(reader, 12, 13);
+ assertFieldStart(reader, false, 12, 13);
assertFieldEnd(reader, 13, 14);
assertFieldEnd(reader, 14, 15);
assertData(reader, "a", 15, 16);
@@ -643,53 +671,53 @@ TEST(OsdmStreamParser, errorNoFieldEndNestedData)
ASSERT_TRUE(logger.hasError());
}
-TEST(OsdmStreamParser, beginEnd)
+TEST(OsmlStreamParser, beginEnd)
{
const char *testString = "\\begin{book}\\end{book}";
// 012345678901 2345678901
// 0 1 2
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
assertCommand(reader, "book", 7, 11);
- assertFieldStart(reader, 12, 13);
+ assertFieldStart(reader, true, 12, 13);
assertFieldEnd(reader, 17, 21);
assertEnd(reader, 22, 22);
}
-TEST(OsdmStreamParser, beginEndWithName)
+TEST(OsmlStreamParser, beginEndWithName)
{
const char *testString = "\\begin{book#a}\\end{book}";
// 01234567890123 4567890123
// 0 1 2
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
assertCommand(reader, "book", {{"name", "a"}}, 7, 11);
- assertFieldStart(reader, 14, 15);
+ assertFieldStart(reader, true, 14, 15);
assertFieldEnd(reader, 19, 23);
assertEnd(reader, 24, 24);
}
-TEST(OsdmStreamParser, beginEndWithNameAndArgs)
+TEST(OsmlStreamParser, beginEndWithNameAndArgs)
{
const char *testString = "\\begin{book#a}[a=1,b=2,c=\"test\"]\\end{book}";
// 0123456789012345678901234 56789 01 2345678901
// 0 1 2 3 4
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
assertCommand(reader, "book",
{{"name", "a"}, {"a", 1}, {"b", 2}, {"c", "test"}}, 7, 11);
- assertFieldStart(reader, 32, 33);
+ assertFieldStart(reader, true, 32, 33);
assertFieldEnd(reader, 37, 41);
assertEnd(reader, 42, 42);
}
-TEST(OsdmStreamParser, beginEndWithNameAndArgsMultipleFields)
+TEST(OsmlStreamParser, beginEndWithNameAndArgsMultipleFields)
{
const char *testString =
"\\begin{book#a}[a=1,b=2,c=\"test\"]{a \\test}{b \\test{}}\\end{book}";
@@ -697,67 +725,100 @@ TEST(OsdmStreamParser, beginEndWithNameAndArgsMultipleFields)
// 0 1 2 3 4 5 6
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
assertCommand(reader, "book",
{{"name", "a"}, {"a", 1}, {"b", 2}, {"c", "test"}}, 7, 11);
- assertFieldStart(reader, 32, 33);
+ assertFieldStart(reader, false, 32, 33);
assertData(reader, "a", 33, 34);
assertCommand(reader, "test", Variant::mapType{}, 35, 40);
assertFieldEnd(reader, 40, 41);
- assertFieldStart(reader, 41, 42);
+ assertFieldStart(reader, false, 41, 42);
assertData(reader, "b", 42, 43);
assertCommand(reader, "test", Variant::mapType{}, 44, 49);
- assertFieldStart(reader, 49, 50);
+ assertFieldStart(reader, false, 49, 50);
assertFieldEnd(reader, 50, 51);
assertFieldEnd(reader, 51, 52);
- assertFieldStart(reader, 52, 53);
+ assertFieldStart(reader, true, 52, 53);
assertFieldEnd(reader, 57, 61);
assertEnd(reader, 62, 62);
}
-TEST(OsdmStreamParser, beginEndWithData)
+TEST(OsmlStreamParser, beginEndWithData)
{
const char *testString = "\\begin{book}a\\end{book}";
// 0123456789012 3456789012
// 0 1 2
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
assertCommand(reader, "book", 7, 11);
- assertFieldStart(reader, 12, 13);
+ assertFieldStart(reader, true, 12, 13);
assertData(reader, "a", 12, 13);
assertFieldEnd(reader, 18, 22);
assertEnd(reader, 23, 23);
}
-TEST(OsdmStreamParser, beginEndWithCommand)
+TEST(OsmlStreamParser, beginEndNested)
+{
+ const char *testString =
+ "\\begin{a}{b} c \\begin{d}{e}{f} \\g{h} \\end{d}\\end{a}";
+ // 012345678901234 5678901234567890 123456 7890123 4567890
+ // 0 1 2 3 4 5
+ CharReader charReader(testString);
+
+ OsmlStreamParser reader(charReader, logger);
+
+ assertCommand(reader, "a", 7, 8);
+ assertFieldStart(reader, false, 9, 10);
+ assertData(reader, "b", 10, 11);
+ assertFieldEnd(reader, 11, 12);
+ assertFieldStart(reader, true, 13, 14);
+ assertData(reader, "c", 13, 14);
+ assertCommand(reader, "d", 22, 23);
+ assertFieldStart(reader, false, 24, 25);
+ assertData(reader, "e", 25, 26);
+ assertFieldEnd(reader, 26, 27);
+ assertFieldStart(reader, false, 27, 28);
+ assertData(reader, "f", 28, 29);
+ assertFieldEnd(reader, 29, 30);
+ assertFieldStart(reader, true, 31, 32);
+ assertCommand(reader, "g", 31, 33);
+ assertFieldStart(reader, false, 33, 34);
+ assertData(reader, "h", 34, 35);
+ assertFieldEnd(reader, 35, 36);
+ assertFieldEnd(reader, 42, 43);
+ assertFieldEnd(reader, 49, 50);
+ assertEnd(reader, 51, 51);
+}
+
+TEST(OsmlStreamParser, beginEndWithCommand)
{
const char *testString = "\\begin{book}\\a{test}\\end{book}";
// 012345678901 23456789 0123456789
// 0 1 2
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
assertCommand(reader, "book", 7, 11);
- assertFieldStart(reader, 12, 13);
+ assertFieldStart(reader, true, 12, 13);
assertCommand(reader, "a", 12, 14);
- assertFieldStart(reader, 14, 15);
+ assertFieldStart(reader, false, 14, 15);
assertData(reader, "test", 15, 19);
assertFieldEnd(reader, 19, 20);
assertFieldEnd(reader, 25, 29);
assertEnd(reader, 30, 30);
}
-TEST(OsdmStreamParser, errorBeginNoBraceOpen)
+TEST(OsmlStreamParser, errorBeginNoBraceOpen)
{
const char *testString = "\\begin a";
// 01234567
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
logger.reset();
ASSERT_FALSE(logger.hasError());
@@ -765,12 +826,12 @@ TEST(OsdmStreamParser, errorBeginNoBraceOpen)
ASSERT_TRUE(logger.hasError());
}
-TEST(OsdmStreamParser, errorBeginNoIdentifier)
+TEST(OsmlStreamParser, errorBeginNoIdentifier)
{
const char *testString = "\\begin{!";
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
logger.reset();
ASSERT_FALSE(logger.hasError());
@@ -778,12 +839,12 @@ TEST(OsdmStreamParser, errorBeginNoIdentifier)
ASSERT_TRUE(logger.hasError());
}
-TEST(OsdmStreamParser, errorBeginNoBraceClose)
+TEST(OsmlStreamParser, errorBeginNoBraceClose)
{
const char *testString = "\\begin{a";
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
logger.reset();
ASSERT_FALSE(logger.hasError());
@@ -791,12 +852,12 @@ TEST(OsdmStreamParser, errorBeginNoBraceClose)
ASSERT_TRUE(logger.hasError());
}
-TEST(OsdmStreamParser, errorBeginNoName)
+TEST(OsmlStreamParser, errorBeginNoName)
{
const char *testString = "\\begin{a#}";
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
logger.reset();
ASSERT_FALSE(logger.hasError());
@@ -808,13 +869,13 @@ TEST(OsdmStreamParser, errorBeginNoName)
ASSERT_TRUE(logger.hasError());
}
-TEST(OsdmStreamParser, errorEndNoBraceOpen)
+TEST(OsmlStreamParser, errorEndNoBraceOpen)
{
const char *testString = "\\end a";
// 012345
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
logger.reset();
ASSERT_FALSE(logger.hasError());
@@ -822,12 +883,12 @@ TEST(OsdmStreamParser, errorEndNoBraceOpen)
ASSERT_TRUE(logger.hasError());
}
-TEST(OsdmStreamParser, errorEndNoIdentifier)
+TEST(OsmlStreamParser, errorEndNoIdentifier)
{
const char *testString = "\\end{!";
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
logger.reset();
ASSERT_FALSE(logger.hasError());
@@ -835,12 +896,12 @@ TEST(OsdmStreamParser, errorEndNoIdentifier)
ASSERT_TRUE(logger.hasError());
}
-TEST(OsdmStreamParser, errorEndNoBraceClose)
+TEST(OsmlStreamParser, errorEndNoBraceClose)
{
const char *testString = "\\end{a";
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
logger.reset();
ASSERT_FALSE(logger.hasError());
@@ -848,12 +909,12 @@ TEST(OsdmStreamParser, errorEndNoBraceClose)
ASSERT_TRUE(logger.hasError());
}
-TEST(OsdmStreamParser, errorEndNoBegin)
+TEST(OsmlStreamParser, errorEndNoBegin)
{
const char *testString = "\\end{a}";
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
logger.reset();
ASSERT_FALSE(logger.hasError());
@@ -861,91 +922,91 @@ TEST(OsdmStreamParser, errorEndNoBegin)
ASSERT_TRUE(logger.hasError());
}
-TEST(OsdmStreamParser, errorBeginEndMismatch)
+TEST(OsmlStreamParser, errorBeginEndMismatch)
{
const char *testString = "\\begin{a} \\begin{b} test \\end{a}";
// 0123456789 012345678901234 5678901
// 0 1 2 3
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
logger.reset();
assertCommand(reader, "a", 7, 8);
- assertFieldStart(reader, 10, 11);
+ assertFieldStart(reader, true, 10, 11);
assertCommand(reader, "b", 17, 18);
- assertFieldStart(reader, 20, 24);
+ assertFieldStart(reader, true, 20, 24);
assertData(reader, "test", 20, 24);
ASSERT_FALSE(logger.hasError());
ASSERT_THROW(reader.parse(), LoggableException);
ASSERT_TRUE(logger.hasError());
}
-TEST(OsdmStreamParser, commandWithNSSep)
+TEST(OsmlStreamParser, commandWithNSSep)
{
const char *testString = "\\test1:test2";
// 012345678901
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
assertCommand(reader, "test1:test2", 0, 12);
assertEnd(reader, 12, 12);
}
-TEST(OsdmStreamParser, beginEndWithNSSep)
+TEST(OsmlStreamParser, beginEndWithNSSep)
{
const char *testString = "\\begin{test1:test2}\\end{test1:test2}";
// 0123456789012345678 90123456789012345
// 0 1 2 3
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
assertCommand(reader, "test1:test2", 7, 18);
- assertFieldStart(reader, 19, 20);
+ assertFieldStart(reader, true, 19, 20);
assertFieldEnd(reader, 24, 35);
assertEnd(reader, 36, 36);
}
-TEST(OsdmStreamParser, errorBeginNSSep)
+TEST(OsmlStreamParser, errorBeginNSSep)
{
const char *testString = "\\begin:test{blub}\\end{blub}";
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
logger.reset();
ASSERT_FALSE(logger.hasError());
assertCommand(reader, "blub");
ASSERT_TRUE(logger.hasError());
- assertFieldStart(reader);
+ assertFieldStart(reader, true);
assertFieldEnd(reader);
assertEnd(reader);
}
-TEST(OsdmStreamParser, errorEndNSSep)
+TEST(OsmlStreamParser, errorEndNSSep)
{
const char *testString = "\\begin{blub}\\end:test{blub}";
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
logger.reset();
assertCommand(reader, "blub");
- assertFieldStart(reader);
+ assertFieldStart(reader, true);
ASSERT_FALSE(logger.hasError());
assertFieldEnd(reader);
ASSERT_TRUE(logger.hasError());
assertEnd(reader);
}
-TEST(OsdmStreamParser, errorEmptyNs)
+TEST(OsmlStreamParser, errorEmptyNs)
{
const char *testString = "\\test:";
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
logger.reset();
ASSERT_FALSE(logger.hasError());
@@ -955,12 +1016,12 @@ TEST(OsdmStreamParser, errorEmptyNs)
assertEnd(reader);
}
-TEST(OsdmStreamParser, errorRepeatedNs)
+TEST(OsmlStreamParser, errorRepeatedNs)
{
const char *testString = "\\test::";
CharReader charReader(testString);
- OsdmStreamParser reader(charReader, logger);
+ OsmlStreamParser reader(charReader, logger);
logger.reset();
ASSERT_FALSE(logger.hasError());
@@ -969,5 +1030,232 @@ TEST(OsdmStreamParser, errorRepeatedNs)
assertData(reader, "::");
assertEnd(reader);
}
+
+TEST(OsmlStreamParser, explicitDefaultField)
+{
+ const char *testString = "\\a{!b}c";
+ // 01234567
+ CharReader charReader(testString);
+
+ OsmlStreamParser reader(charReader, logger);
+
+ assertCommand(reader, "a", 0, 2);
+ assertFieldStart(reader, true, 2, 4);
+ assertData(reader, "b", 4, 5);
+ assertFieldEnd(reader, 5, 6);
+ assertData(reader, "c", 6, 7);
+ assertEnd(reader, 7, 7);
+}
+
+TEST(OsmlStreamParser, explicitDefaultFieldWithCommand)
+{
+ const char *testString = "\\a{!\\b}c";
+ // 0123 4567
+ CharReader charReader(testString);
+
+ OsmlStreamParser reader(charReader, logger);
+
+ assertCommand(reader, "a", 0, 2);
+ assertFieldStart(reader, true, 2, 4);
+ assertCommand(reader, "b", 4, 6);
+ assertFieldEnd(reader, 6, 7);
+ assertData(reader, "c", 7, 8);
+ assertEnd(reader, 8, 8);
+}
+
+TEST(OsmlStreamParser, errorFieldAfterExplicitDefaultField)
+{
+ const char *testString = "\\a{!\\b}{c}";
+ // 0123 456789
+ CharReader charReader(testString);
+
+ OsmlStreamParser reader(charReader, logger);
+
+ logger.reset();
+ assertCommand(reader, "a", 0, 2);
+ assertFieldStart(reader, true, 2, 4);
+ assertCommand(reader, "b", 4, 6);
+ assertFieldEnd(reader, 6, 7);
+ ASSERT_FALSE(logger.hasError());
+ assertData(reader, "c", 8, 9);
+ ASSERT_TRUE(logger.hasError());
+ assertEnd(reader, 10, 10);
+}
+
+TEST(OsmlStreamParser, annotationStart)
+{
+ const char *testString = "<\\a";
+ // 0 12
+
+ CharReader charReader(testString);
+
+ OsmlStreamParser reader(charReader, logger);
+
+ assertAnnotationStart(reader, "a", Variant::mapType{}, 0, 3);
+ assertEnd(reader, 3, 3);
+}
+
+TEST(OsmlStreamParser, annotationStartWithName)
+{
+ const char *testString = "<\\annotationWithName#aName";
+ // 0 1234567890123456789012345
+ // 0 1 2
+
+ CharReader charReader(testString);
+
+ OsmlStreamParser reader(charReader, logger);
+
+ assertAnnotationStart(reader, "annotationWithName",
+ Variant::mapType{{"name", "aName"}}, 0, 20);
+ assertEnd(reader, 26, 26);
+}
+
+TEST(OsmlStreamParser, annotationStartWithArguments)
+{
+ const char *testString = "<\\annotationWithName#aName[a=1,b=2]";
+ // 0 1234567890123456789012345678901234
+ // 0 1 2 3
+
+ CharReader charReader(testString);
+
+ OsmlStreamParser reader(charReader, logger);
+
+ assertAnnotationStart(
+ reader, "annotationWithName",
+ Variant::mapType{{"name", "aName"}, {"a", 1}, {"b", 2}}, 0, 20);
+ assertEnd(reader, 35, 35);
+}
+
+TEST(OsmlStreamParser, simpleAnnotationStartBeginEnd)
+{
+ const char *testString = "<\\begin{ab#name}[a=1,b=2] a \\end{ab}\\>";
+ // 0 123456789012345678901234567 89012345 67
+ // 0 1 2 3
+
+ CharReader charReader(testString);
+
+ OsmlStreamParser reader(charReader, logger);
+
+ assertAnnotationStart(
+ reader, "ab", Variant::mapType{{"name", "name"}, {"a", 1}, {"b", 2}}, 8,
+ 10);
+ assertFieldStart(reader, true, 26, 27);
+ assertData(reader, "a", 26, 27);
+ assertFieldEnd(reader, 33, 35);
+ assertAnnotationEnd(reader, "", "", 36, 38);
+ assertEnd(reader, 38, 38);
+}
+
+TEST(OsmlStreamParser, annotationEnd)
+{
+ const char *testString = "\\a>";
+ // 012
+
+ CharReader charReader(testString);
+
+ OsmlStreamParser reader(charReader, logger);
+
+ assertAnnotationEnd(reader, "a", "", 0, 2);
+ assertEnd(reader, 3, 3);
+}
+
+TEST(OsmlStreamParser, annotationEndWithName)
+{
+ const char *testString = "\\a#name>";
+ // 01234567
+
+ CharReader charReader(testString);
+
+ OsmlStreamParser reader(charReader, logger);
+
+ assertAnnotationEnd(reader, "a", "name", 0, 2);
+ assertEnd(reader, 8, 8);
+}
+
+TEST(OsmlStreamParser, annotationEndWithNameAsArgs)
+{
+ const char *testString = "\\a[name=name]>";
+ // 01234567890123
+
+ CharReader charReader(testString);
+
+ OsmlStreamParser reader(charReader, logger);
+
+ assertAnnotationEnd(reader, "a", "name", 0, 2);
+ assertEnd(reader, 14, 14);
+}
+
+TEST(OsmlStreamParser, errorAnnotationEndWithArguments)
+{
+ const char *testString = "\\a[foo=bar]>";
+ // 012345678901
+ // 0 1
+
+ CharReader charReader(testString);
+
+ OsmlStreamParser reader(charReader, logger);
+
+ logger.reset();
+ ASSERT_FALSE(logger.hasError());
+ assertCommand(reader, "a", Variant::mapType{{"foo", "bar"}}, 0, 2);
+ ASSERT_TRUE(logger.hasError());
+ assertData(reader, ">", 11, 12);
+ assertEnd(reader, 12, 12);
+}
+
+TEST(OsmlStreamParser, closingAnnotation)
+{
+ const char *testString = "<\\a>";
+ // 0 123
+
+ CharReader charReader(testString);
+
+ OsmlStreamParser reader(charReader, logger);
+
+ assertAnnotationStart(reader, "a", Variant::mapType{}, 0, 3);
+ assertData(reader, ">", 3, 4);
+ assertEnd(reader, 4, 4);
+}
+
+TEST(OsmlStreamParser, annotationWithFields)
+{
+ const char *testString = "a <\\b{c}{d}{!e} f \\> g";
+ // 012 345678901234567 8901
+ // 0 1 2
+
+ CharReader charReader(testString);
+
+ OsmlStreamParser reader(charReader, logger);
+
+ assertData(reader, "a", 0, 1);
+ assertAnnotationStart(reader, "b", Variant::mapType{}, 2, 5);
+ assertFieldStart(reader, false, 5, 6);
+ assertData(reader, "c", 6, 7);
+ assertFieldEnd(reader, 7, 8);
+ assertFieldStart(reader, false, 8, 9);
+ assertData(reader, "d", 9, 10);
+ assertFieldEnd(reader, 10, 11);
+ assertFieldStart(reader, true, 11, 13);
+ assertData(reader, "e", 13, 14);
+ assertFieldEnd(reader, 14, 15);
+ assertData(reader, "f", 16, 17);
+ assertAnnotationEnd(reader, "", "", 18, 20);
+ assertData(reader, "g", 21, 22);
+ assertEnd(reader, 22, 22);
+}
+
+TEST(OsmlStreamParser, annotationStartEscape)
+{
+ const char *testString = "<\\%test";
+ // 0 123456
+ // 0
+
+ CharReader charReader(testString);
+
+ OsmlStreamParser reader(charReader, logger);
+
+ assertData(reader, "<%test", 0, 7);
+ assertEnd(reader, 7, 7);
+}
}
diff --git a/test/formats/osxml/OsxmlEventParserTest.cpp b/test/formats/osxml/OsxmlEventParserTest.cpp
new file mode 100644
index 0000000..3293370
--- /dev/null
+++ b/test/formats/osxml/OsxmlEventParserTest.cpp
@@ -0,0 +1,217 @@
+/*
+ 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 <http://www.gnu.org/licenses/>.
+*/
+
+#include <gtest/gtest.h>
+
+#include <core/frontend/TerminalLogger.hpp>
+#include <core/common/CharReader.hpp>
+#include <core/common/Variant.hpp>
+
+#include <formats/osxml/OsxmlEventParser.hpp>
+
+namespace ousia {
+
+static TerminalLogger logger(std::cerr, true);
+// static ConcreteLogger logger;
+
+namespace {
+enum class OsxmlEvent {
+ COMMAND,
+ ANNOTATION_START,
+ ANNOTATION_END,
+ FIELD_END,
+ DATA
+};
+
+class TestOsxmlEventListener : public OsxmlEvents {
+public:
+ std::vector<std::pair<OsxmlEvent, Variant>> events;
+
+ void command(const Variant &name, const Variant::mapType &args) override
+ {
+ events.emplace_back(OsxmlEvent::COMMAND,
+ Variant::arrayType{name, args});
+ }
+
+ void annotationStart(const Variant &className,
+ const Variant::mapType &args) override
+ {
+ events.emplace_back(OsxmlEvent::ANNOTATION_START,
+ Variant::arrayType{className, args});
+ }
+
+ void annotationEnd(const Variant &className,
+ const Variant &elementName) override
+ {
+ events.emplace_back(OsxmlEvent::ANNOTATION_END,
+ Variant::arrayType{className, elementName});
+ }
+
+ void fieldEnd() override
+ {
+ events.emplace_back(OsxmlEvent::FIELD_END, Variant::arrayType{});
+ }
+
+ void data(const Variant &data) override
+ {
+ events.emplace_back(OsxmlEvent::DATA, Variant::arrayType{data});
+ }
+};
+
+static std::vector<std::pair<OsxmlEvent, Variant>> parseXml(
+ const char *testString,
+ WhitespaceMode whitespaceMode = WhitespaceMode::TRIM)
+{
+ TestOsxmlEventListener listener;
+ CharReader reader(testString);
+ OsxmlEventParser parser(reader, listener, logger);
+ parser.setWhitespaceMode(whitespaceMode);
+ parser.parse();
+ return listener.events;
+}
+}
+
+TEST(OsxmlEventParser, simpleCommandWithArgs)
+{
+ const char *testString = "<a name=\"test\" a=\"1\" b=\"2\" c=\"blub\"/>";
+ // 01234567 89012 3456 78 9012 34 5678 90123 456
+ // 0 1 2 3
+
+ std::vector<std::pair<OsxmlEvent, Variant>> expectedEvents{
+ {OsxmlEvent::COMMAND,
+ Variant::arrayType{
+ "a", Variant::mapType{
+ {"name", "test"}, {"a", 1}, {"b", 2}, {"c", "blub"}}}},
+ {OsxmlEvent::FIELD_END, Variant::arrayType{}}};
+
+ auto events = parseXml(testString);
+ ASSERT_EQ(expectedEvents, events);
+
+ // Check the locations (I'll do this one time and then just assume it works)
+ ASSERT_EQ(1U, events[0].second.asArray()[0].getLocation().getStart());
+ ASSERT_EQ(2U, events[0].second.asArray()[0].getLocation().getEnd());
+ ASSERT_EQ(
+ 9U,
+ events[0].second.asArray()[1].asMap()["name"].getLocation().getStart());
+ ASSERT_EQ(
+ 13U,
+ events[0].second.asArray()[1].asMap()["name"].getLocation().getEnd());
+ ASSERT_EQ(
+ 18U,
+ events[0].second.asArray()[1].asMap()["a"].getLocation().getStart());
+ ASSERT_EQ(
+ 19U, events[0].second.asArray()[1].asMap()["a"].getLocation().getEnd());
+ ASSERT_EQ(
+ 24U,
+ events[0].second.asArray()[1].asMap()["b"].getLocation().getStart());
+ ASSERT_EQ(
+ 25U, events[0].second.asArray()[1].asMap()["b"].getLocation().getEnd());
+ ASSERT_EQ(
+ 30U,
+ events[0].second.asArray()[1].asMap()["c"].getLocation().getStart());
+ ASSERT_EQ(
+ 34U, events[0].second.asArray()[1].asMap()["c"].getLocation().getEnd());
+}
+
+TEST(OsxmlEventParser, magicTopLevelTag)
+{
+ const char *testString = "<ousia><a/><b/></ousia>";
+
+ std::vector<std::pair<OsxmlEvent, Variant>> expectedEvents{
+ {OsxmlEvent::COMMAND, Variant::arrayType{{"a", Variant::mapType{}}}},
+ {OsxmlEvent::FIELD_END, Variant::arrayType{}},
+ {OsxmlEvent::COMMAND, Variant::arrayType{{"b", Variant::mapType{}}}},
+ {OsxmlEvent::FIELD_END, Variant::arrayType{}}};
+
+ auto events = parseXml(testString);
+ ASSERT_EQ(expectedEvents, events);
+}
+
+TEST(OsxmlEventParser, magicTopLevelTagInside)
+{
+ const char *testString = "<a><ousia/></a>";
+
+ std::vector<std::pair<OsxmlEvent, Variant>> expectedEvents{
+ {OsxmlEvent::COMMAND, Variant::arrayType{{"a", Variant::mapType{}}}},
+ {OsxmlEvent::COMMAND,
+ Variant::arrayType{{"ousia", Variant::mapType{}}}},
+ {OsxmlEvent::FIELD_END, Variant::arrayType{}},
+ {OsxmlEvent::FIELD_END, Variant::arrayType{}}};
+
+ auto events = parseXml(testString);
+ ASSERT_EQ(expectedEvents, events);
+}
+
+TEST(OsxmlEventParser, commandWithDataPreserveWhitespace)
+{
+ const char *testString = "<a> hello \n world </a>";
+ // 012345678901 234567890123
+ // 0 1 2
+
+ std::vector<std::pair<OsxmlEvent, Variant>> expectedEvents{
+ {OsxmlEvent::COMMAND, Variant::arrayType{"a", Variant::mapType{}}},
+ {OsxmlEvent::DATA, Variant::arrayType{" hello \n world "}},
+ {OsxmlEvent::FIELD_END, Variant::arrayType{}}};
+
+ auto events = parseXml(testString, WhitespaceMode::PRESERVE);
+ ASSERT_EQ(expectedEvents, events);
+
+ // Check the location of the text
+ ASSERT_EQ(3U, events[1].second.asArray()[0].getLocation().getStart());
+ ASSERT_EQ(20U, events[1].second.asArray()[0].getLocation().getEnd());
+}
+
+TEST(OsxmlEventParser, commandWithDataTrimWhitespace)
+{
+ const char *testString = "<a> hello \n world </a>";
+ // 012345678901 234567890123
+ // 0 1 2
+
+ std::vector<std::pair<OsxmlEvent, Variant>> expectedEvents{
+ {OsxmlEvent::COMMAND, Variant::arrayType{"a", Variant::mapType{}}},
+ {OsxmlEvent::DATA, Variant::arrayType{"hello \n world"}},
+ {OsxmlEvent::FIELD_END, Variant::arrayType{}}};
+
+ auto events = parseXml(testString, WhitespaceMode::TRIM);
+ ASSERT_EQ(expectedEvents, events);
+
+ // Check the location of the text
+ ASSERT_EQ(5U, events[1].second.asArray()[0].getLocation().getStart());
+ ASSERT_EQ(19U, events[1].second.asArray()[0].getLocation().getEnd());
+}
+
+TEST(OsxmlEventParser, commandWithDataCollapseWhitespace)
+{
+ const char *testString = "<a> hello \n world </a>";
+ // 012345678901 234567890123
+ // 0 1 2
+
+ std::vector<std::pair<OsxmlEvent, Variant>> expectedEvents{
+ {OsxmlEvent::COMMAND, Variant::arrayType{"a", Variant::mapType{}}},
+ {OsxmlEvent::DATA, Variant::arrayType{"hello world"}},
+ {OsxmlEvent::FIELD_END, Variant::arrayType{}}};
+
+ auto events = parseXml(testString, WhitespaceMode::COLLAPSE);
+ ASSERT_EQ(expectedEvents, events);
+
+ // Check the location of the text
+ ASSERT_EQ(5U, events[1].second.asArray()[0].getLocation().getStart());
+ ASSERT_EQ(19U, events[1].second.asArray()[0].getLocation().getEnd());
+}
+}
+
diff --git a/test/plugins/xml/XmlParserTest.cpp b/test/formats/osxml/OsxmlParserTest.cpp
index fdae779..fe8ed34 100644
--- a/test/plugins/xml/XmlParserTest.cpp
+++ b/test/formats/osxml/OsxmlParserTest.cpp
@@ -30,7 +30,7 @@
#include <core/StandaloneEnvironment.hpp>
#include <plugins/filesystem/FileLocator.hpp>
-#include <plugins/xml/XmlParser.hpp>
+#include <formats/osxml/OsxmlParser.hpp>
namespace ousia {
@@ -41,7 +41,7 @@ extern const Rtti Typesystem;
}
struct XmlStandaloneEnvironment : public StandaloneEnvironment {
- XmlParser xmlParser;
+ OsxmlParser parser;
FileLocator fileLocator;
XmlStandaloneEnvironment(ConcreteLogger &logger)
@@ -52,21 +52,21 @@ struct XmlStandaloneEnvironment : public StandaloneEnvironment {
registry.registerDefaultExtensions();
registry.registerParser({"text/vnd.ousia.oxm", "text/vnd.ousia.oxd"},
- {&RttiTypes::Node}, &xmlParser);
+ {&RttiTypes::Node}, &parser);
registry.registerResourceLocator(&fileLocator);
}
};
static TerminalLogger logger(std::cerr, true);
-TEST(XmlParser, mismatchedTag)
+TEST(OsxmlParser, mismatchedTag)
{
XmlStandaloneEnvironment env(logger);
env.parse("mismatchedTag.oxm", "", "", RttiSet{&RttiTypes::Document});
ASSERT_TRUE(logger.hasError());
}
-TEST(XmlParser, generic)
+TEST(OsxmlParser, generic)
{
XmlStandaloneEnvironment env(logger);
env.parse("generic.oxm", "", "", RttiSet{&RttiTypes::Node});
@@ -186,7 +186,7 @@ static void checkFieldDescriptor(
Handle<Type> primitiveType = nullptr, bool optional = false)
{
auto res = desc->resolve(&RttiTypes::FieldDescriptor, name);
- ASSERT_EQ(1, res.size());
+ ASSERT_EQ(1U, res.size());
checkFieldDescriptor(res[0].node, name, parent, children, type,
primitiveType, optional);
}
@@ -201,7 +201,7 @@ static void checkFieldDescriptor(
optional);
}
-TEST(XmlParser, domainParsing)
+TEST(OsxmlParser, domainParsing)
{
XmlStandaloneEnvironment env(logger);
Rooted<Node> book_domain_node =
@@ -332,10 +332,10 @@ static void checkText(Handle<Node> p, Handle<Node> expectedParent,
{
checkStructuredEntity(p, expectedParent, doc, "paragraph");
Rooted<StructuredEntity> par = p.cast<StructuredEntity>();
- ASSERT_EQ(1, par->getField().size());
+ ASSERT_EQ(1U, par->getField().size());
checkStructuredEntity(par->getField()[0], par, doc, "text");
Rooted<StructuredEntity> text = par->getField()[0].cast<StructuredEntity>();
- ASSERT_EQ(1, text->getField().size());
+ ASSERT_EQ(1U, text->getField().size());
Handle<StructureNode> d = text->getField()[0];
ASSERT_FALSE(d == nullptr);
@@ -345,7 +345,7 @@ static void checkText(Handle<Node> p, Handle<Node> expectedParent,
ASSERT_EQ(expected, prim->getContent());
}
-TEST(XmlParser, documentParsing)
+TEST(OsxmlParser, documentParsing)
{
XmlStandaloneEnvironment env(logger);
Rooted<Node> book_document_node =
@@ -357,7 +357,7 @@ TEST(XmlParser, documentParsing)
checkStructuredEntity(doc->getRoot(), doc, doc, "book");
{
Rooted<StructuredEntity> book = doc->getRoot();
- ASSERT_EQ(2, book->getField().size());
+ ASSERT_EQ(2U, book->getField().size());
checkText(book->getField()[0], book, doc,
"This might be some introductory text or a dedication.");
checkStructuredEntity(book->getField()[1], book, doc, "chapter",
@@ -365,7 +365,7 @@ TEST(XmlParser, documentParsing)
{
Rooted<StructuredEntity> chapter =
book->getField()[1].cast<StructuredEntity>();
- ASSERT_EQ(3, chapter->getField().size());
+ ASSERT_EQ(3U, chapter->getField().size());
checkText(chapter->getField()[0], chapter, doc,
"Here we might have an introduction to the chapter.");
checkStructuredEntity(chapter->getField()[1], chapter, doc,
@@ -374,7 +374,7 @@ TEST(XmlParser, documentParsing)
{
Rooted<StructuredEntity> section =
chapter->getField()[1].cast<StructuredEntity>();
- ASSERT_EQ(1, section->getField().size());
+ ASSERT_EQ(1U, section->getField().size());
checkText(section->getField()[0], section, doc,
"Here we might find the actual section content.");
}
@@ -384,7 +384,7 @@ TEST(XmlParser, documentParsing)
{
Rooted<StructuredEntity> section =
chapter->getField()[2].cast<StructuredEntity>();
- ASSERT_EQ(1, section->getField().size());
+ ASSERT_EQ(1U, section->getField().size());
checkText(section->getField()[0], section, doc,
"Here we might find the actual section content.");
}
diff --git a/test/core/CodeTokenizerTest.cpp b/test/plugins/css/CodeTokenizerTest.cpp
index 2d4d5a7..2d4d5a7 100644
--- a/test/core/CodeTokenizerTest.cpp
+++ b/test/plugins/css/CodeTokenizerTest.cpp
diff --git a/test/core/TokenizerTest.cpp b/test/plugins/css/TokenizerTest.cpp
index c53f93d..c53f93d 100644
--- a/test/core/TokenizerTest.cpp
+++ b/test/plugins/css/TokenizerTest.cpp