]> git.saurik.com Git - wxWidgets.git/blame - tests/xml/xmltest.cpp
No changes, just a small optimization in DataStreamTestCase.
[wxWidgets.git] / tests / xml / xmltest.cpp
CommitLineData
5e05df3c
VS
1///////////////////////////////////////////////////////////////////////////////
2// Name: tests/xml/xmltest.cpp
3// Purpose: XML classes unit test
4// Author: Vaclav Slavik
5// Created: 2008-03-29
6// RCS-ID: $Id$
7// Copyright: (c) 2008 Vaclav Slavik
8///////////////////////////////////////////////////////////////////////////////
9
10// ----------------------------------------------------------------------------
11// headers
12// ----------------------------------------------------------------------------
13
14#include "testprec.h"
15
16#ifdef __BORLANDC__
17 #pragma hdrstop
18#endif
19
20#ifndef WX_PRECOMP
21 #include "wx/wx.h"
22#endif // WX_PRECOMP
23
24#include "wx/xml/xml.h"
e8afaabf 25#include "wx/scopedptr.h"
4c493e0b 26#include "wx/sstream.h"
5e05df3c
VS
27
28#include <stdarg.h>
29
30// ----------------------------------------------------------------------------
31// helpers for testing XML tree
32// ----------------------------------------------------------------------------
33
34namespace
35{
36
02c94354 37void CheckXml(const wxXmlNode *n, ...)
5e05df3c
VS
38{
39 va_list args;
40 va_start(args, n);
41
42 wxXmlNode *child = n->GetChildren();
43
44 for (;;)
45 {
46 const char *childName = va_arg(args, char*);
47 if ( childName == NULL )
48 break;
49
50 CPPUNIT_ASSERT( child );
1de532f5 51 CPPUNIT_ASSERT_EQUAL( childName, child->GetName() );
5e05df3c 52 CPPUNIT_ASSERT( child->GetChildren() == NULL );
02c94354 53 CPPUNIT_ASSERT( child->GetParent() == n );
5e05df3c
VS
54
55 child = child->GetNext();
56 }
57
58 va_end(args);
59
60 CPPUNIT_ASSERT( child == NULL ); // no more children
61}
62
63} // anon namespace
64
65// ----------------------------------------------------------------------------
66// test class
67// ----------------------------------------------------------------------------
68
69class XmlTestCase : public CppUnit::TestCase
70{
71public:
72 XmlTestCase() {}
73
74private:
75 CPPUNIT_TEST_SUITE( XmlTestCase );
76 CPPUNIT_TEST( InsertChild );
43a302f2 77 CPPUNIT_TEST( InsertChildAfter );
4c493e0b 78 CPPUNIT_TEST( LoadSave );
2388960a 79 CPPUNIT_TEST( CDATA );
cee8636e 80 CPPUNIT_TEST( PI );
926649a9 81 CPPUNIT_TEST( Escaping );
cee8636e
VZ
82 CPPUNIT_TEST( DetachRoot );
83 CPPUNIT_TEST( AppendToProlog );
6f24b817 84 CPPUNIT_TEST( SetRoot );
5e05df3c
VS
85 CPPUNIT_TEST_SUITE_END();
86
87 void InsertChild();
43a302f2 88 void InsertChildAfter();
4c493e0b 89 void LoadSave();
2388960a 90 void CDATA();
cee8636e 91 void PI();
926649a9 92 void Escaping();
cee8636e
VZ
93 void DetachRoot();
94 void AppendToProlog();
6f24b817 95 void SetRoot();
5e05df3c
VS
96
97 DECLARE_NO_COPY_CLASS(XmlTestCase)
98};
99
100// register in the unnamed registry so that these tests are run by default
101CPPUNIT_TEST_SUITE_REGISTRATION( XmlTestCase );
102
e3778b4d 103// also include in its own registry so that these tests can be run alone
5e05df3c
VS
104CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( XmlTestCase, "XmlTestCase" );
105
106void XmlTestCase::InsertChild()
107{
e8afaabf 108 wxScopedPtr<wxXmlNode> root(new wxXmlNode(wxXML_ELEMENT_NODE, "root"));
5e05df3c
VS
109 root->AddChild(new wxXmlNode(wxXML_ELEMENT_NODE, "1"));
110 wxXmlNode *two = new wxXmlNode(wxXML_ELEMENT_NODE, "2");
111 root->AddChild(two);
112 root->AddChild(new wxXmlNode(wxXML_ELEMENT_NODE, "3"));
02c94354 113 CheckXml(root.get(), "1", "2", "3", NULL);
5e05df3c
VS
114
115 // check inserting in front:
116 root->InsertChild(new wxXmlNode(wxXML_ELEMENT_NODE, "A"), NULL);
02c94354 117 CheckXml(root.get(), "A", "1", "2", "3", NULL);
5e05df3c 118 root->InsertChild(new wxXmlNode(wxXML_ELEMENT_NODE, "B"), root->GetChildren());
02c94354 119 CheckXml(root.get(), "B", "A", "1", "2", "3", NULL);
5e05df3c
VS
120
121 // and in the middle:
122 root->InsertChild(new wxXmlNode(wxXML_ELEMENT_NODE, "C"), two);
02c94354 123 CheckXml(root.get(), "B", "A", "1", "C", "2", "3", NULL);
5e05df3c 124}
43a302f2
VS
125
126void XmlTestCase::InsertChildAfter()
127{
e8afaabf 128 wxScopedPtr<wxXmlNode> root(new wxXmlNode(wxXML_ELEMENT_NODE, "root"));
43a302f2
VS
129
130 root->InsertChildAfter(new wxXmlNode(wxXML_ELEMENT_NODE, "1"), NULL);
02c94354 131 CheckXml(root.get(), "1", NULL);
43a302f2
VS
132
133 wxXmlNode *two = new wxXmlNode(wxXML_ELEMENT_NODE, "2");
134 root->AddChild(two);
135 wxXmlNode *three = new wxXmlNode(wxXML_ELEMENT_NODE, "3");
136 root->AddChild(three);
02c94354 137 CheckXml(root.get(), "1", "2", "3", NULL);
43a302f2
VS
138
139 // check inserting in the middle:
140 root->InsertChildAfter(new wxXmlNode(wxXML_ELEMENT_NODE, "A"), root->GetChildren());
02c94354 141 CheckXml(root.get(), "1", "A", "2", "3", NULL);
43a302f2 142 root->InsertChildAfter(new wxXmlNode(wxXML_ELEMENT_NODE, "B"), two);
02c94354 143 CheckXml(root.get(), "1", "A", "2", "B", "3", NULL);
43a302f2
VS
144
145 // and at the end:
146 root->InsertChildAfter(new wxXmlNode(wxXML_ELEMENT_NODE, "C"), three);
02c94354 147 CheckXml(root.get(), "1", "A", "2", "B", "3", "C", NULL);
43a302f2 148}
4c493e0b
VZ
149
150void XmlTestCase::LoadSave()
151{
152 // NB: this is not real XRC but rather some XRC-like XML fragment which
153 // exercises different XML constructs to check that they're saved back
154 // correctly
155 //
156 // Also note that there should be no blank lines here as they disappear
157 // after saving.
158 const char *xmlText =
159"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
160"<resource xmlns=\"http://www.wxwidgets.org/wxxrc\" version=\"2.3.0.1\">\n"
cee8636e 161" <!-- Test comment -->\n"
4c493e0b
VZ
162" <object class=\"wxDialog\" name=\"my_dialog\">\n"
163" <children>\n"
164" <grandchild id=\"1\"/>\n"
165" </children>\n"
166" <subobject/>\n"
167" </object>\n"
168"</resource>\n"
169 ;
170
171 wxStringInputStream sis(xmlText);
172
173 wxXmlDocument doc;
174 CPPUNIT_ASSERT( doc.Load(sis) );
175
176 wxStringOutputStream sos;
177 CPPUNIT_ASSERT( doc.Save(sos) );
178
179 CPPUNIT_ASSERT_EQUAL( xmlText, sos.GetString() );
e767076e
VZ
180
181
87f528f1 182#if wxUSE_UNICODE
e767076e
VZ
183 const char *utf8xmlText =
184"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
185"<word>\n"
186" <lang name=\"fr\">\xc3\xa9t\xc3\xa9</lang>\n"
187" <lang name=\"ru\">\xd0\xbb\xd0\xb5\xd1\x82\xd0\xbe</lang>\n"
188"</word>\n"
189 ;
190
191 wxStringInputStream sis8(wxString::FromUTF8(utf8xmlText));
192 CPPUNIT_ASSERT( doc.Load(sis8) );
193
194 // this contents can't be represented in Latin-1 as it contains Cyrillic
195 // letters
196 doc.SetFileEncoding("ISO-8859-1");
197 CPPUNIT_ASSERT( !doc.Save(sos) );
198
199 // but it should work in UTF-8
200 wxStringOutputStream sos8;
201 doc.SetFileEncoding("UTF-8");
202 CPPUNIT_ASSERT( doc.Save(sos8) );
a0871132
VZ
203 CPPUNIT_ASSERT_EQUAL( wxString(utf8xmlText),
204 wxString(sos8.GetString().ToUTF8()) );
87f528f1 205#endif // wxUSE_UNICODE
cee8636e
VZ
206
207 const char *xmlTextProlog =
208"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
209"<!-- Prolog comment -->\n"
210"<?xml-stylesheet href=\"style.css\" type=\"text/css\"?>\n"
211"<resource xmlns=\"http://www.wxwidgets.org/wxxrc\" version=\"2.3.0.1\">\n"
212" <!-- Test comment -->\n"
213" <object class=\"wxDialog\" name=\"my_dialog\">\n"
214" <children>\n"
215" <grandchild id=\"1\"/>\n"
216" </children>\n"
217" <subobject/>\n"
218" </object>\n"
219"</resource>\n"
220"<!-- Trailing comment -->\n"
221 ;
222
223 wxStringInputStream sisp(xmlTextProlog);
224 CPPUNIT_ASSERT( doc.Load(sisp, "UTF-8") );
225
226 wxStringOutputStream sosp;
227 CPPUNIT_ASSERT( doc.Save(sosp) );
228
229 CPPUNIT_ASSERT_EQUAL( xmlTextProlog, sosp.GetString() );
4c493e0b
VZ
230}
231
2388960a
VZ
232void XmlTestCase::CDATA()
233{
234 const char *xmlText =
235 "<?xml version=\"1.0\" encoding=\"windows-1252\"?>\n"
236 "<name>\n"
237 " <![CDATA[Giovanni Mittone]]>\n"
238 "</name>\n"
239 ;
240
241 wxStringInputStream sis(xmlText);
242 wxXmlDocument doc;
243 CPPUNIT_ASSERT( doc.Load(sis) );
244
245 wxXmlNode *n = doc.GetRoot();
246 CPPUNIT_ASSERT( n );
247
248 n = n->GetChildren();
249 CPPUNIT_ASSERT( n );
250
a6cf6bcf
VZ
251 // check that both leading (" ") and trailing white space is not part of
252 // the node contents when CDATA is used and wxXMLDOC_KEEP_WHITESPACE_NODES
253 // is not
254 CPPUNIT_ASSERT_EQUAL( "Giovanni Mittone", n->GetContent() );
2388960a 255}
926649a9 256
cee8636e
VZ
257void XmlTestCase::PI()
258{
259 const char *xmlText =
260 "<?xml version=\"1.0\" encoding=\"windows-1252\"?>\n"
261 "<root>\n"
262 " <?robot index=\"no\" follow=\"no\"?>\n"
263 "</root>\n"
264 ;
265
266 wxStringInputStream sis(xmlText);
267 wxXmlDocument doc;
268 CPPUNIT_ASSERT( doc.Load(sis) );
269
270 wxXmlNode *n = doc.GetRoot();
271 CPPUNIT_ASSERT( n );
272
273 n = n->GetChildren();
274 CPPUNIT_ASSERT( n );
275
276 CPPUNIT_ASSERT_EQUAL( "index=\"no\" follow=\"no\"", n->GetContent() );
277}
278
926649a9
VS
279void XmlTestCase::Escaping()
280{
281 // Verify that attribute values are escaped correctly, see
282 // http://trac.wxwidgets.org/ticket/12275
283
284 const char *xmlText =
285"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
286"<root text=\"hello&#xD;&#xA;this is a new line\">\n"
287" <x/>\n"
288"</root>\n"
289 ;
290
291 wxStringInputStream sis(xmlText);
292
293 wxXmlDocument doc;
294 CPPUNIT_ASSERT( doc.Load(sis) );
295
296 wxStringOutputStream sos;
297 CPPUNIT_ASSERT( doc.Save(sos) );
298
299 CPPUNIT_ASSERT_EQUAL( xmlText, sos.GetString() );
300}
cee8636e
VZ
301
302void XmlTestCase::DetachRoot()
303{
304 const char *xmlTextProlog =
305"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
306"<!-- Prolog comment -->\n"
307"<?xml-stylesheet href=\"style.css\" type=\"text/css\"?>\n"
308"<resource xmlns=\"http://www.wxwidgets.org/wxxrc\" version=\"2.3.0.1\">\n"
309" <!-- Test comment -->\n"
310" <object class=\"wxDialog\" name=\"my_dialog\">\n"
311" <children>\n"
312" <grandchild id=\"1\"/>\n"
313" </children>\n"
314" <subobject/>\n"
315" </object>\n"
316"</resource>\n"
317"<!-- Trailing comment -->\n"
318 ;
319 const char *xmlTextHtm =
320"<?xml version=\"1.0\" encoding=\"windows-1252\"?>\n"
321"<html>\n"
322" <head>\n"
323" <title>Testing wxXml</title>\n"
324" </head>\n"
325" <body>\n"
326" <p>Some body text</p>\n"
327" </body>\n"
328"</html>\n"
329 ;
330 wxXmlDocument doc;
331
332 wxStringInputStream sish(xmlTextHtm);
333 CPPUNIT_ASSERT( doc.Load(sish) );
334
335 wxXmlNode *root = doc.DetachRoot();
336
337 wxStringInputStream sisp(xmlTextProlog);
338 CPPUNIT_ASSERT( doc.Load(sisp) );
339
340 doc.SetRoot(root);
341
342 wxStringOutputStream sos;
343 CPPUNIT_ASSERT( doc.Save(sos) );
344
345 const char *xmlTextResult1 =
346"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
347"<!-- Prolog comment -->\n"
348"<?xml-stylesheet href=\"style.css\" type=\"text/css\"?>\n"
349"<html>\n"
350" <head>\n"
351" <title>Testing wxXml</title>\n"
352" </head>\n"
353" <body>\n"
354" <p>Some body text</p>\n"
355" </body>\n"
356"</html>\n"
357"<!-- Trailing comment -->\n"
358 ;
359 CPPUNIT_ASSERT_EQUAL( xmlTextResult1, sos.GetString() );
360
361 wxStringInputStream sisp2(xmlTextProlog);
362 CPPUNIT_ASSERT( doc.Load(sisp2) );
363
364 root = doc.DetachRoot();
365
366 wxStringInputStream sish2(xmlTextHtm);
367 CPPUNIT_ASSERT( doc.Load(sish2) );
368
369 doc.SetRoot(root);
370
371 wxStringOutputStream sos2;
372 CPPUNIT_ASSERT( doc.Save(sos2) );
373
374 const char *xmlTextResult2 =
375"<?xml version=\"1.0\" encoding=\"windows-1252\"?>\n"
376"<resource xmlns=\"http://www.wxwidgets.org/wxxrc\" version=\"2.3.0.1\">\n"
377" <!-- Test comment -->\n"
378" <object class=\"wxDialog\" name=\"my_dialog\">\n"
379" <children>\n"
380" <grandchild id=\"1\"/>\n"
381" </children>\n"
382" <subobject/>\n"
383" </object>\n"
384"</resource>\n"
385 ;
386 CPPUNIT_ASSERT_EQUAL( xmlTextResult2, sos2.GetString() );
387}
388
389void XmlTestCase::AppendToProlog()
390{
391 const char *xmlText =
392"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
393"<root>\n"
394" <p>Some text</p>\n"
395"</root>\n"
396 ;
397 wxXmlDocument rootdoc;
398 wxStringInputStream sis(xmlText);
399 CPPUNIT_ASSERT( rootdoc.Load(sis) );
400 wxXmlNode *root = rootdoc.DetachRoot();
401
402 wxXmlNode *comment1 = new wxXmlNode(wxXML_COMMENT_NODE, "comment",
403 " 1st prolog entry ");
404 wxXmlNode *pi = new wxXmlNode(wxXML_PI_NODE, "xml-stylesheet",
405 "href=\"style.css\" type=\"text/css\"");
406 wxXmlNode *comment2 = new wxXmlNode(wxXML_COMMENT_NODE, "comment",
407 " 3rd prolog entry ");
408
409 wxXmlDocument doc;
410 doc.AppendToProlog( comment1 );
411 doc.AppendToProlog( pi );
412 doc.SetRoot( root );
413 doc.AppendToProlog( comment2 );
414
415 wxStringOutputStream sos;
416 CPPUNIT_ASSERT( doc.Save(sos) );
417
418 const char *xmlTextResult =
419"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
420"<!-- 1st prolog entry -->\n"
421"<?xml-stylesheet href=\"style.css\" type=\"text/css\"?>\n"
422"<!-- 3rd prolog entry -->\n"
423"<root>\n"
424" <p>Some text</p>\n"
425"</root>\n"
426 ;
427 CPPUNIT_ASSERT_EQUAL( xmlTextResult, sos.GetString() );
428}
6f24b817
VZ
429
430void XmlTestCase::SetRoot()
431{
432 wxXmlDocument doc;
433 CPPUNIT_ASSERT( !doc.IsOk() );
434 wxXmlNode *root = new wxXmlNode(wxXML_ELEMENT_NODE, "root");
435
436 // Test for the problem of http://trac.wxwidgets.org/ticket/13135
437 doc.SetRoot( root );
438 wxXmlNode *docNode = doc.GetDocumentNode();
439 CPPUNIT_ASSERT( docNode && root == docNode->GetChildren() );
440 CPPUNIT_ASSERT( doc.IsOk() );
441
442 // Other tests.
443 CPPUNIT_ASSERT( docNode == root->GetParent() );
444 doc.SetRoot(NULL); // Removes from doc but dosn't free mem, doc node left.
445 CPPUNIT_ASSERT( !doc.IsOk() );
446
447 wxXmlNode *comment = new wxXmlNode(wxXML_COMMENT_NODE, "comment", "Prolog Comment");
448 wxXmlNode *pi = new wxXmlNode(wxXML_PI_NODE, "target", "PI instructions");
449 doc.AppendToProlog(comment);
450 doc.SetRoot( root );
451 doc.AppendToProlog(pi);
452 CPPUNIT_ASSERT( doc.IsOk() );
453 wxXmlNode *node = docNode->GetChildren();
454 CPPUNIT_ASSERT( node );
455 CPPUNIT_ASSERT( node->GetType() == wxXML_COMMENT_NODE );
456 CPPUNIT_ASSERT( node->GetParent() == docNode );
457 node = node->GetNext();
458 CPPUNIT_ASSERT( node );
459 CPPUNIT_ASSERT( node->GetType() == wxXML_PI_NODE );
460 CPPUNIT_ASSERT( node->GetParent() == docNode );
461 node = node->GetNext();
462 CPPUNIT_ASSERT( node );
463 CPPUNIT_ASSERT( node->GetType() == wxXML_ELEMENT_NODE );
464 CPPUNIT_ASSERT( node->GetParent() == docNode );
465 node = node->GetNext();
466 CPPUNIT_ASSERT( !node );
467 doc.SetRoot(NULL);
468 CPPUNIT_ASSERT( !doc.IsOk() );
469 doc.SetRoot(root);
470 CPPUNIT_ASSERT( doc.IsOk() );
471}