diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/allocator.cpp | 7 | ||||
| -rw-r--r-- | tests/test_dom_traverse.cpp | 24 | ||||
| -rw-r--r-- | tests/test_write.cpp | 27 | ||||
| -rw-r--r-- | tests/test_xpath_api.cpp | 228 | ||||
| -rw-r--r-- | tests/test_xpath_variables.cpp | 166 | 
5 files changed, 447 insertions, 5 deletions
| diff --git a/tests/allocator.cpp b/tests/allocator.cpp index 8ca0963..e1d99d5 100644 --- a/tests/allocator.cpp +++ b/tests/allocator.cpp @@ -2,6 +2,7 @@  #include <string.h>  #include <assert.h> +#include <stdlib.h>  // Low-level allocation functions  #if defined(_WIN32) || defined(_WIN64) @@ -80,7 +81,9 @@ namespace  	void* allocate_page_aligned(size_t size)  	{ -		return mmap(0, size + page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); +		void* result = malloc(size + page_size); + +		return reinterpret_cast<void*>(align_to_page(reinterpret_cast<size_t>(result)));  	}  	void* allocate(size_t size) @@ -111,8 +114,6 @@ namespace  	}  }  #else -#	include <stdlib.h> -  namespace  {  	void* allocate(size_t size) diff --git a/tests/test_dom_traverse.cpp b/tests/test_dom_traverse.cpp index 4423dbe..e4b8c44 100644 --- a/tests/test_dom_traverse.cpp +++ b/tests/test_dom_traverse.cpp @@ -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 diff --git a/tests/test_write.cpp b/tests/test_write.cpp index af4acf4..df7b0b1 100644 --- a/tests/test_write.cpp +++ b/tests/test_write.cpp @@ -21,6 +21,31 @@ TEST_XML(write_indent, "<node attr='1'><child><sub>text</sub></child></node>")  	CHECK_NODE_EX(doc, STR("<node attr=\"1\">\n\t<child>\n\t\t<sub>text</sub>\n\t</child>\n</node>\n"), STR("\t"), format_indent);  } +TEST_XML(write_indent_attributes, "<node attr='1' other='2'><child><sub>text</sub></child></node>") +{ +	CHECK_NODE_EX(doc, STR("<node\n\tattr=\"1\"\n\tother=\"2\">\n\t<child>\n\t\t<sub>text</sub>\n\t</child>\n</node>\n"), STR("\t"), format_indent_attributes); +} + +TEST_XML(write_indent_attributes_empty_element, "<node attr='1' other='2' />") +{ +	CHECK_NODE_EX(doc, STR("<node\n\tattr=\"1\"\n\tother=\"2\" />\n"), STR("\t"), format_indent_attributes); +} + +TEST_XML_FLAGS(write_indent_attributes_declaration, "<?xml version=\"1.0\" encoding=\"UTF-8\"?><node attr='1' other='2' />", parse_full) +{ +	CHECK_NODE_EX(doc, STR("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<node\n\tattr=\"1\"\n\tother=\"2\" />\n"), STR("\t"), format_indent_attributes); +} + +TEST_XML(write_indent_attributes_raw, "<node attr='1' other='2'><child><sub>text</sub></child></node>") +{ +	CHECK_NODE_EX(doc, STR("<node attr=\"1\" other=\"2\"><child><sub>text</sub></child></node>"), STR("\t"), format_indent_attributes | format_raw); +} + +TEST_XML(write_indent_attributes_empty_indent, "<node attr='1' other='2'><child><sub>text</sub></child></node>") +{ +	CHECK_NODE_EX(doc, STR("<node\nattr=\"1\"\nother=\"2\">\n<child>\n<sub>text</sub>\n</child>\n</node>\n"), STR(""), format_indent_attributes); +} +  TEST_XML(write_pcdata, "<node attr='1'><child><sub/>text</child></node>")  {  	CHECK_NODE_EX(doc, STR("<node attr=\"1\">\n\t<child>\n\t\t<sub />text</child>\n</node>\n"), STR("\t"), format_indent); @@ -360,7 +385,7 @@ TEST(write_encoding_huge_invalid)  TEST(write_unicode_escape)  {  	char s_utf8[] = "<\xE2\x82\xAC \xC2\xA2='\"\xF0\xA4\xAD\xA2
\"'>&\x14\xF0\xA4\xAD\xA2<</\xE2\x82\xAC>"; -	 +  	xml_document doc;  	CHECK(doc.load_buffer(s_utf8, sizeof(s_utf8), parse_default, encoding_utf8)); diff --git a/tests/test_xpath_api.cpp b/tests/test_xpath_api.cpp index df078a0..295bd95 100644 --- a/tests/test_xpath_api.cpp +++ b/tests/test_xpath_api.cpp @@ -7,6 +7,7 @@  #include "helpers.hpp"  #include <string> +#include <vector>  TEST_XML(xpath_api_select_nodes, "<node><head/><foo/><foo/><tail/></node>")  { @@ -381,15 +382,20 @@ TEST_XML(xpath_api_node_set_assign_out_of_memory_preserve, "<node><a/><b/></node  {  	xpath_node_set ns = doc.select_nodes(STR("node/*"));  	CHECK(ns.size() == 2); +	CHECK(ns.type() == xpath_node_set::type_sorted);  	xpath_node_set nsall = doc.select_nodes(STR("//*")); +	nsall.sort(true);  	CHECK(nsall.size() == 3); +	CHECK(nsall.type() == xpath_node_set::type_sorted_reverse);  	test_runner::_memory_fail_threshold = 1;  	CHECK_ALLOC_FAIL(ns = nsall); -	CHECK(ns.size() == 2 && ns[0] == doc.child(STR("node")).child(STR("a")) && ns[1] == doc.child(STR("node")).child(STR("b"))); +	CHECK(ns.size() == 2); +	CHECK(ns.type() == xpath_node_set::type_sorted); +	CHECK(ns[0] == doc.child(STR("node")).child(STR("a")) && ns[1] == doc.child(STR("node")).child(STR("b")));  }  TEST_XML(xpath_api_deprecated_select_single_node, "<node><head/><foo id='1'/><foo/><tail/></node>") @@ -402,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' + char_t(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 diff --git a/tests/test_xpath_variables.cpp b/tests/test_xpath_variables.cpp index 0d33312..f72d6ff 100644 --- a/tests/test_xpath_variables.cpp +++ b/tests/test_xpath_variables.cpp @@ -413,4 +413,170 @@ TEST_XML(xpath_variables_count_sum, "<node><c1>12</c1><c2>23</c2><c3>34</c3></no  	CHECK_XPATH_NUMBER_VAR(xml_node(), STR("sum($c12) * count($c) - sum($c3)"), &set, 71);
  }
 +
 +TEST_XML(xpath_variables_copy, "<node />")
 +{
 +	xpath_variable_set set1;
 +	set1.set(STR("a"), true);
 +	set1.set(STR("b"), 2.0);
 +	set1.set(STR("c"), STR("string"));
 +	set1.set(STR("d"), doc.select_nodes(STR("//*")));
 +
 +	CHECK_XPATH_STRING_VAR(xml_node(), STR("substring($c, count($d[$a]) + $b)"), &set1, STR("ring"));
 +
 +	xpath_variable_set set2 = set1;
 +
 +	CHECK_XPATH_STRING_VAR(xml_node(), STR("substring($c, count($d[$a]) + $b)"), &set2, STR("ring"));
 +
 +	xpath_variable_set set3;
 +
 +	CHECK(!set3.get(STR("a")));
 +
 +	set3 = set1;
 +
 +	CHECK_XPATH_STRING_VAR(xml_node(), STR("substring($c, count($d[$a]) + $b)"), &set2, STR("ring"));
 +
 +	set3 = set3;
 +
 +	CHECK_XPATH_STRING_VAR(xml_node(), STR("substring($c, count($d[$a]) + $b)"), &set2, STR("ring"));
 +
 +	set3 = xpath_variable_set();
 +
 +	CHECK(!set3.get(STR("a")));
 +}
 +
 +TEST_XML(xpath_variables_copy_out_of_memory, "<node />")
 +{
 +	xpath_variable_set set1;
 +	set1.set(STR("a"), true);
 +	set1.set(STR("b"), 2.0);
 +	set1.set(STR("c"), STR("string"));
 +	set1.set(STR("d"), doc.select_nodes(STR("//*")));
 +
 +	xpath_variable_set set2 = set1;
 +
 +	test_runner::_memory_fail_threshold = 32768 + 75 * sizeof(void*);
 +
 +	CHECK_ALLOC_FAIL(xpath_variable_set set3 = set1);
 +
 +	xpath_variable_set set4;
 +
 +	CHECK_ALLOC_FAIL(set4 = set1);
 +	CHECK(!set4.get(STR("a")) && !set4.get(STR("b")) && !set4.get(STR("c")) && !set4.get(STR("d")));
 +
 +	CHECK_ALLOC_FAIL(set2 = set1);
 +
 +	CHECK(set2.get(STR("a")) && set2.get(STR("b")) && set2.get(STR("c")) && set2.get(STR("d")));
 +
 +	CHECK(set2.get(STR("a"))->get_boolean() == true);
 +	CHECK(set2.get(STR("b"))->get_number() == 2.0);
 +	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' + char_t(i / 10);
 +		name[2] = '0' + char_t(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' + char_t(i / 10);
 +		name[2] = '0' + char_t(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' + char_t(i / 10);
 +		name[2] = '0' + char_t(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' + char_t(i / 10);
 +		name[2] = '0' + char_t(i % 10);
 +		name[3] = 0;
 +
 +		CHECK(!copy.get(name));
 +	}
 +}
  #endif
 | 
