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