diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-02-18 21:29:36 +0100 |
---|---|---|
committer | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-02-18 21:29:36 +0100 |
commit | 5dfa2b6cba3e31d18e2cc23f05d330e387fc1a29 (patch) | |
tree | 2f97711bd12bfdb35425c0ffaca5af6a231b8076 /test/core | |
parent | f6d3495b681e19227a5ea9ec081d36644be55d68 (diff) | |
parent | 19e3e43e80e413d297ca8970d018eeda57ee65e1 (diff) |
Merge branch 'master' of somweyr.de:ousia
Diffstat (limited to 'test/core')
-rw-r--r-- | test/core/common/VariantConverterTest.cpp | 2 | ||||
-rw-r--r-- | test/core/model/DomainTest.cpp | 185 | ||||
-rw-r--r-- | test/core/parser/ParserScopeTest.cpp | 6 | ||||
-rw-r--r-- | test/core/parser/stack/StackTest.cpp | 20 |
4 files changed, 199 insertions, 14 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 |