diff options
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/formats/osml/OsmlParser.cpp | 16 | ||||
-rw-r--r-- | test/formats/osml/OsmlParserTest.cpp | 95 | ||||
-rw-r--r-- | testdata/osmlparser/empty_document.osml | 2 | ||||
-rw-r--r-- | testdata/osmlparser/empty_domain.osml | 2 | ||||
-rw-r--r-- | testdata/osmlparser/empty_typesystem.osml | 2 |
6 files changed, 118 insertions, 1 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index b2a4b82..5b310a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -352,6 +352,7 @@ IF(TEST) ) ADD_EXECUTABLE(ousia_test_osml + test/formats/osml/OsmlParserTest test/formats/osml/OsmlStreamParserTest ) @@ -359,6 +360,7 @@ IF(TEST) ${GTEST_LIBRARIES} ousia_core ousia_osml + ousia_filesystem ) ADD_EXECUTABLE(ousia_test_osxml diff --git a/src/formats/osml/OsmlParser.cpp b/src/formats/osml/OsmlParser.cpp index 87f4c00..519a2d8 100644 --- a/src/formats/osml/OsmlParser.cpp +++ b/src/formats/osml/OsmlParser.cpp @@ -64,13 +64,27 @@ public: */ void parse() { + // Flag set to true if a "document" element needs to be created + bool needsDocument = true; while (true) { OsmlStreamParser::State state = parser.parse(); switch (state) { - case OsmlStreamParser::State::COMMAND: + case OsmlStreamParser::State::COMMAND: { + // Implicitly create a "document" element if the first + // command is not any other top-level command + if (needsDocument) { + const std::string &cmd = + parser.getCommandName().asString(); + if (cmd != "typesystem" && cmd != "document" && + cmd != "domain") { + stack.command("document", Variant::mapType{}); + } + needsDocument = false; + } stack.command(parser.getCommandName(), parser.getCommandArguments().asMap()); break; + } case OsmlStreamParser::State::DATA: stack.data(parser.getData()); break; diff --git a/test/formats/osml/OsmlParserTest.cpp b/test/formats/osml/OsmlParserTest.cpp new file mode 100644 index 0000000..1ab55f2 --- /dev/null +++ b/test/formats/osml/OsmlParserTest.cpp @@ -0,0 +1,95 @@ +/* + 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/common/CharReader.hpp> +#include <core/common/SourceContextReader.hpp> +#include <core/model/Document.hpp> +#include <core/model/Domain.hpp> +#include <core/model/Typesystem.hpp> +#include <core/model/Node.hpp> +#include <core/model/Project.hpp> +#include <core/frontend/TerminalLogger.hpp> +#include <core/StandaloneEnvironment.hpp> + +#include <plugins/filesystem/FileLocator.hpp> +#include <formats/osml/OsmlParser.hpp> + +namespace ousia { + +namespace RttiTypes { +extern const Rtti Document; +extern const Rtti Domain; +extern const Rtti Typesystem; +} + +struct OsmlStandaloneEnvironment : public StandaloneEnvironment { + OsmlParser parser; + FileLocator fileLocator; + + OsmlStandaloneEnvironment(ConcreteLogger &logger) + : StandaloneEnvironment(logger) + { + fileLocator.addDefaultSearchPaths(); + fileLocator.addUnittestSearchPath("osmlparser"); + + registry.registerDefaultExtensions(); + registry.registerParser({"text/vnd.ousia.osml"}, {&RttiTypes::Node}, + &parser); + registry.registerResourceLocator(&fileLocator); + } +}; + +static TerminalLogger logger(std::cerr, true); + +TEST(OsmlParser, empty_document) +{ + OsmlStandaloneEnvironment env(logger); + Rooted<Node> node = + env.parse("empty_document.osml", "", "", RttiSet{&RttiTypes::Node}); + + ASSERT_TRUE(node != nullptr); + ASSERT_TRUE(node->isa(&RttiTypes::Document)); +} + +TEST(OsmlParser, empty_domain) +{ + OsmlStandaloneEnvironment env(logger); + Rooted<Node> node = + env.parse("empty_domain.osml", "", "", RttiSet{&RttiTypes::Node}); + + ASSERT_TRUE(node != nullptr); + ASSERT_TRUE(node->isa(&RttiTypes::Domain)); + ASSERT_EQ("testDomain", node->getName()); +} + +TEST(OsmlParser, empty_typesystem) +{ + OsmlStandaloneEnvironment env(logger); + Rooted<Node> node = + env.parse("empty_typesystem.osml", "", "", RttiSet{&RttiTypes::Node}); + + ASSERT_TRUE(node != nullptr); + ASSERT_TRUE(node->isa(&RttiTypes::Typesystem)); + ASSERT_EQ("testTypesystem", node->getName()); +} +} + diff --git a/testdata/osmlparser/empty_document.osml b/testdata/osmlparser/empty_document.osml new file mode 100644 index 0000000..adf34fa --- /dev/null +++ b/testdata/osmlparser/empty_document.osml @@ -0,0 +1,2 @@ +\begin{document} +\end{document} diff --git a/testdata/osmlparser/empty_domain.osml b/testdata/osmlparser/empty_domain.osml new file mode 100644 index 0000000..e8d6452 --- /dev/null +++ b/testdata/osmlparser/empty_domain.osml @@ -0,0 +1,2 @@ +\begin{domain#testDomain} +\end{domain} diff --git a/testdata/osmlparser/empty_typesystem.osml b/testdata/osmlparser/empty_typesystem.osml new file mode 100644 index 0000000..6a13aef --- /dev/null +++ b/testdata/osmlparser/empty_typesystem.osml @@ -0,0 +1,2 @@ +\begin{typesystem#testTypesystem} +\end{typesystem} |