URLTest.java revision dc24b1b274a6110a56993849c8e93033e0c2f1ff
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package libcore.java.net;
18
19import java.net.Inet6Address;
20import java.net.InetAddress;
21import java.net.MalformedURLException;
22import java.net.URL;
23import junit.framework.TestCase;
24import libcore.util.SerializationTester;
25
26public final class URLTest extends TestCase {
27
28    public void testUrlParts() throws Exception {
29        URL url = new URL("http://username:password@host:8080/directory/file?query#ref");
30        assertEquals("http", url.getProtocol());
31        assertEquals("username:password@host:8080", url.getAuthority());
32        assertEquals("username:password", url.getUserInfo());
33        assertEquals("host", url.getHost());
34        assertEquals(8080, url.getPort());
35        assertEquals(80, url.getDefaultPort());
36        assertEquals("/directory/file?query", url.getFile());
37        assertEquals("/directory/file", url.getPath());
38        assertEquals("query", url.getQuery());
39        assertEquals("ref", url.getRef());
40    }
41    // http://code.google.com/p/android/issues/detail?id=12724
42    public void testExplicitPort() throws Exception {
43        URL url = new URL("http://www.google.com:80/example?language[id]=2");
44        assertEquals("www.google.com", url.getHost());
45        assertEquals(80, url.getPort());
46    }
47
48    /**
49     * Android's URL.equals() works as if the network is down. This is different
50     * from the RI, which does potentially slow and inconsistent DNS lookups in
51     * URL.equals.
52     */
53    public void testEqualsDoesNotDoHostnameResolution() throws Exception {
54        for (InetAddress inetAddress : InetAddress.getAllByName("localhost")) {
55            String address = inetAddress.getHostAddress();
56            if (inetAddress instanceof Inet6Address) {
57                address = "[" + address + "]";
58            }
59            URL urlByHostName = new URL("http://localhost/foo?bar=baz#quux");
60            URL urlByAddress = new URL("http://" + address + "/foo?bar=baz#quux");
61            assertFalse("Expected " + urlByHostName + " to not equal " + urlByAddress,
62                    urlByHostName.equals(urlByAddress)); // fails on RI, which does DNS
63        }
64    }
65
66    public void testEqualsCaseMapping() throws Exception {
67        assertEquals(new URL("HTTP://localhost/foo?bar=baz#quux"),
68                new URL("HTTP://localhost/foo?bar=baz#quux"));
69        assertTrue(new URL("http://localhost/foo?bar=baz#quux").equals(
70                new URL("http://LOCALHOST/foo?bar=baz#quux")));
71        assertFalse(new URL("http://localhost/foo?bar=baz#quux").equals(
72                new URL("http://localhost/FOO?bar=baz#quux")));
73        assertFalse(new URL("http://localhost/foo?bar=baz#quux").equals(
74                new URL("http://localhost/foo?BAR=BAZ#quux")));
75        assertFalse(new URL("http://localhost/foo?bar=baz#quux").equals(
76                new URL("http://localhost/foo?bar=baz#QUUX")));
77    }
78
79    public void testFileEqualsWithEmptyHost() throws Exception {
80        assertEquals(new URL("file", "", -1, "/a/"), new URL("file:/a/"));
81    }
82
83    public void testHttpEqualsWithEmptyHost() throws Exception {
84        assertEquals(new URL("http", "", 80, "/a/"), new URL("http:/a/"));
85        assertFalse(new URL("http", "", 80, "/a/").equals(new URL("http://host/a/")));
86    }
87
88    public void testFileEquals() throws Exception {
89        assertEquals(new URL("file", null, -1, "/a"), new URL("file", null, -1, "/a"));
90        assertFalse(new URL("file", null, -1, "/a").equals(new URL("file", null, -1, "/A")));
91    }
92
93    public void testJarEquals() throws Exception {
94        assertEquals(new URL("jar", null, -1, "/a!b"), new URL("jar", null, -1, "/a!b"));
95        assertFalse(new URL("jar", null, -1, "/a!b").equals(new URL("jar", null, -1, "/a!B")));
96        assertFalse(new URL("jar", null, -1, "/a!b").equals(new URL("jar", null, -1, "/A!b")));
97    }
98
99    public void testUrlSerialization() throws Exception {
100        String s = "aced00057372000c6a6176612e6e65742e55524c962537361afce472030006490004706f72744c0"
101                + "009617574686f726974797400124c6a6176612f6c616e672f537472696e673b4c000466696c65710"
102                + "07e00014c0004686f737471007e00014c000870726f746f636f6c71007e00014c000372656671007"
103                + "e00017870ffffffff74000e757365723a7061737340686f73747400102f706174682f66696c653f7"
104                + "175657279740004686f7374740004687474707400046861736878";
105        URL url = new URL("http://user:pass@host/path/file?query#hash");
106        new SerializationTester<URL>(url, s).test();
107    }
108
109    /**
110     * The serialized form of a URL includes its hash code. But the hash code
111     * is not documented. Check that we don't return a deserialized hash code
112     * from a deserialized value.
113     */
114    public void testUrlSerializationWithHashCode() throws Exception {
115        String s = "aced00057372000c6a6176612e6e65742e55524c962537361afce47203000749000868617368436"
116                + "f6465490004706f72744c0009617574686f726974797400124c6a6176612f6c616e672f537472696"
117                + "e673b4c000466696c6571007e00014c0004686f737471007e00014c000870726f746f636f6c71007"
118                + "e00014c000372656671007e00017870cdf0efacffffffff74000e757365723a7061737340686f737"
119                + "47400102f706174682f66696c653f7175657279740004686f7374740004687474707400046861736"
120                + "878";
121        final URL url = new URL("http://user:pass@host/path/file?query#hash");
122        new SerializationTester<URL>(url, s) {
123            @Override protected void verify(URL deserialized) {
124                assertEquals(url.hashCode(), deserialized.hashCode());
125            }
126        }.test();
127    }
128
129    public void testOnlySupportedProtocols() {
130        try {
131            new URL("abcd://host");
132            fail();
133        } catch (MalformedURLException expected) {
134        }
135    }
136
137    public void testOmittedHost() throws Exception {
138        URL url = new URL("http:///path");
139        assertEquals("", url.getHost());
140        assertEquals("/path", url.getFile());
141        assertEquals("/path", url.getPath());
142    }
143
144    public void testNoHost() throws Exception {
145        URL url = new URL("http:/path");
146        assertEquals("http", url.getProtocol());
147        assertEquals(null, url.getAuthority());
148        assertEquals(null, url.getUserInfo());
149        assertEquals("", url.getHost());
150        assertEquals(-1, url.getPort());
151        assertEquals(80, url.getDefaultPort());
152        assertEquals("/path", url.getFile());
153        assertEquals("/path", url.getPath());
154        assertEquals(null, url.getQuery());
155        assertEquals(null, url.getRef());
156    }
157
158    public void testNoPath() throws Exception {
159        URL url = new URL("http://host");
160        assertEquals("host", url.getHost());
161        assertEquals("", url.getFile());
162        assertEquals("", url.getPath());
163    }
164
165    public void testEmptyHostAndNoPath() throws Exception {
166        URL url = new URL("http://");
167        assertEquals("http", url.getProtocol());
168        assertEquals("", url.getAuthority());
169        assertEquals(null, url.getUserInfo());
170        assertEquals("", url.getHost());
171        assertEquals(-1, url.getPort());
172        assertEquals(80, url.getDefaultPort());
173        assertEquals("", url.getFile());
174        assertEquals("", url.getPath());
175        assertEquals(null, url.getQuery());
176        assertEquals(null, url.getRef());
177    }
178
179    public void testNoHostAndNoPath() throws Exception {
180        URL url = new URL("http:");
181        assertEquals("http", url.getProtocol());
182        assertEquals(null, url.getAuthority());
183        assertEquals(null, url.getUserInfo());
184        assertEquals("", url.getHost());
185        assertEquals(-1, url.getPort());
186        assertEquals(80, url.getDefaultPort());
187        assertEquals("", url.getFile());
188        assertEquals("", url.getPath());
189        assertEquals(null, url.getQuery());
190        assertEquals(null, url.getRef());
191    }
192
193    public void testAtSignInUserInfo() throws Exception {
194        try {
195            new URL("http://user@userhost.com:password@host");
196            fail();
197        } catch (MalformedURLException expected) {
198        }
199    }
200
201    public void testUserNoPassword() throws Exception {
202        URL url = new URL("http://user@host");
203        assertEquals("user@host", url.getAuthority());
204        assertEquals("user", url.getUserInfo());
205        assertEquals("host", url.getHost());
206    }
207
208    public void testUserNoPasswordExplicitPort() throws Exception {
209        URL url = new URL("http://user@host:8080");
210        assertEquals("user@host:8080", url.getAuthority());
211        assertEquals("user", url.getUserInfo());
212        assertEquals("host", url.getHost());
213        assertEquals(8080, url.getPort());
214    }
215
216    public void testUserPasswordHostPort() throws Exception {
217        URL url = new URL("http://user:password@host:8080");
218        assertEquals("user:password@host:8080", url.getAuthority());
219        assertEquals("user:password", url.getUserInfo());
220        assertEquals("host", url.getHost());
221        assertEquals(8080, url.getPort());
222    }
223
224    public void testUserPasswordEmptyHostPort() throws Exception {
225        URL url = new URL("http://user:password@:8080");
226        assertEquals("user:password@:8080", url.getAuthority());
227        assertEquals("user:password", url.getUserInfo());
228        assertEquals("", url.getHost());
229        assertEquals(8080, url.getPort());
230    }
231
232    public void testUserPasswordEmptyHostEmptyPort() throws Exception {
233        URL url = new URL("http://user:password@");
234        assertEquals("user:password@", url.getAuthority());
235        assertEquals("user:password", url.getUserInfo());
236        assertEquals("", url.getHost());
237        assertEquals(-1, url.getPort());
238    }
239
240    public void testPathOnly() throws Exception {
241        URL url = new URL("http://host/path");
242        assertEquals("/path", url.getFile());
243        assertEquals("/path", url.getPath());
244    }
245
246    public void testQueryOnly() throws Exception {
247        URL url = new URL("http://host?query");
248        assertEquals("?query", url.getFile());
249        assertEquals("", url.getPath());
250        assertEquals("query", url.getQuery());
251    }
252
253    public void testFragmentOnly() throws Exception {
254        URL url = new URL("http://host#fragment");
255        assertEquals("", url.getFile());
256        assertEquals("", url.getPath());
257        assertEquals("fragment", url.getRef());
258    }
259
260    public void testAtSignInPath() throws Exception {
261        URL url = new URL("http://host/file@foo");
262        assertEquals("/file@foo", url.getFile());
263        assertEquals("/file@foo", url.getPath());
264        assertEquals(null, url.getUserInfo());
265    }
266
267    public void testColonInPath() throws Exception {
268        URL url = new URL("http://host/file:colon");
269        assertEquals("/file:colon", url.getFile());
270        assertEquals("/file:colon", url.getPath());
271    }
272
273    public void testSlashInQuery() throws Exception {
274        URL url = new URL("http://host/file?query/path");
275        assertEquals("/file?query/path", url.getFile());
276        assertEquals("/file", url.getPath());
277        assertEquals("query/path", url.getQuery());
278    }
279
280    public void testQuestionMarkInQuery() throws Exception {
281        URL url = new URL("http://host/file?query?another");
282        assertEquals("/file?query?another", url.getFile());
283        assertEquals("/file", url.getPath());
284        assertEquals("query?another", url.getQuery());
285    }
286
287    public void testAtSignInQuery() throws Exception {
288        URL url = new URL("http://host/file?query@at");
289        assertEquals("/file?query@at", url.getFile());
290        assertEquals("/file", url.getPath());
291        assertEquals("query@at", url.getQuery());
292    }
293
294    public void testColonInQuery() throws Exception {
295        URL url = new URL("http://host/file?query:colon");
296        assertEquals("/file?query:colon", url.getFile());
297        assertEquals("/file", url.getPath());
298        assertEquals("query:colon", url.getQuery());
299    }
300
301    public void testQuestionMarkInFragment() throws Exception {
302        URL url = new URL("http://host/file#fragment?query");
303        assertEquals("/file", url.getFile());
304        assertEquals("/file", url.getPath());
305        assertEquals(null, url.getQuery());
306        assertEquals("fragment?query", url.getRef());
307    }
308
309    public void testColonInFragment() throws Exception {
310        URL url = new URL("http://host/file#fragment:80");
311        assertEquals("/file", url.getFile());
312        assertEquals("/file", url.getPath());
313        assertEquals(-1, url.getPort());
314        assertEquals("fragment:80", url.getRef());
315    }
316
317    public void testSlashInFragment() throws Exception {
318        URL url = new URL("http://host/file#fragment/path");
319        assertEquals("/file", url.getFile());
320        assertEquals("/file", url.getPath());
321        assertEquals("fragment/path", url.getRef());
322    }
323
324    public void testSlashInFragmentCombiningConstructor() throws Exception {
325        URL url = new URL("http", "host", "/file#fragment/path");
326        assertEquals("/file", url.getFile());
327        assertEquals("/file", url.getPath());
328        assertEquals("fragment/path", url.getRef());
329    }
330
331    public void testHashInFragment() throws Exception {
332        URL url = new URL("http://host/file#fragment#another");
333        assertEquals("/file", url.getFile());
334        assertEquals("/file", url.getPath());
335        assertEquals("fragment#another", url.getRef());
336    }
337
338    public void testEmptyPort() throws Exception {
339        URL url = new URL("http://host:/");
340        assertEquals(-1, url.getPort());
341    }
342
343    public void testNonNumericPort() throws Exception {
344        try {
345            new URL("http://host:x/");
346            fail();
347        } catch (MalformedURLException expected) {
348        }
349    }
350
351    public void testNegativePort() throws Exception {
352        try {
353            new URL("http://host:-2/");
354            fail();
355        } catch (MalformedURLException expected) {
356        }
357    }
358
359    public void testNegativePortEqualsPlaceholder() throws Exception {
360        try {
361            new URL("http://host:-1/");
362            fail(); // RI fails this
363        } catch (MalformedURLException expected) {
364        }
365    }
366
367    public void testRelativePathOnQuery() throws Exception {
368        URL base = new URL("http://host/file?query/x");
369        URL url = new URL(base, "another");
370        assertEquals("http://host/another", url.toString());
371        assertEquals("/another", url.getFile());
372        assertEquals("/another", url.getPath());
373        assertEquals(null, url.getQuery());
374        assertEquals(null, url.getRef());
375    }
376
377    public void testRelativeFragmentOnQuery() throws Exception {
378        URL base = new URL("http://host/file?query/x#fragment");
379        URL url = new URL(base, "#another");
380        assertEquals("http://host/file?query/x#another", url.toString());
381        assertEquals("/file?query/x", url.getFile());
382        assertEquals("/file", url.getPath());
383        assertEquals("query/x", url.getQuery());
384        assertEquals("another", url.getRef());
385    }
386
387    public void testPathContainsRelativeParts() throws Exception {
388        URL url = new URL("http://host/a/b/../c");
389        assertEquals("http://host/a/c", url.toString()); // RI doesn't canonicalize
390    }
391
392    public void testRelativePathAndFragment() throws Exception {
393        URL base = new URL("http://host/file");
394        assertEquals("http://host/another#fragment", new URL(base, "another#fragment").toString());
395    }
396
397    public void testRelativeParentDirectory() throws Exception {
398        URL base = new URL("http://host/a/b/c");
399        assertEquals("http://host/a/d", new URL(base, "../d").toString());
400    }
401
402    public void testRelativeChildDirectory() throws Exception {
403        URL base = new URL("http://host/a/b/c");
404        assertEquals("http://host/a/b/d/e", new URL(base, "d/e").toString());
405    }
406
407    public void testRelativeRootDirectory() throws Exception {
408        URL base = new URL("http://host/a/b/c");
409        assertEquals("http://host/d", new URL(base, "/d").toString());
410    }
411
412    public void testRelativeFullUrl() throws Exception {
413        URL base = new URL("http://host/a/b/c");
414        assertEquals("http://host2/d/e", new URL(base, "http://host2/d/e").toString());
415        assertEquals("https://host2/d/e", new URL(base, "https://host2/d/e").toString());
416    }
417
418    public void testRelativeDifferentScheme() throws Exception {
419        URL base = new URL("http://host/a/b/c");
420        assertEquals("https://host2/d/e", new URL(base, "https://host2/d/e").toString());
421    }
422
423    public void testRelativeDifferentAuthority() throws Exception {
424        URL base = new URL("http://host/a/b/c");
425        assertEquals("http://another/d/e", new URL(base, "//another/d/e").toString());
426    }
427
428    public void testRelativeWithScheme() throws Exception {
429        URL base = new URL("http://host/a/b/c");
430        assertEquals("http://host/a/b/c", new URL(base, "http:").toString());
431        assertEquals("http://host/", new URL(base, "http:/").toString());
432    }
433
434    public void testMalformedUrlsRefusedByFirefoxAndChrome() throws Exception {
435        URL base = new URL("http://host/a/b/c");
436        assertEquals("http://", new URL(base, "http://").toString()); // fails on RI; path retained
437        assertEquals("http://", new URL(base, "//").toString()); // fails on RI
438        assertEquals("https:", new URL(base, "https:").toString());
439        assertEquals("https:/", new URL(base, "https:/").toString());
440        assertEquals("https://", new URL(base, "https://").toString());
441    }
442
443    public void testRfc1808NormalExamples() throws Exception {
444        URL base = new URL("http://a/b/c/d;p?q");
445        assertEquals("https:h", new URL(base, "https:h").toString());
446        assertEquals("http://a/b/c/g", new URL(base, "g").toString());
447        assertEquals("http://a/b/c/g", new URL(base, "./g").toString());
448        assertEquals("http://a/b/c/g/", new URL(base, "g/").toString());
449        assertEquals("http://a/g", new URL(base, "/g").toString());
450        assertEquals("http://g", new URL(base, "//g").toString());
451        assertEquals("http://a/b/c/d;p?y", new URL(base, "?y").toString()); // RI fails; file lost
452        assertEquals("http://a/b/c/g?y", new URL(base, "g?y").toString());
453        assertEquals("http://a/b/c/d;p?q#s", new URL(base, "#s").toString());
454        assertEquals("http://a/b/c/g#s", new URL(base, "g#s").toString());
455        assertEquals("http://a/b/c/g?y#s", new URL(base, "g?y#s").toString());
456        assertEquals("http://a/b/c/;x", new URL(base, ";x").toString());
457        assertEquals("http://a/b/c/g;x", new URL(base, "g;x").toString());
458        assertEquals("http://a/b/c/g;x?y#s", new URL(base, "g;x?y#s").toString());
459        assertEquals("http://a/b/c/d;p?q", new URL(base, "").toString());
460        assertEquals("http://a/b/c/", new URL(base, ".").toString());
461        assertEquals("http://a/b/c/", new URL(base, "./").toString());
462        assertEquals("http://a/b/", new URL(base, "..").toString());
463        assertEquals("http://a/b/", new URL(base, "../").toString());
464        assertEquals("http://a/b/g", new URL(base, "../g").toString());
465        assertEquals("http://a/", new URL(base, "../..").toString());
466        assertEquals("http://a/", new URL(base, "../../").toString());
467        assertEquals("http://a/g", new URL(base, "../../g").toString());
468    }
469
470    public void testRfc1808AbnormalExampleTooManyDotDotSequences() throws Exception {
471        URL base = new URL("http://a/b/c/d;p?q");
472        assertEquals("http://a/g", new URL(base, "../../../g").toString()); // RI doesn't normalize
473        assertEquals("http://a/g", new URL(base, "../../../../g").toString());
474    }
475
476    public void testRfc1808AbnormalExampleRemoveDotSegments() throws Exception {
477        URL base = new URL("http://a/b/c/d;p?q");
478        assertEquals("http://a/g", new URL(base, "/./g").toString()); // RI doesn't normalize
479        assertEquals("http://a/g", new URL(base, "/../g").toString()); // RI doesn't normalize
480        assertEquals("http://a/b/c/g.", new URL(base, "g.").toString());
481        assertEquals("http://a/b/c/.g", new URL(base, ".g").toString());
482        assertEquals("http://a/b/c/g..", new URL(base, "g..").toString());
483        assertEquals("http://a/b/c/..g", new URL(base, "..g").toString());
484    }
485
486    public void testRfc1808AbnormalExampleNonsensicalDots() throws Exception {
487        URL base = new URL("http://a/b/c/d;p?q");
488        assertEquals("http://a/b/g", new URL(base, "./../g").toString());
489        assertEquals("http://a/b/c/g/", new URL(base, "./g/.").toString());
490        assertEquals("http://a/b/c/g/h", new URL(base, "g/./h").toString());
491        assertEquals("http://a/b/c/h", new URL(base, "g/../h").toString());
492        assertEquals("http://a/b/c/g;x=1/y", new URL(base, "g;x=1/./y").toString());
493        assertEquals("http://a/b/c/y", new URL(base, "g;x=1/../y").toString());
494    }
495
496    public void testRfc1808AbnormalExampleRelativeScheme() throws Exception {
497        URL base = new URL("http://a/b/c/d;p?q");
498        // this result is permitted; strict parsers prefer "http:g"
499        assertEquals("http://a/b/c/g", new URL(base, "http:g").toString());
500    }
501
502    public void testRfc1808AbnormalExampleQueryOrFragmentDots() throws Exception {
503        URL base = new URL("http://a/b/c/d;p?q");
504        assertEquals("http://a/b/c/g?y/./x", new URL(base, "g?y/./x").toString());
505        assertEquals("http://a/b/c/g?y/../x", new URL(base, "g?y/../x").toString());
506        assertEquals("http://a/b/c/g#s/./x", new URL(base, "g#s/./x").toString());
507        assertEquals("http://a/b/c/g#s/../x", new URL(base, "g#s/../x").toString());
508    }
509
510    public void testSquareBracketsInUserInfo() throws Exception {
511        URL url = new URL("http://user:[::1]@host");
512        assertEquals("user:[::1]", url.getUserInfo());
513        assertEquals("host", url.getHost());
514    }
515
516    public void testComposeUrl() throws Exception {
517        URL url = new URL("http", "host", "a");
518        assertEquals("http", url.getProtocol());
519        assertEquals("host", url.getAuthority());
520        assertEquals("host", url.getHost());
521        assertEquals("/a", url.getFile()); // RI fails; doesn't insert '/' separator
522        assertEquals("http://host/a", url.toString()); // fails on RI
523    }
524
525    public void testComposeUrlWithNullHost() throws Exception {
526        URL url = new URL("http", null, "a");
527        assertEquals("http", url.getProtocol());
528        assertEquals(null, url.getAuthority());
529        assertEquals(null, url.getHost());
530        assertEquals("a", url.getFile());
531        assertEquals("http:a", url.toString()); // fails on RI
532    }
533
534    public void testFileUrlExtraLeadingSlashes() throws Exception {
535        URL url = new URL("file:////foo");
536        assertEquals("", url.getAuthority()); // RI returns null
537        assertEquals("//foo", url.getPath());
538        assertEquals("file:////foo", url.toString());
539    }
540
541    public void testFileUrlWithAuthority() throws Exception {
542        URL url = new URL("file://x/foo");
543        assertEquals("x", url.getAuthority());
544        assertEquals("/foo", url.getPath());
545        assertEquals("file://x/foo", url.toString());
546    }
547
548    /**
549     * The RI is not self-consistent on missing authorities, returning either
550     * null or the empty string depending on the number of slashes in the path.
551     * We always treat '//' as the beginning of an authority.
552     */
553    public void testEmptyAuthority() throws Exception {
554        URL url = new URL("http:///foo");
555        assertEquals("", url.getAuthority());
556        assertEquals("/foo", url.getPath());
557        assertEquals("http:///foo", url.toString()); // RI drops '//'
558    }
559
560    public void testHttpUrlExtraLeadingSlashes() throws Exception {
561        URL url = new URL("http:////foo");
562        assertEquals("", url.getAuthority()); // RI returns null
563        assertEquals("//foo", url.getPath());
564        assertEquals("http:////foo", url.toString());
565    }
566
567    public void testFileUrlRelativePath() throws Exception {
568        URL base = new URL("file:a/b/c");
569        assertEquals("file:a/b/d", new URL(base, "d").toString());
570    }
571
572    public void testFileUrlDottedPath() throws Exception {
573        URL url = new URL("file:../a/b");
574        assertEquals("../a/b", url.getPath());
575        assertEquals("file:../a/b", url.toString());
576    }
577
578    public void testParsingDotAsHostname() throws Exception {
579        URL url = new URL("http://./");
580        assertEquals(".", url.getAuthority());
581        assertEquals(".", url.getHost());
582    }
583
584    public void testSquareBracketsWithIPv4() throws Exception {
585        try {
586            new URL("http://[192.168.0.1]/");
587            fail();
588        } catch (MalformedURLException expected) {
589        }
590        URL url = new URL("http", "[192.168.0.1]", "/");
591        assertEquals("[192.168.0.1]", url.getHost());
592    }
593
594    public void testSquareBracketsWithHostname() throws Exception {
595        try {
596            new URL("http://[www.android.com]/");
597            fail();
598        } catch (MalformedURLException expected) {
599        }
600        URL url = new URL("http", "[www.android.com]", "/");
601        assertEquals("[www.android.com]", url.getHost());
602    }
603
604    public void testIPv6WithoutSquareBrackets() throws Exception {
605        try {
606            new URL("http://fe80::1234/");
607            fail();
608        } catch (MalformedURLException expected) {
609        }
610        URL url = new URL("http", "fe80::1234", "/");
611        assertEquals("[fe80::1234]", url.getHost());
612    }
613
614    public void testIpv6WithSquareBrackets() throws Exception {
615        URL url = new URL("http://[::1]:2/");
616        assertEquals("[::1]", url.getHost());
617        assertEquals(2, url.getPort());
618    }
619
620    public void testEqualityWithNoPath() throws Exception {
621        assertFalse(new URL("http://android.com").equals(new URL("http://android.com/")));
622    }
623
624    public void testUrlDoesNotEncodeParts() throws Exception {
625        URL url = new URL("http", "host", 80, "/doc|search?q=green robots#over 6\"");
626        assertEquals("http", url.getProtocol());
627        assertEquals("host:80", url.getAuthority());
628        assertEquals("/doc|search", url.getPath());
629        assertEquals("q=green robots", url.getQuery());
630        assertEquals("over 6\"", url.getRef());
631        assertEquals("http://host:80/doc|search?q=green robots#over 6\"", url.toString());
632    }
633
634    public void testSchemeCaseIsCanonicalized() throws Exception {
635        URL url = new URL("HTTP://host/path");
636        assertEquals("http", url.getProtocol());
637    }
638
639    public void testEmptyAuthorityWithPath() throws Exception {
640        URL url = new URL("http:///path");
641        assertEquals("", url.getAuthority());
642        assertEquals("/path", url.getPath());
643    }
644
645    public void testEmptyAuthorityWithQuery() throws Exception {
646        URL url = new URL("http://?query");
647        assertEquals("", url.getAuthority());
648        assertEquals("", url.getPath());
649        assertEquals("query", url.getQuery());
650    }
651
652    public void testEmptyAuthorityWithFragment() throws Exception {
653        URL url = new URL("http://#fragment");
654        assertEquals("", url.getAuthority());
655        assertEquals("", url.getPath());
656        assertEquals("fragment", url.getRef());
657    }
658
659    public void testCombiningConstructorsMakeRelativePathsAbsolute() throws Exception {
660        assertEquals("/relative", new URL("http", "host", "relative").getPath());
661        assertEquals("/relative", new URL("http", "host", -1, "relative").getPath());
662        assertEquals("/relative", new URL("http", "host", -1, "relative", null).getPath());
663    }
664
665    public void testCombiningConstructorsDoNotMakeEmptyPathsAbsolute() throws Exception {
666        assertEquals("", new URL("http", "host", "").getPath());
667        assertEquals("", new URL("http", "host", -1, "").getPath());
668        assertEquals("", new URL("http", "host", -1, "", null).getPath());
669    }
670
671    public void testPartContainsSpace() throws Exception {
672        try {
673            new URL("ht tp://host/");
674            fail();
675        } catch (MalformedURLException expected) {
676        }
677        assertEquals("user name", new URL("http://user name@host/").getUserInfo());
678        assertEquals("ho st", new URL("http://ho st/").getHost());
679        try {
680            new URL("http://host:80 80/");
681            fail();
682        } catch (MalformedURLException expected) {
683        }
684        assertEquals("/fi le", new URL("http://host/fi le").getFile());
685        assertEquals("que ry", new URL("http://host/file?que ry").getQuery());
686        assertEquals("re f", new URL("http://host/file?query#re f").getRef());
687    }
688
689    // http://code.google.com/p/android/issues/detail?id=37577
690    public void testUnderscore() throws Exception {
691        URL url = new URL("http://a_b.c.d.net/");
692        assertEquals("a_b.c.d.net", url.getAuthority());
693        // The RFC's don't permit underscores in hostnames, but URL accepts them (unlike URI).
694        assertEquals("a_b.c.d.net", url.getHost());
695    }
696
697    // Adding a new test? Consider adding an equivalent test to URITest.java
698}
699