Fix URi tests (and class) to be omcpatible with both 2.0 and 4.0 (and SL4)
authorSebastien Pouliot <sebastien@ximian.com>
Mon, 13 Sep 2010 21:38:42 +0000 (17:38 -0400)
committerSebastien Pouliot <sebastien@ximian.com>
Mon, 13 Sep 2010 21:38:42 +0000 (17:38 -0400)
* System/Uri.cs: Fix some "bugs" that are not part of FX4 anymore.
Change how Query/Fragment are merged to match FX4 (while keeping it
compatible with buggy FX2 under the NET_2_0 profile)

* Test/System/UriTest.cs: Adjust test cases to work with 4.0. Mark with
NotDotNet two test cases that are Mono/Unix-specific
* Test/System/UriTest2.cs: Add new test cases where a relative Uri is
merged with an absolute Uri (some changes in SL4/FX4 wrt FX2)
* Test/System/UriTest3.cs: Adjust for bugs fixed after FX 2.0.

mcs/class/System/System/Uri.cs
mcs/class/System/Test/System/UriTest.cs
mcs/class/System/Test/System/UriTest2.cs
mcs/class/System/Test/System/UriTest3.cs

index d950223ff29382a65528f675a127d82a4fdb40d2..101f6c94d813e7cfa3eac7e08cdc95ad062276b3 100644 (file)
@@ -285,13 +285,13 @@ namespace System {
                        this.isUnixFilePath = baseUri.isUnixFilePath;
                        this.isOpaquePart = baseUri.isOpaquePart;
 
-                       if (relativeUri == String.Empty) {
+                       if (relativeUri.Length == 0) {
                                this.path = baseUri.path;
                                this.query = baseUri.query;
                                this.fragment = baseUri.fragment;
                                return;
                        }
-                       
+
                        // 8 fragment
                        // Note that in relative constructor, file URI cannot handle '#' as a filename character, but just regarded as a fragment identifier.
                        pos = relativeUri.IndexOf ('#');
@@ -300,16 +300,24 @@ namespace System {
                                        fragment = relativeUri.Substring (pos);
                                else
                                        fragment = "#" + EscapeString (relativeUri.Substring (pos+1));
-                               relativeUri = relativeUri.Substring (0, pos);
+                               relativeUri = pos == 0 ? String.Empty : relativeUri.Substring (0, pos);
                        }
 
+                       bool consider_query = false;
+
                        // 6 query
                        pos = relativeUri.IndexOf ('?');
                        if (pos != -1) {
                                query = relativeUri.Substring (pos);
                                if (!userEscaped)
                                        query = EscapeString (query);
-                               relativeUri = relativeUri.Substring (0, pos);
+#if !NET_4_0 && !MOONLIGHT
+                               consider_query = query.Length > 0;
+#endif
+                               relativeUri = pos == 0 ? String.Empty : relativeUri.Substring (0, pos);
+                       } else if (relativeUri.Length == 0) {
+                               // if there is no relative path then we keep the Query and Fragment from the absolute
+                               query = baseUri.query;
                        }
 
                        if (relativeUri.Length > 0 && relativeUri [0] == '/') {
@@ -327,11 +335,7 @@ namespace System {
                        
                        // par 5.2 step 6 a)
                        path = baseUri.path;
-#if NET_4_0
-                       if (relativeUri.Length > 0) {
-#else
-                       if (relativeUri.Length > 0 || query.Length > 0) {
-#endif
+                       if ((relativeUri.Length > 0) || consider_query) {
                                pos = path.LastIndexOf ('/');
                                if (pos >= 0) 
                                        path = path.Substring (0, pos + 1);
@@ -1019,7 +1023,7 @@ namespace System {
                void AppendQueryAndFragment (ref string result)
                {
                        if (query.Length > 0) {
-                               string q = query [0] == '?' ? '?' + Unescape (query.Substring (1), false) : Unescape (query, false);
+                               string q = query [0] == '?' ? '?' + Unescape (query.Substring (1), true) : Unescape (query, false);
                                result += q;
                        }
                        if (fragment.Length > 0)
@@ -1878,6 +1882,10 @@ namespace System {
 
                public bool IsBaseOf (Uri uri)
                {
+#if NET_4_0
+                       if (uri == null)
+                               throw new ArgumentNullException ("uri");
+#endif
                        return Parser.IsBaseOf (this, uri);
                }
 
@@ -2033,6 +2041,12 @@ namespace System {
                //[MonoTODO ("rework code to avoid exception catching")]
                public static bool TryCreate (Uri baseUri, Uri relativeUri, out Uri result)
                {
+#if NET_4_0
+                       if (relativeUri == null) {
+                               result = null;
+                               return false;
+                       }
+#endif
                        try {
                                // FIXME: this should call UriParser.Resolve
                                result = new Uri (baseUri, relativeUri.OriginalString);
index 2c9d43cd32a7f3dd2fef231efc678a7c0897aadc..bb243a9268cbc74cc515b127d0d615a47180c489 100644 (file)
@@ -716,8 +716,12 @@ namespace MonoTests.System
                        Uri u1 = new Uri("http://localhost:8080/test.aspx?ReturnUrl=%2fSearchDoc%2fSearcher.aspx");
                        Uri u2 = new Uri("http://localhost:8080/test.aspx?ReturnUrl=%252fSearchDoc%252fSearcher.aspx");
 
-                       Assert.AreEqual (u1.ToString (), "http://localhost:8080/test.aspx?ReturnUrl=/SearchDoc/Searcher.aspx", "QE1");
-                       Assert.AreEqual (u2.ToString (), "http://localhost:8080/test.aspx?ReturnUrl=%2fSearchDoc%2fSearcher.aspx", "QE2");
+                       Assert.AreEqual ("http://localhost:8080/test.aspx?ReturnUrl=/SearchDoc/Searcher.aspx", u1.ToString (), "QE1");
+#if NET_2_0
+                       Assert.AreEqual ("http://localhost:8080/test.aspx?ReturnUrl=%252fSearchDoc%252fSearcher.aspx", u2.ToString (), "QE2");
+#else
+                       Assert.AreEqual ("http://localhost:8080/test.aspx?ReturnUrl=%2fSearchDoc%2fSearcher.aspx", u2.ToString (), "QE2");
+#endif
                }
 
                [Test]
@@ -1786,7 +1790,7 @@ namespace MonoTests.System
                        Assert.IsFalse (fileUri.IsUnc, "LocalPath_FileNameWithAtSign IsUnc");
 
                        Assert.AreEqual (fullpath, fileUri.OriginalString, "LocalPath_FileNameWithAtSign OriginalString");
-                       Assert.AreEqual (path, new DerivedUri (fullpath).TestUnescape(path), "LocalPath_FileNameWithAtSign ProtectedUnescape");
+                       Assert.AreEqual (path, new DerivedUri (fullpath).TestUnescape (path), "LocalPath_FileNameWithAtSign ProtectedUnescape");
                        Assert.AreEqual (path, fileUri.AbsolutePath, "LocalPath_FileNameWithAtSign AbsPath");
                        Assert.AreEqual (path, fileUri.LocalPath, "LocalPath_FileNameWithAtSign LocalPath");
                }
@@ -1833,6 +1837,7 @@ namespace MonoTests.System
                }
 
                [Test]
+               [Category ("NotDotNet")]
                public void UnixAbsoluteFilePath_WithSpecialChars1 ()
                {
                        Uri unixuri = new Uri ("/home/user/a@b");
@@ -1840,6 +1845,7 @@ namespace MonoTests.System
                }
 
                [Test]
+               [Category ("NotDotNet")]
                public void UnixAbsoluteFilePath_WithSpecialChars2 ()
                {
                        Uri unixuri = new Uri ("/home/user/a:b");
@@ -1862,9 +1868,9 @@ namespace MonoTests.System
                        Assert.AreEqual ("http://media.libsyn.com/bounce/http://cdn4.libsyn.com/nerdist/somestuff.txt", uri.ToString ());
                }
 
-               public class DerivedUri : Uri
-               {
-                       public DerivedUri (string uriString) : base (uriString)
+               public class DerivedUri : Uri {
+                       public DerivedUri (string uriString)
+                               : base (uriString)
                        {
                        }
 
index f1d6ed3068cfff1b40d6f304c44a60c1d49650fa..1aa479b2fcfd477c563ee0577a0b4f4c5b2e8b27 100644 (file)
@@ -548,6 +548,111 @@ TextWriter sw = Console.Out;
                        Assert.AreEqual (uri.Port.ToString (), uri.GetComponents (UriComponents.StrongPort, UriFormat.Unescaped), "StrongPort");\r
                        Assert.AreEqual (uri.UserInfo, uri.GetComponents (UriComponents.UserInfo, UriFormat.Unescaped), "UserInfo");\r
                }\r
-#endif\r
+#endif
+
+               [Test]
+               public void Merge_Query_Fragment ()
+               {
+                       Uri absolute = new Uri ("http://host/dir/subdir/weird;name?moonlight");
+                       Assert.AreEqual ("?moonlight", absolute.Query, "absolute.Query");
+
+                       Uri merged = new Uri (absolute, "#mono");
+                       Assert.AreEqual ("#mono", merged.Fragment, "merged.Fragment");
+                       Assert.AreEqual ("?moonlight", merged.Query, "merged.Query");
+                       Assert.AreEqual ("http://host/dir/subdir/weird;name?moonlight#mono", merged.ToString (), "merged.ToString");
+               }
+
+               [Test]
+               public void Merge_Query_Query ()
+               {
+                       Uri absolute = new Uri ("http://host/dir/subdir/weird;name?moonlight");
+                       Assert.AreEqual ("?moonlight", absolute.Query, "absolute.Query");
+
+                       Uri merged = new Uri (absolute, "?moon");
+                       Assert.AreEqual ("?moon", merged.Query, "merged.Query");
+#if NET_4_0
+                       Assert.AreEqual ("http://host/dir/subdir/weird;name?moon", merged.ToString (), "merged.ToString");
+#else
+                       Assert.AreEqual ("http://host/dir/subdir/?moon", merged.ToString (), "merged.ToString");
+#endif
+               }
+
+               [Test]
+               public void Merge_Query_RelativePath ()
+               {
+                       Uri absolute = new Uri ("http://host/dir/subdir/weird;name?moonlight");
+                       Assert.AreEqual ("?moonlight", absolute.Query, "absolute.Query");
+
+                       Uri merged = new Uri (absolute, "../");
+                       Assert.AreEqual (String.Empty, merged.Query, "../Query");
+                       Assert.AreEqual ("http://host/dir/", merged.ToString (), "../ToString");
+
+                       merged = new Uri (absolute, "..");
+                       Assert.AreEqual (String.Empty, merged.Query, "..Query");
+                       Assert.AreEqual ("http://host/dir/", merged.ToString (), "..ToString");
+
+                       merged = new Uri (absolute, "./");
+                       Assert.AreEqual (String.Empty, merged.Query, "./Query");
+                       Assert.AreEqual ("http://host/dir/subdir/", merged.ToString (), "./ToString");
+
+                       merged = new Uri (absolute, ".");
+                       Assert.AreEqual (String.Empty, merged.Query, ".Query");
+                       Assert.AreEqual ("http://host/dir/subdir/", merged.ToString (), ".ToString");
+
+                       merged = new Uri (absolute, "/");
+                       Assert.AreEqual (String.Empty, merged.Query, "/Query");
+                       Assert.AreEqual ("http://host/", merged.ToString (), "/ToString");
+
+                       merged = new Uri (absolute, "index.html");
+                       Assert.AreEqual (String.Empty, merged.Query, "index.html Query");
+                       Assert.AreEqual ("http://host/dir/subdir/index.html", merged.ToString (), "index.html ToString");
+
+                       merged = new Uri (absolute, "i");
+                       Assert.AreEqual (String.Empty, merged.Query, "i Query");
+                       Assert.AreEqual ("http://host/dir/subdir/i", merged.ToString (), "i ToString");
+
+                       merged = new Uri (absolute, String.Empty);
+                       Assert.AreEqual ("?moonlight", merged.Query, "Query");
+                       Assert.AreEqual ("http://host/dir/subdir/weird;name?moonlight", merged.ToString (), "ToString");
+               }
+
+               [Test]
+               public void Merge_Fragment_RelativePath ()
+               {
+                       Uri absolute = new Uri ("http://host/dir/subdir/weird;name#mono");
+                       Assert.AreEqual ("#mono", absolute.Fragment, "absolute.Fragment");
+
+                       Uri merged = new Uri (absolute, "../");
+                       Assert.AreEqual (String.Empty, merged.Fragment, "../Fragment");
+                       Assert.AreEqual ("http://host/dir/", merged.ToString (), "../ToString");
+
+                       merged = new Uri (absolute, "..");
+                       Assert.AreEqual (String.Empty, merged.Fragment, "..Fragment");
+                       Assert.AreEqual ("http://host/dir/", merged.ToString (), "..ToString");
+
+                       merged = new Uri (absolute, "./");
+                       Assert.AreEqual (String.Empty, merged.Fragment, "./Fragment");
+                       Assert.AreEqual ("http://host/dir/subdir/", merged.ToString (), "./ToString");
+
+                       merged = new Uri (absolute, ".");
+                       Assert.AreEqual (String.Empty, merged.Fragment, ".Fragment");
+                       Assert.AreEqual ("http://host/dir/subdir/", merged.ToString (), ".ToString");
+
+                       merged = new Uri (absolute, "/");
+                       Assert.AreEqual (String.Empty, merged.Fragment, "/Fragment");
+                       Assert.AreEqual ("http://host/", merged.ToString (), "/ToString");
+
+                       merged = new Uri (absolute, "index.html");
+                       Assert.AreEqual (String.Empty, merged.Fragment, "index.html Fragment");
+                       Assert.AreEqual ("http://host/dir/subdir/index.html", merged.ToString (), "index.html ToString");
+
+                       merged = new Uri (absolute, "i");
+                       Assert.AreEqual (String.Empty, merged.Fragment, "i Fragment");
+                       Assert.AreEqual ("http://host/dir/subdir/i", merged.ToString (), "i ToString");
+
+                       merged = new Uri (absolute, String.Empty);
+                       Assert.AreEqual ("#mono", merged.Fragment, "Fragment");
+                       Assert.AreEqual ("http://host/dir/subdir/weird;name#mono", merged.ToString (), "ToString");
+               }
        }\r
 }\r
index 98cf9ec63e6fa739aa09b90cf988f8db393538b2..fbde811ac667dd97c11f1a12503ce1d0546f07ee 100644 (file)
@@ -292,8 +292,16 @@ namespace MonoTests.System
                        Uri baseUri = new Uri (absolute);
                        try {
                                Uri.TryCreate (baseUri, (Uri) null, out uri);
-                               Assert.Fail ();
-                       } catch (NullReferenceException) {
+#if NET_4_0
+                               Assert.IsNull (uri);
+#else
+                               Assert.Fail ("throw NRE under FX 2.0");
+#endif
+                       }
+                       catch (NullReferenceException) {
+#if NET_4_0
+                               Assert.Fail ("does not throw NRE under FX 4.0");
+#endif
                        }
                }
 
@@ -410,8 +418,14 @@ namespace MonoTests.System
                        try {
                                http.IsBaseOf (null);
                                Assert.Fail ();
-                       } catch (NullReferenceException) {
                        }
+#if NET_4_0
+                       catch (ArgumentNullException) {
+                       }
+#else
+                       catch (NullReferenceException) {
+                       }
+#endif
                }
 
                [Test] 
@@ -487,8 +501,14 @@ namespace MonoTests.System
                        try {
                                uri.MakeRelativeUri ((Uri) null);
                                Assert.Fail ("#1");
-                       } catch (NullReferenceException) {
                        }
+#if NET_4_0
+                       catch (ArgumentNullException) {
+                       }
+#else
+                       catch (NullReferenceException) {
+                       }
+#endif
                }
 
                [Test] // LAMESPEC: see bug #321113