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 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) (limited to 'tests/test_write.cpp') 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); } -- 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/test_write.cpp') 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/test_write.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tests/test_write.cpp') 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