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