diff options
Diffstat (limited to 'tests/test_dom_traverse.cpp')
-rw-r--r-- | tests/test_dom_traverse.cpp | 1512 |
1 files changed, 756 insertions, 756 deletions
diff --git a/tests/test_dom_traverse.cpp b/tests/test_dom_traverse.cpp index 896bf6f..8075dc3 100644 --- a/tests/test_dom_traverse.cpp +++ b/tests/test_dom_traverse.cpp @@ -1,756 +1,756 @@ -#define _CRT_SECURE_NO_WARNINGS
-#define _SCL_SECURE_NO_WARNINGS
-
-#include "common.hpp"
-
-#include <stdio.h>
-
-#include <string.h>
-#include <wchar.h>
-
-#include <utility>
-#include <vector>
-#include <iterator>
-#include <string>
-
-#include "helpers.hpp"
-
-#ifdef PUGIXML_NO_STL
-template <typename I> static I move_iter(I base, int n)
-{
- if (n > 0) while (n--) ++base;
- else while (n++) --base;
- return base;
-}
-#else
-template <typename I> static I move_iter(I base, int n)
-{
- std::advance(base, n);
- return base;
-}
-#endif
-
-template <typename T> static void generic_empty_test(const T& obj)
-{
- T null;
-
- CHECK(null.empty());
- CHECK(!obj.empty());
-}
-
-TEST_XML(dom_attr_bool_ops, "<node attr='1'/>")
-{
- generic_bool_ops_test(doc.child(STR("node")).attribute(STR("attr")));
-}
-
-TEST_XML(dom_attr_eq_ops, "<node attr1='1' attr2='2'/>")
-{
- generic_eq_ops_test(doc.child(STR("node")).attribute(STR("attr1")), doc.child(STR("node")).attribute(STR("attr2")));
-}
-
-TEST_XML(dom_attr_rel_ops, "<node attr1='1' attr2='2'/>")
-{
- generic_rel_ops_test(doc.child(STR("node")).attribute(STR("attr1")), doc.child(STR("node")).attribute(STR("attr2")));
-}
-
-TEST_XML(dom_attr_empty, "<node attr='1'/>")
-{
- generic_empty_test(doc.child(STR("node")).attribute(STR("attr")));
-}
-
-TEST_XML(dom_attr_next_previous_attribute, "<node attr1='1' attr2='2' />")
-{
- xml_attribute attr1 = doc.child(STR("node")).attribute(STR("attr1"));
- xml_attribute attr2 = doc.child(STR("node")).attribute(STR("attr2"));
-
- CHECK(attr1.next_attribute() == attr2);
- CHECK(attr2.next_attribute() == xml_attribute());
-
- CHECK(attr1.previous_attribute() == xml_attribute());
- CHECK(attr2.previous_attribute() == attr1);
-
- CHECK(xml_attribute().next_attribute() == xml_attribute());
- CHECK(xml_attribute().previous_attribute() == xml_attribute());
-}
-
-TEST_XML(dom_attr_name_value, "<node attr='1'/>")
-{
- xml_attribute attr = doc.child(STR("node")).attribute(STR("attr"));
-
- CHECK_NAME_VALUE(attr, STR("attr"), STR("1"));
- CHECK_NAME_VALUE(xml_attribute(), STR(""), STR(""));
-}
-
-TEST_XML(dom_attr_as_int, "<node attr1='1' attr2='-1' attr3='-2147483648' attr4='2147483647'/>")
-{
- xml_node node = doc.child(STR("node"));
-
- CHECK(xml_attribute().as_int() == 0);
- CHECK(node.attribute(STR("attr1")).as_int() == 1);
- CHECK(node.attribute(STR("attr2")).as_int() == -1);
- CHECK(node.attribute(STR("attr3")).as_int() == -2147483647 - 1);
- CHECK(node.attribute(STR("attr4")).as_int() == 2147483647);
-}
-
-TEST_XML(dom_attr_as_uint, "<node attr1='0' attr2='1' attr3='2147483647' attr4='4294967295'/>")
-{
- xml_node node = doc.child(STR("node"));
-
- CHECK(xml_attribute().as_uint() == 0);
- CHECK(node.attribute(STR("attr1")).as_uint() == 0);
- CHECK(node.attribute(STR("attr2")).as_uint() == 1);
- CHECK(node.attribute(STR("attr3")).as_uint() == 2147483647);
- CHECK(node.attribute(STR("attr4")).as_uint() == 4294967295u);
-}
-
-TEST_XML(dom_attr_as_float, "<node attr1='0' attr2='1' attr3='0.12' attr4='-5.1' attr5='3e-4' attr6='3.14159265358979323846'/>")
-{
- xml_node node = doc.child(STR("node"));
-
- CHECK(xml_attribute().as_float() == 0);
- CHECK_DOUBLE(node.attribute(STR("attr1")).as_float(), 0);
- CHECK_DOUBLE(node.attribute(STR("attr2")).as_float(), 1);
- CHECK_DOUBLE(node.attribute(STR("attr3")).as_float(), 0.12);
- CHECK_DOUBLE(node.attribute(STR("attr4")).as_float(), -5.1);
- CHECK_DOUBLE(node.attribute(STR("attr5")).as_float(), 3e-4);
- CHECK_DOUBLE(node.attribute(STR("attr6")).as_float(), 3.14159265358979323846);
-}
-
-TEST_XML(dom_attr_as_double, "<node attr1='0' attr2='1' attr3='0.12' attr4='-5.1' attr5='3e-4' attr6='3.14159265358979323846'/>")
-{
- xml_node node = doc.child(STR("node"));
-
- CHECK(xml_attribute().as_double() == 0);
- CHECK_DOUBLE(node.attribute(STR("attr1")).as_double(), 0);
- CHECK_DOUBLE(node.attribute(STR("attr2")).as_double(), 1);
- CHECK_DOUBLE(node.attribute(STR("attr3")).as_double(), 0.12);
- CHECK_DOUBLE(node.attribute(STR("attr4")).as_double(), -5.1);
- CHECK_DOUBLE(node.attribute(STR("attr5")).as_double(), 3e-4);
- CHECK_DOUBLE(node.attribute(STR("attr6")).as_double(), 3.14159265358979323846);
-}
-
-TEST_XML(dom_attr_as_bool, "<node attr1='0' attr2='1' attr3='true' attr4='True' attr5='Yes' attr6='yes' attr7='false'/>")
-{
- xml_node node = doc.child(STR("node"));
-
- CHECK(!xml_attribute().as_bool());
- CHECK(!node.attribute(STR("attr1")).as_bool());
- CHECK(node.attribute(STR("attr2")).as_bool());
- CHECK(node.attribute(STR("attr3")).as_bool());
- CHECK(node.attribute(STR("attr4")).as_bool());
- CHECK(node.attribute(STR("attr5")).as_bool());
- CHECK(node.attribute(STR("attr6")).as_bool());
- CHECK(!node.attribute(STR("attr7")).as_bool());
-}
-
-TEST_XML(dom_attr_iterator, "<node><node1 attr1='0'/><node2 attr1='0' attr2='1'/><node3/></node>")
-{
- xml_node node1 = doc.child(STR("node")).child(STR("node1"));
- xml_node node2 = doc.child(STR("node")).child(STR("node2"));
- xml_node node3 = doc.child(STR("node")).child(STR("node3"));
-
- CHECK(xml_node().attributes_begin() == xml_attribute_iterator());
- CHECK(xml_node().attributes_end() == xml_attribute_iterator());
-
- CHECK(node1.attributes_begin() == xml_attribute_iterator(node1.attribute(STR("attr1")), node1));
- CHECK(move_iter(node1.attributes_begin(), 1) == node1.attributes_end());
- CHECK(move_iter(node1.attributes_end(), -1) == node1.attributes_begin());
- CHECK(*node1.attributes_begin() == node1.attribute(STR("attr1")));
- CHECK_STRING(node1.attributes_begin()->name(), STR("attr1"));
-
- CHECK(move_iter(node2.attributes_begin(), 2) == node2.attributes_end());
- CHECK(move_iter(node2.attributes_end(), -2) == node2.attributes_begin());
-
- CHECK(node3.attributes_begin() != xml_attribute_iterator());
- CHECK(node3.attributes_begin() == node3.attributes_end());
-
- xml_attribute_iterator it = xml_attribute_iterator(node2.attribute(STR("attr2")), node2);
- xml_attribute_iterator itt = it;
-
- CHECK(itt++ == it);
- CHECK(itt == node2.attributes_end());
-
- CHECK(itt-- == node2.attributes_end());
- CHECK(itt == it);
-
- CHECK(++itt == node2.attributes_end());
- CHECK(itt == node2.attributes_end());
-
- CHECK(--itt == it);
- CHECK(itt == it);
-
- CHECK(++itt != it);
-}
-
-TEST_XML(dom_attr_iterator_end, "<node><node1 attr1='0'/><node2 attr1='0' attr2='1'/><node3/></node>")
-{
- xml_node node1 = doc.child(STR("node")).child(STR("node1"));
- xml_node node2 = doc.child(STR("node")).child(STR("node2"));
- xml_node node3 = doc.child(STR("node")).child(STR("node3"));
-
- CHECK(node1.attributes_end() != node2.attributes_end() && node1.attributes_end() != node3.attributes_end() && node2.attributes_end() != node3.attributes_end());
- CHECK(node1.attributes_end() != xml_attribute_iterator() && node2.attributes_end() != xml_attribute_iterator() && node3.attributes_end() != xml_attribute_iterator());
-}
-
-TEST_XML(dom_attr_iterator_invalidate, "<node><node1 attr1='0'/><node2 attr1='0' attr2='1'/><node3/></node>")
-{
- xml_node node2 = doc.child(STR("node")).child(STR("node2"));
-
- xml_attribute_iterator it1 = node2.attributes_begin();
- xml_attribute_iterator it2 = move_iter(it1, 1);
- xml_attribute_iterator it3 = move_iter(it2, 1);
-
- CHECK(it3 == node2.attributes_end());
-
- // removing attr2, it2 is invalid now, it3 is still past-the-end
- node2.remove_attribute(*it2);
-
- CHECK(node2.attributes_end() == it3);
- CHECK(move_iter(it1, 1) == it3);
- CHECK(move_iter(it3, -1) == it1);
- CHECK_STRING(it1->name(), STR("attr1"));
-
- // adding attr2 back, it3 is still past-the-end!
- xml_attribute_iterator it2new = xml_attribute_iterator(node2.append_attribute(STR("attr2-new")), node2);
-
- CHECK(node2.attributes_end() == it3);
- CHECK(move_iter(it1, 1) == it2new);
- CHECK(move_iter(it2new, 1) == it3);
- CHECK(move_iter(it3, -1) == it2new);
- CHECK_STRING(it2new->name(), STR("attr2-new"));
-
- // removing both attributes, it3 is now equal to the begin
- node2.remove_attribute(*it1);
- node2.remove_attribute(*it2new);
- CHECK(!node2.first_attribute());
-
- CHECK(node2.attributes_begin() == it3);
- CHECK(node2.attributes_end() == it3);
-}
-
-TEST_XML(dom_node_bool_ops, "<node/>")
-{
- generic_bool_ops_test(doc.child(STR("node")));
-}
-
-TEST_XML(dom_node_eq_ops, "<node><node1/><node2/></node>")
-{
- generic_eq_ops_test(doc.child(STR("node")).child(STR("node1")), doc.child(STR("node")).child(STR("node2")));
-}
-
-TEST_XML(dom_node_rel_ops, "<node><node1/><node2/></node>")
-{
- generic_rel_ops_test(doc.child(STR("node")).child(STR("node1")), doc.child(STR("node")).child(STR("node2")));
-}
-
-TEST_XML(dom_node_empty, "<node/>")
-{
- generic_empty_test(doc.child(STR("node")));
-}
-
-TEST_XML(dom_node_iterator, "<node><node1><child1/></node1><node2><child1/><child2/></node2><node3/></node>")
-{
- xml_node node1 = doc.child(STR("node")).child(STR("node1"));
- xml_node node2 = doc.child(STR("node")).child(STR("node2"));
- xml_node node3 = doc.child(STR("node")).child(STR("node3"));
-
- CHECK(xml_node().begin() == xml_node_iterator());
- CHECK(xml_node().end() == xml_node_iterator());
-
- CHECK(node1.begin() == xml_node_iterator(node1.child(STR("child1"))));
- CHECK(move_iter(node1.begin(), 1) == node1.end());
- CHECK(move_iter(node1.end(), -1) == node1.begin());
- CHECK(*node1.begin() == node1.child(STR("child1")));
- CHECK_STRING(node1.begin()->name(), STR("child1"));
-
- CHECK(move_iter(node2.begin(), 2) == node2.end());
- CHECK(move_iter(node2.end(), -2) == node2.begin());
-
- CHECK(node3.begin() != xml_node_iterator());
- CHECK(node3.begin() == node3.end());
-
- xml_node_iterator it = node2.child(STR("child2"));
- xml_node_iterator itt = it;
-
- CHECK(itt++ == it);
- CHECK(itt == node2.end());
-
- CHECK(itt-- == node2.end());
- CHECK(itt == it);
-
- CHECK(++itt == node2.end());
- CHECK(itt == node2.end());
-
- CHECK(--itt == it);
- CHECK(itt == it);
-
- CHECK(++itt != it);
-}
-
-TEST_XML(dom_node_iterator_end, "<node><node1><child1/></node1><node2><child1/><child2/></node2><node3/></node>")
-{
- xml_node node1 = doc.child(STR("node")).child(STR("node1"));
- xml_node node2 = doc.child(STR("node")).child(STR("node2"));
- xml_node node3 = doc.child(STR("node")).child(STR("node3"));
-
- CHECK(node1.end() != node2.end() && node1.end() != node3.end() && node2.end() != node3.end());
- CHECK(node1.end() != xml_node_iterator() && node2.end() != xml_node_iterator() && node3.end() != xml_node_iterator());
-}
-
-TEST_XML(dom_node_iterator_invalidate, "<node><node1><child1/></node1><node2><child1/><child2/></node2><node3/></node>")
-{
- xml_node node2 = doc.child(STR("node")).child(STR("node2"));
-
- xml_node_iterator it1 = node2.begin();
- xml_node_iterator it2 = move_iter(it1, 1);
- xml_node_iterator it3 = move_iter(it2, 1);
-
- CHECK(it3 == node2.end());
-
- // removing child2, it2 is invalid now, it3 is still past-the-end
- node2.remove_child(*it2);
-
- CHECK(node2.end() == it3);
- CHECK(move_iter(it1, 1) == it3);
- CHECK(move_iter(it3, -1) == it1);
- CHECK_STRING(it1->name(), STR("child1"));
-
- // adding attr2 back, it3 is still past-the-end!
- xml_node_iterator it2new = node2.append_child();
- it2new->set_name(STR("child2-new"));
-
- CHECK(node2.end() == it3);
- CHECK(move_iter(it1, 1) == it2new);
- CHECK(move_iter(it2new, 1) == it3);
- CHECK(move_iter(it3, -1) == it2new);
- CHECK_STRING(it2new->name(), STR("child2-new"));
-
- // removing both nodes, it3 is now equal to the begin
- node2.remove_child(*it1);
- node2.remove_child(*it2new);
- CHECK(!node2.first_child());
-
- CHECK(node2.begin() == it3);
- CHECK(node2.end() == it3);
-}
-
-TEST_XML(dom_node_parent, "<node><child/></node>")
-{
- CHECK(xml_node().parent() == xml_node());
- CHECK(doc.child(STR("node")).child(STR("child")).parent() == doc.child(STR("node")));
- CHECK(doc.child(STR("node")).parent() == doc);
-}
-
-TEST_XML(dom_node_root, "<node><child/></node>")
-{
- CHECK(xml_node().root() == xml_node());
- CHECK(doc.child(STR("node")).child(STR("child")).root() == doc);
- CHECK(doc.child(STR("node")).root() == doc);
-}
-
-TEST_XML_FLAGS(dom_node_type, "<?xml?><?pi?><!--comment--><node>pcdata<![CDATA[cdata]]></node>", parse_default | parse_pi | parse_comments | parse_declaration)
-{
- CHECK(xml_node().type() == node_null);
- CHECK(doc.type() == node_document);
-
- xml_node_iterator it = doc.begin();
-
- CHECK((it++)->type() == node_declaration);
- CHECK((it++)->type() == node_pi);
- CHECK((it++)->type() == node_comment);
- CHECK((it++)->type() == node_element);
-
- xml_node_iterator cit = doc.child(STR("node")).begin();
-
- CHECK((cit++)->type() == node_pcdata);
- CHECK((cit++)->type() == node_cdata);
-}
-
-TEST_XML_FLAGS(dom_node_name_value, "<?xml?><?pi?><!--comment--><node>pcdata<![CDATA[cdata]]></node>", parse_default | parse_pi | parse_comments | parse_declaration)
-{
- CHECK_NAME_VALUE(xml_node(), STR(""), STR(""));
- CHECK_NAME_VALUE(doc, STR(""), STR(""));
-
- xml_node_iterator it = doc.begin();
-
- CHECK_NAME_VALUE(*it++, STR("xml"), STR(""));
- CHECK_NAME_VALUE(*it++, STR("pi"), STR(""));
- CHECK_NAME_VALUE(*it++, STR(""), STR("comment"));
- CHECK_NAME_VALUE(*it++, STR("node"), STR(""));
-
- xml_node_iterator cit = doc.child(STR("node")).begin();
-
- CHECK_NAME_VALUE(*cit++, STR(""), STR("pcdata"));
- CHECK_NAME_VALUE(*cit++, STR(""), STR("cdata"));
-}
-
-TEST_XML(dom_node_child, "<node><child1/><child2/></node>")
-{
- CHECK(xml_node().child(STR("n")) == xml_node());
-
- CHECK(doc.child(STR("n")) == xml_node());
- CHECK_NAME_VALUE(doc.child(STR("node")), STR("node"), STR(""));
- CHECK(doc.child(STR("node")).child(STR("child2")) == doc.child(STR("node")).last_child());
-}
-
-TEST_XML(dom_node_attribute, "<node attr1='0' attr2='1'/>")
-{
- CHECK(xml_node().attribute(STR("a")) == xml_attribute());
-
- xml_node node = doc.child(STR("node"));
-
- CHECK(node.attribute(STR("n")) == xml_attribute());
- CHECK_NAME_VALUE(node.attribute(STR("attr1")), STR("attr1"), STR("0"));
- CHECK(node.attribute(STR("attr2")) == node.last_attribute());
-}
-
-TEST_XML(dom_node_next_previous_sibling, "<node><child1/><child2/><child3/></node>")
-{
- CHECK(xml_node().next_sibling() == xml_node());
- CHECK(xml_node().next_sibling(STR("n")) == xml_node());
-
- CHECK(xml_node().previous_sibling() == xml_node());
- CHECK(xml_node().previous_sibling(STR("n")) == xml_node());
-
- xml_node child1 = doc.child(STR("node")).child(STR("child1"));
- xml_node child2 = doc.child(STR("node")).child(STR("child2"));
- xml_node child3 = doc.child(STR("node")).child(STR("child3"));
-
- CHECK(child1.next_sibling() == child2);
- CHECK(child3.next_sibling() == xml_node());
-
- CHECK(child1.previous_sibling() == xml_node());
- CHECK(child3.previous_sibling() == child2);
-
- CHECK(child1.next_sibling(STR("child3")) == child3);
- CHECK(child1.next_sibling(STR("child")) == xml_node());
-
- CHECK(child3.previous_sibling(STR("child1")) == child1);
- CHECK(child3.previous_sibling(STR("child")) == xml_node());
-}
-
-TEST_XML(dom_node_child_value, "<node><novalue/><child1>value1</child1><child2>value2<n/></child2><child3><![CDATA[value3]]></child3>value4</node>")
-{
- CHECK_STRING(xml_node().child_value(), STR(""));
- CHECK_STRING(xml_node().child_value(STR("n")), STR(""));
-
- xml_node node = doc.child(STR("node"));
-
- CHECK_STRING(node.child_value(), STR("value4"));
- CHECK_STRING(node.child(STR("child1")).child_value(), STR("value1"));
- CHECK_STRING(node.child(STR("child2")).child_value(), STR("value2"));
- CHECK_STRING(node.child(STR("child3")).child_value(), STR("value3"));
- CHECK_STRING(node.child_value(STR("child3")), STR("value3"));
-}
-
-TEST_XML(dom_node_first_last_attribute, "<node attr1='0' attr2='1'/>")
-{
- xml_node node = doc.child(STR("node"));
-
- CHECK(node.first_attribute() == node.attribute(STR("attr1")));
- CHECK(node.last_attribute() == node.attribute(STR("attr2")));
-
- CHECK(xml_node().first_attribute() == xml_attribute());
- CHECK(xml_node().last_attribute() == xml_attribute());
-
- CHECK(doc.first_attribute() == xml_attribute());
- CHECK(doc.last_attribute() == xml_attribute());
-}
-
-TEST_XML(dom_node_first_last_child, "<node><child1/><child2/></node>")
-{
- xml_node node = doc.child(STR("node"));
-
- CHECK(node.first_child() == node.child(STR("child1")));
- CHECK(node.last_child() == node.child(STR("child2")));
-
- CHECK(xml_node().first_child() == xml_node());
- CHECK(xml_node().last_child() == xml_node());
-
- CHECK(doc.first_child() == node);
- CHECK(doc.last_child() == node);
-}
-
-TEST_XML(dom_node_find_child_by_attribute, "<node><child1 attr='value1'/><child2 attr='value2'/><child2 attr='value3'/></node>")
-{
- CHECK(xml_node().find_child_by_attribute(STR("name"), STR("attr"), STR("value")) == xml_node());
- CHECK(xml_node().find_child_by_attribute(STR("attr"), STR("value")) == xml_node());
-
- xml_node node = doc.child(STR("node"));
-
- CHECK(node.find_child_by_attribute(STR("child2"), STR("attr"), STR("value3")) == node.last_child());
- CHECK(node.find_child_by_attribute(STR("child2"), STR("attr3"), STR("value3")) == xml_node());
- CHECK(node.find_child_by_attribute(STR("attr"), STR("value2")) == node.child(STR("child2")));
- CHECK(node.find_child_by_attribute(STR("attr3"), STR("value")) == xml_node());
-}
-
-struct find_predicate_const
-{
- bool result;
-
- find_predicate_const(bool result): result(result)
- {
- }
-
- template <typename T> bool operator()(const T&) const
- {
- return result;
- }
-};
-
-struct find_predicate_prefix
-{
- const pugi::char_t* prefix;
-
- find_predicate_prefix(const pugi::char_t* prefix): prefix(prefix)
- {
- }
-
- template <typename T> bool operator()(const T& obj) const
- {
- #ifdef PUGIXML_WCHAR_MODE
- // can't use wcsncmp here because of a bug in DMC
- return std::basic_string<pugi::char_t>(obj.name()).compare(0, wcslen(prefix), prefix) == 0;
- #else
- return strncmp(obj.name(), prefix, strlen(prefix)) == 0;
- #endif
- }
-};
-
-TEST_XML(dom_node_find_attribute, "<node attr1='0' attr2='1'/>")
-{
- CHECK(xml_node().find_attribute(find_predicate_const(true)) == xml_attribute());
-
- xml_node node = doc.child(STR("node"));
-
- CHECK(doc.find_attribute(find_predicate_const(true)) == xml_attribute());
- CHECK(node.find_attribute(find_predicate_const(true)) == node.first_attribute());
- CHECK(node.find_attribute(find_predicate_const(false)) == xml_attribute());
- CHECK(node.find_attribute(find_predicate_prefix(STR("attr2"))) == node.last_attribute());
- CHECK(node.find_attribute(find_predicate_prefix(STR("attr"))) == node.first_attribute());
-}
-
-TEST_XML(dom_node_find_child, "<node><child1/><child2/></node>")
-{
- CHECK(xml_node().find_child(find_predicate_const(true)) == xml_node());
-
- xml_node node = doc.child(STR("node"));
-
- CHECK(node.child(STR("node")).child(STR("child1")).find_child(find_predicate_const(true)) == xml_node());
- CHECK(node.find_child(find_predicate_const(true)) == node.first_child());
- CHECK(node.find_child(find_predicate_const(false)) == xml_node());
- CHECK(node.find_child(find_predicate_prefix(STR("child2"))) == node.last_child());
- CHECK(node.find_child(find_predicate_prefix(STR("child"))) == node.first_child());
-}
-
-TEST_XML(dom_node_find_node, "<node><child1/><child2/></node>")
-{
- CHECK(xml_node().find_node(find_predicate_const(true)) == xml_node());
-
- xml_node node = doc.child(STR("node"));
-
- CHECK(node.child(STR("node")).child(STR("child1")).find_node(find_predicate_const(true)) == xml_node());
- CHECK(node.find_node(find_predicate_const(true)) == node.first_child());
- CHECK(node.find_node(find_predicate_const(false)) == xml_node());
- CHECK(node.find_node(find_predicate_prefix(STR("child2"))) == node.last_child());
- CHECK(node.find_node(find_predicate_prefix(STR("child"))) == node.first_child());
- CHECK(doc.find_node(find_predicate_prefix(STR("child"))) == node.first_child());
- CHECK(doc.find_node(find_predicate_prefix(STR("child2"))) == node.last_child());
- CHECK(doc.find_node(find_predicate_prefix(STR("child3"))) == xml_node());
-}
-
-#ifndef PUGIXML_NO_STL
-TEST_XML(dom_node_path, "<node><child1>text<child2/></child1></node>")
-{
- CHECK(xml_node().path() == STR(""));
-
- CHECK(doc.path() == STR(""));
- CHECK(doc.child(STR("node")).path() == STR("/node"));
- CHECK(doc.child(STR("node")).child(STR("child1")).path() == STR("/node/child1"));
- CHECK(doc.child(STR("node")).child(STR("child1")).child(STR("child2")).path() == STR("/node/child1/child2"));
- CHECK(doc.child(STR("node")).child(STR("child1")).first_child().path() == STR("/node/child1/"));
-
- CHECK(doc.child(STR("node")).child(STR("child1")).path('\\') == STR("\\node\\child1"));
-}
-#endif
-
-TEST_XML(dom_node_first_element_by_path, "<node><child1>text<child2/></child1></node>")
-{
- CHECK(xml_node().first_element_by_path(STR("/")) == xml_node());
-
- CHECK(doc.first_element_by_path(STR("")) == doc);
- CHECK(doc.first_element_by_path(STR("/")) == doc);
-
- CHECK(doc.first_element_by_path(STR("/node/")) == doc.child(STR("node")));
- CHECK(doc.first_element_by_path(STR("node/")) == doc.child(STR("node")));
- CHECK(doc.first_element_by_path(STR("node")) == doc.child(STR("node")));
- CHECK(doc.first_element_by_path(STR("/node")) == doc.child(STR("node")));
-
-#ifndef PUGIXML_NO_STL
- CHECK(doc.first_element_by_path(STR("/node/child1/child2")).path() == STR("/node/child1/child2"));
-#endif
-
- CHECK(doc.first_element_by_path(STR("/node/child2")) == xml_node());
-
- CHECK(doc.first_element_by_path(STR("\\node\\child1"), '\\') == doc.child(STR("node")).child(STR("child1")));
-
- CHECK(doc.child(STR("node")).first_element_by_path(STR("..")) == doc);
- CHECK(doc.child(STR("node")).first_element_by_path(STR(".")) == doc.child(STR("node")));
-
- CHECK(doc.child(STR("node")).first_element_by_path(STR("../node/./child1/../.")) == doc.child(STR("node")));
-
- CHECK(doc.child(STR("node")).first_element_by_path(STR("child1")) == doc.child(STR("node")).child(STR("child1")));
- CHECK(doc.child(STR("node")).first_element_by_path(STR("child1/")) == doc.child(STR("node")).child(STR("child1")));
- CHECK(doc.child(STR("node")).first_element_by_path(STR("child")) == xml_node());
- CHECK(doc.child(STR("node")).first_element_by_path(STR("child11")) == xml_node());
-}
-
-struct test_walker: xml_tree_walker
-{
- std::basic_string<pugi::char_t> log;
- unsigned int call_count;
- unsigned int stop_count;
-
- test_walker(unsigned int stop_count = 0): call_count(0), stop_count(stop_count)
- {
- }
-
- std::basic_string<pugi::char_t> depthstr() const
- {
- char buf[32];
- sprintf(buf, "%d", depth());
-
- #ifdef PUGIXML_WCHAR_MODE
- wchar_t wbuf[32];
- std::copy(buf, buf + strlen(buf) + 1, &wbuf[0]);
-
- return std::basic_string<pugi::char_t>(wbuf);
- #else
- return std::basic_string<pugi::char_t>(buf);
- #endif
- }
-
- virtual bool begin(xml_node& node)
- {
- log += STR("|");
- log += depthstr();
- log += STR(" <");
- log += node.name();
- log += STR("=");
- log += node.value();
-
- return ++call_count != stop_count && xml_tree_walker::begin(node);
- }
-
- virtual bool for_each(xml_node& node)
- {
- log += STR("|");
- log += depthstr();
- log += STR(" !");
- log += node.name();
- log += STR("=");
- log += node.value();
-
- return ++call_count != stop_count && xml_tree_walker::end(node);
- }
-
- virtual bool end(xml_node& node)
- {
- log += STR("|");
- log += depthstr();
- log += STR(" >");
- log += node.name();
- log += STR("=");
- log += node.value();
-
- return ++call_count != stop_count;
- }
-};
-
-TEST_XML(dom_node_traverse, "<node><child>text</child></node>")
-{
- test_walker walker;
-
- CHECK(doc.traverse(walker));
-
- CHECK(walker.call_count == 5);
- CHECK(walker.log == STR("|-1 <=|0 !node=|1 !child=|2 !=text|-1 >="));
-}
-
-TEST_XML(dom_node_traverse_siblings, "<node><child/><child>text</child><child/></node>")
-{
- test_walker walker;
-
- CHECK(doc.traverse(walker));
-
- CHECK(walker.call_count == 7);
- CHECK(walker.log == STR("|-1 <=|0 !node=|1 !child=|1 !child=|2 !=text|1 !child=|-1 >="));
-}
-
-TEST(dom_node_traverse_empty)
-{
- test_walker walker;
-
- CHECK(xml_node().traverse(walker));
-
- CHECK(walker.call_count == 2);
- CHECK(walker.log == STR("|-1 <=|-1 >="));
-}
-
-TEST_XML(dom_node_traverse_child, "<node><child>text</child></node>")
-{
- test_walker walker;
-
- CHECK(doc.child(STR("node")).traverse(walker));
-
- CHECK(walker.call_count == 4);
- CHECK(walker.log == STR("|-1 <node=|0 !child=|1 !=text|-1 >node="));
-}
-
-TEST_XML(dom_node_traverse_stop_begin, "<node><child>text</child></node>")
-{
- test_walker walker(1);
-
- CHECK(!doc.traverse(walker));
-
- CHECK(walker.call_count == 1);
- CHECK(walker.log == STR("|-1 <="));
-}
-
-TEST_XML(dom_node_traverse_stop_for_each, "<node><child>text</child></node>")
-{
- test_walker walker(3);
-
- CHECK(!doc.traverse(walker));
-
- CHECK(walker.call_count == 3);
- CHECK(walker.log == STR("|-1 <=|0 !node=|1 !child="));
-}
-
-TEST_XML(dom_node_traverse_stop_end, "<node><child>text</child></node>")
-{
- test_walker walker(5);
-
- CHECK(!doc.traverse(walker));
-
- CHECK(walker.call_count == 5);
- CHECK(walker.log == STR("|-1 <=|0 !node=|1 !child=|2 !=text|-1 >="));
-}
-
-TEST_XML_FLAGS(dom_offset_debug, "<?xml?><?pi?><!--comment--><node>pcdata<![CDATA[cdata]]></node>", parse_default | parse_pi | parse_comments | parse_declaration)
-{
- CHECK(xml_node().offset_debug() == -1);
- CHECK(doc.offset_debug() == 0);
-
- xml_node_iterator it = doc.begin();
-
- CHECK((it++)->offset_debug() == 2);
- CHECK((it++)->offset_debug() == 9);
- CHECK((it++)->offset_debug() == 17);
- CHECK((it++)->offset_debug() == 28);
-
- xml_node_iterator cit = doc.child(STR("node")).begin();
-
- CHECK((cit++)->offset_debug() == 33);
- CHECK((cit++)->offset_debug() == 48);
-}
+#define _CRT_SECURE_NO_WARNINGS +#define _SCL_SECURE_NO_WARNINGS + +#include "common.hpp" + +#include <stdio.h> + +#include <string.h> +#include <wchar.h> + +#include <utility> +#include <vector> +#include <iterator> +#include <string> + +#include "helpers.hpp" + +#ifdef PUGIXML_NO_STL +template <typename I> static I move_iter(I base, int n) +{ + if (n > 0) while (n--) ++base; + else while (n++) --base; + return base; +} +#else +template <typename I> static I move_iter(I base, int n) +{ + std::advance(base, n); + return base; +} +#endif + +template <typename T> static void generic_empty_test(const T& obj) +{ + T null; + + CHECK(null.empty()); + CHECK(!obj.empty()); +} + +TEST_XML(dom_attr_bool_ops, "<node attr='1'/>") +{ + generic_bool_ops_test(doc.child(STR("node")).attribute(STR("attr"))); +} + +TEST_XML(dom_attr_eq_ops, "<node attr1='1' attr2='2'/>") +{ + generic_eq_ops_test(doc.child(STR("node")).attribute(STR("attr1")), doc.child(STR("node")).attribute(STR("attr2"))); +} + +TEST_XML(dom_attr_rel_ops, "<node attr1='1' attr2='2'/>") +{ + generic_rel_ops_test(doc.child(STR("node")).attribute(STR("attr1")), doc.child(STR("node")).attribute(STR("attr2"))); +} + +TEST_XML(dom_attr_empty, "<node attr='1'/>") +{ + generic_empty_test(doc.child(STR("node")).attribute(STR("attr"))); +} + +TEST_XML(dom_attr_next_previous_attribute, "<node attr1='1' attr2='2' />") +{ + xml_attribute attr1 = doc.child(STR("node")).attribute(STR("attr1")); + xml_attribute attr2 = doc.child(STR("node")).attribute(STR("attr2")); + + CHECK(attr1.next_attribute() == attr2); + CHECK(attr2.next_attribute() == xml_attribute()); + + CHECK(attr1.previous_attribute() == xml_attribute()); + CHECK(attr2.previous_attribute() == attr1); + + CHECK(xml_attribute().next_attribute() == xml_attribute()); + CHECK(xml_attribute().previous_attribute() == xml_attribute()); +} + +TEST_XML(dom_attr_name_value, "<node attr='1'/>") +{ + xml_attribute attr = doc.child(STR("node")).attribute(STR("attr")); + + CHECK_NAME_VALUE(attr, STR("attr"), STR("1")); + CHECK_NAME_VALUE(xml_attribute(), STR(""), STR("")); +} + +TEST_XML(dom_attr_as_int, "<node attr1='1' attr2='-1' attr3='-2147483648' attr4='2147483647'/>") +{ + xml_node node = doc.child(STR("node")); + + CHECK(xml_attribute().as_int() == 0); + CHECK(node.attribute(STR("attr1")).as_int() == 1); + CHECK(node.attribute(STR("attr2")).as_int() == -1); + CHECK(node.attribute(STR("attr3")).as_int() == -2147483647 - 1); + CHECK(node.attribute(STR("attr4")).as_int() == 2147483647); +} + +TEST_XML(dom_attr_as_uint, "<node attr1='0' attr2='1' attr3='2147483647' attr4='4294967295'/>") +{ + xml_node node = doc.child(STR("node")); + + CHECK(xml_attribute().as_uint() == 0); + CHECK(node.attribute(STR("attr1")).as_uint() == 0); + CHECK(node.attribute(STR("attr2")).as_uint() == 1); + CHECK(node.attribute(STR("attr3")).as_uint() == 2147483647); + CHECK(node.attribute(STR("attr4")).as_uint() == 4294967295u); +} + +TEST_XML(dom_attr_as_float, "<node attr1='0' attr2='1' attr3='0.12' attr4='-5.1' attr5='3e-4' attr6='3.14159265358979323846'/>") +{ + xml_node node = doc.child(STR("node")); + + CHECK(xml_attribute().as_float() == 0); + CHECK_DOUBLE(node.attribute(STR("attr1")).as_float(), 0); + CHECK_DOUBLE(node.attribute(STR("attr2")).as_float(), 1); + CHECK_DOUBLE(node.attribute(STR("attr3")).as_float(), 0.12); + CHECK_DOUBLE(node.attribute(STR("attr4")).as_float(), -5.1); + CHECK_DOUBLE(node.attribute(STR("attr5")).as_float(), 3e-4); + CHECK_DOUBLE(node.attribute(STR("attr6")).as_float(), 3.14159265358979323846); +} + +TEST_XML(dom_attr_as_double, "<node attr1='0' attr2='1' attr3='0.12' attr4='-5.1' attr5='3e-4' attr6='3.14159265358979323846'/>") +{ + xml_node node = doc.child(STR("node")); + + CHECK(xml_attribute().as_double() == 0); + CHECK_DOUBLE(node.attribute(STR("attr1")).as_double(), 0); + CHECK_DOUBLE(node.attribute(STR("attr2")).as_double(), 1); + CHECK_DOUBLE(node.attribute(STR("attr3")).as_double(), 0.12); + CHECK_DOUBLE(node.attribute(STR("attr4")).as_double(), -5.1); + CHECK_DOUBLE(node.attribute(STR("attr5")).as_double(), 3e-4); + CHECK_DOUBLE(node.attribute(STR("attr6")).as_double(), 3.14159265358979323846); +} + +TEST_XML(dom_attr_as_bool, "<node attr1='0' attr2='1' attr3='true' attr4='True' attr5='Yes' attr6='yes' attr7='false'/>") +{ + xml_node node = doc.child(STR("node")); + + CHECK(!xml_attribute().as_bool()); + CHECK(!node.attribute(STR("attr1")).as_bool()); + CHECK(node.attribute(STR("attr2")).as_bool()); + CHECK(node.attribute(STR("attr3")).as_bool()); + CHECK(node.attribute(STR("attr4")).as_bool()); + CHECK(node.attribute(STR("attr5")).as_bool()); + CHECK(node.attribute(STR("attr6")).as_bool()); + CHECK(!node.attribute(STR("attr7")).as_bool()); +} + +TEST_XML(dom_attr_iterator, "<node><node1 attr1='0'/><node2 attr1='0' attr2='1'/><node3/></node>") +{ + xml_node node1 = doc.child(STR("node")).child(STR("node1")); + xml_node node2 = doc.child(STR("node")).child(STR("node2")); + xml_node node3 = doc.child(STR("node")).child(STR("node3")); + + CHECK(xml_node().attributes_begin() == xml_attribute_iterator()); + CHECK(xml_node().attributes_end() == xml_attribute_iterator()); + + CHECK(node1.attributes_begin() == xml_attribute_iterator(node1.attribute(STR("attr1")), node1)); + CHECK(move_iter(node1.attributes_begin(), 1) == node1.attributes_end()); + CHECK(move_iter(node1.attributes_end(), -1) == node1.attributes_begin()); + CHECK(*node1.attributes_begin() == node1.attribute(STR("attr1"))); + CHECK_STRING(node1.attributes_begin()->name(), STR("attr1")); + + CHECK(move_iter(node2.attributes_begin(), 2) == node2.attributes_end()); + CHECK(move_iter(node2.attributes_end(), -2) == node2.attributes_begin()); + + CHECK(node3.attributes_begin() != xml_attribute_iterator()); + CHECK(node3.attributes_begin() == node3.attributes_end()); + + xml_attribute_iterator it = xml_attribute_iterator(node2.attribute(STR("attr2")), node2); + xml_attribute_iterator itt = it; + + CHECK(itt++ == it); + CHECK(itt == node2.attributes_end()); + + CHECK(itt-- == node2.attributes_end()); + CHECK(itt == it); + + CHECK(++itt == node2.attributes_end()); + CHECK(itt == node2.attributes_end()); + + CHECK(--itt == it); + CHECK(itt == it); + + CHECK(++itt != it); +} + +TEST_XML(dom_attr_iterator_end, "<node><node1 attr1='0'/><node2 attr1='0' attr2='1'/><node3/></node>") +{ + xml_node node1 = doc.child(STR("node")).child(STR("node1")); + xml_node node2 = doc.child(STR("node")).child(STR("node2")); + xml_node node3 = doc.child(STR("node")).child(STR("node3")); + + CHECK(node1.attributes_end() != node2.attributes_end() && node1.attributes_end() != node3.attributes_end() && node2.attributes_end() != node3.attributes_end()); + CHECK(node1.attributes_end() != xml_attribute_iterator() && node2.attributes_end() != xml_attribute_iterator() && node3.attributes_end() != xml_attribute_iterator()); +} + +TEST_XML(dom_attr_iterator_invalidate, "<node><node1 attr1='0'/><node2 attr1='0' attr2='1'/><node3/></node>") +{ + xml_node node2 = doc.child(STR("node")).child(STR("node2")); + + xml_attribute_iterator it1 = node2.attributes_begin(); + xml_attribute_iterator it2 = move_iter(it1, 1); + xml_attribute_iterator it3 = move_iter(it2, 1); + + CHECK(it3 == node2.attributes_end()); + + // removing attr2, it2 is invalid now, it3 is still past-the-end + node2.remove_attribute(*it2); + + CHECK(node2.attributes_end() == it3); + CHECK(move_iter(it1, 1) == it3); + CHECK(move_iter(it3, -1) == it1); + CHECK_STRING(it1->name(), STR("attr1")); + + // adding attr2 back, it3 is still past-the-end! + xml_attribute_iterator it2new = xml_attribute_iterator(node2.append_attribute(STR("attr2-new")), node2); + + CHECK(node2.attributes_end() == it3); + CHECK(move_iter(it1, 1) == it2new); + CHECK(move_iter(it2new, 1) == it3); + CHECK(move_iter(it3, -1) == it2new); + CHECK_STRING(it2new->name(), STR("attr2-new")); + + // removing both attributes, it3 is now equal to the begin + node2.remove_attribute(*it1); + node2.remove_attribute(*it2new); + CHECK(!node2.first_attribute()); + + CHECK(node2.attributes_begin() == it3); + CHECK(node2.attributes_end() == it3); +} + +TEST_XML(dom_node_bool_ops, "<node/>") +{ + generic_bool_ops_test(doc.child(STR("node"))); +} + +TEST_XML(dom_node_eq_ops, "<node><node1/><node2/></node>") +{ + generic_eq_ops_test(doc.child(STR("node")).child(STR("node1")), doc.child(STR("node")).child(STR("node2"))); +} + +TEST_XML(dom_node_rel_ops, "<node><node1/><node2/></node>") +{ + generic_rel_ops_test(doc.child(STR("node")).child(STR("node1")), doc.child(STR("node")).child(STR("node2"))); +} + +TEST_XML(dom_node_empty, "<node/>") +{ + generic_empty_test(doc.child(STR("node"))); +} + +TEST_XML(dom_node_iterator, "<node><node1><child1/></node1><node2><child1/><child2/></node2><node3/></node>") +{ + xml_node node1 = doc.child(STR("node")).child(STR("node1")); + xml_node node2 = doc.child(STR("node")).child(STR("node2")); + xml_node node3 = doc.child(STR("node")).child(STR("node3")); + + CHECK(xml_node().begin() == xml_node_iterator()); + CHECK(xml_node().end() == xml_node_iterator()); + + CHECK(node1.begin() == xml_node_iterator(node1.child(STR("child1")))); + CHECK(move_iter(node1.begin(), 1) == node1.end()); + CHECK(move_iter(node1.end(), -1) == node1.begin()); + CHECK(*node1.begin() == node1.child(STR("child1"))); + CHECK_STRING(node1.begin()->name(), STR("child1")); + + CHECK(move_iter(node2.begin(), 2) == node2.end()); + CHECK(move_iter(node2.end(), -2) == node2.begin()); + + CHECK(node3.begin() != xml_node_iterator()); + CHECK(node3.begin() == node3.end()); + + xml_node_iterator it = node2.child(STR("child2")); + xml_node_iterator itt = it; + + CHECK(itt++ == it); + CHECK(itt == node2.end()); + + CHECK(itt-- == node2.end()); + CHECK(itt == it); + + CHECK(++itt == node2.end()); + CHECK(itt == node2.end()); + + CHECK(--itt == it); + CHECK(itt == it); + + CHECK(++itt != it); +} + +TEST_XML(dom_node_iterator_end, "<node><node1><child1/></node1><node2><child1/><child2/></node2><node3/></node>") +{ + xml_node node1 = doc.child(STR("node")).child(STR("node1")); + xml_node node2 = doc.child(STR("node")).child(STR("node2")); + xml_node node3 = doc.child(STR("node")).child(STR("node3")); + + CHECK(node1.end() != node2.end() && node1.end() != node3.end() && node2.end() != node3.end()); + CHECK(node1.end() != xml_node_iterator() && node2.end() != xml_node_iterator() && node3.end() != xml_node_iterator()); +} + +TEST_XML(dom_node_iterator_invalidate, "<node><node1><child1/></node1><node2><child1/><child2/></node2><node3/></node>") +{ + xml_node node2 = doc.child(STR("node")).child(STR("node2")); + + xml_node_iterator it1 = node2.begin(); + xml_node_iterator it2 = move_iter(it1, 1); + xml_node_iterator it3 = move_iter(it2, 1); + + CHECK(it3 == node2.end()); + + // removing child2, it2 is invalid now, it3 is still past-the-end + node2.remove_child(*it2); + + CHECK(node2.end() == it3); + CHECK(move_iter(it1, 1) == it3); + CHECK(move_iter(it3, -1) == it1); + CHECK_STRING(it1->name(), STR("child1")); + + // adding attr2 back, it3 is still past-the-end! + xml_node_iterator it2new = node2.append_child(); + it2new->set_name(STR("child2-new")); + + CHECK(node2.end() == it3); + CHECK(move_iter(it1, 1) == it2new); + CHECK(move_iter(it2new, 1) == it3); + CHECK(move_iter(it3, -1) == it2new); + CHECK_STRING(it2new->name(), STR("child2-new")); + + // removing both nodes, it3 is now equal to the begin + node2.remove_child(*it1); + node2.remove_child(*it2new); + CHECK(!node2.first_child()); + + CHECK(node2.begin() == it3); + CHECK(node2.end() == it3); +} + +TEST_XML(dom_node_parent, "<node><child/></node>") +{ + CHECK(xml_node().parent() == xml_node()); + CHECK(doc.child(STR("node")).child(STR("child")).parent() == doc.child(STR("node"))); + CHECK(doc.child(STR("node")).parent() == doc); +} + +TEST_XML(dom_node_root, "<node><child/></node>") +{ + CHECK(xml_node().root() == xml_node()); + CHECK(doc.child(STR("node")).child(STR("child")).root() == doc); + CHECK(doc.child(STR("node")).root() == doc); +} + +TEST_XML_FLAGS(dom_node_type, "<?xml?><?pi?><!--comment--><node>pcdata<![CDATA[cdata]]></node>", parse_default | parse_pi | parse_comments | parse_declaration) +{ + CHECK(xml_node().type() == node_null); + CHECK(doc.type() == node_document); + + xml_node_iterator it = doc.begin(); + + CHECK((it++)->type() == node_declaration); + CHECK((it++)->type() == node_pi); + CHECK((it++)->type() == node_comment); + CHECK((it++)->type() == node_element); + + xml_node_iterator cit = doc.child(STR("node")).begin(); + + CHECK((cit++)->type() == node_pcdata); + CHECK((cit++)->type() == node_cdata); +} + +TEST_XML_FLAGS(dom_node_name_value, "<?xml?><?pi?><!--comment--><node>pcdata<![CDATA[cdata]]></node>", parse_default | parse_pi | parse_comments | parse_declaration) +{ + CHECK_NAME_VALUE(xml_node(), STR(""), STR("")); + CHECK_NAME_VALUE(doc, STR(""), STR("")); + + xml_node_iterator it = doc.begin(); + + CHECK_NAME_VALUE(*it++, STR("xml"), STR("")); + CHECK_NAME_VALUE(*it++, STR("pi"), STR("")); + CHECK_NAME_VALUE(*it++, STR(""), STR("comment")); + CHECK_NAME_VALUE(*it++, STR("node"), STR("")); + + xml_node_iterator cit = doc.child(STR("node")).begin(); + + CHECK_NAME_VALUE(*cit++, STR(""), STR("pcdata")); + CHECK_NAME_VALUE(*cit++, STR(""), STR("cdata")); +} + +TEST_XML(dom_node_child, "<node><child1/><child2/></node>") +{ + CHECK(xml_node().child(STR("n")) == xml_node()); + + CHECK(doc.child(STR("n")) == xml_node()); + CHECK_NAME_VALUE(doc.child(STR("node")), STR("node"), STR("")); + CHECK(doc.child(STR("node")).child(STR("child2")) == doc.child(STR("node")).last_child()); +} + +TEST_XML(dom_node_attribute, "<node attr1='0' attr2='1'/>") +{ + CHECK(xml_node().attribute(STR("a")) == xml_attribute()); + + xml_node node = doc.child(STR("node")); + + CHECK(node.attribute(STR("n")) == xml_attribute()); + CHECK_NAME_VALUE(node.attribute(STR("attr1")), STR("attr1"), STR("0")); + CHECK(node.attribute(STR("attr2")) == node.last_attribute()); +} + +TEST_XML(dom_node_next_previous_sibling, "<node><child1/><child2/><child3/></node>") +{ + CHECK(xml_node().next_sibling() == xml_node()); + CHECK(xml_node().next_sibling(STR("n")) == xml_node()); + + CHECK(xml_node().previous_sibling() == xml_node()); + CHECK(xml_node().previous_sibling(STR("n")) == xml_node()); + + xml_node child1 = doc.child(STR("node")).child(STR("child1")); + xml_node child2 = doc.child(STR("node")).child(STR("child2")); + xml_node child3 = doc.child(STR("node")).child(STR("child3")); + + CHECK(child1.next_sibling() == child2); + CHECK(child3.next_sibling() == xml_node()); + + CHECK(child1.previous_sibling() == xml_node()); + CHECK(child3.previous_sibling() == child2); + + CHECK(child1.next_sibling(STR("child3")) == child3); + CHECK(child1.next_sibling(STR("child")) == xml_node()); + + CHECK(child3.previous_sibling(STR("child1")) == child1); + CHECK(child3.previous_sibling(STR("child")) == xml_node()); +} + +TEST_XML(dom_node_child_value, "<node><novalue/><child1>value1</child1><child2>value2<n/></child2><child3><![CDATA[value3]]></child3>value4</node>") +{ + CHECK_STRING(xml_node().child_value(), STR("")); + CHECK_STRING(xml_node().child_value(STR("n")), STR("")); + + xml_node node = doc.child(STR("node")); + + CHECK_STRING(node.child_value(), STR("value4")); + CHECK_STRING(node.child(STR("child1")).child_value(), STR("value1")); + CHECK_STRING(node.child(STR("child2")).child_value(), STR("value2")); + CHECK_STRING(node.child(STR("child3")).child_value(), STR("value3")); + CHECK_STRING(node.child_value(STR("child3")), STR("value3")); +} + +TEST_XML(dom_node_first_last_attribute, "<node attr1='0' attr2='1'/>") +{ + xml_node node = doc.child(STR("node")); + + CHECK(node.first_attribute() == node.attribute(STR("attr1"))); + CHECK(node.last_attribute() == node.attribute(STR("attr2"))); + + CHECK(xml_node().first_attribute() == xml_attribute()); + CHECK(xml_node().last_attribute() == xml_attribute()); + + CHECK(doc.first_attribute() == xml_attribute()); + CHECK(doc.last_attribute() == xml_attribute()); +} + +TEST_XML(dom_node_first_last_child, "<node><child1/><child2/></node>") +{ + xml_node node = doc.child(STR("node")); + + CHECK(node.first_child() == node.child(STR("child1"))); + CHECK(node.last_child() == node.child(STR("child2"))); + + CHECK(xml_node().first_child() == xml_node()); + CHECK(xml_node().last_child() == xml_node()); + + CHECK(doc.first_child() == node); + CHECK(doc.last_child() == node); +} + +TEST_XML(dom_node_find_child_by_attribute, "<node><child1 attr='value1'/><child2 attr='value2'/><child2 attr='value3'/></node>") +{ + CHECK(xml_node().find_child_by_attribute(STR("name"), STR("attr"), STR("value")) == xml_node()); + CHECK(xml_node().find_child_by_attribute(STR("attr"), STR("value")) == xml_node()); + + xml_node node = doc.child(STR("node")); + + CHECK(node.find_child_by_attribute(STR("child2"), STR("attr"), STR("value3")) == node.last_child()); + CHECK(node.find_child_by_attribute(STR("child2"), STR("attr3"), STR("value3")) == xml_node()); + CHECK(node.find_child_by_attribute(STR("attr"), STR("value2")) == node.child(STR("child2"))); + CHECK(node.find_child_by_attribute(STR("attr3"), STR("value")) == xml_node()); +} + +struct find_predicate_const +{ + bool result; + + find_predicate_const(bool result): result(result) + { + } + + template <typename T> bool operator()(const T&) const + { + return result; + } +}; + +struct find_predicate_prefix +{ + const pugi::char_t* prefix; + + find_predicate_prefix(const pugi::char_t* prefix): prefix(prefix) + { + } + + template <typename T> bool operator()(const T& obj) const + { + #ifdef PUGIXML_WCHAR_MODE + // can't use wcsncmp here because of a bug in DMC + return std::basic_string<pugi::char_t>(obj.name()).compare(0, wcslen(prefix), prefix) == 0; + #else + return strncmp(obj.name(), prefix, strlen(prefix)) == 0; + #endif + } +}; + +TEST_XML(dom_node_find_attribute, "<node attr1='0' attr2='1'/>") +{ + CHECK(xml_node().find_attribute(find_predicate_const(true)) == xml_attribute()); + + xml_node node = doc.child(STR("node")); + + CHECK(doc.find_attribute(find_predicate_const(true)) == xml_attribute()); + CHECK(node.find_attribute(find_predicate_const(true)) == node.first_attribute()); + CHECK(node.find_attribute(find_predicate_const(false)) == xml_attribute()); + CHECK(node.find_attribute(find_predicate_prefix(STR("attr2"))) == node.last_attribute()); + CHECK(node.find_attribute(find_predicate_prefix(STR("attr"))) == node.first_attribute()); +} + +TEST_XML(dom_node_find_child, "<node><child1/><child2/></node>") +{ + CHECK(xml_node().find_child(find_predicate_const(true)) == xml_node()); + + xml_node node = doc.child(STR("node")); + + CHECK(node.child(STR("node")).child(STR("child1")).find_child(find_predicate_const(true)) == xml_node()); + CHECK(node.find_child(find_predicate_const(true)) == node.first_child()); + CHECK(node.find_child(find_predicate_const(false)) == xml_node()); + CHECK(node.find_child(find_predicate_prefix(STR("child2"))) == node.last_child()); + CHECK(node.find_child(find_predicate_prefix(STR("child"))) == node.first_child()); +} + +TEST_XML(dom_node_find_node, "<node><child1/><child2/></node>") +{ + CHECK(xml_node().find_node(find_predicate_const(true)) == xml_node()); + + xml_node node = doc.child(STR("node")); + + CHECK(node.child(STR("node")).child(STR("child1")).find_node(find_predicate_const(true)) == xml_node()); + CHECK(node.find_node(find_predicate_const(true)) == node.first_child()); + CHECK(node.find_node(find_predicate_const(false)) == xml_node()); + CHECK(node.find_node(find_predicate_prefix(STR("child2"))) == node.last_child()); + CHECK(node.find_node(find_predicate_prefix(STR("child"))) == node.first_child()); + CHECK(doc.find_node(find_predicate_prefix(STR("child"))) == node.first_child()); + CHECK(doc.find_node(find_predicate_prefix(STR("child2"))) == node.last_child()); + CHECK(doc.find_node(find_predicate_prefix(STR("child3"))) == xml_node()); +} + +#ifndef PUGIXML_NO_STL +TEST_XML(dom_node_path, "<node><child1>text<child2/></child1></node>") +{ + CHECK(xml_node().path() == STR("")); + + CHECK(doc.path() == STR("")); + CHECK(doc.child(STR("node")).path() == STR("/node")); + CHECK(doc.child(STR("node")).child(STR("child1")).path() == STR("/node/child1")); + CHECK(doc.child(STR("node")).child(STR("child1")).child(STR("child2")).path() == STR("/node/child1/child2")); + CHECK(doc.child(STR("node")).child(STR("child1")).first_child().path() == STR("/node/child1/")); + + CHECK(doc.child(STR("node")).child(STR("child1")).path('\\') == STR("\\node\\child1")); +} +#endif + +TEST_XML(dom_node_first_element_by_path, "<node><child1>text<child2/></child1></node>") +{ + CHECK(xml_node().first_element_by_path(STR("/")) == xml_node()); + + CHECK(doc.first_element_by_path(STR("")) == doc); + CHECK(doc.first_element_by_path(STR("/")) == doc); + + CHECK(doc.first_element_by_path(STR("/node/")) == doc.child(STR("node"))); + CHECK(doc.first_element_by_path(STR("node/")) == doc.child(STR("node"))); + CHECK(doc.first_element_by_path(STR("node")) == doc.child(STR("node"))); + CHECK(doc.first_element_by_path(STR("/node")) == doc.child(STR("node"))); + +#ifndef PUGIXML_NO_STL + CHECK(doc.first_element_by_path(STR("/node/child1/child2")).path() == STR("/node/child1/child2")); +#endif + + CHECK(doc.first_element_by_path(STR("/node/child2")) == xml_node()); + + CHECK(doc.first_element_by_path(STR("\\node\\child1"), '\\') == doc.child(STR("node")).child(STR("child1"))); + + CHECK(doc.child(STR("node")).first_element_by_path(STR("..")) == doc); + CHECK(doc.child(STR("node")).first_element_by_path(STR(".")) == doc.child(STR("node"))); + + CHECK(doc.child(STR("node")).first_element_by_path(STR("../node/./child1/../.")) == doc.child(STR("node"))); + + CHECK(doc.child(STR("node")).first_element_by_path(STR("child1")) == doc.child(STR("node")).child(STR("child1"))); + CHECK(doc.child(STR("node")).first_element_by_path(STR("child1/")) == doc.child(STR("node")).child(STR("child1"))); + CHECK(doc.child(STR("node")).first_element_by_path(STR("child")) == xml_node()); + CHECK(doc.child(STR("node")).first_element_by_path(STR("child11")) == xml_node()); +} + +struct test_walker: xml_tree_walker +{ + std::basic_string<pugi::char_t> log; + unsigned int call_count; + unsigned int stop_count; + + test_walker(unsigned int stop_count = 0): call_count(0), stop_count(stop_count) + { + } + + std::basic_string<pugi::char_t> depthstr() const + { + char buf[32]; + sprintf(buf, "%d", depth()); + + #ifdef PUGIXML_WCHAR_MODE + wchar_t wbuf[32]; + std::copy(buf, buf + strlen(buf) + 1, &wbuf[0]); + + return std::basic_string<pugi::char_t>(wbuf); + #else + return std::basic_string<pugi::char_t>(buf); + #endif + } + + virtual bool begin(xml_node& node) + { + log += STR("|"); + log += depthstr(); + log += STR(" <"); + log += node.name(); + log += STR("="); + log += node.value(); + + return ++call_count != stop_count && xml_tree_walker::begin(node); + } + + virtual bool for_each(xml_node& node) + { + log += STR("|"); + log += depthstr(); + log += STR(" !"); + log += node.name(); + log += STR("="); + log += node.value(); + + return ++call_count != stop_count && xml_tree_walker::end(node); + } + + virtual bool end(xml_node& node) + { + log += STR("|"); + log += depthstr(); + log += STR(" >"); + log += node.name(); + log += STR("="); + log += node.value(); + + return ++call_count != stop_count; + } +}; + +TEST_XML(dom_node_traverse, "<node><child>text</child></node>") +{ + test_walker walker; + + CHECK(doc.traverse(walker)); + + CHECK(walker.call_count == 5); + CHECK(walker.log == STR("|-1 <=|0 !node=|1 !child=|2 !=text|-1 >=")); +} + +TEST_XML(dom_node_traverse_siblings, "<node><child/><child>text</child><child/></node>") +{ + test_walker walker; + + CHECK(doc.traverse(walker)); + + CHECK(walker.call_count == 7); + CHECK(walker.log == STR("|-1 <=|0 !node=|1 !child=|1 !child=|2 !=text|1 !child=|-1 >=")); +} + +TEST(dom_node_traverse_empty) +{ + test_walker walker; + + CHECK(xml_node().traverse(walker)); + + CHECK(walker.call_count == 2); + CHECK(walker.log == STR("|-1 <=|-1 >=")); +} + +TEST_XML(dom_node_traverse_child, "<node><child>text</child></node>") +{ + test_walker walker; + + CHECK(doc.child(STR("node")).traverse(walker)); + + CHECK(walker.call_count == 4); + CHECK(walker.log == STR("|-1 <node=|0 !child=|1 !=text|-1 >node=")); +} + +TEST_XML(dom_node_traverse_stop_begin, "<node><child>text</child></node>") +{ + test_walker walker(1); + + CHECK(!doc.traverse(walker)); + + CHECK(walker.call_count == 1); + CHECK(walker.log == STR("|-1 <=")); +} + +TEST_XML(dom_node_traverse_stop_for_each, "<node><child>text</child></node>") +{ + test_walker walker(3); + + CHECK(!doc.traverse(walker)); + + CHECK(walker.call_count == 3); + CHECK(walker.log == STR("|-1 <=|0 !node=|1 !child=")); +} + +TEST_XML(dom_node_traverse_stop_end, "<node><child>text</child></node>") +{ + test_walker walker(5); + + CHECK(!doc.traverse(walker)); + + CHECK(walker.call_count == 5); + CHECK(walker.log == STR("|-1 <=|0 !node=|1 !child=|2 !=text|-1 >=")); +} + +TEST_XML_FLAGS(dom_offset_debug, "<?xml?><?pi?><!--comment--><node>pcdata<![CDATA[cdata]]></node>", parse_default | parse_pi | parse_comments | parse_declaration) +{ + CHECK(xml_node().offset_debug() == -1); + CHECK(doc.offset_debug() == 0); + + xml_node_iterator it = doc.begin(); + + CHECK((it++)->offset_debug() == 2); + CHECK((it++)->offset_debug() == 9); + CHECK((it++)->offset_debug() == 17); + CHECK((it++)->offset_debug() == 28); + + xml_node_iterator cit = doc.child(STR("node")).begin(); + + CHECK((cit++)->offset_debug() == 33); + CHECK((cit++)->offset_debug() == 48); +} |