14#include <libxml/xpath.h>
15#include <libxml/parser.h>
24#include <cppunit/TestAssert.h>
38 : elementName(
nullptr)
45 tolerance(
const tolerance& tol)
47 elementName = xmlStrdup(tol.elementName);
48 attribName = xmlStrdup(tol.attribName);
49 relative = tol.relative;
57 bool operator<(
const tolerance& rTol)
const
59 int cmp = xmlStrcmp(elementName, rTol.elementName);
62 cmp = xmlStrcmp(attribName, rTol.attribName);
72 XMLDiff(
const char* pFileName,
const char* pContent,
int size,
const char* pToleranceFileName);
77 typedef std::set<tolerance> ToleranceContainer;
79 void loadToleranceFile(xmlDocPtr xmlTolerance);
80 bool compareAttributes(xmlNodePtr node1, xmlNodePtr node2);
81 bool compareElements(xmlNode* node1, xmlNode* node2);
84 void cppunitAssertEqual(
const xmlChar *expected,
const xmlChar *found);
87 void cppunitAssertEqualDouble(
const xmlNodePtr node,
const xmlAttrPtr attr,
double expected,
double found,
double delta);
89 ToleranceContainer toleranceContainer;
97XMLDiff::XMLDiff(
const char* pFileName,
const char* pContent,
int size,
const char* pToleranceFile)
98 : xmlFile1(xmlParseFile(pFileName))
99 , xmlFile2(xmlParseMemory(pContent,
size))
100 , fileName(pFileName)
104 xmlDocPtr xmlToleranceFile = xmlParseFile(pToleranceFile);
105 loadToleranceFile(xmlToleranceFile);
106 xmlFreeDoc(xmlToleranceFile);
112 xmlFreeDoc(xmlFile1);
113 xmlFreeDoc(xmlFile2);
118void readAttributesForTolerance(xmlNodePtr node, tolerance& tol)
120 xmlChar* elementName = xmlGetProp(node, BAD_CAST(
"elementName"));
121 tol.elementName = elementName;
123 xmlChar* attribName = xmlGetProp(node, BAD_CAST(
"attribName"));
124 tol.attribName = attribName;
126 xmlChar*
value = xmlGetProp(node, BAD_CAST(
"value"));
127 double val = xmlXPathCastStringToNumber(value);
131 xmlChar* relative = xmlGetProp(node, BAD_CAST(
"relative"));
133 if(xmlStrEqual(relative, BAD_CAST(
"true")))
141void XMLDiff::loadToleranceFile(xmlDocPtr xmlToleranceFile)
143 xmlNodePtr root = xmlDocGetRootElement(xmlToleranceFile);
145 CPPUNIT_ASSERT_MESSAGE(
"did not find correct tolerance file", xmlStrEqual( root->name, BAD_CAST(
"tolerances") ));
147 if(!xmlStrEqual( root->name, BAD_CAST(
"tolerances") ))
153 xmlNodePtr child =
nullptr;
154 for (child = root->children; child !=
nullptr; child = child->next)
157 if(child->type != XML_ELEMENT_NODE)
160 assert(xmlStrEqual(child->name, BAD_CAST(
"tolerance")));
163 readAttributesForTolerance(child, tol);
164 toleranceContainer.insert(tol);
168bool XMLDiff::compare()
170 xmlNode* root1 = xmlDocGetRootElement(xmlFile1);
171 xmlNode* root2 = xmlDocGetRootElement(xmlFile2);
174 CPPUNIT_ASSERT(root1);
175 CPPUNIT_ASSERT(root2);
176 cppunitAssertEqual(root1->name, root2->name);
178 if (!root1 || !root2)
180 if(!xmlStrEqual(root1->name, root2->name))
183 return compareElements(root1, root2);
188bool checkForEmptyChildren(xmlNodePtr node)
193 for(; node !=
nullptr; node = node->next)
195 if (node->type == XML_ELEMENT_NODE)
203bool XMLDiff::compareElements(xmlNode* node1, xmlNode* node2)
206 cppunitAssertEqual(node1->name, node2->name);
208 if (!xmlStrEqual( node1->name, node2->name ))
213 bool sameAttribs = compareAttributes(node1, node2);
215 CPPUNIT_ASSERT(sameAttribs);
222 xmlNode* child2 =
nullptr;
223 xmlNode* child1 =
nullptr;
224 for(child1 = node1->children, child2 = node2->children; child1 !=
nullptr && child2 !=
nullptr; child1 = child1->next, child2 = child2->next)
226 if (child1->type == XML_ELEMENT_NODE)
228 bool bCompare = compareElements(child1, child2);
237 CPPUNIT_ASSERT(checkForEmptyChildren(child1));
238 CPPUNIT_ASSERT(checkForEmptyChildren(child2));
240 if(!checkForEmptyChildren(child1) || !checkForEmptyChildren(child2))
247void XMLDiff::cppunitAssertEqual(
const xmlChar *expected,
const xmlChar *found)
250 std::stringstream stringStream;
251 stringStream <<
"Reference: " << fileName <<
"\n- Expected: " <<
reinterpret_cast<const char*
>(expected) <<
"\n- Found: " <<
reinterpret_cast<const char*
>(found);
253 CPPUNIT_ASSERT_MESSAGE(stringStream.str(), xmlStrEqual(expected, found));
257void XMLDiff::cppunitAssertEqualDouble(
const xmlNodePtr node,
const xmlAttrPtr attr,
double expected,
double found,
double delta)
260 xmlChar * path = xmlGetNodePath(node);
261 std::stringstream stringStream;
262 stringStream <<
"Reference: " << fileName <<
"\n- Node: " <<
reinterpret_cast<const char*
>(path) <<
"\n- Attr: " <<
reinterpret_cast<const char*
>(attr->name);
265 CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE(stringStream.str(), expected, found, delta);
271bool compareValuesWithTolerance(
double val1,
double val2,
double tolerance,
bool relative)
275 return (val1/tolerance) <= val2 && val2 <= (val1*tolerance);
279 return (val1 - tolerance) <= val2 && val2 <= (val1 + tolerance);
285bool XMLDiff::compareAttributes(xmlNodePtr node1, xmlNodePtr node2)
287 xmlAttrPtr attr1 =
nullptr;
288 xmlAttrPtr attr2 =
nullptr;
289 for(attr1 = node1->properties, attr2 = node2->properties; attr1 !=
nullptr && attr2 !=
nullptr; attr1 = attr1->next, attr2 = attr2->next)
292 cppunitAssertEqual(attr1->name, attr2->name);
294 if (!xmlStrEqual( attr1->name, attr2->name ))
298 xmlChar* val1 = xmlGetProp(node1, attr1->name);
299 xmlChar* val2 = xmlGetProp(node2, attr2->name);
301 double dVal1 = xmlXPathCastStringToNumber(val1);
302 double dVal2 = xmlXPathCastStringToNumber(val2);
304 if(!std::isnan(dVal1) || !std::isnan(dVal2))
308 tol.elementName = xmlStrdup(node1->name);
309 tol.attribName = xmlStrdup(attr1->name);
310 ToleranceContainer::iterator itr = toleranceContainer.find( tol );
311 bool useTolerance =
false;
312 if (itr != toleranceContainer.end())
319 bool valInTolerance = compareValuesWithTolerance(dVal1, dVal2, itr->value, itr->relative);
321 std::stringstream stringStream(
"Expected Value: ");
322 stringStream << dVal1 <<
"; Found Value: " << dVal2 <<
"; Tolerance: " << itr->value;
323 stringStream <<
"; Relative: " << itr->relative;
324 CPPUNIT_ASSERT_MESSAGE(stringStream.str(), valInTolerance);
333 cppunitAssertEqualDouble(node1, attr1, dVal1, dVal2, 1e-08);
344 cppunitAssertEqual(val1, val2);
346 if(!xmlStrEqual( val1, val2 ))
359 std::stringstream failStream;
360 failStream <<
"Unequal number of attributes in ";
362 std::vector<std::string> parents;
367 parents.push_back(std::string(
reinterpret_cast<const char *
>(
n->name)));
371 for (
auto it = parents.rbegin(); it != parents.rend(); ++it)
378 failStream <<
" Attr1: ";
379 attr1 = node1->properties;
380 while (attr1 !=
nullptr)
382 xmlChar* val1 = xmlGetProp(node1, attr1->name);
383 failStream << BAD_CAST(attr1->name) <<
"=" << BAD_CAST(val1) <<
", ";
388 failStream <<
" Attr2: ";
389 attr2 = node2->properties;
390 while (attr2 !=
nullptr)
392 xmlChar* val2 = xmlGetProp(node2, attr2->name);
393 failStream << BAD_CAST(attr2->name) <<
"=" << BAD_CAST(val2) <<
", ";
397 CPPUNIT_ASSERT_MESSAGE(failStream.str(),
false);
409doXMLDiff(
char const*
const pFileName,
char const*
const pContent,
int const size,
410 char const*
const pToleranceFileName)
412 XMLDiff aDiff(pFileName, pContent,
size, pToleranceFileName);
413 return aDiff.compare();
bool doXMLDiff(char const *const pFileName, char const *const pContent, int const size, char const *const pToleranceFileName)
constexpr OUStringLiteral first
SbxDecimal::CmpResult compare(SAL_UNUSED_PARAMETER const SbxDecimal &, SAL_UNUSED_PARAMETER const SbxDecimal &)
bool operator<(const wwFont &r1, const wwFont &r2)