427cc70091d2bf93bf8879d715aceaebcb1a659b
[mono.git] / mcs / class / System.XML / Test / XmlDocumentTests.cs
1 //
2 // System.Xml.XmlDocumentTests
3 //
4 // Authors:
5 //   Jason Diamond <jason@injektilo.org>
6 //   Kral Ferch <kral_ferch@hotmail.com>
7 //
8 // (C) 2002 Jason Diamond, Kral Ferch
9 //
10
11 using System;
12 using System.Collections;
13 using System.Xml;
14 using System.IO;
15 using System.Text;
16
17 using NUnit.Framework;
18
19 namespace MonoTests.System.Xml
20 {
21         public class XmlDocumentTests : TestCase
22         {
23                 public XmlDocumentTests () : base ("MonoTests.System.Xml.XmlDocumentTests testsuite") {}
24                 public XmlDocumentTests (string name) : base (name) {}
25
26                 private XmlDocument document;
27                 private ArrayList eventStrings = new ArrayList();
28
29                 // These Event* methods support the TestEventNode* Tests in this file.
30                 // Most of them are event handlers for the XmlNodeChangedEventHandler
31                 // delegate.
32                 private void EventStringAdd(string eventName, XmlNodeChangedEventArgs e)
33                 {
34                         string oldParent = (e.OldParent != null) ? e.OldParent.Name : "<none>";
35                         string newParent = (e.NewParent != null) ? e.NewParent.Name : "<none>";
36                         eventStrings.Add (String.Format ("{0}, {1}, {2}, {3}, {4}", eventName, e.Action.ToString (), e.Node.OuterXml, oldParent, newParent));
37                 }
38
39                 private void EventNodeChanged(Object sender, XmlNodeChangedEventArgs e)
40                 {
41                         EventStringAdd ("NodeChanged", e);
42                 }
43
44                 private void EventNodeChanging (Object sender, XmlNodeChangedEventArgs e)
45                 {
46                         EventStringAdd ("NodeChanging", e);
47                 }
48
49                 private void EventNodeChangingException (Object sender, XmlNodeChangedEventArgs e)
50                 {
51                         throw new Exception ("don't change the value.");
52                 }
53
54                 private void EventNodeInserted(Object sender, XmlNodeChangedEventArgs e)
55                 {
56                         EventStringAdd ("NodeInserted", e);
57                 }
58
59                 private void EventNodeInserting(Object sender, XmlNodeChangedEventArgs e)
60                 {
61                         EventStringAdd ("NodeInserting", e);
62                 }
63
64                 private void EventNodeInsertingException(Object sender, XmlNodeChangedEventArgs e)
65                 {
66                         throw new Exception ("don't insert the element.");
67                 }
68
69                 private void EventNodeRemoved(Object sender, XmlNodeChangedEventArgs e)
70                 {
71                         EventStringAdd ("NodeRemoved", e);
72                 }
73
74                 private void EventNodeRemoving(Object sender, XmlNodeChangedEventArgs e)
75                 {
76                         EventStringAdd ("NodeRemoving", e);
77                 }
78
79                 private void EventNodeRemovingException(Object sender, XmlNodeChangedEventArgs e)
80                 {
81                         throw new Exception ("don't remove the element.");
82                 }
83
84                 protected override void SetUp ()
85                 {
86                         document = new XmlDocument ();
87                 }
88
89                 public void TestCreateNodeNodeTypeNameEmptyParams ()
90                 {
91                         XmlNode node;
92
93                         try {
94                                 node = document.CreateNode (null, null, null);
95                                 Fail ("Expected an ArgumentException to be thrown.");
96                         } catch (ArgumentException) {}
97
98                         try {
99                                 node = document.CreateNode ("attribute", null, null);
100                                 Fail ("Expected a NullReferenceException to be thrown.");
101                         } catch (NullReferenceException) {}
102
103                         try {
104                                 node = document.CreateNode ("attribute", "", null);
105                                 Fail ("Expected an ArgumentException to be thrown.");
106                         } catch (ArgumentException) {}
107
108                         try {
109                                 node = document.CreateNode ("element", null, null);
110                                 Fail ("Expected a NullReferenceException to be thrown.");
111                         } catch (NullReferenceException) {}
112
113                         try {
114                                 node = document.CreateNode ("element", "", null);
115                                 Fail ("Expected an ArgumentException to be thrown.");
116                         } catch (ArgumentException) {}
117
118                         try {
119                                 node = document.CreateNode ("entityreference", null, null);
120                                 Fail ("Expected a NullReferenceException to be thrown.");
121                         } catch (NullReferenceException) {}
122                 }
123
124                 public void TestCreateNodeInvalidXmlNodeType ()
125                 {
126                         XmlNode node;
127
128                         try {
129                                 node = document.CreateNode (XmlNodeType.EndElement, null, null);
130                                 Fail ("Expected an ArgumentOutOfRangeException to be thrown.");
131                         } catch (ArgumentOutOfRangeException) {}
132
133                         try {
134                                 node = document.CreateNode (XmlNodeType.EndEntity, null, null);
135                                 Fail ("Expected an ArgumentOutOfRangeException to be thrown.");
136                         } catch (ArgumentOutOfRangeException) {}
137
138                         try {
139                                 node = document.CreateNode (XmlNodeType.Entity, null, null);
140                                 Fail ("Expected an ArgumentOutOfRangeException to be thrown.");
141                         } catch (ArgumentOutOfRangeException) {}
142
143                         try {
144                                 node = document.CreateNode (XmlNodeType.None, null, null);
145                                 Fail ("Expected an ArgumentOutOfRangeException to be thrown.");
146                         } catch (ArgumentOutOfRangeException) {}
147
148                         try {
149                                 node = document.CreateNode (XmlNodeType.Notation, null, null);
150                                 Fail ("Expected an ArgumentOutOfRangeException to be thrown.");
151                         } catch (ArgumentOutOfRangeException) {}
152
153                         // TODO:  undocumented allowable type.
154                         node = document.CreateNode (XmlNodeType.XmlDeclaration, null, null);
155                         AssertEquals (XmlNodeType.XmlDeclaration, node.NodeType);
156                 }
157
158                 public void TestCreateNodeWhichParamIsUsed ()
159                 {
160                         XmlNode node;
161
162                         // No constructor params for Document, DocumentFragment.
163
164                         node = document.CreateNode (XmlNodeType.CDATA, "a", "b", "c");
165                         AssertEquals (String.Empty, ((XmlCDataSection)node).Value);
166
167                         node = document.CreateNode (XmlNodeType.Comment, "a", "b", "c");
168                         AssertEquals (String.Empty, ((XmlComment)node).Value);
169
170                         node = document.CreateNode (XmlNodeType.DocumentType, "a", "b", "c");
171                         AssertNull (((XmlDocumentType)node).Value);
172
173 // TODO: add this back in to test when it's implemented.
174 //                      node = document.CreateNode (XmlNodeType.EntityReference, "a", "b", "c");
175 //                      AssertNull (((XmlEntityReference)node).Value);
176
177                         node = document.CreateNode (XmlNodeType.ProcessingInstruction, "a", "b", "c");
178                         AssertEquals (String.Empty, ((XmlProcessingInstruction)node).Value);
179
180                         node = document.CreateNode (XmlNodeType.SignificantWhitespace, "a", "b", "c");
181                         AssertEquals (String.Empty, ((XmlSignificantWhitespace)node).Value);
182
183                         node = document.CreateNode (XmlNodeType.Text, "a", "b", "c");
184                         AssertEquals (String.Empty, ((XmlText)node).Value);
185
186                         node = document.CreateNode (XmlNodeType.Whitespace, "a", "b", "c");
187                         AssertEquals (String.Empty, ((XmlWhitespace)node).Value);
188
189                         node = document.CreateNode (XmlNodeType.XmlDeclaration, "a", "b", "c");
190                         AssertEquals ("version=\"1.0\"", ((XmlDeclaration)node).Value);
191                 }
192
193                 public void TestCreateNodeNodeTypeName ()
194                 {
195                         XmlNode node;
196
197                         try {
198                                 node = document.CreateNode ("foo", null, null);
199                                 Fail ("Expected an ArgumentException to be thrown.");
200                         } catch (ArgumentException) {}
201
202                         node = document.CreateNode("attribute", "foo", null);
203                         AssertEquals (XmlNodeType.Attribute, node.NodeType);
204
205                         node = document.CreateNode("cdatasection", null, null);
206                         AssertEquals (XmlNodeType.CDATA, node.NodeType);
207
208                         node = document.CreateNode("comment", null, null);
209                         AssertEquals (XmlNodeType.Comment, node.NodeType);
210
211                         node = document.CreateNode("document", null, null);
212                         AssertEquals (XmlNodeType.Document, node.NodeType);
213                         // TODO: test which constructor this ended up calling,
214                         // i.e. reuse underlying NameTable or not?
215
216 // TODO: add this back in to test when it's implemented.
217 //                      node = document.CreateNode("documentfragment", null, null);
218 //                      AssertEquals (XmlNodeType.DocumentFragment, node.NodeType);
219
220                         node = document.CreateNode("documenttype", null, null);
221                         AssertEquals (XmlNodeType.DocumentType, node.NodeType);
222
223                         node = document.CreateNode("element", "foo", null);
224                         AssertEquals (XmlNodeType.Element, node.NodeType);
225
226 // TODO: add this back in to test when it's implemented.
227 //                      node = document.CreateNode("entityreference", "foo", null);
228 //                      AssertEquals (XmlNodeType.EntityReference, node.NodeType);
229
230                         node = document.CreateNode("processinginstruction", null, null);
231                         AssertEquals (XmlNodeType.ProcessingInstruction, node.NodeType);
232
233                         node = document.CreateNode("significantwhitespace", null, null);
234                         AssertEquals (XmlNodeType.SignificantWhitespace, node.NodeType);
235
236                         node = document.CreateNode("text", null, null);
237                         AssertEquals (XmlNodeType.Text, node.NodeType);
238
239                         node = document.CreateNode("whitespace", null, null);
240                         AssertEquals (XmlNodeType.Whitespace, node.NodeType);
241                 }
242
243                 public void TestDocumentElement ()
244                 {
245                         AssertNull (document.DocumentElement);
246                         XmlElement element = document.CreateElement ("foo", "bar", "http://foo/");
247                         AssertNotNull (element);
248
249                         AssertEquals ("foo", element.Prefix);
250                         AssertEquals ("bar", element.LocalName);
251                         AssertEquals ("http://foo/", element.NamespaceURI);
252
253                         AssertEquals ("foo:bar", element.Name);
254
255                         AssertSame (element, document.AppendChild (element));
256
257                         AssertSame (element, document.DocumentElement);
258                 }
259
260                 public void TestDocumentEmpty()
261                 {
262                         AssertEquals ("Incorrect output for empty document.", "", document.OuterXml);
263                 }
264
265                 public void TestEventNodeChanged()
266                 {
267                         XmlElement element;
268                         XmlComment comment;
269
270                         document.NodeChanged += new XmlNodeChangedEventHandler (this.EventNodeChanged);
271
272                         // Node that is part of the document.
273                         document.AppendChild (document.CreateElement ("foo"));
274                         comment = document.CreateComment ("bar");
275                         document.DocumentElement.AppendChild (comment);
276                         AssertEquals ("<!--bar-->", document.DocumentElement.InnerXml);
277                         comment.Value = "baz";
278                         Assert (eventStrings.Contains ("NodeChanged, Change, <!--baz-->, foo, foo"));
279                         AssertEquals ("<!--baz-->", document.DocumentElement.InnerXml);
280
281                         // Node that isn't part of the document but created by the document.
282                         element = document.CreateElement ("foo");
283                         comment = document.CreateComment ("bar");
284                         element.AppendChild (comment);
285                         AssertEquals ("<!--bar-->", element.InnerXml);
286                         comment.Value = "baz";
287                         Assert (eventStrings.Contains ("NodeChanged, Change, <!--baz-->, foo, foo"));
288                         AssertEquals ("<!--baz-->", element.InnerXml);
289
290 /*
291  TODO:  Insert this when XmlNode.InnerText() and XmlNode.InnerXml() have been implemented.
292  
293                         // Node that is part of the document.
294                         element = document.CreateElement ("foo");
295                         element.InnerText = "bar";
296                         document.AppendChild(element);
297                         element.InnerText = "baz";
298                         Assert(eventStrings.Contains("NodeChanged, Change, baz, foo, foo"));
299                         
300                         // Node that isn't part of the document but created by the document.
301                         element = document.CreateElement("qux");
302                         element.InnerText = "quux";
303                         element.InnerText = "quuux";
304                         Assert(eventStrings.Contains("NodeChanged, Change, quuux, qux, qux"));
305 */
306                 }
307
308                 public void TestEventNodeChanging()
309                 {
310                         XmlElement element;
311                         XmlComment comment;
312
313                         document.NodeChanging += new XmlNodeChangedEventHandler (this.EventNodeChanging);
314
315                         // Node that is part of the document.
316                         document.AppendChild (document.CreateElement ("foo"));
317                         comment = document.CreateComment ("bar");
318                         document.DocumentElement.AppendChild (comment);
319                         AssertEquals ("<!--bar-->", document.DocumentElement.InnerXml);
320                         comment.Value = "baz";
321                         Assert (eventStrings.Contains ("NodeChanging, Change, <!--bar-->, foo, foo"));
322                         AssertEquals ("<!--baz-->", document.DocumentElement.InnerXml);
323
324                         // Node that isn't part of the document but created by the document.
325                         element = document.CreateElement ("foo");
326                         comment = document.CreateComment ("bar");
327                         element.AppendChild (comment);
328                         AssertEquals ("<!--bar-->", element.InnerXml);
329                         comment.Value = "baz";
330                         Assert (eventStrings.Contains ("NodeChanging, Change, <!--bar-->, foo, foo"));
331                         AssertEquals ("<!--baz-->", element.InnerXml);
332
333                         // If an exception is thrown the Document returns to original state.
334                         document.NodeChanging += new XmlNodeChangedEventHandler (this.EventNodeChangingException);
335                         element = document.CreateElement("foo");
336                         comment = document.CreateComment ("bar");
337                         element.AppendChild (comment);
338                         AssertEquals ("<!--bar-->", element.InnerXml);
339                         try 
340                         {
341                                 comment.Value = "baz";
342                                 Fail("Expected an exception to be thrown by the NodeChanging event handler method EventNodeChangingException().");
343                         } catch (Exception) {}
344                         AssertEquals ("<!--bar-->", element.InnerXml);
345
346                         // Yes it's a bit anal but this tests whether the node changing event exception fires before the
347                         // ArgumentOutOfRangeException.  Turns out it does so that means our implementation needs to raise
348                         // the node changing event before doing any work.
349                         try 
350                         {
351                                 comment.ReplaceData(-1, 0, "qux");
352                                 Fail("Expected an ArgumentOutOfRangeException to be thrown.");
353                         } 
354                         catch (Exception) {}
355
356                         /*
357  TODO:  Insert this when XmlNode.InnerText() and XmlNode.InnerXml() have been implemented.
358  
359                         // Node that is part of the document.
360                         element = document.CreateElement ("foo");
361                         element.InnerText = "bar";
362                         document.AppendChild(element);
363                         element.InnerText = "baz";
364                         Assert(eventStrings.Contains("NodeChanging, Change, bar, foo, foo"));
365
366                         // Node that isn't part of the document but created by the document.
367                         element = document.CreateElement("foo");
368                         element.InnerText = "bar";
369                         element.InnerText = "baz";
370                         Assert(eventStrings.Contains("NodeChanging, Change, bar, foo, foo"));
371
372                         // If an exception is thrown the Document returns to original state.
373                         document.NodeChanging += new XmlNodeChangedEventHandler (this.EventNodeChangingException);
374                         element = document.CreateElement("foo");
375                         element.InnerText = "bar";
376                         try {
377                                 element.InnerText = "baz";
378                                 Fail("Expected an exception to be thrown by the NodeChanging event handler method EventNodeChangingException().");
379                         } catch (Exception) {}
380                         AssertEquals("bar", element.InnerText);
381 */
382                 }
383
384                 public void TestEventNodeInserted()
385                 {
386                         XmlElement element;
387
388                         document.NodeInserted += new XmlNodeChangedEventHandler (this.EventNodeInserted);
389
390                         // Inserted 'foo' element to the document.
391                         element = document.CreateElement ("foo");
392                         document.AppendChild (element);
393                         Assert (eventStrings.Contains ("NodeInserted, Insert, <foo />, <none>, #document"));
394
395                         // Append child on node in document
396                         element = document.CreateElement ("foo");
397                         document.DocumentElement.AppendChild (element);
398                         Assert (eventStrings.Contains ("NodeInserted, Insert, <foo />, <none>, foo"));
399
400                         // Append child on node not in document but created by document
401                         element = document.CreateElement ("bar");
402                         element.AppendChild(document.CreateElement ("bar"));
403                         Assert(eventStrings.Contains("NodeInserted, Insert, <bar />, <none>, bar"));
404                 }
405
406                 public void TestEventNodeInserting()
407                 {
408                         XmlElement element;
409
410                         document.NodeInserting += new XmlNodeChangedEventHandler (this.EventNodeInserting);
411
412                         // Inserting 'foo' element to the document.
413                         element = document.CreateElement ("foo");
414                         document.AppendChild (element);
415                         Assert (eventStrings.Contains ("NodeInserting, Insert, <foo />, <none>, #document"));
416
417                         // Append child on node in document
418                         element = document.CreateElement ("foo");
419                         document.DocumentElement.AppendChild (element);
420                         Assert(eventStrings.Contains ("NodeInserting, Insert, <foo />, <none>, foo"));
421
422                         // Append child on node not in document but created by document
423                         element = document.CreateElement ("bar");
424                         AssertEquals (0, element.ChildNodes.Count);
425                         element.AppendChild (document.CreateElement ("bar"));
426                         Assert (eventStrings.Contains ("NodeInserting, Insert, <bar />, <none>, bar"));
427                         AssertEquals (1, element.ChildNodes.Count);
428
429                         // If an exception is thrown the Document returns to original state.
430                         document.NodeInserting += new XmlNodeChangedEventHandler (this.EventNodeInsertingException);
431                         AssertEquals (1, element.ChildNodes.Count);
432                         try 
433                         {
434                                 element.AppendChild (document.CreateElement("baz"));
435                                 Fail ("Expected an exception to be thrown by the NodeInserting event handler method EventNodeInsertingException().");
436                         } 
437                         catch (Exception) {}
438                         AssertEquals (1, element.ChildNodes.Count);
439                 }
440
441                 public void TestEventNodeRemoved()
442                 {
443                         XmlElement element;
444                         XmlElement element2;
445
446                         document.NodeRemoved += new XmlNodeChangedEventHandler (this.EventNodeRemoved);
447
448                         // Removed 'bar' element from 'foo' outside document.
449                         element = document.CreateElement ("foo");
450                         element2 = document.CreateElement ("bar");
451                         element.AppendChild (element2);
452                         AssertEquals (1, element.ChildNodes.Count);
453                         element.RemoveChild (element2);
454                         Assert (eventStrings.Contains ("NodeRemoved, Remove, <bar />, foo, <none>"));
455                         AssertEquals (0, element.ChildNodes.Count);
456
457 /*
458  * TODO:  put this test back in when AttributeCollection.RemoveAll() is implemented.
459
460                         // RemoveAll.
461                         element = document.CreateElement ("foo");
462                         element2 = document.CreateElement ("bar");
463                         element.AppendChild(element2);
464                         AssertEquals(1, element.ChildNodes.Count);
465                         element.RemoveAll();
466                         Assert (eventStrings.Contains ("NodeRemoved, Remove, <bar />, foo, <none>"));
467                         AssertEquals(0, element.ChildNodes.Count);
468 */
469
470                         // Removed 'bar' element from 'foo' inside document.
471                         element = document.CreateElement ("foo");
472                         document.AppendChild (element);
473                         element = document.CreateElement ("bar");
474                         document.DocumentElement.AppendChild (element);
475                         AssertEquals (1, document.DocumentElement.ChildNodes.Count);
476                         document.DocumentElement.RemoveChild (element);
477                         Assert (eventStrings.Contains ("NodeRemoved, Remove, <bar />, foo, <none>"));
478                         AssertEquals (0, document.DocumentElement.ChildNodes.Count);
479                 }
480         
481                 public void TestEventNodeRemoving()
482                 {
483                         XmlElement element;
484                         XmlElement element2;
485
486                         document.NodeRemoving += new XmlNodeChangedEventHandler (this.EventNodeRemoving);
487
488                         // Removing 'bar' element from 'foo' outside document.
489                         element = document.CreateElement ("foo");
490                         element2 = document.CreateElement ("bar");
491                         element.AppendChild (element2);
492                         AssertEquals (1, element.ChildNodes.Count);
493                         element.RemoveChild (element2);
494                         Assert (eventStrings.Contains ("NodeRemoving, Remove, <bar />, foo, <none>"));
495                         AssertEquals (0, element.ChildNodes.Count);
496
497 /*
498  * TODO:  put this test back in when AttributeCollection.RemoveAll() is implemented.
499
500                         // RemoveAll.
501                         element = document.CreateElement ("foo");
502                         element2 = document.CreateElement ("bar");
503                         element.AppendChild(element2);
504                         AssertEquals(1, element.ChildNodes.Count);
505                         element.RemoveAll();
506                         Assert (eventStrings.Contains ("NodeRemoving, Remove, <bar />, foo, <none>"));
507                         AssertEquals(0, element.ChildNodes.Count);
508 */
509
510                         // Removing 'bar' element from 'foo' inside document.
511                         element = document.CreateElement ("foo");
512                         document.AppendChild (element);
513                         element = document.CreateElement ("bar");
514                         document.DocumentElement.AppendChild (element);
515                         AssertEquals (1, document.DocumentElement.ChildNodes.Count);
516                         document.DocumentElement.RemoveChild (element);
517                         Assert (eventStrings.Contains ("NodeRemoving, Remove, <bar />, foo, <none>"));
518                         AssertEquals (0, document.DocumentElement.ChildNodes.Count);
519
520                         // If an exception is thrown the Document returns to original state.
521                         document.NodeRemoving += new XmlNodeChangedEventHandler (this.EventNodeRemovingException);
522                         element.AppendChild (element2);
523                         AssertEquals (1, element.ChildNodes.Count);
524                         try 
525                         {
526                                 element.RemoveChild(element2);
527                                 Fail ("Expected an exception to be thrown by the NodeRemoving event handler method EventNodeRemovingException().");
528                         } 
529                         catch (Exception) {}
530                         AssertEquals (1, element.ChildNodes.Count);
531                 }
532
533                 public void TestGetElementsByTagNameNoNameSpace ()
534                 {
535                         string xml = @"<library><book><title>XML Fun</title><author>John Doe</author>
536                                 <price>34.95</price></book><book><title>Bear and the Dragon</title>
537                                 <author>Tom Clancy</author><price>6.95</price></book><book>
538                                 <title>Bourne Identity</title><author>Robert Ludlum</author>
539                                 <price>9.95</price></book><Fluffer><Nutter><book>
540                                 <title>Bourne Ultimatum</title><author>Robert Ludlum</author>
541                                 <price>9.95</price></book></Nutter></Fluffer></library>";
542
543                         MemoryStream memoryStream = new MemoryStream (Encoding.UTF8.GetBytes (xml));
544                         document = new XmlDocument ();
545                         document.Load (memoryStream);
546                         XmlNodeList bookList = document.GetElementsByTagName ("book");
547                         AssertEquals ("GetElementsByTagName (string) returned incorrect count.", 4, bookList.Count);
548                 }
549
550         
551                 public void TestInnerAndOuterXml ()
552                 {
553                         AssertEquals (String.Empty, document.InnerXml);
554                         AssertEquals (document.InnerXml, document.OuterXml);
555
556                         XmlDeclaration declaration = document.CreateXmlDeclaration ("1.0", null, null);
557                         document.AppendChild (declaration);
558                         AssertEquals ("<?xml version=\"1.0\"?>", document.InnerXml);
559                         AssertEquals (document.InnerXml, document.OuterXml);
560
561                         XmlElement element = document.CreateElement ("foo");
562                         document.AppendChild (element);
563                         AssertEquals ("<?xml version=\"1.0\"?><foo />", document.InnerXml);
564                         AssertEquals (document.InnerXml, document.OuterXml);
565
566                         XmlComment comment = document.CreateComment ("bar");
567                         document.DocumentElement.AppendChild (comment);
568                         AssertEquals ("<?xml version=\"1.0\"?><foo><!--bar--></foo>", document.InnerXml);
569                         AssertEquals (document.InnerXml, document.OuterXml);
570
571                         XmlText text = document.CreateTextNode ("baz");
572                         document.DocumentElement.AppendChild (text);
573                         AssertEquals ("<?xml version=\"1.0\"?><foo><!--bar-->baz</foo>", document.InnerXml);
574                         AssertEquals (document.InnerXml, document.OuterXml);
575
576                         element = document.CreateElement ("quux");
577                         element.SetAttribute ("quuux", "squonk");
578                         document.DocumentElement.AppendChild (element);
579                         AssertEquals ("<?xml version=\"1.0\"?><foo><!--bar-->baz<quux quuux=\"squonk\" /></foo>", document.InnerXml);
580                         AssertEquals (document.InnerXml, document.OuterXml);
581                 }
582
583                 public void TestLoadWithSystemIOStream ()
584                 {                       
585                         string xml = @"<library><book><title>XML Fun</title><author>John Doe</author>
586                                 <price>34.95</price></book><book><title>Bear and the Dragon</title>
587                                 <author>Tom Clancy</author><price>6.95</price></book><book>
588                                 <title>Bourne Identity</title><author>Robert Ludlum</author>
589                                 <price>9.95</price></book><Fluffer><Nutter><book>
590                                 <title>Bourne Ultimatum</title><author>Robert Ludlum</author>
591                                 <price>9.95</price></book></Nutter></Fluffer></library>";
592
593                         MemoryStream memoryStream = new MemoryStream (Encoding.UTF8.GetBytes (xml));
594                         document = new XmlDocument ();
595                         document.Load (memoryStream);
596                         AssertEquals ("Not Loaded From IOStream", true, document.HasChildNodes);
597                 }
598
599                 public void TestLoadXmlCDATA ()
600                 {
601                         document.LoadXml ("<foo><![CDATA[bar]]></foo>");
602                         Assert (document.DocumentElement.FirstChild.NodeType == XmlNodeType.CDATA);
603                         AssertEquals ("bar", document.DocumentElement.FirstChild.Value);
604                 }
605
606                 public void TestLoadXMLComment()
607                 {
608 // XmlTextReader needs to throw this exception
609 //                      try {
610 //                              document.LoadXml("<!--foo-->");
611 //                              Fail("XmlException should have been thrown.");
612 //                      }
613 //                      catch (XmlException e) {
614 //                              AssertEquals("Exception message doesn't match.", "The root element is missing.", e.Message);
615 //                      }
616
617                         document.LoadXml ("<foo><!--Comment--></foo>");
618                         Assert (document.DocumentElement.FirstChild.NodeType == XmlNodeType.Comment);
619                         AssertEquals ("Comment", document.DocumentElement.FirstChild.Value);
620
621                         document.LoadXml (@"<foo><!--bar--></foo>");
622                         AssertEquals ("Incorrect target.", "bar", ((XmlComment)document.FirstChild.FirstChild).Data);
623                 }
624
625                 public void TestLoadXmlElementSingle ()
626                 {
627                         AssertNull (document.DocumentElement);
628                         document.LoadXml ("<foo/>");
629
630                         AssertNotNull (document.DocumentElement);
631                         AssertSame (document.FirstChild, document.DocumentElement);
632
633                         AssertEquals (String.Empty, document.DocumentElement.Prefix);
634                         AssertEquals ("foo", document.DocumentElement.LocalName);
635                         AssertEquals (String.Empty, document.DocumentElement.NamespaceURI);
636                         AssertEquals ("foo", document.DocumentElement.Name);
637                 }
638
639                 public void TestLoadXmlElementWithAttributes ()
640                 {
641                         AssertNull (document.DocumentElement);
642                         document.LoadXml ("<foo bar='baz' quux='quuux'/>");
643
644                         XmlElement documentElement = document.DocumentElement;
645
646                         AssertEquals ("baz", documentElement.GetAttribute ("bar"));
647                         AssertEquals ("quuux", documentElement.GetAttribute ("quux"));
648                 }
649                 public void TestLoadXmlElementWithChildElement ()
650                 {
651                         document.LoadXml ("<foo><bar/></foo>");
652                         Assert (document.ChildNodes.Count == 1);
653                         Assert (document.FirstChild.ChildNodes.Count == 1);
654                         AssertEquals ("foo", document.DocumentElement.LocalName);
655                         AssertEquals ("bar", document.DocumentElement.FirstChild.LocalName);
656                 }
657
658                 public void TestLoadXmlElementWithTextNode ()
659                 {
660                         document.LoadXml ("<foo>bar</foo>");
661                         Assert (document.DocumentElement.FirstChild.NodeType == XmlNodeType.Text);
662                         AssertEquals ("bar", document.DocumentElement.FirstChild.Value);
663                 }
664
665                 public void TestLoadXmlExceptionClearsDocument ()
666                 {
667                         document.LoadXml ("<foo/>");
668                         Assert (document.FirstChild != null);
669                         
670                         try {
671                                 document.LoadXml ("<123/>");
672                                 Fail ("An XmlException should have been thrown.");
673                         } catch (XmlException) {}
674
675                         Assert (document.FirstChild == null);
676                 }
677
678                 public void TestLoadXmlProcessingInstruction ()
679                 {
680                         document.LoadXml (@"<?foo bar='baaz' quux='quuux'?><quuuux></quuuux>");
681                         AssertEquals ("Incorrect target.", "foo", ((XmlProcessingInstruction)document.FirstChild).Target);
682                         AssertEquals ("Incorrect data.", "bar='baaz' quux='quuux'", ((XmlProcessingInstruction)document.FirstChild).Data);
683                 }
684
685                 public void TestOuterXml ()
686                 {
687                         string xml;
688                         
689                         xml = "<root><![CDATA[foo]]></root>";
690                         document.LoadXml (xml);
691                         AssertEquals("XmlDocument with cdata OuterXml is incorrect.", xml, document.OuterXml);
692
693                         xml = "<root><!--foo--></root>";
694                         document.LoadXml (xml);
695                         AssertEquals("XmlDocument with comment OuterXml is incorrect.", xml, document.OuterXml);
696
697                         xml = "<root><?foo bar?></root>";
698                         document.LoadXml (xml);
699                         AssertEquals("XmlDocument with processing instruction OuterXml is incorrect.", xml, document.OuterXml);
700                 }
701
702                 public void TestParentNodes ()
703                 {
704                         document.LoadXml ("<foo><bar><baz/></bar></foo>");
705                         XmlNode node = document.FirstChild.FirstChild.FirstChild;
706                         AssertEquals ("Wrong child found.", "baz", node.LocalName);
707                         AssertEquals ("Wrong parent.", "bar", node.ParentNode.LocalName);
708                         AssertEquals ("Wrong parent.", "foo", node.ParentNode.ParentNode.LocalName);
709                         AssertEquals ("Wrong parent.", "#document", node.ParentNode.ParentNode.ParentNode.LocalName);
710                         AssertNull ("Expected parent to be null.", node.ParentNode.ParentNode.ParentNode.ParentNode);
711                 }
712
713                 public void TestRemovedElementNextSibling ()
714                 {
715                         XmlNode node;
716                         XmlNode nextSibling;
717
718                         document.LoadXml ("<foo><child1/><child2/></foo>");
719                         node = document.DocumentElement.FirstChild;
720                         document.DocumentElement.RemoveChild (node);
721                         nextSibling = node.NextSibling;
722                         AssertNull ("Expected removed node's next sibling to be null.", nextSibling);
723                 }
724         }
725 }