diff options
Diffstat (limited to 'test/test-url.cc')
| -rw-r--r-- | test/test-url.cc | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/test/test-url.cc b/test/test-url.cc new file mode 100644 index 0000000..79e6564 --- /dev/null +++ b/test/test-url.cc @@ -0,0 +1,212 @@ +// -*- mode: c++; c-basic-offset: 2; -*- + +#include "common.hh" +#include "test.hh" + +#include <cstring> +#include <memory> +#include <sstream> + +#include "url.hh" + +namespace { + +bool good(std::string const& url, + std::string const& scheme, + char const* userinfo, + std::string const& host, + uint16_t port, + std::string const& path, + char const* query, + char const* fragment) { + std::unique_ptr<Url> u(Url::parse(url)); + if (!u) { + std::cerr << "good:" << url << ": Invalid url" << std::endl; + return false; + } + if (scheme != u->scheme()) { + std::cerr << "good:" << url << ":scheme: Expected " << scheme + << " got " << u->scheme() << std::endl; + return false; + } + if (userinfo) { + if (u->userinfo()) { + if (strcmp(userinfo, u->userinfo())) { + std::cerr << "good:" << url << ":authority: Expected " << userinfo + << " got " << u->userinfo() << std::endl; + return false; + } + } else { + std::cerr << "good:" << url << ":authority: Expected " << userinfo + << " got no authority" << std::endl; + return false; + } + } else { + if (u->userinfo()) { + std::cerr << "good:" << url << ":authority: Expected no authority" + << " got " << u->userinfo() << std::endl; + return false; + } + } + if (host != u->host()) { + std::cerr << "good:" << url << ":host: Expected " << host + << " got " << u->host() << std::endl; + return false; + } + if (port != u->port()) { + std::cerr << "good:" << url << ":port: Expected " << port + << " got " << u->port() << std::endl; + return false; + } + if (path != u->path()) { + std::cerr << "good:" << url << ":path: Expected " << path + << " got " << u->path() << std::endl; + return false; + } + if (query) { + if (u->full_query()) { + if (strcmp(query, u->full_query())) { + std::cerr << "good:" << url << ":query: Expected " << query + << " got " << u->full_query() << std::endl; + return false; + } + } else { + std::cerr << "good:" << url << ":query: Expected " << query + << " got no query" << std::endl; + return false; + } + } else { + if (u->full_query()) { + std::cerr << "good:" << url << ":query: Expected no query" + << " got " << u->full_query() << std::endl; + return false; + } + } + if (fragment) { + if (u->fragment()) { + if (strcmp(fragment, u->fragment())) { + std::cerr << "good:" << url << ":fragment: Expected " << fragment + << " got " << u->fragment() << std::endl; + return false; + } + } else { + std::cerr << "good:" << url << ":fragment: Expected " << fragment + << " got no fragment" << std::endl; + return false; + } + } else { + if (u->fragment()) { + std::cerr << "good:" << url << ":fragment: Expected no fragment" + << " got " << u->fragment() << std::endl; + return false; + } + } + + return true; +} + +bool query(std::string const& url, std::string const& name, + char const* value) { + std::unique_ptr<Url> u(Url::parse(url)); + if (!u) { + std::cerr << "query:" << url << ":" << name + << ": Invalid url" << std::endl; + return false; + } + std::string tmp; + if (u->query(name, &tmp)) { + if (!value) { + std::cerr << "query:" << url << ":" << name + << ": Expected no value got " << tmp << std::endl; + return false; + } + if (tmp.compare(value)) { + std::cerr << "query:" << url << ":" << name + << ": Expected " << value << " got " << tmp << std::endl; + return false; + } + } else { + if (value) { + std::cerr << "query:" << url << ":" << name + << ": Expected " << value << " got no value" << std::endl; + return false; + } + } + return true; +} + +bool bad(std::string const& url) { + std::unique_ptr<Url> u(Url::parse(url)); + if (u) { + std::cerr << "bad:" << url << ": Expected invalid url got "; + u->print(std::cerr); + std::cerr << std::endl; + return false; + } + return true; +} + +bool relative(std::string const& url, std::string const& base, + std::string const& full) { + std::unique_ptr<Url> b(Url::parse(base)); + if (!b) { + std::cerr << "relative:" << url << ":" << base + << ": Invalid base url" << std::endl; + return false; + } + std::unique_ptr<Url> u(Url::parse(url, b.get())); + if (!u) { + std::cerr << "relative:" << url << ":" << base + << ": Invalid url" << std::endl; + return false; + } + std::stringstream ss; + u->print(ss); + if (full != ss.str()) { + std::cerr << "relative:" << url << ":" << base + << ": Expected " << full << " got " << ss.str() << std::endl; + return false; + } + return true; +} + +} // namespace + +int main() { + BEFORE; + RUN(good("http://example.org", + "http", nullptr, "example.org", 0, "", nullptr, nullptr)); + RUN(good("http://example.org/", + "http", nullptr, "example.org", 0, "/", nullptr, nullptr)); + RUN(good("http://example.org/index.htm", + "http", nullptr, "example.org", 0, "/index.htm", nullptr, nullptr)); + RUN(good("http://example.org:80?foo", + "http", nullptr, "example.org", 80, "", "foo", nullptr)); + RUN(good("http://user@example.org#foo", + "http", "user", "example.org", 0, "", nullptr, "foo")); + RUN(good("http://user:pw@example.org?foo#bar", + "http", "user:pw", "example.org", 0, "", "foo", "bar")); + RUN(good("http://%40user@example.org/foo%2fbar?a=%25+%20+%23#frag%25", + "http", "@user", "example.org", 0, "/foo/bar", "a=% #", "frag%")); + RUN(query("http://host?foo=bar", "foo", "bar")); + RUN(query("http://host?foo=bar", "bar", nullptr)); + RUN(query("http://host?foo=bar", "fo", nullptr)); + RUN(query("http://host?foo=bar", "", nullptr)); + RUN(query("http://host?foo=bar&foo=k", "foo", "bar")); + RUN(query("http://host?foo=bar&bar=foo", "bar", "foo")); + RUN(bad("")); + RUN(bad("/")); + RUN(bad("http")); + RUN(bad("http://")); + RUN(bad("http:///")); + RUN(bad("http://meh@/")); + RUN(bad("http://.meh@/")); + RUN(bad("http://.meh@/foo#frag?q")); + RUN(relative("/foo", "http://host/bar", "http://host/foo")); + RUN(relative("foo", "http://host/bar", "http://host/bar/foo")); + RUN(relative("foo?a=c", "http://host/?a=b", "http://host/foo?a=c")); + RUN(relative("foo#c", "http://host/#b", "http://host/foo#c")); + RUN(relative("foo#c", "http://host/?b", "http://host/foo#c")); + RUN(relative("foo", "http://host/?b", "http://host/foo")); + AFTER; +} |
