19773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson/*
29773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson * Copyright (C) 2011 The Android Open Source Project
39773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson *
49773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson * Licensed under the Apache License, Version 2.0 (the "License");
59773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson * you may not use this file except in compliance with the License.
69773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson * You may obtain a copy of the License at
79773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson *
89773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson *      http://www.apache.org/licenses/LICENSE-2.0
99773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson *
109773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson * Unless required by applicable law or agreed to in writing, software
119773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
129773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson * See the License for the specific language governing permissions and
149773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson * limitations under the License.
159773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson */
169773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
179773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilsonpackage libcore.java.net;
189773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
199773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilsonimport java.io.UnsupportedEncodingException;
209773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilsonimport java.net.URI;
219773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilsonimport java.net.URISyntaxException;
229773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilsonimport java.net.URLDecoder;
239773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilsonimport java.net.URLEncoder;
2456099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilsonimport java.nio.charset.IllegalCharsetNameException;
2556099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilsonimport java.nio.charset.UnsupportedCharsetException;
269773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilsonimport junit.framework.TestCase;
279773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
289773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilsonpublic final class UrlEncodingTest extends TestCase {
299773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
309773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    public void testUriRetainsOriginalEncoding() throws Exception {
319773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals("%61", new URI("http://foo#%61").getRawFragment());
329773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
339773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
349773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    /**
359773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson     * URLDecoder and URI disagree on what '+' should decode to.
369773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson     */
379773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    public void testDecodingPlus() throws Exception {
389773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals("a b", URLDecoder.decode("a+b"));
399773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals("a b", URLDecoder.decode("a+b", "UTF-8"));
409773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals("a+b", new URI("http://foo#a+b").getFragment());
419773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
429773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
439773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    public void testEncodingPlus() throws Exception {
449773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals("a%2Bb", URLEncoder.encode("a+b"));
459773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals("a%2Bb", URLEncoder.encode("a+b", "UTF-8"));
469773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals("a+b", new URI("http", "foo", "/", "a+b").getRawFragment());
479773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
489773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
499773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    public void testDecodingSpace() throws Exception {
509773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals("a b", URLDecoder.decode("a b"));
519773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals("a b", URLDecoder.decode("a b", "UTF-8"));
529773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        try {
539773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson            new URI("http://foo#a b");
549773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson            fail();
559773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        } catch (URISyntaxException expected) {
569773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        }
579773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
589773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
599773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    public void testEncodingSpace() throws Exception {
609773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals("a+b", URLEncoder.encode("a b"));
619773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals("a+b", URLEncoder.encode("a b", "UTF-8"));
629773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals("a%20b", new URI("http", "foo", "/", "a b").getRawFragment());
639773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
649773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
659773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    public void testUriDecodingPartial() throws Exception {
669773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        try {
679773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson            new URI("http://foo#%");
689773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson            fail();
699773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        } catch (URISyntaxException expected) {
709773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        }
719773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        try {
729773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson            new URI("http://foo#%0");
739773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson            fail();
749773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        } catch (URISyntaxException expected) {
759773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        }
769773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
779773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
789773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    public void testUrlDecoderDecodingPartial() throws Exception {
799773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        try {
809773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson            URLDecoder.decode("%");
819773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson            fail();
829773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        } catch (IllegalArgumentException expected) {
839773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        }
849773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        try {
859773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson            URLDecoder.decode("%0");
869773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson            fail();
879773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        } catch (IllegalArgumentException expected) {
889773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        }
899773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
909773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
919773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    public void testUriDecodingInvalid() {
929773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        try {
939773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson            new URI("http://foo#%0g");
949773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson            fail();
959773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        } catch (URISyntaxException expected) {
969773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        }
979773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
989773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
999773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    public void testUrlDecoderDecodingInvalid() {
1009773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        try {
1019773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson            URLDecoder.decode("%0g");
1029773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson            fail();
1039773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        } catch (IllegalArgumentException expected) {
1049773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        }
1059773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
1069773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
1079773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    public void testUrlDecoderFailsOnNullCharset() throws Exception {
1089773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        try {
1099773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson            URLDecoder.decode("ab", null);
1109773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson            fail();
11156099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilson        } catch (IllegalCharsetNameException expected) {
1129773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        } catch (NullPointerException expected) {
1139773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        }
1149773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
1159773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
116786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson    public void testUrlDecoderFailsOnEmptyCharset() {
117786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson        try {
118786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson            URLDecoder.decode("ab", "");
119786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson            fail();
120786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson        } catch (IllegalCharsetNameException expected) {
121786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson        } catch (UnsupportedEncodingException expected) {
122786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson        }
123786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson    }
124786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson
1259773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    public void testUrlEncoderFailsOnNullCharset() throws Exception {
1269773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        try {
1279773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson            URLEncoder.encode("ab", null);
1289773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson            fail();
12956099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilson        } catch (IllegalCharsetNameException expected) {
1309773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        } catch (NullPointerException expected) {
1319773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        }
1329773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
1339773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
134786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson    public void testUrlEncoderFailsOnEmptyCharset() {
135786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson        try {
136786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson            URLEncoder.encode("ab", "");
137786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson            fail();
138786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson        } catch (IllegalCharsetNameException expected) {
139786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson        } catch (UnsupportedEncodingException expected) {
140786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson        }
141786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson    }
142786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson
14356099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilson    /**
14456099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilson     * The RI looks up the charset lazily; Android looks it up eagerly. Either
14556099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilson     * behavior is acceptable.
14656099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilson     */
1479773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    public void testUrlDecoderIgnoresUnnecessaryCharset() throws Exception {
14856099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilson        try {
14956099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilson            assertEquals("ab", URLDecoder.decode("ab", "no-such-charset"));
15056099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilson            // no fail()
15156099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilson        } catch (UnsupportedCharsetException expected) {
15256099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilson        }
1539773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
1549773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
1559773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    public void testUrlEncoderFailsOnInvalidCharset() throws Exception {
1569773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        try {
15756099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilson            URLEncoder.encode("ab", "no-such-charset");
1589773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson            fail();
15956099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilson        } catch (UnsupportedCharsetException expected) {
1609773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        } catch (UnsupportedEncodingException expected) {
1619773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        }
1629773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
1639773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
1649773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    public void testDecoding() throws Exception {
1659773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertDecoded("a\u0000b", "a%00b");
1669773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertDecoded("a b", "a%20b");
1679773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertDecoded("a+b", "a%2bb");
1689773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertDecoded("a%b", "a%25b");
1699773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertDecoded("a\u007fb", "a%7fb");
1709773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
1719773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
1729773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    public void testEncoding() throws Exception {
1739773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEncoded("a%25b", "a%b");
1749773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEncoded("a%7Fb", "a\u007fb");
1759773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
1769773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
1779773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    public void testDecodingLiterals() throws Exception {
1789773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertDecoded("\ud842\udf9f", "\ud842\udf9f");
1799773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
1809773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
1819773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    public void testDecodingBrokenUtf8SequenceYieldsReplacementCharacter() throws Exception {
1829773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertDecoded("a\ufffdb", "a%ffb");
1839773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
1849773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
1859773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    public void testDecodingUtf8Octets() throws Exception {
1869773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertDecoded("\u20AC", "%e2%82%ac");
1879773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertDecoded("\ud842\udf9f", "%f0%a0%ae%9f");
1889773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
1899773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
19032559028b14b9b321b10eede050afd554a376569Jesse Wilson    public void testDecodingNonUsDigits() throws Exception {
19132559028b14b9b321b10eede050afd554a376569Jesse Wilson        try {
19232559028b14b9b321b10eede050afd554a376569Jesse Wilson            new URI("http://foo#" + "%\u0664\u0661");
19332559028b14b9b321b10eede050afd554a376569Jesse Wilson            fail();
19432559028b14b9b321b10eede050afd554a376569Jesse Wilson        } catch (URISyntaxException expected) {
19532559028b14b9b321b10eede050afd554a376569Jesse Wilson        }
19632559028b14b9b321b10eede050afd554a376569Jesse Wilson        try {
19732559028b14b9b321b10eede050afd554a376569Jesse Wilson            URLDecoder.decode("%\u0664\u0661");
19832559028b14b9b321b10eede050afd554a376569Jesse Wilson            fail(); // RI fails this test returning "A"
19932559028b14b9b321b10eede050afd554a376569Jesse Wilson        } catch (IllegalArgumentException expected) {
20032559028b14b9b321b10eede050afd554a376569Jesse Wilson        }
20132559028b14b9b321b10eede050afd554a376569Jesse Wilson    }
20232559028b14b9b321b10eede050afd554a376569Jesse Wilson
2039773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    /**
2049773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson     * Android's URLEncoder.encode() failed for surrogate pairs, encoding them
2059773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson     * as two replacement characters ("??"). http://b/3436051
2069773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson     */
2079773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    public void testUrlEncoderEncodesNonPrintableNonAsciiCharacters() throws Exception {
2089773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals("%00", URLEncoder.encode("\u0000", "UTF-8"));
2099773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals("%00", URLEncoder.encode("\u0000"));
2109773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals("%E2%82%AC", URLEncoder.encode("\u20AC", "UTF-8"));
2119773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals("%E2%82%AC", URLEncoder.encode("\u20AC"));
2129773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals("%F0%A0%AE%9F", URLEncoder.encode("\ud842\udf9f", "UTF-8"));
2139773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals("%F0%A0%AE%9F", URLEncoder.encode("\ud842\udf9f"));
2149773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
2159773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
2169773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    public void testUriDoesNotEncodeNonPrintableNonAsciiCharacters() throws Exception {
2179773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals("\u20AC", new URI("http", "foo", "/", "\u20AC").getRawFragment());
2189773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals("\ud842\udf9f", new URI("http", "foo", "/", "\ud842\udf9f").getRawFragment());
2199773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
2209773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
22156099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilson    public void testUriEncodesControlCharacters() throws Exception {
22256099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilson        assertEquals("%01", new URI("http", "foo", "/", "\u0001").getRawFragment());
22356099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilson
22456099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilson        // The RI fails this, encoding \u0001 but not \u0000
22556099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilson        assertEquals("%00", new URI("http", "foo", "/", "\u0000").getRawFragment());
22656099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilson    }
22756099d23fcb002b164bff8fb7f14d6ec0453509eJesse Wilson
228786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson    public void testEncodeAndDecode() throws Exception {
229786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson        assertRoundTrip("http://jcltest.apache.org/test?hl=en&q=te st",
230786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson                "http%3A%2F%2Fjcltest.apache.org%2Ftest%3Fhl%3Den%26q%3Dte+st");
231786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson        assertRoundTrip ("file://a b/c/d.e-f*g_ l",
232786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson                "file%3A%2F%2Fa+b%2Fc%2Fd.e-f*g_+l");
233786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson        assertRoundTrip("jar:file://a.jar !/b.c/\u1052",
234786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson                "jar%3Afile%3A%2F%2Fa.jar+%21%2Fb.c%2F%E1%81%92");
235786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson        assertRoundTrip("ftp://test:pwd@localhost:2121/%D0%9C",
236786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson                "ftp%3A%2F%2Ftest%3Apwd%40localhost%3A2121%2F%25D0%259C");
237786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson    }
238786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson
2399773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    /**
2409773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson     * Asserts that {@code original} decodes to {@code decoded} using both URI
2419773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson     * and UrlDecoder.
2429773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson     */
2439773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    private void assertDecoded(String decoded, String original) throws Exception {
2449773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals(decoded, new URI("http://foo#" + original).getFragment());
2459773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals(decoded, URLDecoder.decode(original));
2469773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals(decoded, URLDecoder.decode(original, "UTF-8"));
2479773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
2489773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson
2499773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    /**
2509773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson     * Asserts that {@code original} encodes to {@code encoded} using both URI
2519773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson     * and URLEncoder.
2529773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson     */
2539773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    private void assertEncoded(String encoded, String original) throws Exception {
2549773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals(encoded, URLEncoder.encode(original, "UTF-8"));
2559773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals(encoded, URLEncoder.encode(original));
2569773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson        assertEquals(encoded, new URI("http", "foo", "/", original).getRawFragment());
2579773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson    }
258786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson
259786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson    private void assertRoundTrip(String original, String encoded) throws Exception {
260786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson        assertEquals(encoded, URLEncoder.encode(original, "UTF-8"));
261786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson        assertEquals(original, URLDecoder.decode(encoded, "UTF-8"));
262786ca658dfe8596835859ce45ee3b0ed46b8f21cJesse Wilson    }
2639773c9ed094e164ace98757bb6d54964ca8978fdJesse Wilson}
264