/* 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 namespace ousia { class TestNode : public Node { protected: void doResolve(ResolutionState &state) override { continueResolveComposita(composita, composita.getIndex(), state); continueResolveReferences(references, state); } public: NodeVector composita; NodeVector references; TestNode(Manager &mgr, Handle parent = nullptr) : Node(mgr, parent), composita(this), references(this) { } TestNode(Manager &mgr, std::string name, Handle parent = nullptr) : Node(mgr, name, parent), composita(this), references(this) { } Rooted addCompositum(Handle n) { composita.push_back(n); return n; } Rooted addReference(Handle n) { references.push_back(n); return n; } }; namespace RttiTypes { const Rtti TestNode = RttiBuilder("TestNode") .parent(&RttiTypes::Node) .composedOf(&TestNode); } TEST(Node, isRoot) { Manager mgr{1}; Rooted n1{new TestNode(mgr)}; Rooted n2{new TestNode(mgr)}; Rooted n3{new TestNode(mgr, n2)}; ASSERT_TRUE(n1->isRoot()); ASSERT_TRUE(n2->isRoot()); ASSERT_FALSE(n3->isRoot()); } TEST(Node, resolveCompositaSimple) { Manager mgr{1}; Rooted root{new TestNode(mgr, "root")}; Rooted child1 = root->addCompositum(new TestNode(mgr, "child1")); Rooted child11 = child1->addCompositum(new TestNode(mgr, "child11")); std::vector res; res = root->resolve(&RttiTypes::TestNode, std::vector{"root", "child1", "child11"}); ASSERT_EQ(1U, res.size()); ASSERT_TRUE(child11 == res[0].node); res = root->resolve(&RttiTypes::TestNode, std::vector{"child1", "child11"}); ASSERT_EQ(1U, res.size()); ASSERT_TRUE(child11 == res[0].node); res = root->resolve(&RttiTypes::TestNode, std::vector{"child11"}); ASSERT_EQ(1U, res.size()); ASSERT_TRUE(child11 == res[0].node); } TEST(Node, resolveCompositaDouble) { Manager mgr{1}; Rooted root{new TestNode(mgr, "root")}; Rooted root2 = root->addCompositum(new TestNode(mgr, "root")); Rooted child1 = root2->addCompositum(new TestNode(mgr, "child1")); Rooted child11 = child1->addCompositum(new TestNode(mgr, "child11")); std::vector res; res = root->resolve(&RttiTypes::TestNode, std::vector{"root", "child1", "child11"}); ASSERT_EQ(1U, res.size()); ASSERT_TRUE(child11 == res[0].node); res = root->resolve(&RttiTypes::TestNode, std::vector{"child1", "child11"}); ASSERT_EQ(1U, res.size()); ASSERT_TRUE(child11 == res[0].node); res = root->resolve(&RttiTypes::TestNode, std::vector{"child11"}); ASSERT_EQ(1U, res.size()); ASSERT_TRUE(child11 == res[0].node); } TEST(Node, resolveAmbigousComposita) { Manager mgr{1}; Rooted root{new TestNode(mgr, "root")}; Rooted a = root->addCompositum(new TestNode(mgr, "a")); Rooted b = root->addCompositum(new TestNode(mgr, "b")); Rooted child1 = a->addCompositum(new TestNode(mgr, "child1")); Rooted child11 = child1->addCompositum(new TestNode(mgr, "child11")); Rooted child12 = b->addCompositum(new TestNode(mgr, "child1")); Rooted child112 = child12->addCompositum(new TestNode(mgr, "child11")); std::vector res; res = root->resolve(&RttiTypes::TestNode, std::vector{"child1", "child11"}); ASSERT_EQ(2U, res.size()); ASSERT_TRUE(child11 == res[0].node || child11 == res[1].node); ASSERT_TRUE(child112 == res[0].node || child112 == res[1].node); res = root->resolve(&RttiTypes::TestNode, std::vector{"child11"}); ASSERT_EQ(2U, res.size()); ASSERT_TRUE(child11 == res[0].node || child11 == res[1].node); ASSERT_TRUE(child112 == res[0].node || child112 == res[1].node); } TEST(Node, resolveReferences) { Manager mgr{1}; Rooted root{new TestNode(mgr, "root")}; Rooted a = root->addReference(new TestNode(mgr, "a")); Rooted b = root->addReference(new TestNode(mgr, "b")); Rooted child1 = a->addCompositum(new TestNode(mgr, "child1")); Rooted child11 = child1->addCompositum(new TestNode(mgr, "child11")); Rooted child12 = b->addCompositum(new TestNode(mgr, "child1")); Rooted child112 = child12->addCompositum(new TestNode(mgr, "child11")); std::vector res; res = root->resolve(&RttiTypes::TestNode, std::vector{"a", "child1", "child11"}); ASSERT_EQ(1U, res.size()); ASSERT_TRUE(child11 == res[0].node); res = root->resolve(&RttiTypes::TestNode, std::vector{"b", "child1", "child11"}); ASSERT_EQ(1U, res.size()); ASSERT_TRUE(child112 == res[0].node); res = root->resolve(&RttiTypes::TestNode, std::vector{"child1", "child11"}); ASSERT_EQ(2U, res.size()); ASSERT_TRUE(child11 == res[0].node || child11 == res[1].node); ASSERT_TRUE(child112 == res[0].node || child112 == res[1].node); res = root->resolve(&RttiTypes::TestNode, std::vector{"child11"}); ASSERT_EQ(2U, res.size()); ASSERT_TRUE(child11 == res[0].node || child11 == res[1].node); ASSERT_TRUE(child112 == res[0].node || child112 == res[1].node); res = root->resolve(&RttiTypes::TestNode, std::vector{"child1"}); ASSERT_EQ(2U, res.size()); ASSERT_TRUE(child1 == res[0].node || child1 == res[1].node); ASSERT_TRUE(child12 == res[0].node || child12 == res[1].node); } TEST(Node, resolveReferencesAndComposita) { Manager mgr{1}; Rooted root{new TestNode(mgr, "root")}; Rooted a = root->addReference(new TestNode(mgr, "a")); Rooted b = root->addReference(new TestNode(mgr, "b")); Rooted child1 = a->addCompositum(new TestNode(mgr, "child1")); Rooted child11 = child1->addCompositum(new TestNode(mgr, "child11")); Rooted child12 = b->addCompositum(new TestNode(mgr, "child1")); Rooted child112 = child12->addCompositum(new TestNode(mgr, "child11")); Rooted child13 = root->addCompositum(new TestNode(mgr, "child1")); std::vector res; res = root->resolve(&RttiTypes::TestNode, std::vector{"a", "child1", "child11"}); ASSERT_EQ(1U, res.size()); ASSERT_TRUE(child11 == res[0].node); res = root->resolve(&RttiTypes::TestNode, std::vector{"b", "child1", "child11"}); ASSERT_EQ(1U, res.size()); ASSERT_TRUE(child112 == res[0].node); res = root->resolve(&RttiTypes::TestNode, std::vector{"child1", "child11"}); ASSERT_EQ(2U, res.size()); ASSERT_TRUE(child11 == res[0].node || child11 == res[1].node); ASSERT_TRUE(child112 == res[0].node || child112 == res[1].node); res = root->resolve(&RttiTypes::TestNode, std::vector{"child11"}); ASSERT_EQ(2U, res.size()); ASSERT_TRUE(child11 == res[0].node || child11 == res[1].node); ASSERT_TRUE(child112 == res[0].node || child112 == res[1].node); // Resolving for "child1" should not descend into the referenced nodes res = root->resolve(&RttiTypes::TestNode, std::vector{"child1"}); ASSERT_EQ(1U, res.size()); ASSERT_TRUE(child13 == res[0].node); } }