Fix URi tests (and class) to be omcpatible with both 2.0 and 4.0 (and SL4)
[mono.git] / mcs / class / System / Test / System / UriTest3.cs
1 //
2 // UriTest3.cs - Even more (2.0 specific) unit tests for System.Uri
3 //
4 // Author:
5 //      Sebastien Pouliot  <sebastien@ximian.com>
6 //
7 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 #if NET_2_0
30
31 using NUnit.Framework;
32
33 using System;
34
35 namespace MonoTests.System
36 {
37         [TestFixture]
38         public class UriTest3
39         {
40                 private const string absolute = "http://www.mono-project.com/CAS";
41                 private const string relative = "server.com/directory/";
42
43                 [Test] // .ctor (String, UriKind)
44                 public void Constructor4_UriKind_Invalid ()
45                 {
46                         try {
47                                 new Uri ("http://www.contoso.com", (UriKind) 666);
48                                 Assert.Fail ("#1");
49                         } catch (ArgumentException ex) {
50                                 // The value '666' passed for the UriKind parameter
51                                 // is invalid
52                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
53                                 Assert.IsNull (ex.InnerException, "#3");
54                                 Assert.IsNotNull (ex.Message, "#4");
55                                 Assert.IsNotNull (ex.Message.IndexOf ("'666'") != -1, "#5:" + ex.Message);
56                                 Assert.IsNotNull (ex.Message.IndexOf ("UriKind") != -1, "#6:" + ex.Message);
57                                 Assert.IsNull (ex.ParamName, "#7");
58                         }
59                 }
60
61                 [Test] // .ctor (String, UriKind)
62                 public void Constructor4_UriString_Null ()
63                 {
64                         try {
65                                 new Uri ((string) null, (UriKind) 666);
66                                 Assert.Fail ("#1");
67                         } catch (ArgumentNullException ex) {
68                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
69                                 Assert.IsNull (ex.InnerException, "#3");
70                                 Assert.IsNotNull (ex.Message, "#4");
71                                 Assert.AreEqual ("uriString", ex.ParamName, "#5");
72                         }
73                 }
74
75                 [Test]
76                 public void AbsoluteUri_RelativeUri ()
77                 {
78                         Uri uri1 = new Uri ("http://www.contoso.com/index.htm?x=2");
79                         Uri uri2 = new Uri ("http://www.contoso.com/foo/bar/index.htm#fragment");
80                         Uri relativeUri = uri1.MakeRelativeUri (uri2);
81
82                         try {
83                                 string result = relativeUri.AbsoluteUri;
84                                 Assert.Fail ("#1: " + result);
85                         } catch (InvalidOperationException ex) {
86                                 // This operation is not supported for a relative URI
87                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
88                                 Assert.IsNull (ex.InnerException, "#3");
89                                 Assert.IsNotNull (ex.Message, "#4");
90                         }
91                 }
92
93                 [Test]
94                 public void Absolute_UriKind_Absolute ()
95                 {
96                         Uri uri = new Uri (absolute, UriKind.Absolute);
97                         Assert.AreEqual ("www.mono-project.com", uri.DnsSafeHost, "#1");
98                         Assert.IsTrue (uri.IsAbsoluteUri, "#2");
99                         Assert.AreEqual (absolute, uri.OriginalString, "#3");
100                         Assert.AreEqual (absolute, uri.ToString (), "#4");
101                         Assert.IsFalse (uri.UserEscaped, "#5");
102                 }
103
104                 [Test]
105                 public void Relative_UriKind_Relative ()
106                 {
107                         Uri uri = new Uri (relative, UriKind.Relative);
108                         Assert.IsFalse (uri.IsAbsoluteUri, "#A1");
109                         Assert.AreEqual (relative, uri.OriginalString, "#A2");
110                         Assert.AreEqual (relative, uri.ToString (), "#A3");
111                         Assert.IsFalse (uri.UserEscaped, "#A4");
112
113                         uri = new Uri (string.Empty, UriKind.Relative);
114                         Assert.IsFalse (uri.IsAbsoluteUri, "#B1");
115                         Assert.AreEqual (string.Empty, uri.OriginalString, "#B2");
116                         Assert.AreEqual (string.Empty, uri.ToString (), "#B3");
117                         Assert.IsFalse (uri.UserEscaped, "#B4");
118
119                         uri = new Uri ("foo/bar", UriKind.Relative);
120                         Assert.IsFalse (uri.IsAbsoluteUri, "#C1");
121                         Assert.AreEqual ("foo/bar", uri.OriginalString, "#C2");
122                         Assert.AreEqual ("foo/bar", uri.ToString (), "#C3");
123                         Assert.IsFalse (uri.UserEscaped, "#C4");
124
125                         uri = new Uri ("/test.aspx", UriKind.Relative);
126                         Assert.IsFalse (uri.IsAbsoluteUri, "#D1");
127                         Assert.AreEqual ("/test.aspx", uri.OriginalString, "#D2");
128                         Assert.AreEqual ("/test.aspx", uri.ToString (), "#D3");
129                         Assert.IsFalse (uri.UserEscaped, "#D4");
130
131                         uri = new Uri ("", UriKind.Relative);
132                         Assert.IsFalse (uri.IsAbsoluteUri, "#E1");
133                         Assert.AreEqual ("", uri.OriginalString, "#E2");
134                         Assert.AreEqual ("", uri.ToString (), "#E3");
135                         Assert.IsFalse (uri.UserEscaped, "#E4");
136
137                         uri = new Uri ("a", UriKind.Relative);
138                         Assert.IsFalse (uri.IsAbsoluteUri, "#F1");
139                         Assert.AreEqual ("a", uri.OriginalString, "#F2");
140                         Assert.AreEqual ("a", uri.ToString (), "#F3");
141                         Assert.IsFalse (uri.UserEscaped, "#F4");
142                 }
143
144                 [Test]
145                 [ExpectedException (typeof (UriFormatException))]
146                 public void Relative_UriKind_Absolute ()
147                 {
148                         new Uri (relative, UriKind.Absolute);
149                 }
150
151                 [Test]
152                 [ExpectedException (typeof (UriFormatException))]
153                 public void Absolute_UriKind_Relative ()
154                 {
155                         new Uri (absolute, UriKind.Relative);
156                 }
157
158                 [Test] // TryCreate (String, UriKind, Uri)
159                 public void TryCreate1 ()
160                 {
161                         Uri uri;
162
163                         uri = new Uri ("http://dummy.com");
164                         Assert.IsTrue (Uri.TryCreate (absolute, UriKind.Absolute, out uri), "absolute-Absolute");
165                         Assert.AreEqual (absolute, uri.AbsoluteUri, "absolute-Absolute-AbsoluteUri");
166
167                         uri = new Uri ("http://dummy.com");
168                         Assert.IsTrue (Uri.TryCreate (absolute, UriKind.RelativeOrAbsolute, out uri), "absolute-RelativeOrAbsolute");
169                         Assert.AreEqual (absolute, uri.AbsoluteUri, "absolute-RelativeOrAbsolute-AbsoluteUri");
170
171                         uri = new Uri ("http://dummy.com");
172                         Assert.IsFalse (Uri.TryCreate (absolute, UriKind.Relative, out uri), "absolute-Relative");
173                         Assert.IsNull (uri, "absolute-Relative-uri");
174
175                         uri = new Uri ("http://dummy.com");
176                         Assert.IsFalse (Uri.TryCreate (relative, UriKind.Absolute, out uri), "relative-Absolute");
177                         Assert.IsNull (uri, "relative-Relative-uri");
178
179                         uri = new Uri ("http://dummy.com");
180                         Assert.IsTrue (Uri.TryCreate (relative, UriKind.RelativeOrAbsolute, out uri), "relative-RelativeOrAbsolute");
181                         Assert.AreEqual (relative, uri.OriginalString, "relative-RelativeOrAbsolute-OriginalString");
182
183                         uri = new Uri ("http://dummy.com");
184                         Assert.IsTrue (Uri.TryCreate (relative, UriKind.Relative, out uri), "relative-Relative");
185                         Assert.AreEqual (relative, uri.OriginalString, "relative-RelativeOrAbsolute-OriginalString");
186                 }
187
188                 [Test] // TryCreate (String, UriKind, Uri)
189                 public void TryCreate1_UriKind_Invalid ()
190                 {
191                         Uri relativeUri = new Uri (relative, UriKind.Relative);
192                         Uri uri = relativeUri;
193
194                         try {
195                                 Uri.TryCreate (absolute, (UriKind) 666, out uri);
196                                 Assert.Fail ("#A1");
197                         } catch (ArgumentException ex) {
198                                 // The value '666' passed for the UriKind parameter
199                                 // is invalid
200                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
201                                 Assert.IsNull (ex.InnerException, "#A3");
202                                 Assert.IsNotNull (ex.Message, "#A4");
203                                 Assert.IsNotNull (ex.Message.IndexOf ("'666'") != -1, "#A5:" + ex.Message);
204                                 Assert.IsNotNull (ex.Message.IndexOf ("UriKind") != -1, "#A6:" + ex.Message);
205                                 Assert.IsNull (ex.ParamName, "#A7");
206
207                                 Assert.IsNotNull (uri, "#A8");
208                                 Assert.AreSame (relativeUri, uri, "#A9");
209                         }
210
211                         Assert.IsFalse (Uri.TryCreate ((string) null, (UriKind) 666, out uri), "#B1");
212                         Assert.IsNull (uri, "#B2");
213                 }
214
215                 [Test] // TryCreate (Uri, String, Uri)
216                 [Category ("NotWorking")]
217                 public void TryCreate2 ()
218                 {
219                         Uri baseUri = new Uri (absolute);
220                         Uri uri;
221
222                         uri = new Uri ("http://dummy.com");
223                         Assert.IsTrue (Uri.TryCreate (baseUri, relative, out uri), "baseUri+relative");
224                         Assert.AreEqual ("http://www.mono-project.com/server.com/directory/", uri.AbsoluteUri, "baseUri+relative+AbsoluteUri");
225                         Assert.AreEqual ("http://www.mono-project.com/server.com/directory/", uri.OriginalString, "baseUri+relative+OriginalString");
226
227                         uri = new Uri ("http://dummy.com");
228                         Assert.IsTrue (Uri.TryCreate (baseUri, absolute, out uri), "baseUri+absolute");
229                         Assert.AreEqual (absolute, uri.AbsoluteUri, "baseUri+absolute+AbsoluteUri");
230                         Assert.AreEqual (absolute, uri.OriginalString, "baseUri+absolute+OriginalString");
231
232                         uri = new Uri ("http://dummy.com");
233                         Uri relativeUri = new Uri (relative, UriKind.Relative);
234                         Assert.IsFalse (Uri.TryCreate (relativeUri, relative, out uri), "relativeUri+relative");
235                         Assert.IsNull (uri, "relativeUri+relative+Uri");
236
237                         uri = new Uri ("http://dummy.com");
238                         Assert.IsTrue (Uri.TryCreate (relativeUri, absolute, out uri), "relativeUri+absolute");
239                         Assert.AreEqual (absolute, uri.OriginalString, "relativeUri+absolute+OriginalString");
240
241                         uri = new Uri ("http://dummy.com");
242                         string n = null;
243                         Assert.IsFalse (Uri.TryCreate (baseUri, n, out uri), "baseUri+null");
244                         Assert.IsNull (uri, "baseUri+null+Uri");
245                         Assert.IsFalse (Uri.TryCreate (relativeUri, n, out uri), "relativeUri+null");
246                         Assert.IsNull (uri, "relativeUri+null+Uri");
247                         Assert.IsFalse (Uri.TryCreate (null, relative, out uri), "null+relative");
248                         Assert.IsNull (uri, "null+relative+Uri");
249
250                         uri = new Uri ("http://dummy.com");
251                         Assert.IsTrue (Uri.TryCreate (null, absolute, out uri), "null+absolute");
252                         Assert.AreEqual (absolute, uri.OriginalString, "null+absolute+OriginalString");
253                 }
254
255                 [Test] // TryCreate (Uri, Uri, Uri)
256                 [Category ("NotWorking")]
257                 public void TryCreate3 ()
258                 {
259                         Uri baseUri = new Uri (absolute);
260                         Uri relativeUri = new Uri (relative, UriKind.Relative);
261                         Uri uri;
262
263                         uri = new Uri ("http://dummy.com");
264                         Assert.IsTrue (Uri.TryCreate (baseUri, relativeUri, out uri), "baseUri+relativeUri");
265                         Assert.AreEqual ("http://www.mono-project.com/server.com/directory/", uri.AbsoluteUri, "baseUri+relativeUri+AbsoluteUri");
266                         Assert.AreEqual ("http://www.mono-project.com/server.com/directory/", uri.OriginalString, "baseUri+relativeUri+OriginalString");
267
268                         uri = new Uri ("http://dummy.com");
269                         Assert.IsTrue (Uri.TryCreate (baseUri, baseUri, out uri), "baseUri+baseUri");
270                         Assert.AreEqual (absolute, uri.AbsoluteUri, "baseUri+baseUri+AbsoluteUri");
271                         Assert.AreEqual (absolute, uri.OriginalString, "baseUri+baseUri+OriginalString");
272
273                         uri = new Uri ("http://dummy.com");
274                         Assert.IsFalse (Uri.TryCreate (relativeUri, relativeUri, out uri), "relativeUri+relativeUri");
275                         Assert.IsNull (uri, "relativeUri+relativeUri+Uri");
276
277                         uri = new Uri ("http://dummy.com");
278                         Assert.IsFalse (Uri.TryCreate (relativeUri, baseUri, out uri), "relativeUri+baseUri");
279                         Assert.IsNull (uri, "relativeUri+baseUri+Uri");
280
281                         uri = new Uri ("http://dummy.com");
282                         Assert.IsFalse (Uri.TryCreate (null, relativeUri, out uri), "null+relativeUri");
283                         Assert.IsNull (uri, "null+relativeUri+Uri");
284                         Assert.IsFalse (Uri.TryCreate (null, baseUri, out uri), "null+baseUri");
285                         Assert.IsNull (uri, "null+baseUri+Uri");
286                 }
287
288                 [Test] // TryCreate (Uri, Uri, out Uri)
289                 public void TryCreate3_RelativeUri_Null ()
290                 {
291                         Uri uri = null;
292                         Uri baseUri = new Uri (absolute);
293                         try {
294                                 Uri.TryCreate (baseUri, (Uri) null, out uri);
295 #if NET_4_0
296                                 Assert.IsNull (uri);
297 #else
298                                 Assert.Fail ("throw NRE under FX 2.0");
299 #endif
300                         }
301                         catch (NullReferenceException) {
302 #if NET_4_0
303                                 Assert.Fail ("does not throw NRE under FX 4.0");
304 #endif
305                         }
306                 }
307
308                 [Test]
309                 public void IsWellFormedUriString ()
310                 {
311                         Assert.IsFalse (Uri.IsWellFormedUriString ("http://www.go-mono.com/Main Page", UriKind.Absolute), "http/space");
312                         Assert.IsTrue (Uri.IsWellFormedUriString ("http://www.go-mono.com/Main%20Page", UriKind.Absolute), "http/%20");
313                         Assert.IsFalse (Uri.IsWellFormedUriString (null, UriKind.Absolute), "null");
314                         Assert.IsFalse (Uri.IsWellFormedUriString ("data", UriKind.Absolute), "data");
315                         Assert.IsTrue (Uri.IsWellFormedUriString ("http://www.go-mono.com/Main_Page#1", UriKind.Absolute), "http/hex");
316                 }
317
318                 [Test]
319                 public void IsWellFormedUriString_UriKind_Invalid ()
320                 {
321                         try {
322                                 Uri.IsWellFormedUriString ("http://www.go-mono.com/Main Page",
323                                         (UriKind) 666);
324                                 Assert.Fail ("#1");
325                         } catch (ArgumentException ex) {
326                                 // The value '666' passed for the UriKind parameter
327                                 // is invalid
328                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
329                                 Assert.IsNull (ex.InnerException, "#3");
330                                 Assert.IsNotNull (ex.Message, "#4");
331                                 Assert.IsNotNull (ex.Message.IndexOf ("'666'") != -1, "#5:" + ex.Message);
332                                 Assert.IsNotNull (ex.Message.IndexOf ("UriKind") != -1, "#6:" + ex.Message);
333                                 Assert.IsNull (ex.ParamName, "#7");
334                         }
335                 }
336
337                 [Test]
338                 public void Compare ()
339                 {
340                         Uri u1 = null;
341                         Uri u2 = null;
342                         Assert.AreEqual (0, Uri.Compare (u1, u2, UriComponents.AbsoluteUri, UriFormat.UriEscaped, StringComparison.CurrentCulture), "null-null");
343
344                         u1 = new Uri ("http://www.go-mono.com/Main Page");
345                         u2 = new Uri ("http://www.go-mono.com/Main%20Page");
346                         Assert.AreEqual (0, Uri.Compare (u1, u2, UriComponents.AbsoluteUri, UriFormat.Unescaped, StringComparison.CurrentCulture), "http/space-http/%20-unescaped");
347                         Assert.AreEqual (0, Uri.Compare (u1, u2, UriComponents.AbsoluteUri, UriFormat.UriEscaped, StringComparison.CurrentCulture), "http/space-http/%20-escaped");
348                         Assert.AreEqual (0, Uri.Compare (u1, u2, UriComponents.AbsoluteUri, UriFormat.SafeUnescaped, StringComparison.CurrentCulture), "http/space-http/%20-safe");
349                 }
350
351                 [Test]
352                 public void IsBaseOf ()
353                 {
354                         Uri http = new Uri ("http://www.mono-project.com/Main_Page#FAQ?Edit");
355                         Assert.IsTrue (http.IsBaseOf (http), "http-http");
356
357                         Uri u = new Uri ("http://www.mono-project.com/Main_Page#FAQ");
358                         Assert.IsTrue (u.IsBaseOf (http), "http-1a");
359                         Assert.IsTrue (http.IsBaseOf (u), "http-1b");
360
361                         u = new Uri ("http://www.mono-project.com/Main_Page");
362                         Assert.IsTrue (u.IsBaseOf (http), "http-2a");
363                         Assert.IsTrue (http.IsBaseOf (u), "http-2b");
364
365                         u = new Uri ("http://www.mono-project.com/");
366                         Assert.IsTrue (u.IsBaseOf (http), "http-3a");
367                         Assert.IsTrue (http.IsBaseOf (u), "http-3b");
368
369                         u = new Uri ("http://www.mono-project.com/Main_Page/");
370                         Assert.IsFalse (u.IsBaseOf (http), "http-4a");
371                         Assert.IsTrue (http.IsBaseOf (u), "http-4b");
372
373                         // docs says the UserInfo isn't evaluated, but...
374                         u = new Uri ("http://username:password@www.mono-project.com/Main_Page");
375                         Assert.IsFalse (u.IsBaseOf (http), "http-5a");
376                         Assert.IsFalse (http.IsBaseOf (u), "http-5b");
377
378                         // scheme case sensitive ? no
379                         u = new Uri ("HTTP://www.mono-project.com/Main_Page");
380                         Assert.IsTrue (u.IsBaseOf (http), "http-6a");
381                         Assert.IsTrue (http.IsBaseOf (u), "http-6b");
382
383                         // host case sensitive ? no
384                         u = new Uri ("http://www.Mono-Project.com/Main_Page");
385                         Assert.IsTrue (u.IsBaseOf (http), "http-7a");
386                         Assert.IsTrue (http.IsBaseOf (u), "http-7b");
387
388                         // path case sensitive ? no
389                         u = new Uri ("http://www.Mono-Project.com/MAIN_Page");
390                         Assert.IsTrue (u.IsBaseOf (http), "http-8a");
391                         Assert.IsTrue (http.IsBaseOf (u), "http-8b");
392
393                         // different scheme
394                         u = new Uri ("ftp://www.mono-project.com/Main_Page");
395                         Assert.IsFalse (u.IsBaseOf (http), "http-9a");
396                         Assert.IsFalse (http.IsBaseOf (u), "http-9b");
397
398                         // different host
399                         u = new Uri ("http://www.go-mono.com/Main_Page");
400                         Assert.IsFalse (u.IsBaseOf (http), "http-10a");
401                         Assert.IsFalse (http.IsBaseOf (u), "http-10b");
402
403                         // different port
404                         u = new Uri ("http://www.mono-project.com:8080/");
405                         Assert.IsFalse (u.IsBaseOf (http), "http-11a");
406                         Assert.IsFalse (http.IsBaseOf (u), "http-11b");
407
408                         // specify default port
409                         u = new Uri ("http://www.mono-project.com:80/");
410                         Assert.IsTrue (u.IsBaseOf (http), "http-12a");
411                         Assert.IsTrue (http.IsBaseOf (u), "http-12b");
412                 }
413
414                 [Test]
415                 public void IsBaseOf_Null ()
416                 {
417                         Uri http = new Uri ("http://www.mono-project.com/Main_Page#FAQ?Edit");
418                         try {
419                                 http.IsBaseOf (null);
420                                 Assert.Fail ();
421                         }
422 #if NET_4_0
423                         catch (ArgumentNullException) {
424                         }
425 #else
426                         catch (NullReferenceException) {
427                         }
428 #endif
429                 }
430
431                 [Test] 
432                 public void MakeRelativeUri ()
433                 {
434                         Uri uri1 = new Uri ("http://www.contoso.com/index.htm?x=2");
435                         Uri uri2 = new Uri ("http://www.contoso.com/foo/bar/index.htm#fragment");
436                         Uri uri3 = new Uri ("http://www.contoso.com/bar/foo/index.htm?y=1");
437                         Uri uri4 = new Uri ("http://www.contoso.com/bar/foo2/index.htm?x=0");
438                         Uri uri5 = new Uri ("https://www.contoso.com/bar/foo/index.htm?y=1");
439                         Uri uri6 = new Uri ("http://www.contoso2.com/bar/foo/index.htm?x=0");
440                         Uri uri7 = new Uri ("http://www.contoso2.com/bar/foo/foobar.htm?z=0&y=5");
441                         Uri uri8 = new Uri ("http://www.xxx.com/bar/foo/foobar.htm?z=0&y=5" + (char) 0xa9);
442                         Uri uri10 = new Uri ("mailto:xxx@xxx.com");
443                         Uri uri11 = new Uri ("mailto:xxx@xxx.com?subject=hola");
444                         Uri uri12 = new Uri ("mailto:xxx@mail.xxx.com?subject=hola");
445                         Uri uri13 = new Uri ("mailto:xxx@xxx.com/foo/bar");
446
447                         AssertRelativeUri ("foo/bar/index.htm#fragment", uri1, uri2, "#A");
448                         AssertRelativeUri ("../../index.htm?x=2", uri2, uri1, "#B");
449                         AssertRelativeUri ("../../bar/foo/index.htm?y=1", uri2, uri3, "#C");
450                         AssertRelativeUri ("../../foo/bar/index.htm#fragment", uri3, uri2, "#D");
451                         AssertRelativeUri ("../foo2/index.htm?x=0", uri3, uri4, "#E");
452                         AssertRelativeUri ("../foo/index.htm?y=1", uri4, uri3, "#F");
453                         AssertRelativeUri ("?x=0", uri6, uri6, "#G");
454                         AssertRelativeUri ("foobar.htm?z=0&y=5", uri6, uri7, "#H");
455                         AssertRelativeUri ("?subject=hola", uri10, uri11, "#I");
456                         AssertRelativeUri ("/foo/bar", uri10, uri13, "#J");
457
458                         Uri relativeUri = uri1.MakeRelativeUri (uri8);
459                         Assert.IsTrue (relativeUri.IsAbsoluteUri, "#K1");
460                         Assert.AreEqual (uri8.ToString (), relativeUri.ToString (), "#K2");
461                         Assert.AreEqual (uri8.OriginalString, relativeUri.OriginalString, "#K3");
462
463                         relativeUri = uri10.MakeRelativeUri (uri12);
464                         Assert.IsTrue (relativeUri.IsAbsoluteUri, "#L1");
465                         Assert.AreEqual (uri12.ToString (), relativeUri.ToString (), "#L2");
466                         Assert.AreEqual (uri12.OriginalString, relativeUri.OriginalString, "#L3");
467
468                         relativeUri = uri4.MakeRelativeUri (uri6);
469                         Assert.IsTrue (relativeUri.IsAbsoluteUri, "#M1");
470                         Assert.AreEqual (uri6.ToString (), relativeUri.ToString (), "#M2");
471                         Assert.AreEqual (uri6.OriginalString, relativeUri.OriginalString, "#M3");
472
473                         relativeUri = uri4.MakeRelativeUri (uri5);
474                         Assert.IsTrue (relativeUri.IsAbsoluteUri, "#N1");
475                         Assert.AreEqual (uri5.ToString (), relativeUri.ToString (), "#N2");
476                         Assert.AreEqual (uri5.OriginalString, relativeUri.OriginalString, "#N3");
477                 }
478
479                 [Test]
480                 [Category ("NotDotNet")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=299942
481                 public void MakeRelativeUri_Uri_Null_Mono ()
482                 {
483                         Uri uri = new Uri ("http://test.com");
484                         try {
485                                 uri.MakeRelativeUri ((Uri) null);
486                                 Assert.Fail ("#1");
487                         } catch (ArgumentNullException ex) {
488                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
489                                 Assert.IsNull (ex.InnerException, "#3");
490                                 Assert.IsNotNull (ex.Message, "#4");
491                                 Assert.IsNotNull (ex.ParamName, "#5");
492                                 Assert.AreEqual ("uri", ex.ParamName, "#6");
493                         }
494                 }
495
496                 [Test]
497                 [Category ("NotWorking")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=299942
498                 public void MakeRelativeUri_Uri_Null_MS ()
499                 {
500                         Uri uri = new Uri ("http://test.com");
501                         try {
502                                 uri.MakeRelativeUri ((Uri) null);
503                                 Assert.Fail ("#1");
504                         }
505 #if NET_4_0
506                         catch (ArgumentNullException) {
507                         }
508 #else
509                         catch (NullReferenceException) {
510                         }
511 #endif
512                 }
513
514                 [Test] // LAMESPEC: see bug #321113
515                 public void OriginalStringRelative ()
516                 {
517                         Uri k1 = new Uri ("http://www.mono-project.com");
518                         Uri k2 = new Uri (k1, "docs");
519                         Assert.AreEqual ("http://www.mono-project.com/docs", k2.OriginalString, "#1");
520
521                         Uri a = new Uri ("http://www.mono-project.com:808/foo");
522                         Uri b = new Uri (a, "../docs?queryyy#% %20%23%25bar");
523                         //Assert.AreEqual ("http://www.mono-project.com:808/docs?queryyy#% %20%23%25bar", b.OriginalString, "#2");
524
525                         Uri c = new Uri ("http://www.mono-project.com:808/foo");
526                         Uri d = new Uri (a, "../docs?queryyy#%20%23%25bar");
527                         Assert.AreEqual ("http://www.mono-project.com:808/docs?queryyy#%20%23%25bar", d.OriginalString, "#3");
528
529                         Uri e = new Uri ("http://www.mono-project.com:909");
530                         Uri f = new Uri (e, "http://www.mono-project.com:606/docs");
531                         Assert.AreEqual ("http://www.mono-project.com:606/docs", f.OriginalString, "#4");
532
533                         Uri g = new Uri ("http://www.mono-project.com:303/foo");
534                         Uri h = new Uri (g, "?query");
535                         // it doesn't work. MS.NET also returns incorrect URI: ..303/?query
536                         // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=412604
537                         //Assert.AreEqual ("http://www.mono-project.com:303/foo?query", h.OriginalString, "#5");
538                 }
539
540                 [Test]
541                 public void PathAndQuery_RelativeUri ()
542                 {
543                         Uri uri1 = new Uri ("http://www.contoso.com/index.htm?x=2");
544                         Uri uri2 = new Uri ("http://www.contoso.com/foo/bar/index.htm#fragment");
545                         Uri relativeUri = uri1.MakeRelativeUri (uri2);
546
547                         try {
548                                 string result = relativeUri.PathAndQuery;
549                                 Assert.Fail ("#1: " + result);
550                         } catch (InvalidOperationException ex) {
551                                 // This operation is not supported for a relative URI
552                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
553                                 Assert.IsNull (ex.InnerException, "#3");
554                                 Assert.IsNotNull (ex.Message, "#4");
555                         }
556                 }
557
558                 [Test]
559                 public void Query_RelativeUri ()
560                 {
561                         Uri uri1 = new Uri ("http://www.contoso.com/index.htm?x=2");
562                         Uri uri2 = new Uri ("http://www.contoso.com/foo/bar/index.htm#fragment");
563                         Uri relativeUri = uri1.MakeRelativeUri (uri2);
564
565                         try {
566                                 string result = relativeUri.Query;
567                                 Assert.Fail ("#1: " + result);
568                         } catch (InvalidOperationException ex) {
569                                 // This operation is not supported for a relative URI
570                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
571                                 Assert.IsNull (ex.InnerException, "#3");
572                                 Assert.IsNotNull (ex.Message, "#4");
573                         }
574                 }
575
576                 [Test]
577                 public void Scheme_RelativeUri ()
578                 {
579                         Uri uri1 = new Uri ("http://www.contoso.com/index.htm?x=2");
580                         Uri uri2 = new Uri ("http://www.contoso.com/foo/bar/index.htm#fragment");
581                         Uri relativeUri = uri1.MakeRelativeUri (uri2);
582
583                         try {
584                                 string result = relativeUri.Scheme;
585                                 Assert.Fail ("#1: " + result);
586                         } catch (InvalidOperationException ex) {
587                                 // This operation is not supported for a relative URI
588                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
589                                 Assert.IsNull (ex.InnerException, "#3");
590                                 Assert.IsNotNull (ex.Message, "#4");
591                         }
592                 }
593
594                 [Test]
595                 public void UnescapeDataString ()
596                 {
597                         Assert.AreEqual ("/new folder/", Uri.UnescapeDataString ("/new%20folder/"));
598                         Assert.AreEqual ("/new folder/", Uri.UnescapeDataString ("/new%20%66older/"));
599                         Assert.AreEqual ("/new+folder/", Uri.UnescapeDataString ("/new+folder/"));
600                 }
601
602                 void AssertRelativeUri (string expected, Uri uri1, Uri uri2, string msg)
603                 {
604                         Uri relativeUri;
605                         relativeUri = uri1.MakeRelativeUri (uri2);
606                         
607                         Assert.IsFalse (relativeUri.IsAbsoluteUri, msg + "1");
608                         Assert.AreEqual (expected, relativeUri.ToString (), msg + "2");
609                         Assert.AreEqual (expected, relativeUri.OriginalString, msg + "3");
610                         Assert.IsFalse (relativeUri.UserEscaped, msg + "4");
611                 }
612
613                 [Test]
614                 public void DontCheckHostWithCustomParsers ()
615                 {
616                         UriParser.Register (new TolerantUriParser (), "assembly", 0);
617                         try {
618                                 new Uri ("assembly://Spring.Core, Version=1.2.0.20001, Culture=neutral, "
619                                         + "PublicKeyToken=null/Spring.Objects.Factory.Xml/spring-objects-1.1.xsd");
620                         } catch (UriFormatException) {
621                                 Assert.Fail ("Spring Uri is expected to work.");
622                         }
623                 }
624
625                 [Test]
626                 public void ParseShortNameAsRelativeOrAbsolute ()
627                 {
628                         new Uri ("x", UriKind.RelativeOrAbsolute);
629                 }
630
631                 private class TolerantUriParser : GenericUriParser
632                 {
633                         private const GenericUriParserOptions DefaultOptions
634                                 = GenericUriParserOptions.Default
635                                 | GenericUriParserOptions.GenericAuthority
636                                 | GenericUriParserOptions.AllowEmptyAuthority;
637                         
638                         public TolerantUriParser()
639                                                         : base(DefaultOptions)
640                         {
641                         }
642                 }
643         }
644 }
645
646 #endif