/*
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);
}
}