Merge pull request #1222 from LogosBible/uri-trycreate
[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 using NUnit.Framework;
30
31 using System;
32
33 namespace MonoTests.System
34 {
35         [TestFixture]
36         public class UriTest3
37         {
38                 private const string absolute = "http://www.mono-project.com/CAS";
39                 private const string relative = "server.com/directory/";
40
41                 [Test] // .ctor (String, UriKind)
42                 public void Constructor4_UriKind_Invalid ()
43                 {
44                         try {
45                                 new Uri ("http://www.contoso.com", (UriKind) 666);
46                                 Assert.Fail ("#1");
47                         } catch (ArgumentException ex) {
48                                 // The value '666' passed for the UriKind parameter
49                                 // is invalid
50                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
51                                 Assert.IsNull (ex.InnerException, "#3");
52                                 Assert.IsNotNull (ex.Message, "#4");
53                                 Assert.IsNotNull (ex.Message.IndexOf ("'666'") != -1, "#5:" + ex.Message);
54                                 Assert.IsNotNull (ex.Message.IndexOf ("UriKind") != -1, "#6:" + ex.Message);
55                                 Assert.IsNull (ex.ParamName, "#7");
56                         }
57                 }
58
59                 [Test] // .ctor (String, UriKind)
60                 public void Constructor4_UriString_Null ()
61                 {
62                         try {
63                                 new Uri ((string) null, (UriKind) 666);
64                                 Assert.Fail ("#1");
65                         } catch (ArgumentNullException ex) {
66                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
67                                 Assert.IsNull (ex.InnerException, "#3");
68                                 Assert.IsNotNull (ex.Message, "#4");
69                                 Assert.AreEqual ("uriString", ex.ParamName, "#5");
70                         }
71                 }
72
73                 [Test]
74                 public void AbsoluteUri_RelativeUri ()
75                 {
76                         Uri uri1 = new Uri ("http://www.contoso.com/index.htm?x=2");
77                         Uri uri2 = new Uri ("http://www.contoso.com/foo/bar/index.htm#fragment");
78                         Uri relativeUri = uri1.MakeRelativeUri (uri2);
79
80                         try {
81                                 string result = relativeUri.AbsoluteUri;
82                                 Assert.Fail ("#1: " + result);
83                         } catch (InvalidOperationException ex) {
84                                 // This operation is not supported for a relative URI
85                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
86                                 Assert.IsNull (ex.InnerException, "#3");
87                                 Assert.IsNotNull (ex.Message, "#4");
88                         }
89                 }
90
91                 [Test]
92                 public void Absolute_UriKind_Absolute ()
93                 {
94                         Uri uri = new Uri (absolute, UriKind.Absolute);
95                         Assert.AreEqual ("www.mono-project.com", uri.DnsSafeHost, "#1");
96                         Assert.IsTrue (uri.IsAbsoluteUri, "#2");
97                         Assert.AreEqual (absolute, uri.OriginalString, "#3");
98                         Assert.AreEqual (absolute, uri.ToString (), "#4");
99                         Assert.IsFalse (uri.UserEscaped, "#5");
100                 }
101
102                 [Test]
103                 public void Relative_UriKind_Relative ()
104                 {
105                         Uri uri = new Uri (relative, UriKind.Relative);
106                         Assert.IsFalse (uri.IsAbsoluteUri, "#A1");
107                         Assert.AreEqual (relative, uri.OriginalString, "#A2");
108                         Assert.AreEqual (relative, uri.ToString (), "#A3");
109                         Assert.IsFalse (uri.UserEscaped, "#A4");
110
111                         uri = new Uri (string.Empty, UriKind.Relative);
112                         Assert.IsFalse (uri.IsAbsoluteUri, "#B1");
113                         Assert.AreEqual (string.Empty, uri.OriginalString, "#B2");
114                         Assert.AreEqual (string.Empty, uri.ToString (), "#B3");
115                         Assert.IsFalse (uri.UserEscaped, "#B4");
116
117                         uri = new Uri ("foo/bar", UriKind.Relative);
118                         Assert.IsFalse (uri.IsAbsoluteUri, "#C1");
119                         Assert.AreEqual ("foo/bar", uri.OriginalString, "#C2");
120                         Assert.AreEqual ("foo/bar", uri.ToString (), "#C3");
121                         Assert.IsFalse (uri.UserEscaped, "#C4");
122
123                         uri = new Uri ("/test.aspx", UriKind.Relative);
124                         Assert.IsFalse (uri.IsAbsoluteUri, "#D1");
125                         Assert.AreEqual ("/test.aspx", uri.OriginalString, "#D2");
126                         Assert.AreEqual ("/test.aspx", uri.ToString (), "#D3");
127                         Assert.IsFalse (uri.UserEscaped, "#D4");
128
129                         uri = new Uri ("", UriKind.Relative);
130                         Assert.IsFalse (uri.IsAbsoluteUri, "#E1");
131                         Assert.AreEqual ("", uri.OriginalString, "#E2");
132                         Assert.AreEqual ("", uri.ToString (), "#E3");
133                         Assert.IsFalse (uri.UserEscaped, "#E4");
134
135                         uri = new Uri ("a", UriKind.Relative);
136                         Assert.IsFalse (uri.IsAbsoluteUri, "#F1");
137                         Assert.AreEqual ("a", uri.OriginalString, "#F2");
138                         Assert.AreEqual ("a", uri.ToString (), "#F3");
139                         Assert.IsFalse (uri.UserEscaped, "#F4");
140                 }
141
142                 [Test]
143                 [ExpectedException (typeof (UriFormatException))]
144                 public void Relative_UriKind_Absolute ()
145                 {
146                         new Uri (relative, UriKind.Absolute);
147                 }
148
149                 [Test]
150                 [ExpectedException (typeof (UriFormatException))]
151                 public void Absolute_UriKind_Relative ()
152                 {
153                         new Uri (absolute, UriKind.Relative);
154                 }
155
156                 [Test] // TryCreate (String, UriKind, Uri)
157                 public void TryCreate1 ()
158                 {
159                         Uri uri;
160
161                         uri = new Uri ("http://dummy.com");
162                         Assert.IsTrue (Uri.TryCreate (absolute, UriKind.Absolute, out uri), "absolute-Absolute");
163                         Assert.AreEqual (absolute, uri.AbsoluteUri, "absolute-Absolute-AbsoluteUri");
164
165                         uri = new Uri ("http://dummy.com");
166                         Assert.IsTrue (Uri.TryCreate (absolute, UriKind.RelativeOrAbsolute, out uri), "absolute-RelativeOrAbsolute");
167                         Assert.AreEqual (absolute, uri.AbsoluteUri, "absolute-RelativeOrAbsolute-AbsoluteUri");
168
169                         uri = new Uri ("http://dummy.com");
170                         Assert.IsFalse (Uri.TryCreate (absolute, UriKind.Relative, out uri), "absolute-Relative");
171                         Assert.IsNull (uri, "absolute-Relative-uri");
172
173                         uri = new Uri ("http://dummy.com");
174                         Assert.IsFalse (Uri.TryCreate (relative, UriKind.Absolute, out uri), "relative-Absolute");
175                         Assert.IsNull (uri, "relative-Relative-uri");
176
177                         uri = new Uri ("http://dummy.com");
178                         Assert.IsTrue (Uri.TryCreate (relative, UriKind.RelativeOrAbsolute, out uri), "relative-RelativeOrAbsolute");
179                         Assert.AreEqual (relative, uri.OriginalString, "relative-RelativeOrAbsolute-OriginalString");
180
181                         uri = new Uri ("http://dummy.com");
182                         Assert.IsTrue (Uri.TryCreate (relative, UriKind.Relative, out uri), "relative-Relative");
183                         Assert.AreEqual (relative, uri.OriginalString, "relative-RelativeOrAbsolute-OriginalString");
184
185                         Assert.IsTrue (Uri.TryCreate ("http://mono-project.com/☕", UriKind.Absolute, out uri), "highunicode-Absolute");
186                         Assert.AreEqual("http://mono-project.com/%E2%98%95", uri.AbsoluteUri, "highunicode-Absolute-AbsoluteUri");
187
188                         string mixedCaseUri = "http://mOnO-proJECT.com";
189                         uri = new Uri (mixedCaseUri);
190                         Uri uri2;
191                         Assert.IsTrue (Uri.TryCreate (mixedCaseUri, UriKind.Absolute, out uri2), "mixedcasehost-absolute");
192                         Assert.AreEqual (uri.AbsoluteUri, uri2.AbsoluteUri, "mixedcasehost-absoluteuri-absoluteuri");
193                 }
194
195                 [Test] // TryCreate (String, UriKind, Uri)
196                 public void TryCreate1_UriKind_Invalid ()
197                 {
198                         Uri relativeUri = new Uri (relative, UriKind.Relative);
199                         Uri uri = relativeUri;
200
201                         try {
202                                 Uri.TryCreate (absolute, (UriKind) 666, out uri);
203                                 Assert.Fail ("#A1");
204                         } catch (ArgumentException ex) {
205                                 // The value '666' passed for the UriKind parameter
206                                 // is invalid
207                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#A2");
208                                 Assert.IsNull (ex.InnerException, "#A3");
209                                 Assert.IsNotNull (ex.Message, "#A4");
210                                 Assert.IsNotNull (ex.Message.IndexOf ("'666'") != -1, "#A5:" + ex.Message);
211                                 Assert.IsNotNull (ex.Message.IndexOf ("UriKind") != -1, "#A6:" + ex.Message);
212                                 Assert.IsNull (ex.ParamName, "#A7");
213
214                                 Assert.IsNotNull (uri, "#A8");
215                                 Assert.AreSame (relativeUri, uri, "#A9");
216                         }
217
218                         Assert.IsFalse (Uri.TryCreate ((string) null, (UriKind) 666, out uri), "#B1");
219                         Assert.IsNull (uri, "#B2");
220                 }
221
222                 [Test] // TryCreate (Uri, String, Uri)
223                 public void TryCreate2 ()
224                 {
225                         Uri baseUri = new Uri (absolute);
226                         Uri uri;
227
228                         uri = new Uri ("http://dummy.com");
229                         Assert.IsTrue (Uri.TryCreate (baseUri, relative, out uri), "baseUri+relative");
230                         Assert.AreEqual ("http://www.mono-project.com/server.com/directory/", uri.AbsoluteUri, "baseUri+relative+AbsoluteUri");
231                         Assert.AreEqual ("http://www.mono-project.com/server.com/directory/", uri.OriginalString, "baseUri+relative+OriginalString");
232
233                         uri = new Uri ("http://dummy.com");
234                         Assert.IsTrue (Uri.TryCreate (baseUri, absolute, out uri), "baseUri+absolute");
235                         Assert.AreEqual (absolute, uri.AbsoluteUri, "baseUri+absolute+AbsoluteUri");
236                         Assert.AreEqual (absolute, uri.OriginalString, "baseUri+absolute+OriginalString");
237
238                         uri = new Uri ("http://dummy.com");
239                         Uri relativeUri = new Uri (relative, UriKind.Relative);
240                         Assert.IsFalse (Uri.TryCreate (relativeUri, relative, out uri), "relativeUri+relative");
241                         Assert.IsNull (uri, "relativeUri+relative+Uri");
242
243                         uri = new Uri ("http://dummy.com");
244                         Assert.IsTrue (Uri.TryCreate (relativeUri, absolute, out uri), "relativeUri+absolute");
245                         Assert.AreEqual (absolute, uri.OriginalString, "relativeUri+absolute+OriginalString");
246
247                         uri = new Uri ("http://dummy.com");
248                         string n = null;
249                         Assert.IsFalse (Uri.TryCreate (baseUri, n, out uri), "baseUri+null");
250                         Assert.IsNull (uri, "baseUri+null+Uri");
251                         Assert.IsFalse (Uri.TryCreate (relativeUri, n, out uri), "relativeUri+null");
252                         Assert.IsNull (uri, "relativeUri+null+Uri");
253                         Assert.IsFalse (Uri.TryCreate (null, relative, out uri), "null+relative");
254                         Assert.IsNull (uri, "null+relative+Uri");
255
256                         uri = new Uri ("http://dummy.com");
257                         Assert.IsTrue (Uri.TryCreate (null, absolute, out uri), "null+absolute");
258                         Assert.AreEqual (absolute, uri.OriginalString, "null+absolute+OriginalString");
259                 }
260
261                 [Test] // TryCreate (Uri, Uri, Uri)
262                 public void TryCreate3 ()
263                 {
264                         Uri baseUri = new Uri (absolute);
265                         Uri relativeUri = new Uri (relative, UriKind.Relative);
266                         Uri uri;
267
268                         uri = new Uri ("http://dummy.com");
269                         Assert.IsTrue (Uri.TryCreate (baseUri, relativeUri, out uri), "baseUri+relativeUri");
270                         Assert.AreEqual ("http://www.mono-project.com/server.com/directory/", uri.AbsoluteUri, "baseUri+relativeUri+AbsoluteUri");
271                         Assert.AreEqual ("http://www.mono-project.com/server.com/directory/", uri.OriginalString, "baseUri+relativeUri+OriginalString");
272
273                         uri = new Uri ("http://dummy.com");
274                         Assert.IsTrue (Uri.TryCreate (baseUri, baseUri, out uri), "baseUri+baseUri");
275                         Assert.AreEqual (absolute, uri.AbsoluteUri, "baseUri+baseUri+AbsoluteUri");
276                         Assert.AreEqual (absolute, uri.OriginalString, "baseUri+baseUri+OriginalString");
277
278                         uri = new Uri ("http://dummy.com");
279                         Assert.IsFalse (Uri.TryCreate (relativeUri, relativeUri, out uri), "relativeUri+relativeUri");
280                         Assert.IsNull (uri, "relativeUri+relativeUri+Uri");
281
282                         uri = new Uri ("http://dummy.com");
283                         Assert.IsFalse (Uri.TryCreate (relativeUri, baseUri, out uri), "relativeUri+baseUri");
284                         Assert.IsNull (uri, "relativeUri+baseUri+Uri");
285
286                         uri = new Uri ("http://dummy.com");
287                         Assert.IsFalse (Uri.TryCreate (null, relativeUri, out uri), "null+relativeUri");
288                         Assert.IsNull (uri, "null+relativeUri+Uri");
289                         Assert.IsFalse (Uri.TryCreate (null, baseUri, out uri), "null+baseUri");
290                         Assert.IsNull (uri, "null+baseUri+Uri");
291                 }
292
293                 [Test] // TryCreate (Uri, Uri, out Uri)
294                 public void TryCreate3_RelativeUri_Null ()
295                 {
296                         Uri uri = null;
297                         Uri baseUri = new Uri (absolute);
298                         try {
299                                 Uri.TryCreate (baseUri, (Uri) null, out uri);
300 #if NET_4_0
301                                 Assert.IsNull (uri);
302 #else
303                                 Assert.Fail ("throw NRE under FX 2.0");
304 #endif
305                         }
306                         catch (NullReferenceException) {
307 #if NET_4_0
308                                 Assert.Fail ("does not throw NRE under FX 4.0");
309 #endif
310                         }
311                 }
312
313                 [Test]
314                 public void IsWellFormedUriString ()
315                 {
316                         Assert.IsFalse (Uri.IsWellFormedUriString ("http://www.go-mono.com/Main Page", UriKind.Absolute), "http/space");
317                         Assert.IsTrue (Uri.IsWellFormedUriString ("http://www.go-mono.com/Main%20Page", UriKind.Absolute), "http/%20");
318                         Assert.IsFalse (Uri.IsWellFormedUriString (null, UriKind.Absolute), "null");
319                         Assert.IsFalse (Uri.IsWellFormedUriString ("data", UriKind.Absolute), "data");
320                         Assert.IsTrue (Uri.IsWellFormedUriString ("http://www.go-mono.com/Main_Page#1", UriKind.Absolute), "http/hex");
321                 }
322
323                 [Test]
324                 public void IsWellFormedUriString_UriKind_Invalid ()
325                 {
326                         try {
327                                 Uri.IsWellFormedUriString ("http://www.go-mono.com/Main Page",
328                                         (UriKind) 666);
329                                 Assert.Fail ("#1");
330                         } catch (ArgumentException ex) {
331                                 // The value '666' passed for the UriKind parameter
332                                 // is invalid
333                                 Assert.AreEqual (typeof (ArgumentException), ex.GetType (), "#2");
334                                 Assert.IsNull (ex.InnerException, "#3");
335                                 Assert.IsNotNull (ex.Message, "#4");
336                                 Assert.IsNotNull (ex.Message.IndexOf ("'666'") != -1, "#5:" + ex.Message);
337                                 Assert.IsNotNull (ex.Message.IndexOf ("UriKind") != -1, "#6:" + ex.Message);
338                                 Assert.IsNull (ex.ParamName, "#7");
339                         }
340                 }
341
342                 [Test]
343                 public void Compare ()
344                 {
345                         Uri u1 = null;
346                         Uri u2 = null;
347                         Assert.AreEqual (0, Uri.Compare (u1, u2, UriComponents.AbsoluteUri, UriFormat.UriEscaped, StringComparison.CurrentCulture), "null-null");
348
349                         u1 = new Uri ("http://www.go-mono.com");
350                         Assert.AreEqual (1, Uri.Compare (u1, u2, UriComponents.AbsoluteUri, UriFormat.UriEscaped, StringComparison.CurrentCulture), "non-null - null");
351
352                         u1 = null;
353                         u2 = new Uri ("http://www.go-mono.com");
354                         Assert.AreEqual (-1, Uri.Compare (u1, u2, UriComponents.AbsoluteUri, UriFormat.UriEscaped, StringComparison.CurrentCulture), "null - non-null");
355
356                         u1 = new Uri ("http://www.go-mono.com/Main Page");
357                         u2 = new Uri ("http://www.go-mono.com/Main%20Page");
358                         Assert.AreEqual (0, Uri.Compare (u1, u2, UriComponents.AbsoluteUri, UriFormat.Unescaped, StringComparison.CurrentCulture), "http/space-http/%20-unescaped");
359                         Assert.AreEqual (0, Uri.Compare (u1, u2, UriComponents.AbsoluteUri, UriFormat.UriEscaped, StringComparison.CurrentCulture), "http/space-http/%20-escaped");
360                         Assert.AreEqual (0, Uri.Compare (u1, u2, UriComponents.AbsoluteUri, UriFormat.SafeUnescaped, StringComparison.CurrentCulture), "http/space-http/%20-safe");
361                 }
362
363                 [Test]
364                 public void IsBaseOf ()
365                 {
366                         Uri http = new Uri ("http://www.mono-project.com/Main_Page#FAQ?Edit");
367                         Assert.IsTrue (http.IsBaseOf (http), "http-http");
368
369                         Uri u = new Uri ("http://www.mono-project.com/Main_Page#FAQ");
370                         Assert.IsTrue (u.IsBaseOf (http), "http-1a");
371                         Assert.IsTrue (http.IsBaseOf (u), "http-1b");
372
373                         u = new Uri ("http://www.mono-project.com/Main_Page");
374                         Assert.IsTrue (u.IsBaseOf (http), "http-2a");
375                         Assert.IsTrue (http.IsBaseOf (u), "http-2b");
376
377                         u = new Uri ("http://www.mono-project.com/");
378                         Assert.IsTrue (u.IsBaseOf (http), "http-3a");
379                         Assert.IsTrue (http.IsBaseOf (u), "http-3b");
380
381                         u = new Uri ("http://www.mono-project.com/Main_Page/");
382                         Assert.IsFalse (u.IsBaseOf (http), "http-4a");
383                         Assert.IsTrue (http.IsBaseOf (u), "http-4b");
384
385                         // docs says the UserInfo isn't evaluated, but...
386                         u = new Uri ("http://username:password@www.mono-project.com/Main_Page");
387                         Assert.IsFalse (u.IsBaseOf (http), "http-5a");
388                         Assert.IsFalse (http.IsBaseOf (u), "http-5b");
389
390                         // scheme case sensitive ? no
391                         u = new Uri ("HTTP://www.mono-project.com/Main_Page");
392                         Assert.IsTrue (u.IsBaseOf (http), "http-6a");
393                         Assert.IsTrue (http.IsBaseOf (u), "http-6b");
394
395                         // host case sensitive ? no
396                         u = new Uri ("http://www.Mono-Project.com/Main_Page");
397                         Assert.IsTrue (u.IsBaseOf (http), "http-7a");
398                         Assert.IsTrue (http.IsBaseOf (u), "http-7b");
399
400                         // path case sensitive ? no
401                         u = new Uri ("http://www.Mono-Project.com/MAIN_Page");
402                         Assert.IsTrue (u.IsBaseOf (http), "http-8a");
403                         Assert.IsTrue (http.IsBaseOf (u), "http-8b");
404
405                         // different scheme
406                         u = new Uri ("ftp://www.mono-project.com/Main_Page");
407                         Assert.IsFalse (u.IsBaseOf (http), "http-9a");
408                         Assert.IsFalse (http.IsBaseOf (u), "http-9b");
409
410                         // different host
411                         u = new Uri ("http://www.go-mono.com/Main_Page");
412                         Assert.IsFalse (u.IsBaseOf (http), "http-10a");
413                         Assert.IsFalse (http.IsBaseOf (u), "http-10b");
414
415                         // different port
416                         u = new Uri ("http://www.mono-project.com:8080/");
417                         Assert.IsFalse (u.IsBaseOf (http), "http-11a");
418                         Assert.IsFalse (http.IsBaseOf (u), "http-11b");
419
420                         // specify default port
421                         u = new Uri ("http://www.mono-project.com:80/");
422                         Assert.IsTrue (u.IsBaseOf (http), "http-12a");
423                         Assert.IsTrue (http.IsBaseOf (u), "http-12b");
424                 }
425
426                 [Test]
427                 public void IsBaseOf_Null ()
428                 {
429                         Uri http = new Uri ("http://www.mono-project.com/Main_Page#FAQ?Edit");
430                         try {
431                                 http.IsBaseOf (null);
432                                 Assert.Fail ();
433                         }
434                         catch (ArgumentNullException) {
435                         }
436                 }
437
438                 [Test] 
439                 public void MakeRelativeUri ()
440                 {
441                         Uri uri1 = new Uri ("http://www.contoso.com/index.htm?x=2");
442                         Uri uri2 = new Uri ("http://www.contoso.com/foo/bar/index.htm#fragment");
443                         Uri uri3 = new Uri ("http://www.contoso.com/bar/foo/index.htm?y=1");
444                         Uri uri4 = new Uri ("http://www.contoso.com/bar/foo2/index.htm?x=0");
445                         Uri uri5 = new Uri ("https://www.contoso.com/bar/foo/index.htm?y=1");
446                         Uri uri6 = new Uri ("http://www.contoso2.com/bar/foo/index.htm?x=0");
447                         Uri uri7 = new Uri ("http://www.contoso2.com/bar/foo/foobar.htm?z=0&y=5");
448                         Uri uri8 = new Uri ("http://www.xxx.com/bar/foo/foobar.htm?z=0&y=5" + (char) 0xa9);
449                         Uri uri10 = new Uri ("mailto:xxx@xxx.com");
450                         Uri uri11 = new Uri ("mailto:xxx@xxx.com?subject=hola");
451                         Uri uri12 = new Uri ("mailto:xxx@mail.xxx.com?subject=hola");
452                         Uri uri13 = new Uri ("mailto:xxx@xxx.com/foo/bar");
453                         Uri uri14 = new Uri ("http://www.contoso.com/test1/");
454                         Uri uri15 = new Uri ("http://www.contoso.com/");
455                         Uri uri16 = new Uri ("http://www.contoso.com/test");
456
457                         AssertRelativeUri ("foo/bar/index.htm#fragment", uri1, uri2, "#A");
458                         AssertRelativeUri ("../../index.htm?x=2", uri2, uri1, "#B");
459                         AssertRelativeUri ("../../bar/foo/index.htm?y=1", uri2, uri3, "#C");
460                         AssertRelativeUri ("../../foo/bar/index.htm#fragment", uri3, uri2, "#D");
461                         AssertRelativeUri ("../foo2/index.htm?x=0", uri3, uri4, "#E");
462                         AssertRelativeUri ("../foo/index.htm?y=1", uri4, uri3, "#F");
463                         AssertRelativeUri ("?x=0", uri6, uri6, "#G");
464                         AssertRelativeUri ("foobar.htm?z=0&y=5", uri6, uri7, "#H");
465                         AssertRelativeUri ("?subject=hola", uri10, uri11, "#I");
466                         AssertRelativeUri ("/foo/bar", uri10, uri13, "#J");
467
468                         Uri relativeUri = uri1.MakeRelativeUri (uri8);
469                         Assert.IsTrue (relativeUri.IsAbsoluteUri, "#K1");
470                         Assert.AreEqual (uri8.ToString (), relativeUri.ToString (), "#K2");
471                         Assert.AreEqual (uri8.OriginalString, relativeUri.OriginalString, "#K3");
472
473                         relativeUri = uri10.MakeRelativeUri (uri12);
474                         Assert.IsTrue (relativeUri.IsAbsoluteUri, "#L1");
475                         Assert.AreEqual (uri12.ToString (), relativeUri.ToString (), "#L2");
476                         Assert.AreEqual (uri12.OriginalString, relativeUri.OriginalString, "#L3");
477
478                         relativeUri = uri4.MakeRelativeUri (uri6);
479                         Assert.IsTrue (relativeUri.IsAbsoluteUri, "#M1");
480                         Assert.AreEqual (uri6.ToString (), relativeUri.ToString (), "#M2");
481                         Assert.AreEqual (uri6.OriginalString, relativeUri.OriginalString, "#M3");
482
483                         relativeUri = uri4.MakeRelativeUri (uri5);
484                         Assert.IsTrue (relativeUri.IsAbsoluteUri, "#N1");
485                         Assert.AreEqual (uri5.ToString (), relativeUri.ToString (), "#N2");
486                         Assert.AreEqual (uri5.OriginalString, relativeUri.OriginalString, "#N3");
487
488                         AssertRelativeUri ("../", uri14, uri15, "#O");
489                         AssertRelativeUri ("./", uri16, uri15, "#P");
490
491                         Uri a1 = new Uri ("http://something/something2/test/");
492                         Uri a2 = new Uri ("http://something/something2/");
493                         Uri a3 = new Uri ("http://something/something2/test");
494                         Uri a4 = new Uri ("http://something/something2");
495
496                         AssertRelativeUri ("../", a1, a2, "Q1");
497                         AssertRelativeUri ("../../something2", a1, a4, "Q2");
498                         AssertRelativeUri ("./", a3, a2, "Q3");
499                         AssertRelativeUri ("../something2", a3, a4, "Q4");
500
501                         Uri b1 = new Uri ("http://something/test/");
502                         Uri b2 = new Uri ("http://something/");
503                         Uri b3 = new Uri ("http://something/test");
504                         Uri b4 = new Uri ("http://something");
505                         
506                         AssertRelativeUri ("../", b1, b2, "R1");
507                         AssertRelativeUri ("../", b1, b4, "R2");
508                         AssertRelativeUri ("./", b3, b2, "R3");
509                         AssertRelativeUri ("./", b3, b4, "R4");
510
511                         Uri c1 = new Uri ("C:\\something\\something2\\test\\");
512                         Uri c2 = new Uri ("C:\\something\\something2\\");
513                         Uri c3 = new Uri ("C:\\something\\something2\\test");
514                         Uri c4 = new Uri ("C:\\something\\something2");
515                         
516                         AssertRelativeUri ("../", c1, c2, "S1");
517                         AssertRelativeUri ("../../something2", c1, c4, "S2");
518                         AssertRelativeUri ("./", c3, c2, "S3");
519                         AssertRelativeUri ("../something2", c3, c4, "S4");
520
521                         Uri d1 = new Uri ("C:\\something\\test\\");
522                         Uri d2 = new Uri ("C:\\something\\");
523                         Uri d3 = new Uri ("C:\\something\\test");
524                         Uri d4 = new Uri ("C:\\something");
525                         
526                         AssertRelativeUri ("../", d1, d2, "T1");
527                         AssertRelativeUri ("../../something", d1, d4, "T2");
528                         AssertRelativeUri ("./", d3, d2, "T3");
529                         AssertRelativeUri ("../something", d3, d4, "T4");
530
531                         Uri e1 = new Uri ("C:\\something\\");
532                         Uri e2 = new Uri ("C:\\");
533                         Uri e3 = new Uri ("C:\\something");
534                         
535                         AssertRelativeUri ("../", e1, e2, "U1");
536                         AssertRelativeUri ("./", e3, e2, "U2");
537                         AssertRelativeUri ("", e1, e1, "U3");
538                         AssertRelativeUri ("", e3, e3, "U4");
539                         AssertRelativeUri ("../something", e1, e3, "U5");
540                         AssertRelativeUri ("something/", e3, e1, "U6");
541                         AssertRelativeUri ("something", e2, e3, "U7");
542                 }
543
544                 [Test]
545                 public void MakeRelativeUri_Uri_Null ()
546                 {
547                         Uri uri = new Uri ("http://test.com");
548                         try {
549                                 uri.MakeRelativeUri ((Uri) null);
550                                 Assert.Fail ("#1");
551                         }
552 #if NET_4_0
553                         catch (ArgumentNullException ex) {
554                                 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
555                                 Assert.IsNull (ex.InnerException, "#3");
556                                 Assert.IsNotNull (ex.Message, "#4");
557                                 Assert.IsNotNull (ex.ParamName, "#5");
558                                 Assert.AreEqual ("uri", ex.ParamName, "#6");
559                         }
560 #else
561                         catch (NullReferenceException) {
562                                 // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=299942
563                         }
564 #endif
565                 }
566
567                 [Test] // LAMESPEC: see bug #321113
568                 public void OriginalStringRelative ()
569                 {
570                         Uri k1 = new Uri ("http://www.mono-project.com");
571                         Uri k2 = new Uri (k1, "docs");
572                         Assert.AreEqual ("http://www.mono-project.com/docs", k2.OriginalString, "#1");
573
574                         Uri a = new Uri ("http://www.mono-project.com:808/foo");
575                         Uri b = new Uri (a, "../docs?queryyy#% %20%23%25bar");
576                         Assert.AreEqual ("http://www.mono-project.com:808/docs?queryyy#% %20%23%25bar", b.OriginalString, "#2");
577
578                         Uri c = new Uri ("http://www.mono-project.com:808/foo");
579                         Uri d = new Uri (a, "../docs?queryyy#%20%23%25bar");
580                         Assert.AreEqual ("http://www.mono-project.com:808/docs?queryyy#%20%23%25bar", d.OriginalString, "#3");
581
582                         Uri e = new Uri ("http://www.mono-project.com:909");
583                         Uri f = new Uri (e, "http://www.mono-project.com:606/docs");
584                         Assert.AreEqual ("http://www.mono-project.com:606/docs", f.OriginalString, "#4");
585
586                         Uri g = new Uri ("http://www.mono-project.com:303/foo");
587                         Uri h = new Uri (g, "?query");
588                         // it doesn't work. MS.NET also returns incorrect URI: ..303/?query
589                         // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=412604
590                         //Assert.AreEqual ("http://www.mono-project.com:303/foo?query", h.OriginalString, "#5");
591                 }
592
593                 [Test]
594                 public void PathAndQuery_RelativeUri ()
595                 {
596                         Uri uri1 = new Uri ("http://www.contoso.com/index.htm?x=2");
597                         Uri uri2 = new Uri ("http://www.contoso.com/foo/bar/index.htm#fragment");
598                         Uri relativeUri = uri1.MakeRelativeUri (uri2);
599
600                         try {
601                                 string result = relativeUri.PathAndQuery;
602                                 Assert.Fail ("#1: " + result);
603                         } catch (InvalidOperationException ex) {
604                                 // This operation is not supported for a relative URI
605                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
606                                 Assert.IsNull (ex.InnerException, "#3");
607                                 Assert.IsNotNull (ex.Message, "#4");
608                         }
609                 }
610
611                 [Test]
612                 public void Query_RelativeUri ()
613                 {
614                         Uri uri1 = new Uri ("http://www.contoso.com/index.htm?x=2");
615                         Uri uri2 = new Uri ("http://www.contoso.com/foo/bar/index.htm#fragment");
616                         Uri relativeUri = uri1.MakeRelativeUri (uri2);
617
618                         try {
619                                 string result = relativeUri.Query;
620                                 Assert.Fail ("#1: " + result);
621                         } catch (InvalidOperationException ex) {
622                                 // This operation is not supported for a relative URI
623                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
624                                 Assert.IsNull (ex.InnerException, "#3");
625                                 Assert.IsNotNull (ex.Message, "#4");
626                         }
627                 }
628
629                 [Test]
630                 public void Scheme_RelativeUri ()
631                 {
632                         Uri uri1 = new Uri ("http://www.contoso.com/index.htm?x=2");
633                         Uri uri2 = new Uri ("http://www.contoso.com/foo/bar/index.htm#fragment");
634                         Uri relativeUri = uri1.MakeRelativeUri (uri2);
635
636                         try {
637                                 string result = relativeUri.Scheme;
638                                 Assert.Fail ("#1: " + result);
639                         } catch (InvalidOperationException ex) {
640                                 // This operation is not supported for a relative URI
641                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
642                                 Assert.IsNull (ex.InnerException, "#3");
643                                 Assert.IsNotNull (ex.Message, "#4");
644                         }
645                 }
646
647                 [Test]
648                 public void UnescapeDataString ()
649                 {
650                         Assert.AreEqual ("/new folder/", Uri.UnescapeDataString ("/new%20folder/"));
651                         Assert.AreEqual ("/new folder/", Uri.UnescapeDataString ("/new%20%66older/"));
652                         Assert.AreEqual ("/new+folder/", Uri.UnescapeDataString ("/new+folder/"));
653                 }
654
655                 void AssertRelativeUri (string expected, Uri uri1, Uri uri2, string msg)
656                 {
657                         Uri relativeUri;
658                         relativeUri = uri1.MakeRelativeUri (uri2);
659                         
660                         Assert.IsFalse (relativeUri.IsAbsoluteUri, msg + "1");
661                         Assert.AreEqual (expected, relativeUri.ToString (), msg + "2");
662                         Assert.AreEqual (expected, relativeUri.OriginalString, msg + "3");
663                         Assert.IsFalse (relativeUri.UserEscaped, msg + "4");
664                 }
665
666                 [Test]
667                 public void DontCheckHostWithCustomParsers ()
668                 {
669                         UriParser.Register (new TolerantUriParser (), "assembly", 0);
670                         try {
671                                 new Uri ("assembly://Spring.Core, Version=1.2.0.20001, Culture=neutral, "
672                                         + "PublicKeyToken=null/Spring.Objects.Factory.Xml/spring-objects-1.1.xsd");
673                         } catch (UriFormatException) {
674                                 Assert.Fail ("Spring Uri is expected to work.");
675                         }
676                 }
677
678                 [Test]
679                 public void ParseShortNameAsRelativeOrAbsolute ()
680                 {
681                         new Uri ("x", UriKind.RelativeOrAbsolute);
682                 }
683
684                 private class TolerantUriParser : GenericUriParser
685                 {
686                         private const GenericUriParserOptions DefaultOptions
687                                 = GenericUriParserOptions.Default
688                                 | GenericUriParserOptions.GenericAuthority
689                                 | GenericUriParserOptions.AllowEmptyAuthority;
690                         
691                         public TolerantUriParser()
692                                                         : base(DefaultOptions)
693                         {
694                         }
695                 }
696
697                 [Test]
698                 public void DomainLabelLength ()
699                 {
700                         UriHostNameType type = Uri.CheckHostName ("3.141592653589793238462643383279502884197169399375105820974944592.com");
701                         Assert.AreEqual (UriHostNameType.Dns, type, "DomainLabelLength#1");
702                         type = Uri.CheckHostName ("3141592653589793238462643383279502884197169399375105820974944592.com");
703                         Assert.AreEqual (UriHostNameType.Unknown, type, "DomainLabelLength#2");
704                         type = Uri.CheckHostName ("3.1415926535897932384626433832795028841971693993751058209749445923.com");
705                         Assert.AreEqual (UriHostNameType.Unknown, type, "DomainLabelLength#2");
706                         type = Uri.CheckHostName ("3.141592653589793238462643383279502884197169399375105820974944592._om");
707                         Assert.AreEqual (UriHostNameType.Unknown, type, "DomainLabelLength#3");
708                 }
709         }
710 }
711