2008-12-09 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.XML / Test / System.Xml.XPath / XPathNavigatorTests.cs
index 484012241ba04f5ea9a06eb8be2d86005d4f216b..4dfe25a39c5307f8454c8a9a6b94c67acd8e3d29 100644 (file)
@@ -4,15 +4,18 @@
 // Authors:
 //   Jason Diamond <jason@injektilo.org>
 //   Martin Willemoes Hansen <mwh@sysrq.dk>
+//   Atsushi Enomoto <atsushi@ximian.com>
 //
 // (C) 2002 Jason Diamond
 // (C) 2003 Martin Willemoes Hansen
+// (C) 2004-2006 Novell, Inc.
 //
 
 using System;
 using System.IO;
 using System.Xml;
 using System.Xml.XPath;
+using System.Xml.Xsl;
 
 using NUnit.Framework;
 
@@ -284,6 +287,162 @@ namespace MonoTests.System.Xml
                                nav.NodeType);
                }
 
+               [Test]
+               public void VariableReference ()
+               {
+                       XPathDocument xpd = new XPathDocument (
+                               new StringReader ("<root>sample text</root>"));
+                       XPathNavigator nav = xpd.CreateNavigator ();
+
+                       XPathExpression expr = nav.Compile ("foo(string(.),$idx)");
+                       XsltArgumentList args = new XsltArgumentList ();
+                       args.AddParam ("idx", "", 5);
+                       MyContext ctx = new MyContext (nav.NameTable as NameTable, args);
+                       ctx.AddNamespace ("x", "urn:foo");
+
+                       expr.SetContext (ctx);
+
+                       XPathNodeIterator iter = nav.Select ("/root");
+                       iter.MoveNext ();
+                       AssertEquals ("e", iter.Current.Evaluate (expr));
+               }
+
+               class MyContext : XsltContext
+               {
+                       XsltArgumentList args;
+
+                       public MyContext (NameTable nt, XsltArgumentList args)
+                               : base (nt)
+                       {
+                               this.args = args;
+                       }
+
+                       public override IXsltContextFunction ResolveFunction (
+                               string prefix, string name, XPathResultType [] argtypes)
+                       {
+                               if (name == "foo")
+                                       return new MyFunction (argtypes);
+                               return null;
+                       }
+
+                       public override IXsltContextVariable ResolveVariable (string prefix, string name)
+                       {
+                               return new MyVariable (name);
+                       }
+
+                       public override bool PreserveWhitespace (XPathNavigator nav)
+                       {
+                               return false;
+                       }
+
+                       public override int CompareDocument (string uri1, string uri2)
+                       {
+                               return String.CompareOrdinal (uri1, uri2);
+                       }
+
+                       public override bool Whitespace {
+                               get { return false; }
+                       }
+
+                       public object GetParam (string name, string ns)
+                       {
+                               return args.GetParam (name, ns);
+                       }
+               }
+
+               public class MyFunction : IXsltContextFunction
+               {
+                       XPathResultType [] argtypes;
+
+                       public MyFunction (XPathResultType [] argtypes)
+                       {
+                               this.argtypes = argtypes;
+                       }
+
+                       public XPathResultType [] ArgTypes {
+                               get { return argtypes; }
+                       }
+
+                       public int Maxargs {
+                               get { return 2; }
+                       }
+
+                       public int Minargs {
+                               get { return 2; }
+                       }
+
+                       public XPathResultType ReturnType {
+                               get { return XPathResultType.String; }
+                       }
+
+                       public object Invoke (XsltContext xsltContext,
+                               object [] args, XPathNavigator instanceContext)
+                       {
+                               return ((string) args [0]) [(int) (double) args [1]].ToString ();
+                       }
+               }
+
+               public class MyVariable : IXsltContextVariable
+               {
+                       string name;
+
+                       public MyVariable (string name)
+                       {
+                               this.name = name;
+                       }
+
+                       public object Evaluate (XsltContext ctx)
+                       {
+                               return ((MyContext) ctx).GetParam (name, String.Empty);
+                       }
+
+                       public bool IsLocal {
+                               get { return false; }
+                       }
+
+                       public bool IsParam {
+                               get { return false; }
+                       }
+
+                       public XPathResultType VariableType {
+                               get { return XPathResultType.Any; }
+                       }
+               }
+
+               [Test]
+               public void TextMatchesWhitespace ()
+               {
+                       string xml = "<root><ws>   </ws><sws xml:space='preserve'> </sws></root>";
+                       XmlDocument doc = new XmlDocument ();
+                       doc.PreserveWhitespace = true;
+                       doc.LoadXml (xml);
+                       XPathNavigator nav = doc.CreateNavigator ();
+                       nav.MoveToFirstChild (); // root
+                       nav.MoveToFirstChild (); // ws
+                       nav.MoveToFirstChild (); // '   '
+                       AssertEquals ("#1", true, nav.Matches ("text()"));
+                       nav.MoveToParent ();
+                       nav.MoveToNext (); // sws
+                       nav.MoveToFirstChild (); // ' '
+                       AssertEquals ("#2", true, nav.Matches ("text()"));
+               }
+
+               [Test]
+               public void Bug456103 ()
+               {
+                       XmlDocument doc = new XmlDocument ();
+                       doc.LoadXml ("<root><X/></root>");
+
+                       XPathNavigator nav = doc.DocumentElement.CreateNavigator ();
+                       // ".//*" does not reproduce the bug.
+                       var i = nav.Select ("descendant::*");
+
+                       // without this call to get_Count() the bug does not reproduce.
+                       AssertEquals ("#1", 1, i.Count);
+
+                       Assert ("#2", i.MoveNext ());
+               }
+
 #if NET_2_0
                [Test]
                public void ValueAsBoolean ()
