/* Ousía Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include namespace ousia { namespace RttiTypes { extern const Rtti Document; extern const Rtti Domain; extern const Rtti Typesystem; } struct XmlStandaloneEnvironment : public StandaloneEnvironment { XmlParser xmlParser; FileLocator fileLocator; XmlStandaloneEnvironment(ConcreteLogger &logger) : StandaloneEnvironment(logger) { fileLocator.addDefaultSearchPaths(); fileLocator.addUnittestSearchPath("xmlparser"); registry.registerDefaultExtensions(); registry.registerParser({"text/vnd.ousia.oxm", "text/vnd.ousia.oxd"}, {&RttiTypes::Node}, &xmlParser); registry.registerResourceLocator(&fileLocator); } }; static TerminalLogger logger(std::cerr, true); TEST(XmlParser, mismatchedTag) { XmlStandaloneEnvironment env(logger); env.parse("mismatchedTag.oxm", "", "", RttiSet{&RttiTypes::Document}); ASSERT_TRUE(logger.hasError()); } TEST(XmlParser, generic) { XmlStandaloneEnvironment env(logger); env.parse("generic.oxm", "", "", RttiSet{&RttiTypes::Node}); #ifdef MANAGER_GRAPHVIZ_EXPORT env.manager.exportGraphviz("xmlDocument.dot"); #endif } static void checkStructuredClass( Handle n, const std::string &name, Handle domain, Variant cardinality = AnyCardinality, Handle attributesDescriptor = nullptr, Handle superclass = nullptr, bool transparent = false, bool root = false) { ASSERT_FALSE(n == nullptr); Handle sc = n.cast(); ASSERT_FALSE(sc == nullptr); ASSERT_EQ(name, sc->getName()); ASSERT_EQ(domain, sc->getParent()); ASSERT_EQ(cardinality, sc->getCardinality()); ASSERT_EQ(transparent, sc->isTransparent()); ASSERT_EQ(root, sc->hasRootPermission()); } static Rooted checkStructuredClass( const std::string &resolve, const std::string &name, Handle domain, Variant cardinality = AnyCardinality, Handle attributesDescriptor = nullptr, Handle superclass = nullptr, bool transparent = false, bool root = false) { auto res = domain->resolve(RttiTypes::StructuredClass, resolve); if (res.size() != 1) { throw OusiaException("resolution error!"); } Handle sc = res[0].node.cast(); checkStructuredClass(sc, name, domain, cardinality, attributesDescriptor, superclass, transparent, root); return sc; } static void checkFieldDescriptor( Handle n, const std::string &name, Handle parent, NodeVector children, FieldDescriptor::FieldType type = FieldDescriptor::FieldType::TREE, Handle primitiveType = nullptr, bool optional = false) { ASSERT_FALSE(n.isNull()); Handle field = n.cast(); ASSERT_FALSE(field.isNull()); ASSERT_EQ(name, field->getName()); ASSERT_EQ(parent, field->getParent()); ASSERT_EQ(type, field->getFieldType()); ASSERT_EQ(primitiveType, field->getPrimitiveType()); ASSERT_EQ(optional, field->isOptional()); // check the children. ASSERT_EQ(children.size(), field->getChildren().size()); for (unsigned int c = 0; c < children.size(); c++) { ASSERT_EQ(children[c], field->getChildren()[c]); } } static void checkFieldDescriptor( Handle desc, NodeVector children, const std::string &name = "", FieldDescriptor::FieldType type = FieldDescriptor::FieldType::TREE, Handle primitiveType = nullptr, bool optional = false) { auto res = desc->resolve(RttiTypes::FieldDescriptor, name); ASSERT_EQ(1, res.size()); checkFieldDescriptor(res[0].node, name, desc, children, type, primitiveType, optional); } TEST(XmlParser, domainParsing) { XmlStandaloneEnvironment env(logger); Rooted n = env.parse("book_domain.oxm", "", "", RttiSet{&RttiTypes::Domain}); ASSERT_FALSE(n == nullptr); ASSERT_FALSE(logger.hasError()); // check the domain node. Rooted domain = n.cast(); ASSERT_EQ("book", domain->getName()); // get the book struct node. Cardinality single; single.merge({1}); Rooted book = checkStructuredClass( "book", "book", domain, single, nullptr, nullptr, false, true); // get the chapter struct node. Rooted chapter = checkStructuredClass("chapter", "chapter", domain); Rooted section = checkStructuredClass("section", "section", domain); Rooted subsection = checkStructuredClass("subsection", "subsection", domain); Rooted paragraph = checkStructuredClass("paragraph", "paragraph", domain, AnyCardinality, nullptr, nullptr, true, false); Rooted text = checkStructuredClass( "text", "text", domain, AnyCardinality, nullptr, nullptr, true, false); // check the FieldDescriptors. checkFieldDescriptor(book, {chapter, paragraph}); checkFieldDescriptor(chapter, {section, paragraph}); checkFieldDescriptor(section, {subsection, paragraph}); checkFieldDescriptor(subsection, {paragraph}); checkFieldDescriptor(paragraph, {text}); checkFieldDescriptor( text, {}, "content", FieldDescriptor::FieldType::PRIMITIVE, env.project->getSystemTypesystem()->getStringType(), false); } }