/mordor/tests/uri.cpp
C++ | 510 lines | 439 code | 53 blank | 18 comment | 3 complexity | 7f787a5a8f7f53212c30416363585571 MD5 | raw file
Possible License(s): BSD-3-Clause
1// Copyright (c) 2009 - Mozy, Inc. 2 3#include "mordor/uri.h" 4#include "mordor/streams/buffer.h" 5#include "mordor/test/test.h" 6 7using namespace Mordor; 8using namespace Mordor::Test; 9 10static void serializeAndParse(const char *uri, const char *expected = NULL) 11{ 12 if (!expected) expected = uri; 13 MORDOR_TEST_ASSERT_EQUAL(URI(uri).toString(), expected); 14} 15 16MORDOR_UNITTEST(URI, serializationAndParsing) 17{ 18 MORDOR_TEST_ASSERT_EQUAL(URI::Path("/a/b/c/./../../g").toString(), 19 "/a/b/c/./../../g"); 20 serializeAndParse("example://a/b/c/%7Bfoo%7D"); 21 serializeAndParse("eXAMPLE://a/./b/../b/%63/%7bfoo%7d", "eXAMPLE://a/./b/../b/c/%7Bfoo%7D"); 22 serializeAndParse("http://a/b/c/d;p?q"); 23 serializeAndParse("g:h"); 24 serializeAndParse("g"); 25 serializeAndParse("http://a/b/c/g"); 26 serializeAndParse("./g"); 27 serializeAndParse("g/"); 28 serializeAndParse("http://a/b/c/g/"); 29 serializeAndParse("/g"); 30 serializeAndParse("http://a/g"); 31 serializeAndParse("//g"); 32 serializeAndParse("http://g"); 33 serializeAndParse("?y"); 34 serializeAndParse("http://a/b/c/d;p?y"); 35 serializeAndParse("g?y"); 36 serializeAndParse("http://a/b/c/g?y"); 37 serializeAndParse("#s"); 38 serializeAndParse("http://a/b/c/d;p?q#s"); 39 serializeAndParse("g#s"); 40 serializeAndParse("http://a/b/c/g#s"); 41 serializeAndParse("g?y#s"); 42 serializeAndParse("http://a/b/c/g?y#s"); 43 serializeAndParse(";x"); 44 serializeAndParse("http://a/b/c/;x"); 45 serializeAndParse("g;x"); 46 serializeAndParse("http://a/b/c/g;x"); 47 serializeAndParse("g;x?y#s"); 48 serializeAndParse("http://a/b/c/g;x?y#s"); 49 serializeAndParse(""); 50 serializeAndParse("http://a/b/c/d;p?q"); 51 serializeAndParse("."); 52 serializeAndParse("http://a/b/c/"); 53 serializeAndParse("./"); 54 serializeAndParse(".."); 55 serializeAndParse("http://a/b/"); 56 serializeAndParse("../"); 57 serializeAndParse("../g"); 58 serializeAndParse("http://a/b/g"); 59 serializeAndParse("../.."); 60 serializeAndParse("http://a/"); 61 serializeAndParse("../../"); 62 serializeAndParse("../../g"); 63 serializeAndParse("http://a/g"); 64 serializeAndParse("../../../g"); 65 serializeAndParse("../../../../g"); 66 serializeAndParse("/./g"); 67 serializeAndParse("/../g"); 68 serializeAndParse("g."); 69 serializeAndParse("http://a/b/c/g."); 70 serializeAndParse(".g"); 71 serializeAndParse("http://a/b/c/.g"); 72 serializeAndParse("g.."); 73 serializeAndParse("http://a/b/c/g.."); 74 serializeAndParse("..g"); 75 serializeAndParse("http://a/b/c/..g"); 76 serializeAndParse("./../g"); 77 serializeAndParse("./g/."); 78 serializeAndParse("http://a/b/c/g/"); 79 serializeAndParse("g/./h"); 80 serializeAndParse("http://a/b/c/g/h"); 81 serializeAndParse("g/../h"); 82 serializeAndParse("http://a/b/c/h"); 83 serializeAndParse("g;x=1/./y"); 84 serializeAndParse("http://a/b/c/g;x=1/y"); 85 serializeAndParse("g;x=1/../y"); 86 serializeAndParse("http://a/b/c/y"); 87 serializeAndParse("g?y/./x"); 88 serializeAndParse("http://a/b/c/g?y/./x"); 89 serializeAndParse("g?y/../x"); 90 serializeAndParse("http://a/b/c/g?y/../x"); 91 serializeAndParse("g#s/./x"); 92 serializeAndParse("http://a/b/c/g#s/./x"); 93 serializeAndParse("g#s/../x"); 94 serializeAndParse("http://a/b/c/g#s/../x"); 95 serializeAndParse("http:g"); 96 serializeAndParse("http:/hi"); 97 serializeAndParse("http:////hi"); 98} 99 100MORDOR_UNITTEST(URI, pathNormalization) 101{ 102 URI::Path p("/a/b/c/./../../g"); 103 p.removeDotComponents(); 104 MORDOR_TEST_ASSERT_EQUAL(p, URI::Path("/a/g")); 105} 106 107MORDOR_UNITTEST(URI, normalization) 108{ 109 URI lhs("example://a/b/c/%7Bfoo%7D"); 110 URI rhs("eXAMPLE://a/./b/../b/%63/%7bfoo%7d"); 111 112 lhs.normalize(); 113 rhs.normalize(); 114 115 MORDOR_TEST_ASSERT(lhs.isDefined()); 116 MORDOR_TEST_ASSERT(rhs.isDefined()); 117 MORDOR_TEST_ASSERT(lhs.schemeDefined()); 118 MORDOR_TEST_ASSERT(rhs.schemeDefined()); 119 MORDOR_TEST_ASSERT_EQUAL(lhs.scheme(), rhs.scheme()); 120 MORDOR_TEST_ASSERT(!lhs.authority.portDefined()); 121 MORDOR_TEST_ASSERT(!rhs.authority.portDefined()); 122 MORDOR_TEST_ASSERT(lhs.authority.hostDefined()); 123 MORDOR_TEST_ASSERT(rhs.authority.hostDefined()); 124 MORDOR_TEST_ASSERT_EQUAL(lhs.authority.host(), rhs.authority.host()); 125 MORDOR_TEST_ASSERT(!lhs.authority.userinfoDefined()); 126 MORDOR_TEST_ASSERT(!rhs.authority.userinfoDefined()); 127 MORDOR_TEST_ASSERT_EQUAL(lhs.authority, rhs.authority); 128 MORDOR_TEST_ASSERT_EQUAL(lhs.path.segments, rhs.path.segments); 129 MORDOR_TEST_ASSERT_EQUAL(lhs.path, rhs.path); 130 MORDOR_TEST_ASSERT(!lhs.queryDefined()); 131 MORDOR_TEST_ASSERT(!rhs.queryDefined()); 132 MORDOR_TEST_ASSERT(!lhs.fragmentDefined()); 133 MORDOR_TEST_ASSERT(!rhs.fragmentDefined()); 134 MORDOR_TEST_ASSERT_EQUAL(lhs, rhs); 135} 136 137MORDOR_UNITTEST(URI, transform) 138{ 139 URI base("http://a/b/c/d;p?q"); 140 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("g:h")), URI("g:h")); 141 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("g")), URI("http://a/b/c/g")); 142 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("./g")), URI("http://a/b/c/g")); 143 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("g/")), URI("http://a/b/c/g/")); 144 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("/g")), URI("http://a/g")); 145 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("//g")), URI("http://g")); 146 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("?y")), URI("http://a/b/c/d;p?y")); 147 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("g?y")), URI("http://a/b/c/g?y")); 148 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("#s")), URI("http://a/b/c/d;p?q#s")); 149 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("g#s")), URI("http://a/b/c/g#s")); 150 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("g?y#s")), URI("http://a/b/c/g?y#s")); 151 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI(";x")), URI("http://a/b/c/;x")); 152 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("g;x")), URI("http://a/b/c/g;x")); 153 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("g;x?y#s")), URI("http://a/b/c/g;x?y#s")); 154 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("")), URI("http://a/b/c/d;p?q")); 155 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI(".")), URI("http://a/b/c/")); 156 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("./")), URI("http://a/b/c/")); 157 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("..")), URI("http://a/b/")); 158 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("../")), URI("http://a/b/")); 159 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("../g")), URI("http://a/b/g")); 160 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("../..")), URI("http://a/")); 161 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("../../")), URI("http://a/")); 162 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("../../g")), URI("http://a/g")); 163 164 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("../../../g")), URI("http://a/g")); 165 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("../../../../g")), URI("http://a/g")); 166 167 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("/./g")), URI("http://a/g")); 168 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("/../g")), URI("http://a/g")); 169 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("g.")), URI("http://a/b/c/g.")); 170 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI(".g")), URI("http://a/b/c/.g")); 171 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("g..")), URI("http://a/b/c/g..")); 172 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("..g")), URI("http://a/b/c/..g")); 173 174 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("./../g")), URI("http://a/b/g")); 175 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("./g/.")), URI("http://a/b/c/g/")); 176 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("g/./h")), URI("http://a/b/c/g/h")); 177 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("g/../h")), URI("http://a/b/c/h")); 178 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("g;x=1/./y")), URI("http://a/b/c/g;x=1/y")); 179 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("g;x=1/../y")), URI("http://a/b/c/y")); 180 181 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("g?y/./x")), URI("http://a/b/c/g?y/./x")); 182 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("g?y/../x")), URI("http://a/b/c/g?y/../x")); 183 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("g#s/./x")), URI("http://a/b/c/g#s/./x")); 184 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("g#s/../x")), URI("http://a/b/c/g#s/../x")); 185 186 MORDOR_TEST_ASSERT_EQUAL(URI::transform(base, URI("http:g")), URI("http:g")); 187 188 MORDOR_TEST_ASSERT_EQUAL(URI::transform("http:hi", "bob"), "http:bob"); 189 MORDOR_TEST_ASSERT_EQUAL(URI::transform("http://authority", "bob"), "http://authority/bob"); 190} 191 192MORDOR_UNITTEST(URI, serializeCompleteOnBlockBoundary) 193{ 194 Buffer b("http://abc/"); 195 b.copyIn("more"); 196 URI uri(b); 197 MORDOR_TEST_ASSERT_EQUAL(URI(b), "http://abc/more"); 198} 199 200MORDOR_UNITTEST(URI, bigBase64URI) 201{ 202 serializeAndParse("/partialObjects/" 203 "49ZtbkNPlEEi8T+sQLb5mh9zm1DcyaaRoyHUOC9sEfaKIgLh+eKZNUrqR+j3Iybhx321iz" 204 "y3J+Mw7gZmIlVcZrP0qHNDxuEQHMUHLqxhXoXcN18+x4XedNLqc8KhnJtHLXndcKMJu5Cg" 205 "xp2BI9NXDDDuBmYiVVxms/Soc0PG4RAcxQcurGFehSY0Wf0fG5eWquA0b0hozVjE4xxyAF" 206 "TkSU39Hl3XcsUUMO4GZiJVXGaz9KhzQ8bhEBzFBy6sYV6F9718Fox0OiJ3PqBvo2gr352W" 207 "vZBqmEeUV1n0CkcClc0w7gZmIlVcZrP0qHNDxuEQHMUHLqxhXoWapmDUfha0WO9SjTUn4F" 208 "Jeht8Gjdy6mYpDqvUbB+3OoDDuBmYiVVxms/Soc0PG4RAcxQcurGFehcefjKkVeAR2HShU" 209 "2UpBh5g/89ZP9czSJ8qKSKCPGyHWMO4GZiJVXGaz9KhzQ8bhEBzFBy6sYV6FAig0fJADqV" 210 "eInu5RU/pgEXJlZ1MBce/F+rv7MI3g5jgw7gZmIlVcZrP0qHNDxuEQHMUHLqxhXoW4GIxe" 211 "C1lnhkTtrAv3jhk17r3ZwL8Fq7CvpUHeAQl/JTDuBmYiVVxms/Soc0PG4RAcxQcurGFehc" 212 "s4fMw9uBwTihHQAPFbcyDTjZtTMGlaovGaP6xe1H1TMO4GZiJVXGaz9KhzQ8bhEBzFBy6s" 213 "YV6FFAhiH0dzP8E0IRZP+oxeL2JkfxiO5v8r7eWnYtMY8d4w7gZmIlVcZrP0qHNDxuEQHM" 214 "UHLqxhXoUgoQ1pQreM2tYMR9QaJ7CsSOSJs+Qi5KIzV50DBUYLDjDuBmYiVVxms/Soc0PG" 215 "4RAcxQcurGFehdeUg8nHldHqihIknc3OP/QRtBawAyEFY4p0RKlRxnA0MO4GZiJVXGaz9K" 216 "hzQ8bhEBzFBy6sYV6FbRY5v48No3N72yRSA9JiYPhS/YTYcUFz"); 217} 218 219MORDOR_UNITTEST(URI, queryString) 220{ 221 URI uri("http://a/b?a&b"); 222 MORDOR_TEST_ASSERT(uri.queryDefined()); 223 MORDOR_TEST_ASSERT_EQUAL(uri.query(), "a&b"); 224 uri = "http://a/b?a%20b"; 225 MORDOR_TEST_ASSERT(uri.queryDefined()); 226 MORDOR_TEST_ASSERT_EQUAL(uri.query(), "a b"); 227 URI::QueryString qs = uri.queryString(); 228 229 MORDOR_TEST_ASSERT_EQUAL(qs.size(), 1u); 230 MORDOR_TEST_ASSERT_EQUAL(qs.begin()->first, "a b"); 231 MORDOR_TEST_ASSERT_EQUAL(qs.toString(), "a+b"); 232 233 qs = "a%2Bb"; 234 MORDOR_TEST_ASSERT_EQUAL(qs.size(), 1u); 235 MORDOR_TEST_ASSERT_EQUAL(qs.begin()->first, "a+b"); 236 MORDOR_TEST_ASSERT_EQUAL(qs.toString(), "a%2Bb"); 237 238 qs = "a&b;c"; 239 MORDOR_TEST_ASSERT_EQUAL(qs.size(), 3u); 240 URI::QueryString::iterator it = qs.begin(); 241 MORDOR_TEST_ASSERT_EQUAL(it->first, "a"); 242 ++it; 243 MORDOR_TEST_ASSERT_EQUAL(it->first, "b"); 244 ++it; 245 MORDOR_TEST_ASSERT_EQUAL(it->first, "c"); 246 247 qs = "a+b"; 248 MORDOR_TEST_ASSERT_EQUAL(qs.size(), 1u); 249 MORDOR_TEST_ASSERT_EQUAL(qs.begin()->first, "a b"); 250 MORDOR_TEST_ASSERT_EQUAL(qs.toString(), "a+b"); 251 252 qs = ""; 253 MORDOR_TEST_ASSERT(qs.empty()); 254 MORDOR_TEST_ASSERT_EQUAL(qs.toString(), ""); 255 256 qs = "&&;&&;;&"; 257 MORDOR_TEST_ASSERT(qs.empty()); 258 MORDOR_TEST_ASSERT_EQUAL(qs.toString(), ""); 259 260 qs = "a=b&c"; 261 MORDOR_TEST_ASSERT_EQUAL(qs.size(), 2u); 262 it = qs.begin(); 263 MORDOR_TEST_ASSERT_EQUAL(it->first, "a"); 264 MORDOR_TEST_ASSERT_EQUAL(it->second, "b"); 265 ++it; 266 MORDOR_TEST_ASSERT_EQUAL(it->first, "c"); 267 268 qs = "a=b=c=d&e=f=g=h"; 269 MORDOR_TEST_ASSERT_EQUAL(qs.size(), 2u); 270 it = qs.begin(); 271 MORDOR_TEST_ASSERT_EQUAL(it->first, "a"); 272 MORDOR_TEST_ASSERT_EQUAL(it->second, "b=c=d"); 273 ++it; 274 MORDOR_TEST_ASSERT_EQUAL(it->first, "e"); 275 MORDOR_TEST_ASSERT_EQUAL(it->second, "f=g=h"); 276 277 qs = "a="; 278 MORDOR_TEST_ASSERT_EQUAL(qs.size(), 1u); 279 it = qs.begin(); 280 MORDOR_TEST_ASSERT_EQUAL(it->first, "a"); 281 MORDOR_TEST_ASSERT(it->second.empty()); 282 283 qs = "a=&=b&="; 284 MORDOR_TEST_ASSERT_EQUAL(qs.size(), 2u); 285 it = qs.begin(); 286 MORDOR_TEST_ASSERT(it->first.empty()); 287 MORDOR_TEST_ASSERT_EQUAL(it->second, "b"); 288 ++it; 289 MORDOR_TEST_ASSERT_EQUAL(it->first, "a"); 290 MORDOR_TEST_ASSERT(it->second.empty()); 291 292 qs.clear(); 293 qs.insert(std::make_pair("ampersand", "and&and")); 294 MORDOR_TEST_ASSERT_EQUAL(qs.toString(), "ampersand=and%26and"); 295 296 uri = URI(); 297 uri.query(qs); 298 MORDOR_TEST_ASSERT_EQUAL(uri.toString(), "?ampersand=and%26and"); 299} 300 301MORDOR_UNITTEST(URI, encoding) 302{ 303 URI uri; 304 uri.path.segments.push_back(std::string()); 305 uri.path.segments.push_back("WiX Tutorial \xe2\x80\x94 Introduction to the Windows Installer XML Toolset.URL"); 306 MORDOR_TEST_ASSERT_EQUAL(uri.toString(), 307 "/WiX%20Tutorial%20%E2%80%94%20Introduction%20to%20the%20Windows%20Installer%20XML%20Toolset.URL"); 308 309 uri.path.segments[1] = "\xe5\xa4\x9a\xe8\xa8\x80\xe8\xaa\x9e\xe5\xaf\xbe\xe5\xbf\x9c\xe3\x82" 310 "\xb5\xe3\x83\xbc\xe3\x83\x81\xe3\x82\xa8\xe3\x83\xb3\xe3\x82\xb8\xe3" 311 "\x83\xb3\xe3\x81\xae\xe6\x97\xa5\xe6\x9c\xac\xe7\x89\x88\xe3\x80\x82" 312 "\xe3\x82\xa6\xe3\x82\xa7\xe3\x83\x96\xe3\x80\x81\xe3\x82\xa4\xe3\x83" 313 "\xa1\xe3\x83\xbc\xe3\x82\xb8\xe3\x81\x8a\xe3\x82\x88\xe3\x81\xb3\xe3" 314 "\x83\x8b\xe3\x83\xa5\xe3\x83\xbc\xe3\x82\xb9\xe6\xa4\x9c\xe7\xb4\xa2.txt"; 315 MORDOR_TEST_ASSERT_EQUAL(uri.toString(), 316 "/%E5%A4%9A%E8%A8%80%E8%AA%9E%E5%AF%BE%E5%BF%9C%E3%82" 317 "%B5%E3%83%BC%E3%83%81%E3%82%A8%E3%83%B3%E3%82%B8%E3" 318 "%83%B3%E3%81%AE%E6%97%A5%E6%9C%AC%E7%89%88%E3%80%82" 319 "%E3%82%A6%E3%82%A7%E3%83%96%E3%80%81%E3%82%A4%E3%83" 320 "%A1%E3%83%BC%E3%82%B8%E3%81%8A%E3%82%88%E3%81%B3%E3" 321 "%83%8B%E3%83%A5%E3%83%BC%E3%82%B9%E6%A4%9C%E7%B4%A2.txt"); 322} 323 324MORDOR_UNITTEST(URI, emptyFirstComponent) 325{ 326 serializeAndParse("/"); 327 serializeAndParse("http://localhost/"); 328 serializeAndParse("http://localhost//"); 329 serializeAndParse("http://localhost///"); 330 331 URI::Path path; 332 path = "/"; 333 MORDOR_TEST_ASSERT_EQUAL(path.segments.size(), 2u); 334 MORDOR_TEST_ASSERT(path.isAbsolute()); 335 MORDOR_TEST_ASSERT(path.segments.front().empty()); 336 MORDOR_TEST_ASSERT(path.segments.back().empty()); 337 path = ""; 338 MORDOR_TEST_ASSERT(path.isRelative()); 339 MORDOR_TEST_ASSERT(path.segments.empty()); 340 path = "//"; 341 MORDOR_TEST_ASSERT(path.isAbsolute()); 342 MORDOR_TEST_ASSERT_EQUAL(path.segments.size(), 3u); 343 path = "a//"; 344 MORDOR_TEST_ASSERT(path.isRelative()); 345 MORDOR_TEST_ASSERT_EQUAL(path.segments.size(), 3u); 346 347 URI uri = "http://localhost/"; 348 MORDOR_TEST_ASSERT_EQUAL(uri.toString(), "http://localhost/"); 349 uri.path.append("hi"); 350 MORDOR_TEST_ASSERT_EQUAL(uri.toString(), "http://localhost/hi"); 351 uri.path.segments.push_back(""); 352 MORDOR_TEST_ASSERT_EQUAL(uri.toString(), "http://localhost/hi/"); 353 uri.path.segments.push_back("bye"); 354 MORDOR_TEST_ASSERT_EQUAL(uri.toString(), "http://localhost/hi//bye"); 355 uri.path.segments.push_back(""); 356 MORDOR_TEST_ASSERT_EQUAL(uri.toString(), "http://localhost/hi//bye/"); 357 uri.path.append("adios"); 358 MORDOR_TEST_ASSERT_EQUAL(uri.toString(), "http://localhost/hi//bye/adios"); 359 uri = "http://localhost/"; 360 uri.path.append("hi"); 361 MORDOR_TEST_ASSERT_EQUAL(uri.toString(), "http://localhost/hi"); 362 363 // scheme == http, authority is not defined, path = "//hi"; 364 // serialization has to add an extra // so it's not ambiguous with 365 // authority 366 uri = URI(); 367 uri.scheme("http"); 368 uri.path.segments.push_back(std::string()); 369 uri.path.segments.push_back(std::string()); 370 uri.path.segments.push_back("hi"); 371 MORDOR_TEST_ASSERT_EQUAL(uri.toString(), "http:////hi"); 372} 373 374MORDOR_UNITTEST(URI, append) 375{ 376 URI uri = "http://localhost"; 377 uri.path.append("hi"); 378 MORDOR_TEST_ASSERT_EQUAL(uri, "http://localhost/hi"); 379 uri.path.append("bye"); 380 MORDOR_TEST_ASSERT_EQUAL(uri, "http://localhost/hi/bye"); 381 uri.path.append(std::string()); 382 MORDOR_TEST_ASSERT_EQUAL(uri, "http://localhost/hi/bye/"); 383 uri.path.append(std::string()); 384 MORDOR_TEST_ASSERT_EQUAL(uri, "http://localhost/hi/bye/"); 385 386 uri = "http:"; 387 uri.path.append("hi"); 388 MORDOR_TEST_ASSERT_EQUAL(uri, "http:hi"); 389 uri.path.append("bye"); 390 MORDOR_TEST_ASSERT_EQUAL(uri, "http:hi/bye"); 391 392 URI::Path path; 393 path.append("hi"); 394 MORDOR_TEST_ASSERT_EQUAL(path, "hi"); 395 path.append("bye"); 396 MORDOR_TEST_ASSERT_EQUAL(path, "hi/bye"); 397 398 // The following four tests ensure that path's hidden pointer back to the 399 // URI owning it is copied/assigned correctly through URI and Path's 400 // copy constructors and assignement operators 401 402 // Force operator=(const URI &uri) 403 URI uri2 = "http://localhost"; 404 uri = uri2; 405 uri2.authority.hostDefined(false); 406 uri.path.append("hi"); 407 MORDOR_TEST_ASSERT_EQUAL(uri, "http://localhost/hi"); 408 409 // Force URI::URI(const URI &uri) 410 uri2.authority.host("localhost"); 411 URI uri3(uri2); 412 uri2.authority.hostDefined(false); 413 uri3.path.append("hi"); 414 MORDOR_TEST_ASSERT_EQUAL(uri3, "http://localhost/hi"); 415 416 // Force operator=(const Path &path) 417 path = uri3.path; 418 path.segments.clear(); 419 path.append("hi"); 420 MORDOR_TEST_ASSERT_EQUAL(path, "hi"); 421 422 // Force Path::Path(const Path &path) 423 URI::Path path2(uri3.path); 424 path2.segments.clear(); 425 path2.append("hi"); 426 MORDOR_TEST_ASSERT_EQUAL(path2, "hi"); 427} 428 429MORDOR_UNITTEST(URI, makeAbsolute) 430{ 431 URI::Path path; 432 path.makeAbsolute(); 433 MORDOR_TEST_ASSERT_EQUAL(path, "/"); 434 path.makeAbsolute(); 435 MORDOR_TEST_ASSERT_EQUAL(path, "/"); 436 path.makeRelative(); 437 MORDOR_TEST_ASSERT(path.segments.empty()); 438 path.makeRelative(); 439 MORDOR_TEST_ASSERT(path.segments.empty()); 440 path.append("hi"); 441 MORDOR_TEST_ASSERT_EQUAL(path, "hi"); 442 path.makeAbsolute(); 443 MORDOR_TEST_ASSERT_EQUAL(path, "/hi"); 444 path.makeAbsolute(); 445 MORDOR_TEST_ASSERT_EQUAL(path, "/hi"); 446 path.makeRelative(); 447 MORDOR_TEST_ASSERT_EQUAL(path, "hi"); 448 path.makeRelative(); 449 MORDOR_TEST_ASSERT_EQUAL(path, "hi"); 450} 451 452MORDOR_UNITTEST(URI, queryStringConvenience) 453{ 454 URI::QueryString qs; 455 qs["a"] = "1"; 456 457 MORDOR_TEST_ASSERT_EQUAL(qs.size(), 1u); 458 MORDOR_TEST_ASSERT_EQUAL(qs.toString(), "a=1"); 459 qs.insert(std::make_pair("a", "2")); 460 MORDOR_TEST_ASSERT_EQUAL(qs.size(), 2u); 461 MORDOR_TEST_ASSERT_EQUAL(qs.toString(), "a=1&a=2"); 462 // Returns only the first item (removing others) 463 qs["a"] = "3"; 464 MORDOR_TEST_ASSERT_EQUAL(qs.size(), 1u); 465 MORDOR_TEST_ASSERT_EQUAL(qs.toString(), "a=3"); 466 qs.insert(std::make_pair("a", "4")); 467 // Implicitly creates the item, even though we don't assign to it 468 MORDOR_TEST_ASSERT(qs["b"].empty()); 469 MORDOR_TEST_ASSERT_EQUAL(qs.size(), 3u); 470 MORDOR_TEST_ASSERT_EQUAL(qs.toString(), "a=3&a=4&b"); 471 472 // Make sure we're using equal_range correctly (insert between existing elements) 473 qs["a2"] = "5"; 474 MORDOR_TEST_ASSERT_EQUAL(qs.size(), 4u); 475 MORDOR_TEST_ASSERT_EQUAL(qs.toString(), "a=3&a=4&a2=5&b"); 476 477 // Create a const reference, so we call the const version 478 const URI::QueryString &qs2 = qs; 479 // Does not create a new item 480 MORDOR_TEST_ASSERT(qs2["c"].empty()); 481 MORDOR_TEST_ASSERT_EQUAL(qs.size(), 4u); 482 MORDOR_TEST_ASSERT_EQUAL(qs.toString(), "a=3&a=4&a2=5&b"); 483 484 // Returns the first item, but keeps the rest 485 MORDOR_TEST_ASSERT_EQUAL(qs2["a"], "3"); 486 MORDOR_TEST_ASSERT_EQUAL(qs.size(), 4u); 487 MORDOR_TEST_ASSERT_EQUAL(qs.toString(), "a=3&a=4&a2=5&b"); 488 489 // Does not create a new item (in between) 490 MORDOR_TEST_ASSERT(qs2["a3"].empty()); 491 MORDOR_TEST_ASSERT_EQUAL(qs.size(), 4u); 492 MORDOR_TEST_ASSERT_EQUAL(qs.toString(), "a=3&a=4&a2=5&b"); 493} 494 495MORDOR_UNITTEST(URI, decodeOK) 496{ 497 std::string str("https%3A%2F%2Fredmine.mozycorp.com%2Fissues%2F118200"); 498 MORDOR_TEST_ASSERT_EQUAL(URI::decode(str), "https://redmine.mozycorp.com/issues/118200"); 499} 500 501MORDOR_UNITTEST(URI, decodeInvalidURL) 502{ 503 std::vector<std::string> invalidStr; 504 invalidStr.push_back("%4"); // invalid length, should have 2 chars after % 505 invalidStr.push_back("%3xpath"); // invalid first char after % 506 invalidStr.push_back("%x3path"); // invalid second char after % 507 for (std::vector<std::string>::iterator it = invalidStr.begin(); it != invalidStr.end(); ++it) { 508 MORDOR_TEST_ASSERT_EXCEPTION(URI::decode(*it), std::invalid_argument); 509 } 510}