Merge pull request #136 from spencerhakim/master
[mono.git] / mcs / class / System.XML / Test / System.Xml.XPath / XPathNavigatorCommonTests.cs
1 //
2 // MonoTests.System.Xml.XPathNavigatorCommonTests
3 //
4 // Author:
5 //      Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
6 //
7 // (C) 2003 Atsushi Enomoto
8 //
9
10 using System;
11 using System.IO;
12 using System.Xml;
13 using System.Xml.XPath;
14 using NUnit.Framework;
15
16 namespace MonoTests.System.Xml
17 {
18         [TestFixture]
19         public class XPathNavigatorCommonTests
20         {
21                 XmlDocument document;
22                 XPathNavigator nav;
23                 XPathDocument xpathDocument;
24
25                 [SetUp]
26                 public void GetReady ()
27                 {
28                         document = new XmlDocument ();
29                 }
30
31                 private XPathNavigator GetXmlDocumentNavigator (string xml)
32                 {
33                         document.LoadXml (xml);
34                         return document.CreateNavigator ();
35                 }
36                 
37                 private XPathNavigator GetXPathDocumentNavigator (XmlNode node)
38                 {
39                         XmlNodeReader xr = new XmlNodeReader (node);
40                         xpathDocument = new XPathDocument (xr);
41                         return xpathDocument.CreateNavigator ();
42                 }
43
44                 private XPathNavigator GetXPathDocumentNavigator (XmlNode node, XmlSpace space)
45                 {
46                         XmlNodeReader xr = new XmlNodeReader (node);
47                         xpathDocument = new XPathDocument (xr, space);
48                         return xpathDocument.CreateNavigator ();
49                 }
50
51                 private void AssertNavigator (string label, XPathNavigator nav, XPathNodeType type, string prefix, string localName, string ns, string name, string value, bool hasAttributes, bool hasChildren, bool isEmptyElement)
52                 {
53                         label += nav.GetType ();
54                         Assert.AreEqual (type, nav.NodeType, label + "NodeType");
55                         Assert.AreEqual (prefix, nav.Prefix, label + "Prefix");
56                         Assert.AreEqual (localName, nav.LocalName, label + "LocalName");
57                         Assert.AreEqual (ns, nav.NamespaceURI, label + "Namespace");
58                         Assert.AreEqual (name, nav.Name, label + "Name");
59                         Assert.AreEqual (value, nav.Value, label + "Value");
60                         Assert.AreEqual (hasAttributes, nav.HasAttributes, label + "HasAttributes");
61                         Assert.AreEqual (hasChildren, nav.HasChildren, label + "HasChildren");
62                         Assert.AreEqual (isEmptyElement, nav.IsEmptyElement, label + "IsEmptyElement");
63                 }
64
65                 [Test]
66                 public void DocumentWithXmlDeclaration ()
67                 {
68                         string xml = "<?xml version=\"1.0\" standalone=\"yes\"?><foo>bar</foo>";
69
70                         nav = GetXmlDocumentNavigator (xml);
71                         DocumentWithXmlDeclaration (nav);
72                         nav = GetXPathDocumentNavigator (document);
73                         DocumentWithXmlDeclaration (nav);
74                 }
75
76                 public void DocumentWithXmlDeclaration (XPathNavigator nav)
77                 {
78                         nav.MoveToFirstChild ();
79                         AssertNavigator ("#1", nav, XPathNodeType.Element, "", "foo", "", "foo", "bar", false, true, false);
80                 }
81
82                 [Test]
83                 public void DocumentWithProcessingInstruction ()
84                 {
85                         string xml = "<?xml-stylesheet href='foo.xsl' type='text/xsl' ?><foo />";
86
87                         nav = GetXmlDocumentNavigator (xml);
88                         DocumentWithProcessingInstruction (nav);
89                         nav = GetXPathDocumentNavigator (document);
90                         DocumentWithProcessingInstruction (nav);
91                 }
92
93                 public void DocumentWithProcessingInstruction (XPathNavigator nav)
94                 {
95                         Assert.IsTrue (nav.MoveToFirstChild ());
96                         AssertNavigator ("#1", nav, XPathNodeType.ProcessingInstruction, "", "xml-stylesheet", "", "xml-stylesheet", "href='foo.xsl' type='text/xsl' ", false, false, false);
97                         Assert.IsTrue (!nav.MoveToFirstChild ());
98                 }
99
100                 [Test]
101                 public void XmlRootElementOnly ()
102                 {
103                         string xml = "<foo />";
104
105                         nav = GetXmlDocumentNavigator (xml);
106                         XmlRootElementOnly (nav);
107                         nav = GetXPathDocumentNavigator (document);
108                         XmlRootElementOnly (nav);
109                 }
110
111                 private void XmlRootElementOnly (XPathNavigator nav)
112                 {
113                         AssertNavigator ("#1", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
114                         Assert.IsTrue (nav.MoveToFirstChild ());
115                         AssertNavigator ("#2", nav, XPathNodeType.Element, "", "foo", "", "foo", "", false, false, true);
116                         Assert.IsTrue (!nav.MoveToFirstChild ());
117                         Assert.IsTrue (!nav.MoveToNext ());
118                         Assert.IsTrue (!nav.MoveToPrevious ());
119                         nav.MoveToRoot ();
120                         AssertNavigator ("#3", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
121                         Assert.IsTrue (!nav.MoveToNext ());
122                 }
123
124                 [Test]
125                 public void XmlSimpleTextContent ()
126                 {
127                         string xml = "<foo>Test.</foo>";
128
129                         nav = GetXmlDocumentNavigator (xml);
130                         XmlSimpleTextContent (nav);
131                         nav = GetXPathDocumentNavigator (document);
132                         XmlSimpleTextContent (nav);
133                 }
134
135                 private void XmlSimpleTextContent (XPathNavigator nav)
136                 {
137                         AssertNavigator ("#1", nav, XPathNodeType.Root, "", "", "", "", "Test.", false, true, false);
138                         Assert.IsTrue (nav.MoveToFirstChild ());
139                         AssertNavigator ("#2", nav, XPathNodeType.Element, "", "foo", "", "foo", "Test.", false, true, false);
140                         Assert.IsTrue (!nav.MoveToNext ());
141                         Assert.IsTrue (!nav.MoveToPrevious ());
142                         Assert.IsTrue (nav.MoveToFirstChild ());
143                         AssertNavigator ("#3", nav, XPathNodeType.Text, "", "", "", "", "Test.", false, false, false);
144
145                         Assert.IsTrue (nav.MoveToParent ());
146                         AssertNavigator ("#4", nav, XPathNodeType.Element, "", "foo", "", "foo", "Test.", false, true, false);
147
148                         Assert.IsTrue (nav.MoveToParent ());
149                         AssertNavigator ("#5", nav, XPathNodeType.Root, "", "", "", "", "Test.", false, true, false);
150
151                         nav.MoveToFirstChild ();
152                         nav.MoveToFirstChild ();
153                         nav.MoveToRoot ();
154                         AssertNavigator ("#6", nav, XPathNodeType.Root, "", "", "", "", "Test.", false, true, false);
155                         Assert.IsTrue (!nav.MoveToNext ());
156                 }
157
158                 [Test]
159                 public void XmlSimpleElementContent ()
160                 {
161                         string xml = "<foo><bar /></foo>";
162
163                         nav = GetXmlDocumentNavigator (xml);
164                         XmlSimpleElementContent (nav);
165                         nav = GetXPathDocumentNavigator (document);
166                         XmlSimpleElementContent (nav);
167                 }
168
169                 private void XmlSimpleElementContent (XPathNavigator nav)
170                 {
171                         AssertNavigator ("#1", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
172                         Assert.IsTrue (nav.MoveToFirstChild ());
173                         AssertNavigator ("#2", nav, XPathNodeType.Element, "", "foo", "", "foo", "", false, true, false);
174                         Assert.IsTrue (!nav.MoveToNext ());
175                         Assert.IsTrue (!nav.MoveToPrevious ());
176
177                         Assert.IsTrue (nav.MoveToFirstChild ());
178                         AssertNavigator ("#3", nav, XPathNodeType.Element, "", "bar", "", "bar", "", false, false, true);
179
180                         Assert.IsTrue (nav.MoveToParent ());
181                         AssertNavigator ("#4", nav, XPathNodeType.Element, "", "foo", "", "foo", "", false, true, false);
182
183                         nav.MoveToRoot ();
184                         AssertNavigator ("#5", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
185                         Assert.IsTrue (!nav.MoveToNext ());
186                 }
187
188                 [Test]
189                 public void XmlTwoElementsContent ()
190                 {
191                         string xml = "<foo><bar /><baz /></foo>";
192
193                         nav = GetXmlDocumentNavigator (xml);
194                         XmlTwoElementsContent (nav);
195                         nav = GetXPathDocumentNavigator (document);
196                         XmlTwoElementsContent (nav);
197                 }
198
199                 private void XmlTwoElementsContent (XPathNavigator nav)
200                 {
201                         AssertNavigator ("#1", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
202
203                         Assert.IsTrue (nav.MoveToFirstChild ());
204                         AssertNavigator ("#2", nav, XPathNodeType.Element, "", "foo", "", "foo", "", false, true, false);
205                         Assert.IsTrue (!nav.MoveToNext ());
206                         Assert.IsTrue (!nav.MoveToPrevious ());
207
208                         Assert.IsTrue (nav.MoveToFirstChild ());
209                         AssertNavigator ("#3", nav, XPathNodeType.Element, "", "bar", "", "bar", "", false, false, true);
210                         Assert.IsTrue (!nav.MoveToFirstChild ());
211
212                         Assert.IsTrue (nav.MoveToNext ());
213                         AssertNavigator ("#4", nav, XPathNodeType.Element, "", "baz", "", "baz", "", false, false, true);
214                         Assert.IsTrue (!nav.MoveToFirstChild ());
215
216                         Assert.IsTrue (nav.MoveToPrevious ());
217                         AssertNavigator ("#5", nav, XPathNodeType.Element, "", "bar", "", "bar", "", false, false, true);
218
219                         nav.MoveToRoot ();
220                         AssertNavigator ("#6", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
221                         Assert.IsTrue (!nav.MoveToNext ());
222                 }
223
224                 [Test]
225                 public void XmlElementWithAttributes ()
226                 {
227                         string xml = "<img src='foo.png' alt='image Fooooooo!' />";
228
229                         nav = GetXmlDocumentNavigator (xml);
230                         XmlElementWithAttributes (nav);
231                         nav = GetXPathDocumentNavigator (document);
232                         XmlElementWithAttributes (nav);
233                 }
234
235                 private void XmlElementWithAttributes (XPathNavigator nav)
236                 {
237                         nav.MoveToFirstChild ();
238                         AssertNavigator ("#1", nav, XPathNodeType.Element, "", "img", "", "img", "", true, false, true);
239                         Assert.IsTrue (!nav.MoveToNext ());
240                         Assert.IsTrue (!nav.MoveToPrevious ());
241
242                         Assert.IsTrue (nav.MoveToFirstAttribute ());
243                         AssertNavigator ("#2", nav, XPathNodeType.Attribute, "", "src", "", "src", "foo.png", false, false, false);
244                         Assert.IsTrue (!nav.MoveToFirstAttribute ());   // On attributes, it fails.
245
246                         Assert.IsTrue (nav.MoveToNextAttribute ());
247                         AssertNavigator ("#3", nav, XPathNodeType.Attribute, "", "alt", "", "alt", "image Fooooooo!", false, false, false);
248                         Assert.IsTrue (!nav.MoveToNextAttribute ());
249
250                         Assert.IsTrue (nav.MoveToParent ());
251                         AssertNavigator ("#4", nav, XPathNodeType.Element, "", "img", "", "img", "", true, false, true);
252
253                         Assert.IsTrue (nav.MoveToAttribute ("alt", ""));
254                         AssertNavigator ("#5", nav, XPathNodeType.Attribute, "", "alt", "", "alt", "image Fooooooo!", false, false, false);
255                         Assert.IsTrue (!nav.MoveToAttribute ("src", ""));       // On attributes, it fails.
256                         Assert.IsTrue (nav.MoveToParent ());
257                         Assert.IsTrue (nav.MoveToAttribute ("src", ""));
258                         AssertNavigator ("#6", nav, XPathNodeType.Attribute, "", "src", "", "src", "foo.png", false, false, false);
259
260                         nav.MoveToRoot ();
261                         AssertNavigator ("#7", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
262                 }
263
264                 [Test]
265                 // seems like MS does not want to fix their long-time-known
266                 // XPathNavigator bug, so just set it as NotDotNet.
267                 // We are better.
268                 [Category ("NotDotNet")]
269                 public void XmlNamespaceNode ()
270                 {
271                         string xml = "<html xmlns='http://www.w3.org/1999/xhtml'><body>test.</body></html>";
272
273                         nav = GetXmlDocumentNavigator (xml);
274                         XmlNamespaceNode (nav);
275                         nav = GetXPathDocumentNavigator (document);
276                         XmlNamespaceNode (nav);
277                 }
278
279                 private void XmlNamespaceNode (XPathNavigator nav)
280                 {
281                         string xhtml = "http://www.w3.org/1999/xhtml";
282                         string xmlNS = "http://www.w3.org/XML/1998/namespace";
283                         nav.MoveToFirstChild ();
284                         AssertNavigator ("#1", nav, XPathNodeType.Element,
285                                 "", "html", xhtml, "html", "test.", false, true, false);
286                         Assert.IsTrue (nav.MoveToFirstNamespace (XPathNamespaceScope.Local));
287                         AssertNavigator ("#2", nav, XPathNodeType.Namespace,
288                                 "", "", "", "", xhtml, false, false, false);
289
290                         // Test difference between Local, ExcludeXml and All.
291                         Assert.IsTrue (!nav.MoveToNextNamespace (XPathNamespaceScope.Local));
292                         Assert.IsTrue (!nav.MoveToNextNamespace (XPathNamespaceScope.ExcludeXml));
293                         // LAMESPEC: MS.NET 1.0 XmlDocument seems to have some bugs around here.
294                         // see http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q316808
295 #if true
296                         Assert.IsTrue (nav.MoveToNextNamespace (XPathNamespaceScope.All));
297                         AssertNavigator ("#3", nav, XPathNodeType.Namespace,
298                                 "", "xml", "", "xml", xmlNS, false, false, false);
299                         Assert.IsTrue (!nav.MoveToNextNamespace (XPathNamespaceScope.All));
300 #endif
301                         // Test to check if MoveToRoot() resets Namespace node status.
302                         nav.MoveToRoot ();
303                         AssertNavigator ("#4", nav, XPathNodeType.Root, "", "", "", "", "test.", false, true, false);
304                         nav.MoveToFirstChild ();
305
306                         // Test without XPathNamespaceScope argument.
307                         Assert.IsTrue (nav.MoveToFirstNamespace ());
308                         Assert.IsTrue (nav.MoveToNextNamespace ());
309                         AssertNavigator ("#5", nav, XPathNodeType.Namespace,
310                                 "", "xml", "", "xml", xmlNS, false, false, false);
311
312                         // Test MoveToParent()
313                         Assert.IsTrue (nav.MoveToParent ());
314                         AssertNavigator ("#6", nav, XPathNodeType.Element,
315                                 "", "html", xhtml, "html", "test.", false, true, false);
316
317                         nav.MoveToFirstChild ();        // body
318                         // Test difference between Local and ExcludeXml
319                         Assert.IsTrue (!nav.MoveToFirstNamespace (XPathNamespaceScope.Local), "Local should fail");
320                         Assert.IsTrue (nav.MoveToFirstNamespace (XPathNamespaceScope.ExcludeXml), "ExcludeXml should succeed");
321                         AssertNavigator ("#7", nav, XPathNodeType.Namespace,
322                                 "", "", "", "", xhtml, false, false, false);
323
324                         Assert.IsTrue (nav.MoveToNextNamespace (XPathNamespaceScope.All));
325                         AssertNavigator ("#8", nav, XPathNodeType.Namespace,
326                                 "", "xml", "", "xml", xmlNS, false, false, false);
327                         Assert.IsTrue (nav.MoveToParent ());
328                         AssertNavigator ("#9", nav, XPathNodeType.Element,
329                                 "", "body", xhtml, "body", "test.", false, true, false);
330
331                         nav.MoveToRoot ();
332                         AssertNavigator ("#10", nav, XPathNodeType.Root, "", "", "", "", "test.", false, true, false);
333                 }
334
335                 [Test]
336                 public void MoveToNamespaces ()
337                 {
338                         string xml = "<a xmlns:x='urn:x'><b xmlns:y='urn:y'/><c/><d><e attr='a'/></d></a>";
339
340                         nav = GetXmlDocumentNavigator (xml);
341                         MoveToNamespaces (nav);
342                         nav = GetXPathDocumentNavigator (document);
343                         MoveToNamespaces (nav);
344                 }
345
346                 private void MoveToNamespaces (XPathNavigator nav)
347                 {
348                         XPathNodeIterator iter = nav.Select ("//e");
349                         iter.MoveNext ();
350                         nav.MoveTo (iter.Current);
351                         Assert.AreEqual ("e", nav.Name, "#1");
352                         nav.MoveToFirstNamespace ();
353                         Assert.AreEqual ("x", nav.Name, "#2");
354                         nav.MoveToNextNamespace ();
355                         Assert.AreEqual ("xml", nav.Name, "#3");
356                 }
357
358                 [Test]
359                 public void IsDescendant ()
360                 {
361                         string xml = "<a><b/><c/><d><e attr='a'/></d></a>";
362
363                         nav = GetXmlDocumentNavigator (xml);
364                         IsDescendant (nav);
365                         nav = GetXPathDocumentNavigator (document);
366                         IsDescendant (nav);
367                 }
368
369                 private void IsDescendant (XPathNavigator nav)
370                 {
371                         XPathNavigator tmp = nav.Clone ();
372                         XPathNodeIterator iter = nav.Select ("//e");
373                         iter.MoveNext ();
374                         Assert.IsTrue (nav.MoveTo (iter.Current), "#1");
375                         Assert.IsTrue (nav.MoveToFirstAttribute (), "#2");
376                         Assert.AreEqual ("attr", nav.Name, "#3");
377                         Assert.AreEqual ("", tmp.Name, "#4");
378                         Assert.IsTrue (tmp.IsDescendant (nav), "#5");
379                         Assert.IsTrue (!nav.IsDescendant (tmp), "#6");
380                         tmp.MoveToFirstChild ();
381                         Assert.AreEqual ("a", tmp.Name, "#7");
382                         Assert.IsTrue (tmp.IsDescendant (nav), "#8");
383                         Assert.IsTrue (!nav.IsDescendant (tmp), "#9");
384                         tmp.MoveTo (iter.Current);
385                         Assert.AreEqual ("e", tmp.Name, "#10");
386                         Assert.IsTrue (tmp.IsDescendant (nav), "#11");
387                         Assert.IsTrue (!nav.IsDescendant (tmp), "#12");
388                 }
389
390                 [Test]
391                 public void LiterallySplittedText ()
392                 {
393                         string xml = "<root><![CDATA[test]]> string</root>";
394
395                         nav = GetXmlDocumentNavigator (xml);
396                         LiterallySplittedText (nav);
397                         nav = GetXPathDocumentNavigator (document);
398                         LiterallySplittedText (nav);
399                 }
400
401                 private void LiterallySplittedText (XPathNavigator nav)
402                 {
403                         nav.MoveToFirstChild ();
404                         nav.MoveToFirstChild ();
405                         Assert.AreEqual (XPathNodeType.Text, nav.NodeType, "#1");
406                         Assert.AreEqual ("test string", nav.Value, "#2");
407                 }
408
409                 // bug #75609
410                 [Test]
411                 public void SelectChildren ()
412                 {
413                         string xml = "<root><foo xmlns='urn:foo' /><ns:foo xmlns:ns='urn:foo' /></root>";
414
415                         nav = GetXmlDocumentNavigator (xml);
416                         SelectChildrenNS (nav);
417                         nav = GetXPathDocumentNavigator (document);
418                         SelectChildrenNS (nav);
419                 }
420
421                 private void SelectChildrenNS (XPathNavigator nav)
422                 {
423                         nav.MoveToFirstChild (); // root
424                         XPathNodeIterator iter = nav.SelectChildren ("foo", "urn:foo");
425                         Assert.AreEqual (2, iter.Count, "#1");
426                 }
427
428 #if NET_2_0
429
430                 [Test]
431                 // bug #78067
432                 public void OuterXml ()
433                 {
434                         string xml = @"<?xml version=""1.0""?>
435 <one>
436         <two>Some data.</two>
437 </one>";
438
439                         nav = GetXmlDocumentNavigator (xml);
440                         OuterXml (nav);
441                         nav = GetXPathDocumentNavigator (document);
442                         OuterXml (nav);
443                 }
444
445                 private void OuterXml (XPathNavigator nav)
446                 {
447                         string ret = @"<one>
448   <two>Some data.</two>
449 </one>";
450                         Assert.AreEqual (ret, nav.OuterXml.Replace ("\r\n", "\n"), "#1");
451                 }
452
453                 [Test]
454                 public void ReadSubtreeLookupNamespace ()
455                 {
456                         string xml = "<x:foo xmlns:x='urn:x'><bar>x:val</bar></x:foo>";
457                         var doc = new XmlDocument ();
458                         doc.LoadXml (xml);
459                         XPathNavigator nav = doc.LastChild.LastChild.CreateNavigator ();
460                         var xr = nav.ReadSubtree ();
461                         xr.MoveToContent ();
462                         xr.Read (); // should be at x:val
463                         Assert.AreEqual ("urn:x", xr.LookupNamespace ("x"), "#1");
464                 }
465 #endif
466
467                 [Test]
468                 public void GetNamespaceConsistentTree ()
469                 {
470                         document.PreserveWhitespace = true;
471
472                         string xml = "<x:root xmlns:x='urn:x'>  <x:foo xmlns='ns1'> <x:bar /> </x:foo>  <x:foo xmlns:y='ns2'> <x:bar /> </x:foo></x:root>";
473                         nav = GetXmlDocumentNavigator (xml);
474                         GetNamespaceConsistentTree (nav);
475                         nav = GetXPathDocumentNavigator (document, XmlSpace.Preserve);
476                         GetNamespaceConsistentTree (nav);
477                 }
478
479                 private void GetNamespaceConsistentTree (XPathNavigator nav)
480                 {
481                         nav.MoveToFirstChild ();
482                         nav.MoveToFirstChild ();
483                         nav.MoveToNext ();
484                         Assert.AreEqual ("ns1", nav.GetNamespace (""), "#1." + nav.GetType ());
485                         nav.MoveToNext ();
486                         nav.MoveToNext ();
487                         Assert.AreEqual ("", nav.GetNamespace (""), "#2." + nav.GetType ());
488                 }
489         }
490 }