From 87d4f03187c66181c47696f879542b5bf911e8c4 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 14 Oct 2014 04:11:26 +0000 Subject: tests: Add a test for printing comments that contain -- git-svn-id: https://pugixml.googlecode.com/svn/trunk@1059 99668b35-9821-0410-8761-19e4c4f06640 --- tests/test_write.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'tests') diff --git a/tests/test_write.cpp b/tests/test_write.cpp index 0c20e26..98650ac 100644 --- a/tests/test_write.cpp +++ b/tests/test_write.cpp @@ -57,6 +57,29 @@ TEST_XML_FLAGS(write_comment, "", parse_comments | parse_fragment) CHECK_NODE_EX(doc, STR("\n"), STR(""), 0); } +TEST(write_comment_invalid) +{ + xml_document doc; + xml_node child = doc.append_child(node_comment); + + CHECK_NODE(doc, STR("")); + + child.set_value(STR("-")); + CHECK_NODE(doc, STR("")); + + child.set_value(STR("--")); + CHECK_NODE(doc, STR("")); + + child.set_value(STR("---")); + CHECK_NODE(doc, STR("")); + + child.set_value(STR("-->")); + CHECK_NODE(doc, STR("")); + + child.set_value(STR("-->-")); + CHECK_NODE(doc, STR("")); +} + TEST_XML_FLAGS(write_pi, "", parse_pi | parse_fragment) { CHECK_NODE(doc, STR("")); -- cgit v1.2.3 From 883031fb45cf0f86cd36b20ad4762da58dd6126c Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 15 Oct 2014 06:05:49 +0000 Subject: XPath: Fix optimization bug with //name[last()] The actual condition for the optimization is invariance from context list -- this includes both position() and last(). Instead of splitting the posinv concept just include last() into non-posinv expressions - this requires sorting for boolean predicates that depend on last() and do not depend on position(). These cases should be very rare. git-svn-id: https://pugixml.googlecode.com/svn/trunk@1060 99668b35-9821-0410-8761-19e4c4f06640 --- tests/test_xpath_paths.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tests') diff --git a/tests/test_xpath_paths.cpp b/tests/test_xpath_paths.cpp index c18acd2..43096bc 100644 --- a/tests/test_xpath_paths.cpp +++ b/tests/test_xpath_paths.cpp @@ -531,6 +531,12 @@ TEST_XML(xpath_paths_descendant_optimize, "") +{ + CHECK_XPATH_NODESET(doc, STR("//para[last()]")) % 6 % 7 % 8; + CHECK_XPATH_NODESET(doc, STR("//para[last() = 1]")) % 7; +} + TEST_XML(xpath_paths_precision, "") { CHECK_XPATH_NODESET(doc, STR("//para[1]")) % 3; -- cgit v1.2.3 From 5da51dff270f430701b26428c9422f21e0ea4c9c Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 16 Oct 2014 03:46:42 +0000 Subject: XPath: Optimize attribute axis lookup When looking for an attribute by name, finding the first attribute means we can stop looking since attribute names are unique. This makes some queries faster by 40%. Another very common pattern in XPath queries is finding an attribute with a specified value using a predicate (@name = 'value'). While we perform an optimal amount of traversal in that case, there is a substantial overhead with evaluating the nodes, saving and restoring the stack state, pushing the attribute node into a set, etc. Detecting this pattern allows us to use optimized code, resulting in up to 2x speedup for some queries. git-svn-id: https://pugixml.googlecode.com/svn/trunk@1061 99668b35-9821-0410-8761-19e4c4f06640 --- tests/test_xpath_paths.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'tests') diff --git a/tests/test_xpath_paths.cpp b/tests/test_xpath_paths.cpp index 43096bc..4528acd 100644 --- a/tests/test_xpath_paths.cpp +++ b/tests/test_xpath_paths.cpp @@ -561,4 +561,22 @@ TEST_XML(xpath_paths_unsorted_child, "") +{ + CHECK_XPATH_NODESET(doc, STR("node[@id = '1']")) % 2; + CHECK_XPATH_NODESET(doc, STR("node[@id = '2']")) % 4; + CHECK_XPATH_NODESET(doc, STR("node[@id = 2]")) % 4; + CHECK_XPATH_NODESET(doc, STR("node[@id[. > 3] = '2']")); + CHECK_XPATH_NODESET(doc, STR("node['1' = @id]")) % 2; + + xpath_variable_set set; + set.set(STR("var1"), STR("2")); + set.set(STR("var2"), 2.0); + + CHECK_XPATH_NODESET_VAR(doc, STR("node[@id = $var1]"), &set) % 4; + CHECK_XPATH_NODESET_VAR(doc, STR("node[@id = $var2]"), &set) % 4; + + CHECK_XPATH_NODESET(doc, STR("node[@xmlns = '3']")); +} + #endif -- cgit v1.2.3 From 45e0c726f05d8a658600b7ca74db42f252f126e9 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 16 Oct 2014 06:41:04 +0000 Subject: tests: Disable tests that rely on ceil() on CLR CLR x64 JIT does not implement ceil() properly (ceil(-0.1) returns positive zero instead of negative zero). Disable the relevant portions of tests so that everything else is green... git-svn-id: https://pugixml.googlecode.com/svn/trunk@1062 99668b35-9821-0410-8761-19e4c4f06640 --- tests/test_xpath_functions.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/test_xpath_functions.cpp b/tests/test_xpath_functions.cpp index f5d9e53..da820ef 100644 --- a/tests/test_xpath_functions.cpp +++ b/tests/test_xpath_functions.cpp @@ -114,7 +114,7 @@ TEST(xpath_number_ceiling) CHECK_XPATH_STRING(c, STR("string(1 div ceiling(0))"), STR("Infinity")); // ceiling with argument in range (-1, -0] should result in minus zero -#if !(defined(__APPLE__) && defined(__MACH__)) // MacOS X gcc 4.0.1 implements ceil incorrectly (ceil never returns -0) +#if !(defined(__APPLE__) && defined(__MACH__)) && !defined(__CLR_VER) // MacOS X gcc 4.0.1 and x64 CLR implement ceil incorrectly (ceil never returns -0) CHECK_XPATH_STRING(c, STR("string(1 div ceiling(-0))"), STR("-Infinity")); CHECK_XPATH_STRING(c, STR("string(1 div ceiling(-0.1))"), STR("-Infinity")); #endif @@ -145,7 +145,7 @@ TEST(xpath_number_round) // round with argument in range [-0.5, -0] should result in minus zero CHECK_XPATH_STRING(c, STR("string(1 div round(0))"), STR("Infinity")); -#if !(defined(__APPLE__) && defined(__MACH__)) // MacOS X gcc 4.0.1 implements ceil incorrectly (ceil never returns -0) +#if !(defined(__APPLE__) && defined(__MACH__)) && !defined(__CLR_VER) // MacOS X gcc 4.0.1 and x64 CLR implement ceil incorrectly (ceil never returns -0) CHECK_XPATH_STRING(c, STR("string(1 div round(-0.5))"), STR("-Infinity")); CHECK_XPATH_STRING(c, STR("string(1 div round(-0))"), STR("-Infinity")); CHECK_XPATH_STRING(c, STR("string(1 div round(-0.1))"), STR("-Infinity")); -- cgit v1.2.3 From 72ec01c5f6d23405f30614d63fafa048279ca13d Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 18 Oct 2014 15:28:02 +0000 Subject: XPath: Extend the descendant-or-self optimization Use descendant-or-self::node() transformation for self, descendant and descendant-or-self axis. Self axis should be semi-frequent; descendant axes should not really be used with // but if they ever are the complexity of the step becomes quadratic so it's better to optimize this if possible. git-svn-id: https://pugixml.googlecode.com/svn/trunk@1063 99668b35-9821-0410-8761-19e4c4f06640 --- tests/test_xpath_paths.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'tests') diff --git a/tests/test_xpath_paths.cpp b/tests/test_xpath_paths.cpp index 4528acd..b6f53c7 100644 --- a/tests/test_xpath_paths.cpp +++ b/tests/test_xpath_paths.cpp @@ -531,6 +531,21 @@ TEST_XML(xpath_paths_descendant_optimize, "") +{ + CHECK_XPATH_NODESET(doc, STR("//.")) % 1 % 2 % 3 % 4 % 5 % 6 % 7 % 8; + CHECK_XPATH_NODESET(doc, STR("//descendant::*")) % 2 % 3 % 4 % 5 % 6 % 7 % 8; + CHECK_XPATH_NODESET(doc, STR("//descendant-or-self::*")) % 2 % 3 % 4 % 5 % 6 % 7 % 8; + + CHECK_XPATH_NODESET(doc, STR("//..")) % 1 % 2 % 3 % 6; + CHECK_XPATH_NODESET(doc, STR("//ancestor::*")) % 2 % 3 % 6; + CHECK_XPATH_NODESET(doc, STR("//ancestor-or-self::*")) % 2 % 3 % 4 % 5 % 6 % 7 % 8; + CHECK_XPATH_NODESET(doc, STR("//preceding-sibling::*")) % 3 % 4 % 5; + CHECK_XPATH_NODESET(doc, STR("//following-sibling::*")) % 5 % 6 % 8; + CHECK_XPATH_NODESET(doc, STR("//preceding::*")) % 3 % 4 % 5 % 6 % 7; + CHECK_XPATH_NODESET(doc, STR("//following::*")) % 5 % 6 % 7 % 8; +} + TEST_XML(xpath_paths_descendant_optimize_last, "") { CHECK_XPATH_NODESET(doc, STR("//para[last()]")) % 6 % 7 % 8; -- cgit v1.2.3 From f6635588758ed1b650be22903c2e2e81273e05c5 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sun, 19 Oct 2014 07:33:42 +0000 Subject: XPath: Introduce xpath_query::evaluate_node This method is equivalent to xml_node::select_single_node. This makes select_single_node faster in certain cases by avoiding an allocation and - more importantly - paves the way for future step optimizations. git-svn-id: https://pugixml.googlecode.com/svn/trunk@1064 99668b35-9821-0410-8761-19e4c4f06640 --- tests/test_xpath_api.cpp | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/test_xpath_api.cpp b/tests/test_xpath_api.cpp index d831712..8ec5694 100644 --- a/tests/test_xpath_api.cpp +++ b/tests/test_xpath_api.cpp @@ -154,6 +154,9 @@ TEST_XML(xpath_api_evaluate, "") xpath_node_set ns = q.evaluate_node_set(doc); CHECK(ns.size() == 1 && ns[0].attribute() == doc.child(STR("node")).attribute(STR("attr"))); + + xpath_node nr = q.evaluate_node(doc); + CHECK(nr.attribute() == doc.child(STR("node")).attribute(STR("attr"))); } TEST_XML(xpath_api_evaluate_attr, "") @@ -173,6 +176,9 @@ TEST_XML(xpath_api_evaluate_attr, "") xpath_node_set ns = q.evaluate_node_set(n); CHECK(ns.size() == 1 && ns[0] == n); + + xpath_node nr = q.evaluate_node(n); + CHECK(nr == n); } #ifdef PUGIXML_NO_EXCEPTIONS @@ -190,18 +196,20 @@ TEST_XML(xpath_api_evaluate_fail, "") #endif CHECK(q.evaluate_node_set(doc).empty()); + + CHECK(!q.evaluate_node(doc)); } #endif TEST(xpath_api_evaluate_node_set_fail) { + xpath_query q(STR("1")); + #ifdef PUGIXML_NO_EXCEPTIONS - CHECK_XPATH_NODESET(xml_node(), STR("1")); + CHECK(q.evaluate_node_set(xml_node()).empty()); #else try { - xpath_query q(STR("1")); - q.evaluate_node_set(xml_node()); CHECK_FORCE_FAIL("Expected exception"); @@ -212,6 +220,25 @@ TEST(xpath_api_evaluate_node_set_fail) #endif } +TEST(xpath_api_evaluate_node_fail) +{ + xpath_query q(STR("1")); + +#ifdef PUGIXML_NO_EXCEPTIONS + CHECK(!q.evaluate_node(xml_node())); +#else + try + { + q.evaluate_node(xml_node()); + + CHECK_FORCE_FAIL("Expected exception"); + } + catch (const xpath_exception&) + { + } +#endif +} + TEST(xpath_api_evaluate_string) { xpath_query q(STR("\"0123456789\"")); -- cgit v1.2.3 From c3eb9c92a86b041b40e70afb32ea66d4369c892b Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sun, 19 Oct 2014 07:33:51 +0000 Subject: XPath: Rename xml_node::select_single_node to ::select_node select_node is shorter and mistyping nodes as node or vice versa should not lead to any issues since return types are substantially different. select_single_node method still works and will be deprecated with an attribute and removed at some point. git-svn-id: https://pugixml.googlecode.com/svn/trunk@1065 99668b35-9821-0410-8761-19e4c4f06640 --- tests/test_xpath_api.cpp | 32 +++++++++++++++++++++----------- tests/test_xpath_variables.cpp | 2 +- tests/test_xpath_xalan_3.cpp | 16 ++++++++-------- 3 files changed, 30 insertions(+), 20 deletions(-) (limited to 'tests') diff --git a/tests/test_xpath_api.cpp b/tests/test_xpath_api.cpp index 8ec5694..270f6aa 100644 --- a/tests/test_xpath_api.cpp +++ b/tests/test_xpath_api.cpp @@ -19,22 +19,22 @@ TEST_XML(xpath_api_select_nodes, "") xpath_node_set_tester(ns2, "ns2") % 4 % 5; } -TEST_XML(xpath_api_select_single_node, "") +TEST_XML(xpath_api_select_node, "") { - xpath_node n1 = doc.select_single_node(STR("node/foo")); + xpath_node n1 = doc.select_node(STR("node/foo")); xpath_query q(STR("node/foo")); - xpath_node n2 = doc.select_single_node(q); + xpath_node n2 = doc.select_node(q); CHECK(n1.node().attribute(STR("id")).as_int() == 1); CHECK(n2.node().attribute(STR("id")).as_int() == 1); - xpath_node n3 = doc.select_single_node(STR("node/bar")); + xpath_node n3 = doc.select_node(STR("node/bar")); CHECK(!n3); - xpath_node n4 = doc.select_single_node(STR("node/head/following-sibling::foo")); - xpath_node n5 = doc.select_single_node(STR("node/tail/preceding-sibling::foo")); + xpath_node n4 = doc.select_node(STR("node/head/following-sibling::foo")); + xpath_node n5 = doc.select_node(STR("node/tail/preceding-sibling::foo")); CHECK(n4.node().attribute(STR("id")).as_int() == 1); CHECK(n5.node().attribute(STR("id")).as_int() == 1); @@ -42,20 +42,20 @@ TEST_XML(xpath_api_select_single_node, "< TEST_XML(xpath_api_node_bool_ops, "") { - generic_bool_ops_test(doc.select_single_node(STR("node"))); - generic_bool_ops_test(doc.select_single_node(STR("node/@attr"))); + generic_bool_ops_test(doc.select_node(STR("node"))); + generic_bool_ops_test(doc.select_node(STR("node/@attr"))); } TEST_XML(xpath_api_node_eq_ops, "") { - generic_eq_ops_test(doc.select_single_node(STR("node")), doc.select_single_node(STR("node/@attr"))); + generic_eq_ops_test(doc.select_node(STR("node")), doc.select_node(STR("node/@attr"))); } TEST_XML(xpath_api_node_accessors, "") { xpath_node null; - xpath_node node = doc.select_single_node(STR("node")); - xpath_node attr = doc.select_single_node(STR("node/@attr")); + xpath_node node = doc.select_node(STR("node")); + xpath_node attr = doc.select_node(STR("node/@attr")); CHECK(!null.node()); CHECK(!null.attribute()); @@ -411,4 +411,14 @@ TEST_XML(xpath_api_node_set_assign_out_of_memory_preserve, "") +{ + xpath_node n1 = doc.select_single_node(STR("node/foo")); + + xpath_query q(STR("node/foo")); + xpath_node n2 = doc.select_single_node(q); + + CHECK(n1.node().attribute(STR("id")).as_int() == 1); + CHECK(n2.node().attribute(STR("id")).as_int() == 1); +} #endif diff --git a/tests/test_xpath_variables.cpp b/tests/test_xpath_variables.cpp index 785a504..70bb4ea 100644 --- a/tests/test_xpath_variables.cpp +++ b/tests/test_xpath_variables.cpp @@ -281,7 +281,7 @@ TEST_XML(xpath_variables_select, "") xpath_node_set ns = doc.select_nodes(STR("node[@attr=$one+1]"), &set); CHECK(ns.size() == 1 && ns[0].node() == doc.last_child()); - xpath_node n = doc.select_single_node(STR("node[@attr=$one+1]"), &set); + xpath_node n = doc.select_node(STR("node[@attr=$one+1]"), &set); CHECK(n == ns[0]); } diff --git a/tests/test_xpath_xalan_3.cpp b/tests/test_xpath_xalan_3.cpp index 54b8a62..d2df3e5 100644 --- a/tests/test_xpath_xalan_3.cpp +++ b/tests/test_xpath_xalan_3.cpp @@ -4,7 +4,7 @@ TEST_XML(xpath_xalan_axes_1, "
") { - xml_node center = doc.select_single_node(STR("//center")).node(); + xml_node center = doc.select_node(STR("//center")).node(); CHECK_XPATH_NODESET(center, STR("self::*[near-south]")) % 10; CHECK_XPATH_NODESET(center, STR("self::*[@center-attr-2]")) % 10; @@ -35,7 +35,7 @@ TEST_XML(xpath_xalan_axes_1, " Level-1 Level-2 Level-3 Level-4
Level-5 Level-6
", parse_default | parse_comments | parse_pi) { - xml_node center = doc.select_single_node(STR("//center")).node(); + xml_node center = doc.select_node(STR("//center")).node(); CHECK_XPATH_NODESET(center, STR("@*")) % 21 % 22 % 23; CHECK_XPATH_NODESET(center, STR("@*/child::*")); @@ -65,7 +65,7 @@ TEST_XML_FLAGS(xpath_xalan_axes_2, " Level-1
") { - xml_node center = doc.select_single_node(STR("//center")).node(); + xml_node center = doc.select_node(STR("//center")).node(); CHECK_XPATH_NODESET(center, STR("ancestor-or-self::*")) % 8 % 4 % 3 % 2; CHECK_XPATH_NODESET(center, STR("ancestor::*[3]")) % 2; @@ -99,7 +99,7 @@ TEST_XML(xpath_xalan_axes_3, "
") { - xml_node north = doc.select_single_node(STR("//north")).node(); + xml_node north = doc.select_node(STR("//north")).node(); CHECK_XPATH_STRING(north, STR("name(/descendant-or-self::north)"), STR("north")); CHECK_XPATH_STRING(north, STR("name(/descendant::near-north)"), STR("near-north")); @@ -166,7 +166,7 @@ TEST_XML(xpath_xalan_axes_6, "Test for source tree depth
A< TEST_XML(xpath_xalan_axes_7, "
") { - xml_node center = doc.select_single_node(STR("//center")).node(); + xml_node center = doc.select_node(STR("//center")).node(); CHECK_XPATH_NODESET(center, STR("attribute::*[2]")) % 10; CHECK_XPATH_NODESET(center, STR("@*")) % 9 % 10 % 11; @@ -177,7 +177,7 @@ TEST_XML(xpath_xalan_axes_7, "
") { - xml_node near_north = doc.select_single_node(STR("//near-north")).node(); + xml_node near_north = doc.select_node(STR("//near-north")).node(); CHECK_XPATH_NODESET(near_north, STR("center//child::*")) % 12 % 13 % 14 % 15 % 16; CHECK_XPATH_NODESET(near_north, STR("center//descendant::*")) % 12 % 13 % 14 % 15 % 16; @@ -188,7 +188,7 @@ TEST_XML(xpath_xalan_axes_8, "") { - xml_node baz = doc.select_single_node(STR("//baz")).node(); + xml_node baz = doc.select_node(STR("//baz")).node(); CHECK_XPATH_NODESET(baz, STR("ancestor-or-self::*[@att1][1]/@att1")) % 8; CHECK_XPATH_NODESET(baz, STR("(ancestor-or-self::*)[@att1][1]/@att1")) % 4; @@ -243,7 +243,7 @@ TEST_XML_FLAGS(xpath_xalan_axes_12, "north-text1") { xml_node d = doc.child(STR("doc")); - xml_node baz = doc.select_single_node(STR("//baz")).node(); + xml_node baz = doc.select_node(STR("//baz")).node(); CHECK_XPATH_NUMBER(d, STR("count(descendant-or-self::*/@att1)"), 5); CHECK_XPATH_NODESET(d, STR("descendant-or-self::*/@att1[last()]")) % 3 % 5 % 7 % 9 % 11; -- cgit v1.2.3 From 1b8b87904b0618f853345619e7ee2656cab80113 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 20 Oct 2014 01:00:48 +0000 Subject: XPath: Introduce _first/_any set evaluation modes Sometimes when evaluating the node set we don't need the entire set and only need the first element in docorder or any element. In the absence of iterator support we can still use this information to short-circuit traversals. This does not have any effect on straightforward node collection queries, but frequently improves performance of complex queries with predicates etc. XMark benchmark gets 15x faster with some queries enjoying 100x speedup on 10 Mb dataset due to a significant complexity improvement. git-svn-id: https://pugixml.googlecode.com/svn/trunk@1067 99668b35-9821-0410-8761-19e4c4f06640 --- tests/test_xpath.cpp | 22 ++++++++++++++++++++++ tests/test_xpath_paths.cpp | 22 ++++++++++++++++++++++ 2 files changed, 44 insertions(+) (limited to 'tests') diff --git a/tests/test_xpath.cpp b/tests/test_xpath.cpp index f7da258..2143376 100644 --- a/tests/test_xpath.cpp +++ b/tests/test_xpath.cpp @@ -122,6 +122,28 @@ TEST_XML(xpath_sort_attributes, "") xpath_node_set_tester(reverse_sorted, "reverse sorted order failed") % 5 % 4 % 3; } +TEST(xpath_sort_random_medium) +{ + xml_document doc; + load_document_copy(doc, STR("") + STR("testtest") + STR("testtest") + STR("testtest") + STR("")); + + xpath_node_set ns = doc.select_nodes(STR("//node() | //@*")); + + std::vector nsv(ns.begin(), ns.end()); + std::random_shuffle(nsv.begin(), nsv.end()); + + xpath_node_set copy(&nsv[0], &nsv[0] + nsv.size()); + copy.sort(); + + xpath_node_set_tester tester(copy, "sorted order failed"); + + for (unsigned int i = 2; i < 39; ++i) tester % i; +} + TEST(xpath_sort_random_large) { xml_document doc; diff --git a/tests/test_xpath_paths.cpp b/tests/test_xpath_paths.cpp index b6f53c7..d791cdf 100644 --- a/tests/test_xpath_paths.cpp +++ b/tests/test_xpath_paths.cpp @@ -594,4 +594,26 @@ TEST_XML(xpath_paths_optimize_compare_attribute, " CHECK_XPATH_NODESET(doc, STR("node[@xmlns = '3']")); } +TEST_XML(xpath_paths_optimize_step_once, "") +{ + CHECK_XPATH_BOOLEAN(doc, STR("node//para2/following::*"), true); + CHECK_XPATH_BOOLEAN(doc, STR("node//para6/following::*"), false); + + CHECK_XPATH_STRING(doc, STR("name(node//para2/following::*)"), STR("para3")); + CHECK_XPATH_STRING(doc, STR("name(node//para6/following::*)"), STR("")); + + CHECK_XPATH_BOOLEAN(doc, STR("node//para1/preceding::*"), false); + CHECK_XPATH_BOOLEAN(doc, STR("node//para6/preceding::*"), true); + + CHECK_XPATH_STRING(doc, STR("name(node//para1/preceding::*)"), STR("")); + CHECK_XPATH_STRING(doc, STR("name(node//para6/preceding::*)"), STR("para1")); + + CHECK_XPATH_BOOLEAN(doc, STR("node//para6/preceding::para4"), true); + + CHECK_XPATH_BOOLEAN(doc, STR("//@attr5/ancestor-or-self::*"), true); + CHECK_XPATH_BOOLEAN(doc, STR("//@attr5/ancestor::*"), true); + + CHECK_XPATH_BOOLEAN(doc, STR("//@attr5/following::para6"), true); + CHECK_XPATH_STRING(doc, STR("name(//@attr5/following::para6)"), STR("para6")); +} #endif -- cgit v1.2.3 From 45b6315d995d70bc117b2ee7320112e54050463c Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Mon, 20 Oct 2014 01:00:56 +0000 Subject: tests: Add a coverage test for unspecified_bool It's unfortunate that we can even do that... git-svn-id: https://pugixml.googlecode.com/svn/trunk@1068 99668b35-9821-0410-8761-19e4c4f06640 --- tests/test_dom_traverse.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'tests') diff --git a/tests/test_dom_traverse.cpp b/tests/test_dom_traverse.cpp index c2437ab..e42846f 100644 --- a/tests/test_dom_traverse.cpp +++ b/tests/test_dom_traverse.cpp @@ -1043,3 +1043,19 @@ TEST_XML(dom_node_children_attributes, "< CHECK(r4.begin() == xml_attribute_iterator()); CHECK(r4.end() == xml_attribute_iterator()); } + +TEST_XML(dom_unspecified_bool_coverage, "text") +{ + xml_node node = doc.first_child(); + + node(0); + node.first_attribute()(0); + node.text()(0); + +#ifndef PUGIXML_NO_XPATH + xpath_query q(STR("/node")); + + q(0); + q.evaluate_node(doc)(0); +#endif +} -- cgit v1.2.3 From 7774cdd96e01b2d89be16f7e240c1ffb2436b4c9 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 21 Oct 2014 03:33:37 +0000 Subject: XPath: Make sure step_push is called with valid nodes Some steps relied on step_push rejecting null inputs; this is no longer the case. Additionally stepping now more rigorously filters null inputs. git-svn-id: https://pugixml.googlecode.com/svn/trunk@1069 99668b35-9821-0410-8761-19e4c4f06640 --- tests/test_xpath_paths.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'tests') diff --git a/tests/test_xpath_paths.cpp b/tests/test_xpath_paths.cpp index d791cdf..f1d52ad 100644 --- a/tests/test_xpath_paths.cpp +++ b/tests/test_xpath_paths.cpp @@ -616,4 +616,27 @@ TEST_XML(xpath_paths_optimize_step_once, "

") +{ + xpath_node nodes[] = + { + xpath_node(doc.first_child()), + xpath_node(xml_node()), + xpath_node(doc.first_child().first_attribute(), doc.first_child()), + xpath_node(xml_attribute(), doc.first_child()), + xpath_node(xml_attribute(), xml_node()), + }; + + xpath_node_set ns(nodes, nodes + sizeof(nodes) / sizeof(nodes[0])); + + xpath_variable_set vars; + vars.set(STR("x"), ns); + + xpath_node_set rs = xpath_query("$x/.", &vars).evaluate_node_set(xml_node()); + + CHECK(rs.size() == 2); + CHECK(rs[0] == nodes[0]); + CHECK(rs[1] == nodes[2]); +} #endif -- cgit v1.2.3 From 7258aea09be1847b3dcc99ca389990027d4a92d3 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 21 Oct 2014 03:33:47 +0000 Subject: tests: Assert on out-of-memory in tests This should never happen but can improve debugging experience for work-in-progress changes since that avoids memcpy() into negative memory space (debugger can't backtrace from failed memcpy since it does not set up the stack frame). git-svn-id: https://pugixml.googlecode.com/svn/trunk@1070 99668b35-9821-0410-8761-19e4c4f06640 --- tests/allocator.cpp | 3 +++ tests/main.cpp | 1 + 2 files changed, 4 insertions(+) (limited to 'tests') diff --git a/tests/allocator.cpp b/tests/allocator.cpp index 3641585..094d5e5 100644 --- a/tests/allocator.cpp +++ b/tests/allocator.cpp @@ -1,6 +1,7 @@ #include "allocator.hpp" #include +#include // Low-level allocation functions #if defined(_WIN32) || defined(_WIN64) @@ -97,6 +98,8 @@ void* memory_allocate(size_t size) size_t memory_size(void* ptr) { + assert(ptr); + size_t result; memcpy(&result, static_cast(ptr) - 1, sizeof(size_t)); diff --git a/tests/main.cpp b/tests/main.cpp index 3bcf9be..75b0108 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -34,6 +34,7 @@ static void* custom_allocate(size_t size) else { void* ptr = memory_allocate(size); + assert(ptr); g_memory_total_size += memory_size(ptr); g_memory_total_count++; -- cgit v1.2.3