blob: 6e84c24264e6cc23ea0a528d50ac69fc7d5e30fe [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/* @test
25 * @summary Unit test for java.net.URI
26 * @bug 4464135 4505046 4503239 4438319 4991359 4866303
27 * @author Mark Reinhold
28 */
29
30import java.io.ByteArrayInputStream;
31import java.io.ByteArrayOutputStream;
32import java.io.IOException;
33import java.io.ObjectInputStream;
34import java.io.ObjectOutputStream;
35import java.io.PrintStream;
36import java.net.URI;
37import java.net.URISyntaxException;
38import java.net.URL;
39import java.net.MalformedURLException;
40
41
42public class Test {
43
44 static PrintStream out = System.out;
45 static int testCount = 0;
46
47 // Properties that we check
48 static final int PARSEFAIL = 1 << 0;
49 static final int SCHEME = 1 << 1;
50 static final int SSP = 1 << 2;
51 static final int SSP_D = 1 << 3; // Decoded form
52 static final int OPAQUEPART = 1 << 4; // SSP, and URI is opaque
53 static final int USERINFO = 1 << 5;
54 static final int USERINFO_D = 1 << 6; // Decoded form
55 static final int HOST = 1 << 7;
56 static final int PORT = 1 << 8;
57 static final int REGISTRY = 1 << 9;
58 static final int REGISTRY_D = 1 << 10; // Decoded form
59 static final int PATH = 1 << 11;
60 static final int PATH_D = 1 << 12; // Decoded form
61 static final int QUERY = 1 << 13;
62 static final int QUERY_D = 1 << 14; // Decoded form
63 static final int FRAGMENT = 1 << 15;
64 static final int FRAGMENT_D = 1 << 16; // Decoded form
65 static final int TOASCII = 1 << 17;
66 static final int IDENT_STR = 1 << 18; // Identities
67 static final int IDENT_URI1 = 1 << 19;
68 static final int IDENT_URI3 = 1 << 20;
69 static final int IDENT_URI5 = 1 << 21;
70 static final int IDENT_URI7 = 1 << 22;
71 static final int TOSTRING = 1 << 23;
72
73 String input;
74 URI uri = null;
75 URI originalURI;
76 URI base = null; // Base for resolution/relativization
77 String op = null; // Op performed if uri != originalURI
78 int checked = 0; // Mask for checked properties
79 int failed = 0; // Mask for failed properties
80 Exception exc = null;
81
82 private Test(String s) {
83 testCount++;
84 input = s;
85 try {
86 uri = new URI(s);
87 } catch (URISyntaxException x) {
88 exc = x;
89 }
90 originalURI = uri;
91 }
92
93 static Test test(String s) {
94 return new Test(s);
95 }
96
97 private Test(String s, String u, String h, int n,
98 String p, String q, String f)
99 {
100 testCount++;
101 try {
102 uri = new URI(s, u, h, n, p, q, f);
103 } catch (URISyntaxException x) {
104 exc = x;
105 input = x.getInput();
106 }
107 if (uri != null)
108 input = uri.toString();
109 originalURI = uri;
110 }
111
112 static Test test(String s, String u, String h, int n,
113 String p, String q, String f) {
114 return new Test(s, u, h, n, p, q, f);
115 }
116
117 private Test(String s, String a,
118 String p, String q, String f)
119 {
120 testCount++;
121 try {
122 uri = new URI(s, a, p, q, f);
123 } catch (URISyntaxException x) {
124 exc = x;
125 input = x.getInput();
126 }
127 if (uri != null)
128 input = uri.toString();
129 originalURI = uri;
130 }
131
132 static Test test(String s, String a,
133 String p, String q, String f) {
134 return new Test(s, a, p, q, f);
135 }
136
137 private Test(String s, String h, String p, String f) {
138 testCount++;
139 try {
140 uri = new URI(s, h, p, f);
141 } catch (URISyntaxException x) {
142 exc = x;
143 input = x.getInput();
144 }
145 if (uri != null)
146 input = uri.toString();
147 originalURI = uri;
148 }
149
150 static Test test(String s, String h, String p, String f) {
151 return new Test(s, h, p, f);
152 }
153
154 private Test(String s, String ssp, String f) {
155 testCount++;
156 try {
157 uri = new URI(s, ssp, f);
158 } catch (URISyntaxException x) {
159 exc = x;
160 input = x.getInput();
161 }
162 if (uri != null)
163 input = uri.toString();
164 originalURI = uri;
165 }
166
167 static Test test(String s, String ssp, String f) {
168 return new Test(s, ssp, f);
169 }
170
171 private Test(String s, boolean xxx) {
172 testCount++;
173 try {
174 uri = URI.create(s);
175 } catch (IllegalArgumentException x) {
176 exc = x;
177 }
178 if (uri != null)
179 input = uri.toString();
180 originalURI = uri;
181 }
182
183 static Test testCreate(String s) {
184 return new Test(s, false);
185 }
186
187 boolean parsed() {
188 return uri != null;
189 }
190
191 boolean resolved() {
192 return base != null;
193 }
194
195 URI uri() {
196 return uri;
197 }
198
199
200 // Operations on Test instances
201 //
202 // These are short so as to make test cases compact.
203 //
204 // s Scheme
205 // sp Scheme-specific part
206 // spd Scheme-specific part, decoded
207 // o Opaque part (isOpaque() && ssp matches)
208 // g reGistry (authority matches, and host is not defined)
209 // gd reGistry, decoded
210 // u User info
211 // ud User info, decoded
212 // h Host
213 // n port Number
214 // p Path
215 // pd Path, decoded
216 // q Query
217 // qd Query, decoded
218 // f Fragment
219 // fd Fragment, decoded
220 //
221 // rslv Resolve against given base
222 // rtvz Relativize
223 // psa Parse server Authority
224 // norm Normalize
225 // ta ASCII form
226 //
227 // x Check that parse failed as expected
228 // z End -- ensure that unchecked components are null
229
230 private boolean check1(int prop) {
231 checked |= prop;
232 if (!parsed()) {
233 failed |= prop;
234 return false;
235 }
236 return true;
237 }
238
239 private void check2(String s, String ans, int prop) {
240 if ((s == null) || !s.equals(ans))
241 failed |= prop;
242 }
243
244 Test s(String s) {
245 if (check1(SCHEME)) check2(uri.getScheme(), s, SCHEME);
246 return this;
247 }
248
249 Test u(String s) {
250 if (check1(USERINFO)) check2(uri.getRawUserInfo(), s, USERINFO);
251 return this;
252 }
253
254 Test ud(String s) {
255 if (check1(USERINFO_D)) {
256 check2(uri.getUserInfo(), s, USERINFO_D);
257 }
258 return this;
259 }
260
261 Test h(String s) {
262 if (check1(HOST)) check2(uri.getHost(), s, HOST);
263 return this;
264 }
265
266 Test g(String s) {
267 if (check1(REGISTRY)) {
268 if (uri.getHost() != null)
269 failed |= REGISTRY;
270 else
271 check2(uri.getRawAuthority(), s, REGISTRY);
272 }
273 return this;
274 }
275
276 Test gd(String s) {
277 if (check1(REGISTRY_D)) {
278 if (uri.getHost() != null)
279 failed |= REGISTRY_D;
280 else
281 check2(uri.getAuthority(), s, REGISTRY_D);
282 }
283 return this;
284 }
285
286 Test n(int n) {
287 checked |= PORT;
288 if (!parsed() || (uri.getPort() != n))
289 failed |= PORT;
290 return this;
291 }
292
293 Test p(String s) {
294 if (check1(PATH)) check2(uri.getRawPath(), s, PATH);
295 return this;
296 }
297
298 Test pd(String s) {
299 if (check1(PATH_D)) check2(uri.getPath(), s, PATH_D);
300 return this;
301 }
302
303 Test o(String s) {
304 if (check1(OPAQUEPART)) {
305 if (!uri.isOpaque())
306 failed |= OPAQUEPART;
307 else
308 check2(uri.getSchemeSpecificPart(), s, OPAQUEPART);
309 }
310 return this;
311 }
312
313 Test sp(String s) {
314 if (check1(SSP)) check2(uri.getRawSchemeSpecificPart(), s, SSP);
315 return this;
316 }
317
318 Test spd(String s) {
319 if (check1(SSP_D)) check2(uri.getSchemeSpecificPart(), s, SSP_D);
320 return this;
321 }
322
323 Test q(String s) {
324 if (check1(QUERY)) check2(uri.getRawQuery(), s, QUERY);
325 return this;
326 }
327
328 Test qd(String s) {
329 if (check1(QUERY_D)) check2(uri.getQuery(), s, QUERY_D);
330 return this;
331 }
332
333 Test f(String s) {
334 if (check1(FRAGMENT)) check2(uri.getRawFragment(), s, FRAGMENT);
335 return this;
336 }
337
338 Test fd(String s) {
339 if (check1(FRAGMENT_D)) check2(uri.getFragment(), s, FRAGMENT_D);
340 return this;
341 }
342
343 Test ta(String s) {
344 if (check1(TOASCII))
345 check2(uri.toASCIIString(), s, TOASCII);
346 return this;
347 }
348
349 Test ts(String s) {
350 if (check1(TOSTRING))
351 check2(uri.toString(), s, TOSTRING);
352 return this;
353 }
354
355 Test x() {
356 checked |= PARSEFAIL;
357 if (parsed())
358 failed |= PARSEFAIL;
359 return this;
360 }
361
362 Test rslv(URI base) {
363 if (!parsed())
364 return this;
365 this.base = base;
366 op = "rslv";
367 URI u = uri;
368 uri = null;
369 try {
370 this.uri = base.resolve(u);
371 } catch (IllegalArgumentException x) {
372 exc = x;
373 }
374 checked = 0;
375 failed = 0;
376 return this;
377 }
378
379 Test norm() {
380 if (!parsed())
381 return this;
382 op = "norm";
383 uri = uri.normalize();
384 return this;
385 }
386
387 Test rtvz(URI base) {
388 if (!parsed())
389 return this;
390 this.base = base;
391 op = "rtvz";
392 uri = base.relativize(uri);
393 checked = 0;
394 failed = 0;
395 return this;
396 }
397
398 Test psa() {
399 try {
400 uri.parseServerAuthority();
401 } catch (URISyntaxException x) {
402 exc = x;
403 uri = null;
404 }
405 checked = 0;
406 failed = 0;
407 return this;
408 }
409
410 private void checkEmpty(String s, int prop) {
411 if (((checked & prop) == 0) && (s != null))
412 failed |= prop;
413 }
414
415 // Check identity for the seven-argument URI constructor
416 //
417 void checkURI7() {
418 // Only works on hierarchical URIs
419 if (uri.isOpaque())
420 return;
421 // Only works with server-based authorities
422 if ((uri.getAuthority() == null)
423 != ((uri.getUserInfo() == null) && (uri.getHost() == null)))
424 return;
425 // Not true if non-US-ASCII chars are encoded unnecessarily
426 if (uri.getPath().indexOf('\u20AC') >= 0)
427 return;
428 try {
429 URI u2 = new URI(uri.getScheme(), uri.getUserInfo(),
430 uri.getHost(), uri.getPort(), uri.getPath(),
431 uri.getQuery(), uri.getFragment());
432 if (!uri.equals(u2))
433 failed |= IDENT_URI7;
434 } catch (URISyntaxException x) {
435 failed |= IDENT_URI7;
436 }
437 }
438
439 // Check identity for the five-argument URI constructor
440 //
441 void checkURI5() {
442 // Only works on hierarchical URIs
443 if (uri.isOpaque())
444 return;
445 try {
446 URI u2 = new URI(uri.getScheme(), uri.getAuthority(),
447 uri.getPath(), uri.getQuery(), uri.getFragment());
448 if (!uri.equals(u2))
449 failed |= IDENT_URI5;
450 } catch (URISyntaxException x) {
451 failed |= IDENT_URI5;
452 }
453 }
454
455 // Check identity for the three-argument URI constructor
456 //
457 void checkURI3() {
458 try {
459 URI u2 = new URI(uri.getScheme(),
460 uri.getSchemeSpecificPart(),
461 uri.getFragment());
462 if (!uri.equals(u2))
463 failed |= IDENT_URI3;
464 } catch (URISyntaxException x) {
465 failed |= IDENT_URI3;
466 }
467 }
468
469 // Check all identities mentioned in the URI class specification
470 //
471 void checkIdentities() {
472 if (input != null) {
473 if (!uri.toString().equals(input))
474 failed |= IDENT_STR;
475 }
476 try {
477 if (!(new URI(uri.toString())).equals(uri))
478 failed |= IDENT_URI1;
479 } catch (URISyntaxException x) {
480 failed |= IDENT_URI1;
481 }
482
483 // Remaining identities fail if "//" given but authority is undefined
484 if ((uri.getAuthority() == null)
485 && (uri.getSchemeSpecificPart() != null)
486 && (uri.getSchemeSpecificPart().startsWith("///")
487 || uri.getSchemeSpecificPart().startsWith("//?")
488 || uri.getSchemeSpecificPart().equals("//")))
489 return;
490
491 // Remaining identities fail if ":" given but port is undefined
492 if ((uri.getHost() != null)
493 && (uri.getAuthority() != null)
494 && (uri.getAuthority().equals(uri.getHost() + ":")))
495 return;
496
497 // Remaining identities fail if non-US-ASCII chars are encoded
498 // unnecessarily
499 if ((uri.getPath() != null) && uri.getPath().indexOf('\u20AC') >= 0)
500 return;
501
502 checkURI3();
503 checkURI5();
504 checkURI7();
505 }
506
507 // Check identities, check that unchecked component properties are not
508 // defined, and report any failures
509 //
510 Test z() {
511 if (!parsed()) {
512 report();
513 return this;
514 }
515
516 if (op == null)
517 checkIdentities();
518
519 // Check that unchecked components are undefined
520 checkEmpty(uri.getScheme(), SCHEME);
521 checkEmpty(uri.getUserInfo(), USERINFO);
522 checkEmpty(uri.getHost(), HOST);
523 if (((checked & PORT) == 0) && (uri.getPort() != -1)) failed |= PORT;
524 checkEmpty(uri.getPath(), PATH);
525 checkEmpty(uri.getQuery(), QUERY);
526 checkEmpty(uri.getFragment(), FRAGMENT);
527
528 // Report failures
529 report();
530 return this;
531 }
532
533
534 // Summarization and reporting
535
536 static void header(String s) {
537 out.println();
538 out.println();
539 out.println("-- " + s + " --");
540 }
541
542 static void show(String prefix, URISyntaxException x) {
543 out.println(uquote(x.getInput()));
544 if (x.getIndex() >= 0) {
545 for (int i = 0; i < x.getIndex(); i++) {
546 if (x.getInput().charAt(i) >= '\u0080')
547 out.print(" "); // Skip over \u1234
548 else
549 out.print(" ");
550 }
551 out.println("^");
552 }
553 out.println(prefix + ": " + x.getReason());
554 }
555
556 private void summarize() {
557 out.println();
558 StringBuffer sb = new StringBuffer();
559 if (input.length() == 0)
560 sb.append("\"\"");
561 else
562 sb.append(input);
563 if (base != null) {
564 sb.append(" ");
565 sb.append(base);
566 }
567 if (!parsed()) {
568 String s = (((checked & PARSEFAIL) != 0)
569 ? "Correct exception" : "UNEXPECTED EXCEPTION");
570 if (exc instanceof URISyntaxException)
571 show(s, (URISyntaxException)exc);
572 else {
573 out.println(uquote(sb.toString()));
574 out.print(s + ": ");
575 exc.printStackTrace(out);
576 }
577 } else {
578 if (uri != originalURI) {
579 sb.append(" ");
580 sb.append(op);
581 sb.append(" --> ");
582 sb.append(uri);
583 }
584 out.println(uquote(sb.toString()));
585 }
586 }
587
588 public static String uquote(String str) {
589 if (str == null)
590 return str;
591 StringBuffer sb = new StringBuffer();
592 int n = str.length();
593 for (int i = 0; i < n; i++) {
594 char c = str.charAt(i);
595 if ((c >= ' ') && (c < 0x7f)) {
596 sb.append(c);
597 continue;
598 }
599 sb.append("\\u");
600 String s = Integer.toHexString(c).toUpperCase();
601 while (s.length() < 4)
602 s = "0" + s;
603 sb.append(s);
604 }
605 return sb.toString();
606 }
607
608 static void show(String n, String v) {
609 out.println(" " + n
610 + " = ".substring(n.length())
611 + uquote(v));
612 }
613
614 static void show(String n, String v, String vd) {
615 if ((v == null) || v.equals(vd))
616 show(n, v);
617 else {
618 out.println(" " + n
619 + " = ".substring(n.length())
620 + uquote(v)
621 + " = " + uquote(vd));
622 }
623 }
624
625 public static void show(URI u) {
626 show("opaque", "" + u.isOpaque());
627 show("scheme", u.getScheme());
628 show("ssp", u.getRawSchemeSpecificPart(), u.getSchemeSpecificPart());
629 show("authority", u.getRawAuthority(), u.getAuthority());
630 show("userinfo", u.getRawUserInfo(), u.getUserInfo());
631 show("host", u.getHost());
632 show("port", "" + u.getPort());
633 show("path", u.getRawPath(), u.getPath());
634 show("query", u.getRawQuery(), u.getQuery());
635 show("fragment", u.getRawFragment(), u.getFragment());
636 if (!u.toString().equals(u.toASCIIString()))
637 show("toascii", u.toASCIIString());
638 }
639
640 private void report() {
641 summarize();
642 if (failed == 0) return;
643 StringBuffer sb = new StringBuffer();
644 sb.append("FAIL:");
645 if ((failed & PARSEFAIL) != 0) sb.append(" parsefail");
646 if ((failed & SCHEME) != 0) sb.append(" scheme");
647 if ((failed & SSP) != 0) sb.append(" ssp");
648 if ((failed & OPAQUEPART) != 0) sb.append(" opaquepart");
649 if ((failed & USERINFO) != 0) sb.append(" userinfo");
650 if ((failed & USERINFO_D) != 0) sb.append(" userinfod");
651 if ((failed & HOST) != 0) sb.append(" host");
652 if ((failed & PORT) != 0) sb.append(" port");
653 if ((failed & REGISTRY) != 0) sb.append(" registry");
654 if ((failed & PATH) != 0) sb.append(" path");
655 if ((failed & PATH_D) != 0) sb.append(" pathd");
656 if ((failed & QUERY) != 0) sb.append(" query");
657 if ((failed & QUERY_D) != 0) sb.append(" queryd");
658 if ((failed & FRAGMENT) != 0) sb.append(" fragment");
659 if ((failed & FRAGMENT_D) != 0) sb.append(" fragmentd");
660 if ((failed & TOASCII) != 0) sb.append(" toascii");
661 if ((failed & IDENT_STR) != 0) sb.append(" ident-str");
662 if ((failed & IDENT_URI1) != 0) sb.append(" ident-uri1");
663 if ((failed & IDENT_URI3) != 0) sb.append(" ident-uri3");
664 if ((failed & IDENT_URI5) != 0) sb.append(" ident-uri5");
665 if ((failed & IDENT_URI7) != 0) sb.append(" ident-uri7");
666 if ((failed & TOSTRING) != 0) sb.append(" tostring");
667 out.println(sb.toString());
668 if (uri != null) show(uri);
669 throw new RuntimeException("Test failed");
670 }
671
672
673
674 // -- Tests --
675
676 static void rfc2396() {
677
678
679 header("RFC2396: Basic examples");
680
681 test("ftp://ftp.is.co.za/rfc/rfc1808.txt")
682 .s("ftp").h("ftp.is.co.za").p("/rfc/rfc1808.txt").z();
683
684 test("gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles")
685 .s("gopher").h("spinaltap.micro.umn.edu")
686 .p("/00/Weather/California/Los%20Angeles").z();
687
688 test("http://www.math.uio.no/faq/compression-faq/part1.html")
689 .s("http").h("www.math.uio.no").p("/faq/compression-faq/part1.html").z();
690
691 test("mailto:mduerst@ifi.unizh.ch")
692 .s("mailto").o("mduerst@ifi.unizh.ch").z();
693
694 test("news:comp.infosystems.www.servers.unix")
695 .s("news").o("comp.infosystems.www.servers.unix").z();
696
697 test("telnet://melvyl.ucop.edu/")
698 .s("telnet").h("melvyl.ucop.edu").p("/").z();
699
700 test("http://www.w3.org/Addressing/")
701 .s("http").h("www.w3.org").p("/Addressing/").z();
702
703 test("ftp://ds.internic.net/rfc/")
704 .s("ftp").h("ds.internic.net").p("/rfc/").z();
705
706 test("http://www.ics.uci.edu/pub/ietf/uri/historical.html#WARNING")
707 .s("http").h("www.ics.uci.edu").p("/pub/ietf/uri/historical.html")
708 .f("WARNING").z();
709
710 test("http://www.ics.uci.edu/pub/ietf/uri/#Related")
711 .s("http").h("www.ics.uci.edu").p("/pub/ietf/uri/")
712 .f("Related").z();
713
714
715 header("RFC2396: Normal relative-URI examples (appendix C)");
716
717 URI base = (test("http://a/b/c/d;p?q")
718 .s("http").h("a").p("/b/c/d;p").q("q").z().uri());
719
720 // g:h g:h
721 test("g:h")
722 .s("g").o("h").z()
723 .rslv(base).s("g").o("h").z();
724
725 // g http://a/b/c/g
726 test("g")
727 .p("g").z()
728 .rslv(base).s("http").h("a").p("/b/c/g").z();
729
730 // ./g http://a/b/c/g
731 test("./g")
732 .p("./g").z()
733 .rslv(base).s("http").h("a").p("/b/c/g").z();
734
735 // g/ http://a/b/c/g/
736 test("g/")
737 .p("g/").z()
738 .rslv(base).s("http").h("a").p("/b/c/g/").z();
739
740 // /g http://a/g
741 test("/g")
742 .p("/g").z()
743 .rslv(base).s("http").h("a").p("/g").z();
744
745 // //g http://g
746 test("//g")
747 .h("g").p("").z()
748 .rslv(base).s("http").h("g").p("").z();
749
750 // ?y http://a/b/c/?y
751 test("?y")
752 .p("").q("y").z()
753 .rslv(base).s("http").h("a").p("/b/c/").q("y").z();
754
755 // g?y http://a/b/c/g?y
756 test("g?y")
757 .p("g").q("y").z()
758 .rslv(base).s("http").h("a").p("/b/c/g").q("y").z();
759
760 // #s (current document)#s
761 // DEVIATION: Lone fragment parses as relative URI with empty path
762 test("#s")
763 .p("").f("s").z()
764 .rslv(base).s("http").h("a").p("/b/c/d;p").f("s").q("q").z();
765
766 // g#s http://a/b/c/g#s
767 test("g#s")
768 .p("g").f("s").z()
769 .rslv(base).s("http").h("a").p("/b/c/g").f("s").z();
770
771 // g?y#s http://a/b/c/g?y#s
772 test("g?y#s")
773 .p("g").q("y").f("s").z()
774 .rslv(base).s("http").h("a").p("/b/c/g").q("y").f("s").z();
775
776 // ;x http://a/b/c/;x
777 test(";x")
778 .p(";x").z()
779 .rslv(base).s("http").h("a").p("/b/c/;x").z();
780
781 // g;x http://a/b/c/g;x
782 test("g;x")
783 .p("g;x").z()
784 .rslv(base).s("http").h("a").p("/b/c/g;x").z();
785
786 // g;x?y#s http://a/b/c/g;x?y#s
787 test("g;x?y#s")
788 .p("g;x").q("y").f("s").z()
789 .rslv(base).s("http").h("a").p("/b/c/g;x").q("y").f("s").z();
790
791 // . http://a/b/c/
792 test(".")
793 .p(".").z()
794 .rslv(base).s("http").h("a").p("/b/c/").z();
795
796 // ./ http://a/b/c/
797 test("./")
798 .p("./").z()
799 .rslv(base).s("http").h("a").p("/b/c/").z();
800
801 // .. http://a/b/
802 test("..")
803 .p("..").z()
804 .rslv(base).s("http").h("a").p("/b/").z();
805
806 // ../ http://a/b/
807 test("../")
808 .p("../").z()
809 .rslv(base).s("http").h("a").p("/b/").z();
810
811 // ../g http://a/b/g
812 test("../g")
813 .p("../g").z()
814 .rslv(base).s("http").h("a").p("/b/g").z();
815
816 // ../.. http://a/
817 test("../..")
818 .p("../..").z()
819 .rslv(base).s("http").h("a").p("/").z();
820
821 // ../../ http://a/
822 test("../../")
823 .p("../../").z()
824 .rslv(base).s("http").h("a").p("/").z();
825
826 // ../../g http://a/g
827 test("../../g")
828 .p("../../g").z()
829 .rslv(base).s("http").h("a").p("/g").z();
830
831
832 header("RFC2396: Abnormal relative-URI examples (appendix C)");
833
834 // ../../../g = http://a/../g
835 test("../../../g")
836 .p("../../../g").z()
837 .rslv(base).s("http").h("a").p("/../g").z();
838
839 // ../../../../g = http://a/../../g
840 test("../../../../g")
841 .p("../../../../g").z()
842 .rslv(base).s("http").h("a").p("/../../g").z();
843
844
845 // /./g = http://a/./g
846 test("/./g")
847 .p("/./g").z()
848 .rslv(base).s("http").h("a").p("/./g").z();
849
850 // /../g = http://a/../g
851 test("/../g")
852 .p("/../g").z()
853 .rslv(base).s("http").h("a").p("/../g").z();
854
855 // g. = http://a/b/c/g.
856 test("g.")
857 .p("g.").z()
858 .rslv(base).s("http").h("a").p("/b/c/g.").z();
859
860 // .g = http://a/b/c/.g
861 test(".g")
862 .p(".g").z()
863 .rslv(base).s("http").h("a").p("/b/c/.g").z();
864
865 // g.. = http://a/b/c/g..
866 test("g..")
867 .p("g..").z()
868 .rslv(base).s("http").h("a").p("/b/c/g..").z();
869
870 // ..g = http://a/b/c/..g
871 test("..g")
872 .p("..g").z()
873 .rslv(base).s("http").h("a").p("/b/c/..g").z();
874
875 // ./../g = http://a/b/g
876 test("./../g")
877 .p("./../g").z()
878 .rslv(base).s("http").h("a").p("/b/g").z();
879
880 // ./g/. = http://a/b/c/g/
881 test("./g/.")
882 .p("./g/.").z()
883 .rslv(base).s("http").h("a").p("/b/c/g/").z();
884
885 // g/./h = http://a/b/c/g/h
886 test("g/./h")
887 .p("g/./h").z()
888 .rslv(base).s("http").h("a").p("/b/c/g/h").z();
889
890 // g/../h = http://a/b/c/h
891 test("g/../h")
892 .p("g/../h").z()
893 .rslv(base).s("http").h("a").p("/b/c/h").z();
894
895 // g;x=1/./y = http://a/b/c/g;x=1/y
896 test("g;x=1/./y")
897 .p("g;x=1/./y").z()
898 .rslv(base).s("http").h("a").p("/b/c/g;x=1/y").z();
899
900 // g;x=1/../y = http://a/b/c/y
901 test("g;x=1/../y")
902 .p("g;x=1/../y").z()
903 .rslv(base).s("http").h("a").p("/b/c/y").z();
904
905 // g?y/./x = http://a/b/c/g?y/./x
906 test("g?y/./x")
907 .p("g").q("y/./x").z()
908 .rslv(base).s("http").h("a").p("/b/c/g").q("y/./x").z();
909
910 // g?y/../x = http://a/b/c/g?y/../x
911 test("g?y/../x")
912 .p("g").q("y/../x").z()
913 .rslv(base).s("http").h("a").p("/b/c/g").q("y/../x").z();
914
915 // g#s/./x = http://a/b/c/g#s/./x
916 test("g#s/./x")
917 .p("g").f("s/./x").z()
918 .rslv(base).s("http").h("a").p("/b/c/g").f("s/./x").z();
919
920 // g#s/../x = http://a/b/c/g#s/../x
921 test("g#s/../x")
922 .p("g").f("s/../x").z()
923 .rslv(base).s("http").h("a").p("/b/c/g").f("s/../x").z();
924
925 // http:g = http:g
926 test("http:g")
927 .s("http").o("g").z()
928 .rslv(base).s("http").o("g").z();
929
930 }
931
932
933 static void ip() {
934
935 header("IP addresses");
936
937 test("http://1.2.3.4:5")
938 .s("http").h("1.2.3.4").n(5).p("").z();
939
940 // From RFC2732
941
942 test("http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html")
943 .s("http").h("[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]")
944 .n(80).p("/index.html").z();
945
946 test("http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:10%12]:80/index.html")
947 .s("http").h("[FEDC:BA98:7654:3210:FEDC:BA98:7654:10%12]")
948 .n(80).p("/index.html").z();
949
950 test("http://[1080:0:0:0:8:800:200C:417A]/index.html")
951 .s("http").h("[1080:0:0:0:8:800:200C:417A]").p("/index.html").z();
952
953 test("http://[1080:0:0:0:8:800:200C:417A%1]/index.html")
954 .s("http").h("[1080:0:0:0:8:800:200C:417A%1]").p("/index.html").z();
955
956 test("http://[3ffe:2a00:100:7031::1]")
957 .s("http").h("[3ffe:2a00:100:7031::1]").p("").z();
958
959 test("http://[1080::8:800:200C:417A]/foo")
960 .s("http").h("[1080::8:800:200C:417A]").p("/foo").z();
961
962 test("http://[::192.9.5.5]/ipng")
963 .s("http").h("[::192.9.5.5]").p("/ipng").z();
964
965 test("http://[::192.9.5.5%interface]/ipng")
966 .s("http").h("[::192.9.5.5%interface]").p("/ipng").z();
967
968 test("http://[::FFFF:129.144.52.38]:80/index.html")
969 .s("http").h("[::FFFF:129.144.52.38]").n(80).p("/index.html").z();
970
971 test("http://[2010:836B:4179::836B:4179]")
972 .s("http").h("[2010:836B:4179::836B:4179]").p("").z();
973
974 // From RFC2373
975
976 test("http://[FF01::101]")
977 .s("http").h("[FF01::101]").p("").z();
978
979 test("http://[::1]")
980 .s("http").h("[::1]").p("").z();
981
982 test("http://[::]")
983 .s("http").h("[::]").p("").z();
984
985 test("http://[::%hme0]")
986 .s("http").h("[::%hme0]").p("").z();
987
988 test("http://[0:0:0:0:0:0:13.1.68.3]")
989 .s("http").h("[0:0:0:0:0:0:13.1.68.3]").p("").z();
990
991 test("http://[0:0:0:0:0:FFFF:129.144.52.38]")
992 .s("http").h("[0:0:0:0:0:FFFF:129.144.52.38]").p("").z();
993
994 test("http://[0:0:0:0:0:FFFF:129.144.52.38%33]")
995 .s("http").h("[0:0:0:0:0:FFFF:129.144.52.38%33]").p("").z();
996
997 test("http://[0:0:0:0:0:ffff:1.2.3.4]")
998 .s("http").h("[0:0:0:0:0:ffff:1.2.3.4]").p("").z();
999
1000 test("http://[::13.1.68.3]")
1001 .s("http").h("[::13.1.68.3]").p("").z();
1002
1003 // Optional IPv6 brackets in constructors
1004
1005 test("s", null, "1:2:3:4:5:6:7:8", -1, null, null, null)
1006 .s("s").h("[1:2:3:4:5:6:7:8]").p("").z();
1007
1008 test("s", null, "[1:2:3:4:5:6:7:8]", -1, null, null, null)
1009 .s("s").h("[1:2:3:4:5:6:7:8]").p("").z();
1010
1011 test("s", null, "[1:2:3:4:5:6:7:8]", -1, null, null, null)
1012 .s("s").h("[1:2:3:4:5:6:7:8]").p("").z();
1013
1014 test("s", "1:2:3:4:5:6:7:8", null, null)
1015 .s("s").h("[1:2:3:4:5:6:7:8]").p("").z();
1016
1017 test("s", "1:2:3:4:5:6:7:8%hme0", null, null)
1018 .s("s").h("[1:2:3:4:5:6:7:8%hme0]").p("").z();
1019
1020 test("s", "1:2:3:4:5:6:7:8%1", null, null)
1021 .s("s").h("[1:2:3:4:5:6:7:8%1]").p("").z();
1022
1023 test("s", "[1:2:3:4:5:6:7:8]", null, null)
1024 .s("s").h("[1:2:3:4:5:6:7:8]").p("").z();
1025
1026 test("s", "[1:2:3:4:5:6:7:8]", null, null, null)
1027 .s("s").h("[1:2:3:4:5:6:7:8]").p("").z();
1028
1029 test("s", "1:2:3:4:5:6:7:8", null, null, null)
1030 .s("s").g("1:2:3:4:5:6:7:8").p("").z();
1031
1032 // Error cases
1033
1034 test("http://[ff01:234/foo").x().z();
1035 test("http://[ff01:234:zzz]/foo").x().z();
1036 test("http://[foo]").x().z();
1037 test("http://[]").x().z();
1038 test("http://[129.33.44.55]").x().z();
1039 test("http://[ff:ee:dd:cc:bb::aa:9:8]").x().z();
1040 test("http://[fffff::1]").x().z();
1041 test("http://[ff::ee::8]").x().z();
1042 test("http://[1:2:3:4::5:6:7:8]").x().z();
1043 test("http://[1:2]").x().z();
1044 test("http://[1:2:3:4:5:6:7:8:9]").x().z();
1045 test("http://[1:2:3:4:5:6:7:8%]").x().z();
1046 test("http://[1:2:3:4:5:6:7:8%!/]").x().z();
1047 test("http://[::1.2.3.300]").x().z();
1048 test("http://1.2.3").psa().x().z();
1049 test("http://1.2.3.300").psa().x().z();
1050 test("http://1.2.3.4.5").psa().x().z();
1051 test("http://[1.2.3.4:5]").x().z();
1052 test("http://1:2:3:4:5:6:7:8").psa().x().z();
1053
1054 // Test hostnames that might initially look like IPv4 addresses
1055
1056 test("s://1.2.3.com").psa().s("s").h("1.2.3.com").p("").z();
1057 test("s://1.2.3.4me.com").psa().s("s").h("1.2.3.4me.com").p("").z();
1058
1059 test("s://7up.com").psa().s("s").h("7up.com").p("").z();
1060 test("s://7up.com/p").psa().s("s").h("7up.com").p("/p").z();
1061 test("s://7up").psa().s("s").h("7up").p("").z();
1062 test("s://7up/p").psa().s("s").h("7up").p("/p").z();
1063 test("s://7up.").psa().s("s").h("7up.").p("").z();
1064 test("s://7up./p").psa().s("s").h("7up.").p("/p").z();
1065 }
1066
1067
1068 static void misc() throws URISyntaxException {
1069
1070 URI base = new URI("s://h/a/b");
1071 URI rbase = new URI("a/b/c/d");
1072
1073
1074 header("Corner cases");
1075
1076 // The empty URI parses as a relative URI with an empty path
1077 test("").p("").z()
1078 .rslv(base).s("s").h("h").p("/a/").z();
1079
1080 // Resolving solo queries and fragments
1081 test("#f").p("").f("f").z()
1082 .rslv(base).s("s").h("h").p("/a/b").f("f").z();
1083 test("?q").p("").q("q").z()
1084 .rslv(base).s("s").h("h").p("/a/").q("q").z();
1085
1086 // Fragment is not part of ssp
1087 test("p#f").p("p").f("f").sp("p").z();
1088 test("s:p#f").s("s").o("p").f("f").z();
1089 test("p#f")
1090 .rslv(base).s("s").h("h").p("/a/p").f("f").sp("//h/a/p").z();
1091 test("").p("").sp("").z();
1092
1093
1094 header("Emptiness");
1095
1096 // Components that may be empty
1097 test("///p").p("/p").z(); // Authority (w/ path)
1098 test("//@h/p").u("").h("h").p("/p").z(); // User info
1099 test("//h:/p").h("h").p("/p").z(); // Port
1100 test("//h").h("h").p("").z(); // Path
1101 test("//h?q").h("h").p("").q("q").z(); // Path (w/query)
1102 test("//?q").p("").q("q").z(); // Authority (w/query)
1103 test("//#f").p("").f("f").z(); // Authority (w/fragment)
1104 test("p?#").p("p").q("").f("").z(); // Query & fragment
1105
1106 // Components that may not be empty
1107 test(":").x().z(); // Scheme
1108 test("x:").x().z(); // Hier/opaque
1109 test("//").x().z(); // Authority (w/o path)
1110
1111
1112 header("Resolution, normalization, and relativization");
1113
1114 // Resolving relative paths
1115 test("../e/f").p("../e/f").z()
1116 .rslv(rbase).p("a/b/e/f").z();
1117 test("../../../../d").p("../../../../d").z()
1118 .rslv(rbase).p("../d").z();
1119 test("../../../d:e").p("../../../d:e").z()
1120 .rslv(rbase).p("./d:e").z();
1121 test("../../../d:e/f").p("../../../d:e/f").z()
1122 .rslv(rbase).p("./d:e/f").z();
1123
1124 // Normalization
1125 test("a/./c/../d/f").p("a/./c/../d/f").z()
1126 .norm().p("a/d/f").z();
1127 test("http://a/./b/c/../d?q#f")
1128 .s("http").h("a").p("/./b/c/../d").q("q").f("f").z()
1129 .norm().s("http").h("a").p("/b/d").q("q").f("f").z();
1130 test("a/../b").p("a/../b").z().
1131 norm().p("b");
1132 test("a/../b:c").p("a/../b:c").z()
1133 .norm().p("./b:c").z();
1134
1135 // Normalization of already normalized URI should yield the
1136 // same URI
1137 URI u1 = URI.create("s://h/../p");
1138 URI u2 = u1.normalize();
1139 eq(u1, u2);
1140 eqeq(u1, u2);
1141
1142 // Relativization
1143 test("/a/b").p("/a/b").z()
1144 .rtvz(new URI("/a")).p("b").z();
1145 test("/a/b").p("/a/b").z()
1146 .rtvz(new URI("/a/")).p("b").z();
1147 test("a/b").p("a/b").z()
1148 .rtvz(new URI("a")).p("b").z();
1149 test("/a/b").p("/a/b").z()
1150 .rtvz(new URI("/a/b")).p("").z(); // Result is empty path
1151 test("a/../b:c/d").p("a/../b:c/d").z()
1152 .rtvz(new URI("./b:c/")).p("d").z();
1153
1154 test("http://a/b/d/e?q#f")
1155 .s("http").h("a").p("/b/d/e").q("q").f("f").z()
1156 .rtvz(new URI("http://a/b/?r#g"))
1157 .p("d/e").q("q").f("f").z();
1158
1159 // parseServerAuthority
1160 test("/a/b").psa().p("/a/b").z();
1161 test("s://u@h:1/p")
1162 .psa().s("s").u("u").h("h").n(1).p("/p").z();
1163 test("s://u@h:-foo/p").s("s").g("u@h:-foo").p("/p").z()
1164 .psa().x().z();
1165 test("s://h:999999999999999999999999").psa().x().z();
1166 test("s://:/b").psa().x().z();
1167
1168
1169 header("Constructors and factories");
1170
1171 test("s", null, null, -1, "p", null, null).x().z();
1172 test(null, null, null, -1, null, null, null).p("").z();
1173 test(null, null, null, -1, "p", null, null).p("p").z();
1174 test(null, null, "foo%20bar", -1, null, null, null).x().z();
1175 test(null, null, "foo", -100, null, null, null).x().z();
1176 test("s", null, null, -1, "", null, null).x().z();
1177 test("s", null, null, -1, "/p", null, null).s("s").p("/p").z();
1178 test("s", "u", "h", 10, "/p", "q", "f")
1179 .s("s").u("u").h("h").n(10).p("/p").q("q").f("f").z();
1180 test("s", "a:b", "/p", "q", "f")
1181 .s("s").g("a:b").p("/p").q("q").f("f").z();
1182 test("s", "h", "/p", "f")
1183 .s("s").h("h").p("/p").f("f").z();
1184 test("s", "p", "f").s("s").o("p").f("f").z();
1185 test("s", "/p", "f").s("s").p("/p").f("f").z();
1186 testCreate("s://u@h/p?q#f")
1187 .s("s").u("u").h("h").p("/p").q("q").f("f").z();
1188 }
1189
1190 static void npes() throws URISyntaxException {
1191
1192 header("NullPointerException");
1193
1194 URI base = URI.create("mailto:root@foobar.com");
1195
1196 out.println();
1197
1198 try {
1199 base.resolve((URI)null);
1200 throw new RuntimeException("NullPointerException not thrown");
1201 } catch (NullPointerException x) {
1202 out.println("resolve((URI)null) -->");
1203 out.println("Correct exception: " + x);
1204 }
1205
1206 out.println();
1207
1208 try {
1209 base.resolve((String)null);
1210 throw new RuntimeException("NullPointerException not thrown");
1211 } catch (NullPointerException x) {
1212 out.println("resolve((String)null) -->");
1213 out.println("Correct exception: " + x);
1214 }
1215
1216 out.println();
1217
1218 try {
1219 base.relativize((URI)null);
1220 throw new RuntimeException("NullPointerException not thrown");
1221 } catch (NullPointerException x) {
1222 out.println("relativize((String)null) -->");
1223 out.println("Correct exception: " + x);
1224 }
1225
1226 testCount += 3;
1227 }
1228
1229
1230 static void chars() throws URISyntaxException {
1231
1232 header("Escapes and non-US-ASCII characters");
1233
1234 URI uri;
1235
1236 // Escape pairs
1237 test("%0a%0A%0f%0F%01%09zz")
1238 .p("%0a%0A%0f%0F%01%09zz").z();
1239 test("foo%1").x().z();
1240 test("foo%z").x().z();
1241 test("foo%9z").x().z();
1242
1243 // Escapes not permitted in scheme, host
1244 test("s%20t://a").x().z();
1245 test("//a%20b").g("a%20b").p("").z(); // Parses as registry
1246
1247 // Escapes permitted in opaque part, userInfo, registry, path,
1248 // query, and fragment
1249 test("//u%20v@a").u("u%20v").h("a").p("").z();
1250 test("/p%20q").p("/p%20q").z();
1251 test("/p?q%20").p("/p").q("q%20").z();
1252 test("/p#%20f").p("/p").f("%20f").z();
1253
1254 // Non-US-ASCII chars
1255 test("s\u00a7t://a").x().z();
1256 test("//\u00a7/b").g("\u00a7").p("/b").z(); // Parses as registry
1257 test("//u\u00a7v@a").u("u\u00a7v").h("a").p("").z();
1258 test("/p\u00a7q").p("/p\u00a7q").z();
1259 test("/p?q\u00a7").p("/p").q("q\u00a7").z();
1260 test("/p#\u00a7f").p("/p").f("\u00a7f").z();
1261
1262 // 4648111 - Escapes quoted by toString after resolution
1263 uri = new URI("http://a/b/c/d;p?q");
1264 test("/p%20p")
1265 .rslv(uri).s("http").h("a").p("/p%20p").ts("http://a/p%20p").z();
1266
1267 // 4464135: Forbid unwise characters throughout opaque part
1268 test("foo:x{bar").x().z();
1269 test("foo:{bar").x().z();
1270
1271 // 4438319: Single-argument constructor requires quotation,
1272 // preserves escapes
1273 test("//u%01@h/a/b/%02/c?q%03#f%04")
1274 .u("u%01").ud("u\1")
1275 .h("h")
1276 .p("/a/b/%02/c").pd("/a/b/\2/c")
1277 .q("q%03").qd("q\3")
1278 .f("f%04").fd("f\4")
1279 .z();
1280 test("/a/b c").x().z();
1281
1282 // 4438319: Multi-argument constructors quote illegal chars and
1283 // preserve legal non-ASCII chars
1284 // \uA001-\uA009 are visible characters, \u2000 is a space character
1285 test(null, "u\uA001\1", "h", -1,
1286 "/p% \uA002\2\u2000",
1287 "q% \uA003\3\u2000",
1288 "f% \uA004\4\u2000")
1289 .u("u\uA001%01").h("h")
1290 .p("/p%25%20\uA002%02%E2%80%80").pd("/p% \uA002\2\u2000")
1291 .q("q%25%20\uA003%03%E2%80%80").qd("q% \uA003\3\u2000")
1292 .f("f%25%20\uA004%04%E2%80%80").fd("f% \uA004\4\u2000").z();
1293 test(null, "g\uA001\1",
1294 "/p% \uA002\2\u2000",
1295 "q% \uA003\3\u2000",
1296 "f% \uA004\4\u2000")
1297 .g("g\uA001%01")
1298 .p("/p%25%20\uA002%02%E2%80%80").pd("/p% \uA002\2\u2000")
1299 .q("q%25%20\uA003%03%E2%80%80").qd("q% \uA003\3\u2000")
1300 .f("f%25%20\uA004%04%E2%80%80").fd("f% \uA004\4\u2000").z();
1301 test(null, null, "/p% \uA002\2\u2000", "f% \uA004\4\u2000")
1302 .p("/p%25%20\uA002%02%E2%80%80").pd("/p% \uA002\2\u2000")
1303 .f("f%25%20\uA004%04%E2%80%80").fd("f% \uA004\4\u2000").z();
1304 test(null, "/sp% \uA001\1\u2000", "f% \uA004\4\u2000")
1305 .sp("/sp%25%20\uA001%01%E2%80%80").spd("/sp% \uA001\1\u2000")
1306 .p("/sp%25%20\uA001%01%E2%80%80").pd("/sp% \uA001\1\u2000")
1307 .f("f%25%20\uA004%04%E2%80%80").fd("f% \uA004\4\u2000").z();
1308
1309 // 4438319: Non-raw accessors decode all escaped octets
1310 test("/%25%20%E2%82%AC%E2%80%80")
1311 .p("/%25%20%E2%82%AC%E2%80%80").pd("/% \u20Ac\u2000").z();
1312
1313 // 4438319: toASCIIString
1314 test("/\uCAFE\uBABE")
1315 .p("/\uCAFE\uBABE").ta("/%EC%AB%BE%EB%AA%BE").z();
1316
1317 // 4991359 and 4866303: bad quoting by defineSchemeSpecificPart()
1318 URI base = new URI ("http://host/foo%20bar/a/b/c/d");
1319 test ("resolve")
1320 .rslv(base).spd("//host/foo bar/a/b/c/resolve")
1321 .sp("//host/foo%20bar/a/b/c/resolve").s("http")
1322 .pd("/foo bar/a/b/c/resolve").h("host")
1323 .p("/foo%20bar/a/b/c/resolve").z();
1324 }
1325
1326
1327 static void eq0(Comparable u, Comparable v) throws URISyntaxException {
1328 testCount++;
1329 if (!u.equals(v))
1330 throw new RuntimeException("Not equal: " + u + " " + v);
1331 int uh = u.hashCode();
1332 int vh = v.hashCode();
1333 if (uh != vh)
1334 throw new RuntimeException("Hash codes not equal: "
1335 + u + " " + Integer.toHexString(uh) + " "
1336 + v + " " + Integer.toHexString(vh));
1337 out.println();
1338 out.println(u + " == " + v
1339 + " [" + Integer.toHexString(uh) + "]");
1340 }
1341
1342 static void cmp0(Comparable u, Comparable v, boolean same)
1343 throws URISyntaxException
1344 {
1345 int c = u.compareTo(v);
1346 if ((c == 0) != same)
1347 throw new RuntimeException("Comparison inconsistent: " + u + " " + v
1348 + " " + c);
1349 }
1350
1351 static void eq(Comparable u, Comparable v) throws URISyntaxException {
1352 eq0(u, v);
1353 cmp0(u, v, true);
1354 }
1355
1356 static void eqeq(Comparable u, Comparable v) {
1357 testCount++;
1358 if (u != v)
1359 throw new RuntimeException("Not ==: " + u + " " + v);
1360 }
1361
1362 static void ne0(Comparable u, Comparable v) throws URISyntaxException {
1363 testCount++;
1364 if (u.equals(v))
1365 throw new RuntimeException("Equal: " + u + " " + v);
1366 out.println();
1367 out.println(u + " != " + v
1368 + " [" + Integer.toHexString(u.hashCode())
1369 + " " + Integer.toHexString(v.hashCode())
1370 + "]");
1371 }
1372
1373 static void ne(Comparable u, Comparable v) throws URISyntaxException {
1374 ne0(u, v);
1375 cmp0(u, v, false);
1376 }
1377
1378 static void lt(Comparable u, Comparable v) throws URISyntaxException {
1379 ne0(u, v);
1380 int c = u.compareTo(v);
1381 if (c >= 0) {
1382 show((URI)u);
1383 show((URI)v);
1384 throw new RuntimeException("Not less than: " + u + " " + v
1385 + " " + c);
1386 }
1387 out.println(u + " < " + v);
1388 }
1389
1390 static void lt(String s, String t) throws URISyntaxException {
1391 lt(new URI(s), new URI(t));
1392 }
1393
1394 static void gt(Comparable u, Comparable v) throws URISyntaxException {
1395 lt(v, u);
1396 }
1397
1398 static void eqHashComp() throws URISyntaxException {
1399
1400 header("Equality, hashing, and comparison");
1401
1402 URI o = new URI("mailto:foo@bar.com");
1403 URI r = new URI("reg://some%20registry/b/c/d?q#f");
1404 URI s = new URI("http://jag:cafebabe@java.sun.com:94/b/c/d?q#f");
1405 eq(o, o);
1406 lt(o, r);
1407 lt(s, o);
1408 lt(s, r);
1409 eq(o, new URI("MaILto:foo@bar.com"));
1410 gt(o, new URI("mailto:foo@bar.COM"));
1411 eq(r, new URI("rEg://some%20registry/b/c/d?q#f"));
1412 gt(r, new URI("reg://Some%20Registry/b/c/d?q#f"));
1413 gt(r, new URI("reg://some%20registry/b/c/D?q#f"));
1414 eq(s, new URI("hTtP://jag:cafebabe@Java.Sun.COM:94/b/c/d?q#f"));
1415 gt(s, new URI("http://jag:CafeBabe@java.sun.com:94/b/c/d?q#f"));
1416 lt(s, new URI("http://jag:cafebabe@java.sun.com:94/b/c/d?r#f"));
1417 lt(s, new URI("http://jag:cafebabe@java.sun.com:94/b/c/d?q#g"));
1418
1419 lt("p", "s:p");
1420 lt("s:p", "T:p");
1421 lt("S:p", "t:p");
1422 lt("s:/p", "s:p");
1423 lt("s:p", "s:q");
1424 lt("s:p#f", "s:p#g");
1425 lt("s://u@h:1", "s://v@h:1");
1426 lt("s://u@h:1", "s://u@i:1");
1427 lt("s://u@h:1", "s://v@h:2");
1428 lt("s://a%20b", "s://a%20c");
1429 lt("s://a%20b", "s://aab");
1430 lt("s://AA", "s://A_");
1431 lt("s:/p", "s:/q");
1432 lt("s:/p?q", "s:/p?r");
1433 lt("s:/p#f", "s:/p#g");
1434
1435 lt("s://h", "s://h/p");
1436 lt("s://h/p", "s://h/p?q");
1437
1438 }
1439
1440
1441 static void serial(URI u) throws IOException, URISyntaxException {
1442
1443 ByteArrayOutputStream bo = new ByteArrayOutputStream();
1444 ObjectOutputStream oo = new ObjectOutputStream(bo);
1445
1446 oo.writeObject(u);
1447 oo.close();
1448
1449 ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
1450 ObjectInputStream oi = new ObjectInputStream(bi);
1451 try {
1452 Object o = oi.readObject();
1453 eq(u, (Comparable)o);
1454 } catch (ClassNotFoundException x) {
1455 x.printStackTrace();
1456 throw new RuntimeException(x.toString());
1457 }
1458
1459 testCount++;
1460 }
1461
1462 static void serial() throws IOException, URISyntaxException {
1463 header("Serialization");
1464
1465 serial(URI.create("http://java.sun.com/jdk/1.4?release#beta"));
1466 serial(URI.create("s://h/p").resolve("/long%20path/"));
1467 }
1468
1469
1470 static void urls() throws URISyntaxException {
1471
1472 header("URLs");
1473
1474 URI uri;
1475 URL url;
1476 boolean caught = false;
1477
1478 out.println();
1479 uri = new URI("http://a/p?q#f");
1480 try {
1481 url = uri.toURL();
1482 } catch (MalformedURLException x) {
1483 throw new RuntimeException(x.toString());
1484 }
1485 if (!url.toString().equals("http://a/p?q#f"))
1486 throw new RuntimeException("Incorrect URL: " + url);
1487 out.println(uri + " url --> " + url);
1488
1489 out.println();
1490 uri = new URI("a/b");
1491 try {
1492 out.println(uri + " url --> ");
1493 url = uri.toURL();
1494 } catch (IllegalArgumentException x) {
1495 caught = true;
1496 out.println("Correct exception: " + x);
1497 } catch (MalformedURLException x) {
1498 caught = true;
1499 throw new RuntimeException("Incorrect exception: " + x);
1500 }
1501 if (!caught)
1502 throw new RuntimeException("Incorrect URL: " + url);
1503
1504 out.println();
1505 uri = new URI("foo://bar/baz");
1506 caught = false;
1507 try {
1508 out.println(uri + " url --> ");
1509 url = uri.toURL();
1510 } catch (MalformedURLException x) {
1511 caught = true;
1512 out.println("Correct exception: " + x);
1513 } catch (IllegalArgumentException x) {
1514 caught = true;
1515 throw new RuntimeException("Incorrect exception: " + x);
1516 }
1517 if (!caught)
1518 throw new RuntimeException("Incorrect URL: " + url);
1519
1520 testCount += 3;
1521 }
1522
1523
1524 static void tests() throws IOException, URISyntaxException {
1525 rfc2396();
1526 ip();
1527 misc();
1528 chars();
1529 eqHashComp();
1530 serial();
1531 urls();
1532 npes();
1533 }
1534
1535
1536 // -- Command-line invocation --
1537
1538 static void usage() {
1539 out.println("Usage:");
1540 out.println(" java Test -- Runs all tests in this file");
1541 out.println(" java Test <uri> -- Parses uri, shows components");
1542 out.println(" java Test <base> <uri> -- Parses uri and base, then resolves");
1543 out.println(" uri against base");
1544 }
1545
1546 static void clargs(String base, String uri) {
1547 URI b = null, u;
1548 try {
1549 if (base != null) {
1550 b = new URI(base);
1551 out.println(base);
1552 show(b);
1553 }
1554 u = new URI(uri);
1555 out.println(uri);
1556 show(u);
1557 if (base != null) {
1558 URI r = b.resolve(u);
1559 out.println(r);
1560 show(r);
1561 }
1562 } catch (URISyntaxException x) {
1563 show("ERROR", x);
1564 x.printStackTrace(out);
1565 }
1566 }
1567
1568
1569 public static void main(String[] args) throws Exception {
1570 switch (args.length) {
1571
1572 case 0:
1573 tests();
1574 out.println();
1575 out.println("Test cases: " + testCount);
1576 break;
1577
1578 case 1:
1579 if (args[0].equals("-help")) {
1580 usage();
1581 break;
1582 }
1583 clargs(null, args[0]);
1584 break;
1585
1586 case 2:
1587 clargs(args[0], args[1]);
1588 break;
1589
1590 default:
1591 usage();
1592 break;
1593
1594 }
1595 }
1596
1597}