Merge pull request #1949 from lewurm/fixtype
[mono.git] / mcs / class / System / Test / System / UriBuilderTest.cs
index 4ca030fd0ec93668e20c6d683a816528325b0da7..a01e0accc2fb580acd4c5e279ea39f8b7b7625c3 100644 (file)
@@ -6,35 +6,92 @@
 //   Martin Willemoes Hansen (mwh@sysrq.dk)
 //
 // (C) 2003 Martin Willemoes Hansen
+// Copyright (C) 2010 Novell, Inc (http://www.novell.com)
 //
 
 using NUnit.Framework;
 using System;
+using System.Reflection;
 
 namespace MonoTests.System
 {
        [TestFixture]
-       public class UriBuilderTest : Assertion
+       public class UriBuilderTest
        {
                private UriBuilder b, b2, b3;
+               public bool IriParsing;
                
                [SetUp]
                public void GetReady()
                {
                        b = new UriBuilder ("http", "www.ximian.com", 80, "foo/bar/index.html");
+
+                       //Make sure Uri static constructor is called
+                       Uri.EscapeDataString ("");
+
+                       FieldInfo iriParsingField = typeof (Uri).GetField ("s_IriParsing",
+                               BindingFlags.Static | BindingFlags.GetField | BindingFlags.NonPublic);
+                       if (iriParsingField != null)
+                               IriParsing = (bool) iriParsingField.GetValue (null);
                }
 
-               [Test]
+               [Test] // ctor ()
                public void Constructor_Empty ()
                {
                        b = new UriBuilder ();
-                       AssertEquals ("#1", "http", b.Scheme);
-#if NET_2_0
-                       AssertEquals ("#2", "localhost", b.Host);
-#else
-                       AssertEquals ("#2", "loopback", b.Host);
-#endif
-                       AssertEquals ("#3", -1, b.Port);
+                       Assert.AreEqual ("http", b.Scheme, "#1");
+                       Assert.AreEqual ("localhost", b.Host, "#2");
+                       Assert.AreEqual (-1, b.Port, "#4");
+                       Assert.AreEqual (string.Empty, b.Query, "#5");
+                       Assert.AreEqual (string.Empty, b.Fragment, "#6");
+               }
+
+               [Test] // ctor (string)
+               public void Constructor1 ()
+               {
+                       b = new UriBuilder ("http://www.ximian.com:8001#test?name=50");
+                       Assert.AreEqual ("#test?name=50", b.Fragment, "#A1");
+                       Assert.AreEqual ("www.ximian.com", b.Host, "#A2");
+                       Assert.AreEqual (string.Empty, b.Password, "#A3");
+                       Assert.AreEqual ("/", b.Path, "#A4");
+                       Assert.AreEqual (8001, b.Port, "#A5");
+                       Assert.AreEqual (string.Empty, b.Query, "#A5");
+                       Assert.AreEqual ("http", b.Scheme, "#A6");
+                       Assert.AreEqual ("http://www.ximian.com:8001/#test?name=50", b.Uri.ToString (), "#A7");
+                       Assert.AreEqual (string.Empty, b.UserName, "#A8");
+
+                       b = new UriBuilder ("http://www.ximian.com?name=50#test");
+                       Assert.AreEqual ("#test", b.Fragment, "#B1");
+                       Assert.AreEqual ("www.ximian.com", b.Host, "#B2");
+                       Assert.AreEqual (string.Empty, b.Password, "#B3");
+                       Assert.AreEqual ("/", b.Path, "#B4");
+                       Assert.AreEqual (80, b.Port, "#B5");
+                       Assert.AreEqual ("?name=50", b.Query, "#B5");
+                       Assert.AreEqual ("http", b.Scheme, "#B6");
+                       Assert.AreEqual ("http://www.ximian.com/?name=50#test", b.Uri.ToString (), "#B7");
+                       Assert.AreEqual (string.Empty, b.UserName, "#B8");
+               }
+
+               [Test] // ctor (string)
+               public void Constructor1_Uri_Null ()
+               {
+                       try {
+                               new UriBuilder ((string) null);
+                               Assert.Fail ("#1");
+                       } catch (ArgumentNullException ex) {
+                               Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
+                               Assert.IsNull (ex.InnerException, "#3");
+                               Assert.IsNotNull (ex.Message, "#4");
+                               Assert.IsNotNull (ex.ParamName, "#5");
+                               Assert.AreEqual ("uriString", ex.ParamName, "#6");
+                       }
+               }
+
+               [Test] // ctor (Uri)
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void Constructor2_Uri_Null ()
+               {
+                       new UriBuilder ((Uri) null);
                }
 
                [Test]
@@ -52,32 +109,51 @@ namespace MonoTests.System
                }
                
                [Test]
-               // This test does not make sense, will fix soon
-               [Category ("NotWorking")] // bug #75144
+               public void Constructor_StringStringInt ()
+               {
+                       UriBuilder ub = new UriBuilder ("http", "www.mono-project.com", 80);
+                       Assert.AreEqual ("http://www.mono-project.com/", ub.Uri.AbsoluteUri, "Uri.AbsoluteUri");
+               }
+
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               public void Constructor_RelativeUri ()
+               {
+                       Uri relative = new Uri ("../dir/subdir/file", UriKind.RelativeOrAbsolute);
+                       UriBuilder ub = new UriBuilder (relative);
+               }
+
+               [Test]
                public void UserInfo ()
-               {                       
-                       b = new UriBuilder ("mailto://myname:mypwd@contoso.com?subject=hello");
-#if NET_2_0
-                       AssertEquals ("#1", String.Empty, b.UserName);
-                       AssertEquals ("#2", String.Empty, b.Password);
-#else
-                       // NotWorking here for 1.x (bad behaviour in 1.x - may not be worth fixing)
-                       AssertEquals ("#1", "myname", b.UserName);
-                       AssertEquals ("#2", "mypwd", b.Password);
-#endif                 
+               {
+                       string s = "mailto://myname:mypwd@contoso.com?subject=hello";
+                       b = new UriBuilder (s);
+                       Assert.AreEqual (s, b.ToString (), "1.ToString");
+                       Assert.AreEqual (string.Empty, b.UserName, "1.UserName");
+                       Assert.AreEqual (string.Empty, b.Password, "1.Password");
+                       Assert.AreEqual ("//myname:mypwd@contoso.com", b.Uri.LocalPath, "1.Uri.LocalPath");
+
+                       // weird ?caching? issue, UserInfo is not updated if we look at the value of UserName before setting Password
+                       b = new UriBuilder ("mailto", "contoso.com");
+                       b.UserName = "myname";
+                       Assert.AreEqual ("myname", b.Uri.UserInfo, "2.UserName");
+                       b.Password = "mypwd";
+                       Assert.AreEqual ("myname", b.Uri.UserInfo, "2.Password");
+                       Assert.AreEqual ("/", b.Uri.LocalPath, "2.Uri.LocalPath");
+
                        b = new UriBuilder ("mailto", "contoso.com");
                        b.UserName = "myname";
                        b.Password = "mypwd";
-                       // NotWorking here for 2.0 - worth fixing
-                       AssertEquals ("#3", "myname:mypwd", b.Uri.UserInfo);
+                       Assert.AreEqual ("myname:mypwd", b.Uri.UserInfo, "3.Uri.UserInfo");
+                       Assert.AreEqual ("/", b.Uri.LocalPath, "3.Uri.LocalPath");
                }
 
                [Test]
                public void Path ()
-               {                       
+               {
                        b.Path = ((char) 0xa9) + " 2002";
-                       AssertEquals ("#1", "%C2%A9%202002", b.Path);                   
-               }       
+                       Assert.AreEqual ("%C2%A9%202002", b.Path);
+               }
                
                [Test]
                [ExpectedException (typeof (ArgumentOutOfRangeException))]
@@ -85,93 +161,98 @@ namespace MonoTests.System
                {
                        b.Port = -12345;
                }
-#if NET_2_0
+
                [Test]
                public void DefaultPort ()
                {
                        b.Port = -1;
-                       AssertEquals ("Port", -1, b.Port);
-                       AssertEquals ("ToString", "http://www.ximian.com/foo/bar/index.html", b.ToString ());
+                       Assert.AreEqual (-1, b.Port, "#1");
+                       Assert.AreEqual ("http://www.ximian.com/foo/bar/index.html", b.ToString (), "#2");
                }
-#else
-               [Test]
-               [ExpectedException (typeof (ArgumentOutOfRangeException))]
-               public void BadPort3 ()
-               {
-                       b.Port = -1;
-               }
-#endif
+
                [Test]
                public void Query ()
                {
                        b.Query = ((char) 0xa9) + " 2002";
-                       AssertEquals ("#1", "?\xA9 2002", b.Query);                     
-                       AssertEquals ("#2", String.Empty, b.Fragment);
+                       Assert.AreEqual ("?\xA9 2002", b.Query, "#1");
+                       Assert.AreEqual (string.Empty, b.Fragment, "#2");
                        b.Query = "?test";
-                       AssertEquals ("#3", "??test", b.Query);
+                       Assert.AreEqual ("??test", b.Query, "#3");
+                       b.Query = null;
+                       Assert.AreEqual (string.Empty, b.Query, "#4");
+                       b.Fragment = "test";
+                       Assert.AreEqual ("#test", b.Fragment, "#5");
+                       b.Query = "name";
+                       Assert.AreEqual ("#test", b.Fragment, "#6");
+                       Assert.AreEqual ("?name", b.Query, "#7");
+                       b.Fragment = "run";
+                       Assert.AreEqual ("#run", b.Fragment, "#8");
                        b.Query = null;
-                       AssertEquals ("#4", String.Empty, b.Query);
+                       Assert.AreEqual ("#run", b.Fragment, "#9");
+                       Assert.AreEqual (string.Empty, b.Query, "#10");
                }
                
                [Test]
                public void Fragment ()
                {
                        b.Fragment = ((char) 0xa9) + " 2002";
-                       AssertEquals ("#1", "#\xA9 2002", b.Fragment);
-                       AssertEquals ("#2", String.Empty, b.Query);
+                       Assert.AreEqual ("#\xA9 2002", b.Fragment, "#1");
+                       Assert.AreEqual (string.Empty, b.Query, "#2");
                        b.Fragment = "#test";
-                       AssertEquals ("#3", "##test", b.Fragment);
+                       Assert.AreEqual ("##test", b.Fragment, "#3");
                        b.Fragment = null;
-                       AssertEquals ("#4", String.Empty, b.Fragment);
+                       Assert.AreEqual (String.Empty, b.Fragment, "#4");
+                       b.Query = "name";
+                       Assert.AreEqual ("?name", b.Query, "#5");
+                       b.Fragment = null;
+                       Assert.AreEqual ("?name", b.Query, "#6");
+                       Assert.AreEqual (string.Empty, b.Fragment, "#7");
                }
                
                [Test]
                public void Scheme ()
                {
                        b.Scheme = "http";
-                       AssertEquals ("#1", b.Scheme, "http");
+                       Assert.AreEqual ("http", b.Scheme, "#1");
                        b.Scheme = "http:";
-                       AssertEquals ("#2", b.Scheme, "http");
+                       Assert.AreEqual ("http", b.Scheme, "#2");
                        b.Scheme = "http://";
-                       AssertEquals ("#3", b.Scheme, "http");
+                       Assert.AreEqual ("http", b.Scheme, "#3");
                        b.Scheme = "http://foo/bar";
-                       AssertEquals ("#4", b.Scheme, "http");
+                       Assert.AreEqual ("http", b.Scheme, "#4");
                        b.Scheme = "mailto:";
-                       AssertEquals ("#5", b.Scheme, "mailto");
+                       Assert.AreEqual ("mailto", b.Scheme, "#5");
                        b.Scheme = "unknown";
-                       AssertEquals ("#6", b.Scheme, "unknown");
+                       Assert.AreEqual ("unknown", b.Scheme, "#6");
                        b.Scheme = "unknown://";
-                       AssertEquals ("#7", b.Scheme, "unknown");
+                       Assert.AreEqual ("unknown", b.Scheme, "#7");
                }
                
                [Test]
-#if NET_2_0
-               [Category ("NotWorking")] // equals changed in 2.0
-#endif
                public void Equals ()
                {
                        b = new UriBuilder ("http://", "www.ximian.com", 80, "foo/bar/index.html?item=1");
+                       Assert.AreEqual ("foo/bar/index.html%3Fitem=1", b.Path, "1.Path");
+                       Assert.AreEqual ("http://www.ximian.com:80/foo/bar/index.html%3Fitem=1", b.ToString (), "1.ToString");
+
                        b2 = new UriBuilder ("http", "www.ximian.com", 80, "/foo/bar/index.html", "?item=1");
+                       Assert.AreEqual ("http://www.ximian.com:80/foo/bar/index.html?item=1", b2.ToString (), "2.ToString");
+
                        b3 = new UriBuilder (new Uri ("http://www.ximian.com/foo/bar/index.html?item=1"));
-#if NET_2_0
-                       Assert ("#1", !b.Equals (b2));
-                       Assert ("#2", !b.Uri.Equals (b2.Uri));
-                       Assert ("#3", !b.Equals (b3));
-                       Assert ("#5", !b3.Equals (b));
-#else
-                       Assert ("#1", b.Equals (b2));
-                       Assert ("#2", b.Uri.Equals (b2.Uri));
-                       Assert ("#3", b.Equals (b3));
-                       Assert ("#5", b3.Equals (b));
-#endif
-                       Assert ("#4", b2.Equals (b3));
+                       Assert.AreEqual ("http://www.ximian.com:80/foo/bar/index.html?item=1", b3.ToString (), "3.ToString");
+
+                       Assert.IsFalse (b.Equals (b2), "#1");
+                       Assert.IsFalse (b.Uri.Equals (b2.Uri), "#2");
+                       Assert.IsFalse (b.Equals (b3), "#3");
+                       Assert.IsFalse (b3.Equals (b), "#4");
+                       Assert.IsTrue (b2.Equals (b3), "#5");
                }
                
                [Test]
                public void ToStringTest ()
                {
-                       AssertEquals ("ToString ()", "http://www.ximian.com:80/foo/bar/index.html", b.ToString ());
-                       AssertEquals ("Uri.ToString ()", "http://www.ximian.com/foo/bar/index.html", b.Uri.ToString ());
+                       Assert.AreEqual ("http://www.ximian.com:80/foo/bar/index.html", b.ToString (), "#1");
+                       Assert.AreEqual ("http://www.ximian.com/foo/bar/index.html", b.Uri.ToString (), "#2");
                }
 
                [Test]
@@ -179,13 +260,13 @@ namespace MonoTests.System
                {
                        b = new UriBuilder ("http", "www.ximian.com", 80, "/lalala/lelele.aspx", null);
                        string noquery = "http://www.ximian.com/lalala/lelele.aspx";
-                       AssertEquals ("#01", b.Uri.ToString (), noquery);
+                       Assert.AreEqual (noquery, b.Uri.ToString (), "#1");
                        b = new UriBuilder ("http", "www.ximian.com", 80, "/lalala/lelele.aspx", "?");
-                       AssertEquals ("#02", b.Uri.ToString (), noquery);
+                       Assert.AreEqual (noquery, b.Uri.ToString (), "#2");
                        b = new UriBuilder ("http", "www.ximian.com", 80, "/lalala/lelele.aspx", "??");
-                       AssertEquals ("#03", b.Uri.ToString (), noquery + "??");
+                       Assert.AreEqual (noquery + "??", b.Uri.ToString (), "#3");
                        b = new UriBuilder ("http", "www.ximian.com", 80, "/lalala/lelele.aspx", "?something");
-                       AssertEquals ("#04", b.Uri.ToString (), noquery + "?something");
+                       Assert.AreEqual (noquery + "?something", b.Uri.ToString (), "#4");
                }
 
                [Test] // bug #76501
@@ -194,7 +275,120 @@ namespace MonoTests.System
                        UriBuilder ub = new UriBuilder (
                                "http://mondomaine/trucmuche/login.aspx");
                        ub.Query = ub.Query.TrimStart (new char [] {'?'}) + "&ticket=bla";
-                       Assert (ub.ToString ().IndexOf ("80//") < 0);
+                       Assert.IsTrue (ub.ToString ().IndexOf ("80//") < 0);
+               }
+
+               [Test]
+               public void TestAppendFragment ()
+               {
+                       UriBuilder uri = new UriBuilder ("http://www.mono-project.com/Main_Page");
+                       uri.Fragment = "Features";
+                       Assert.AreEqual ("#Features", uri.Fragment, "#1");
+                       Assert.AreEqual ("http://www.mono-project.com/Main_Page#Features", uri.Uri.ToString (), "#2");
+               }
+
+               [Test]
+               public void IPv6_Host ()
+               {
+                       UriBuilder ub = new UriBuilder ("http", "[1:2:3:4:5:6:7:8]", 8080, "/dir/subdir/file");
+                       Assert.AreEqual ("[1:2:3:4:5:6:7:8]", ub.Host, "Host.1");
+                       if (IriParsing)
+                               Assert.AreEqual ("[1:2:3:4:5:6:7:8]", ub.Uri.Host, "Uri.Host");
+                       else {
+                               Assert.AreEqual ("[0001:0002:0003:0004:0005:0006:0007:0008]", ub.Uri.Host, "Uri.Host");
+                               // once the Uri is created then some builder properties may change
+                               Assert.AreEqual ("[0001:0002:0003:0004:0005:0006:0007:0008]", ub.Host, "Host.2");
+                       }
+               }
+
+               [Test]
+               public void IPv6_Host_IncompleteAddress ()
+               {
+                       UriBuilder ub = new UriBuilder ("http", "1:2:3:4:5:6:7:8", 8080, "/dir/subdir/file");
+                       Assert.AreEqual ("[1:2:3:4:5:6:7:8]", ub.Host, "1.Host");
+                       Assert.AreEqual ("http://[1:2:3:4:5:6:7:8]:8080/dir/subdir/file", ub.ToString (), "1.ToString ()");
+
+                       ub = new UriBuilder ("http", "1:", 8080, "/dir/subdir/file");
+                       Assert.AreEqual ("[1:]", ub.Host, "2.Host");
+                       Assert.AreEqual ("http://[1:]:8080/dir/subdir/file", ub.ToString (), "2.ToString ()");
+
+                       ub = new UriBuilder ("http", "[1:", 8080, "/dir/subdir/file");
+                       Assert.AreEqual ("[1:", ub.Host, "3.Host");
+                       Assert.AreEqual ("http://[1::8080/dir/subdir/file", ub.ToString (), "3.ToString ()");
+
+                       ub = new UriBuilder ("http", "1:2]", 8080, "/dir/subdir/file");
+                       Assert.AreEqual ("[1:2]]", ub.Host, "4.Host");
+                       Assert.AreEqual ("http://[1:2]]:8080/dir/subdir/file", ub.ToString (), "4.ToString ()");
+               }
+
+               [Test]
+               public void Path_UriAbsolutePath_Path ()
+               {
+                       UriBuilder ub = new UriBuilder ("http", "127.0.0.1", 80, "dir/subdir/file");
+                       Assert.AreEqual ("dir/subdir/file", ub.Path, "Path.1");
+                       Assert.AreEqual ("/dir/subdir/file", ub.Uri.AbsolutePath, "Uri.AbsolutePath");
+                       // once the Uri is created then some builder properties may change
+                       Assert.AreEqual ("/dir/subdir/file", ub.Path, "Path.2");
+               }
+
+               [Test]
+               public void UnparsableUri ()
+               {
+                       // some URI can't be parsed by System.Uri but are accepted by UriBuilder
+                       Uri u = null;
+                       string uri = "www.mono-project.com";
+                       Assert.IsFalse (Uri.TryCreate (uri, UriKind.Absolute, out u), "1.Uri.TryCreate");
+                       UriBuilder ub = new UriBuilder (uri);
+                       Assert.AreEqual ("www.mono-project.com", ub.Host, "1.Host");
+                       Assert.AreEqual ("http", ub.Scheme, "1.Scheme");
+                       Assert.AreEqual (80, ub.Port, "1.Port");
+                       Assert.AreEqual ("/", ub.Path, "1.Path");
+
+                       // always assume http, port 80
+                       uri = "ftp.novell.com/dir/subdir/file";
+                       ub = new UriBuilder (uri);
+                       Assert.IsFalse (Uri.TryCreate (uri, UriKind.Absolute, out u), "2.Uri.TryCreate");
+                       Assert.AreEqual ("ftp.novell.com", ub.Host, "2.Host");
+                       Assert.AreEqual ("http", ub.Scheme, "2.Scheme");
+                       Assert.AreEqual (80, ub.Port, "2.Port");
+                       Assert.AreEqual ("/dir/subdir/file", ub.Path, "2.Path");
+               }
+
+               [Test]
+               public void AspNetRedirectUsage_Old ()
+               {
+                       Uri uri = new Uri ("http://192.168.0.21:80/WebResource.axd?d=AAAAAAAAAAEAAAAAAAAAAA2");
+                       UriBuilder ub = new UriBuilder (uri);
+                       ub.Path = "error404.aspx?aspxerrorpath=/WebResource.axd";
+                       ub.Fragment = null;
+                       ub.Password = null;
+                       ub.Query = null;
+                       ub.UserName = null;
+                       // a bug in older UriBuilder did not encode the ? - existing ASP.NET depends on buggy behavior
+                       Assert.AreEqual ("http://192.168.0.21/error404.aspx%3Faspxerrorpath=/WebResource.axd", ub.Uri.ToString ());
+               }
+
+               [Test]
+               public void AspNetRedirectUsage_New ()
+               {
+                       string path = "error404.aspx?aspxerrorpath=/WebResource.axd";
+                       Uri uri = new Uri ("http://192.168.0.21:80/WebResource.axd?d=AAAAAAAAAAEAAAAAAAAAAA2");
+                       UriBuilder ub = new UriBuilder (uri);
+                       int qpos = path.IndexOf ('?');
+                       ub.Path = path.Substring (0, qpos);
+                       ub.Fragment = null;
+                       ub.Password = null;
+                       ub.Query = path.Substring (qpos + 1);
+                       ub.UserName = null;
+                       // this is what ASP.NET really means (the ?)
+                       Assert.AreEqual ("http://192.168.0.21/error404.aspx?aspxerrorpath=/WebResource.axd", ub.Uri.ToString ());
+               }
+
+               [Test]
+               public void NoHostname ()
+               {
+                       UriBuilder ub = new UriBuilder ("about", null, -1, "config");
+                       Assert.AreEqual ("about:config", ub.ToString ());
                }
        }
 }