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