mirror of
https://github.com/zeux/pugixml.git
synced 2025-01-14 01:47:55 +08:00
tests: Add move semantics tests
Also test ranged for and copying big xpath_variable_set objects (to make sure we actually handle hash collisions properly)
This commit is contained in:
parent
83b894b8f1
commit
4eadece45f
@ -1106,3 +1106,27 @@ TEST_XML(dom_unspecified_bool_coverage, "<node attr='value'>text</node>")
|
||||
static_cast<void (*)(xpath_node***)>(qn)(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103
|
||||
TEST_XML(dom_ranged_for, "<node attr1='1' attr2='2'><test>3</test><fake>5</fake><test>4</test></node>")
|
||||
{
|
||||
int index = 1;
|
||||
|
||||
for (xml_node n: doc.children())
|
||||
{
|
||||
for (xml_attribute a: n.attributes())
|
||||
{
|
||||
CHECK(a.as_int() == index);
|
||||
index++;
|
||||
}
|
||||
|
||||
for (xml_node c: n.children(STR("test")))
|
||||
{
|
||||
CHECK(c.text().as_int() == index);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
CHECK(index == 5);
|
||||
}
|
||||
#endif
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "helpers.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
TEST_XML(xpath_api_select_nodes, "<node><head/><foo/><foo/><tail/></node>")
|
||||
{
|
||||
@ -407,4 +408,224 @@ TEST_XML(xpath_api_deprecated_select_single_node, "<node><head/><foo id='1'/><fo
|
||||
CHECK(n1.node().attribute(STR("id")).as_int() == 1);
|
||||
CHECK(n2.node().attribute(STR("id")).as_int() == 1);
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103
|
||||
TEST_XML(xpath_api_nodeset_move_ctor, "<node><foo/><foo/><bar/></node>")
|
||||
{
|
||||
xpath_node_set set = doc.select_nodes(STR("node/bar/preceding::*"));
|
||||
|
||||
CHECK(set.size() == 2);
|
||||
CHECK(set.type() == xpath_node_set::type_sorted_reverse);
|
||||
|
||||
test_runner::_memory_fail_threshold = 1;
|
||||
|
||||
xpath_node_set move = std::move(set);
|
||||
|
||||
CHECK(set.size() == 0);
|
||||
CHECK(set.type() == xpath_node_set::type_unsorted);
|
||||
|
||||
CHECK(move.size() == 2);
|
||||
CHECK(move.type() == xpath_node_set::type_sorted_reverse);
|
||||
CHECK(move[1] == doc.first_child().first_child());
|
||||
}
|
||||
|
||||
|
||||
TEST_XML(xpath_api_nodeset_move_ctor_single, "<node><foo/><foo/><bar/></node>")
|
||||
{
|
||||
xpath_node_set set = doc.select_nodes(STR("node/bar"));
|
||||
|
||||
CHECK(set.size() == 1);
|
||||
CHECK(set.type() == xpath_node_set::type_sorted);
|
||||
|
||||
test_runner::_memory_fail_threshold = 1;
|
||||
|
||||
xpath_node_set move = std::move(set);
|
||||
|
||||
CHECK(set.size() == 0);
|
||||
CHECK(set.type() == xpath_node_set::type_unsorted);
|
||||
|
||||
CHECK(move.size() == 1);
|
||||
CHECK(move.type() == xpath_node_set::type_sorted);
|
||||
CHECK(move[0] == doc.first_child().last_child());
|
||||
}
|
||||
|
||||
TEST(xpath_api_nodeset_move_ctor_empty)
|
||||
{
|
||||
xpath_node_set set;
|
||||
set.sort();
|
||||
|
||||
CHECK(set.size() == 0);
|
||||
CHECK(set.type() == xpath_node_set::type_sorted);
|
||||
|
||||
test_runner::_memory_fail_threshold = 1;
|
||||
|
||||
xpath_node_set move = std::move(set);
|
||||
|
||||
CHECK(set.size() == 0);
|
||||
CHECK(set.type() == xpath_node_set::type_unsorted);
|
||||
|
||||
CHECK(move.size() == 0);
|
||||
CHECK(move.type() == xpath_node_set::type_sorted);
|
||||
}
|
||||
|
||||
TEST_XML(xpath_api_nodeset_move_assign, "<node><foo/><foo/><bar/></node>")
|
||||
{
|
||||
xpath_node_set set = doc.select_nodes(STR("node/bar/preceding::*"));
|
||||
|
||||
CHECK(set.size() == 2);
|
||||
CHECK(set.type() == xpath_node_set::type_sorted_reverse);
|
||||
|
||||
test_runner::_memory_fail_threshold = 1;
|
||||
|
||||
xpath_node_set move;
|
||||
|
||||
CHECK(move.size() == 0);
|
||||
CHECK(move.type() == xpath_node_set::type_unsorted);
|
||||
|
||||
move = std::move(set);
|
||||
|
||||
CHECK(set.size() == 0);
|
||||
CHECK(set.type() == xpath_node_set::type_unsorted);
|
||||
|
||||
CHECK(move.size() == 2);
|
||||
CHECK(move.type() == xpath_node_set::type_sorted_reverse);
|
||||
CHECK(move[1] == doc.first_child().first_child());
|
||||
}
|
||||
|
||||
TEST_XML(xpath_api_nodeset_move_assign_destroy, "<node><foo/><foo/><bar/></node>")
|
||||
{
|
||||
xpath_node_set set = doc.select_nodes(STR("node/bar/preceding::*"));
|
||||
|
||||
CHECK(set.size() == 2);
|
||||
CHECK(set.type() == xpath_node_set::type_sorted_reverse);
|
||||
|
||||
xpath_node_set all = doc.select_nodes(STR("//*"));
|
||||
|
||||
CHECK(all.size() == 4);
|
||||
|
||||
test_runner::_memory_fail_threshold = 1;
|
||||
|
||||
all = std::move(set);
|
||||
|
||||
CHECK(set.size() == 0);
|
||||
CHECK(set.type() == xpath_node_set::type_unsorted);
|
||||
|
||||
CHECK(all.size() == 2);
|
||||
CHECK(all.type() == xpath_node_set::type_sorted_reverse);
|
||||
CHECK(all[1] == doc.first_child().first_child());
|
||||
}
|
||||
|
||||
TEST_XML(xpath_api_nodeset_move_assign_single, "<node><foo/><foo/><bar/></node>")
|
||||
{
|
||||
xpath_node_set set = doc.select_nodes(STR("node/bar"));
|
||||
|
||||
CHECK(set.size() == 1);
|
||||
CHECK(set.type() == xpath_node_set::type_sorted);
|
||||
|
||||
test_runner::_memory_fail_threshold = 1;
|
||||
|
||||
xpath_node_set move;
|
||||
|
||||
CHECK(move.size() == 0);
|
||||
CHECK(move.type() == xpath_node_set::type_unsorted);
|
||||
|
||||
move = std::move(set);
|
||||
|
||||
CHECK(set.size() == 0);
|
||||
CHECK(set.type() == xpath_node_set::type_unsorted);
|
||||
|
||||
CHECK(move.size() == 1);
|
||||
CHECK(move.type() == xpath_node_set::type_sorted);
|
||||
CHECK(move[0] == doc.first_child().last_child());
|
||||
}
|
||||
|
||||
TEST(xpath_api_nodeset_move_assign_empty)
|
||||
{
|
||||
xpath_node_set set;
|
||||
set.sort();
|
||||
|
||||
CHECK(set.size() == 0);
|
||||
CHECK(set.type() == xpath_node_set::type_sorted);
|
||||
|
||||
test_runner::_memory_fail_threshold = 1;
|
||||
|
||||
xpath_node_set move;
|
||||
|
||||
CHECK(move.size() == 0);
|
||||
CHECK(move.type() == xpath_node_set::type_unsorted);
|
||||
|
||||
move = std::move(set);
|
||||
|
||||
CHECK(set.size() == 0);
|
||||
CHECK(set.type() == xpath_node_set::type_unsorted);
|
||||
|
||||
CHECK(move.size() == 0);
|
||||
CHECK(move.type() == xpath_node_set::type_sorted);
|
||||
}
|
||||
|
||||
TEST(xpath_api_query_move)
|
||||
{
|
||||
xml_node c;
|
||||
|
||||
xpath_query q1(STR("true()"));
|
||||
xpath_query q4(STR("true() and false()"));
|
||||
|
||||
test_runner::_memory_fail_threshold = 1;
|
||||
|
||||
CHECK(q1);
|
||||
CHECK(q1.evaluate_boolean(c));
|
||||
|
||||
xpath_query q2 = std::move(q1);
|
||||
CHECK(!q1);
|
||||
CHECK(!q1.evaluate_boolean(c));
|
||||
CHECK(q2);
|
||||
CHECK(q2.evaluate_boolean(c));
|
||||
|
||||
xpath_query q3;
|
||||
CHECK(!q3);
|
||||
CHECK(!q3.evaluate_boolean(c));
|
||||
|
||||
q3 = std::move(q2);
|
||||
CHECK(!q2);
|
||||
CHECK(!q2.evaluate_boolean(c));
|
||||
CHECK(q3);
|
||||
CHECK(q3.evaluate_boolean(c));
|
||||
|
||||
CHECK(q4);
|
||||
CHECK(!q4.evaluate_boolean(c));
|
||||
|
||||
q4 = std::move(q3);
|
||||
|
||||
CHECK(!q3);
|
||||
CHECK(!q3.evaluate_boolean(c));
|
||||
CHECK(q4);
|
||||
CHECK(q4.evaluate_boolean(c));
|
||||
|
||||
q4 = std::move(q4);
|
||||
|
||||
CHECK(q4);
|
||||
CHECK(q4.evaluate_boolean(c));
|
||||
}
|
||||
|
||||
TEST(xpath_api_query_vector)
|
||||
{
|
||||
std::vector<xpath_query> qv;
|
||||
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
char_t expr[2];
|
||||
expr[0] = '0' + i;
|
||||
expr[1] = 0;
|
||||
|
||||
qv.push_back(xpath_query(expr));
|
||||
}
|
||||
|
||||
double result = 0;
|
||||
|
||||
for (auto& q: qv)
|
||||
result += q.evaluate_number(xml_node());
|
||||
|
||||
CHECK(result == 45);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -473,4 +473,110 @@ TEST_XML(xpath_variables_copy_out_of_memory, "<node />")
|
||||
CHECK_STRING(set2.get(STR("c"))->get_string(), STR("string"));
|
||||
CHECK(set2.get(STR("d"))->get_node_set().size() == 1);
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103
|
||||
TEST_XML(xpath_variables_move, "<node />")
|
||||
{
|
||||
xpath_variable_set set;
|
||||
set.set(STR("a"), true);
|
||||
set.set(STR("b"), 2.0);
|
||||
set.set(STR("c"), STR("string"));
|
||||
set.set(STR("d"), doc.select_nodes(STR("//*")));
|
||||
|
||||
xpath_variable_set copy = set;
|
||||
copy.set(STR("e"), 42.0);
|
||||
|
||||
test_runner::_memory_fail_threshold = 1;
|
||||
|
||||
xpath_variable_set move1 = std::move(set);
|
||||
|
||||
CHECK(!set.get(STR("a")) && !set.get(STR("b")) && !set.get(STR("c")) && !set.get(STR("d")));
|
||||
CHECK(move1.get(STR("a")) && move1.get(STR("b")) && move1.get(STR("c")) && move1.get(STR("d")));
|
||||
|
||||
CHECK(move1.get(STR("a"))->get_boolean() == true);
|
||||
CHECK(move1.get(STR("b"))->get_number() == 2.0);
|
||||
CHECK_STRING(move1.get(STR("c"))->get_string(), STR("string"));
|
||||
CHECK(move1.get(STR("d"))->get_node_set().size() == 1);
|
||||
|
||||
xpath_variable_set move2;
|
||||
move2 = std::move(move1);
|
||||
|
||||
CHECK(!move1.get(STR("a")) && !move1.get(STR("b")) && !move1.get(STR("c")) && !move1.get(STR("d")));
|
||||
CHECK(move2.get(STR("a")) && move2.get(STR("b")) && move2.get(STR("c")) && move2.get(STR("d")));
|
||||
|
||||
CHECK(copy.get(STR("e")));
|
||||
|
||||
copy = std::move(move2);
|
||||
|
||||
CHECK(!move2.get(STR("a")) && !move2.get(STR("b")) && !move2.get(STR("c")) && !move2.get(STR("d")));
|
||||
CHECK(copy.get(STR("a")) && copy.get(STR("b")) && copy.get(STR("c")) && copy.get(STR("d")));
|
||||
CHECK(!copy.get(STR("e")));
|
||||
|
||||
CHECK(copy.get(STR("a"))->get_boolean() == true);
|
||||
CHECK(copy.get(STR("b"))->get_number() == 2.0);
|
||||
CHECK_STRING(copy.get(STR("c"))->get_string(), STR("string"));
|
||||
CHECK(copy.get(STR("d"))->get_node_set().size() == 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(xpath_variables_copy_big)
|
||||
{
|
||||
xpath_variable_set set;
|
||||
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
char_t name[4];
|
||||
name[0] = 'a';
|
||||
name[1] = '0' + (i / 10);
|
||||
name[2] = '0' + (i % 10);
|
||||
name[3] = 0;
|
||||
|
||||
set.set(name, double(i));
|
||||
}
|
||||
|
||||
xpath_variable_set copy = set;
|
||||
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
char_t name[4];
|
||||
name[0] = 'a';
|
||||
name[1] = '0' + (i / 10);
|
||||
name[2] = '0' + (i % 10);
|
||||
name[3] = 0;
|
||||
|
||||
CHECK(copy.get(name) && copy.get(name)->get_number() == i);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(xpath_variables_copy_big_out_of_memory)
|
||||
{
|
||||
xpath_variable_set set;
|
||||
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
char_t name[4];
|
||||
name[0] = 'a';
|
||||
name[1] = '0' + (i / 10);
|
||||
name[2] = '0' + (i % 10);
|
||||
name[3] = 0;
|
||||
|
||||
set.set(name, double(i));
|
||||
}
|
||||
|
||||
test_runner::_memory_fail_threshold = 1;
|
||||
|
||||
xpath_variable_set copy;
|
||||
CHECK_ALLOC_FAIL(copy = set);
|
||||
|
||||
for (int i = 0; i < 100; ++i)
|
||||
{
|
||||
char_t name[4];
|
||||
name[0] = 'a';
|
||||
name[1] = '0' + (i / 10);
|
||||
name[2] = '0' + (i % 10);
|
||||
name[3] = 0;
|
||||
|
||||
CHECK(!copy.get(name));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user