X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1de532f57e9a7d25158edb8aed633fb1099a04ea..eceb6af1586b7ec760bcbc1aca01ca59e4cd1711:/tests/xml/xmltest.cpp diff --git a/tests/xml/xmltest.cpp b/tests/xml/xmltest.cpp index 96f812b600..ee41451a38 100644 --- a/tests/xml/xmltest.cpp +++ b/tests/xml/xmltest.cpp @@ -22,6 +22,8 @@ #endif // WX_PRECOMP #include "wx/xml/xml.h" +#include "wx/scopedptr.h" +#include "wx/sstream.h" #include @@ -32,7 +34,7 @@ namespace { -void CheckXml(wxXmlNode *n, ...) +void CheckXml(const wxXmlNode *n, ...) { va_list args; va_start(args, n); @@ -73,10 +75,24 @@ private: CPPUNIT_TEST_SUITE( XmlTestCase ); CPPUNIT_TEST( InsertChild ); CPPUNIT_TEST( InsertChildAfter ); + CPPUNIT_TEST( LoadSave ); + CPPUNIT_TEST( CDATA ); + CPPUNIT_TEST( PI ); + CPPUNIT_TEST( Escaping ); + CPPUNIT_TEST( DetachRoot ); + CPPUNIT_TEST( AppendToProlog ); + CPPUNIT_TEST( SetRoot ); CPPUNIT_TEST_SUITE_END(); void InsertChild(); void InsertChildAfter(); + void LoadSave(); + void CDATA(); + void PI(); + void Escaping(); + void DetachRoot(); + void AppendToProlog(); + void SetRoot(); DECLARE_NO_COPY_CLASS(XmlTestCase) }; @@ -84,49 +100,372 @@ private: // register in the unnamed registry so that these tests are run by default CPPUNIT_TEST_SUITE_REGISTRATION( XmlTestCase ); -// also include in it's own registry so that these tests can be run alone +// also include in its own registry so that these tests can be run alone CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( XmlTestCase, "XmlTestCase" ); void XmlTestCase::InsertChild() { - wxXmlNode *root = new wxXmlNode(wxXML_ELEMENT_NODE, "root"); + wxScopedPtr root(new wxXmlNode(wxXML_ELEMENT_NODE, "root")); root->AddChild(new wxXmlNode(wxXML_ELEMENT_NODE, "1")); wxXmlNode *two = new wxXmlNode(wxXML_ELEMENT_NODE, "2"); root->AddChild(two); root->AddChild(new wxXmlNode(wxXML_ELEMENT_NODE, "3")); - CheckXml(root, "1", "2", "3", NULL); + CheckXml(root.get(), "1", "2", "3", NULL); // check inserting in front: root->InsertChild(new wxXmlNode(wxXML_ELEMENT_NODE, "A"), NULL); - CheckXml(root, "A", "1", "2", "3", NULL); + CheckXml(root.get(), "A", "1", "2", "3", NULL); root->InsertChild(new wxXmlNode(wxXML_ELEMENT_NODE, "B"), root->GetChildren()); - CheckXml(root, "B", "A", "1", "2", "3", NULL); + CheckXml(root.get(), "B", "A", "1", "2", "3", NULL); // and in the middle: root->InsertChild(new wxXmlNode(wxXML_ELEMENT_NODE, "C"), two); - CheckXml(root, "B", "A", "1", "C", "2", "3", NULL); + CheckXml(root.get(), "B", "A", "1", "C", "2", "3", NULL); } void XmlTestCase::InsertChildAfter() { - wxXmlNode *root = new wxXmlNode(wxXML_ELEMENT_NODE, "root"); + wxScopedPtr root(new wxXmlNode(wxXML_ELEMENT_NODE, "root")); root->InsertChildAfter(new wxXmlNode(wxXML_ELEMENT_NODE, "1"), NULL); - CheckXml(root, "1", NULL); + CheckXml(root.get(), "1", NULL); wxXmlNode *two = new wxXmlNode(wxXML_ELEMENT_NODE, "2"); root->AddChild(two); wxXmlNode *three = new wxXmlNode(wxXML_ELEMENT_NODE, "3"); root->AddChild(three); - CheckXml(root, "1", "2", "3", NULL); + CheckXml(root.get(), "1", "2", "3", NULL); // check inserting in the middle: root->InsertChildAfter(new wxXmlNode(wxXML_ELEMENT_NODE, "A"), root->GetChildren()); - CheckXml(root, "1", "A", "2", "3", NULL); + CheckXml(root.get(), "1", "A", "2", "3", NULL); root->InsertChildAfter(new wxXmlNode(wxXML_ELEMENT_NODE, "B"), two); - CheckXml(root, "1", "A", "2", "B", "3", NULL); + CheckXml(root.get(), "1", "A", "2", "B", "3", NULL); // and at the end: root->InsertChildAfter(new wxXmlNode(wxXML_ELEMENT_NODE, "C"), three); - CheckXml(root, "1", "A", "2", "B", "3", "C", NULL); + CheckXml(root.get(), "1", "A", "2", "B", "3", "C", NULL); +} + +void XmlTestCase::LoadSave() +{ + // NB: this is not real XRC but rather some XRC-like XML fragment which + // exercises different XML constructs to check that they're saved back + // correctly + // + // Also note that there should be no blank lines here as they disappear + // after saving. + const char *xmlText = +"\n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" + ; + + wxStringInputStream sis(xmlText); + + wxXmlDocument doc; + CPPUNIT_ASSERT( doc.Load(sis) ); + + wxStringOutputStream sos; + CPPUNIT_ASSERT( doc.Save(sos) ); + + CPPUNIT_ASSERT_EQUAL( xmlText, sos.GetString() ); + + +#if wxUSE_UNICODE + const char *utf8xmlText = +"\n" +"\n" +" \xc3\xa9t\xc3\xa9\n" +" \xd0\xbb\xd0\xb5\xd1\x82\xd0\xbe\n" +"\n" + ; + + wxStringInputStream sis8(wxString::FromUTF8(utf8xmlText)); + CPPUNIT_ASSERT( doc.Load(sis8) ); + + // this contents can't be represented in Latin-1 as it contains Cyrillic + // letters + doc.SetFileEncoding("ISO-8859-1"); + CPPUNIT_ASSERT( !doc.Save(sos) ); + + // but it should work in UTF-8 + wxStringOutputStream sos8; + doc.SetFileEncoding("UTF-8"); + CPPUNIT_ASSERT( doc.Save(sos8) ); + CPPUNIT_ASSERT_EQUAL( wxString(utf8xmlText), + wxString(sos8.GetString().ToUTF8()) ); +#endif // wxUSE_UNICODE + + const char *xmlTextProlog = +"\n" +"\n" +"\n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" + ; + + wxStringInputStream sisp(xmlTextProlog); + CPPUNIT_ASSERT( doc.Load(sisp, "UTF-8") ); + + wxStringOutputStream sosp; + CPPUNIT_ASSERT( doc.Save(sosp) ); + + CPPUNIT_ASSERT_EQUAL( xmlTextProlog, sosp.GetString() ); +} + +void XmlTestCase::CDATA() +{ + const char *xmlText = + "\n" + "\n" + " \n" + "\n" + ; + + wxStringInputStream sis(xmlText); + wxXmlDocument doc; + CPPUNIT_ASSERT( doc.Load(sis) ); + + wxXmlNode *n = doc.GetRoot(); + CPPUNIT_ASSERT( n ); + + n = n->GetChildren(); + CPPUNIT_ASSERT( n ); + + // check that both leading (" ") and trailing white space is not part of + // the node contents when CDATA is used and wxXMLDOC_KEEP_WHITESPACE_NODES + // is not + CPPUNIT_ASSERT_EQUAL( "Giovanni Mittone", n->GetContent() ); +} + +void XmlTestCase::PI() +{ + const char *xmlText = + "\n" + "\n" + " \n" + "\n" + ; + + wxStringInputStream sis(xmlText); + wxXmlDocument doc; + CPPUNIT_ASSERT( doc.Load(sis) ); + + wxXmlNode *n = doc.GetRoot(); + CPPUNIT_ASSERT( n ); + + n = n->GetChildren(); + CPPUNIT_ASSERT( n ); + + CPPUNIT_ASSERT_EQUAL( "index=\"no\" follow=\"no\"", n->GetContent() ); +} + +void XmlTestCase::Escaping() +{ + // Verify that attribute values are escaped correctly, see + // http://trac.wxwidgets.org/ticket/12275 + + const char *xmlText = +"\n" +"\n" +" \n" +"\n" + ; + + wxStringInputStream sis(xmlText); + + wxXmlDocument doc; + CPPUNIT_ASSERT( doc.Load(sis) ); + + wxStringOutputStream sos; + CPPUNIT_ASSERT( doc.Save(sos) ); + + CPPUNIT_ASSERT_EQUAL( xmlText, sos.GetString() ); +} + +void XmlTestCase::DetachRoot() +{ + const char *xmlTextProlog = +"\n" +"\n" +"\n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n" + ; + const char *xmlTextHtm = +"\n" +"\n" +" \n" +" Testing wxXml\n" +" \n" +" \n" +"

