Merge pull request #3028 from lateralusX/jlorenss/threadpool_warning
[mono.git] / mcs / class / System / Test / System / UriTest.cs
1 //
2 // UriTest.cs - NUnit Test Cases for System.Uri
3 //
4 // Authors:
5 //   Lawrence Pit (loz@cable.a2000.nl)
6 //   Martin Willemoes Hansen (mwh@sysrq.dk)
7 //   Ben Maurer (bmaurer@users.sourceforge.net)
8 //
9 // (C) 2003 Martin Willemoes Hansen
10 // (C) 2003 Ben Maurer
11 //
12
13 using System.Reflection;
14 using NUnit.Framework;
15 using System;
16 using System.IO;
17 using System.Text;
18
19 namespace MonoTests.System
20 {
21         [TestFixture]
22         public class UriTest
23         {
24                 bool isWin32;
25
26                 [TestFixtureSetUp]
27                 public void GetReady ()
28                 {
29                         isWin32 = (Path.DirectorySeparatorChar == '\\');
30                 }
31
32                 [Test]
33                 public void Constructors ()
34                 {
35                         Uri uri = null;
36
37                         /*
38                         uri = new Uri ("http://www.ximian.com/foo" + ((char) 0xa9) + "/bar/index.cgi?a=1&b=" + ((char) 0xa9) + "left#fragm?ent2");
39                         Print (uri);
40
41                         uri = new Uri ("http://www.ximian.com/foo/xxx\"()-._;<=>@{|}~-,.`_^]\\[xx/" + ((char) 0xa9) + "/bar/index.cgi#fra+\">=@[gg]~gment2");
42                         Print (uri);
43
44                         uri = new Uri("http://11.22.33.588:9090");
45                         Print (uri);
46
47                         uri = new Uri("http://[11:22:33::88]:9090");
48                         Print (uri);
49
50                         uri = new Uri("http://[::127.11.22.33]:8080");
51                         Print (uri);
52
53                         uri = new Uri("http://[abcde::127.11.22.33]:8080");
54                         Print (uri);
55                         */
56
57                         /*
58                         uri = new Uri ("http://www.contoso.com:1234/foo/bar/");
59                         Print (uri);
60
61                         uri = new Uri ("http://www.contoso.com:1234/foo/bar");
62                         Print (uri);
63
64                         uri = new Uri ("http://www.contoso.com:1234/");
65                         Print (uri);
66
67                         uri = new Uri ("http://www.contoso.com:1234");
68                         Print (uri);
69                         */
70
71                         uri = new Uri("  \r  \n http://test.com\r\n \r\r  ");
72                         Assert.AreEqual ("http://test.com/", uri.ToString(), "#k0");
73                         Assert.AreEqual ("http", uri.GetComponents (UriComponents.Scheme, UriFormat.UriEscaped), "#k0-gc");
74
75                         uri = new Uri ("http://contoso.com?subject=uri");
76                         Assert.AreEqual ("/", uri.AbsolutePath, "#k1");
77                         Assert.AreEqual ("http://contoso.com/?subject=uri", uri.AbsoluteUri, "#k2");
78                         Assert.AreEqual ("contoso.com", uri.Authority, "#k3");
79                         Assert.AreEqual ("", uri.Fragment, "#k4");
80                         Assert.AreEqual ("contoso.com", uri.Host, "#k5");
81                         Assert.AreEqual (UriHostNameType.Dns, uri.HostNameType, "#k6");
82                         Assert.AreEqual (true, uri.IsDefaultPort, "#k7");
83                         Assert.AreEqual (false, uri.IsFile, "#k8");
84                         Assert.AreEqual (false, uri.IsLoopback, "#k9");
85                         Assert.AreEqual (false, uri.IsUnc, "#k10");
86                         Assert.AreEqual ("/", uri.LocalPath, "#k11");
87                         Assert.AreEqual ("/?subject=uri", uri.PathAndQuery, "#k12");
88                         Assert.AreEqual (80, uri.Port, "#k13");
89                         Assert.AreEqual ("?subject=uri", uri.Query, "#k14");
90                         Assert.AreEqual ("http", uri.Scheme, "#k15");
91                         Assert.AreEqual (false, uri.UserEscaped, "#k16");
92                         Assert.AreEqual ("", uri.UserInfo, "#k17");
93
94                         uri = new Uri ("mailto:user:pwd@contoso.com?subject=uri");
95                         Assert.AreEqual ("", uri.AbsolutePath, "#m1");
96                         Assert.AreEqual ("mailto:user:pwd@contoso.com?subject=uri", uri.AbsoluteUri, "#m2");
97                         Assert.AreEqual ("contoso.com", uri.Authority, "#m3");
98                         Assert.AreEqual ("", uri.Fragment, "#m4");
99                         Assert.AreEqual ("contoso.com", uri.Host, "#m5");
100                         Assert.AreEqual (UriHostNameType.Dns, uri.HostNameType, "#m6");
101                         Assert.AreEqual (true, uri.IsDefaultPort, "#m7");
102                         Assert.AreEqual (false, uri.IsFile, "#m8");
103                         Assert.AreEqual (false, uri.IsLoopback, "#m9");
104                         Assert.AreEqual (false, uri.IsUnc, "#m10");
105                         Assert.AreEqual ("", uri.LocalPath, "#m11");
106                         Assert.AreEqual ("?subject=uri", uri.PathAndQuery, "#m12");
107                         Assert.AreEqual (25, uri.Port, "#m13");
108                         Assert.AreEqual ("?subject=uri", uri.Query, "#m14");
109                         Assert.AreEqual ("mailto", uri.Scheme, "#m15");
110                         Assert.AreEqual (false, uri.UserEscaped, "#m16");
111                         Assert.AreEqual ("user:pwd", uri.UserInfo, "#m17");
112
113                         uri = new Uri("myscheme://127.0.0.1:5");
114                         Assert.AreEqual ("myscheme://127.0.0.1:5/", uri.ToString(), "#c1");
115
116                         uri = new Uri (@"\\myserver\mydir\mysubdir\myfile.ext");
117                         Assert.AreEqual ("/mydir/mysubdir/myfile.ext", uri.AbsolutePath, "#n1");
118                         Assert.AreEqual ("file://myserver/mydir/mysubdir/myfile.ext", uri.AbsoluteUri, "#n2");
119                         Assert.AreEqual ("myserver", uri.Authority, "#n3");
120                         Assert.AreEqual ("", uri.Fragment, "#n4");
121                         Assert.AreEqual ("myserver", uri.Host, "#n5");
122                         Assert.AreEqual (UriHostNameType.Dns, uri.HostNameType, "#n6");
123                         Assert.AreEqual (true, uri.IsDefaultPort, "#n7");
124                         Assert.AreEqual (true, uri.IsFile, "#n8");
125                         Assert.AreEqual (false, uri.IsLoopback, "#n9");
126                         Assert.AreEqual (true, uri.IsUnc, "#n10");
127
128                         if (isWin32)
129                                 Assert.AreEqual (@"\\myserver\mydir\mysubdir\myfile.ext", uri.LocalPath, "#n11");
130                         else
131                                 // myserver never could be the part of Unix path.
132                                 Assert.AreEqual ("/mydir/mysubdir/myfile.ext", uri.LocalPath, "#n11");
133
134                         Assert.AreEqual ("/mydir/mysubdir/myfile.ext", uri.PathAndQuery, "#n12");
135                         Assert.AreEqual (-1, uri.Port, "#n13");
136                         Assert.AreEqual ("", uri.Query, "#n14");
137                         Assert.AreEqual ("file", uri.Scheme, "#n15");
138                         Assert.AreEqual (false, uri.UserEscaped, "#n16");
139                         Assert.AreEqual ("", uri.UserInfo, "#n17");
140
141                         uri = new Uri (new Uri("http://www.contoso.com"), "Hello World.htm", true);
142                         Assert.AreEqual ("http://www.contoso.com/Hello World.htm", uri.AbsoluteUri, "#rel1a");
143                         Assert.AreEqual (true, uri.UserEscaped, "#rel1b");
144                         uri = new Uri (new Uri("http://www.contoso.com"), "Hello World.htm", false);
145                         Assert.AreEqual ("http://www.contoso.com/Hello%20World.htm", uri.AbsoluteUri, "#rel2a");
146                         Assert.AreEqual (false, uri.UserEscaped, "#rel2b");
147                         uri = new Uri (new Uri("http://www.contoso.com"), "http://www.xxx.com/Hello World.htm", false);
148                         Assert.AreEqual ("http://www.xxx.com/Hello%20World.htm", uri.AbsoluteUri, "#rel3");
149
150                         uri = new Uri (new Uri("http://www.contoso.com"), "foo/bar/Hello World.htm?x=0:8", false);
151                         Assert.AreEqual ("http://www.contoso.com/foo/bar/Hello%20World.htm?x=0:8", uri.AbsoluteUri, "#rel5");
152                         uri = new Uri (new Uri("http://www.contoso.com/xxx/yyy/index.htm"), "foo/bar/Hello World.htm?x=0:8", false);
153                         Assert.AreEqual ("http://www.contoso.com/xxx/yyy/foo/bar/Hello%20World.htm?x=0:8", uri.AbsoluteUri, "#rel6");
154                         uri = new Uri (new Uri("http://www.contoso.com/xxx/yyy/index.htm"), "/foo/bar/Hello World.htm?x=0:8", false);
155                         Assert.AreEqual ("http://www.contoso.com/foo/bar/Hello%20World.htm?x=0:8", uri.AbsoluteUri, "#rel7");
156                         uri = new Uri (new Uri("http://www.contoso.com/xxx/yyy/index.htm"), "../foo/bar/Hello World.htm?x=0:8", false);
157                         Assert.AreEqual ("http://www.contoso.com/xxx/foo/bar/Hello%20World.htm?x=0:8", uri.AbsoluteUri, "#rel8");
158                         uri = new Uri (new Uri("http://www.contoso.com/xxx/yyy/index.htm"), "../../../foo/bar/Hello World.htm?x=0:8", false);
159                         Assert.AreEqual ("http://www.contoso.com/foo/bar/Hello%20World.htm?x=0:8", uri.AbsoluteUri, "#rel9");
160                         Assert.AreEqual ("/foo/bar/Hello%20World.htm", uri.AbsolutePath, "#rel9-path");
161
162                         uri = new Uri (new Uri("http://www.contoso.com/xxx/yyy/index.htm"), "./foo/bar/Hello World.htm?x=0:8", false);
163                         Assert.AreEqual ("http://www.contoso.com/xxx/yyy/foo/bar/Hello%20World.htm?x=0:8", uri.AbsoluteUri, "#rel10");
164
165                         uri = new Uri (new Uri("http://www.contoso.com/foo/bar/index.html?x=0"), String.Empty, false);
166                         Assert.AreEqual ("http://www.contoso.com/foo/bar/index.html?x=0", uri.ToString (), "#22");
167
168                         uri = new Uri (new Uri("http://www.xxx.com"), "?x=0");
169                         Assert.AreEqual ("http://www.xxx.com/?x=0", uri.ToString(), "#rel30");
170                         uri = new Uri (new Uri("http://www.xxx.com/index.htm"), "#here");
171                         Assert.AreEqual ("http://www.xxx.com/index.htm#here", uri.ToString(), "#rel32");
172
173                         uri = new Uri ("relative", UriKind.Relative);
174                         uri = new Uri ("relative/abc", UriKind.Relative);
175                         uri = new Uri ("relative", UriKind.RelativeOrAbsolute);
176
177                         Assert.IsTrue (!uri.IsAbsoluteUri, "#rel33");
178                         Assert.AreEqual (uri.OriginalString, "relative", "#rel34");
179                         Assert.IsTrue (!uri.UserEscaped, "#rel35");
180                 }
181
182                 [Test]
183                 public void Constructor_DualHostPort ()
184                 {
185                         string relative = "foo:8080/bar/Hello World.htm";
186                         Uri uri = new Uri (new Uri("http://www.contoso.com"), relative, false);
187                         Assert.AreEqual ("8080/bar/Hello%20World.htm", uri.AbsolutePath, "AbsolutePath");
188                         Assert.AreEqual ("foo:8080/bar/Hello%20World.htm", uri.AbsoluteUri, "AbsoluteUri");
189                         Assert.AreEqual (String.Empty, uri.Authority, "Authority");
190                         Assert.AreEqual (String.Empty, uri.Fragment, "Fragment");
191                         Assert.AreEqual (String.Empty, uri.Host, "Host");
192                         Assert.AreEqual ("8080/bar/Hello%20World.htm", uri.PathAndQuery, "PathAndQuery");
193                         Assert.AreEqual (-1, uri.Port, "Port");
194                         Assert.AreEqual (String.Empty, uri.Query, "Query");
195                         Assert.AreEqual ("foo", uri.Scheme, "Scheme");
196                         Assert.AreEqual (String.Empty, uri.UserInfo, "Query");
197
198                         Assert.AreEqual ("8080/", uri.Segments[0], "Segments[0]");
199                         Assert.AreEqual ("bar/", uri.Segments[1], "Segments[1]");
200                         Assert.AreEqual ("Hello%20World.htm", uri.Segments[2], "Segments[2]");
201
202                         Assert.IsTrue (uri.IsDefaultPort, "IsDefaultPort");
203                         Assert.IsTrue (!uri.IsFile, "IsFile");
204                         Assert.IsTrue (!uri.IsLoopback, "IsLoopback");
205                         Assert.IsTrue (!uri.IsUnc, "IsUnc");
206                         Assert.IsTrue (!uri.UserEscaped, "UserEscaped");
207
208                         Assert.AreEqual (UriHostNameType.Unknown, uri.HostNameType, "HostNameType");
209                         Assert.IsTrue (uri.IsAbsoluteUri, "IsAbsoluteUri");
210                         Assert.AreEqual (relative, uri.OriginalString, "OriginalString");
211                 }
212
213                 [Test]
214                 [ExpectedException (typeof (ArgumentNullException))]
215                 public void Constructor_NullStringBool ()
216                 {
217                         new Uri (null, "http://www.contoso.com/index.htm", false);
218                 }
219
220                 [Test]
221                 public void Constructor_UriNullBool ()
222                 {
223                         new Uri (new Uri ("http://www.contoso.com"), null, false);
224                 }
225
226                 // regression for bug #47573
227                 [Test]
228                 public void RelativeCtor ()
229                 {
230                         Uri b = new Uri ("http://a/b/c/d;p?q");
231                         Assert.AreEqual ("http://a/g", new Uri (b, "/g").ToString (), "#1");
232                         Assert.AreEqual ("http://g/", new Uri (b, "//g").ToString (), "#2");
233                         Assert.IsTrue (new Uri (b, "#s").ToString ().EndsWith ("#s"), "#4");
234
235                         Uri u = new Uri (b, "/g?q=r");
236                         Assert.AreEqual ("http://a/g?q=r", u.ToString (), "#5");
237                         Assert.AreEqual ("?q=r", u.Query, "#6");
238
239                         u = new Uri (b, "/g?q=r;. a");
240                         Assert.AreEqual ("http://a/g?q=r;. a", u.ToString (), "#5");
241                         Assert.AreEqual ("?q=r;.%20a", u.Query, "#6");
242                 }
243
244
245                 [Test]
246                 [ExpectedException (typeof (UriFormatException))]
247                 public void RelativeCtor_11_Crasher ()
248                 {
249                         Uri b = new Uri ("http://a/b/c/d;p?q");
250                         // this causes crash under MS.NET 1.1
251                         Assert.AreEqual ("g:h", new Uri (b, "g:h").ToString (), "g:h");
252                 }
253
254                 [Test]
255                 [ExpectedException (typeof (UriFormatException))]
256                 public void Bad_IPv6 ()
257                 {
258                         new Uri ("http://0:0:0:0::127.1.2.3]/");
259                 }
260
261                 [Test]
262                 public void LeadingSlashes_ShouldFailOn1x ()
263                 {
264                         // doesn't (but should) fail under 1.x
265                         Assert.AreEqual ("file:///", new Uri ("file:///").ToString (), "#1");
266                         Assert.AreEqual ("file:///", new Uri ("file://").ToString (), "#2");
267                 }
268
269                 [Test]
270                 public void LeadingSlashes_BadResultsOn1x ()
271                 {
272                         // strange behaviours of 1.x - it's probably not worth to fix it
273                         // on Mono as 2.0 has been fixed
274                         Uri u = new Uri ("file:///foo/bar");
275                         Assert.AreEqual (String.Empty, u.Host, "#3a");
276                         Assert.AreEqual (UriHostNameType.Basic, u.HostNameType, "#3b");
277                         Assert.AreEqual ("file:///foo/bar", u.ToString (), "#3c");
278                         Assert.AreEqual (false, u.IsUnc, "#3d");
279
280                         u = new Uri ("mailto:/foo");
281                         Assert.AreEqual (String.Empty, u.Host, "#13a");
282                         Assert.AreEqual (UriHostNameType.Basic, u.HostNameType, "#13b");
283                         Assert.AreEqual ("mailto:/foo", u.ToString (), "#13c");
284
285                         u = new Uri ("mailto://foo");
286                         Assert.AreEqual (String.Empty, u.Host, "#14a");
287                         Assert.AreEqual (UriHostNameType.Basic, u.HostNameType, "#14b");
288                         Assert.AreEqual ("mailto://foo", u.ToString (), "#14c");
289
290                         u = new Uri ("news:/");
291                         Assert.AreEqual (String.Empty, u.Host, "#18a");
292                         Assert.AreEqual (UriHostNameType.Unknown, u.HostNameType, "#18b");
293                         Assert.AreEqual ("news:/", u.ToString (), "#18c");
294                         Assert.AreEqual ("/", u.AbsolutePath, "#18d");
295                         Assert.AreEqual ("news:/", u.AbsoluteUri, "#18e");
296
297                         u = new Uri ("news:/foo");
298                         Assert.AreEqual (String.Empty, u.Host, "#19a");
299                         Assert.AreEqual (UriHostNameType.Unknown, u.HostNameType, "#19b");
300                         Assert.AreEqual ("news:/foo", u.ToString (), "#19c");
301                         Assert.AreEqual ("/foo", u.AbsolutePath, "#19d");
302                         Assert.AreEqual ("news:/foo", u.AbsoluteUri, "#19e");
303
304                         u = new Uri ("news://foo");
305                         Assert.AreEqual (String.Empty, u.Host, "#20a");
306                         Assert.AreEqual (UriHostNameType.Unknown, u.HostNameType, "#20b");
307                         Assert.AreEqual ("news://foo", u.ToString (), "#20c");
308                         Assert.AreEqual ("//foo", u.AbsolutePath, "#20d");
309                         Assert.AreEqual ("news://foo", u.AbsoluteUri, "#20e");
310
311                         u = new Uri ("news://foo/bar");
312                         Assert.AreEqual (String.Empty, u.Host, "#22a");
313                         Assert.AreEqual (UriHostNameType.Unknown, u.HostNameType, "#22b");
314                         Assert.AreEqual ("news://foo/bar", u.ToString (), "#22c");
315                         Assert.AreEqual ("//foo/bar", u.AbsolutePath, "#22d");
316                         Assert.AreEqual ("news://foo/bar", u.AbsoluteUri, "#22e");
317                 }
318
319                 [Test]
320                 public void LeadingSlashes_FailOn1x ()
321                 {
322                         // 1.x throws an UriFormatException because it can't decode the host name
323                         Uri u = new Uri ("mailto:");
324                         Assert.AreEqual (String.Empty, u.Host, "#10a");
325                         Assert.AreEqual (UriHostNameType.Basic, u.HostNameType, "#10b");
326                         Assert.AreEqual ("mailto:", u.ToString (), "#10c");
327
328                         // 1.x throws an UriFormatException because it can't decode the host name
329                         u = new Uri ("mailto:/");
330                         Assert.AreEqual (String.Empty, u.Host, "#12a");
331                         Assert.AreEqual (UriHostNameType.Basic, u.HostNameType, "#12b");
332                         Assert.AreEqual ("mailto:/", u.ToString (), "#12c");
333
334                         // 1.x throws an UriFormatException because it cannot detect the format
335                         u = new Uri ("mailto:///foo");
336                         Assert.AreEqual (String.Empty, u.Host, "#15a");
337                         Assert.AreEqual (UriHostNameType.Basic, u.HostNameType, "#15b");
338                         Assert.AreEqual ("mailto:///foo", u.ToString (), "#15c");
339
340                         // 1.x throws an UriFormatException because it cannot detect the format
341                         u = new Uri ("news:///foo");
342                         Assert.AreEqual (String.Empty, u.Host, "#21a");
343                         Assert.AreEqual (UriHostNameType.Unknown, u.HostNameType, "#21b");
344                         Assert.AreEqual ("news:///foo", u.ToString (), "#21c");
345                         Assert.AreEqual ("///foo", u.AbsolutePath, "#21d");
346                         Assert.AreEqual ("news:///foo", u.AbsoluteUri, "#21e");
347                 }
348
349                 [Test]
350                 // some tests from bug 75144
351                 public void LeadingSlashes ()
352                 {
353                         Uri u = new Uri ("file://foo/bar");
354                         Assert.AreEqual ("foo", u.Host, "#5a");
355                         Assert.AreEqual (UriHostNameType.Dns, u.HostNameType, "#5b");
356                         Assert.AreEqual ("file://foo/bar", u.ToString (), "#5c");
357                         Assert.AreEqual (isWin32, u.IsUnc, "#5d");
358
359                         u = new Uri ("file:////foo/bar");
360                         Assert.AreEqual ("foo", u.Host, "#7a");
361                         Assert.AreEqual (UriHostNameType.Dns, u.HostNameType, "#7b");
362                         Assert.AreEqual ("file://foo/bar", u.ToString (), "#7c");
363                         Assert.AreEqual (isWin32, u.IsUnc, "#7d");
364
365                         Assert.AreEqual ("file://foo/bar", new Uri ("file://///foo/bar").ToString(), "#9");
366
367                         u = new Uri ("mailto:foo");
368                         Assert.AreEqual ("foo", u.Host, "#11a");
369                         Assert.AreEqual (UriHostNameType.Dns, u.HostNameType, "#11b");
370                         Assert.AreEqual ("mailto:foo", u.ToString (), "#11c");
371
372                         u = new Uri ("news:");
373                         Assert.AreEqual (String.Empty, u.Host, "#16a");
374                         Assert.AreEqual (UriHostNameType.Unknown, u.HostNameType, "#16b");
375                         Assert.AreEqual ("news:", u.ToString (), "#16c");
376
377                         u = new Uri ("news:foo");
378                         Assert.AreEqual (String.Empty, u.Host, "#17a");
379                         Assert.AreEqual (UriHostNameType.Unknown, u.HostNameType, "#17b");
380                         Assert.AreEqual ("news:foo", u.ToString (), "#17c");
381                         Assert.AreEqual ("foo", u.AbsolutePath, "#17d");
382                         Assert.AreEqual ("news:foo", u.AbsoluteUri, "#17e");
383                 }
384
385                 [Test]
386                 [ExpectedException (typeof (UriFormatException))]
387                 public void HttpHostname1 ()
388                 {
389                         new Uri ("http:");
390                 }
391
392                 [Test]
393                 [ExpectedException (typeof (UriFormatException))]
394                 public void HttpHostname2 ()
395                 {
396                         new Uri ("http:a");
397                 }
398
399                 [Test]
400                 [ExpectedException (typeof (UriFormatException))]
401                 public void HttpHostname3 ()
402                 {
403                         new Uri ("http:/");
404                 }
405
406                 [Test]
407                 [ExpectedException (typeof (UriFormatException))]
408                 public void HttpHostname4 ()
409                 {
410                         new Uri ("http:/foo");
411                 }
412
413                 [Test]
414                 [ExpectedException (typeof (UriFormatException))]
415                 public void HttpHostname5 ()
416                 {
417                         new Uri ("http://");
418                 }
419
420                 [Test]
421                 [ExpectedException (typeof (UriFormatException))]
422                 public void HttpHostname6 ()
423                 {
424                         new Uri ("http:///");
425                 }
426
427                 [Test]
428                 [ExpectedException (typeof (UriFormatException))]
429                 public void HttpHostname7 ()
430                 {
431                         new Uri ("http:///foo");
432                 }
433
434                 [Test]
435                 [ExpectedException (typeof (UriFormatException))]
436                 public void InvalidFile1 ()
437                 {
438                         new Uri ("file:");
439                 }
440
441                 [Test]
442                 [ExpectedException (typeof (UriFormatException))]
443                 public void InvalidFile2 ()
444                 {
445                         new Uri ("file:/");
446                 }
447
448                 [Test]
449                 [ExpectedException (typeof (UriFormatException))]
450                 public void InvalidFile3 ()
451                 {
452                         new Uri ("file:/foo");
453                 }
454
455                 [Test]
456                 [ExpectedException (typeof (UriFormatException))]
457                 public void InvalidScheme ()
458                 {
459                         new Uri ("_:/");
460                 }
461
462                 [Test]
463                 public void ConstructorsRejectRelativePath ()
464                 {
465                         string [] reluris = new string [] {
466                                 "readme.txt",
467                                 "thisdir/childdir/file",
468                                 "./testfile"
469                         };
470                         string [] winRelUris = new string [] {
471                                 "c:readme.txt"
472                         };
473
474                         for (int i = 0; i < reluris.Length; i++) {
475                                 try {
476                                         new Uri (reluris [i]);
477                                         Assert.Fail ("Should be failed: " + reluris [i]);
478                                 } catch (UriFormatException) {
479                                 }
480                         }
481
482                         if (isWin32) {
483                                 for (int i = 0; i < winRelUris.Length; i++) {
484                                         try {
485                                                 new Uri (winRelUris [i]);
486                                                 Assert.Fail ("Should be failed: " + winRelUris [i]);
487                                         } catch (UriFormatException) {
488                                         }
489                                 }
490                         }
491                 }
492
493                 [Test]
494                 public void LocalPath ()
495                 {
496                         Uri uri = new Uri ("c:\\tmp\\hello.txt");
497                         Assert.AreEqual ("file:///c:/tmp/hello.txt", uri.ToString (), "#1a");
498                         Assert.AreEqual ("c:\\tmp\\hello.txt", uri.LocalPath, "#1b");
499                         Assert.AreEqual ("file", uri.Scheme, "#1c");
500                         Assert.AreEqual ("", uri.Host, "#1d");
501                         Assert.AreEqual ("c:/tmp/hello.txt", uri.AbsolutePath, "#1e");
502
503                         uri = new Uri ("file:////////cygwin/tmp/hello.txt");
504                         Assert.AreEqual ("file://cygwin/tmp/hello.txt", uri.ToString (), "#3a");
505                         if (isWin32)
506                                 Assert.AreEqual ("\\\\cygwin\\tmp\\hello.txt", uri.LocalPath, "#3b win32");
507                         else
508                                 Assert.AreEqual ("/tmp/hello.txt", uri.LocalPath, "#3b *nix");
509                         Assert.AreEqual ("file", uri.Scheme, "#3c");
510                         Assert.AreEqual ("cygwin", uri.Host, "#3d");
511                         Assert.AreEqual ("/tmp/hello.txt", uri.AbsolutePath, "#3e");
512
513                         uri = new Uri ("file://mymachine/cygwin/tmp/hello.txt");
514                         Assert.AreEqual ("file://mymachine/cygwin/tmp/hello.txt", uri.ToString (), "#4a");
515                         if (isWin32)
516                                 Assert.AreEqual ("\\\\mymachine\\cygwin\\tmp\\hello.txt", uri.LocalPath, "#4b win32");
517                         else
518                                 Assert.AreEqual ("/cygwin/tmp/hello.txt", uri.LocalPath, "#4b *nix");
519                         Assert.AreEqual ("file", uri.Scheme, "#4c");
520                         Assert.AreEqual ("mymachine", uri.Host, "#4d");
521                         Assert.AreEqual ("/cygwin/tmp/hello.txt", uri.AbsolutePath, "#4e");
522
523                         uri = new Uri ("file://///c:/cygwin/tmp/hello.txt");
524                         Assert.AreEqual ("file:///c:/cygwin/tmp/hello.txt", uri.ToString (), "#5a");
525                         Assert.AreEqual ("c:\\cygwin\\tmp\\hello.txt", uri.LocalPath, "#5b");
526                         Assert.AreEqual ("file", uri.Scheme, "#5c");
527                         Assert.AreEqual ("", uri.Host, "#5d");
528                         Assert.AreEqual ("c:/cygwin/tmp/hello.txt", uri.AbsolutePath, "#5e");
529                 }
530
531                 [Test]
532                 public void LocalPath_FileHost ()
533                 {
534                         // Hmm, they should be regarded just as a host name, since all URIs are base on absolute path.
535                         Uri uri = new Uri("file://one_file.txt");
536                         Assert.AreEqual ("file://one_file.txt/", uri.ToString(), "#6a");
537                         Assert.AreEqual ("/", uri.AbsolutePath, "#6e");
538                         Assert.AreEqual ("/", uri.PathAndQuery, "#6f");
539                         Assert.AreEqual ("file://one_file.txt/", uri.GetLeftPart (UriPartial.Path), "#6g");
540                         if (isWin32)
541                                 Assert.AreEqual ("\\\\one_file.txt", uri.LocalPath, "#6b");
542                         else
543                                 Assert.AreEqual ("/", uri.LocalPath, "#6b");
544                         Assert.AreEqual ("file", uri.Scheme, "#6c");
545                         Assert.AreEqual ("one_file.txt", uri.Host, "#6d");
546
547                         // same tests - but original Uri is now ending with a '/'
548
549                         uri = new Uri ("file://one_file.txt/");
550                         Assert.AreEqual ("file://one_file.txt/", uri.ToString (), "#7a");
551                         Assert.AreEqual ("/", uri.AbsolutePath, "#7e");
552                         Assert.AreEqual ("/", uri.PathAndQuery, "#7f");
553                         Assert.AreEqual ("file://one_file.txt/", uri.GetLeftPart (UriPartial.Path), "#7g");
554                         if (isWin32)
555                                 Assert.AreEqual ("\\\\one_file.txt\\", uri.LocalPath, "#7b");
556                         else
557                                 Assert.AreEqual ("/", uri.LocalPath, "#7b");
558                         Assert.AreEqual ("file", uri.Scheme, "#7c");
559                         Assert.AreEqual ("one_file.txt", uri.Host, "#7d");
560                 }
561
562                 [Test]
563                 public void LocalPath_Escape ()
564                 {
565                         // escape
566                         Uri uri = new Uri ("file:///tmp/a%20a");
567                         if (isWin32) {
568                                 Assert.IsTrue (uri.LocalPath.EndsWith ("/tmp/a a"), "#7a:" + uri.LocalPath);
569                         } else
570                                 Assert.AreEqual ("/tmp/a a", uri.LocalPath, "#7b");
571
572                         uri = new Uri ("file:///tmp/foo%25bar");
573                         if (isWin32) {
574                                 Assert.IsTrue (uri.LocalPath.EndsWith ("/tmp/foo%bar"), "#8a:" + uri.LocalPath);
575                                 Assert.IsTrue (uri.ToString ().EndsWith ("//tmp/foo%25bar"), "#8c:" + uri.ToString ());
576                         } else {
577                                 Assert.AreEqual ("/tmp/foo%bar", uri.LocalPath, "#8b");
578                                 Assert.AreEqual ("file:///tmp/foo%25bar", uri.ToString (), "#8d");
579                         }
580                         // bug #76643
581                         uri = new Uri ("file:///foo%25bar");
582                         if (isWin32) {
583                                 Assert.IsTrue (uri.LocalPath.EndsWith ("/foo%bar"), "#9a:" + uri.LocalPath);
584                                 // ditto, file://tmp/foo%25bar (bug in 1.x)
585                                 Assert.IsTrue (uri.ToString ().EndsWith ("//foo%25bar"), "#9c:" + uri.ToString ());
586                         } else {
587                                 Assert.AreEqual ("/foo%bar", uri.LocalPath, "#9b");
588                                 Assert.AreEqual ("file:///foo%25bar", uri.ToString (), "#9d");
589                         }
590                 }
591
592                 // Novell Bugzilla #320614
593                 [Test]
594                 public void QueryEscape ()
595                 {
596                         Uri u1 = new Uri("http://localhost:8080/test.aspx?ReturnUrl=%2fSearchDoc%2fSearcher.aspx");
597                         Uri u2 = new Uri("http://localhost:8080/test.aspx?ReturnUrl=%252fSearchDoc%252fSearcher.aspx");
598
599                         Assert.AreEqual ("http://localhost:8080/test.aspx?ReturnUrl=%2fSearchDoc%2fSearcher.aspx", u1.ToString (), "QE1");
600
601                         Assert.AreEqual ("http://localhost:8080/test.aspx?ReturnUrl=%252fSearchDoc%252fSearcher.aspx", u2.ToString (), "QE2");
602                 }
603
604                 [Test]
605                 public void UnixPath () {
606                         if (!isWin32)
607                                 Assert.AreEqual ("file:///cygwin/tmp/hello.txt", new Uri ("/cygwin/tmp/hello.txt").ToString (), "#6a");
608                 }
609
610                 [Test]
611                 public void Unc ()
612                 {
613                         Uri uri = new Uri ("http://www.contoso.com");
614                         Assert.IsTrue (!uri.IsUnc, "#1");
615
616                         uri = new Uri ("news:123456@contoso.com");
617                         Assert.IsTrue (!uri.IsUnc, "#2");
618
619                         uri = new Uri ("file://server/filename.ext");
620                         Assert.AreEqual (isWin32, uri.IsUnc, "#3");
621
622                         uri = new Uri (@"\\server\share\filename.ext");
623                         Assert.IsTrue (uri.IsUnc, "#6");
624
625                         uri = new Uri (@"a:\dir\filename.ext");
626                         Assert.IsTrue (!uri.IsUnc, "#8");
627                 }
628
629                 [Test]
630                 [Category("NotDotNet")]
631                 public void UncFail ()
632                 {
633                         if (!isWin32) {
634                                 Uri uri = new Uri ("/home/user/dir/filename.ext");
635                                 Assert.IsTrue (!uri.IsUnc, "#7");
636                         }
637                 }
638
639                 [Test]
640                 public void FromHex ()
641                 {
642                         Assert.AreEqual (0, Uri.FromHex ('0'), "#1");
643                         Assert.AreEqual (9, Uri.FromHex ('9'), "#2");
644                         Assert.AreEqual (10, Uri.FromHex ('a'), "#3");
645                         Assert.AreEqual (15, Uri.FromHex ('f'), "#4");
646                         Assert.AreEqual (10, Uri.FromHex ('A'), "#5");
647                         Assert.AreEqual (15, Uri.FromHex ('F'), "#6");
648                         try {
649                                 Uri.FromHex ('G');
650                                 Assert.Fail ("#7");
651                         } catch (ArgumentException) {}
652                         try {
653                                 Uri.FromHex (' ');
654                                 Assert.Fail ("#8");
655                         } catch (ArgumentException) {}
656                         try {
657                                 Uri.FromHex ('%');
658                                 Assert.Fail ("#8");
659                         } catch (ArgumentException) {}
660                 }
661
662                 class UriEx : Uri
663                 {
664                         public UriEx (string s) : base (s)
665                         {
666                         }
667
668                         public string UnescapeString (string s)
669                         {
670                                 return Unescape (s);
671                         }
672
673                         public static string UnescapeString (string uri, string target)
674                         {
675                                 return new UriEx (uri).UnescapeString (target);
676                         }
677                 }
678
679                 [Test]
680                 public void Unescape ()
681                 {
682                         Assert.AreEqual ("#", UriEx.UnescapeString ("file://localhost/c#", "%23"), "#1");
683                         Assert.AreEqual ("c#", UriEx.UnescapeString ("file://localhost/c#", "c%23"), "#2");
684                         Assert.AreEqual ("#", UriEx.UnescapeString ("http://localhost/c#", "%23"), "#1");
685                         Assert.AreEqual ("c#", UriEx.UnescapeString ("http://localhost/c#", "c%23"), "#2");
686                         Assert.AreEqual ("%A9", UriEx.UnescapeString ("file://localhost/c#", "%A9"), "#3");
687                         Assert.AreEqual ("%A9", UriEx.UnescapeString ("http://localhost/c#", "%A9"), "#3");
688                 }
689
690                 [Test]
691                 public void HexEscape ()
692                 {
693                         Assert.AreEqual ("%20", Uri.HexEscape (' '), "#1");
694                         Assert.AreEqual ("%A9", Uri.HexEscape ((char) 0xa9), "#2");
695                         Assert.AreEqual ("%41", Uri.HexEscape ('A'), "#3");
696                         try {
697                                 Uri.HexEscape ((char) 0x0369);
698                                 Assert.Fail ("#4");
699                         } catch (ArgumentOutOfRangeException) {}
700                 }
701
702         [Test]
703         public void MoreHexEscape()
704         {
705             string url = "http://guyc-2003-sp/wiki/wiki%20document%20library/בד%20יקה.docx";
706             string escapedAbsolutePath = "/wiki/wiki%20document%20library/%D7%91%D7%93%20%D7%99%D7%A7%D7%94.docx";
707             Uri u = new Uri(url);
708             Assert.AreEqual (escapedAbsolutePath, u.AbsolutePath, "Escaped non-english combo");
709         }
710
711                 [Test]
712                 public void HexUnescape ()
713                 {
714                         int i = 0;
715                         Assert.AreEqual (' ', Uri.HexUnescape ("%20", ref i), "#1");
716                         Assert.AreEqual (3, i, "#2");
717                         i = 4;
718                         Assert.AreEqual ((char) 0xa9, Uri.HexUnescape ("test%a9test", ref i), "#3");
719                         Assert.AreEqual (7, i, "#4");
720                         Assert.AreEqual ('t', Uri.HexUnescape ("test%a9test", ref i), "#5");
721                         Assert.AreEqual (8, i, "#6");
722                         i = 4;
723                         Assert.AreEqual ('%', Uri.HexUnescape ("test%a", ref i), "#5");
724                         Assert.AreEqual (5, i, "#6");
725                         Assert.AreEqual ('%', Uri.HexUnescape ("testx%xx", ref i), "#7");
726                         Assert.AreEqual (6, i, "#8");
727
728                         // Tests from bug 74872 - don't handle multi-byte characters as multi-byte
729                         i = 1;
730                         Assert.AreEqual (227, (int) Uri.HexUnescape ("a%E3%81%8B", ref i), "#9");
731                         Assert.AreEqual (4, i, "#10");
732                         i = 1;
733                         Assert.AreEqual (240, (int) Uri.HexUnescape ("a%F0%90%84%80", ref i), "#11");
734                         Assert.AreEqual (4, i, "#12");
735                 }
736
737                 [Test]
738                 public void HexUnescapeMultiByte ()
739                 {
740                         // Tests from bug 74872
741                         // Note: These won't pass exactly with MS.NET, due to differences in the
742                         // handling of backslashes/forwardslashes
743                         Uri uri;
744                         string path;
745
746                         // 3-byte character
747                         uri = new Uri ("file:///foo/a%E3%81%8Bb", true);
748                         path = uri.LocalPath;
749                         Assert.AreEqual (8, path.Length, "#1");
750                         Assert.AreEqual (0x304B, path [6], "#2");
751
752                         // 4-byte character which should be handled as a surrogate
753                         uri = new Uri ("file:///foo/a%F3%A0%84%80b", true);
754                         path = uri.LocalPath;
755                         Assert.AreEqual (9, path.Length, "#3");
756                         Assert.AreEqual (0xDB40, path [6], "#4");
757                         Assert.AreEqual (0xDD00, path [7], "#5");
758                         Assert.AreEqual (0x62, path [8], "#6");
759
760                         // 2-byte escape sequence, 2 individual characters
761                         uri = new Uri ("file:///foo/a%C2%F8b", true);
762                         path = uri.LocalPath;
763                         Assert.AreEqual ("/foo/a%C2%F8b", path, "#7");
764                 }
765
766                 [Test]
767                 public void IsHexDigit ()
768                 {
769                         Assert.IsTrue (Uri.IsHexDigit ('a'), "#1");
770                         Assert.IsTrue (Uri.IsHexDigit ('f'), "#2");
771                         Assert.IsTrue (!Uri.IsHexDigit ('g'), "#3");
772                         Assert.IsTrue (Uri.IsHexDigit ('0'), "#4");
773                         Assert.IsTrue (Uri.IsHexDigit ('9'), "#5");
774                         Assert.IsTrue (Uri.IsHexDigit ('A'), "#6");
775                         Assert.IsTrue (Uri.IsHexDigit ('F'), "#7");
776                         Assert.IsTrue (!Uri.IsHexDigit ('G'), "#8");
777                 }
778
779                 [Test]
780                 public void IsHexEncoding ()
781                 {
782                         Assert.IsTrue (Uri.IsHexEncoding ("test%a9test", 4), "#1");
783                         Assert.IsTrue (!Uri.IsHexEncoding ("test%a9test", 3), "#2");
784                         Assert.IsTrue (Uri.IsHexEncoding ("test%a9", 4), "#3");
785                         Assert.IsTrue (!Uri.IsHexEncoding ("test%a", 4), "#4");
786                 }
787
788                 [Test]
789                 public void GetLeftPart ()
790                 {
791                         Uri uri = new Uri ("http://www.contoso.com/index.htm#main");
792                         Assert.AreEqual ("http://", uri.GetLeftPart (UriPartial.Scheme), "#1");
793                         Assert.AreEqual ("http://www.contoso.com", uri.GetLeftPart (UriPartial.Authority), "#2");
794                         Assert.AreEqual ("http://www.contoso.com/index.htm", uri.GetLeftPart (UriPartial.Path), "#3");
795
796                         uri = new Uri ("mailto:user@contoso.com?subject=uri");
797                         Assert.AreEqual ("mailto:", uri.GetLeftPart (UriPartial.Scheme), "#4");
798                         Assert.AreEqual ("", uri.GetLeftPart (UriPartial.Authority), "#5");
799                         Assert.AreEqual ("mailto:user@contoso.com", uri.GetLeftPart (UriPartial.Path), "#6");
800
801                         uri = new Uri ("nntp://news.contoso.com/123456@contoso.com");
802                         Assert.AreEqual ("nntp://", uri.GetLeftPart (UriPartial.Scheme), "#7");
803                         Assert.AreEqual ("nntp://news.contoso.com", uri.GetLeftPart (UriPartial.Authority), "#8");
804                         Assert.AreEqual ("nntp://news.contoso.com/123456@contoso.com", uri.GetLeftPart (UriPartial.Path), "#9");
805
806                         uri = new Uri ("news:123456@contoso.com");
807                         Assert.AreEqual ("news:", uri.GetLeftPart (UriPartial.Scheme), "#10");
808                         Assert.AreEqual ("", uri.GetLeftPart (UriPartial.Authority), "#11");
809                         Assert.AreEqual ("news:123456@contoso.com", uri.GetLeftPart (UriPartial.Path), "#12");
810
811                         uri = new Uri ("file://server/filename.ext");
812                         Assert.AreEqual ("file://", uri.GetLeftPart (UriPartial.Scheme), "#13");
813                         Assert.AreEqual ("file://server", uri.GetLeftPart (UriPartial.Authority), "#14");
814                         Assert.AreEqual ("file://server/filename.ext", uri.GetLeftPart (UriPartial.Path), "#15");
815
816                         uri = new Uri (@"\\server\share\filename.ext");
817                         Assert.AreEqual ("file://", uri.GetLeftPart (UriPartial.Scheme), "#20");
818                         Assert.AreEqual ("file://server", uri.GetLeftPart (UriPartial.Authority), "#21");
819                         Assert.AreEqual ("file://server/share/filename.ext", uri.GetLeftPart (UriPartial.Path), "#22");
820
821                         uri = new Uri ("http://www.contoso.com:8080/index.htm#main");
822                         Assert.AreEqual ("http://", uri.GetLeftPart (UriPartial.Scheme), "#23");
823                         Assert.AreEqual ("http://www.contoso.com:8080", uri.GetLeftPart (UriPartial.Authority), "#24");
824                         Assert.AreEqual ("http://www.contoso.com:8080/index.htm", uri.GetLeftPart (UriPartial.Path), "#25");
825                 }
826
827                 [Test]
828                 public void NewsDefaultPort ()
829                 {
830                         Uri uri = new Uri("news://localhost:119/");
831                         Assert.AreEqual (uri.IsDefaultPort, true, "#1");
832                 }
833
834                 [Test]
835                 public void Fragment_Escape ()
836                 {
837                         Uri u = new Uri("http://localhost/index.asp#main#start", false);
838
839 #if NET_4_5
840                                 Assert.AreEqual (u.Fragment, "#main#start", "#1");
841 #else
842                                 Assert.AreEqual (u.Fragment, "#main%23start", "#1");
843 #endif
844
845                         u = new Uri("http://localhost/index.asp#main#start", true);
846                         Assert.AreEqual (u.Fragment, "#main#start", "#2");
847
848                         // The other code path uses a BaseUri
849
850                         Uri b = new Uri ("http://www.gnome.org");
851                         Uri n = new Uri (b, "blah#main#start");
852 #if NET_4_5
853                                 Assert.AreEqual (n.Fragment, "#main#start", "#3");
854 #else
855                                 Assert.AreEqual (n.Fragment, "#main%23start", "#3");
856 #endif
857
858                         n = new Uri (b, "blah#main#start", true);
859                         Assert.AreEqual (n.Fragment, "#main#start", "#4");
860                 }
861
862                 [Test]
863                 public void Fragment_RelativeUri ()
864                 {
865                         Uri uri1 = new Uri ("http://www.contoso.com/index.htm?x=2");
866                         Uri uri2 = new Uri ("http://www.contoso.com/foo/bar/index.htm#fragment");
867                         Uri relativeUri = uri1.MakeRelativeUri (uri2);
868
869                         try {
870                                 string fragment = relativeUri.Fragment;
871                                 Assert.Fail ("#1: " + fragment);
872                         } catch (InvalidOperationException ex) {
873                                 // This operation is not supported for a relative URI
874                                 Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
875                                 Assert.IsNull (ex.InnerException, "#3");
876                                 Assert.IsNotNull (ex.Message, "#4");
877                         }
878                 }
879
880                 [Test]
881                 [ExpectedException(typeof(UriFormatException))]
882                 public void IncompleteSchemeDelimiter ()
883                 {
884                         new Uri ("file:/filename.ext");
885                 }
886
887                 [Test]
888                 public void CheckHostName1 ()
889                 {
890                         // reported to MSDN Product Feedback Center (FDBK28671)
891                         Assert.AreEqual (UriHostNameType.IPv6, Uri.CheckHostName (":11:22:33:44:55:66:77:88"), "#36 known to fail with ms.net: this is not a valid IPv6 address.");
892                 }
893
894                 [Test]
895                 public void CheckHostName2 ()
896                 {
897                         Assert.AreEqual (UriHostNameType.Unknown, Uri.CheckHostName (null), "#1");
898                         Assert.AreEqual (UriHostNameType.Unknown, Uri.CheckHostName (""), "#2");
899                         Assert.AreEqual (UriHostNameType.Unknown, Uri.CheckHostName ("^&()~`!@"), "#3");
900                         Assert.AreEqual (UriHostNameType.Dns, Uri.CheckHostName ("x"), "#4");
901                         Assert.AreEqual (UriHostNameType.IPv4, Uri.CheckHostName ("1.2.3.4"), "#5");
902                         Assert.AreEqual (UriHostNameType.IPv4, Uri.CheckHostName ("0001.002.03.4"), "#6");
903                         Assert.AreEqual (UriHostNameType.Dns, Uri.CheckHostName ("0001.002.03.256"), "#7");
904                         Assert.AreEqual (UriHostNameType.Dns, Uri.CheckHostName ("9001.002.03.4"), "#8");
905                         Assert.AreEqual (UriHostNameType.Dns, Uri.CheckHostName ("www.contoso.com"), "#9");
906                         Assert.AreEqual (UriHostNameType.Unknown, Uri.CheckHostName (".www.contoso.com"), "#10");
907                         Assert.AreEqual (UriHostNameType.Dns, Uri.CheckHostName ("www.contoso.com."), "#11");
908                         Assert.AreEqual (UriHostNameType.Dns, Uri.CheckHostName ("www.con-toso.com"), "#12");
909                         Assert.AreEqual (UriHostNameType.Dns, Uri.CheckHostName ("www.con_toso.com"), "#13");
910                         Assert.AreEqual (UriHostNameType.Unknown, Uri.CheckHostName ("www.con,toso.com"), "#14");
911
912                         // test IPv6
913                         Assert.AreEqual (UriHostNameType.IPv6, Uri.CheckHostName ("11:22:33:44:55:66:77:88"), "#15");
914                         Assert.AreEqual (UriHostNameType.IPv6, Uri.CheckHostName ("11::33:44:55:66:77:88"), "#16");
915                         Assert.AreEqual (UriHostNameType.IPv6, Uri.CheckHostName ("::22:33:44:55:66:77:88"), "#17");
916                         Assert.AreEqual (UriHostNameType.IPv6, Uri.CheckHostName ("11:22:33:44:55:66:77::"), "#18");
917                         Assert.AreEqual (UriHostNameType.IPv6, Uri.CheckHostName ("11::88"), "#19");
918                         Assert.AreEqual (UriHostNameType.IPv6, Uri.CheckHostName ("11::77:88"), "#20");
919                         Assert.AreEqual (UriHostNameType.IPv6, Uri.CheckHostName ("11:22::88"), "#21");
920                         Assert.AreEqual (UriHostNameType.IPv6, Uri.CheckHostName ("11::"), "#22");
921                         Assert.AreEqual (UriHostNameType.IPv6, Uri.CheckHostName ("::88"), "#23");
922                         Assert.AreEqual (UriHostNameType.IPv6, Uri.CheckHostName ("::1"), "#24");
923                         Assert.AreEqual (UriHostNameType.IPv6, Uri.CheckHostName ("::"), "#25");
924                         Assert.AreEqual (UriHostNameType.IPv6, Uri.CheckHostName ("0:0:0:0:0:0:127.0.0.1"), "#26");
925                         Assert.AreEqual (UriHostNameType.IPv6, Uri.CheckHostName ("::127.0.0.1"), "#27");
926                         Assert.AreEqual (UriHostNameType.IPv6, Uri.CheckHostName ("::ffFF:169.32.14.5"), "#28");
927                         Assert.AreEqual (UriHostNameType.IPv6, Uri.CheckHostName ("2001:03A0::/35"), "#29");
928                         Assert.AreEqual (UriHostNameType.IPv6, Uri.CheckHostName ("[2001:03A0::/35]"), "#30");
929                         Assert.AreEqual (UriHostNameType.IPv6, Uri.CheckHostName ("2001::03A0:1.2.3.4"), "#33");
930
931                         Assert.AreEqual (UriHostNameType.Unknown, Uri.CheckHostName ("2001::03A0::/35"), "#31");
932                         Assert.AreEqual (UriHostNameType.Unknown, Uri.CheckHostName ("2001:03A0::/35a"), "#32");
933                         Assert.AreEqual (UriHostNameType.Unknown, Uri.CheckHostName ("::ffff:123.256.155.43"), "#34");
934                         Assert.AreEqual (UriHostNameType.Unknown, Uri.CheckHostName (":127.0.0.1"), "#35");
935                         Assert.AreEqual (UriHostNameType.Unknown, Uri.CheckHostName ("::11:22:33:44:55:66:77:88"), "#37");
936                         Assert.AreEqual (UriHostNameType.Unknown, Uri.CheckHostName ("11:22:33:44:55:66:77:88::"), "#38");
937                         Assert.AreEqual (UriHostNameType.Unknown, Uri.CheckHostName ("11:22:33:44:55:66:77:88:"), "#39");
938                         Assert.AreEqual (UriHostNameType.Unknown, Uri.CheckHostName ("::acbde"), "#40");
939                         Assert.AreEqual (UriHostNameType.Unknown, Uri.CheckHostName ("::abce:"), "#41");
940                         Assert.AreEqual (UriHostNameType.Unknown, Uri.CheckHostName ("::abcg"), "#42");
941                         Assert.AreEqual (UriHostNameType.Unknown, Uri.CheckHostName (":::"), "#43");
942                         Assert.AreEqual (UriHostNameType.Unknown, Uri.CheckHostName (":"), "#44");
943
944                         Assert.AreEqual (UriHostNameType.Unknown, Uri.CheckHostName ("*"), "#45");
945                         Assert.AreEqual (UriHostNameType.Unknown, Uri.CheckHostName ("*.go-mono.com"), "#46");
946                         Assert.AreEqual (UriHostNameType.Unknown, Uri.CheckHostName ("www*.go-mono.com"), "#47");
947                 }
948
949                 [Test]
950                 public void IsLoopback ()
951                 {
952                         Uri uri = new Uri("http://loopback:8080");
953                         Assert.AreEqual (true, uri.IsLoopback, "#1");
954                         uri = new Uri("http://localhost:8080");
955                         Assert.AreEqual (true, uri.IsLoopback, "#2");
956                         uri = new Uri("http://127.0.0.1:8080");
957                         Assert.AreEqual (true, uri.IsLoopback, "#3");
958                         uri = new Uri("http://127.0.0.001:8080");
959                         Assert.AreEqual (true, uri.IsLoopback, "#4");
960                         uri = new Uri("http://[::1]");
961                         Assert.AreEqual (true, uri.IsLoopback, "#5");
962                         uri = new Uri("http://[::1]:8080");
963                         Assert.AreEqual (true, uri.IsLoopback, "#6");
964                         uri = new Uri("http://[::0001]:8080");
965                         Assert.AreEqual (true, uri.IsLoopback, "#7");
966                         uri = new Uri("http://[0:0:0:0::1]:8080");
967                         Assert.AreEqual (true, uri.IsLoopback, "#8");
968                         uri = new Uri("http://[0:0:0:0::127.0.0.1]:8080");
969                         Assert.AreEqual (true, uri.IsLoopback, "#9");
970                         uri = new Uri("http://[0:0:0:0::127.11.22.33]:8080");
971                         Assert.AreEqual (false, uri.IsLoopback, "#10");
972                         uri = new Uri("http://[::ffff:127.11.22.33]:8080");
973                         Assert.AreEqual (false, uri.IsLoopback, "#11");
974                         uri = new Uri("http://[::ff00:7f11:2233]:8080");
975                         Assert.AreEqual (false, uri.IsLoopback, "#12");
976                         uri = new Uri("http://[1:0:0:0::1]:8080");
977                         Assert.AreEqual (false, uri.IsLoopback, "#13");
978                 }
979
980                 [Test]
981                 public void IsLoopback_File ()
982                 {
983                         Uri uri = new Uri ("file:///index.html");
984                         Assert.IsTrue (uri.IsLoopback, "file");
985                 }
986
987                 [Test]
988                 public void IsLoopback_Relative_Http ()
989                 {
990                         string relative = "http:8080/bar/Hello World.htm";
991                         Uri uri = new Uri (new Uri ("http://www.contoso.com"), relative, false);
992                         Assert.IsTrue (!uri.IsLoopback, "http");
993                 }
994
995                 [Test]
996                 public void IsLoopback_Relative_Unknown ()
997                 {
998                         string relative = "foo:8080/bar/Hello World.htm";
999                         Uri uri = new Uri (new Uri ("http://www.contoso.com"), relative, false);
1000                         Assert.IsTrue (!uri.IsLoopback, "foo");
1001                 }
1002
1003                 [Test]
1004                 public void Equals1 ()
1005                 {
1006                         Uri uri1 = new Uri ("http://www.contoso.com/index.htm#main");
1007                         Uri uri2 = new Uri ("http://www.contoso.com/index.htm#fragment");
1008                         Assert.IsTrue (uri1.Equals (uri2), "#1");
1009                         Assert.IsTrue (!uri2.Equals ("http://www.contoso.com/index.html?x=1"), "#3");
1010                         Assert.IsTrue (!uri1.Equals ("http://www.contoso.com:8080/index.htm?x=1"), "#4");
1011                 }
1012
1013                 [Test]
1014                 public void Equals2 ()
1015                 {
1016                         Uri uri1 = new Uri ("http://www.contoso.com/index.htm#main");
1017                         Uri uri2 = new Uri ("http://www.contoso.com/index.htm?x=1");
1018                         Assert.IsTrue (!uri1.Equals (uri2), "#2 known to fail with ms.net 1.x");
1019                 }
1020
1021                 [Test]
1022                 public void Equals3 ()
1023                 {
1024                         Uri uri1 = new Uri ("svn+ssh://atsushi@mono-cvs.ximian.com");
1025                         Uri uri2 = new Uri ("svn+ssh://anonymous@mono-cvs.ximian.com");
1026                         Assert.IsTrue (uri1.Equals (uri2));
1027                 }
1028
1029                 [Test]
1030                 public void Equals4 ()
1031                 {
1032                         var uri = new Uri ("http://w3.org");
1033                         Assert.IsFalse (uri.Equals ("-"));
1034                 }
1035
1036                 [Test]
1037                 public void TestEquals2 ()
1038                 {
1039                         Uri a = new Uri ("http://www.go-mono.com");
1040                         Uri b = new Uri ("http://www.go-mono.com");
1041
1042                         Assert.AreEqual (a, b, "#1");
1043
1044                         a = new Uri ("mailto:user:pwd@go-mono.com?subject=uri");
1045                         b = new Uri ("MAILTO:USER:PWD@GO-MONO.COM?SUBJECT=URI");
1046
1047                         Assert.IsTrue (a != b, "#2");
1048                         Assert.AreEqual ("mailto:user:pwd@go-mono.com?subject=uri", a.ToString (), "#2a");
1049                         Assert.AreEqual ("mailto:USER:PWD@go-mono.com?SUBJECT=URI", b.ToString (), "#2b");
1050
1051                         a = new Uri ("http://www.go-mono.com/ports/");
1052                         b = new Uri ("http://www.go-mono.com/PORTS/");
1053
1054                         Assert.IsTrue (!a.Equals (b), "#3");
1055                 }
1056
1057                 [Test]
1058                 public void CaseSensitivity ()
1059                 {
1060                         Uri mailto = new Uri ("MAILTO:USER:PWD@GO-MONO.COM?SUBJECT=URI");
1061                         Assert.AreEqual ("mailto", mailto.Scheme, "#1");
1062                         Assert.AreEqual ("go-mono.com", mailto.Host, "#2");
1063                         Assert.AreEqual ("mailto:USER:PWD@go-mono.com?SUBJECT=URI", mailto.ToString (), "#3");
1064
1065                         Uri http = new Uri ("HTTP://GO-MONO.COM/INDEX.HTML");
1066                         Assert.AreEqual ("http", http.Scheme, "#4");
1067                         Assert.AreEqual ("go-mono.com", http.Host, "#5");
1068                         Assert.AreEqual ("http://go-mono.com/INDEX.HTML", http.ToString (), "#6");
1069
1070                         // IPv6 Address
1071                         Uri ftp = new Uri ("FTP://[::ffFF:169.32.14.5]/");
1072                         Assert.AreEqual ("ftp", ftp.Scheme, "#7");
1073
1074 #if NET_4_5
1075                         Assert.AreEqual ("[::ffff:169.32.14.5]", ftp.Host, "#8");
1076                         Assert.AreEqual ("ftp://[::ffff:169.32.14.5]/", ftp.ToString (), "#9");
1077 #else
1078                         Assert.AreEqual ("[0000:0000:0000:0000:0000:FFFF:A920:0E05]", ftp.Host, "#8");
1079                         Assert.AreEqual ("ftp://[0000:0000:0000:0000:0000:FFFF:A920:0E05]/", ftp.ToString (), "#9");
1080 #endif
1081                 }
1082
1083                 [Test]
1084                 public void GetHashCodeTest ()
1085                 {
1086                         Uri uri1 = new Uri ("http://www.contoso.com/index.htm#main");
1087                         Uri uri2 = new Uri ("http://www.contoso.com/index.htm#fragment");
1088                         Assert.AreEqual (uri1.GetHashCode (), uri2.GetHashCode (), "#1");
1089                         uri2 = new Uri ("http://www.contoso.com/index.htm?x=1");
1090                         Assert.IsTrue (uri1.GetHashCode () != uri2.GetHashCode (), "#2");
1091                         uri2 = new Uri ("http://www.contoso.com:80/index.htm");
1092                         Assert.AreEqual (uri1.GetHashCode (), uri2.GetHashCode (), "#3");
1093                         uri2 = new Uri ("http://www.contoso.com:8080/index.htm");
1094                         Assert.IsTrue (uri1.GetHashCode () != uri2.GetHashCode (), "#4");
1095                 }
1096
1097                 [Test]
1098                 public void RelativeEqualsTest()
1099                 {
1100                         Uri uri1 = new Uri ("foo/bar", UriKind.Relative);
1101                         Uri uri2 = new Uri ("foo/bar", UriKind.Relative);
1102                         Uri uri3 = new Uri ("bar/man", UriKind.Relative);
1103                         Uri uri4 = new Uri ("BAR/MAN", UriKind.Relative);
1104                         Assert.IsTrue (uri1 == uri2, "#1a");
1105                         Assert.IsTrue (uri1.Equals(uri2), "#1b");
1106                         Assert.IsTrue (uri1 != uri3, "#2a");
1107                         Assert.IsTrue (!uri1.Equals(uri3), "#2b");
1108                         Assert.IsTrue (uri1 == uri2, "#3a");
1109                         Assert.IsTrue (uri1.Equals(uri2), "#3b");
1110                         Assert.IsTrue (uri1 != uri3, "#4a");
1111                         Assert.IsTrue (!uri1.Equals(uri3), "#4b");
1112                         Assert.IsTrue (uri3 != uri4, "#5a");
1113                         Assert.IsTrue (!uri3.Equals(uri4), "#5b");
1114                 }
1115
1116                 [Test]
1117                 [ExpectedException(typeof(InvalidOperationException))]
1118                 public void GetLeftPart_Partial1 ()
1119                 {
1120                         Uri u = new Uri ("foo", UriKind.Relative);
1121                         u.GetLeftPart (UriPartial.Scheme);
1122                 }
1123
1124                 [ExpectedException(typeof(InvalidOperationException))]
1125                 [Test]
1126                 public void GetLeftPart_Partial2 ()
1127                 {
1128                         Uri u = new Uri ("foo", UriKind.Relative);
1129                         u.GetLeftPart (UriPartial.Authority);
1130                 }
1131
1132                 [ExpectedException(typeof(InvalidOperationException))]
1133                 [Test]
1134                 public void GetLeftPart_Partial3 ()
1135                 {
1136                         Uri u = new Uri ("foo", UriKind.Relative);
1137                         u.GetLeftPart (UriPartial.Path);
1138                 }
1139
1140                 [Test]
1141                 public void TestPartialToString ()
1142                 {
1143                         Assert.AreEqual (new Uri ("foo", UriKind.Relative).ToString (), "foo", "#1");
1144                         Assert.AreEqual (new Uri ("foo#aa", UriKind.Relative).ToString (), "foo#aa", "#2");
1145                         Assert.AreEqual (new Uri ("foo?aa", UriKind.Relative).ToString (), "foo?aa", "#3");
1146                         Assert.AreEqual (new Uri ("foo#dingus?aa", UriKind.Relative).ToString (), "foo#dingus?aa", "#4");
1147                         Assert.AreEqual (new Uri ("foo?dingus#aa", UriKind.Relative).ToString (), "foo?dingus#aa", "#4");
1148                 }
1149
1150                 [Test]
1151                 public void RelativeGetHashCodeTest()
1152                 {
1153                         Uri uri1 = new Uri ("foo/bar", UriKind.Relative);
1154                         Uri uri2 = new Uri ("foo/bar", UriKind.Relative);
1155                         Uri uri3 = new Uri ("bar/man", UriKind.Relative);
1156                         Assert.AreEqual (uri1.GetHashCode(), uri2.GetHashCode(), "#1");
1157                         Assert.IsTrue (uri1.GetHashCode() != uri3.GetHashCode(), "#2");
1158                 }
1159
1160                 [Test]
1161                 public void MakeRelative ()
1162                 {
1163                         Uri uri1 = new Uri ("http://www.contoso.com/index.htm?x=2");
1164                         Uri uri2 = new Uri ("http://www.contoso.com/foo/bar/index.htm#fragment");
1165                         Uri uri3 = new Uri ("http://www.contoso.com/bar/foo/index.htm?y=1");
1166                         Uri uri4 = new Uri ("http://www.contoso.com/bar/foo2/index.htm?x=0");
1167                         Uri uri5 = new Uri ("https://www.contoso.com/bar/foo/index.htm?y=1");
1168                         Uri uri6 = new Uri ("http://www.contoso2.com/bar/foo/index.htm?x=0");
1169                         Uri uri7 = new Uri ("http://www.contoso2.com/bar/foo/foobar.htm?z=0&y=5");
1170                         Uri uri8 = new Uri ("http://www.xxx.com/bar/foo/foobar.htm?z=0&y=5" + (char) 0xa9);
1171
1172                         Assert.AreEqual ("foo/bar/index.htm", uri1.MakeRelative (uri2), "#1");
1173                         Assert.AreEqual ("../../index.htm", uri2.MakeRelative (uri1), "#2");
1174
1175                         Assert.AreEqual ("../../bar/foo/index.htm", uri2.MakeRelative (uri3), "#3");
1176                         Assert.AreEqual ("../../foo/bar/index.htm", uri3.MakeRelative (uri2), "#4");
1177
1178                         Assert.AreEqual ("../foo2/index.htm", uri3.MakeRelative (uri4), "#5");
1179                         Assert.AreEqual ("../foo/index.htm", uri4.MakeRelative (uri3), "#6");
1180
1181                         Assert.AreEqual ("https://www.contoso.com/bar/foo/index.htm?y=1", uri4.MakeRelative (uri5), "#7");
1182
1183                         Assert.AreEqual ("http://www.contoso2.com/bar/foo/index.htm?x=0", uri4.MakeRelative (uri6), "#8");
1184
1185                         Assert.AreEqual ("", uri6.MakeRelative (uri6), "#9");
1186                         Assert.AreEqual ("foobar.htm", uri6.MakeRelative (uri7), "#10");
1187
1188                         Uri uri10 = new Uri ("mailto:xxx@xxx.com");
1189                         Uri uri11 = new Uri ("mailto:xxx@xxx.com?subject=hola");
1190                         Assert.AreEqual ("", uri10.MakeRelative (uri11), "#11");
1191
1192                         Uri uri12 = new Uri ("mailto:xxx@mail.xxx.com?subject=hola");
1193                         Assert.AreEqual ("mailto:xxx@mail.xxx.com?subject=hola", uri10.MakeRelative (uri12), "#12");
1194
1195                         Uri uri13 = new Uri ("mailto:xxx@xxx.com/foo/bar");
1196                         Assert.AreEqual ("/foo/bar", uri10.MakeRelative (uri13), "#13");
1197
1198                         Assert.AreEqual ("http://www.xxx.com/bar/foo/foobar.htm?z=0&y=5" + (char) 0xa9, uri1.MakeRelative (uri8), "#14");
1199                 }
1200
1201                 [Test]
1202                 public void RelativeFragmentUri ()
1203                 {
1204                         Uri u = new Uri("http://localhost/../../../a");
1205                         Assert.AreEqual ("http://localhost/a", u.ToString ());
1206
1207                         u = new Uri ("http://localhost/../c/b/../a");
1208                         Assert.AreEqual ("http://localhost/c/a", u.ToString ());
1209                 }
1210
1211                 [Test]
1212                 public void RelativeFragmentUri2 ()
1213                 {
1214                         Assert.AreEqual ("hoge:ext", new Uri (new Uri ("hoge:foo:bar:baz"), "hoge:ext").ToString (), "#1");
1215                         if (isWin32) {
1216                                 Assert.AreEqual ("file:///d:/myhost/ext", new Uri (new Uri ("file:///c:/localhost/bar"), "file:///d:/myhost/ext").ToString (), "#2-w");
1217                                 Assert.AreEqual ("file:///c:/localhost/myhost/ext", new Uri (new Uri ("file:///c:/localhost/bar"), "file:myhost/ext").ToString (), "#3-w");
1218                                 Assert.AreEqual ("uuid:ext", new Uri (new Uri ("file:///c:/localhost/bar"), "uuid:ext").ToString (), "#4-w");
1219                                 Assert.AreEqual ("file:///c:/localhost/ext", new Uri (new Uri ("file:///c:/localhost/bar"), "file:./ext").ToString (), "#5-w");
1220                         } else {
1221                                 Assert.AreEqual ("file:///d/myhost/ext", new Uri (new Uri ("file:///c/localhost/bar"), "file:///d/myhost/ext").ToString (), "#2-u");
1222                                 Assert.AreEqual ("file:///c/localhost/myhost/ext", new Uri (new Uri ("file:///c/localhost/bar"), "file:myhost/ext").ToString (), "#3-u");
1223                                 Assert.AreEqual ("uuid:ext", new Uri (new Uri ("file:///c/localhost/bar"), "uuid:ext").ToString (), "#4-u");
1224                                 Assert.AreEqual ("file:///c/localhost/ext", new Uri (new Uri ("file:///c/localhost/bar"), "file:./ext").ToString (), "#5-u");
1225                         }
1226                         Assert.AreEqual ("http://localhost/ext", new Uri (new Uri ("http://localhost/bar"), "http:./ext").ToString (), "#6");
1227                 }
1228
1229                 [Test]
1230                 public void ToStringTest()
1231                 {
1232                         Uri uri = new Uri ("dummy://xxx");
1233                         Assert.AreEqual ("dummy://xxx/", uri.ToString (), "#1");
1234                 }
1235
1236                 [Test]
1237                 public void CheckSchemeName ()
1238                 {
1239                         Assert.AreEqual (false, Uri.CheckSchemeName (null), "#01");
1240                         Assert.AreEqual (false, Uri.CheckSchemeName (""), "#02");
1241                         Assert.AreEqual (true, Uri.CheckSchemeName ("http"), "#03");
1242                         Assert.AreEqual (true, Uri.CheckSchemeName ("http-"), "#04");
1243                         Assert.AreEqual (false, Uri.CheckSchemeName ("6http-"), "#05");
1244                         Assert.AreEqual (true, Uri.CheckSchemeName ("http6-"), "#06");
1245                         Assert.AreEqual (false, Uri.CheckSchemeName ("http6,"), "#07");
1246                         Assert.AreEqual (true, Uri.CheckSchemeName ("http6."), "#08");
1247                         Assert.AreEqual (false, Uri.CheckSchemeName ("+http"), "#09");
1248                         Assert.AreEqual (true, Uri.CheckSchemeName ("htt+p6"), "#10");
1249                         // 0x00E1 -> &atilde;
1250                         Assert.IsTrue (!Uri.CheckSchemeName ("htt\u00E1+p6"), "#11");
1251                 }
1252
1253                 [Test]
1254                 public void CheckSchemeName_FirstChar ()
1255                 {
1256                         for (int i = 0; i < 256; i++) {
1257                                 string s = String.Format ("#{0}", i);
1258                                 char c = (char) i;
1259                                 bool b = Uri.CheckSchemeName (c.ToString ());
1260                                 bool valid = (((i >= 0x41) && (i <= 0x5A)) || ((i >= 0x61) && (i <= 0x7A)));
1261                                 Assert.AreEqual (valid, b, s);
1262                         }
1263                 }
1264
1265                 [Test]
1266                 public void CheckSchemeName_AnyOtherChar ()
1267                 {
1268                         for (int i = 0; i < 256; i++) {
1269                                 string s = String.Format ("#{0}", i);
1270                                 char c = (char) i;
1271                                 string scheme = String.Format ("a+b-c.d{0}", c);
1272                                 bool b = Uri.CheckSchemeName (scheme);
1273                                 bool common = Char.IsDigit (c) || (c == '+') || (c == '-') || (c == '.');
1274                                 bool valid = (common || ((i >= 0x41) && (i <= 0x5A)) || ((i >= 0x61) && (i <= 0x7A)));
1275                                 Assert.AreEqual (valid, b, s);
1276                         }
1277                 }
1278
1279                 [Test]
1280                 [ExpectedException (typeof (UriFormatException))]
1281                 public void NoHostname ()
1282                 {
1283                         Uri uri = new Uri ("http://");
1284                 }
1285
1286                 [Test]
1287                 public void NoHostname2 ()
1288                 {
1289                         // bug 75144
1290                         Uri uri = new Uri ("file://");
1291                         Assert.AreEqual (true, uri.IsFile, "#1");
1292                         Assert.AreEqual (false, uri.IsUnc, "#2");
1293                         Assert.AreEqual ("file", uri.Scheme, "#3");
1294                         Assert.AreEqual ("/", uri.LocalPath, "#4");
1295                         Assert.AreEqual (string.Empty, uri.Query, "#5");
1296                         Assert.AreEqual ("/", uri.AbsolutePath, "#6");
1297                         Assert.AreEqual ("file:///", uri.AbsoluteUri, "#7");
1298                         Assert.AreEqual (string.Empty, uri.Authority, "#8");
1299                         Assert.AreEqual (string.Empty, uri.Host, "#9");
1300                         Assert.AreEqual (UriHostNameType.Basic, uri.HostNameType, "#10");
1301                         Assert.AreEqual (string.Empty, uri.Fragment, "#11");
1302                         Assert.AreEqual (true, uri.IsDefaultPort, "#12");
1303                         Assert.IsTrue (uri.IsLoopback, "#13");
1304                         Assert.AreEqual ("/", uri.PathAndQuery, "#14");
1305                         Assert.AreEqual (false, uri.UserEscaped, "#15");
1306                         Assert.AreEqual (string.Empty, uri.UserInfo, "#16");
1307                         Assert.AreEqual ("file://", uri.GetLeftPart (UriPartial.Authority), "#17");
1308                         Assert.AreEqual ("file:///", uri.GetLeftPart (UriPartial.Path), "#18");
1309                         Assert.AreEqual ("file://", uri.GetLeftPart (UriPartial.Scheme), "#19");
1310                 }
1311
1312                 [Test]
1313                 public void Segments1 ()
1314                 {
1315                         Uri uri = new Uri ("http://localhost/");
1316                         string [] segments = uri.Segments;
1317                         Assert.AreEqual (1, segments.Length, "#01");
1318                         Assert.AreEqual ("/", segments [0], "#02");
1319                 }
1320
1321                 [Test]
1322                 public void Segments2 ()
1323                 {
1324                         Uri uri = new Uri ("http://localhost/dir/dummypage.html");
1325                         string [] segments = uri.Segments;
1326                         Assert.AreEqual (3, segments.Length, "#01");
1327                         Assert.AreEqual ("/", segments [0], "#02");
1328                         Assert.AreEqual ("dir/", segments [1], "#03");
1329                         Assert.AreEqual ("dummypage.html", segments [2], "#04");
1330                 }
1331
1332                 [Test]
1333                 public void CachingSegments ()
1334                 {
1335                         Uri uri = new Uri ("http://localhost/dir/dummypage.html");
1336                         uri.Segments [0] = uri.Segments [1] = uri.Segments [2] = "*";
1337                         string [] segments = uri.Segments;
1338                         Assert.AreEqual (3, segments.Length, "#01");
1339                         Assert.AreEqual ("/", segments [0], "#02");
1340                         Assert.AreEqual ("dir/", segments [1], "#03");
1341                         Assert.AreEqual ("dummypage.html", segments [2], "#04");
1342                 }
1343
1344                 [Test]
1345                 public void Segments3 ()
1346                 {
1347                         Uri uri = new Uri ("http://localhost/dir/dummypage/");
1348                         string [] segments = uri.Segments;
1349                         Assert.AreEqual (3, segments.Length, "#01");
1350                         Assert.AreEqual ("/", segments [0], "#02");
1351                         Assert.AreEqual ("dir/", segments [1], "#03");
1352                         Assert.AreEqual ("dummypage/", segments [2], "#04");
1353                 }
1354
1355                 [Test]
1356                 public void Segments4 ()
1357                 {
1358                         Uri uri = new Uri ("file:///c:/hello");
1359
1360                         Assert.AreEqual ("c:/hello", uri.AbsolutePath, "AbsolutePath");
1361                         Assert.AreEqual ("c:\\hello", uri.LocalPath, "LocalPath");
1362
1363                         string [] segments = uri.Segments;
1364                         Assert.AreEqual (3, segments.Length, "#01");
1365                         Assert.AreEqual ("/", segments [0], "#02");
1366                         Assert.AreEqual ("c:/", segments[1], "#03");
1367                         Assert.AreEqual ("hello", segments [2], "#04");
1368                 }
1369
1370                 [Test]
1371                 public void Segments5 ()
1372                 {
1373                         Uri uri = new Uri ("http://www.xxx.com/bar/foo/foobar.htm?z=0&y=5" + (char) 0xa9);
1374                         string [] segments = uri.Segments;
1375                         Assert.AreEqual (4, segments.Length, "#01");
1376                         Assert.AreEqual ("/", segments [0], "#02");
1377                         Assert.AreEqual ("bar/", segments [1], "#03");
1378                         Assert.AreEqual ("foo/", segments [2], "#04");
1379                         Assert.AreEqual ("foobar.htm", segments [3], "#05");
1380                 }
1381
1382                 [Test]
1383                 [ExpectedException (typeof (UriFormatException))]
1384                 public void UriStartingWithColon()
1385                 {
1386                         new Uri("://");
1387                 }
1388
1389                 [Test]
1390                 [ExpectedException (typeof (UriFormatException))]
1391                 public void EmptyScheme ()
1392                 {
1393                         new Uri ("hey");
1394                 }
1395
1396                 [Test]
1397                 public void SchemeWithDigits ()
1398                 {
1399                         Uri uri = new Uri ("net.p2p://foobar");
1400                         Assert.AreEqual ("net.p2p", uri.Scheme);
1401                 }
1402
1403                 // on .NET 2.0 a port number is limited to UInt16.MaxValue
1404                 [ExpectedException (typeof (UriFormatException))]
1405                 [Test]
1406                 public void InvalidPort1 ()
1407                 {
1408                         Uri uri = new Uri ("http://www.contoso.com:65536/foo/bar/");
1409                         Assert.AreEqual (65536, uri.Port);
1410                 }
1411
1412                 [ExpectedException (typeof (UriFormatException))]
1413                 [Test]
1414                 public void InvalidPort2 ()
1415                 {
1416                         // UInt32.MaxValue gives port == -1 !!!
1417                         Uri uri = new Uri ("http://www.contoso.com:4294967295/foo/bar/");
1418                         Assert.AreEqual (-1, uri.Port);
1419                 }
1420
1421                 [ExpectedException (typeof (UriFormatException))]
1422                 [Test]
1423                 public void InvalidPort3 ()
1424                 {
1425                         // ((uint) Int32.MaxValue + (uint) 1) gives port == -2147483648 !!!
1426                         Uri uri = new Uri ("http://www.contoso.com:2147483648/foo/bar/");
1427                         Assert.AreEqual (-2147483648, uri.Port);
1428                 }
1429
1430                 [Test]
1431                 public void PortMax ()
1432                 {
1433                         // on .NET 2.0 a port number is limited to UInt16.MaxValue
1434                         Uri uri = new Uri ("http://www.contoso.com:65535/foo/bar/");
1435                         Assert.AreEqual (65535, uri.Port);
1436                 }
1437
1438                 class UriEx2 : Uri
1439                 {
1440                         public UriEx2 (string s) : base (s)
1441                         {
1442                         }
1443
1444                         protected override void Parse ()
1445                         {
1446                         }
1447                 }
1448
1449                 // Parse method is no longer used on .NET 2.0
1450                 [ExpectedException (typeof (UriFormatException))]
1451                 [Test]
1452                 public void ParseOverride ()
1453                 {
1454                         // If this does not override base's Parse(), it will
1455                         // fail since this argument is not Absolute URI.
1456                         UriEx2 ex = new UriEx2 ("readme.txt");
1457                 }
1458
1459                 [Test]
1460                 public void UnixLocalPath ()
1461                 {
1462                         // This works--the location is not part of the absolute path
1463                         string path = "file://localhost/tmp/foo/bar";
1464                         Uri fileUri = new Uri( path );
1465                         Assert.AreEqual ("/tmp/foo/bar", fileUri.AbsolutePath, path);
1466
1467                         // Empty path == localhost, in theory
1468                         path = "file:///c:/tmp/foo/bar";
1469                         fileUri = new Uri( path );
1470                         Assert.AreEqual ("c:/tmp/foo/bar", fileUri.AbsolutePath, path);
1471                 }
1472
1473                 [Test]
1474                 public void WindowsLocalPath ()
1475                 {
1476                         new Uri (@"file:///J:\Wrldwide\MSFin\Flash\FLASH.xls");
1477                 }
1478
1479                 [Test]
1480                 public void TestEscapeDataString ()
1481                 {
1482                         StringBuilder sb = new StringBuilder ();
1483
1484                         for (int i = 0; i < 128; i++)
1485                                 sb.Append ((char) i);
1486
1487 #if NET_4_5
1488                         Assert.AreEqual (
1489                                 "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20%21%22%23%24%25%26%27%28%29%2A%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~%7F",
1490                                 Uri.EscapeDataString (sb.ToString ()));
1491 #else
1492                         Assert.AreEqual (
1493                                 "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20!%22%23%24%25%26'()*%2B%2C-.%2F0123456789%3A%3B%3C%3D%3E%3F%40ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~%7F",
1494                                 Uri.EscapeDataString (sb.ToString ()));
1495 #endif
1496
1497                         Assert.AreEqual ("%C3%A1", Uri.EscapeDataString ("á"));
1498                 }
1499                 [Test]
1500                 public void TestEscapeUriString ()
1501                 {
1502                         StringBuilder sb = new StringBuilder ();
1503                         for (int i = 0; i < 128; i++)
1504                                 sb.Append ((char) i);
1505
1506 #if NET_4_5
1507                         Assert.AreEqual (
1508                                 "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20!%22#$%25&'()*+,-./0123456789:;%3C=%3E?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[%5C]%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~%7F",
1509                                 Uri.EscapeUriString (sb.ToString ()));
1510 #else
1511                         Assert.AreEqual (
1512                                 "%00%01%02%03%04%05%06%07%08%09%0A%0B%0C%0D%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%20!%22#$%25&'()*+,-./0123456789:;%3C=%3E?@ABCDEFGHIJKLMNOPQRSTUVWXYZ%5B%5C%5D%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~%7F",
1513                                 Uri.EscapeUriString (sb.ToString ()));
1514 #endif
1515
1516                         Assert.AreEqual ("%C3%A1", Uri.EscapeDataString ("á"));
1517                 }
1518
1519                 //bnc #363320
1520                 [Test]
1521                 public void TestUTF8Strings ()
1522                 {
1523                         string [] tests = {
1524                                 "file:///tmp/x (%232).jpg",
1525                                 "file:///tmp/ü (%232).jpg" };
1526
1527                         foreach (string test in tests) {
1528                                 Uri uri = new Uri (test);
1529                                 Assert.IsFalse (uri.IsWellFormedOriginalString (), "IsWellFormedOriginalString/" + test);
1530                                 Assert.AreEqual (test, uri.OriginalString, "OriginalString/" + test);
1531                                 Assert.AreEqual (test, uri.ToString (), "ToString/" + test);
1532                         }
1533                 }
1534
1535                 // This test doesn't work on Linux, and arguably shouldn't work.
1536                 // new Uri("file:///tmp/foo/bar").AbsolutePath returns "/tmp/foo/bar"
1537                 // on Linux, as anyone sane would expect.  It *doesn't* under .NET 1.1
1538                 // Apparently "tmp" is supposed to be a hostname (!)...
1539                 // Since "correct" behavior would confuse all Linux developers, and having
1540                 // an expected failure is evil, we'll just ignore this for now...
1541                 //
1542                 // Furthermore, Microsoft fixed this so it behaves sensibly in .NET 2.0.
1543                 //
1544                 // You are surrounded by conditional-compilation code, all alike.
1545                 // You are likely to be eaten by a Grue...
1546                 [Test]
1547                 public void UnixLocalPath_WTF ()
1548                 {
1549                         // Empty path == localhost, in theory
1550                         string path = "file:///tmp/foo/bar";
1551                         Uri fileUri = new Uri( path );
1552                         Assert.AreEqual ("/tmp/foo/bar", fileUri.AbsolutePath, path);
1553
1554                         // bug #76643
1555                         string path2 = "file:///foo%25bar";
1556                         fileUri = new Uri (path2);
1557                         Assert.AreEqual ("file:///foo%25bar", fileUri.ToString (), path2);
1558                 }
1559
1560                 public static void Print (Uri uri)
1561                 {
1562                         Console.WriteLine ("ToString: " + uri.ToString ());
1563
1564                         Console.WriteLine ("AbsolutePath: " + uri.AbsolutePath);
1565                         Console.WriteLine ("AbsoluteUri: " + uri.AbsoluteUri);
1566                         Console.WriteLine ("Authority: " + uri.Authority);
1567                         Console.WriteLine ("Fragment: " + uri.Fragment);
1568                         Console.WriteLine ("Host: " + uri.Host);
1569                         Console.WriteLine ("HostNameType: " + uri.HostNameType);
1570                         Console.WriteLine ("IsDefaultPort: " + uri.IsDefaultPort);
1571                         Console.WriteLine ("IsFile: " + uri.IsFile);
1572                         Console.WriteLine ("IsLoopback: " + uri.IsLoopback);
1573                         Console.WriteLine ("IsUnc: " + uri.IsUnc);
1574                         Console.WriteLine ("LocalPath: " + uri.LocalPath);
1575                         Console.WriteLine ("PathAndQuery        : " + uri.PathAndQuery);
1576                         Console.WriteLine ("Port: " + uri.Port);
1577                         Console.WriteLine ("Query: " + uri.Query);
1578                         Console.WriteLine ("Scheme: " + uri.Scheme);
1579                         Console.WriteLine ("UserEscaped: " + uri.UserEscaped);
1580                         Console.WriteLine ("UserInfo: " + uri.UserInfo);
1581
1582                         Console.WriteLine ("Segments:");
1583                         string [] segments = uri.Segments;
1584                         if (segments == null)
1585                                 Console.WriteLine ("\tNo Segments");
1586                         else
1587                                 for (int i = 0; i < segments.Length; i++)
1588                                         Console.WriteLine ("\t" + segments[i]);
1589                         Console.WriteLine ("");
1590                 }
1591
1592                 [Test]
1593                 public void FtpRootPath ()
1594                 {
1595                         Uri u = new Uri ("ftp://a.b/%2fabc/def");
1596                         string p = u.PathAndQuery;
1597                         Assert.AreEqual ("/%2fabc/def", p);
1598                         p = Uri.UnescapeDataString (p).Substring (1);
1599                         Assert.AreEqual ("/abc/def", p);
1600                         u = new Uri (new Uri ("ftp://a.b/c/d/e/f"), p);
1601                         Assert.AreEqual ("/abc/def", u.PathAndQuery);
1602                 }
1603
1604 //BNC#533572
1605                 [Test]
1606                 public void LocalPath_FileNameWithAtSign1 ()
1607                 {
1608                         string path = "/some/path/file_with_an_@_sign.mp3";
1609                         string fullpath = "http://thehost" + path;
1610                         Uri fileUri = new Uri (fullpath);
1611
1612                         Assert.AreEqual (fileUri.UserInfo, String.Empty, "LocalPath_FileNameWithAtSign UserInfo");
1613                         Assert.AreEqual (fileUri.Host, "thehost", "LocalPath_FileNameWithAtSign Host");
1614                         Assert.IsFalse (fileUri.IsFile, "LocalPath_FileNameWithAtSign IsFile");
1615                         Assert.IsTrue (fileUri.IsAbsoluteUri, "LocalPath_FileNameWithAtSign IsAbsUri");
1616                         Assert.IsFalse (fileUri.IsUnc, "LocalPath_FileNameWithAtSign IsUnc");
1617
1618                         Assert.AreEqual (fullpath, fileUri.OriginalString, "LocalPath_FileNameWithAtSign OriginalString");
1619                         Assert.AreEqual (path, new DerivedUri (fullpath).TestUnescape (path), "LocalPath_FileNameWithAtSign ProtectedUnescape");
1620                         Assert.AreEqual (path, fileUri.AbsolutePath, "LocalPath_FileNameWithAtSign AbsPath");
1621                         Assert.AreEqual (path, fileUri.LocalPath, "LocalPath_FileNameWithAtSign LocalPath");
1622                 }
1623
1624                 [Test]
1625                 public void LocalPath_FileNameWithAtSign2 ()
1626                 {
1627                         string path = "/some/path/file_with_an_@_sign.mp3";
1628                         string fullpath = "http://user:password@thehost" + path;
1629                         Uri fileUri = new Uri (fullpath);
1630
1631                         Assert.AreEqual (fileUri.UserInfo, "user:password", "LocalPath_FileNameWithAtSign UserInfo");
1632                         Assert.AreEqual (fileUri.Host, "thehost", "LocalPath_FileNameWithAtSign Host");
1633                         Assert.IsFalse (fileUri.IsFile, "LocalPath_FileNameWithAtSign IsFile");
1634                         Assert.IsTrue (fileUri.IsAbsoluteUri, "LocalPath_FileNameWithAtSign IsAbsUri");
1635                         Assert.IsFalse (fileUri.IsUnc, "LocalPath_FileNameWithAtSign IsUnc");
1636
1637                         Assert.AreEqual (fullpath, fileUri.OriginalString, "LocalPath_FileNameWithAtSign OriginalString");
1638                         Assert.AreEqual (path, new DerivedUri (fullpath).TestUnescape (path), "LocalPath_FileNameWithAtSign ProtectedUnescape");
1639                         Assert.AreEqual (path, fileUri.AbsolutePath, "LocalPath_FileNameWithAtSign AbsPath");
1640                         Assert.AreEqual (path, fileUri.LocalPath, "LocalPath_FileNameWithAtSign LocalPath");
1641                 }
1642
1643                 [Test]
1644                 public void LocalPath_FileNameWithAtSign3 ()
1645                 {
1646                         string path = "/some/path/file_with_an_@_sign.mp3";
1647                         string fullpath = "file://" + path;
1648                         Uri fileUri = new Uri (fullpath);
1649
1650                         Assert.AreEqual (fileUri.UserInfo, String.Empty, "LocalPath_FileNameWithAtSign UserInfo");
1651                         Assert.AreEqual (fileUri.Host, String.Empty, "LocalPath_FileNameWithAtSign Host");
1652                         Assert.IsTrue (fileUri.IsFile, "LocalPath_FileNameWithAtSign IsFile");
1653                         Assert.IsTrue (fileUri.IsAbsoluteUri, "LocalPath_FileNameWithAtSign IsAbsUri");
1654                         Assert.IsFalse (fileUri.IsUnc, "LocalPath_FileNameWithAtSign IsUnc");
1655
1656                         Assert.AreEqual (fullpath, fileUri.OriginalString, "LocalPath_FileNameWithAtSign OriginalString");
1657                         Assert.AreEqual (path, new DerivedUri (fullpath).TestUnescape (path), "LocalPath_FileNameWithAtSign ProtectedUnescape");
1658                         Assert.AreEqual (path, fileUri.AbsolutePath, "LocalPath_FileNameWithAtSign AbsPath");
1659                         Assert.AreEqual (path, fileUri.LocalPath, "LocalPath_FileNameWithAtSign LocalPath");
1660                 }
1661
1662                 [Test]
1663                 public void LocalPath_FileNameWithAtSign4 ()
1664                 {
1665                         string path = "/some/path/file_with_an_@_sign.mp3";
1666                         string fullpath = "file://localhost" + path;
1667                         Uri fileUri = new Uri (fullpath);
1668
1669                         Assert.AreEqual (fileUri.UserInfo, String.Empty, "LocalPath_FileNameWithAtSign UserInfo");
1670                         Assert.AreEqual (fileUri.Host, "localhost", "LocalPath_FileNameWithAtSign Host");
1671                         Assert.IsTrue (fileUri.IsFile, "LocalPath_FileNameWithAtSign IsFile");
1672                         Assert.IsTrue (fileUri.IsAbsoluteUri, "LocalPath_FileNameWithAtSign IsAbsUri");
1673                         Assert.AreEqual (isWin32, fileUri.IsUnc, "LocalPath_FileNameWithAtSign IsUnc");
1674
1675                         Assert.AreEqual (fullpath, fileUri.OriginalString, "LocalPath_FileNameWithAtSign OriginalString");
1676                         Assert.AreEqual (path, new DerivedUri (fullpath).TestUnescape (path), "LocalPath_FileNameWithAtSign ProtectedUnescape");
1677                         Assert.AreEqual (path, fileUri.AbsolutePath, "LocalPath_FileNameWithAtSign AbsPath");
1678                         //this test is marked as NotWorking below:
1679                         //Assert.AreEqual ("\\\\localhost" + path.Replace ("/", "\\"), fileUri.LocalPath, "LocalPath_FileNameWithAtSign LocalPath");
1680                 }
1681
1682                 [Test]
1683                 public void LocalPath_FileNameWithAtSign5 ()
1684                 {
1685                         string path = "/some/path/file_with_an_@_sign.mp3";
1686                         string fullpath = "file://localhost" + path;
1687                         Uri fileUri = new Uri (fullpath);
1688
1689                         string expected = isWin32 ? "\\\\localhost" + path.Replace ("/", "\\") : "/some/path/file_with_an_@_sign.mp3";
1690                         Assert.AreEqual (expected, fileUri.LocalPath, "LocalPath_FileNameWithAtSign LocalPath");
1691                 }
1692
1693                 [Test]
1694                 [ExpectedException (typeof (UriFormatException))]
1695                 public void LocalPath_FileNameWithAtSign6 ()
1696                 {
1697                         string path = "/some/path/file_with_an_@_sign.mp3";
1698                         string fullpath = "file://user:password@localhost" + path;
1699                         Uri fileUri = new Uri (fullpath);
1700                 }
1701
1702                 [Test]
1703                 [Category ("NotDotNet")]
1704                 public void UnixAbsoluteFilePath_WithSpecialChars1 ()
1705                 {
1706                         Uri unixuri = new Uri ("/home/user/a@b");
1707                         Assert.AreEqual ("file", unixuri.Scheme, "UnixAbsoluteFilePath_WithSpecialChars #1");
1708                 }
1709
1710                 [Test]
1711                 [Category ("NotDotNet")]
1712                 public void UnixAbsoluteFilePath_WithSpecialChars2 ()
1713                 {
1714                         Uri unixuri = new Uri ("/home/user/a:b");
1715                         Assert.AreEqual ("file", unixuri.Scheme, "UnixAbsoluteFilePath_WithSpecialChars #2");
1716                 }
1717
1718                 [Test]
1719                 [Category ("NotDotNet")]
1720                 public void UnixAbsolutePath_ReplaceRelative ()
1721                 {
1722                         var u1 = new Uri ("/Users/demo/Projects/file.xml");
1723                         var u2 = new Uri (u1, "b.jpg");
1724
1725                         Assert.AreEqual ("file:///Users/demo/Projects/b.jpg", u2.ToString ());
1726                 }
1727
1728                 [Test]
1729                 public void RelativeUriWithColons ()
1730                 {
1731                         string s = @"Transform?args=[{""__type"":""Record:#Nostr"",""Code"":""%22test%22SomeGloss"",""ID"":""1"",""Table"":""Glossary""},{""__type"":""Record:#Nostr"",""Code"":""%22test%22All"",""ID"":""2"",""Table"":""GlossView""}, {""__type"":""Record:#Nostr"",""Code"":""%22test%22Q"",""ID"":""3"",""Table"":""Glossary""}]"; // with related to bug #573795
1732                         new Uri (s, UriKind.Relative);
1733                         new Uri (":", UriKind.Relative);
1734                         new Uri ("1:", UriKind.Relative);
1735                 }
1736
1737                 [Test]
1738                 public void ConsecutiveSlashes ()
1739                 {
1740                         Uri uri = new Uri ("http://media.libsyn.com/bounce/http://cdn4.libsyn.com/nerdist/somestuff.txt");
1741                         Assert.AreEqual ("http://media.libsyn.com/bounce/http://cdn4.libsyn.com/nerdist/somestuff.txt", uri.ToString ());
1742                 }
1743
1744                 public class DerivedUri : Uri {
1745                         public DerivedUri (string uriString)
1746                                 : base (uriString)
1747                         {
1748                         }
1749
1750                         internal string TestUnescape (string path)
1751                         {
1752                                 return base.Unescape (path);
1753                         }
1754                 }
1755
1756                 [Test]
1757                 [ExpectedException (typeof (InvalidOperationException))]
1758                 public void GetComponents_Relative ()
1759                 {
1760                         Uri rel = new Uri ("/relative/path/with?query", UriKind.Relative);
1761                         rel.GetComponents (UriComponents.Query, UriFormat.SafeUnescaped);
1762                 }
1763
1764                 [Test]
1765                 public void GetComponents_AbsoluteUri ()
1766                 {
1767                         Uri uri = new Uri ("http://mono-project.com/list?id=1%262&sort=asc#fragment%263");
1768
1769                         Assert.AreEqual ("http://mono-project.com/list?id=1%262&sort=asc#fragment%263", uri.AbsoluteUri, "AbsoluteUri");
1770
1771                         string safe = uri.GetComponents (UriComponents.AbsoluteUri, UriFormat.SafeUnescaped);
1772                         Assert.AreEqual ("http://mono-project.com/list?id=1%262&sort=asc#fragment%263", safe, "SafeUnescaped");
1773
1774                         string unescaped = uri.GetComponents (UriComponents.AbsoluteUri, UriFormat.Unescaped);
1775                         Assert.AreEqual ("http://mono-project.com/list?id=1&2&sort=asc#fragment&3", unescaped, "Unescaped");
1776
1777                         string escaped = uri.GetComponents (UriComponents.AbsoluteUri, UriFormat.UriEscaped);
1778                         Assert.AreEqual ("http://mono-project.com/list?id=1%262&sort=asc#fragment%263", escaped, "UriEscaped");
1779                 }
1780
1781                 [Test]
1782                 public void GetComponents_HttpRequestUrl ()
1783                 {
1784                         Uri uri = new Uri ("http://mono-project.com/list?id=1%262&sort=asc#fragment%263");
1785
1786                         string safe = uri.GetComponents (UriComponents.HttpRequestUrl, UriFormat.SafeUnescaped);
1787                         Assert.AreEqual ("http://mono-project.com/list?id=1%262&sort=asc", safe, "SafeUnescaped");
1788
1789                         string unescaped = uri.GetComponents (UriComponents.HttpRequestUrl, UriFormat.Unescaped);
1790                         Assert.AreEqual ("http://mono-project.com/list?id=1&2&sort=asc", unescaped, "Unescaped");
1791
1792                         string escaped = uri.GetComponents (UriComponents.HttpRequestUrl, UriFormat.UriEscaped);
1793                         Assert.AreEqual ("http://mono-project.com/list?id=1%262&sort=asc", escaped, "UriEscaped");
1794                 }
1795
1796                 [Test]
1797                 public void GetComponents_KeepDelimiter ()
1798                 {
1799                         Uri uri = new Uri ("http://mono-project.com/list?id=1%262&sort=asc#fragment%263");
1800
1801                         string safe = uri.GetComponents (UriComponents.KeepDelimiter, UriFormat.SafeUnescaped);
1802                         Assert.AreEqual (String.Empty, safe, "SafeUnescaped");
1803
1804                         string unescaped = uri.GetComponents (UriComponents.KeepDelimiter, UriFormat.Unescaped);
1805                         Assert.AreEqual (String.Empty, unescaped, "Unescaped");
1806
1807                         string escaped = uri.GetComponents (UriComponents.KeepDelimiter, UriFormat.UriEscaped);
1808                         Assert.AreEqual (String.Empty, escaped, "UriEscaped");
1809                 }
1810
1811                 [Test]
1812                 public void GetComponents_StrongAuthority ()
1813                 {
1814                         Uri uri = new Uri ("http://mono-project.com/list?id=1%262&sort=asc#fragment%263");
1815
1816                         string safe = uri.GetComponents (UriComponents.StrongAuthority, UriFormat.SafeUnescaped);
1817                         Assert.AreEqual ("mono-project.com:80", safe, "SafeUnescaped");
1818
1819                         string unescaped = uri.GetComponents (UriComponents.StrongAuthority, UriFormat.Unescaped);
1820                         Assert.AreEqual ("mono-project.com:80", unescaped, "Unescaped");
1821
1822                         string escaped = uri.GetComponents (UriComponents.StrongAuthority, UriFormat.UriEscaped);
1823                         Assert.AreEqual ("mono-project.com:80", escaped, "UriEscaped");
1824                 }
1825
1826                 [Test]
1827                 public void GetComponents_Path ()
1828                 {
1829                         Uri uri1 = new Uri ("http://mono-project.com/Main%20Page");
1830                         Assert.AreEqual ("/Main Page", uri1.LocalPath, "Path1");
1831
1832                         string safe = uri1.GetComponents (UriComponents.Path, UriFormat.SafeUnescaped);
1833                         Assert.AreEqual ("Main Page", safe, "SafeUnescaped1");
1834
1835                         string unescaped = uri1.GetComponents (UriComponents.Path, UriFormat.Unescaped);
1836                         Assert.AreEqual ("Main Page", unescaped, "Unescaped1");
1837
1838                         string escaped = uri1.GetComponents (UriComponents.Path, UriFormat.UriEscaped);
1839                         Assert.AreEqual ("Main%20Page", escaped, "UriEscaped1");
1840
1841                         // same result is unescaped original string
1842                         Uri uri2 = new Uri ("http://mono-project.com/Main Page");
1843                         Assert.AreEqual ("/Main Page", uri2.LocalPath, "Path2");
1844
1845                         safe = uri2.GetComponents (UriComponents.Path, UriFormat.SafeUnescaped);
1846                         Assert.AreEqual ("Main Page", safe, "SafeUnescaped2");
1847
1848                         unescaped = uri2.GetComponents (UriComponents.Path, UriFormat.Unescaped);
1849                         Assert.AreEqual ("Main Page", unescaped, "Unescaped2");
1850
1851                         escaped = uri2.GetComponents (UriComponents.Path, UriFormat.UriEscaped);
1852                         Assert.AreEqual ("Main%20Page", escaped, "UriEscaped2");
1853                 }
1854
1855                 [Test]
1856                 public void GetComponents_PathAndQuery ()
1857                 {
1858                         Uri uri = new Uri ("http://mono-project.com/MåÏn Påge?id=1%262&sort=asc");
1859
1860                         Assert.AreEqual ("/M%C3%A5%C3%8Fn%20P%C3%A5ge?id=1%262&sort=asc", uri.PathAndQuery, "PathAndQuery");
1861
1862                         string safe = uri.GetComponents (UriComponents.PathAndQuery, UriFormat.SafeUnescaped);
1863                         Assert.AreEqual ("/MåÏn Påge?id=1%262&sort=asc", safe, "SafeUnescaped");
1864
1865                         string unescaped = uri.GetComponents (UriComponents.PathAndQuery, UriFormat.Unescaped);
1866                         Assert.AreEqual ("/MåÏn Påge?id=1&2&sort=asc", unescaped, "Unescaped");
1867
1868                         string escaped = uri.GetComponents (UriComponents.PathAndQuery, UriFormat.UriEscaped);
1869                         Assert.AreEqual ("/M%C3%A5%C3%8Fn%20P%C3%A5ge?id=1%262&sort=asc", escaped, "UriEscaped");
1870                 }
1871
1872                 [Test]
1873                 public void GetComponents_Query ()
1874                 {
1875                         Uri uri = new Uri ("http://mono-project.com/list?id=1%262&sort=asc");
1876
1877                         Assert.AreEqual ("?id=1%262&sort=asc", uri.Query, "Query");
1878                         
1879                         string safe = uri.GetComponents (UriComponents.Query, UriFormat.SafeUnescaped);
1880                         Assert.AreEqual ("id=1%262&sort=asc", safe, "SafeUnescaped");
1881
1882                         string unescaped = uri.GetComponents (UriComponents.Query, UriFormat.Unescaped);
1883                         Assert.AreEqual ("id=1&2&sort=asc", unescaped, "Unescaped");
1884
1885                         string escaped = uri.GetComponents (UriComponents.Query, UriFormat.UriEscaped);
1886                         Assert.AreEqual ("id=1%262&sort=asc", escaped, "UriEscaped");
1887                 }
1888
1889                 [Test]
1890                 public void GetComponents_Fragment ()
1891                 {
1892                         Uri uri = new Uri ("http://mono-project.com/list#id=1%262&sort=asc");
1893
1894                         Assert.AreEqual ("#id=1%262&sort=asc", uri.Fragment, "Fragment");
1895
1896                         string safe = uri.GetComponents (UriComponents.Fragment, UriFormat.SafeUnescaped);
1897                         Assert.AreEqual ("id=1%262&sort=asc", safe, "SafeUnescaped");
1898
1899                         string unescaped = uri.GetComponents (UriComponents.Fragment, UriFormat.Unescaped);
1900                         Assert.AreEqual ("id=1&2&sort=asc", unescaped, "Unescaped");
1901
1902                         string escaped = uri.GetComponents (UriComponents.Fragment, UriFormat.UriEscaped);
1903                         Assert.AreEqual ("id=1%262&sort=asc", escaped, "UriEscaped");
1904                 }
1905
1906                 // When used, paths such as "/foo" are assumed relative.
1907                 static UriKind DotNetRelativeOrAbsolute = (Type.GetType ("Mono.Runtime") == null)? UriKind.RelativeOrAbsolute : (UriKind) 300;
1908
1909                 [Test]
1910                 public void DotNetRelativeOrAbsoluteTest ()
1911                 {
1912                         FieldInfo useDotNetRelativeOrAbsoluteField = null;
1913                         bool useDotNetRelativeOrAbsoluteOld = false;
1914
1915                         if (Type.GetType ("Mono.Runtime") != null) {
1916                                 useDotNetRelativeOrAbsoluteField = typeof (Uri).GetField ("useDotNetRelativeOrAbsolute",
1917                                         BindingFlags.Static | BindingFlags.GetField | BindingFlags.NonPublic);
1918                                 useDotNetRelativeOrAbsoluteOld = (bool) useDotNetRelativeOrAbsoluteField.GetValue (null);
1919                                 useDotNetRelativeOrAbsoluteField.SetValue (null, false);
1920                         }
1921
1922                         try {
1923                                 Uri uri;
1924
1925                                 uri = new Uri ("/foo", DotNetRelativeOrAbsolute);
1926                                 Assert.IsFalse (uri.IsAbsoluteUri, "#2");
1927                                 
1928                                 Assert.IsTrue (Uri.TryCreate("/foo", DotNetRelativeOrAbsolute, out uri), "#3");
1929                                 Assert.IsFalse (uri.IsAbsoluteUri, "#3a");
1930
1931                                 if (useDotNetRelativeOrAbsoluteField != null) {
1932                                         uri = new Uri ("/foo", UriKind.RelativeOrAbsolute);
1933                                         Assert.IsTrue (uri.IsAbsoluteUri, "#4");
1934
1935                                         Assert.IsTrue (Uri.TryCreate("/foo", UriKind.RelativeOrAbsolute, out uri), "#5");
1936                                         Assert.IsTrue (uri.IsAbsoluteUri, "#5a");
1937
1938                                         useDotNetRelativeOrAbsoluteField.SetValue (null, true);
1939                                 }
1940
1941                                 uri = new Uri ("/foo", UriKind.RelativeOrAbsolute);
1942                                 Assert.IsFalse (uri.IsAbsoluteUri, "#10");
1943
1944                                 Assert.IsTrue (Uri.TryCreate("/foo", UriKind.RelativeOrAbsolute, out uri), "#11");
1945                                 Assert.IsFalse (uri.IsAbsoluteUri, "#11a");
1946                         } finally {
1947                                 if (useDotNetRelativeOrAbsoluteField != null)
1948                                         useDotNetRelativeOrAbsoluteField.SetValue (null, useDotNetRelativeOrAbsoluteOld);
1949                         }
1950                 }
1951
1952                 [Test]
1953                 // Bug #12631
1954                 public void LocalPathWithBaseUrl ()
1955                 {
1956                         var mainUri = new Uri ("http://www.imdb.com");
1957                         var uriPath = "/title/tt0106521";
1958
1959                         Uri result;
1960                         Assert.IsTrue (Uri.TryCreate (mainUri, uriPath, out result), "#1");
1961                         Assert.AreEqual ("http://www.imdb.com/title/tt0106521", result.ToString (), "#2");
1962                 }
1963
1964                 [Test]
1965                 public void GetSerializationInfoStringOnRelativeUri ()
1966                 {
1967                         var uri = new Uri ("/relative/path", UriKind.Relative);
1968                         var result = uri.GetComponents (UriComponents.SerializationInfoString, UriFormat.UriEscaped);
1969
1970                         Assert.AreEqual (uri.OriginalString, result);
1971                 }
1972
1973                 [Test]
1974                 [ExpectedException (typeof (ArgumentOutOfRangeException))]
1975                 public void GetSerializationInfoStringException ()
1976                 {
1977                         var uri = new Uri ("/relative/path", UriKind.Relative);
1978                         uri.GetComponents (UriComponents.SerializationInfoString  | UriComponents.Host, UriFormat.UriEscaped);
1979                 }
1980
1981                 [Test]
1982                 public void UserInfo_EscapedLetter ()
1983                 {
1984                         var uri = new Uri ("https://first%61second@host");
1985                         Assert.AreEqual ("firstasecond", uri.UserInfo);
1986                 }
1987
1988                 [Test]
1989                 public void UserInfo_EscapedAt ()
1990                 {
1991                         var userinfo =  "first%40second";
1992                         var uri = new Uri ("https://" + userinfo + "@host");
1993                         Assert.AreEqual (userinfo, uri.UserInfo);
1994                 }
1995
1996                 [Test]
1997                 public void UserInfo_EscapedChars ()
1998                 {
1999                         for (var ch = (char) 1; ch < 128; ch++) {
2000                                 var userinfo = Uri.EscapeDataString (ch.ToString ());
2001                                 try {
2002                                         new Uri (string.Format("http://{0}@localhost:80/", userinfo));
2003                                 } catch (Exception e) {
2004                                         Assert.Fail (string.Format("Unexpected {0} while building URI with username {1}", e.GetType ().Name, userinfo));
2005                                 }
2006                         }
2007                 }
2008
2009                 [Test]
2010                 public void UserInfo_Spaces ()
2011                 {
2012                         const string userinfo = "test 1:pass 1";
2013                         const string expected = "test%201:pass%201";
2014
2015                         try {
2016                                 var uri = new Uri (string.Format ("rtmp://{0}@test.com:333/live", userinfo));
2017                                 Assert.AreEqual (expected, uri.UserInfo);
2018                         } catch (Exception e) {
2019                                 Assert.Fail (string.Format ("Unexpected {0} while building URI with username {1}", e.GetType ().Name, userinfo));
2020                         }
2021                 }
2022
2023                 // Covers #29864
2024                 [Test]
2025                 public void PathDotTrim ()
2026                 {
2027                         var baseUri = new Uri ("http://test.com", UriKind.Absolute);
2028                         var relUri = new Uri ("path/dot./", UriKind.Relative);
2029                         var uri = new Uri (baseUri, relUri);
2030                         Assert.AreEqual ("http://test.com/path/dot./", uri.ToString ());
2031                 }
2032
2033                 [Test]
2034                 public void GuardedIPv6Address ()
2035                 {
2036                         var x = new Uri ("asfd://[::1]:123/");
2037                         Assert.AreEqual ("[::1]", x.Host, "#1");
2038                 }
2039
2040                 [Test]
2041                 public void CombineWithUserSchema ()
2042                 {
2043                         var baseUri = new Uri ("zip:mem:///");
2044                         var relativeUrl = "zip:mem:///foo/bar.txt";
2045
2046                         var result = new Uri (baseUri, relativeUrl);
2047
2048                         Assert.AreEqual ("zip:mem:///foo/bar.txt", result.ToString ());
2049                 }
2050
2051                 [Test]
2052                 public void Scheme_msapp ()
2053                 {
2054                         var uri = new Uri ("ms-app://s-1-15-2-1613647288");
2055                         Assert.AreEqual ("ms-app", uri.Scheme);
2056                 }
2057
2058                 [Test]
2059                 public void CombineWithUnixAbsolutePath ()
2060                 {
2061                         var a = new Uri ("http://localhost/");
2062                         var b = new Uri ("/foo", UriKind.RelativeOrAbsolute);
2063                         var res = new Uri (a, b);
2064
2065                         Assert.AreEqual ("http://localhost/foo", res.ToString ());
2066                 }
2067         }
2068 }