summaryrefslogtreecommitdiff
path: root/test/test-url.cc
diff options
context:
space:
mode:
Diffstat (limited to 'test/test-url.cc')
-rw-r--r--test/test-url.cc212
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;
+}