Some body text

\n" +" \n" +"\n" + ; + wxXmlDocument doc; + + wxStringInputStream sish(xmlTextHtm); + CPPUNIT_ASSERT( doc.Load(sish) ); + + wxXmlNode *root = doc.DetachRoot(); + + wxStringInputStream sisp(xmlTextProlog); + CPPUNIT_ASSERT( doc.Load(sisp) ); + + doc.SetRoot(root); + + wxStringOutputStream sos; + CPPUNIT_ASSERT( doc.Save(sos) ); + + const char *xmlTextResult1 = +"\n" +"\n" +"\n" +"\n" +" \n" +" Testing wxXml\n" +" \n" +" \n" +"

Some body text

\n" +" \n" +"\n" +"\n" + ; + CPPUNIT_ASSERT_EQUAL( xmlTextResult1, sos.GetString() ); + + wxStringInputStream sisp2(xmlTextProlog); + CPPUNIT_ASSERT( doc.Load(sisp2) ); + + root = doc.DetachRoot(); + + wxStringInputStream sish2(xmlTextHtm); + CPPUNIT_ASSERT( doc.Load(sish2) ); + + doc.SetRoot(root); + + wxStringOutputStream sos2; + CPPUNIT_ASSERT( doc.Save(sos2) ); + + const char *xmlTextResult2 = +"\n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" + ; + CPPUNIT_ASSERT_EQUAL( xmlTextResult2, sos2.GetString() ); +} + +void XmlTestCase::AppendToProlog() +{ + const char *xmlText = +"\n" +"\n" +"

