Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2010 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 // Basic tests that verify our KURL's interface behaves the same as the
     32 // original KURL's.
     33 
     34 #include "config.h"
     35 
     36 #include <gtest/gtest.h>
     37 
     38 #include "KURL.h"
     39 
     40 namespace {
     41 
     42 // Output stream operator so gTest's macros work with WebCore strings.
     43 std::ostream& operator<<(std::ostream& out, const WebCore::String& str)
     44 {
     45     return str.isEmpty() ? out : out << str.utf8().data();
     46 }
     47 
     48 struct ComponentCase {
     49     const char* url;
     50     const char* protocol;
     51     const char* host;
     52     const int port;
     53     const char* user;
     54     const char* pass;
     55     const char* path;
     56     const char* lastPath;
     57     const char* query;
     58     const char* ref;
     59 };
     60 
     61 // Test the cases where we should be the same as WebKit's old KURL.
     62 TEST(KURLTest, SameGetters)
     63 {
     64     struct GetterCase {
     65         const char* url;
     66         const char* protocol;
     67         const char* host;
     68         int port;
     69         const char* user;
     70         const char* pass;
     71         const char* lastPathComponent;
     72         const char* query;
     73         const char* ref;
     74         bool hasRef;
     75     } cases[] = {
     76         {"http://www.google.com/foo/blah?bar=baz#ref", "http", "www.google.com", 0, "", 0, "blah", "bar=baz", "ref", true},
     77         {"http://foo.com:1234/foo/bar/", "http", "foo.com", 1234, "", 0, "bar", 0, 0, false},
     78         {"http://www.google.com?#", "http", "www.google.com", 0, "", 0, 0, "", "", true},
     79         {"https://me:pass@google.com:23#foo", "https", "google.com", 23, "me", "pass", 0, 0, "foo", true},
     80         {"javascript:hello!//world", "javascript", "", 0, "", 0, "world", 0, 0, false},
     81     };
     82 
     83     for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) {
     84         // UTF-8
     85         WebCore::KURL kurl(WebCore::ParsedURLString, cases[i].url);
     86 
     87         EXPECT_EQ(cases[i].protocol, kurl.protocol());
     88         EXPECT_EQ(cases[i].host, kurl.host());
     89         EXPECT_EQ(cases[i].port, kurl.port());
     90         EXPECT_EQ(cases[i].user, kurl.user());
     91         EXPECT_EQ(cases[i].pass, kurl.pass());
     92         EXPECT_EQ(cases[i].lastPathComponent, kurl.lastPathComponent());
     93         EXPECT_EQ(cases[i].query, kurl.query());
     94         EXPECT_EQ(cases[i].ref, kurl.fragmentIdentifier());
     95         EXPECT_EQ(cases[i].hasRef, kurl.hasFragmentIdentifier());
     96 
     97         // UTF-16
     98         WebCore::String utf16(cases[i].url);
     99         kurl = WebCore::KURL(WebCore::ParsedURLString, utf16);
    100 
    101         EXPECT_EQ(cases[i].protocol, kurl.protocol());
    102         EXPECT_EQ(cases[i].host, kurl.host());
    103         EXPECT_EQ(cases[i].port, kurl.port());
    104         EXPECT_EQ(cases[i].user, kurl.user());
    105         EXPECT_EQ(cases[i].pass, kurl.pass());
    106         EXPECT_EQ(cases[i].lastPathComponent, kurl.lastPathComponent());
    107         EXPECT_EQ(cases[i].query, kurl.query());
    108         EXPECT_EQ(cases[i].ref, kurl.fragmentIdentifier());
    109         EXPECT_EQ(cases[i].hasRef, kurl.hasFragmentIdentifier());
    110     }
    111 }
    112 
    113 // Test a few cases where we're different just to make sure we give reasonable
    114 // output.
    115 TEST(KURLTest, DifferentGetters)
    116 {
    117     ComponentCase cases[] = {
    118         // url                                    protocol      host        port  user  pass    path                lastPath  query      ref
    119 
    120         // Old WebKit allows references and queries in what we call "path" URLs
    121         // like javascript, so the path here will only consist of "hello!".
    122         {"javascript:hello!?#/\\world",           "javascript", "",         0,    "",   0,      "hello!?#/\\world", "world",  0,         0},
    123 
    124         // Old WebKit doesn't handle "parameters" in paths, so will
    125         // disagree with us about where the path is for this URL.
    126         {"http://a.com/hello;world",              "http",       "a.com",    0,    "",   0,      "/hello;world",     "hello",  0,         0},
    127 
    128         // WebKit doesn't like UTF-8 or UTF-16 input.
    129         {"http://\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xbd\xa0\xe5\xa5\xbd/", "http", "xn--6qqa088eba", 0, "", 0, "/",       0,        0,         0},
    130 
    131         // WebKit %-escapes non-ASCII characters in reference, but we don't.
    132         {"http://www.google.com/foo/blah?bar=baz#\xce\xb1\xce\xb2", "http", "www.google.com", 0, "", 0, "/foo/blah/", "blah", "bar=baz", "\xce\xb1\xce\xb2"},
    133     };
    134 
    135     for (size_t i = 0; i < arraysize(cases); i++) {
    136         WebCore::KURL kurl(WebCore::ParsedURLString, cases[i].url);
    137 
    138         EXPECT_EQ(cases[i].protocol, kurl.protocol());
    139         EXPECT_EQ(cases[i].host, kurl.host());
    140         EXPECT_EQ(cases[i].port, kurl.port());
    141         EXPECT_EQ(cases[i].user, kurl.user());
    142         EXPECT_EQ(cases[i].pass, kurl.pass());
    143         EXPECT_EQ(cases[i].lastPath, kurl.lastPathComponent());
    144         EXPECT_EQ(cases[i].query, kurl.query());
    145         // Want to compare UCS-16 refs (or to null).
    146         if (cases[i].ref)
    147             EXPECT_EQ(WebCore::String::fromUTF8(cases[i].ref), kurl.fragmentIdentifier());
    148         else
    149             EXPECT_TRUE(kurl.fragmentIdentifier().isNull());
    150     }
    151 }
    152 
    153 // Ensures that both ASCII and UTF-8 canonical URLs are handled properly and we
    154 // get the correct string object out.
    155 TEST(KURLTest, UTF8)
    156 {
    157     const char asciiURL[] = "http://foo/bar#baz";
    158     WebCore::KURL asciiKURL(WebCore::ParsedURLString, asciiURL);
    159     EXPECT_TRUE(asciiKURL.string() == WebCore::String(asciiURL));
    160 
    161     // When the result is ASCII, we should get an ASCII String. Some
    162     // code depends on being able to compare the result of the .string()
    163     // getter with another String, and the isASCIIness of the two
    164     // strings must match for these functions (like equalIgnoringCase).
    165     EXPECT_TRUE(WebCore::equalIgnoringCase(asciiKURL, WebCore::String(asciiURL)));
    166 
    167     // Reproduce code path in FrameLoader.cpp -- equalIgnoringCase implicitly
    168     // expects gkurl.protocol() to have been created as ascii.
    169     WebCore::KURL mailto(WebCore::ParsedURLString, "mailto:foo (at) foo.com");
    170     EXPECT_TRUE(WebCore::equalIgnoringCase(mailto.protocol(), "mailto"));
    171 
    172     const char utf8URL[] = "http://foo/bar#\xe4\xbd\xa0\xe5\xa5\xbd";
    173     WebCore::KURL utf8KURL(WebCore::ParsedURLString, utf8URL);
    174 
    175     EXPECT_TRUE(utf8KURL.string() == WebCore::String::fromUTF8(utf8URL));
    176 }
    177 
    178 TEST(KURLTest, Setters)
    179 {
    180     // Replace the starting URL with the given components one at a time and
    181     // verify that we're always the same as the old KURL.
    182     //
    183     // Note that old KURL won't canonicalize the default port away, so we
    184     // can't set setting the http port to "80" (or even "0").
    185     //
    186     // We also can't test clearing the query.
    187     //
    188     // The format is every other row is a test, and the row that follows it is the
    189     // expected result.
    190     struct ExpectedComponentCase {
    191         const char* url;
    192         const char* protocol;
    193         const char* host;
    194         const int port;
    195         const char* user;
    196         const char* pass;
    197         const char* path;
    198         const char* query;
    199         const char* ref;
    200 
    201         // The full expected URL with the given "set" applied.
    202         const char* expectedProtocol;
    203         const char* expectedHost;
    204         const char* expectedPort;
    205         const char* expectedUser;
    206         const char* expectedPass;
    207         const char* expectedPath;
    208         const char* expectedQuery;
    209         const char* expectedRef;
    210     } cases[] = {
    211          // url                                   protocol      host               port  user  pass    path            query      ref
    212         {"http://www.google.com/",                "https",      "news.google.com", 8888, "me", "pass", "/foo",         "?q=asdf", "heehee",
    213                                                   "https://www.google.com/",
    214                                                                 "https://news.google.com/",
    215                                                                                    "https://news.google.com:8888/",
    216                                                                                          "https://me@news.google.com:8888/",
    217                                                                                                "https://me:pass@news.google.com:8888/",
    218                                                                                                        "https://me:pass@news.google.com:8888/foo",
    219                                                                                                                        "https://me:pass@news.google.com:8888/foo?q=asdf",
    220                                                                                                                                   "https://me:pass@news.google.com:8888/foo?q=asdf#heehee"},
    221 
    222         {"https://me:pass@google.com:88/a?f#b",   "http",       "goo.com",         92,   "",   "",     "/",            0,      "",
    223                                                   "http://me:pass@google.com:88/a?f#b",
    224                                                                 "http://me:pass@goo.com:88/a?f#b",
    225                                                                                    "http://me:pass@goo.com:92/a?f#b",
    226                                                                                          "http://:pass@goo.com:92/a?f#b",
    227                                                                                                "http://goo.com:92/a?f#b",
    228                                                                                                         "http://goo.com:92/?f#b",
    229                                                                                                                        "http://goo.com:92/#b",
    230                                                                                                                                   "https://goo.com:92/"},
    231     };
    232 
    233     for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) {
    234         WebCore::KURL kurl(WebCore::ParsedURLString, cases[i].url);
    235 
    236         kurl.setProtocol(cases[i].protocol);
    237         EXPECT_STREQ(cases[i].expectedProtocol, kurl.string().utf8().data());
    238 
    239         kurl.setHost(cases[i].host);
    240         EXPECT_STREQ(cases[i].expectedHost, kurl.string().utf8().data());
    241 
    242         kurl.setPort(cases[i].port);
    243         EXPECT_STREQ(cases[i].expectedPort, kurl.string().utf8().data());
    244 
    245         kurl.setUser(cases[i].user);
    246         EXPECT_STREQ(cases[i].expectedUser, kurl.string().utf8().data());
    247 
    248         kurl.setPass(cases[i].pass);
    249         EXPECT_STREQ(cases[i].expectedPass, kurl.string().utf8().data());
    250 
    251         kurl.setPath(cases[i].path);
    252         EXPECT_STREQ(cases[i].expectedPath, kurl.string().utf8().data());
    253 
    254         kurl.setQuery(cases[i].query);
    255         EXPECT_STREQ(cases[i].expectedQuery, kurl.string().utf8().data());
    256 
    257         // Refs are tested below. On the Safari 3.1 branch, we don't match their
    258         // KURL since we integrated a fix from their trunk.
    259     }
    260 }
    261 
    262 // Tests that KURL::decodeURLEscapeSequences works as expected
    263 #if USE(GOOGLEURL)
    264 TEST(KURLTest, Decode)
    265 {
    266     struct DecodeCase {
    267         const char* input;
    268         const char* output;
    269     } decodeCases[] = {
    270         {"hello, world", "hello, world"},
    271         {"%01%02%03%04%05%06%07%08%09%0a%0B%0C%0D%0e%0f/", "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0B\x0C\x0D\x0e\x0f/"},
    272         {"%10%11%12%13%14%15%16%17%18%19%1a%1B%1C%1D%1e%1f/", "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1B\x1C\x1D\x1e\x1f/"},
    273         {"%20%21%22%23%24%25%26%27%28%29%2a%2B%2C%2D%2e%2f/", " !\"#$%&'()*+,-.//"},
    274         {"%30%31%32%33%34%35%36%37%38%39%3a%3B%3C%3D%3e%3f/", "0123456789:;<=>?/"},
    275         {"%40%41%42%43%44%45%46%47%48%49%4a%4B%4C%4D%4e%4f/", "@ABCDEFGHIJKLMNO/"},
    276         {"%50%51%52%53%54%55%56%57%58%59%5a%5B%5C%5D%5e%5f/", "PQRSTUVWXYZ[\\]^_/"},
    277         {"%60%61%62%63%64%65%66%67%68%69%6a%6B%6C%6D%6e%6f/", "`abcdefghijklmno/"},
    278         {"%70%71%72%73%74%75%76%77%78%79%7a%7B%7C%7D%7e%7f/", "pqrstuvwxyz{|}~\x7f/"},
    279           // Test un-UTF-8-ization.
    280         {"%e4%bd%a0%e5%a5%bd", "\xe4\xbd\xa0\xe5\xa5\xbd"},
    281     };
    282 
    283     for (size_t i = 0; i < ARRAYSIZE_UNSAFE(decodeCases); i++) {
    284         WebCore::String input(decodeCases[i].input);
    285         WebCore::String str = WebCore::decodeURLEscapeSequences(input);
    286         EXPECT_STREQ(decodeCases[i].output, str.utf8().data());
    287     }
    288 
    289     // Our decode should decode %00
    290     WebCore::String zero = WebCore::decodeURLEscapeSequences("%00");
    291     EXPECT_STRNE("%00", zero.utf8().data());
    292 
    293     // Test the error behavior for invalid UTF-8 (we differ from WebKit here).
    294     WebCore::String invalid = WebCore::decodeURLEscapeSequences(
    295         "%e4%a0%e5%a5%bd");
    296     char16 invalidExpectedHelper[4] = { 0x00e4, 0x00a0, 0x597d, 0 };
    297     WebCore::String invalidExpected(
    298         reinterpret_cast<const ::UChar*>(invalidExpectedHelper),
    299         3);
    300     EXPECT_EQ(invalidExpected, invalid);
    301 }
    302 #endif
    303 
    304 TEST(KURLTest, Encode)
    305 {
    306     // Also test that it gets converted to UTF-8 properly.
    307     char16 wideInputHelper[3] = { 0x4f60, 0x597d, 0 };
    308     WebCore::String wideInput(
    309         reinterpret_cast<const ::UChar*>(wideInputHelper), 2);
    310     WebCore::String wideReference("\xe4\xbd\xa0\xe5\xa5\xbd", 6);
    311     WebCore::String wideOutput =
    312         WebCore::encodeWithURLEscapeSequences(wideInput);
    313     EXPECT_EQ(wideReference, wideOutput);
    314 
    315     // Our encode only escapes NULLs for safety (see the implementation for
    316     // more), so we only bother to test a few cases.
    317     WebCore::String input(
    318         "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 16);
    319     WebCore::String reference(
    320         "%00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", 18);
    321     WebCore::String output = WebCore::encodeWithURLEscapeSequences(input);
    322     EXPECT_EQ(reference, output);
    323 }
    324 
    325 TEST(KURLTest, ResolveEmpty)
    326 {
    327     WebCore::KURL emptyBase;
    328 
    329     // WebKit likes to be able to resolve absolute input agains empty base URLs,
    330     // which would normally be invalid since the base URL is invalid.
    331     const char abs[] = "http://www.google.com/";
    332     WebCore::KURL resolveAbs(emptyBase, abs);
    333     EXPECT_TRUE(resolveAbs.isValid());
    334     EXPECT_STREQ(abs, resolveAbs.string().utf8().data());
    335 
    336     // Resolving a non-relative URL agains the empty one should still error.
    337     const char rel[] = "foo.html";
    338     WebCore::KURL resolveErr(emptyBase, rel);
    339     EXPECT_FALSE(resolveErr.isValid());
    340 }
    341 
    342 // WebKit will make empty URLs and set components on them. kurl doesn't allow
    343 // replacements on invalid URLs, but here we do.
    344 TEST(KURLTest, ReplaceInvalid)
    345 {
    346     WebCore::KURL kurl;
    347 
    348     EXPECT_FALSE(kurl.isValid());
    349     EXPECT_TRUE(kurl.isEmpty());
    350     EXPECT_STREQ("", kurl.string().utf8().data());
    351 
    352     kurl.setProtocol("http");
    353     // GKURL will say that a URL with just a scheme is invalid, KURL will not.
    354 #if USE(GOOGLEURL)
    355     EXPECT_FALSE(kurl.isValid());
    356 #else
    357     EXPECT_TRUE(kurl.isValid());
    358 #endif
    359     EXPECT_FALSE(kurl.isEmpty());
    360     // At this point, we do things slightly differently if there is only a scheme.
    361     // We check the results here to make it more obvious what is going on, but it
    362     // shouldn't be a big deal if these change.
    363 #if USE(GOOGLEURL)
    364     EXPECT_STREQ("http:", kurl.string().utf8().data());
    365 #else
    366     EXPECT_STREQ("http:/", kurl.string().utf8().data());
    367 #endif
    368 
    369     kurl.setHost("www.google.com");
    370     EXPECT_TRUE(kurl.isValid());
    371     EXPECT_FALSE(kurl.isEmpty());
    372     EXPECT_STREQ("http://www.google.com/", kurl.string().utf8().data());
    373 
    374     kurl.setPort(8000);
    375     EXPECT_TRUE(kurl.isValid());
    376     EXPECT_FALSE(kurl.isEmpty());
    377     EXPECT_STREQ("http://www.google.com:8000/", kurl.string().utf8().data());
    378 
    379     kurl.setPath("/favicon.ico");
    380     EXPECT_TRUE(kurl.isValid());
    381     EXPECT_FALSE(kurl.isEmpty());
    382     EXPECT_STREQ("http://www.google.com:8000/favicon.ico", kurl.string().utf8().data());
    383 
    384     // Now let's test that giving an invalid replacement still fails.
    385 #if USE(GOOGLEURL)
    386     kurl.setProtocol("f/sj#@");
    387     EXPECT_FALSE(kurl.isValid());
    388 #endif
    389 }
    390 
    391 TEST(KURLTest, Path)
    392 {
    393     const char initial[] = "http://www.google.com/path/foo";
    394     WebCore::KURL kurl(WebCore::ParsedURLString, initial);
    395 
    396     // Clear by setting a null string.
    397     WebCore::String nullString;
    398     EXPECT_TRUE(nullString.isNull());
    399     kurl.setPath(nullString);
    400     EXPECT_STREQ("http://www.google.com/", kurl.string().utf8().data());
    401 }
    402 
    403 // Test that setting the query to different things works. Thq query is handled
    404 // a littler differently than some of the other components.
    405 TEST(KURLTest, Query)
    406 {
    407     const char initial[] = "http://www.google.com/search?q=awesome";
    408     WebCore::KURL kurl(WebCore::ParsedURLString, initial);
    409 
    410     // Clear by setting a null string.
    411     WebCore::String nullString;
    412     EXPECT_TRUE(nullString.isNull());
    413     kurl.setQuery(nullString);
    414     EXPECT_STREQ("http://www.google.com/search", kurl.string().utf8().data());
    415 
    416     // Clear by setting an empty string.
    417     kurl = WebCore::KURL(WebCore::ParsedURLString, initial);
    418     WebCore::String emptyString("");
    419     EXPECT_FALSE(emptyString.isNull());
    420     kurl.setQuery(emptyString);
    421     EXPECT_STREQ("http://www.google.com/search?", kurl.string().utf8().data());
    422 
    423     // Set with something that begins in a question mark.
    424     const char question[] = "?foo=bar";
    425     kurl.setQuery(question);
    426     EXPECT_STREQ("http://www.google.com/search?foo=bar",
    427                  kurl.string().utf8().data());
    428 
    429     // Set with something that doesn't begin in a question mark.
    430     const char query[] = "foo=bar";
    431     kurl.setQuery(query);
    432     EXPECT_STREQ("http://www.google.com/search?foo=bar",
    433                  kurl.string().utf8().data());
    434 }
    435 
    436 TEST(KURLTest, Ref)
    437 {
    438     WebCore::KURL kurl(WebCore::ParsedURLString, "http://foo/bar#baz");
    439 
    440     // Basic ref setting.
    441     WebCore::KURL cur(WebCore::ParsedURLString, "http://foo/bar");
    442     cur.setFragmentIdentifier("asdf");
    443     EXPECT_STREQ("http://foo/bar#asdf", cur.string().utf8().data());
    444     cur = kurl;
    445     cur.setFragmentIdentifier("asdf");
    446     EXPECT_STREQ("http://foo/bar#asdf", cur.string().utf8().data());
    447 
    448     // Setting a ref to the empty string will set it to "#".
    449     cur = WebCore::KURL(WebCore::ParsedURLString, "http://foo/bar");
    450     cur.setFragmentIdentifier("");
    451     EXPECT_STREQ("http://foo/bar#", cur.string().utf8().data());
    452     cur = kurl;
    453     cur.setFragmentIdentifier("");
    454     EXPECT_STREQ("http://foo/bar#", cur.string().utf8().data());
    455 
    456     // Setting the ref to the null string will clear it altogether.
    457     cur = WebCore::KURL(WebCore::ParsedURLString, "http://foo/bar");
    458     cur.setFragmentIdentifier(WebCore::String());
    459     EXPECT_STREQ("http://foo/bar", cur.string().utf8().data());
    460     cur = kurl;
    461     cur.setFragmentIdentifier(WebCore::String());
    462     EXPECT_STREQ("http://foo/bar", cur.string().utf8().data());
    463 }
    464 
    465 TEST(KURLTest, Empty)
    466 {
    467     WebCore::KURL kurl;
    468 
    469     // First test that regular empty URLs are the same.
    470     EXPECT_TRUE(kurl.isEmpty());
    471     EXPECT_FALSE(kurl.isValid());
    472     EXPECT_TRUE(kurl.isNull());
    473     EXPECT_TRUE(kurl.string().isNull());
    474     EXPECT_TRUE(kurl.string().isEmpty());
    475 
    476     // Test resolving a null URL on an empty string.
    477     WebCore::KURL kurl2(kurl, "");
    478     EXPECT_FALSE(kurl2.isNull());
    479     EXPECT_TRUE(kurl2.isEmpty());
    480     EXPECT_FALSE(kurl2.isValid());
    481     EXPECT_FALSE(kurl2.string().isNull());
    482     EXPECT_TRUE(kurl2.string().isEmpty());
    483     EXPECT_FALSE(kurl2.string().isNull());
    484     EXPECT_TRUE(kurl2.string().isEmpty());
    485 
    486     // Resolve the null URL on a null string.
    487     WebCore::KURL kurl22(kurl, WebCore::String());
    488     EXPECT_FALSE(kurl22.isNull());
    489     EXPECT_TRUE(kurl22.isEmpty());
    490     EXPECT_FALSE(kurl22.isValid());
    491     EXPECT_FALSE(kurl22.string().isNull());
    492     EXPECT_TRUE(kurl22.string().isEmpty());
    493     EXPECT_FALSE(kurl22.string().isNull());
    494     EXPECT_TRUE(kurl22.string().isEmpty());
    495 
    496     // Test non-hierarchical schemes resolving. The actual URLs will be different.
    497     // WebKit's one will set the string to "something.gif" and we'll set it to an
    498     // empty string. I think either is OK, so we just check our behavior.
    499 #if USE(GOOGLEURL)
    500     WebCore::KURL kurl3(WebCore::KURL(WebCore::ParsedURLString, "data:foo"),
    501                         "something.gif");
    502     EXPECT_TRUE(kurl3.isEmpty());
    503     EXPECT_FALSE(kurl3.isValid());
    504 #endif
    505 
    506     // Test for weird isNull string input,
    507     // see: http://bugs.webkit.org/show_bug.cgi?id=16487
    508     WebCore::KURL kurl4(WebCore::ParsedURLString, kurl.string());
    509     EXPECT_TRUE(kurl4.isEmpty());
    510     EXPECT_FALSE(kurl4.isValid());
    511     EXPECT_TRUE(kurl4.string().isNull());
    512     EXPECT_TRUE(kurl4.string().isEmpty());
    513 
    514     // Resolving an empty URL on an invalid string.
    515     WebCore::KURL kurl5(WebCore::KURL(), "foo.js");
    516     // We'll be empty in this case, but KURL won't be. Should be OK.
    517     // EXPECT_EQ(kurl5.isEmpty(), kurl5.isEmpty());
    518     // EXPECT_EQ(kurl5.string().isEmpty(), kurl5.string().isEmpty());
    519     EXPECT_FALSE(kurl5.isValid());
    520     EXPECT_FALSE(kurl5.string().isNull());
    521 
    522     // Empty string as input
    523     WebCore::KURL kurl6(WebCore::ParsedURLString, "");
    524     EXPECT_TRUE(kurl6.isEmpty());
    525     EXPECT_FALSE(kurl6.isValid());
    526     EXPECT_FALSE(kurl6.string().isNull());
    527     EXPECT_TRUE(kurl6.string().isEmpty());
    528 
    529     // Non-empty but invalid C string as input.
    530     WebCore::KURL kurl7(WebCore::ParsedURLString, "foo.js");
    531     // WebKit will actually say this URL has the string "foo.js" but is invalid.
    532     // We don't do that.
    533     // EXPECT_EQ(kurl7.isEmpty(), kurl7.isEmpty());
    534     EXPECT_FALSE(kurl7.isValid());
    535     EXPECT_FALSE(kurl7.string().isNull());
    536 }
    537 
    538 TEST(KURLTest, UserPass)
    539 {
    540     const char* src = "http://user:pass@google.com/";
    541     WebCore::KURL kurl(WebCore::ParsedURLString, src);
    542 
    543     // Clear just the username.
    544     kurl.setUser("");
    545     EXPECT_EQ("http://:pass@google.com/", kurl.string());
    546 
    547     // Clear just the password.
    548     kurl = WebCore::KURL(WebCore::ParsedURLString, src);
    549     kurl.setPass("");
    550     EXPECT_EQ("http://user@google.com/", kurl.string());
    551 
    552     // Now clear both.
    553     kurl.setUser("");
    554     EXPECT_EQ("http://google.com/", kurl.string());
    555 }
    556 
    557 TEST(KURLTest, Offsets)
    558 {
    559     const char* src1 = "http://user:pass@google.com/foo/bar.html?baz=query#ref";
    560     WebCore::KURL kurl1(WebCore::ParsedURLString, src1);
    561 
    562     EXPECT_EQ(17u, kurl1.hostStart());
    563     EXPECT_EQ(27u, kurl1.hostEnd());
    564     EXPECT_EQ(27u, kurl1.pathStart());
    565     EXPECT_EQ(40u, kurl1.pathEnd());
    566     EXPECT_EQ(32u, kurl1.pathAfterLastSlash());
    567 
    568     const char* src2 = "http://google.com/foo/";
    569     WebCore::KURL kurl2(WebCore::ParsedURLString, src2);
    570 
    571     EXPECT_EQ(7u, kurl2.hostStart());
    572     EXPECT_EQ(17u, kurl2.hostEnd());
    573     EXPECT_EQ(17u, kurl2.pathStart());
    574     EXPECT_EQ(22u, kurl2.pathEnd());
    575     EXPECT_EQ(22u, kurl2.pathAfterLastSlash());
    576 
    577     const char* src3 = "javascript:foobar";
    578     WebCore::KURL kurl3(WebCore::ParsedURLString, src3);
    579 
    580     EXPECT_EQ(11u, kurl3.hostStart());
    581     EXPECT_EQ(11u, kurl3.hostEnd());
    582     EXPECT_EQ(11u, kurl3.pathStart());
    583     EXPECT_EQ(17u, kurl3.pathEnd());
    584     EXPECT_EQ(11u, kurl3.pathAfterLastSlash());
    585 }
    586 
    587 TEST(KURLTest, DeepCopy)
    588 {
    589     const char url[] = "http://www.google.com/";
    590     WebCore::KURL src(WebCore::ParsedURLString, url);
    591     EXPECT_TRUE(src.string() == url); // This really just initializes the cache.
    592     WebCore::KURL dest = src.copy();
    593     EXPECT_TRUE(dest.string() == url); // This really just initializes the cache.
    594 
    595     // The pointers should be different for both UTF-8 and UTF-16.
    596     EXPECT_NE(dest.string().characters(), src.string().characters());
    597     EXPECT_NE(dest.utf8String().data(), src.utf8String().data());
    598 }
    599 
    600 TEST(KURLTest, ProtocolIs)
    601 {
    602     WebCore::KURL url1(WebCore::ParsedURLString, "foo://bar");
    603     EXPECT_TRUE(url1.protocolIs("foo"));
    604     EXPECT_FALSE(url1.protocolIs("foo-bar"));
    605 
    606     WebCore::KURL url2(WebCore::ParsedURLString, "foo-bar:");
    607     EXPECT_TRUE(url2.protocolIs("foo-bar"));
    608     EXPECT_FALSE(url2.protocolIs("foo"));
    609 }
    610 
    611 } // namespace
    612