From 51da129b50a0b99ee85af20cc4a4b77f6bc823ff Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 13 Mar 2015 22:13:10 -0700 Subject: tests: Fix truncation test data/truncation.xml was corrupted at some point and was not actually valid. Fix the file and make the test fail if we can't parse truncation.xml at all. --- tests/data/truncation.xml | 16 ++++++++-------- tests/test_document.cpp | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'tests') diff --git a/tests/data/truncation.xml b/tests/data/truncation.xml index 9cdbe13..1b0e9a8 100644 --- a/tests/data/truncation.xml +++ b/tests/data/truncation.xml @@ -1,6 +1,6 @@ - - + + some text @@ -8,12 +8,12 @@ some more text - <+%- __--="name" >__="value">-__%___-_- + <汉语 名字="name" 价值="value">世界有很多语言𤭢 - <___> - <_>++" - <__>太__ - + <氏名> + <氏>山田 + <名>太郎 + - + \ No newline at end of file diff --git a/tests/test_document.cpp b/tests/test_document.cpp index 49428f2..09d89d7 100644 --- a/tests/test_document.cpp +++ b/tests/test_document.cpp @@ -1010,7 +1010,7 @@ TEST(document_progressive_truncation) char* buffer = new char[original_size]; - for (size_t i = 1; i < original_size; ++i) + for (size_t i = 1; i <= original_size; ++i) { char* truncated_data = buffer + original_size - i; @@ -1022,7 +1022,7 @@ TEST(document_progressive_truncation) bool result = doc.load_buffer_inplace(truncated_data, i); // only eof is parseable - CHECK((i >= 3325) ? result : !result); + CHECK((i == original_size) ? result : !result); } // fragment mode @@ -1033,7 +1033,7 @@ TEST(document_progressive_truncation) bool result = doc.load_buffer_inplace(truncated_data, i, parse_default | parse_fragment); // some truncate locations are parseable - those that come after declaration, declaration + doctype, declaration + doctype + comment and eof - CHECK(((i - 21) < 3 || (i - 66) < 3 || (i - 95) < 3 || i >= 3325) ? result : !result); + CHECK(((i - 21) < 3 || (i - 66) < 3 || (i - 95) < 3 || i == original_size) ? result : !result); } } -- cgit v1.2.3 From 5f996eba6deaa804bf4caced8acc65d8626720d6 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 18 Mar 2015 08:34:23 -0700 Subject: Do not emit surrounding whitespace for text nodes Previously we omitted extra whitespace for single PCDATA/CDATA children, but in mixed content there was extra indentation before/after text nodes. One of the problems with that is that the text that you saved is not exactly the same as the parsing result using default flags (parse_trim_pcdata helps). Another problem is that parse-format cycles do not have a fixed point for mixed content - the result expands indefinitely. Some XML libraries, like Python minidom, have the same issue, but this is definitely a problem. Pretty-printing mixed content is hard. It seems that the only other sensible choice is to switch mixed content nodes to raw formatting. In a way the code in this change is a weaker version of that - it removes indentation around text nodes but still keeps it around element siblings/children. Thus we can switch to mixed-raw formatting at some point later, which will be a superset of the current behavior. To do this we have to either switch at the first text node (.NET XmlDocument does that), or scan the children of each element for a possible text node and switch before we output the first child. The former behavior seems non-intuitive (and a bit broken); unfortunately, the latter behavior can cost up to 20% of the output time for trees *without* mixed content. Fixes #13. --- tests/test_write.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++---- tests/writer_string.cpp | 6 +++--- 2 files changed, 52 insertions(+), 7 deletions(-) (limited to 'tests') diff --git a/tests/test_write.cpp b/tests/test_write.cpp index 59cdb3e..a61e1cf 100644 --- a/tests/test_write.cpp +++ b/tests/test_write.cpp @@ -22,19 +22,19 @@ TEST_XML(write_indent, "text") TEST_XML(write_pcdata, "text") { - CHECK_NODE_EX(doc, STR("\n\t\n\t\t\n\t\ttext\n\t\n\n"), STR("\t"), format_indent); + CHECK_NODE_EX(doc, STR("\n\t\n\t\ttext\n\n"), STR("\t"), format_indent); } TEST_XML_FLAGS(write_cdata, "", parse_cdata | parse_fragment) { CHECK_NODE(doc, STR("")); - CHECK_NODE_EX(doc, STR("\n"), STR(""), 0); + CHECK_NODE_EX(doc, STR(""), STR(""), 0); } TEST_XML_FLAGS(write_cdata_empty, "", parse_cdata | parse_fragment) { CHECK_NODE(doc, STR("")); - CHECK_NODE_EX(doc, STR("\n"), STR(""), 0); + CHECK_NODE_EX(doc, STR(""), STR(""), 0); } TEST_XML_FLAGS(write_cdata_escape, "", parse_cdata | parse_fragment) @@ -527,5 +527,50 @@ TEST(write_pcdata_null) doc.first_child().append_child(node_pcdata); - CHECK_NODE_EX(doc, STR("\n\t\n\t\n\n"), STR("\t"), format_indent); + CHECK_NODE_EX(doc, STR("\n"), STR("\t"), format_indent); +} + +TEST(write_pcdata_whitespace_fixedpoint) +{ + const char_t* data = STR(" test \n \n \n"); + + static const unsigned int flags_parse[] = + { + 0, + parse_ws_pcdata, + parse_ws_pcdata_single, + parse_trim_pcdata + }; + + static const unsigned int flags_format[] = + { + 0, + format_raw, + format_indent + }; + + for (unsigned int i = 0; i < sizeof(flags_parse) / sizeof(flags_parse[0]); ++i) + { + xml_document doc; + CHECK(doc.load_string(data, flags_parse[i])); + + for (unsigned int j = 0; j < sizeof(flags_format) / sizeof(flags_format[0]); ++j) + { + std::string saved = write_narrow(doc, flags_format[j], encoding_auto); + + xml_document rdoc; + CHECK(rdoc.load_buffer(&saved[0], saved.size(), flags_parse[i])); + + std::string rsaved = write_narrow(rdoc, flags_format[j], encoding_auto); + + CHECK(saved == rsaved); + } + } +} + +TEST_XML_FLAGS(write_mixed, "premidpostfin", parse_full) +{ + CHECK_NODE(doc, "premidpostfin"); + CHECK_NODE_EX(doc, "\n\npremid\npostfin\n\n\n", STR("\t"), 0); + CHECK_NODE_EX(doc, "\n\t\n\tpremid\n\t\tpostfin\n\t\n\n", STR("\t"), format_indent); } diff --git a/tests/writer_string.cpp b/tests/writer_string.cpp index 661c792..26bca8d 100644 --- a/tests/writer_string.cpp +++ b/tests/writer_string.cpp @@ -45,7 +45,7 @@ std::string save_narrow(const pugi::xml_document& doc, unsigned int flags, pugi: { xml_writer_string writer; - doc.save(writer, STR(""), flags, encoding); + doc.save(writer, STR("\t"), flags, encoding); return writer.as_narrow(); } @@ -59,7 +59,7 @@ std::string write_narrow(pugi::xml_node node, unsigned int flags, pugi::xml_enco { xml_writer_string writer; - node.print(writer, STR(""), flags, encoding); + node.print(writer, STR("\t"), flags, encoding); return writer.as_narrow(); } @@ -73,7 +73,7 @@ std::basic_string write_wide(pugi::xml_node node, unsigned int flags, p { xml_writer_string writer; - node.print(writer, STR(""), flags, encoding); + node.print(writer, STR("\t"), flags, encoding); return writer.as_wide(); } -- cgit v1.2.3 From e68048518ea4830ffcdaf79e7f929713263c6f06 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 18 Mar 2015 21:19:58 -0700 Subject: Update version to 1.6 --- tests/test_version.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/test_version.cpp b/tests/test_version.cpp index 24036fc..cf64efc 100644 --- a/tests/test_version.cpp +++ b/tests/test_version.cpp @@ -1,5 +1,5 @@ #include "../src/pugixml.hpp" -#if PUGIXML_VERSION != 150 +#if PUGIXML_VERSION != 160 #error Unexpected pugixml version #endif -- cgit v1.2.3 From 86410cd696e55610cc489af5a69cb83fc15dadf1 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 18 Mar 2015 21:29:55 -0700 Subject: tests: Fix tests in wchar mode --- tests/test_write.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tests') diff --git a/tests/test_write.cpp b/tests/test_write.cpp index a61e1cf..1528453 100644 --- a/tests/test_write.cpp +++ b/tests/test_write.cpp @@ -570,7 +570,7 @@ TEST(write_pcdata_whitespace_fixedpoint) TEST_XML_FLAGS(write_mixed, "premidpostfin", parse_full) { - CHECK_NODE(doc, "premidpostfin"); - CHECK_NODE_EX(doc, "\n\npremid\npostfin\n\n\n", STR("\t"), 0); - CHECK_NODE_EX(doc, "\n\t\n\tpremid\n\t\tpostfin\n\t\n\n", STR("\t"), format_indent); + CHECK_NODE(doc, STR("premidpostfin")); + CHECK_NODE_EX(doc, STR("\n\npremid\npostfin\n\n\n"), STR("\t"), 0); + CHECK_NODE_EX(doc, STR("\n\t\n\tpremid\n\t\tpostfin\n\t\n\n"), STR("\t"), format_indent); } -- cgit v1.2.3 From ce974094ace6a33d46d8dcc6ca66a6fcdc014bbd Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 21 Mar 2015 00:14:53 -0700 Subject: tests: Fix test compilation Rename PAGE_SIZE to page_size to avoid define conflict with Android SDK. Minor fixes in several tests. --- tests/allocator.cpp | 24 ++++++++++++------------ tests/test_header_only.cpp | 3 +++ tests/test_write.cpp | 2 +- 3 files changed, 16 insertions(+), 13 deletions(-) (limited to 'tests') diff --git a/tests/allocator.cpp b/tests/allocator.cpp index 74bbf10..8ca0963 100644 --- a/tests/allocator.cpp +++ b/tests/allocator.cpp @@ -23,11 +23,11 @@ namespace { - const size_t PAGE_SIZE = 4096; + const size_t page_size = 4096; size_t align_to_page(size_t value) { - return (value + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); + return (value + page_size - 1) & ~(page_size - 1); } void* allocate_page_aligned(size_t size) @@ -36,7 +36,7 @@ namespace // We can't use malloc because of occasional problems with CW on CRT termination static HANDLE heap = HeapCreate(0, 0, 0); - void* result = HeapAlloc(heap, 0, size + PAGE_SIZE); + void* result = HeapAlloc(heap, 0, size + page_size); return reinterpret_cast(align_to_page(reinterpret_cast(result))); } @@ -45,13 +45,13 @@ namespace { size_t aligned_size = align_to_page(size); - void* ptr = allocate_page_aligned(aligned_size + PAGE_SIZE); + void* ptr = allocate_page_aligned(aligned_size + page_size); if (!ptr) return 0; char* end = static_cast(ptr) + aligned_size; DWORD old_flags; - VirtualProtect(end, PAGE_SIZE, PAGE_NOACCESS, &old_flags); + VirtualProtect(end, page_size, PAGE_NOACCESS, &old_flags); return end - size; } @@ -63,7 +63,7 @@ namespace void* rptr = static_cast(ptr) + size - aligned_size; DWORD old_flags; - VirtualProtect(rptr, aligned_size + PAGE_SIZE, PAGE_NOACCESS, &old_flags); + VirtualProtect(rptr, aligned_size + page_size, PAGE_NOACCESS, &old_flags); } } #elif defined(__APPLE__) || defined(__linux__) @@ -71,28 +71,28 @@ namespace namespace { - const size_t PAGE_SIZE = 4096; + const size_t page_size = 4096; size_t align_to_page(size_t value) { - return (value + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); + return (value + page_size - 1) & ~(page_size - 1); } void* allocate_page_aligned(size_t size) { - return mmap(0, size + PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); + return mmap(0, size + page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); } void* allocate(size_t size) { size_t aligned_size = align_to_page(size); - void* ptr = allocate_page_aligned(aligned_size + PAGE_SIZE); + void* ptr = allocate_page_aligned(aligned_size + page_size); if (!ptr) return 0; char* end = static_cast(ptr) + aligned_size; - int res = mprotect(end, PAGE_SIZE, PROT_NONE); + int res = mprotect(end, page_size, PROT_NONE); assert(res == 0); (void)!res; @@ -105,7 +105,7 @@ namespace void* rptr = static_cast(ptr) + size - aligned_size; - int res = mprotect(rptr, aligned_size + PAGE_SIZE, PROT_NONE); + int res = mprotect(rptr, aligned_size + page_size, PROT_NONE); assert(res == 0); (void)!res; } diff --git a/tests/test_header_only.cpp b/tests/test_header_only.cpp index f1990dd..17cafca 100644 --- a/tests/test_header_only.cpp +++ b/tests/test_header_only.cpp @@ -12,5 +12,8 @@ TEST(header_only) xml_document doc; CHECK(doc.load_string(STR(""))); CHECK_STRING(doc.first_child().name(), STR("node")); + +#ifndef PUGIXML_NO_XPATH CHECK(doc.first_child() == doc.select_node(STR("//*")).node()); +#endif } diff --git a/tests/test_write.cpp b/tests/test_write.cpp index 1528453..ad6c409 100644 --- a/tests/test_write.cpp +++ b/tests/test_write.cpp @@ -123,7 +123,7 @@ TEST(write_pi_invalid) node.set_name(STR("test")); node.set_value(STR("?")); - CHECK_NODE(doc, STR("")); + CHECK_NODE(doc, STR("")); node.set_value(STR("?>")); -- cgit v1.2.3 From 250b690a546f296fa480cf61ad796a36b66a78c6 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 21 Mar 2015 01:05:31 -0700 Subject: tests: Work around fp issues in various runtime libraries Disable/change some tests for some compilers; use binary float comparison for early MSVC versions. --- tests/test_dom_modify.cpp | 65 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 11 deletions(-) (limited to 'tests') diff --git a/tests/test_dom_modify.cpp b/tests/test_dom_modify.cpp index 5167358..c06c141 100644 --- a/tests/test_dom_modify.cpp +++ b/tests/test_dom_modify.cpp @@ -5,6 +5,10 @@ #include +#ifdef __BORLANDC__ +using std::ldexpf; +#endif + TEST_XML(dom_attr_assign, "") { xml_node node = doc.child(STR("node")); @@ -101,15 +105,28 @@ TEST_XML(dom_attr_set_value_llong, "") } #endif -TEST_XML(dom_attr_assign_large_number, "") +TEST_XML(dom_attr_assign_large_number_float, "") { xml_node node = doc.child(STR("node")); - node.attribute(STR("attr1")) = std::numeric_limits::max(); - node.attribute(STR("attr2")) = std::numeric_limits::max(); + node.attribute(STR("attr")) = std::numeric_limits::max(); - CHECK(test_node(node, STR(""), STR(""), pugi::format_raw) || - test_node(node, STR(""), STR(""), pugi::format_raw)); + CHECK(test_node(node, STR(""), STR(""), pugi::format_raw) || + test_node(node, STR(""), STR(""), pugi::format_raw)); +} + +TEST_XML(dom_attr_assign_large_number_double, "") +{ + xml_node node = doc.child(STR("node")); + + node.attribute(STR("attr")) = std::numeric_limits::max(); + + // Borland C does not print double values with enough precision +#ifdef __BORLANDC__ + CHECK_NODE(node, STR("")); +#else + CHECK_NODE(node, STR("")); +#endif } TEST_XML(dom_node_set_name, "text") @@ -1447,6 +1464,17 @@ TEST(dom_node_copy_declaration_empty_name) CHECK_STRING(decl2.name(), STR("")); } +template bool fp_equal(T lhs, T rhs) +{ + // Several compilers compare float/double values on x87 stack without proper rounding + // This causes roundtrip tests to fail, although they correctly preserve the data. +#if (defined(_MSC_VER) && _MSC_VER < 1400) + return memcmp(&lhs, &rhs, sizeof(T)) == 0; +#else + return lhs == rhs; +#endif +} + TEST(dom_fp_roundtrip_min_max) { xml_document doc; @@ -1454,16 +1482,16 @@ TEST(dom_fp_roundtrip_min_max) xml_attribute attr = node.append_attribute(STR("attr")); node.text().set(std::numeric_limits::min()); - CHECK(node.text().as_float() == std::numeric_limits::min()); + CHECK(fp_equal(node.text().as_float(), std::numeric_limits::min())); attr.set_value(std::numeric_limits::max()); - CHECK(attr.as_float() == std::numeric_limits::max()); + CHECK(fp_equal(attr.as_float(), std::numeric_limits::max())); attr.set_value(std::numeric_limits::min()); - CHECK(attr.as_double() == std::numeric_limits::min()); + CHECK(fp_equal(attr.as_double(), std::numeric_limits::min())); node.text().set(std::numeric_limits::max()); - CHECK(node.text().as_double() == std::numeric_limits::max()); + CHECK(fp_equal(node.text().as_double(), std::numeric_limits::max())); } const double fp_roundtrip_base[] = @@ -1487,11 +1515,13 @@ TEST(dom_fp_roundtrip_float) float value = ldexpf(static_cast(fp_roundtrip_base[i]), e); doc.text().set(value); - CHECK(doc.text().as_float() == value); + CHECK(fp_equal(doc.text().as_float(), value)); } } } +// Borland C does not print double values with enough precision +#ifndef __BORLANDC__ TEST(dom_fp_roundtrip_double) { xml_document doc; @@ -1500,10 +1530,23 @@ TEST(dom_fp_roundtrip_double) { for (size_t i = 0; i < sizeof(fp_roundtrip_base) / sizeof(fp_roundtrip_base[0]); ++i) { + #if defined(_MSC_VER) && _MSC_VER < 1400 + // Not all runtime libraries guarantee roundtripping for denormals + if (e == -1021 && fp_roundtrip_base[i] < 0.5) + continue; + #endif + + #ifdef __DMC__ + // Digital Mars C does not roundtrip on exactly one combination + if (e == -12 && i == 1) + continue; + #endif + double value = ldexp(fp_roundtrip_base[i], e); doc.text().set(value); - CHECK(doc.text().as_double() == value); + CHECK(fp_equal(doc.text().as_double(), value)); } } } +#endif -- cgit v1.2.3 From 5959a179679f1a5680a089ddec6d2466432b8541 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sat, 21 Mar 2015 17:09:42 -0700 Subject: tests: Final test fix for CW --- tests/test_dom_modify.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tests') diff --git a/tests/test_dom_modify.cpp b/tests/test_dom_modify.cpp index c06c141..fa50112 100644 --- a/tests/test_dom_modify.cpp +++ b/tests/test_dom_modify.cpp @@ -4,6 +4,7 @@ #include #include +#include #ifdef __BORLANDC__ using std::ldexpf; @@ -1468,7 +1469,7 @@ template bool fp_equal(T lhs, T rhs) { // Several compilers compare float/double values on x87 stack without proper rounding // This causes roundtrip tests to fail, although they correctly preserve the data. -#if (defined(_MSC_VER) && _MSC_VER < 1400) +#if (defined(_MSC_VER) && _MSC_VER < 1400) || defined(__MWERKS__) return memcmp(&lhs, &rhs, sizeof(T)) == 0; #else return lhs == rhs; @@ -1530,7 +1531,7 @@ TEST(dom_fp_roundtrip_double) { for (size_t i = 0; i < sizeof(fp_roundtrip_base) / sizeof(fp_roundtrip_base[0]); ++i) { - #if defined(_MSC_VER) && _MSC_VER < 1400 + #if (defined(_MSC_VER) && _MSC_VER < 1400) || defined(__MWERKS__) // Not all runtime libraries guarantee roundtripping for denormals if (e == -1021 && fp_roundtrip_base[i] < 0.5) continue; -- cgit v1.2.3 From f1d15342102f7cb9741489901787148fd62844d0 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Fri, 10 Apr 2015 20:38:47 -0700 Subject: Fix archive packaging Base directory is now using target basename. --- tests/archive.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/archive.pl b/tests/archive.pl index 0a03b23..76484f7 100644 --- a/tests/archive.pl +++ b/tests/archive.pl @@ -2,11 +2,12 @@ use Archive::Tar; use Archive::Zip; +use File::Basename; my $target = shift @ARGV; my @sources = @ARGV; -my $basedir = ($target =~ /^(.*)(\.zip|\.tar.gz|\.tgz)$/) ? "$1/" : ''; +my $basedir = basename($target, ('.zip', '.tar.gz', '.tgz')) . '/'; my $zip = $target =~ /\.zip$/; my $arch = $zip ? Archive::Zip->new : Archive::Tar->new; -- cgit v1.2.3