2 // XPathEditableNavigatorTests.cs
5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2005 Novell, Inc. http://www.novell.com
14 using System.Xml.XPath;
15 using NUnit.Framework;
17 namespace MonoTests.System.Xml.XPath
20 public class XPathEditableNavigatorTests
22 private XPathNavigator GetInstance (string xml)
24 XmlDocument doc = new XmlDocument ();
26 return doc.CreateNavigator ();
29 private static void AssertNavigator (string label, XPathNavigator nav, XPathNodeType type, string prefix, string localName, string ns, string name, string value, bool hasAttributes, bool hasChildren, bool isEmptyElement)
31 label += nav.GetType ();
32 Assert.AreEqual (type, nav.NodeType, label + "NodeType");
33 Assert.AreEqual (prefix, nav.Prefix, label + "Prefix");
34 Assert.AreEqual (localName, nav.LocalName, label + "LocalName");
35 Assert.AreEqual (ns, nav.NamespaceURI, label + "Namespace");
36 Assert.AreEqual (name, nav.Name, label + "Name");
37 Assert.AreEqual (value, nav.Value, label + "Value");
38 Assert.AreEqual (hasAttributes, nav.HasAttributes, label + "HasAttributes");
39 Assert.AreEqual (hasChildren, nav.HasChildren, label + "HasChildren");
40 Assert.AreEqual (isEmptyElement, nav.IsEmptyElement, label + "IsEmptyElement");
44 [ExpectedException (typeof (XmlException))]
45 public void AppendChildStartDocumentInvalid ()
47 XPathNavigator nav = GetInstance (String.Empty);
48 XmlWriter w = nav.AppendChild ();
49 w.WriteStartDocument ();
54 [ExpectedException (typeof (XmlException))]
55 public void AppendChildStartAttributeInvalid ()
57 XPathNavigator nav = GetInstance (String.Empty);
58 XmlWriter w = nav.AppendChild ();
59 // Seems like it is just ignored.
60 w.WriteStartAttribute ("test");
61 w.WriteEndAttribute ();
63 Assert.AreEqual (XPathNodeType.Root, nav.NodeType, "#1");
64 Assert.IsFalse (nav.MoveToFirstChild (), "#2");
68 [ExpectedException (typeof (XmlException))]
69 public void AppendChildElementIncomplete ()
71 XPathNavigator nav = GetInstance (String.Empty);
72 XmlWriter w = nav.AppendChild ();
73 w.WriteStartElement ("foo");
78 // empty content is allowed.
79 public void AppendChildEmptyString ()
81 XPathNavigator nav = GetInstance ("<root/>");
82 nav.MoveToFirstChild (); // root
83 nav.AppendChild (String.Empty);
87 public void AppendChildElement ()
89 XPathNavigator nav = GetInstance ("<root/>");
90 nav.MoveToFirstChild ();
91 XmlWriter w = nav.AppendChild ();
92 w.WriteStartElement ("foo");
95 Assert.IsTrue (nav.MoveToFirstChild ());
96 AssertNavigator ("#1", nav,
97 XPathNodeType.Element,
98 String.Empty, // Prefix
100 String.Empty, // NamespaceURI
102 String.Empty, // Value
103 false, // HasAttributes
104 false, // HasChildren
105 true); // IsEmptyElement
109 public void AppendChildStringFragment ()
111 // check that the input string inherits
112 // namespace context.
113 XPathNavigator nav = GetInstance ("<root xmlns='urn:foo'/>");
114 nav.MoveToFirstChild ();
115 nav.AppendChild ("<child/>fragment<child></child>");
117 Assert.IsTrue (nav.MoveToFirstChild (), "#1-1");
118 AssertNavigator ("#1-2", nav,
119 XPathNodeType.Element,
120 String.Empty, // Prefix
121 "child", // LocalName
122 "urn:foo", // NamespaceURI
124 String.Empty, // Value
125 false, // HasAttributes
126 false, // HasChildren
127 true); // IsEmptyElement
129 Assert.IsFalse (nav.MoveToFirstChild (), "#2-1");
130 Assert.IsTrue (nav.MoveToNext (), "#2-2");
131 AssertNavigator ("#2-3", nav,
133 String.Empty, // Prefix
134 String.Empty, // LocalName
135 String.Empty, // NamespaceURI
136 String.Empty, // Name
138 false, // HasAttributes
139 false, // HasChildren
140 false); // IsEmptyElement
142 Assert.IsTrue (nav.MoveToNext (), "#3-1");
143 AssertNavigator ("#3-2", nav,
144 XPathNodeType.Element,
145 String.Empty, // Prefix
146 "child", // LocalName
147 "urn:foo", // NamespaceURI
149 String.Empty, // Value
150 false, // HasAttributes
151 false, // HasChildren
152 false); // IsEmptyElement
156 public void AppendChildStringInvalidFragment ()
158 XPathNavigator nav = GetInstance ("<root xmlns='urn:foo'/>");
159 nav.MoveToFirstChild ();
160 nav.AppendChild ("<?xml version='1.0'?><root/>");
164 [ExpectedException (typeof (InvalidOperationException))]
165 public void AppendChildToTextNode ()
167 XPathNavigator nav = GetInstance ("<root>text</root>");
168 nav.MoveToFirstChild ();
169 nav.MoveToFirstChild ();
170 XmlWriter w = nav.AppendChild ();
174 public void InsertAfter ()
176 XPathNavigator nav = GetInstance ("<root>test</root>");
177 nav.MoveToFirstChild ();
178 nav.MoveToFirstChild ();
179 nav.InsertAfter ("<blah/><doh>sample</doh>");
181 AssertNavigator ("#1", nav,
183 String.Empty, // Prefix
184 String.Empty, // LocalName
185 String.Empty, // NamespaceURI
186 String.Empty, // Name
188 false, // HasAttributes
189 false, // HasChildren
190 false); // IsEmptyElement
192 Assert.IsTrue (nav.MoveToNext (), "#2");
193 AssertNavigator ("#2-2", nav,
194 XPathNodeType.Element,
195 String.Empty, // Prefix
197 String.Empty, // NamespaceURI
199 String.Empty, // Value
200 false, // HasAttributes
201 false, // HasChildren
202 true); // IsEmptyElement
204 Assert.IsTrue (nav.MoveToNext (), "#3");
205 AssertNavigator ("#3-2", nav,
206 XPathNodeType.Element,
207 String.Empty, // Prefix
209 String.Empty, // NamespaceURI
212 false, // HasAttributes
214 false); // IsEmptyElement
218 [ExpectedException (typeof (InvalidOperationException))]
219 public void InsertAfterRoot ()
221 XPathNavigator nav = GetInstance ("<root/>");
226 [ExpectedException (typeof (InvalidOperationException))]
227 public void InsertAfterAttribute ()
229 XPathNavigator nav = GetInstance ("<root a='b'/>");
230 nav.MoveToFirstChild ();
231 nav.MoveToFirstAttribute ();
236 [ExpectedException (typeof (InvalidOperationException))]
237 public void InsertAfterNamespace ()
239 XPathNavigator nav = GetInstance ("<root xmlns='urn:foo'/>");
240 nav.MoveToFirstChild ();
241 nav.MoveToFirstNamespace ();
246 [ExpectedException (typeof (InvalidOperationException))]
247 // xmlns:xml='...', which is likely to have XmlElement or XmlDocument as its node.
248 public void InsertAfterNamespace2 ()
250 XPathNavigator nav = GetInstance ("<root />");
251 nav.MoveToFirstChild ();
252 nav.MoveToFirstNamespace ();
257 // empty content is allowed.
258 public void InsertAfterEmptyString ()
260 XPathNavigator nav = GetInstance ("<root/>");
261 nav.MoveToFirstChild (); // root
262 nav.InsertAfter (String.Empty);
266 public void InsertBefore ()
268 XPathNavigator nav = GetInstance ("<root>test</root>");
269 nav.MoveToFirstChild ();
270 nav.MoveToFirstChild ();
271 nav.InsertBefore ("<blah/><doh>sample</doh>");
273 AssertNavigator ("#1", nav,
275 String.Empty, // Prefix
276 String.Empty, // LocalName
277 String.Empty, // NamespaceURI
278 String.Empty, // Name
280 false, // HasAttributes
281 false, // HasChildren
282 false); // IsEmptyElement
284 Assert.IsTrue (nav.MoveToFirst (), "#2-1");
285 AssertNavigator ("#2-2", nav,
286 XPathNodeType.Element,
287 String.Empty, // Prefix
289 String.Empty, // NamespaceURI
291 String.Empty, // Value
292 false, // HasAttributes
293 false, // HasChildren
294 true); // IsEmptyElement
296 Assert.IsTrue (nav.MoveToNext (), "#3");
297 AssertNavigator ("#3-2", nav,
298 XPathNodeType.Element,
299 String.Empty, // Prefix
301 String.Empty, // NamespaceURI
304 false, // HasAttributes
306 false); // IsEmptyElement
310 [ExpectedException (typeof (InvalidOperationException))]
311 public void InsertBeforeRoot ()
313 XPathNavigator nav = GetInstance ("<root/>");
318 [ExpectedException (typeof (InvalidOperationException))]
319 public void InsertBeforeAttribute ()
321 XPathNavigator nav = GetInstance ("<root a='b'/>");
322 nav.MoveToFirstChild ();
323 nav.MoveToFirstAttribute ();
328 [ExpectedException (typeof (InvalidOperationException))]
329 public void InsertBeforeNamespace ()
331 XPathNavigator nav = GetInstance ("<root xmlns='urn:foo'/>");
332 nav.MoveToFirstChild ();
333 nav.MoveToFirstNamespace ();
338 [ExpectedException (typeof (InvalidOperationException))]
339 // xmlns:xml='...', which is likely to have XmlElement or XmlDocument as its node.
340 public void InsertBeforeNamespace2 ()
342 XPathNavigator nav = GetInstance ("<root />");
343 nav.MoveToFirstChild ();
344 nav.MoveToFirstNamespace ();
349 // empty content is allowed.
350 public void InsertBeforeEmptyString ()
352 XPathNavigator nav = GetInstance ("<root/>");
353 nav.MoveToFirstChild (); // root
354 nav.InsertBefore (String.Empty);
358 public void DeleteRange ()
360 XPathNavigator nav = GetInstance ("<root><foo><bar/><baz/></foo><next>child<tmp/></next>final</root>");
361 nav.MoveToFirstChild ();
362 nav.MoveToFirstChild (); // <foo>
363 XPathNavigator end = nav.Clone ();
364 end.MoveToNext (); // <next>
365 end.MoveToNext (); // final
366 nav.DeleteRange (end);
368 AssertNavigator ("#1", nav,
369 XPathNodeType.Element,
370 String.Empty, // Prefix
372 String.Empty, // NamespaceURI
374 String.Empty, // Value
375 false, // HasAttributes
376 false, // HasChildren
377 false); // IsEmptyElement
381 [ExpectedException (typeof (ArgumentNullException))]
382 public void DeleteRangeNullArg ()
384 XPathNavigator nav = GetInstance ("<root><foo><bar/><baz/></foo><next>child<tmp/></next>final</root>");
385 nav.MoveToFirstChild ();
386 nav.MoveToFirstChild (); // <foo>
387 nav.DeleteRange (null);
391 [ExpectedException (typeof (InvalidOperationException))]
392 public void DeleteRangeInvalidArg ()
394 XPathNavigator nav = GetInstance ("<root><foo><bar/><baz/></foo><next>child<tmp/></next>final</root>");
395 nav.MoveToFirstChild ();
396 nav.MoveToFirstChild (); // <foo>
398 XPathNavigator end = nav.Clone ();
399 end.MoveToNext (); // <next>
400 end.MoveToFirstChild (); // child
401 nav.DeleteRange (end);
405 public void ReplaceRange ()
407 XPathNavigator nav = GetInstance ("<root><foo><bar/><baz/></foo><next>child<tmp/></next>final</root>");
408 nav.MoveToFirstChild ();
409 nav.MoveToFirstChild (); // <foo>
411 XPathNavigator end = nav.Clone ();
412 end.MoveToNext (); // <next>
413 XmlWriter w = nav.ReplaceRange (end);
415 AssertNavigator ("#1", nav,
416 XPathNodeType.Element,
417 String.Empty, // Prefix
419 String.Empty, // NamespaceURI
421 String.Empty, // Value
422 false, // HasAttributes
424 false); // IsEmptyElement
426 Assert.IsTrue (nav.MoveToParent (), "#1-2");
428 w.WriteStartElement ("whoa");
429 w.WriteEndElement ();
432 AssertNavigator ("#2", nav,
433 XPathNodeType.Element,
434 String.Empty, // Prefix
436 String.Empty, // NamespaceURI
438 String.Empty, // Value
439 false, // HasAttributes
440 false, // HasChildren
441 true); // IsEmptyElement
443 Assert.IsTrue (nav.MoveToNext (), "#2-1");
445 AssertNavigator ("#3", nav,
447 String.Empty, // Prefix
448 String.Empty, // LocalName
449 String.Empty, // NamespaceURI
450 String.Empty, // Name
452 false, // HasAttributes
453 false, // HasChildren
454 false); // IsEmptyElement
458 [ExpectedException (typeof (ArgumentNullException))]
459 public void ReplaceRangeNullArg ()
461 XPathNavigator nav = GetInstance ("<root><foo><bar/><baz/></foo><next>child<tmp/></next>final</root>");
462 nav.MoveToFirstChild ();
463 nav.MoveToFirstChild (); // <foo>
464 nav.ReplaceRange (null);
468 [ExpectedException (typeof (InvalidOperationException))]
469 public void ReplaceRangeInvalidArg ()
471 XPathNavigator nav = GetInstance ("<root><foo><bar/><baz/></foo><next>child<tmp/></next>final</root>");
472 nav.MoveToFirstChild ();
473 nav.MoveToFirstChild (); // <foo>
475 XPathNavigator end = nav.Clone ();
476 end.MoveToNext (); // <next>
477 end.MoveToFirstChild (); // child
478 nav.ReplaceRange (end);
482 public void PrependChildXmlReader ()
484 XPathNavigator nav = GetInstance ("<root><foo>existing_child</foo></root>");
485 nav.MoveToFirstChild ();
486 nav.MoveToFirstChild (); // foo
488 XmlReader reader = new XmlTextReader (
489 "<child>text</child><next_sibling/>",
493 nav.PrependChild (reader);
495 XmlAssert.AssertNode ("#0",
499 false, // IsEmptyElement
500 String.Empty, // Name
501 String.Empty, // Prefix
502 String.Empty, // LocalName
503 String.Empty, // NamespaceURI
504 String.Empty, // Value
507 false); // HasAttributes
509 AssertNavigator ("#1", nav,
510 XPathNodeType.Element,
511 String.Empty, // Prefix
513 String.Empty, // NamespaceURI
515 "textexisting_child", // Value
516 false, // HasAttributes
518 false); // IsEmptyElement
520 Assert.IsTrue (nav.MoveToFirstChild (), "#1-2");
522 AssertNavigator ("#2", nav,
523 XPathNodeType.Element,
524 String.Empty, // Prefix
525 "child", // LocalName
526 String.Empty, // NamespaceURI
529 false, // HasAttributes
531 false); // IsEmptyElement
533 Assert.IsTrue (nav.MoveToNext (), "#2-2");
535 AssertNavigator ("#3", nav,
536 XPathNodeType.Element,
537 String.Empty, // Prefix
538 "next_sibling", // LocalName
539 String.Empty, // NamespaceURI
540 "next_sibling", // Name
541 String.Empty, // Value
542 false, // HasAttributes
543 false, // HasChildren
544 true); // IsEmptyElement
546 Assert.IsTrue (nav.MoveToNext (), "#3-2");
548 AssertNavigator ("#4", nav,
550 String.Empty, // Prefix
551 String.Empty, // LocalName
552 String.Empty, // NamespaceURI
553 String.Empty, // Name
554 "existing_child",// Value
555 false, // HasAttributes
556 false, // HasChildren
557 false); // IsEmptyElement
561 [ExpectedException (typeof (InvalidOperationException))]
562 public void PrependChildInvalid ()
564 XPathNavigator nav = GetInstance ("<root><foo>existing_child</foo></root>");
565 nav.MoveToFirstChild ();
566 nav.MoveToFirstChild (); // foo
568 XmlWriter w = nav.PrependChild ();
570 w.WriteStartAttribute ("whoa");
571 w.WriteEndAttribute ();
576 // empty content is allowed.
577 public void PrependChildEmptyString ()
579 XPathNavigator nav = GetInstance ("<root><foo/><bar/><baz/></root>");
580 nav.MoveToFirstChild ();
581 nav.MoveToFirstChild (); // foo
582 nav.MoveToNext (); // bar
583 nav.PrependChild (String.Empty);
585 AssertNavigator ("#1", nav,
586 XPathNodeType.Element,
587 String.Empty, // Prefix
589 String.Empty, // NamespaceURI
591 String.Empty, // Value
592 false, // HasAttributes
593 false, // HasChildren
594 true); // IsEmptyElement
596 Assert.IsTrue (nav.MoveToFirst (), "#1-2");
598 AssertNavigator ("#2", nav,
599 XPathNodeType.Element,
600 String.Empty, // Prefix
602 String.Empty, // NamespaceURI
604 String.Empty, // Value
605 false, // HasAttributes
606 false, // HasChildren
607 true); // IsEmptyElement
611 public void ReplaceSelf ()
613 XPathNavigator nav = GetInstance ("<root><foo>existing_child</foo></root>");
614 nav.MoveToFirstChild ();
615 nav.MoveToFirstChild (); // foo
617 nav.ReplaceSelf ("<hijacker>hah, hah</hijacker><next/>");
619 AssertNavigator ("#1", nav,
620 XPathNodeType.Element,
621 String.Empty, // Prefix
622 "hijacker", // LocalName
623 String.Empty, // NamespaceURI
626 false, // HasAttributes
628 false); // IsEmptyElement
630 Assert.IsTrue (nav.MoveToNext (), "#1-2");
632 AssertNavigator ("#2", nav,
633 XPathNodeType.Element,
634 String.Empty, // Prefix
636 String.Empty, // NamespaceURI
638 String.Empty, // Value
639 false, // HasAttributes
640 false, // HasChildren
641 true); // IsEmptyElement
645 // possible internal behavior difference e.g. due to ReadNode()
646 public void ReplaceSelfXmlReaderInteractive ()
648 XPathNavigator nav = GetInstance ("<root><foo>existing_child</foo></root>");
649 nav.MoveToFirstChild ();
650 nav.MoveToFirstChild (); // foo
652 XmlReader xr = new XmlTextReader (
653 "<hijacker>hah, hah</hijacker><next/>",
657 nav.ReplaceSelf (xr);
659 AssertNavigator ("#1", nav,
660 XPathNodeType.Element,
661 String.Empty, // Prefix
662 "hijacker", // LocalName
663 String.Empty, // NamespaceURI
666 false, // HasAttributes
668 false); // IsEmptyElement
670 Assert.IsFalse (nav.MoveToNext (), "#1-2");
674 [ExpectedException (typeof (InvalidOperationException))]
675 // empty content is not allowed
676 public void ReplaceSelfEmptyString ()
678 XPathNavigator nav = GetInstance ("<root><foo>existing_child</foo></root>");
679 nav.MoveToFirstChild ();
680 nav.MoveToFirstChild (); // foo
682 nav.ReplaceSelf (String.Empty);
686 public void SetValueEmptyString ()
688 XPathNavigator nav = GetInstance ("<root><foo>existing_child</foo></root>");
689 nav.MoveToFirstChild ();
690 nav.MoveToFirstChild (); // foo
692 nav.SetValue (String.Empty);
694 AssertNavigator ("#1", nav,
695 XPathNodeType.Element,
696 String.Empty, // Prefix
698 String.Empty, // NamespaceURI
700 String.Empty, // Value
701 false, // HasAttributes
703 false); // IsEmptyElement
707 public void MoveToFollowing ()
711 XPathNavigator nav = GetInstance ("<root><bar><foo attr='v1'><baz><foo attr='v2'/></baz></foo></bar><dummy/><foo attr='v3'></foo></root>");
712 Assert.IsTrue (nav.MoveToFollowing ("foo", String.Empty), "#1");
713 Assert.AreEqual ("v1", nav.GetAttribute ("attr", String.Empty), "#2");
714 Assert.IsTrue (nav.MoveToFollowing ("foo", String.Empty), "#3");
715 Assert.AreEqual ("v2", nav.GetAttribute ("attr", String.Empty), "#4");
716 Assert.IsTrue (nav.MoveToFollowing ("foo", String.Empty), "#5");
717 Assert.AreEqual ("v3", nav.GetAttribute ("attr", String.Empty), "#6");
723 Assert.IsTrue (nav.MoveToFollowing ("foo", String.Empty, end), "#7");
724 Assert.AreEqual ("v1", nav.GetAttribute ("attr", String.Empty), "#8");
725 Assert.IsTrue (nav.MoveToFollowing ("foo", String.Empty, end), "#9");
726 Assert.AreEqual ("v2", nav.GetAttribute ("attr", String.Empty), "#10");
728 Assert.IsFalse (nav.MoveToFollowing ("foo", String.Empty, end), "#11");
729 // in this case it never moves to somewhere else.
730 Assert.AreEqual ("v2", nav.GetAttribute ("attr", String.Empty), "#12");
734 public void MoveToFollowingFromAttribute ()
736 XPathNavigator nav = GetInstance ("<root a='b'><foo/></root>");
737 nav.MoveToFirstChild ();
738 nav.MoveToFirstAttribute ();
739 // should first move to owner element and go on.
740 Assert.IsTrue (nav.MoveToFollowing ("foo", String.Empty));