summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2014-12-03 17:58:34 +0100
committerBenjamin Paassen <bpaassen@techfak.uni-bielefeld.de>2014-12-03 17:58:34 +0100
commit51b8d39841ea1e803b07cae65020f1b8df6811aa (patch)
treede22ecf94e5c987c41007b3ac2d4165da9e935e4
parente91ba1faf25790eea34e7ae743aff06752f1ea8c (diff)
implemented Unit-Test for SelectorNode::append and fixed a bug in the append function.
-rw-r--r--src/core/CSS.cpp10
-rw-r--r--src/core/CSS.hpp11
-rw-r--r--test/core/CSSTest.cpp104
3 files changed, 119 insertions, 6 deletions
diff --git a/src/core/CSS.cpp b/src/core/CSS.cpp
index 8beb075..c3900e8 100644
--- a/src/core/CSS.cpp
+++ b/src/core/CSS.cpp
@@ -116,16 +116,22 @@ std::vector<Rooted<SelectorNode>> SelectorNode::append(
if (edge->getTarget()->getEdges().size() == 0) {
// if there are no more subsequent edges this is a leafe we could
// not merge, because it is already present in the Tree.
- out.push_back(edge->getTarget());
+ out.push_back(children[0]);
} else {
// otherwise we go into recursion.
for (auto &e : edge->getTarget()->getEdges()) {
+ Rooted<SelectorEdge> e2 {e};
std::vector<Rooted<SelectorNode>> childLeafs =
- children[0]->append(e);
+ children[0]->append(e2);
out.insert(out.end(), childLeafs.begin(), childLeafs.end());
}
}
}
return out;
}
+
+std::vector<Rooted<SelectorNode>> SelectorNode::append(Rooted<SelectorNode> node){
+ const Rooted<SelectorEdge> e {new SelectorEdge{node->getManager(), node}};
+ return std::move(append(e));
+}
}
diff --git a/src/core/CSS.hpp b/src/core/CSS.hpp
index 8c87ee7..e730721 100644
--- a/src/core/CSS.hpp
+++ b/src/core/CSS.hpp
@@ -227,8 +227,9 @@ public:
const SelectionOperator selectionOperator;
public:
- SelectorEdge(Manager &mgr, Handle<SelectorNode> target,
- SelectionOperator selectionOperator)
+ SelectorEdge(
+ Manager &mgr, Handle<SelectorNode> target,
+ SelectionOperator selectionOperator = SelectionOperator::DESCENDANT)
: Managed(mgr),
target(acquire(target)),
selectionOperator(selectionOperator)
@@ -378,6 +379,12 @@ public:
* because they were already contained.
*/
std::vector<Rooted<SelectorNode>> append(Rooted<SelectorEdge> edge);
+
+ /**
+ * This is just a convenience function which creates a new edge
+ * automatically using the DESCENDANT SelectionOperator.
+ */
+ std::vector<Rooted<SelectorNode>> append(Rooted<SelectorNode> node);
};
}
#endif
diff --git a/test/core/CSSTest.cpp b/test/core/CSSTest.cpp
index fdb8238..5bbb492 100644
--- a/test/core/CSSTest.cpp
+++ b/test/core/CSSTest.cpp
@@ -125,8 +125,7 @@ TEST(SelectorNode, testGetChildren)
std::vector<Rooted<SelectorNode>> children = {A, AMy_Select, B};
for (auto &c : children) {
- root->getEdges().push_back(new SelectorNode::SelectorEdge{
- mgr, c, SelectionOperator::DESCENDANT});
+ root->getEdges().push_back(new SelectorNode::SelectorEdge{mgr, c});
}
root->getEdges().push_back(new SelectorNode::SelectorEdge{
mgr, B, SelectionOperator::DIRECT_DESCENDANT});
@@ -166,4 +165,105 @@ TEST(SelectorNode, testGetChildren)
actual = root->getChildren();
ASSERT_EQ(expected, actual);
}
+
+TEST(SelectorNode, testAppend)
+{
+ Manager mgr(1);
+ // build the root.
+ Rooted<SelectorNode> root{new SelectorNode{mgr, "root"}};
+ // append a child.
+ Rooted<SelectorNode> A{new SelectorNode{mgr, "A"}};
+ // this should work without any unmerged leafs.
+ ASSERT_EQ(0, (root->append(A)).size());
+ /*
+ * check the result. We expect the SelectorTree
+ *
+ * root
+ * |
+ * A
+ */
+ ASSERT_EQ(1, (root->getEdges()).size());
+ std::vector<Rooted<SelectorNode>> children = root->getChildren("A");
+ ASSERT_EQ(1, children.size());
+ ASSERT_EQ(A, children[0]);
+
+ // append another child.
+ Rooted<SelectorNode> B{new SelectorNode{mgr, "B"}};
+ ASSERT_EQ(0, (root->append(B)).size());
+ /*
+ * check the result. We expect the SelectorTree
+ *
+ * root
+ * | \
+ * A B
+ */
+ ASSERT_EQ(2, (root->getEdges()).size());
+ children = root->getChildren("B");
+ ASSERT_EQ(1, children.size());
+ ASSERT_EQ(B, children[0]);
+
+ // append a grandchild using a path.
+ Rooted<SelectorNode> C{new SelectorNode{mgr, "C"}};
+ {
+ Rooted<SelectorNode> pathA{new SelectorNode{mgr, "A"}};
+ pathA->append(C);
+
+ ASSERT_EQ(0, (root->append(pathA)).size());
+ }
+ /*
+ * check the result. We expect the SelectorTree
+ *
+ * root
+ * | \
+ * A B
+ * |
+ * C
+ */
+ ASSERT_EQ(2, (root->getEdges()).size());
+ children = root->getChildren("A");
+ ASSERT_EQ(1, children.size());
+ ASSERT_EQ(1, (children[0]->getEdges()).size());
+ children = children[0]->getChildren("C");
+ ASSERT_EQ(1, children.size());
+ ASSERT_EQ(C, children[0]);
+
+ // append a subtree that is partially contained.
+ Rooted<SelectorNode> D{new SelectorNode{mgr, "D"}};
+ {
+ Rooted<SelectorNode> pathA{new SelectorNode{mgr, "A"}};
+ Rooted<SelectorNode> pathC{new SelectorNode{mgr, "C"}};
+ pathA->append(pathC);
+ pathA->append(D);
+
+ // The C leaf can not be appended because it is already part of the
+ // tree. So we expect that as a return value.
+ std::vector<Rooted<SelectorNode>> unmergedLeafs = root->append(pathA);
+ ASSERT_EQ(1,unmergedLeafs.size());
+ ASSERT_EQ(C.get(),unmergedLeafs[0].get());
+ }
+ /*
+ * check the result. We expect the SelectorTree
+ *
+ * root
+ * | \
+ * A B
+ * |\
+ * C D
+ */
+ ASSERT_EQ(2, (root->getEdges()).size());
+ children = root->getChildren("A");
+ ASSERT_EQ(1, children.size());
+ ASSERT_EQ(2, (children[0]->getEdges()).size());
+ children = children[0]->getChildren("D");
+ ASSERT_EQ(1, children.size());
+ ASSERT_EQ(D, children[0]);
+
+ // append a child with a non-trivial PseudoSelector.
+ Rooted<SelectorNode> ASelect {new SelectorNode{mgr, "A", {"my_select", {"a","b"},false}}};
+ ASSERT_EQ(0, (root->append(ASelect)).size());
+ ASSERT_EQ(3, (root->getEdges()).size());
+ children = root->getChildren("A");
+ ASSERT_EQ(2, children.size());
+ ASSERT_EQ(ASelect, children[1]);
+}
}