xlnt/tests/helpers/xml_helper.hpp

166 lines
4.5 KiB
C++
Raw Normal View History

2014-06-05 06:42:17 +08:00
#pragma once
#include <pugixml.hpp>
2014-06-05 06:42:17 +08:00
#include <sstream>
2014-06-06 04:19:31 +08:00
#include "path_helper.hpp"
2014-06-05 06:42:17 +08:00
class xml_helper
2014-06-05 06:42:17 +08:00
{
public:
2014-07-20 02:43:48 +08:00
enum class difference_type
2014-06-05 06:42:17 +08:00
{
2014-07-20 02:43:48 +08:00
names_differ,
missing_attribute,
attribute_values_differ,
missing_text,
text_values_differ,
missing_child,
child_order_differs,
equivalent,
};
struct comparison_result
{
difference_type difference;
2015-11-11 08:46:57 +08:00
std::string value_left;
std::string value_right;
operator bool() const
{
return difference == difference_type::equivalent;
}
2014-07-20 02:43:48 +08:00
};
2016-08-03 12:12:18 +08:00
static bool documents_match(const pugi::xml_document &expected,
const pugi::xml_document &observed)
2015-10-31 06:54:04 +08:00
{
2016-08-03 12:12:18 +08:00
auto result = compare_xml_nodes(expected.root(), observed.root());
if (!result)
{
std::cout << "documents don't match" << std::endl;
std::cout << "expected:" << std::endl;
expected.save(std::cout);
std::cout << std::endl;
std::cout << "observed:" << std::endl;
observed.save(std::cout);
std::cout << std::endl;
return false;
}
return true;
2015-10-31 06:54:04 +08:00
}
2016-08-03 12:12:18 +08:00
static bool file_matches_document(const xlnt::path &expected,
const pugi::xml_document &observed)
{
return string_matches_document(expected.read_contents(), observed);
}
2015-11-03 03:22:13 +08:00
2016-08-03 12:12:18 +08:00
static bool string_matches_document(const std::string &expected_string,
const pugi::xml_document &observed_document)
{
pugi::xml_document expected_document;
expected_document.load(expected_string.c_str());
2016-05-12 07:24:53 +08:00
2016-08-03 12:12:18 +08:00
return documents_match(expected_document, observed_document);
}
2016-08-03 12:12:18 +08:00
static bool strings_match(const std::string &expected_string, const std::string &observed_string)
{
pugi::xml_document left_xml;
2016-08-03 12:12:18 +08:00
left_xml.load(expected_string.c_str());
2015-11-03 03:22:13 +08:00
pugi::xml_document right_xml;
2016-08-03 12:12:18 +08:00
right_xml.load(observed_string.c_str());
2015-11-03 03:22:13 +08:00
2016-08-03 12:12:18 +08:00
return documents_match(left_xml, right_xml);
2015-10-14 12:03:48 +08:00
}
2016-08-03 12:12:18 +08:00
static comparison_result compare_xml_nodes(const pugi::xml_node &left, const pugi::xml_node &right)
2014-07-20 02:43:48 +08:00
{
std::string left_temp = left.name();
std::string right_temp = right.name();
2014-07-20 02:43:48 +08:00
if(left_temp != right_temp)
2014-07-17 07:53:45 +08:00
{
2014-07-20 02:43:48 +08:00
return {difference_type::names_differ, left_temp, right_temp};
2014-07-17 07:53:45 +08:00
}
2014-07-20 02:43:48 +08:00
for(auto &left_attribute : left.attributes())
2014-07-17 07:53:45 +08:00
{
left_temp = left_attribute.name();
if(!right.attribute(left_attribute.name()))
2014-07-20 02:43:48 +08:00
{
return {difference_type::missing_attribute, left_temp, "((empty))"};
}
left_temp = left_attribute.name();
right_temp = right.attribute(left_attribute.name()).name();
2014-07-20 02:43:48 +08:00
if(left_temp != right_temp)
{
return {difference_type::attribute_values_differ, left_temp, right_temp};
}
2014-07-17 07:53:45 +08:00
}
2014-07-20 02:43:48 +08:00
if(left.text())
2014-07-20 02:43:48 +08:00
{
left_temp = left.text().get();
2014-07-20 02:43:48 +08:00
if(!right.text())
2014-07-20 02:43:48 +08:00
{
return {difference_type::missing_text, left_temp, "((empty))"};
}
right_temp = right.text().get();
2014-07-20 02:43:48 +08:00
if(left_temp != right_temp)
{
return {difference_type::text_values_differ, left_temp, right_temp};
}
}
else if(right.text())
2014-07-20 02:43:48 +08:00
{
right_temp = right.text().get();
2014-07-20 02:43:48 +08:00
return {difference_type::text_values_differ, "((empty))", right_temp};
}
auto right_children = right.children();
2015-10-31 06:54:04 +08:00
auto right_child_iter = right_children.begin();
for(auto left_child : left.children())
2014-07-20 02:43:48 +08:00
{
left_temp = left_child.name();
2014-07-20 02:43:48 +08:00
2015-10-31 06:54:04 +08:00
if(right_child_iter == right_children.end())
2014-07-20 02:43:48 +08:00
{
return {difference_type::child_order_differs, left_temp, "((end))"};
}
auto right_child = *right_child_iter;
right_child_iter++;
2016-08-03 12:12:18 +08:00
auto child_comparison_result = compare_xml_nodes(left_child, right_child);
2014-07-20 02:43:48 +08:00
if(!child_comparison_result)
{
return child_comparison_result;
}
}
2015-10-31 06:54:04 +08:00
if(right_child_iter != right_children.end())
2014-07-20 02:43:48 +08:00
{
right_temp = right_child_iter->name();
2014-07-20 02:43:48 +08:00
return {difference_type::child_order_differs, "((end))", right_temp};
}
return {difference_type::equivalent, "", ""};
}
2014-06-05 06:42:17 +08:00
};