0
0
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:
Arseny Kapoulkine 2015-04-21 19:44:19 -07:00
parent 83b894b8f1
commit 4eadece45f
3 changed files with 351 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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