Some text

\n" +"
\n" + ; + wxXmlDocument rootdoc; + wxStringInputStream sis(xmlText); + CPPUNIT_ASSERT( rootdoc.Load(sis) ); + wxXmlNode *root = rootdoc.DetachRoot(); + + wxXmlNode *comment1 = new wxXmlNode(wxXML_COMMENT_NODE, "comment", + " 1st prolog entry "); + wxXmlNode *pi = new wxXmlNode(wxXML_PI_NODE, "xml-stylesheet", + "href=\"style.css\" type=\"text/css\""); + wxXmlNode *comment2 = new wxXmlNode(wxXML_COMMENT_NODE, "comment", + " 3rd prolog entry "); + + wxXmlDocument doc; + doc.AppendToProlog( comment1 ); + doc.AppendToProlog( pi ); + doc.SetRoot( root ); + doc.AppendToProlog( comment2 ); + + wxStringOutputStream sos; + CPPUNIT_ASSERT( doc.Save(sos) ); + + const char *xmlTextResult = +"\n" +"\n" +"\n" +"\n" +"\n" +"

Some text

\n" +"
\n" + ; + CPPUNIT_ASSERT_EQUAL( xmlTextResult, sos.GetString() ); +} + +void XmlTestCase::SetRoot() +{ + wxXmlDocument doc; + CPPUNIT_ASSERT( !doc.IsOk() ); + wxXmlNode *root = new wxXmlNode(wxXML_ELEMENT_NODE, "root"); + + // Test for the problem of http://trac.wxwidgets.org/ticket/13135 + doc.SetRoot( root ); + wxXmlNode *docNode = doc.GetDocumentNode(); + CPPUNIT_ASSERT( docNode && root == docNode->GetChildren() ); + CPPUNIT_ASSERT( doc.IsOk() ); + + // Other tests. + CPPUNIT_ASSERT( docNode == root->GetParent() ); + doc.SetRoot(NULL); // Removes from doc but dosn't free mem, doc node left. + CPPUNIT_ASSERT( !doc.IsOk() ); + + wxXmlNode *comment = new wxXmlNode(wxXML_COMMENT_NODE, "comment", "Prolog Comment"); + wxXmlNode *pi = new wxXmlNode(wxXML_PI_NODE, "target", "PI instructions"); + doc.AppendToProlog(comment); + doc.SetRoot( root ); + doc.AppendToProlog(pi); + CPPUNIT_ASSERT( doc.IsOk() ); + wxXmlNode *node = docNode->GetChildren(); + CPPUNIT_ASSERT( node ); + CPPUNIT_ASSERT( node->GetType() == wxXML_COMMENT_NODE ); + CPPUNIT_ASSERT( node->GetParent() == docNode ); + node = node->GetNext(); + CPPUNIT_ASSERT( node ); + CPPUNIT_ASSERT( node->GetType() == wxXML_PI_NODE ); + CPPUNIT_ASSERT( node->GetParent() == docNode ); + node = node->GetNext(); + CPPUNIT_ASSERT( node ); + CPPUNIT_ASSERT( node->GetType() == wxXML_ELEMENT_NODE ); + CPPUNIT_ASSERT( node->GetParent() == docNode ); + node = node->GetNext(); + CPPUNIT_ASSERT( !node ); + doc.SetRoot(NULL); + CPPUNIT_ASSERT( !doc.IsOk() ); + doc.SetRoot(root); + CPPUNIT_ASSERT( doc.IsOk() ); }