diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:48:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:48:59 +0000 |
commit | c484829272cd13a738e35412498e12f2c9a194ac (patch) | |
tree | a1f5ec09629ee895bd3963fa8820b45f2f4c574b /src/orcus_test_xml.cpp | |
parent | Initial commit. (diff) | |
download | liborcus-upstream/0.19.2.tar.xz liborcus-upstream/0.19.2.zip |
Adding upstream version 0.19.2.upstream/0.19.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/orcus_test_xml.cpp')
-rw-r--r-- | src/orcus_test_xml.cpp | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/src/orcus_test_xml.cpp b/src/orcus_test_xml.cpp new file mode 100644 index 0000000..eb6bc95 --- /dev/null +++ b/src/orcus_test_xml.cpp @@ -0,0 +1,226 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "orcus/sax_ns_parser.hpp" +#include "orcus/dom_tree.hpp" +#include "orcus/xml_namespace.hpp" +#include "orcus/stream.hpp" + +#include <cstdlib> +#include <cassert> +#include <iostream> +#include <sstream> + +using namespace orcus; +using namespace std; + +class sax_handler_encoded_attrs +{ + std::vector<sax::parser_attribute> m_attrs; + +public: + void doctype(const sax::doctype_declaration&) {} + + void start_declaration(std::string_view) {} + + void end_declaration(std::string_view) + { + m_attrs.clear(); + } + + void start_element(const sax::parser_element&) {} + + void end_element(const sax::parser_element&) {} + + void characters(std::string_view, bool) {} + + void attribute(const sax::parser_attribute& attr) + { + m_attrs.push_back(attr); + } + + bool check(const vector<string>& expected) const + { + if (m_attrs.size() != expected.size()) + { + cerr << "unexpected attribute count." << endl; + return false; + } + + for (size_t i = 0, n = m_attrs.size(); i < n; ++i) + { + if (m_attrs[i].value != expected[i].c_str()) + { + cerr << "expected attribute value: " << expected[i] << " actual attribute value: " << m_attrs[i].value << endl; + return false; + } + } + + return true; + } +}; + +const char* sax_parser_test_dirs[] = { + SRCDIR"/test/xml/simple/", + SRCDIR"/test/xml/encoded-char/", + SRCDIR"/test/xml/default-ns/", + SRCDIR"/test/xml/ns-alias-1/", + SRCDIR"/test/xml/bom/", + SRCDIR"/test/xml/custom-decl-1/", + SRCDIR"/test/xml/cdata-1/", + SRCDIR"/test/xml/single-quote/", + SRCDIR"/test/xml/no-decl-1/", + SRCDIR"/test/xml/underscore-identifier/", + SRCDIR"/test/xml/self-closing-root/", + SRCDIR"/test/xml/utf8-1/", + SRCDIR"/test/xml/utf8-2/", +}; + +const char* sax_parser_parse_only_test_dirs[] = { + SRCDIR"/test/xml/parse-only/rss/" +}; + +void parse_file(dom::document_tree& tree, const char* filepath, std::string& /*strm*/) +{ + cout << "testing " << filepath << endl; + file_content content(filepath); + assert(!content.empty()); + + tree.load(content.str()); +} + +void test_xml_sax_parser() +{ + string strm; + size_t n = sizeof(sax_parser_test_dirs)/sizeof(sax_parser_test_dirs[0]); + for (size_t i = 0; i < n; ++i) + { + const char* dir = sax_parser_test_dirs[i]; + string dir_path(dir); + string file = dir_path; + file.append("input.xml"); + + xmlns_repository repo; + xmlns_context cxt = repo.create_context(); + dom::document_tree tree(cxt); + parse_file(tree, file.c_str(), strm); + + // Get the compact form of the content. + ostringstream os; + tree.dump_compact(os); + string content = os.str(); + + // Load the check form. + file = dir_path; + file.append("check.txt"); + file_content check(file.data()); + std::string_view psource(content); + std::string_view pcheck = check.str(); + + // They must be equal, minus preceding or trailing spaces (if any). + assert(trim(psource) == trim(pcheck)); + } +} + +void test_xml_sax_parser_read_only() +{ + string strm; + size_t n = sizeof(sax_parser_parse_only_test_dirs)/sizeof(sax_parser_parse_only_test_dirs[0]); + for (size_t i = 0; i < n; ++i) + { + const char* dir = sax_parser_parse_only_test_dirs[i]; + string dir_path(dir); + string file = dir_path; + file.append("input.xml"); + + xmlns_repository repo; + xmlns_context cxt = repo.create_context(); + dom::document_tree tree(cxt); + parse_file(tree, file.c_str(), strm); + } +} + +void test_xml_declarations() +{ + string strm; + const char* file_path = SRCDIR"/test/xml/custom-decl-1/input.xml"; + xmlns_repository repo; + xmlns_context cxt = repo.create_context(); + dom::document_tree dom(cxt); + parse_file(dom, file_path, strm); + + // Make sure we parse the custom declaration correctly. + dom::const_node decl = dom.declaration("mso-application"); + assert(decl.type() == dom::node_t::declaration); + assert(decl.attribute("progid") == "Excel.Sheet"); +} + +void test_xml_dtd() +{ + struct { + const char* file_path; + sax::doctype_declaration::keyword_type keyword; + const char* root_element; + const char* fpi; + const char* uri; + } tests[] = { + { SRCDIR"/test/xml/doctype/html.xml", sax::doctype_declaration::keyword_type::dtd_public, + "html", "-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" } + }; + + xmlns_repository repo; + size_t n = sizeof(tests)/sizeof(tests[0]); + + for (size_t i = 0; i < n; ++i) + { + const char* file_path = tests[i].file_path; + string strm; + xmlns_context cxt = repo.create_context(); + dom::document_tree dom(cxt); + parse_file(dom, file_path, strm); + const sax::doctype_declaration* dtd = dom.get_doctype(); + assert(dtd); + assert(dtd->keyword == tests[i].keyword); + assert(dtd->root_element == tests[i].root_element); + assert(dtd->fpi == tests[i].fpi); + if (tests[i].uri) + { + assert(dtd->uri == tests[i].uri); + } + } +} + +void test_xml_encoded_attrs() +{ + const char* filepath = SRCDIR"/test/xml/encoded-attrs/test1.xml"; + + cout << "testing " << filepath << endl; + file_content content(filepath); + assert(!content.empty()); + + sax_handler_encoded_attrs hdl; + sax_parser<sax_handler_encoded_attrs> parser(content.str(), hdl); + parser.parse(); + + vector<string> expected; + expected.push_back("1 & 2"); + expected.push_back("3 & 4"); + expected.push_back("5 & 6"); + assert(hdl.check(expected)); +} + +int main() +{ + test_xml_sax_parser(); + test_xml_sax_parser_read_only(); + test_xml_declarations(); + test_xml_dtd(); + test_xml_encoded_attrs(); + + return EXIT_SUCCESS; +} +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |