svn path=/trunk/mcs/; revision=104772
[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 : Assertion
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                         AssertEquals (label + "NodeType", type, nav.NodeType);
55                         AssertEquals (label + "Prefix", prefix, nav.Prefix);
56                         AssertEquals (label + "LocalName", localName, nav.LocalName);
57                         AssertEquals (label + "Namespace", ns, nav.NamespaceURI);
58                         AssertEquals (label + "Name", name, nav.Name);
59                         AssertEquals (label + "Value", value, nav.Value);
60                         AssertEquals (label + "HasAttributes", hasAttributes, nav.HasAttributes);
61                         AssertEquals (label + "HasChildren", hasChildren, nav.HasChildren);
62                         AssertEquals (label + "IsEmptyElement", isEmptyElement, nav.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 (nav.MoveToFirstChild ());
96                         AssertNavigator ("#1", nav, XPathNodeType.ProcessingInstruction, "", "xml-stylesheet", "", "xml-stylesheet", "href='foo.xsl' type='text/xsl' ", false, false, false);
97                         Assert (!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 (nav.MoveToFirstChild ());
115                         AssertNavigator ("#2", nav, XPathNodeType.Element, "", "foo", "", "foo", "", false, false, true);
116                         Assert (!nav.MoveToFirstChild ());
117                         Assert (!nav.MoveToNext ());
118                         Assert (!nav.MoveToPrevious ());
119                         nav.MoveToRoot ();
120                         AssertNavigator ("#3", nav, XPathNodeType.Root, "", "", "", "", "", false, true, false);
121                         Assert (!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 (nav.MoveToFirstChild ());
139                         AssertNavigator ("#2", nav, XPathNodeType.Element, "", "foo", "", "foo", "Test.", false, true, false);
140                         Assert (!nav.MoveToNext ());
141                         Assert (!nav.MoveToPrevious ());
142                         Assert (nav.MoveToFirstChild ());
143                         AssertNavigator ("#3", nav, XPathNodeType.Text, "", "", "", "", "Test.", false, false, false);
144
145                         Assert (nav.MoveToParent ());
146                         AssertNavigator ("#4", nav, XPathNodeType.Element, "", "foo", "", "foo", "Test.", false, true, false);
147
148                         Assert (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 (!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 (nav.MoveToFirstChild ());
173                         AssertNavigator ("#2", nav, XPathNodeType.Element, "", "foo", "", "foo", "", false, true, false);
174                         Assert (!nav.MoveToNext ());
175                         Assert (!nav.MoveToPrevious ());
176
177                         Assert (nav.MoveToFirstChild ());
178                         AssertNavigator ("#3", nav, XPathNodeType.Element, "", "bar", "", "bar", "", false, false, true);
179
180                         Assert (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 (!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 (nav.MoveToFirstChild ());
204                         AssertNavigator ("#2", nav, XPathNodeType.Element, "", "foo", "", "foo", "", false, true, false);
205                         Assert (!nav.MoveToNext ());
206                         Assert (!nav.MoveToPrevious ());
207
208                         Assert (nav.MoveToFirstChild ());
209                         AssertNavigator ("#3", nav, XPathNodeType.Element, "", "bar", "", "bar", "", false, false, true);
210                         Assert (!nav.MoveToFirstChild ());
211
212                         Assert (nav.MoveToNext ());
213                         AssertNavigator ("#4", nav, XPathNodeType.Element, "", "baz", "", "baz", "", false, false, true);
214                         Assert (!nav.MoveToFirstChild ());
215
216                         Assert (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 (!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 (!nav.MoveToNext ());
240                         Assert (!nav.MoveToPrevious ());
241
242                         Assert (nav.MoveToFirstAttribute ());
243                         AssertNavigator ("#2", nav, XPathNodeType.Attribute, "", "src", "", "src", "foo.png", false, false, false);
244                         Assert (!nav.MoveToFirstAttribute ());  // On attributes, it fails.
245
246                         Assert (nav.MoveToNextAttribute ());
247                         AssertNavigator ("#3", nav, XPathNodeType.Attribute, "", "alt", "", "alt", "image Fooooooo!", false, false, false);
248                         Assert (!nav.MoveToNextAttribute ());
249
250                         Assert (nav.MoveToParent ());
251                         AssertNavigator ("#4", nav, XPathNodeType.Element, "", "img", "", "img", "", true, false, true);
252
253                         Assert (nav.MoveToAttribute ("alt", ""));
254                         AssertNavigator ("#5", nav, XPathNodeType.Attribute, "", "alt", "", "alt", "image Fooooooo!", false, false, false);
255                         Assert (!nav.MoveToAttribute ("src", ""));      // On attributes, it fails.
256                         Assert (nav.MoveToParent ());
257                         Assert (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 (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 (!nav.MoveToNextNamespace (XPathNamespaceScope.Local));
292                         Assert (!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 (nav.MoveToNextNamespace (XPathNamespaceScope.All));
297                         AssertNavigator ("#3", nav, XPathNodeType.Namespace,
298                                 "", "xml", "", "xml", xmlNS, false, false, false);
299                         Assert (!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 (nav.MoveToFirstNamespace ());
308                         Assert (nav.MoveToNextNamespace ());
309                         AssertNavigator ("#5", nav, XPathNodeType.Namespace,
310                                 "", "xml", "", "xml", xmlNS, false, false, false);
311
312                         // Test MoveToParent()
313                         Assert (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 ("Local should fail",
320                                 !nav.MoveToFirstNamespace (XPathNamespaceScope.Local));
321                         Assert ("ExcludeXml should succeed",
322                                 nav.MoveToFirstNamespace (XPathNamespaceScope.ExcludeXml));
323                         AssertNavigator ("#7", nav, XPathNodeType.Namespace,
324                                 "", "", "", "", xhtml, false, false, false);
325
326                         Assert (nav.MoveToNextNamespace (XPathNamespaceScope.All));
327                         AssertNavigator ("#8", nav, XPathNodeType.Namespace,
328                                 "", "xml", "", "xml", xmlNS, false, false, false);
329                         Assert (nav.MoveToParent ());
330                         AssertNavigator ("#9", nav, XPathNodeType.Element,
331                                 "", "body", xhtml, "body", "test.", false, true, false);
332
333                         nav.MoveToRoot ();
334                         AssertNavigator ("#10", nav, XPathNodeType.Root, "", "", "", "", "test.", false, true, false);
335                 }
336
337                 [Test]
338                 public void MoveToNamespaces ()
339                 {
340                         string xml = "<a xmlns:x='urn:x'><b xmlns:y='urn:y'/><c/><d><e attr='a'/></d></a>";
341
342                         nav = GetXmlDocumentNavigator (xml);
343                         MoveToNamespaces (nav);
344                         nav = GetXPathDocumentNavigator (document);
345                         MoveToNamespaces (nav);
346                 }
347
348                 private void MoveToNamespaces (XPathNavigator nav)
349                 {
350                         XPathNodeIterator iter = nav.Select ("//e");
351                         iter.MoveNext ();
352                         nav.MoveTo (iter.Current);
353                         AssertEquals ("e", nav.Name);
354                         nav.MoveToFirstNamespace ();
355                         AssertEquals ("x", nav.Name);
356                         nav.MoveToNextNamespace ();
357                         AssertEquals ("xml", nav.Name);
358                 }
359
360                 [Test]
361                 public void IsDescendant ()
362                 {
363                         string xml = "<a><b/><c/><d><e attr='a'/></d></a>";
364
365                         nav = GetXmlDocumentNavigator (xml);
366                         IsDescendant (nav);
367                         nav = GetXPathDocumentNavigator (document);
368                         IsDescendant (nav);
369                 }
370
371                 private void IsDescendant (XPathNavigator nav)
372                 {
373                         XPathNavigator tmp = nav.Clone ();
374                         XPathNodeIterator iter = nav.Select ("//e");
375                         iter.MoveNext ();
376                         Assert (nav.MoveTo (iter.Current));
377                         Assert (nav.MoveToFirstAttribute ());
378                         AssertEquals ("attr", nav.Name);
379                         AssertEquals ("", tmp.Name);
380                         Assert (tmp.IsDescendant (nav));
381                         Assert (!nav.IsDescendant (tmp));
382                         tmp.MoveToFirstChild ();
383                         AssertEquals ("a", tmp.Name);
384                         Assert (tmp.IsDescendant (nav));
385                         Assert (!nav.IsDescendant (tmp));
386                         tmp.MoveTo (iter.Current);
387                         AssertEquals ("e", tmp.Name);
388                         Assert (tmp.IsDescendant (nav));
389                         Assert (!nav.IsDescendant (tmp));
390                 }
391
392                 [Test]
393                 public void LiterallySplittedText ()
394                 {
395                         string xml = "<root><![CDATA[test]]> string</root>";
396
397                         nav = GetXmlDocumentNavigator (xml);
398                         LiterallySplittedText (nav);
399                         nav = GetXPathDocumentNavigator (document);
400                         LiterallySplittedText (nav);
401                 }
402
403                 private void LiterallySplittedText (XPathNavigator nav)
404                 {
405                         nav.MoveToFirstChild ();
406                         nav.MoveToFirstChild ();
407                         AssertEquals (XPathNodeType.Text, nav.NodeType);
408                         AssertEquals ("test string", nav.Value);
409                 }
410
411                 // bug #75609
412                 [Test]
413                 public void SelectChildren ()
414                 {
415                         string xml = "<root><foo xmlns='urn:foo' /><ns:foo xmlns:ns='urn:foo' /></root>";
416
417                         nav = GetXmlDocumentNavigator (xml);
418                         SelectChildrenNS (nav);
419                         nav = GetXPathDocumentNavigator (document);
420                         SelectChildrenNS (nav);
421                 }
422
423                 private void SelectChildrenNS (XPathNavigator nav)
424                 {
425                         nav.MoveToFirstChild (); // root
426                         XPathNodeIterator iter = nav.SelectChildren ("foo", "urn:foo");
427                         AssertEquals (2, iter.Count);
428                 }
429
430 #if NET_2_0
431
432                 [Test]
433                 // bug #78067
434                 public void OuterXml ()
435                 {
436                         string xml = @"<?xml version=""1.0""?>
437 <one>
438         <two>Some data.</two>
439 </one>";
440
441                         nav = GetXmlDocumentNavigator (xml);
442                         OuterXml (nav);
443                         nav = GetXPathDocumentNavigator (document);
444                         OuterXml (nav);
445                 }
446
447                 private void OuterXml (XPathNavigator nav)
448                 {
449                         string ret = @"<one>
450   <two>Some data.</two>
451 </one>";
452                         AssertEquals (ret, nav.OuterXml.Replace ("\r\n", "\n"));
453                 }
454 #endif
455
456                 [Test]
457                 public void GetNamespaceConsistentTree ()
458                 {
459                         document.PreserveWhitespace = true;
460
461                         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>";
462                         nav = GetXmlDocumentNavigator (xml);
463                         GetNamespaceConsistentTree (nav);
464                         nav = GetXPathDocumentNavigator (document, XmlSpace.Preserve);
465                         GetNamespaceConsistentTree (nav);
466                 }
467
468                 private void GetNamespaceConsistentTree (XPathNavigator nav)
469                 {
470                         nav.MoveToFirstChild ();
471                         nav.MoveToFirstChild ();
472                         nav.MoveToNext ();
473                         AssertEquals ("#1." + nav.GetType (), "ns1", nav.GetNamespace (""));
474                         nav.MoveToNext ();
475                         nav.MoveToNext ();
476                         AssertEquals ("#2." + nav.GetType (), "", nav.GetNamespace (""));
477                 }
478         }
479 }