2003-07-26 Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
[mono.git] / mcs / class / System.XML / Test / System.Xml / XmlElementTests.cs
1 //
2 // XmlElementTests
3 //
4 // Authors:
5 //   Jason Diamond (jason@injektilo.org)
6 //   Martin Willemoes Hansen (mwh@sysrq.dk)
7 //
8 // (C) 2002 Jason Diamond  http://injektilo.org/
9 // (C) 2003 Martin Willemoes Hansen 
10 //
11
12 using System;
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         [TestFixture]
22         public class XmlElementTests  : Assertion
23         {
24                 private XmlDocument document;
25
26                 [SetUp]
27                 public void GetReady ()
28                 {
29                         document = new XmlDocument ();
30                 }
31
32                 private void AssertElement (XmlElement element, string prefix,
33                                             string localName, string namespaceURI,
34                                             int attributesCount)
35                 {
36                         AssertEquals (prefix != String.Empty ? prefix + ":" + localName : localName, element.Name);
37                         AssertEquals (prefix, element.Prefix);
38                         AssertEquals (localName, element.LocalName);
39                         AssertEquals (namespaceURI, element.NamespaceURI);
40                         //AssertEquals (attributesCount, element.Attributes.Count);
41                 }
42
43                 // for NodeInserted Event
44                 private bool Inserted = false;
45                 private void OnNodeInserted (object o, XmlNodeChangedEventArgs e)
46                 {
47                         Inserted = true;
48                 }
49
50                 // for NodeChanged Event
51                 private bool Changed = false;
52                 private void OnNodeChanged (object o, XmlNodeChangedEventArgs e)
53                 {
54                         Changed = true;
55                 }
56
57                 // for NodeRemoved Event
58                 private bool Removed = false;
59                 private void OnNodeRemoved (object o, XmlNodeChangedEventArgs e)
60                 {
61                         Removed = true;
62                 }
63
64                 [Test]
65                 public void CloneNode ()
66                 {
67                         XmlElement element = document.CreateElement ("foo");
68                         XmlElement child = document.CreateElement ("bar");
69                         XmlElement grandson = document.CreateElement ("baz");
70
71                         element.SetAttribute ("attr1", "val1");
72                         element.SetAttribute ("attr2", "val2");
73                         element.AppendChild (child);
74                         child.SetAttribute ("attr3", "val3");
75                         child.AppendChild (grandson);
76                         
77                         document.AppendChild (element);
78                         XmlNode deep = element.CloneNode (true);
79                         // AssertEquals ("These should be the same", deep.OuterXml, element.OuterXml); 
80                         AssertNull ("This is not null", deep.ParentNode);
81                         Assert ("Copies, not pointers", !Object.ReferenceEquals (element,deep));
82
83                         XmlNode shallow = element.CloneNode (false);
84                         AssertNull ("This is not null", shallow.ParentNode);
85                         Assert ("Copies, not pointers", !Object.ReferenceEquals (element,shallow));
86                         AssertEquals ("Shallow clones shalt have no children!", false, shallow.HasChildNodes);
87                 }
88
89                 [Test]
90                 public void CreateElement1 ()
91                 {
92                         XmlElement element = document.CreateElement ("name");
93                         AssertElement (element, String.Empty, "name", String.Empty, 0);
94                 }
95
96                 [Test]
97                 public void CreateElement1WithPrefix ()
98                 {
99                         XmlElement element = document.CreateElement ("prefix:localName");
100                         AssertElement (element, "prefix", "localName", String.Empty, 0);
101                 }
102
103                 [Test]
104                 public void CreateElement2 ()
105                 {
106                         XmlElement element = document.CreateElement ("qualifiedName", "namespaceURI");
107                         AssertElement (element, String.Empty, "qualifiedName",
108                                        "namespaceURI", 0);
109                 }
110
111                 [Test]
112                 public void CreateElement2WithPrefix ()
113                 {
114                         XmlElement element = document.CreateElement ("prefix:localName", "namespaceURI");
115                         AssertElement (element, "prefix", "localName", "namespaceURI", 0);
116                 }
117
118                 [Test]
119                 public void CreateElement3 ()
120                 {
121                         XmlElement element = document.CreateElement ("prefix", "localName", "namespaceURI");
122                         AssertElement (element, "prefix", "localName", "namespaceURI", 0);
123                 }
124
125                 [Test]
126                 public void CreateElement3WithNullNamespace ()
127                 {
128                         // bug #26855, NamespaceURI should NEVER be null.
129                         XmlElement element = document.CreateElement (null, "localName", null);
130                         AssertElement (element, String.Empty, "localName", String.Empty, 0);
131                 }
132
133                 [Test]
134                 public void InnerAndOuterXml ()
135                 {
136                         XmlElement element;
137                         XmlText text;
138                         XmlComment comment;
139                         
140                         element = document.CreateElement ("foo");
141                         AssertEquals (String.Empty, element.InnerXml);
142                         AssertEquals ("<foo />", element.OuterXml);
143
144                         text = document.CreateTextNode ("bar");
145                         element.AppendChild (text);
146                         AssertEquals ("bar", element.InnerXml);
147                         AssertEquals ("<foo>bar</foo>", element.OuterXml);
148
149                         element.SetAttribute ("baz", "quux");
150                         AssertEquals ("bar", element.InnerXml);
151                         AssertEquals ("<foo baz=\"quux\">bar</foo>", element.OuterXml);
152
153                         comment = document.CreateComment ("squonk");
154                         element.AppendChild (comment);
155                         AssertEquals ("bar<!--squonk-->", element.InnerXml);
156                         AssertEquals ("<foo baz=\"quux\">bar<!--squonk--></foo>", element.OuterXml);
157
158                         element.RemoveAll();
159                         element.AppendChild(document.CreateElement("hoge"));
160                         AssertEquals ("<hoge />", element.InnerXml);
161                 }
162
163                 [Test]
164                 public void SetGetAttribute ()
165                 {
166                         XmlElement element = document.CreateElement ("foo");
167                         element.SetAttribute ("attr1", "val1");
168                         element.SetAttribute ("attr2", "val2");
169                         AssertEquals ("val1", element.GetAttribute ("attr1"));
170                         AssertEquals ("val2", element.GetAttribute ("attr2"));
171                 }
172
173                 [Test]
174                 public void GetElementsByTagNameNoNameSpace ()
175                 {
176                         string xml = @"<library><book><title>XML Fun</title><author>John Doe</author>
177                                 <price>34.95</price></book><book><title>Bear and the Dragon</title>
178                                 <author>Tom Clancy</author><price>6.95</price></book><book>
179                                 <title>Bourne Identity</title><author>Robert Ludlum</author>
180                                 <price>9.95</price></book><Fluffer><Nutter><book>
181                                 <title>Bourne Ultimatum</title><author>Robert Ludlum</author>
182                                 <price>9.95</price></book></Nutter></Fluffer></library>";
183
184                         MemoryStream memoryStream = new MemoryStream (Encoding.UTF8.GetBytes (xml));
185                         document = new XmlDocument ();
186                         document.Load (memoryStream);
187                         XmlNodeList libraryList = document.GetElementsByTagName ("library");
188                         XmlNode xmlNode = libraryList.Item (0);
189                         XmlElement xmlElement = xmlNode as XmlElement;
190                         XmlNodeList bookList = xmlElement.GetElementsByTagName ("book");
191                         AssertEquals ("GetElementsByTagName (string) returned incorrect count.", 4, bookList.Count);
192                 }
193
194                 [Test]
195                 public void GetElementsByTagNameUsingNameSpace ()
196                 {
197                         StringBuilder xml = new StringBuilder ();
198                         xml.Append ("<?xml version=\"1.0\" ?><library xmlns:North=\"http://www.foo.com\" ");
199                         xml.Append ("xmlns:South=\"http://www.goo.com\"><North:book type=\"non-fiction\"> ");
200                         xml.Append ("<North:title type=\"intro\">XML Fun</North:title> " );
201                         xml.Append ("<North:author>John Doe</North:author> " );
202                         xml.Append ("<North:price>34.95</North:price></North:book> " );
203                         xml.Append ("<South:book type=\"fiction\"> " );
204                         xml.Append ("<South:title>Bear and the Dragon</South:title> " );
205                         xml.Append ("<South:author>Tom Clancy</South:author> " );
206                         xml.Append ("<South:price>6.95</South:price></South:book> " );
207                         xml.Append ("<South:book type=\"fiction\"><South:title>Bourne Identity</South:title> " );
208                         xml.Append ("<South:author>Robert Ludlum</South:author> " );
209                         xml.Append ("<South:price>9.95</South:price></South:book></library>");
210
211                         MemoryStream memoryStream = new MemoryStream (Encoding.UTF8.GetBytes (xml.ToString ()));
212                         document = new XmlDocument ();
213                         document.Load (memoryStream);
214                         XmlNodeList libraryList = document.GetElementsByTagName ("library");
215                         XmlNode xmlNode = libraryList.Item (0);
216                         XmlElement xmlElement = xmlNode as XmlElement;
217                         XmlNodeList bookList = xmlElement.GetElementsByTagName ("book", "http://www.foo.com");
218                         AssertEquals ("GetElementsByTagName (string, uri) returned incorrect count.", 1, bookList.Count);
219                 }
220
221                 [Test]
222                 public void OuterXmlWithNamespace ()
223                 {
224                         XmlElement element = document.CreateElement ("foo", "bar", "#foo");
225                         AssertEquals ("<foo:bar xmlns:foo=\"#foo\" />", element.OuterXml);
226                 }               
227
228                 [Test]
229                 public void RemoveAllAttributes ()
230                 {
231                         StringBuilder xml = new StringBuilder ();
232                         xml.Append ("<?xml version=\"1.0\" ?><library><book type=\"non-fiction\" price=\"34.95\"> ");
233                         xml.Append ("<title type=\"intro\">XML Fun</title> " );
234                         xml.Append ("<author>John Doe</author></book></library>");
235
236                         MemoryStream memoryStream = new MemoryStream (Encoding.UTF8.GetBytes (xml.ToString ()));
237                         document = new XmlDocument ();
238                         document.Load (memoryStream);
239                         XmlNodeList bookList = document.GetElementsByTagName ("book");
240                         XmlNode xmlNode = bookList.Item (0);
241                         XmlElement xmlElement = xmlNode as XmlElement;
242                         xmlElement.RemoveAllAttributes ();
243                         AssertEquals ("attributes not properly removed.", false, xmlElement.HasAttribute ("type"));
244                 }
245
246                 [Test]
247                 public void SetAttributeNode ()
248                 {
249                         XmlDocument xmlDoc = new XmlDocument ();
250                         XmlElement xmlEl = xmlDoc.CreateElement ("TestElement");
251                         XmlAttribute xmlAttribute = xmlEl.SetAttributeNode ("attr1", "namespace1");
252                         XmlAttribute xmlAttribute2 = xmlEl.SetAttributeNode ("attr2", "namespace2");
253                         AssertEquals ("attribute name not properly created.", true, xmlAttribute.Name.Equals ("attr1"));
254                         AssertEquals ("attribute namespace not properly created.", true, xmlAttribute.NamespaceURI.Equals ("namespace1"));
255                 }
256
257                 [Test]
258                 public void InnerTextAndEvent ()
259                 {
260                         XmlDocument doc = new XmlDocument ();
261                         doc.LoadXml ("<root><child>text</child><child2><![CDATA[cdata]]></child2></root>");
262                         doc.NodeInserted += new XmlNodeChangedEventHandler (
263                                 OnNodeInserted);
264                         doc.NodeRemoved += new XmlNodeChangedEventHandler (
265                                 OnNodeRemoved);
266                         // If only one child of the element is Text node,
267                         // then no events are fired.
268                         doc.DocumentElement.FirstChild.InnerText = "no events fired.";
269                         AssertEquals ("NoInsertEventFired", false, Inserted);
270                         AssertEquals ("NoRemoveEventFired", false, Removed);
271                         AssertEquals ("SetInnerTextToSingleText", "no events fired.", doc.DocumentElement.FirstChild.InnerText);
272                         Inserted = false;
273                         Removed = false;
274
275                         // if only one child of the element is CDataSection,
276                         // then events are fired.
277                         doc.DocumentElement.LastChild.InnerText = "events are fired.";
278                         AssertEquals ("InsertedEventFired", true, Inserted);
279                         AssertEquals ("RemovedEventFired", true, Removed);
280                         AssertEquals ("SetInnerTextToCDataSection", "events are fired.", doc.DocumentElement.LastChild.InnerText);
281                 }
282
283                 [Test]
284                 public void InnerXmlSetter ()
285                 {
286                         XmlDocument doc = new XmlDocument ();
287                         doc.LoadXml ("<root/>");
288                         XmlElement el =  doc.DocumentElement;
289                         AssertNull ("#Simple", el.FirstChild);
290                         el.InnerXml = "<foo><bar att='baz'/></foo>";
291                         XmlElement child = el.FirstChild as XmlElement;
292                         AssertNotNull ("#Simple.Child", child);
293                         AssertEquals ("#Simple.Child.Name", "foo", child.LocalName);
294
295                         XmlElement grandchild = child.FirstChild as XmlElement;
296                         AssertNotNull ("#Simple.GrandChild", grandchild);
297                         AssertEquals ("#Simple.GrandChild.Name", "bar", grandchild.LocalName);
298                         AssertEquals ("#Simple.GrandChild.Attr", "baz", grandchild.GetAttribute ("att"));
299
300                         doc.LoadXml ("<root xmlns='NS0' xmlns:ns1='NS1'><foo/><ns1:bar/><ns2:bar xmlns:ns2='NS2' /></root>");
301                         el = doc.DocumentElement.FirstChild.NextSibling as XmlElement;  // ns1:bar
302                         AssertNull ("#Namespaced.Prepare", el.FirstChild);
303                         el.InnerXml = "<ns1:baz />";
304                         AssertNotNull ("#Namespaced.Child", el.FirstChild);
305                         AssertEquals ("#Namespaced.Child.Name", "baz", el.FirstChild.LocalName);
306                         AssertEquals ("#Namespaced.Child.NSURI", "NS1", el.FirstChild.NamespaceURI);    // important!
307
308                         el.InnerXml = "<hoge />";
309                         AssertEquals ("#Namespaced.VerifyPreviousCleared", "hoge", el.FirstChild.Name);
310                 }
311
312                 [Test]
313                 public void IsEmpty ()
314                 {
315                         document.LoadXml ("<root><foo/><bar></bar></root>");
316                         Assertion.AssertEquals ("Empty", true, ((XmlElement) document.DocumentElement.FirstChild).IsEmpty);
317                         Assertion.AssertEquals ("Empty", false, ((XmlElement) document.DocumentElement.LastChild).IsEmpty);
318                 }
319
320                 [Test]
321                 public void RemoveAttribute ()
322                 {
323                         string xlinkURI = "http://www.w3.org/1999/XLink";
324                         XmlDocument doc = new XmlDocument ();
325                         doc.LoadXml ("<root a1='1' a2='2' xlink:href='urn:foo' xmlns:xlink='" + xlinkURI + "' />");
326
327                         XmlElement el =  doc.DocumentElement;
328                         el.RemoveAttribute ("a1");
329                         AssertNull ("RemoveAttribute", el.GetAttributeNode ("a1"));
330                         el.RemoveAttribute ("xlink:href");
331                         AssertNull ("RemoveAttribute", el.GetAttributeNode ("href", xlinkURI));
332                         el.RemoveAllAttributes ();
333                         AssertNull ("RemoveAllAttributes", el.GetAttributeNode ("a2"));
334                 }
335
336                 [Test]
337                 public void WriteToWithDefaultNamespace ()
338                 {
339                         XmlDocument doc = new XmlDocument ();
340                         doc.LoadXml ("<RetrievalElement URI=\"\" xmlns=\"http://www.w3.org/2000/09/xmldsig#\" />");
341                         StringWriter sw = new StringWriter ();
342                         XmlTextWriter xtw = new XmlTextWriter (sw);
343                         doc.DocumentElement.WriteTo (xtw);
344                         AssertEquals ("<RetrievalElement URI=\"\" xmlns=\"http://www.w3.org/2000/09/xmldsig#\" />", sw.ToString());
345                 }
346
347                 [Test]
348                 public void WriteToWithDeletedNamespacePrefix ()
349                 {
350                         XmlDocument doc = new XmlDocument ();
351                         doc.LoadXml ("<root xmlns:foo='urn:dummy'><foo foo:bar='baz' /></root>");
352                         doc.DocumentElement.RemoveAllAttributes ();
353
354                         Assert (doc.DocumentElement.FirstChild.OuterXml.IndexOf("xmlns:foo") > 0);
355                 }
356
357                 [Test]
358                 public void WriteToWithDifferentNamespaceAttributes ()
359                 {
360                         XmlDocument doc = new XmlDocument ();
361                         doc.LoadXml ("<root xmlns:foo='urn:dummy' xmlns:html='http://www.w3.org/1999/xhtml' html:style='font-size: 1em'></root>");
362                         Assert (doc.OuterXml.IndexOf ("xmlns:html=\"http://www.w3.org/1999/xhtml\"") > 0);
363                 }
364
365         }
366 }