@@ -412,6 +571,139 @@ namespace MonoTests.System.Xml
                        nav.MoveToFirstChild ();
                        long l = nav.ValueAsLong;
                }
+
+               [Test] // bug #79874
+               public void InnerXmlText ()
+               {
+                       StringReader sr = new StringReader ("<Abc><Foo>Hello</Foo></Abc>");
+                       XPathDocument doc = new XPathDocument (sr);
+                       XPathNavigator nav = doc.CreateNavigator ();
+                       XPathNodeIterator iter = nav.Select ("/Abc/Foo");
+                       iter.MoveNext ();
+                       AssertEquals ("#1", "Hello", iter.Current.InnerXml);
+                       AssertEquals ("#2", "<Foo>Hello</Foo>", iter.Current.OuterXml);
+                       iter = nav.Select ("/Abc/Foo/text()");
+                       iter.MoveNext ();
+                       AssertEquals ("#3", String.Empty, iter.Current.InnerXml);
+                       AssertEquals ("#4", "Hello", iter.Current.OuterXml);
+               }
+
+               [Test] // bug #79875
+               public void InnerXmlAttribute ()
+               {
+                       StringReader sr = new StringReader ("<Abc><Foo attr='val1'/></Abc>");
+                       XPathDocument doc = new XPathDocument (sr);
+                       XPathNavigator nav = doc.CreateNavigator ();
+
+                       XPathNodeIterator iter = nav.Select ("/Abc/Foo/@attr");
+                       iter.MoveNext ();
+                       AssertEquals ("val1", iter.Current.InnerXml);
+               }
+
+               [Test]
+               public void InnerXmlTextEscape ()
+               {
+                       StringReader sr = new StringReader ("<Abc><Foo>Hello&lt;\r\nInnerXml</Foo></Abc>");
+                       XPathDocument doc = new XPathDocument (sr);
+                       XPathNavigator nav = doc.CreateNavigator ();
+                       XPathNodeIterator iter = nav.Select ("/Abc/Foo");
+                       iter.MoveNext ();
+                       AssertEquals ("#1", "Hello&lt;\r\nInnerXml", iter.Current.InnerXml);
+                       AssertEquals ("#2", "<Foo>Hello&lt;\r\nInnerXml</Foo>", iter.Current.OuterXml);
+                       iter = nav.Select ("/Abc/Foo/text()");
+                       iter.MoveNext ();
+                       AssertEquals ("#3", String.Empty, iter.Current.InnerXml);
+                       AssertEquals ("#4", "Hello&lt;\r\nInnerXml", iter.Current.OuterXml);
+               }
+
+               [Test]
+               [Category ("NotDotNet")] // .NET bug; it should escape value
+               public void InnerXmlAttributeEscape ()
+               {
+                       StringReader sr = new StringReader ("<Abc><Foo attr='val&quot;1&#13;&#10;&gt;'/></Abc>");
+                       XPathDocument doc = new XPathDocument (sr);
+                       XPathNavigator nav = doc.CreateNavigator ();
+
+                       XPathNodeIterator iter = nav.Select ("/Abc/Foo/@attr");
+                       iter.MoveNext ();
+                       AssertEquals ("val&quot;1&#10;&gt;", iter.Current.InnerXml);
+               }
+
+               [Test]
+               public void WriterAttributePrefix ()
+               {
+                       XmlDocument doc = new XmlDocument ();
+                       XmlWriter w = doc.CreateNavigator ().AppendChild ();
+                       w.WriteStartElement ("foo");
+                       w.WriteAttributeString ("xmlns", "x", "http://www.w3.org/2000/xmlns/", "urn:foo");
+                       AssertEquals ("#0", "x", w.LookupPrefix ("urn:foo"));
+                       w.WriteStartElement (null, "bar", "urn:foo");
+                       w.WriteAttributeString (null, "ext", "urn:foo", "bah");
+                       w.WriteEndElement ();
+                       w.WriteEndElement ();
+                       w.Close ();
+                       AssertEquals ("#1", "x", doc.FirstChild.FirstChild.Prefix);
+                       AssertEquals ("#2", "x", doc.FirstChild.FirstChild.Attributes [0].Prefix);
+               }
+
+               [Test]
+               public void ValueAs ()
+               {
+                       string xml = "<root>1</root>";
+                       XPathNavigator nav = new XPathDocument (XmlReader.Create (new StringReader (xml))).CreateNavigator ();
+                       nav.MoveToFirstChild ();
+                       nav.MoveToFirstChild ();
+                       AssertEquals ("1", nav.ValueAs (typeof (string), null));
+                       AssertEquals (1, nav.ValueAs (typeof (int), null));
+               }
+
+               [Test]
+               public void MoveToFollowingNodeTypeAll ()
+               {
+                       XmlDocument doc = new XmlDocument ();
+                       doc.LoadXml ("<root><child/><child2/></root>");
+                       XPathNavigator nav = doc.CreateNavigator ();
+                       Assert ("#1", nav.MoveToFollowing (XPathNodeType.All));
+                       Assert ("#2", nav.MoveToFollowing (XPathNodeType.All));
+                       AssertEquals ("#3", "child", nav.LocalName);
+                       Assert ("#4", nav.MoveToNext (XPathNodeType.All));
+                       AssertEquals ("#5", "child2", nav.LocalName);
+               }
+
+               [Test] // bug #324606.
+               public void XPathDocumentFromSubtreeNodes ()
+               {
+                       string xml = "<root><child1><nest1><nest2>hello!</nest2></nest1></child1><child2/><child3/></root>";
+                       XmlReader r = new XmlTextReader (new StringReader (xml));
+                       while (r.Read ()) {
+                               if (r.Name == "child1")
+                                       break;
+                       }
+                       XPathDocument d = new XPathDocument (r);
+                       XPathNavigator n = d.CreateNavigator ();
+                       string result = @"<child1>
+  <nest1>
+    <nest2>hello!</nest2>
+  </nest1>
+</child1>
+<child2 />
+<child3 />";
+                       AssertEquals (result, n.OuterXml.Replace ("\r\n", "\n"));
+               }
+
+               [Test] // bug #376191
+               public void InnerXmlOnRoot ()
+               {
+                       XmlDocument document = new XmlDocument ();
+                       document.LoadXml (@"<test>
+                       <node>z</node>
+                       <node>a</node>
+                       <node>b</node>
+                       <node>q</node>
+                       </test>");
+                       XPathNavigator navigator = document.CreateNavigator();
+                       AssertEquals (navigator.OuterXml, navigator.InnerXml);
+               }
 #endif
        }
 }