diff options
-rw-r--r-- | tests/helpers.hpp | 90 | ||||
-rw-r--r-- | tests/test_dom_traverse.cpp | 86 | ||||
-rw-r--r-- | tests/test_xpath_api.cpp | 66 | ||||
-rw-r--r-- | tests/test_xpath_paths.cpp | 25 |
4 files changed, 192 insertions, 75 deletions
diff --git a/tests/helpers.hpp b/tests/helpers.hpp new file mode 100644 index 0000000..1481ccd --- /dev/null +++ b/tests/helpers.hpp @@ -0,0 +1,90 @@ +#pragma once
+
+#include "common.hpp"
+
+#include <utility>
+
+template <typename T> static void generic_bool_ops_test(const T& obj)
+{
+ T null;
+
+ CHECK(!null);
+ CHECK(obj);
+ CHECK(!!obj);
+
+ bool b1 = null, b2 = obj;
+
+ CHECK(!b1);
+ CHECK(b2);
+
+ CHECK(obj && true);
+ CHECK(obj || false);
+ CHECK(obj && obj);
+ CHECK(obj || obj);
+}
+
+template <typename T> static void generic_eq_ops_test(const T& obj1, const T& obj2)
+{
+ T null = T();
+
+ // operator==
+ CHECK(null == null);
+ CHECK(obj1 == obj1);
+ CHECK(!(null == obj1));
+ CHECK(!(null == obj2));
+ CHECK(T(null) == null);
+ CHECK(T(obj1) == obj1);
+
+ // operator!=
+ CHECK(!(null != null));
+ CHECK(!(obj1 != obj1));
+ CHECK(null != obj1);
+ CHECK(null != obj2);
+ CHECK(!(T(null) != null));
+ CHECK(!(T(obj1) != obj1));
+}
+
+template <typename T> static void generic_rel_ops_test(T obj1, T obj2)
+{
+ T null = T();
+
+ // obj1 < obj2 (we use operator<, but there is no other choice
+ if (obj1 > obj2) std::swap(obj1, obj2);
+
+ // operator<
+ CHECK(null < obj1);
+ CHECK(null < obj2);
+ CHECK(obj1 < obj2);
+ CHECK(!(null < null));
+ CHECK(!(obj1 < obj1));
+ CHECK(!(obj1 < null));
+ CHECK(!(obj2 < obj1));
+
+ // operator<=
+ CHECK(null <= obj1);
+ CHECK(null <= obj2);
+ CHECK(obj1 <= obj2);
+ CHECK(null <= null);
+ CHECK(obj1 <= obj1);
+ CHECK(!(obj1 <= null));
+ CHECK(!(obj2 <= obj1));
+
+ // operator>
+ CHECK(obj1 > null);
+ CHECK(obj2 > null);
+ CHECK(obj2 > obj1);
+ CHECK(!(null > null));
+ CHECK(!(obj1 > obj1));
+ CHECK(!(null > obj1));
+ CHECK(!(obj1 > obj2));
+
+ // operator>=
+ CHECK(obj1 >= null);
+ CHECK(obj2 >= null);
+ CHECK(obj2 >= obj1);
+ CHECK(null >= null);
+ CHECK(obj1 >= obj1);
+ CHECK(!(null >= obj1));
+ CHECK(!(obj1 >= obj2));
+}
+
diff --git a/tests/test_dom_traverse.cpp b/tests/test_dom_traverse.cpp index 0caef27..513263b 100644 --- a/tests/test_dom_traverse.cpp +++ b/tests/test_dom_traverse.cpp @@ -6,6 +6,8 @@ #include <vector>
#include <iterator>
+#include "helpers.hpp"
+
#ifdef _MSC_VER
#pragma warning(disable: 4996)
#endif
@@ -25,80 +27,6 @@ template <typename I> static I move_iter(I base, int n) }
#endif
-template <typename T> static void generic_bool_ops_test(const T& obj)
-{
- T null;
-
- CHECK(!null);
- CHECK(obj);
- CHECK(!!obj);
-
- bool b1 = null, b2 = obj;
-
- CHECK(!b1);
- CHECK(b2);
-}
-
-template <typename T> static void generic_rel_ops_test(T obj1, T obj2)
-{
- T null = T();
-
- // obj1 < obj2 (we use operator<, but there is no other choice
- if (obj1 > obj2) std::swap(obj1, obj2);
-
- // operator==
- CHECK(null == null);
- CHECK(obj1 == obj1);
- CHECK(!(null == obj1));
- CHECK(!(null == obj2));
- CHECK(T(null) == null);
- CHECK(T(obj1) == obj1);
-
- // operator!=
- CHECK(!(null != null));
- CHECK(!(obj1 != obj1));
- CHECK(null != obj1);
- CHECK(null != obj2);
- CHECK(!(T(null) != null));
- CHECK(!(T(obj1) != obj1));
-
- // operator<
- CHECK(null < obj1);
- CHECK(null < obj2);
- CHECK(obj1 < obj2);
- CHECK(!(null < null));
- CHECK(!(obj1 < obj1));
- CHECK(!(obj1 < null));
- CHECK(!(obj2 < obj1));
-
- // operator<=
- CHECK(null <= obj1);
- CHECK(null <= obj2);
- CHECK(obj1 <= obj2);
- CHECK(null <= null);
- CHECK(obj1 <= obj1);
- CHECK(!(obj1 <= null));
- CHECK(!(obj2 <= obj1));
-
- // operator>
- CHECK(obj1 > null);
- CHECK(obj2 > null);
- CHECK(obj2 > obj1);
- CHECK(!(null > null));
- CHECK(!(obj1 > obj1));
- CHECK(!(null > obj1));
- CHECK(!(obj1 > obj2));
-
- // operator>=
- CHECK(obj1 >= null);
- CHECK(obj2 >= null);
- CHECK(obj2 >= obj1);
- CHECK(null >= null);
- CHECK(obj1 >= obj1);
- CHECK(!(null >= obj1));
- CHECK(!(obj1 >= obj2));
-}
-
template <typename T> static void generic_empty_test(const T& obj)
{
T null;
@@ -112,6 +40,11 @@ TEST_XML(dom_attr_bool_ops, "<node attr='1'/>") generic_bool_ops_test(doc.child("node").attribute("attr"));
}
+TEST_XML(dom_attr_eq_ops, "<node attr1='1' attr2='2'/>")
+{
+ generic_eq_ops_test(doc.child("node").attribute("attr1"), doc.child("node").attribute("attr2"));
+}
+
TEST_XML(dom_attr_rel_ops, "<node attr1='1' attr2='2'/>")
{
generic_rel_ops_test(doc.child("node").attribute("attr1"), doc.child("node").attribute("attr2"));
@@ -250,6 +183,11 @@ TEST_XML(dom_node_bool_ops, "<node/>") generic_bool_ops_test(doc.child("node"));
}
+TEST_XML(dom_node_eq_ops, "<node><node1/><node2/></node>")
+{
+ generic_eq_ops_test(doc.child("node").child("node1"), doc.child("node").child("node2"));
+}
+
TEST_XML(dom_node_rel_ops, "<node><node1/><node2/></node>")
{
generic_rel_ops_test(doc.child("node").child("node1"), doc.child("node").child("node2"));
diff --git a/tests/test_xpath_api.cpp b/tests/test_xpath_api.cpp new file mode 100644 index 0000000..c032cb9 --- /dev/null +++ b/tests/test_xpath_api.cpp @@ -0,0 +1,66 @@ +#ifndef PUGIXML_NO_XPATH
+
+#include "common.hpp"
+
+#include "helpers.hpp"
+
+TEST_XML(xpath_api_select_nodes, "<node><head/><foo/><foo/><tail/></node>")
+{
+ doc.precompute_document_order();
+
+ xpath_node_set ns1 = doc.select_nodes("node/foo");
+
+ xpath_query q("node/foo");
+ xpath_node_set ns2 = doc.select_nodes(q);
+
+ CHECK(ns1.size() == 2 && ns1[0].node().document_order() == 4 && ns1[1].node().document_order() == 5);
+ CHECK(ns2.size() == 2 && ns2[0].node().document_order() == 4 && ns2[1].node().document_order() == 5);
+}
+
+TEST_XML(xpath_api_select_single_node, "<node><head/><foo/><foo/><tail/></node>")
+{
+ doc.precompute_document_order();
+
+ xpath_node n1 = doc.select_single_node("node/foo");
+
+ xpath_query q("node/foo");
+ xpath_node n2 = doc.select_single_node(q);
+
+ CHECK(n1.node().document_order() == 4);
+ CHECK(n2.node().document_order() == 4);
+
+ xpath_node n3 = doc.select_single_node("node/bar");
+
+ CHECK(!n3);
+
+ xpath_node n4 = doc.select_single_node("node/head/following-sibling::foo");
+ xpath_node n5 = doc.select_single_node("node/tail/preceding-sibling::foo");
+
+ CHECK(n4.node().document_order() == 4);
+ CHECK(n5.node().document_order() == 4);
+}
+
+TEST(xpath_api_exception_what)
+{
+ try
+ {
+ xpath_query q("");
+ }
+ catch (const xpath_exception& e)
+ {
+ CHECK(e.what()[0] != 0);
+ }
+}
+
+TEST_XML(xpath_api_node_bool_ops, "<node attr='value'/>")
+{
+ generic_bool_ops_test(doc.select_single_node("node"));
+ generic_bool_ops_test(doc.select_single_node("node/@attr"));
+}
+
+TEST_XML(xpath_api_node_eq_ops, "<node attr='value'/>")
+{
+ generic_eq_ops_test(doc.select_single_node("node"), doc.select_single_node("node/@attr"));
+}
+
+#endif
diff --git a/tests/test_xpath_paths.cpp b/tests/test_xpath_paths.cpp index 5b29309..f2b6402 100644 --- a/tests/test_xpath_paths.cpp +++ b/tests/test_xpath_paths.cpp @@ -404,7 +404,19 @@ TEST_XML(xpath_paths_predicate_several, "<node><employee/><employee secretary='' CHECK_XPATH_NODESET(n, "employee[@secretary and @assistant]") % 8 % 11;
}
-TEST_XML(xpath_paths_predicate_filter, "<node><chapter/><chapter/><chapter/><chapter/><chapter/></node>")
+TEST_XML(xpath_paths_predicate_filter_boolean, "<node><chapter/><chapter/><chapter/><chapter/><chapter/></node>")
+{
+ doc.precompute_document_order();
+
+ xml_node n = doc.child("node").child("chapter").next_sibling().next_sibling();
+
+ CHECK_XPATH_NODESET(n, "(following-sibling::chapter)[position()=1]") % 6;
+ CHECK_XPATH_NODESET(n, "(following-sibling::chapter)[position()=2]") % 7;
+ CHECK_XPATH_NODESET(n, "(preceding-sibling::chapter)[position()=1]") % 3;
+ CHECK_XPATH_NODESET(n, "(preceding-sibling::chapter)[position()=2]") % 4;
+}
+
+TEST_XML(xpath_paths_predicate_filter_number, "<node><chapter/><chapter/><chapter/><chapter/><chapter/></node>")
{
doc.precompute_document_order();
@@ -416,6 +428,17 @@ TEST_XML(xpath_paths_predicate_filter, "<node><chapter/><chapter/><chapter/><cha CHECK_XPATH_NODESET(n, "(preceding-sibling::chapter)[2]") % 4;
}
+TEST_XML(xpath_paths_predicate_filter_posinv, "<node><employee/><employee secretary=''/><employee assistant=''/><employee secretary='' assistant=''/><employee assistant='' secretary=''/></node>")
+{
+ doc.precompute_document_order();
+
+ xml_node n = doc.child("node");
+
+ CHECK_XPATH_NODESET(n, "employee") % 3 % 4 % 6 % 8 % 11;
+ CHECK_XPATH_NODESET(n, "(employee[@secretary])[@assistant]") % 8 % 11;
+ CHECK_XPATH_NODESET(n, "((employee)[@assistant])[@secretary]") % 8 % 11;
+}
+
TEST_XML(xpath_paths_step_compose, "<node><foo><foo/><foo/></foo><foo/></node>")
{
doc.precompute_document_order();
|