CPPUnit Tests for this library. Binary should be installed as ui-gxmlcpp-test.
#include "config.h"
#include <sstream>
#include <fstream>
#include <iostream>
#include <ui-utilcpp/Text.hpp>
#ifdef WIN32
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
#else
#define BOOST_AUTO_TEST_MAIN
#define BOOST_TEST_DYN_LINK
#include <boost/test/auto_unit_test.hpp>
#include <boost/test/floating_point_comparison.hpp>
#endif
namespace GXML {
std::string randomString(std::string::size_type size)
{
time_t t;
::srand((unsigned) time(&t));
std::string result("");
for (std::string::size_type i(0); i < size; ++i)
{
char const c('a' + rand() % 26);
result += c;
}
return result;
}
class UnitTestsConf: public Conf
{
public:
UnitTestsConf()
{
setCustomLogging(true);
setEXSLT();
}
};
UnitTestsConf conf;
BOOST_AUTO_TEST_CASE(test_Tree_Constructors)
{
std::string tmpFolderPath;
#ifdef WIN32
char path[MAX_PATH];
::GetTempPath(MAX_PATH, path);
tmpFolderPath = path;
#else
tmpFolderPath = "/tmp/";
#endif
std::string fileName(tmpFolderPath + "__xyz__ui-gxmlcpp_XML-unit-test.xml");
{
std::ofstream file(fileName.c_str());
file << "<root/>";
}
std::stringstream stringStream("<root/>");
Tree buffer((char *) "<root/>garbage", 7);
Tree cstr((char *) "<root/>");
Tree str(std::string("<root/>"));
Tree sstream(stringStream);
Tree file(Tree::File_, fileName);
Tree tree(file);
tree = file;
BOOST_CHECK(tree == file);
::unlink(fileName.c_str());
}
BOOST_AUTO_TEST_CASE(test_Tree_Build)
{
std::string goal(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<root>"
"<tag attribute=\"aval\">tval</tag>"
"<after>afterVal</after>"
"<after>foo</after>"
"</root>\n");
tag.
setAttribute(
"attribute",
"aval");
BOOST_CHECK(tree.
dump() == goal);
}
BOOST_AUTO_TEST_CASE(test_Tree_Node_Read)
{
for (int c(0); c < 2; ++c)
{
std::string xml(
"<root>"
" <tag attr='attrcontent'>tagcontent</tag>"
"</root>");
Tree tree(xml);
tree.setContext(c == 0);
{
Tree::Node n(tree.getNode("/"));
BOOST_CHECK(n.getType() == XML_DOCUMENT_NODE);
BOOST_CHECK(n.getName() == "");
BOOST_CHECK(n.getContent() == "");
BOOST_CHECK(tree.getContent("/") == "");
}
{
Tree::Node n(tree.getNode("/root/tag"));
BOOST_CHECK(n.getType() == XML_ELEMENT_NODE);
BOOST_CHECK(n.getName() == "tag");
BOOST_CHECK(n.getContent() == "tagcontent");
BOOST_CHECK(n.getAttribute("attr") == "attrcontent");
BOOST_CHECK(tree.getContent("/root/tag") == "tagcontent");
BOOST_CHECK(tree.getContent("/root/tag/@attr") == "attrcontent");
}
{
Tree::Node n(tree.getNode("/root/tag/@attr"));
BOOST_CHECK(n.getType() == XML_ATTRIBUTE_NODE);
BOOST_CHECK(n.getName() == "attr");
BOOST_CHECK(n.getContent() == "attrcontent");
BOOST_CHECK(tree.getContent("/root/tag/@attr") == "attrcontent");
}
}
}
BOOST_AUTO_TEST_CASE(test_Tree_NodeSet_Read)
{
for (int c(0); c < 2; ++c)
{
std::string xml(
"<root>"
" <tag1 attr='attrcontent1'>tagcontent1</tag1>"
" <tag2 attr='attrcontent2'>tagcontent2</tag2>"
" <tag3 attr='attrcontent3'>tagcontent3</tag3>"
"</root>");
Tree tree(xml);
tree.setContext(c == 0);
{
BOOST_CHECK(tree.getNodeSet("/*").size() == 1);
BOOST_CHECK(tree.getNodeSet("/root/*").size() == 3);
BOOST_CHECK(tree.getNodeSet("/root/tag1").size() == 1);
}
{
Tree::NodeSet ns(tree.getNodeSet("/root/*"));
std::string cumContent("");
std::string cumAttr("");
for (Tree::NodeSet::const_iterator i(ns.begin()); i != ns.end(); ++i)
{
cumContent += (*i).getContent();
cumAttr += (*i).getAttribute("attr");
}
BOOST_CHECK(cumContent == "tagcontent1tagcontent2tagcontent3");
BOOST_CHECK(cumAttr == "attrcontent1attrcontent2attrcontent3");
}
}
}
BOOST_AUTO_TEST_CASE(test_Tree_Node_Write)
{
for (int c(0); c < 2; ++c)
{
std::string xml("<root/>");
Tree tree(xml);
tree.setContext(c == 0);
{
tree.addChild("/root", "tag", "tagcontent");
Tree::Node n1(tree.getNode("/root/tag"));
BOOST_CHECK(n1.getContent() == "tagcontent");
BOOST_CHECK(n1.getName() == "tag");
tree.setAttribute("/root/tag", "attr", "attrcontent");
BOOST_CHECK(tree.getContent("/root/tag/@attr") == "attrcontent");
BOOST_CHECK(tree.getAttribute("/root/tag", "attr") == "attrcontent");
tree.setName("/root/tag", "tux");
BOOST_CHECK(tree.getContent("/root/tux") == "tagcontent");
tree.setContent("/root/tux", "tuxcontent");
BOOST_CHECK(tree.getContent("/root/tux") == "tuxcontent");
tree.setAttribute("/root/tux", "attr", "tuxcontent");
BOOST_CHECK(tree.getContent("/root/tux/@attr") == "tuxcontent");
BOOST_CHECK(tree.getAttribute("/root/tux", "attr") == "tuxcontent");
}
}
}
BOOST_AUTO_TEST_CASE(test_Tree_Dump)
{
std::string xmlUTF8(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<root>"
"<tag attr=\"attrcontent1\">tagcontent1</tag>"
"<umlaute attr=\"öäü\">öäü</umlaute>"
"</root>\n");
std::string xmlLatin(
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
"<root>"
"<tag attr=\"attrcontent1\">tagcontent1</tag>"
"<umlaute attr=\"öäü\">öäü</umlaute>"
"</root>\n");
{
Tree t(xmlUTF8);
BOOST_CHECK(Tree::Dump(t, false, "UTF-8").get() == xmlUTF8);
}
{
Tree t(xmlUTF8);
BOOST_CHECK(Tree::Dump(t, false, "ISO-8859-1").get() == xmlLatin);
}
{
Tree t(xmlLatin);
BOOST_CHECK(Tree::Dump(t, false, "UTF-8").get() == xmlUTF8);
}
}
BOOST_AUTO_TEST_CASE(Tree_Node_Dump)
{
std::string header("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
std::string tag1("<tag attr=\"attr1\">pos1</tag>");
std::string tag2("<tag attr=\"attr2\">pos2</tag>");
std::string tag3("<tag>öäü</tag>");
std::string tag4("<tag>" + randomString(5000) + "</tag>");
std::string xml("<root>" + tag1 + tag2 + tag3 + tag4 + "</root>");
std::string xmlDoc(header + xml);
{
Tree const tree(xmlDoc);
{
Tree::Node n(tree.getNode("/root"));
BOOST_CHECK(n.dump() == xml);
}
{
Tree::Node n(tree.getNode("/root/tag[position()=2]"));
BOOST_CHECK(n.dump() == tag2);
}
{
Tree::NodeSet ns(tree.getNodeSet("/root/*"));
BOOST_CHECK(ns.dump() == tag1 + tag2 + tag3 + tag4);
}
{
Tree::Node n(tree.getNode("/root/tag[position()=1]/@attr"));
BOOST_CHECK(n.dump() == " attr=\"attr1\"");
}
{
Tree::NodeSet ns(tree.getNodeSet("/root/tag/@attr"));
BOOST_CHECK(ns.dump() == " attr=\"attr1\" attr=\"attr2\"");
}
{
Tree::Node n(tree.getNode("/root/tag[position()=3]"));
BOOST_CHECK(n.dump() == tag3);
}
{
Tree::Node n(tree.getNode("/root/tag[position()=4]"));
BOOST_CHECK(n.dump() == tag4);
}
}
}
BOOST_AUTO_TEST_CASE(test_xsl_translation)
{
std::string xmlUTF8NoHeader(
"<root>"
"<tag attr=\"attrcontent\">tagcontent</tag>"
"<umlaute attr=\"öäü\">öäü</umlaute>"
"</root>\n");
std::string xmlUTF8(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ xmlUTF8NoHeader);
std::string xmlLatin(
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
"<root>"
"<tag attr=\"attrcontent\">tagcontent</tag>"
"<umlaute attr=\"öäü\">öäü</umlaute>"
"</root>\n");
std::string xslIDSnippet(
"<xsl:template match=\"@*|node()\">"
" <xsl:copy>"
" <xsl:apply-templates select=\"@*|node()\"/>"
" </xsl:copy>"
"</xsl:template>");
std::string xsl_to_XML_UTF8(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
""
"<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">"
""
"<xsl:output method=\"xml\" encoding=\"UTF-8\" />"
""
+ xslIDSnippet +
""
"</xsl:stylesheet>");
std::string xsl_to_XML_LATIN(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
""
"<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">"
""
"<xsl:output method=\"xml\" encoding=\"ISO-8859-1\" />"
""
+ xslIDSnippet +
""
"</xsl:stylesheet>");
std::string xsl_to_HTML_UTF8(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
""
"<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">"
""
"<xsl:output method=\"html\" encoding=\"UTF-8\" />"
""
+ xslIDSnippet +
""
"</xsl:stylesheet>");
conf.setKeepBlanks(true);
{
Tree xmlTree(xmlUTF8);
XSLTree xslTree(xsl_to_XML_UTF8);
XSLTransTree xslTransTree(xslTree, xmlTree);
XSLTransTree::Dump dump(xslTransTree);
BOOST_CHECK(dump.getEncoding() == "UTF-8");
BOOST_CHECK(dump.get() == xmlUTF8);
}
{
Tree xmlTree(xmlUTF8);
XSLTree xslTree(xsl_to_XML_LATIN);
XSLTransTree xslTransTree(xslTree, xmlTree);
XSLTransTree::Dump dump(xslTransTree);
BOOST_CHECK(dump.getEncoding() == "ISO-8859-1");
BOOST_CHECK(dump.get() == xmlLatin);
}
{
Tree xmlTree(xmlLatin);
XSLTree xslTree(xsl_to_XML_UTF8);
XSLTransTree xslTransTree(xslTree, xmlTree);
XSLTransTree::Dump dump(xslTransTree);
BOOST_CHECK(dump.getEncoding() == "UTF-8");
BOOST_CHECK(dump.get() == xmlUTF8);
}
{
Tree xmlTree(xmlLatin);
XSLTree xslTree(xsl_to_HTML_UTF8);
XSLTransTree xslTransTree(xslTree, xmlTree);
XSLTransTree::Dump dump(xslTransTree);
BOOST_CHECK(dump.getEncoding() == "UTF-8");
BOOST_CHECK(dump.get() == xmlUTF8NoHeader);
}
conf.setKeepBlanks(false);
}
BOOST_AUTO_TEST_CASE(test_xmlschema_validation)
{
std::string schema(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
""
"<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"
" <xsd:element name=\"root\" type=\"xsd:string\"/>"
"</xsd:schema>");
std::string validXml(
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
"<root>text</root>\n");
std::string invalidXml(
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
"<root><subtag/></root>\n");
SchemaTree schemaTree(schema);
Tree validTree(validXml);
Tree invalidTree(invalidXml);
BOOST_CHECK(schemaTree.isValid(validTree));
conf.setCustomLoggingEnable(false);
BOOST_CHECK(!schemaTree.isValid(invalidTree));
conf.setCustomLoggingEnable(true);
BOOST_CHECK(schemaTree.isValid(validTree));
}
BOOST_AUTO_TEST_CASE(test_relaxng_validation)
{
std::string relaxNG(
"<element name='root' xmlns='http://relaxng.org/ns/structure/1.0'>"
" <zeroOrMore>"
" <element name='item'>"
" <element name='id'>"
" <text/>"
" </element>"
" </element>"
" </zeroOrMore>"
"</element>");
std::string validXml(
"<?xml version='1.0' encoding='UTF-8'?>\n"
"<root>"
" <item>"
" <id>1234</id>"
" </item>"
" <item>"
" <id>5678</id>"
" </item>"
"</root>");
std::string invalidXml(
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
"<root>"
" <item>"
" <ERROR>error</ERROR>"
" </item>"
"</root>");
RelaxNGTree relaxNGTree(relaxNG);
Tree validTree(validXml);
Tree invalidTree(invalidXml);
BOOST_CHECK(relaxNGTree.isValid(validTree));
conf.setCustomLoggingEnable(false);
BOOST_CHECK(!relaxNGTree.isValid(invalidTree));
conf.setCustomLoggingEnable(true);
}
BOOST_AUTO_TEST_CASE(test_internal_encoding)
{
std::string none(
"<?xml version='1.0'?>"
"<root/>");
std::string utf8(
"<?xml version='1.0' encoding='UTF-8'?>"
"<root/>");
std::string iso(
"<?xml version='1.0' encoding='ISO-8859-1'?>"
"<root/>");
Tree noneTree(none);
Tree utf8Tree(utf8);
Tree isoTree(iso);
BOOST_CHECK(noneTree.getOrigEncoding() == "");
BOOST_CHECK(utf8Tree.getOrigEncoding() == "UTF-8");
BOOST_CHECK(isoTree.getOrigEncoding() == "ISO-8859-1");
}
BOOST_AUTO_TEST_CASE(test_context)
{
Tree tree(
"<?xml version='1.0'?>"
"<root>"
"<sub name='x'>x</sub>"
"<sub name='X'>X</sub>"
"</root>");
Tree::Node node(tree.getNode("/root"));
BOOST_CHECK(node.getName() == "root");
Tree::Node sub1(node.getNode("sub[@name='x']"));
BOOST_CHECK(sub1.getName() == "sub" && sub1.getAttribute("name") == "x" && sub1.getContent() == "x");
Tree::Node sub2(node.getNode("sub[@name='X']"));
BOOST_CHECK(sub2.getName() == "sub" && sub2.getAttribute("name") == "X" && sub2.getContent() == "X");
}
}}