summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/core/common/VariantConverterTest.cpp2
-rw-r--r--test/core/model/DomainTest.cpp185
-rw-r--r--test/core/parser/ParserScopeTest.cpp6
-rw-r--r--test/core/parser/stack/StackTest.cpp20
-rw-r--r--test/formats/osml/OsmlParserTest.cpp41
-rw-r--r--test/formats/osxml/OsxmlParserTest.cpp26
-rw-r--r--test/plugins/xml/XmlOutputTest.cpp40
7 files changed, 297 insertions, 23 deletions
diff --git a/test/core/common/VariantConverterTest.cpp b/test/core/common/VariantConverterTest.cpp
index 9654a7b..2860777 100644
--- a/test/core/common/VariantConverterTest.cpp
+++ b/test/core/common/VariantConverterTest.cpp
@@ -244,7 +244,7 @@ TEST(VariantConverter, toString)
VariantConverter::Mode::ALL, logger);
assertStringConversion(M, "{\"b\":true,\"d\":2.7,\"i\":6,\"s\":\"test\"}",
true, VariantConverter::Mode::ALL, logger);
- assertStringConversion(C, "<cardinality {2-4, >6}>", true,
+ assertStringConversion(C, "{2-4, >6}", true,
VariantConverter::Mode::ALL, logger);
}
diff --git a/test/core/model/DomainTest.cpp b/test/core/model/DomainTest.cpp
index d68648e..6bbf26d 100644
--- a/test/core/model/DomainTest.cpp
+++ b/test/core/model/DomainTest.cpp
@@ -81,6 +81,115 @@ TEST(Domain, testDomainResolving)
assert_path(res[0], &RttiTypes::StructuredClass, {"book", "paragraph"});
}
+// i use this wrapper due to the strange behaviour of GTEST.
+static void assertFalse(bool b){
+ ASSERT_FALSE(b);
+}
+
+static Rooted<FieldDescriptor> createUnsortedPrimitiveField(
+ Handle<StructuredClass> strct, Handle<Type> type, Logger &logger, bool tree,
+ std::string name)
+{
+ FieldDescriptor::FieldType fieldType = FieldDescriptor::FieldType::SUBTREE;
+ if (tree) {
+ fieldType = FieldDescriptor::FieldType::TREE;
+ }
+
+ auto res = strct->createPrimitiveFieldDescriptor(type, logger, fieldType,
+ std::move(name));
+ assertFalse(res.second);
+ return res.first;
+}
+
+TEST(StructuredClass, getFieldDescriptors)
+{
+ /*
+ * We construct a case with the three levels:
+ * 1.) A has the SUBTREE fields a and b as well as a TREE field.
+ * 2.) B is a subclass of A and has the SUBTREE fields b and c as well as
+ * a TREE field.
+ * 3.) C is a subclass of B and has the SUBTREE field a.
+ * As a result we expect C to have none of As fields, the TREE field of B,
+ * and the SUBTREE fields a (of C) , b and c (of B).
+ */
+ TerminalLogger logger{std::cout};
+ Manager mgr{1};
+ Rooted<SystemTypesystem> sys{new SystemTypesystem(mgr)};
+ Rooted<Domain> domain{new Domain(mgr, sys, "myDomain")};
+
+ Rooted<StructuredClass> A{new StructuredClass(
+ mgr, "A", domain, Cardinality::any(), nullptr, false, true)};
+ Rooted<FieldDescriptor> A_a = createUnsortedPrimitiveField(
+ A, sys->getStringType(), logger, false, "a");
+ Rooted<FieldDescriptor> A_b = createUnsortedPrimitiveField(
+ A, sys->getStringType(), logger, false, "b");
+ Rooted<FieldDescriptor> A_main = createUnsortedPrimitiveField(
+ A, sys->getStringType(), logger, true, "somename");
+
+ Rooted<StructuredClass> B{new StructuredClass(
+ mgr, "B", domain, Cardinality::any(), A, false, true)};
+ Rooted<FieldDescriptor> B_b = createUnsortedPrimitiveField(
+ B, sys->getStringType(), logger, false, "b");
+ Rooted<FieldDescriptor> B_c = createUnsortedPrimitiveField(
+ B, sys->getStringType(), logger, false, "c");
+ Rooted<FieldDescriptor> B_main = createUnsortedPrimitiveField(
+ B, sys->getStringType(), logger, true, "othername");
+
+ Rooted<StructuredClass> C{new StructuredClass(
+ mgr, "C", domain, Cardinality::any(), B, false, true)};
+ Rooted<FieldDescriptor> C_a = createUnsortedPrimitiveField(
+ C, sys->getStringType(), logger, false, "a");
+
+ ASSERT_TRUE(domain->validate(logger));
+
+ // check all FieldDescriptors
+ {
+ NodeVector<FieldDescriptor> fds = A->getFieldDescriptors();
+ ASSERT_EQ(3, fds.size());
+ ASSERT_EQ(A_a, fds[0]);
+ ASSERT_EQ(A_b, fds[1]);
+ ASSERT_EQ(A_main, fds[2]);
+ }
+ {
+ NodeVector<FieldDescriptor> fds = B->getFieldDescriptors();
+ ASSERT_EQ(4, fds.size());
+ ASSERT_EQ(A_a, fds[0]);
+ ASSERT_EQ(B_b, fds[1]);
+ ASSERT_EQ(B_c, fds[2]);
+ ASSERT_EQ(B_main, fds[3]);
+ }
+ {
+ NodeVector<FieldDescriptor> fds = C->getFieldDescriptors();
+ ASSERT_EQ(4, fds.size());
+ ASSERT_EQ(B_b, fds[0]);
+ ASSERT_EQ(B_c, fds[1]);
+ // superclass fields come before subclass fields (except for the TREE
+ // field, which is always last).
+ ASSERT_EQ(C_a, fds[2]);
+ ASSERT_EQ(B_main, fds[3]);
+ }
+}
+
+
+TEST(StructuredClass, getFieldDescriptorsCycles)
+{
+ Logger logger;
+ Manager mgr{1};
+ Rooted<SystemTypesystem> sys{new SystemTypesystem(mgr)};
+ Rooted<Domain> domain{new Domain(mgr, sys, "myDomain")};
+
+ Rooted<StructuredClass> A{new StructuredClass(
+ mgr, "A", domain, Cardinality::any(), nullptr, false, true)};
+ A->addSubclass(A, logger);
+ Rooted<FieldDescriptor> A_a = createUnsortedPrimitiveField(
+ A, sys->getStringType(), logger, false, "a");
+ ASSERT_FALSE(domain->validate(logger));
+ // if we call getFieldDescriptors that should still return a valid result.
+ NodeVector<FieldDescriptor> fds = A->getFieldDescriptors();
+ ASSERT_EQ(1, fds.size());
+ ASSERT_EQ(A_a, fds[0]);
+}
+
Rooted<StructuredClass> getClass(const std::string name, Handle<Domain> dom)
{
std::vector<ResolutionResult> res =
@@ -221,6 +330,34 @@ TEST(Descriptor, pathToAdvanced)
ASSERT_EQ("", path[2]->getName());
}
+TEST(Descriptor, pathToCycles)
+{
+ // build a domain with a cycle.
+ Manager mgr{1};
+ Logger logger;
+ Rooted<SystemTypesystem> sys{new SystemTypesystem(mgr)};
+ // Construct the domain
+ Rooted<Domain> domain{new Domain(mgr, sys, "cycles")};
+ Rooted<StructuredClass> A{new StructuredClass(
+ mgr, "A", domain, Cardinality::any(), {nullptr}, true, true)};
+ A->addSubclass(A, logger);
+ ASSERT_FALSE(domain->validate(logger));
+ Rooted<StructuredClass> B{new StructuredClass(
+ mgr, "B", domain, Cardinality::any(), {nullptr}, false, true)};
+ Rooted<FieldDescriptor> A_field = A->createFieldDescriptor(logger).first;
+ A_field->addChild(B);
+ /*
+ * Now try to create the path from A to B. A direct path is possible but
+ * in the worst case this could also try to find shorter paths via an
+ * endless repition of A instances.
+ * As we cut the search tree at paths that are longer than our current
+ * optimum this should not happen, though.
+ */
+ NodeVector<Node> path = A->pathTo(B, logger);
+ ASSERT_EQ(1, path.size());
+ ASSERT_EQ(A_field, path[0]);
+}
+
TEST(Descriptor, getDefaultFields)
{
// construct a domain with lots of default fields to test.
@@ -301,6 +438,29 @@ TEST(Descriptor, getDefaultFields)
ASSERT_EQ(F_field, fields[1]);
}
+TEST(Descriptor, getDefaultFieldsCycles)
+{
+ // build a domain with a cycle.
+ Manager mgr{1};
+ Logger logger;
+ Rooted<SystemTypesystem> sys{new SystemTypesystem(mgr)};
+ // Construct the domain
+ Rooted<Domain> domain{new Domain(mgr, sys, "cycles")};
+ Rooted<StructuredClass> A{new StructuredClass(
+ mgr, "A", domain, Cardinality::any(), {nullptr}, true, true)};
+ A->addSubclass(A, logger);
+ ASSERT_FALSE(domain->validate(logger));
+ Rooted<FieldDescriptor> A_field =
+ A->createPrimitiveFieldDescriptor(sys->getStringType(), logger).first;
+ /*
+ * Now try to get the default fields of A. This should not lead to cycles
+ * if we correctly note all already visited nodes.
+ */
+ NodeVector<FieldDescriptor> defaultFields = A->getDefaultFields();
+ ASSERT_EQ(1, defaultFields.size());
+ ASSERT_EQ(A_field, defaultFields[0]);
+}
+
TEST(Descriptor, getPermittedChildren)
{
// analyze the book domain.
@@ -338,6 +498,31 @@ TEST(Descriptor, getPermittedChildren)
ASSERT_EQ(sub, children[3]);
}
+TEST(Descriptor, getPermittedChildrenCycles)
+{
+ // build a domain with a cycle.
+ Manager mgr{1};
+ Logger logger;
+ Rooted<SystemTypesystem> sys{new SystemTypesystem(mgr)};
+ // Construct the domain
+ Rooted<Domain> domain{new Domain(mgr, sys, "cycles")};
+ Rooted<StructuredClass> A{new StructuredClass(
+ mgr, "A", domain, Cardinality::any(), {nullptr}, true, true)};
+ A->addSubclass(A, logger);
+ ASSERT_FALSE(domain->validate(logger));
+ Rooted<FieldDescriptor> A_field = A->createFieldDescriptor(logger).first;
+ // we make the cycle worse by adding A as child of itself.
+ A_field->addChild(A);
+ /*
+ * Now try to get the permitted children of A. This should not lead to
+ * cycles
+ * if we correctly note all already visited nodes.
+ */
+ NodeVector<StructuredClass> children = A->getPermittedChildren();
+ ASSERT_EQ(1, children.size());
+ ASSERT_EQ(A, children[0]);
+}
+
TEST(StructuredClass, isSubclassOf)
{
// create an inheritance hierarchy.
diff --git a/test/core/parser/ParserScopeTest.cpp b/test/core/parser/ParserScopeTest.cpp
index 7f89f2c..2ead924 100644
--- a/test/core/parser/ParserScopeTest.cpp
+++ b/test/core/parser/ParserScopeTest.cpp
@@ -18,6 +18,7 @@
#include <gtest/gtest.h>
+#include <core/common/Logger.hpp>
#include <core/managed/Manager.hpp>
#include <core/model/Node.hpp>
#include <core/parser/ParserScope.hpp>
@@ -26,6 +27,7 @@ namespace ousia {
TEST(ParserScope, flags)
{
+ Logger logger;
Manager mgr;
ParserScope scope;
@@ -42,9 +44,9 @@ TEST(ParserScope, flags)
ASSERT_TRUE(scope.getFlag(ParserFlag::POST_HEAD));
scope.setFlag(ParserFlag::POST_HEAD, false);
ASSERT_FALSE(scope.getFlag(ParserFlag::POST_HEAD));
- scope.pop();
+ scope.pop(logger);
ASSERT_TRUE(scope.getFlag(ParserFlag::POST_HEAD));
- scope.pop();
+ scope.pop(logger);
ASSERT_FALSE(scope.getFlag(ParserFlag::POST_HEAD));
scope.setFlag(ParserFlag::POST_HEAD, true);
ASSERT_TRUE(scope.getFlag(ParserFlag::POST_HEAD));
diff --git a/test/core/parser/stack/StackTest.cpp b/test/core/parser/stack/StackTest.cpp
index e25f487..a93f14a 100644
--- a/test/core/parser/stack/StackTest.cpp
+++ b/test/core/parser/stack/StackTest.cpp
@@ -449,10 +449,10 @@ TEST(Stack, noImplicitDefaultFieldOnIncompatibleCommand)
tracker.fieldStartResult = false;
s.command("b", {});
- tracker.expect(2, 1, 1, 1, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ tracker.expect(2, 1, 1, 0, 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
+ tracker.expect(2, 2, 1, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
ASSERT_FALSE(logger.hasError());
}
@@ -563,9 +563,9 @@ TEST(Stack, invalidDefaultField)
tracker.fieldStartResult = false;
s.fieldStart(true);
s.fieldEnd();
- tracker.expect(1, 0, 1, 1, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ tracker.expect(1, 0, 1, 0, 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
+ tracker.expect(1, 1, 1, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
ASSERT_FALSE(logger.hasError());
}
@@ -583,9 +583,9 @@ TEST(Stack, errorInvalidDefaultFieldData)
s.data("test");
ASSERT_TRUE(logger.hasError());
s.fieldEnd();
- tracker.expect(1, 0, 1, 1, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
+ tracker.expect(1, 0, 1, 0, 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
+ tracker.expect(1, 1, 1, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
}
TEST(Stack, errorInvalidFieldData)
@@ -602,9 +602,9 @@ TEST(Stack, errorInvalidFieldData)
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, 0, 1, 0, 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
+ tracker.expect(1, 1, 1, 0, 0, 0, 0); // sc, ec, fsc, fse, asc, aec, dc
}
TEST(Stack, errorFieldStartNoCommand)
@@ -743,7 +743,5 @@ TEST(Stack, fieldAfterDefaultField)
tracker.expect(2, 2, 3, 3, 0, 0, 2); // sc, ec, fsc, fse, asc, aec, dc
ASSERT_FALSE(logger.hasError());
}
-
-}
}
-
+} \ No newline at end of file
diff --git a/test/formats/osml/OsmlParserTest.cpp b/test/formats/osml/OsmlParserTest.cpp
index 3472e5f..5127b32 100644
--- a/test/formats/osml/OsmlParserTest.cpp
+++ b/test/formats/osml/OsmlParserTest.cpp
@@ -158,5 +158,46 @@ TEST(OsmlParser, structureInheritance)
ASSERT_TRUE(node != nullptr);
ASSERT_TRUE(node->isa(&RttiTypes::Domain));
}
+
+TEST(OsmlParser, structWithNoField)
+{
+ OsmlStandaloneEnvironment env(logger);
+ logger.reset();
+
+ Rooted<Node> node = env.parse("struct_with_no_field.osml", "", "",
+ RttiSet{&RttiTypes::Node});
+ ASSERT_FALSE(logger.hasError());
+
+ ASSERT_TRUE(node != nullptr);
+ ASSERT_TRUE(node->isa(&RttiTypes::Document));
+}
+
+TEST(OsmlParser, invalidExplicitFields)
+{
+ OsmlStandaloneEnvironment env(logger);
+ logger.reset();
+
+ ASSERT_FALSE(logger.hasError());
+ Rooted<Node> node = env.parse("invalid_explicit_fields.osml", "", "",
+ RttiSet{&RttiTypes::Node});
+ ASSERT_TRUE(logger.hasError());
+
+ ASSERT_TRUE(node != nullptr);
+ ASSERT_TRUE(node->isa(&RttiTypes::Document));
+}
+
+TEST(OsmlParser, explicitFields)
+{
+ OsmlStandaloneEnvironment env(logger);
+ logger.reset();
+
+ Rooted<Node> node = env.parse("explicit_fields.osml", "", "",
+ RttiSet{&RttiTypes::Node});
+ ASSERT_FALSE(logger.hasError());
+
+ ASSERT_TRUE(node != nullptr);
+ ASSERT_TRUE(node->isa(&RttiTypes::Document));
+}
+
}
diff --git a/test/formats/osxml/OsxmlParserTest.cpp b/test/formats/osxml/OsxmlParserTest.cpp
index 5cc0669..3bf4a47 100644
--- a/test/formats/osxml/OsxmlParserTest.cpp
+++ b/test/formats/osxml/OsxmlParserTest.cpp
@@ -66,15 +66,6 @@ TEST(OsxmlParser, mismatchedTag)
ASSERT_TRUE(logger.hasError());
}
-TEST(OsxmlParser, generic)
-{
- XmlStandaloneEnvironment env(logger);
- env.parse("generic.osxml", "", "", RttiSet{&RttiTypes::Node});
-#ifdef MANAGER_GRAPHVIZ_EXPORT
- env.manager.exportGraphviz("xmlDocument.dot");
-#endif
-}
-
static void checkAttributes(Handle<StructType> expected,
Handle<Descriptor> desc)
{
@@ -347,6 +338,7 @@ static void checkText(Handle<Node> p, Handle<Node> expectedParent,
TEST(OsxmlParser, documentParsing)
{
+ logger.reset();
XmlStandaloneEnvironment env(logger);
Rooted<Node> book_document_node =
env.parse("simple_book.osxml", "", "", RttiSet{&RttiTypes::Document});
@@ -391,5 +383,21 @@ TEST(OsxmlParser, documentParsing)
}
}
}
+
+
+TEST(OsxmlParser, complexDocumentParsing)
+{
+ logger.reset();
+ XmlStandaloneEnvironment env(logger);
+ Rooted<Node> book_document_node =
+ env.parse("complex_book.osxml", "", "", RttiSet{&RttiTypes::Document});
+ ASSERT_FALSE(logger.hasError());
+ ASSERT_FALSE(book_document_node == nullptr);
+ ASSERT_TRUE(book_document_node->isa(&RttiTypes::Document));
+ Rooted<Document> doc = book_document_node.cast<Document>();
+ ASSERT_TRUE(doc->validate(logger));
+ ASSERT_FALSE(logger.hasError());
+}
+
}
diff --git a/test/plugins/xml/XmlOutputTest.cpp b/test/plugins/xml/XmlOutputTest.cpp
index 403078d..fcf72d2 100644
--- a/test/plugins/xml/XmlOutputTest.cpp
+++ b/test/plugins/xml/XmlOutputTest.cpp
@@ -107,5 +107,45 @@ TEST(DemoHTMLTransformer, AnnotationProcessing)
"><book:text>blub</book:text><a:end:emphasized/"
"><book:text>bla</book:text><a:end:strong/>") != std::string::npos);
}
+
+TEST(DemoHTMLTransformer, PrimitiveSubtreeFields)
+{
+ // Construct Manager
+ TerminalLogger logger{std::cerr, true};
+ Manager mgr{1};
+ Rooted<SystemTypesystem> sys{new SystemTypesystem(mgr)};
+ // Construct a simple domain.
+ Rooted<Domain> domain{new Domain(mgr, sys, "myDomain")};
+
+ Rooted<StructuredClass> A{new StructuredClass(
+ mgr, "A", domain, Cardinality::any(), nullptr, false, true)};
+ Rooted<FieldDescriptor> A_a =
+ A->createPrimitiveFieldDescriptor(sys->getStringType(), logger,
+ FieldDescriptor::FieldType::SUBTREE,
+ "a").first;
+ Rooted<FieldDescriptor> A_b =
+ A->createPrimitiveFieldDescriptor(sys->getStringType(), logger,
+ FieldDescriptor::FieldType::SUBTREE,
+ "b").first;
+ Rooted<FieldDescriptor> A_main =
+ A->createPrimitiveFieldDescriptor(sys->getStringType(), logger).first;
+ ASSERT_TRUE(domain->validate(logger));
+ // Construct a document for it.
+ Rooted<Document> doc{new Document(mgr, "myDoc")};
+ Rooted<StructuredEntity> A_impl = doc->createRootStructuredEntity(A);
+ A_impl->createChildDocumentPrimitive("test_a", "a");
+ A_impl->createChildDocumentPrimitive("test_b", "b");
+ A_impl->createChildDocumentPrimitive("test");
+ ASSERT_TRUE(doc->validate(logger));
+ // now transform this document.
+ ResourceManager dummy;
+ XmlTransformer transformer;
+ std::stringstream out;
+ transformer.writeXml(doc, out, logger, dummy, false);
+ const std::string res = out.str();
+ ASSERT_TRUE(
+ res.find("<myDomain:A><a>test_a</a><b>test_b</b>test</myDomain:A>") !=
+ std::string::npos);
+}
}
} \ No newline at end of file