2
0
mirror of https://github.com/boostorg/url.git synced 2026-01-20 05:02:43 +00:00
Files
url/test/unit/segments_encoded_view.cpp
Vinnie Falco cdbe24fc7e docs and tidy
2021-10-02 17:44:30 -07:00

430 lines
12 KiB
C++

//
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/CPPAlliance/url
//
// Test that header file is self-contained.
#include <boost/url/segments_encoded_view.hpp>
#include <boost/url/url_view.hpp>
#include "test_suite.hpp"
#include <algorithm>
#include <iostream>
#include <sstream>
#include <utility>
#include <vector>
namespace boost {
namespace urls {
class segments_encoded_view_test
{
public:
#if __cpp_lib_ranges >= 201911
/*
BOOST_STATIC_ASSERT(
std::bidirectional_range<
segments_encoded_view>);
*/
BOOST_STATIC_ASSERT(
std::bidirectional_iterator<
segments_encoded_view::iterator>);
#endif
template<class It>
static
std::reverse_iterator<It>
reverse(It const& it)
{
return std::reverse_iterator<It>(it);
}
void
bad(string_view s,
result<segments_encoded_view> (
*f)(string_view))
{
segments_encoded_view p;
BOOST_TEST_THROWS(p = f(s).value(),
std::exception);
BOOST_TEST(p.empty());
BOOST_TEST(p.begin() == p.end());
}
void
check(
string_view s,
std::vector<
string_view> const& v0,
result<segments_encoded_view>(
*f)(string_view))
{
segments_encoded_view sv;
BOOST_TEST_NO_THROW(sv = f(s).value());
// forward
{
std::vector<string_view> v1;
std::copy(
sv.begin(),
sv.end(),
std::back_inserter(v1));
BOOST_TEST(v0 == v1);
}
// reverse
{
std::vector<string_view> v1;
std::copy(
reverse(sv.end()),
reverse(sv.begin()),
std::back_inserter(v1));
std::reverse(v1.begin(), v1.end());
BOOST_TEST(v0 == v1);
}
}
//--------------------------------------------
void
testMembers()
{
// default constructor
{
segments_encoded_view sv;
BOOST_TEST(sv.empty());
BOOST_TEST(sv.size() == 0);
BOOST_TEST(
sv.begin() == sv.end());
}
// decoded
{
segments_encoded_view sev = parse_path(
"/%70%61%74%68/%74%6f/%66%69%6c%65%2e%74%78%74").value();
segments_view sv = sev.decoded(
std::allocator<char>{});
BOOST_TEST(sv.size() == 3);
BOOST_TEST(sv.is_absolute());
}
// is_absolute
{
BOOST_TEST(parse_path(
"/path/to/file.txt").value().is_absolute());
BOOST_TEST(! parse_path(
"./my/downloads").value().is_absolute());
}
}
void
testElementAccess()
{
// front
// back
{
segments_encoded_view sv = parse_path(
"/path/to/file.txt").value();
BOOST_TEST(sv.front() == "path");
BOOST_TEST(sv.back() == "file.txt");
}
}
void
testIterators()
{
using iter_t =
segments_encoded_view::iterator;
// iterator()
{
segments_encoded_view sv = parse_path(
"/path/to/file.txt").value();
iter_t it1;
iter_t it2;
BOOST_TEST(it1 == it2);
BOOST_TEST(it1 != sv.begin());
BOOST_TEST(it2 != sv.begin());
}
// iterator(iterator const&)
{
segments_encoded_view sv = parse_path(
"/path/to/file.txt").value();
iter_t it1 = sv.begin();
iter_t it2(it1);
BOOST_TEST(it2 == it1);
BOOST_TEST(*it1 == *it2);
BOOST_TEST(*it1 == "path");
BOOST_TEST(*it2 == "path");
}
// operator=(iterator const&)
{
segments_encoded_view sv = parse_path(
"/path/to/file.txt").value();
iter_t it1;
it1 = sv.begin();
iter_t it2;
it2 = sv.end();
BOOST_TEST(it2 != it1);
it2 = it1;
BOOST_TEST(it2 == it1);
BOOST_TEST(*it1 == *it2);
BOOST_TEST(*it1 == "path");
BOOST_TEST(*it2 == "path");
}
// operator*
// operator++
// operator++(int)
{
segments_encoded_view sv = parse_path(
"/path/to/file.txt").value();
iter_t it = sv.begin();
BOOST_TEST(*it == "path");
BOOST_TEST(*++it == "to");
BOOST_TEST(*it++ == "to");
BOOST_TEST(*it++ == "file.txt");
BOOST_TEST(it == sv.end());
}
// operator*
// operator--
// operator--(int)
{
segments_encoded_view sv = parse_path(
"/path/to/file.txt").value();
iter_t it = sv.end();
BOOST_TEST(*--it == "file.txt");
BOOST_TEST(*it-- == "file.txt");
BOOST_TEST(*it == "to");
BOOST_TEST(*--it == "path");
BOOST_TEST(it == sv.begin());
}
// operator ==
// operator !=
{
segments_encoded_view sv = parse_path(
"/path/to/file.txt").value();
iter_t it = sv.begin();
BOOST_TEST(it == sv.begin());
BOOST_TEST(it != sv.end());
BOOST_TEST(++it != sv.begin());
BOOST_TEST(it++ != sv.end());
}
}
//--------------------------------------------
void
test_parse_path()
{
/*
path = [ "/" ] segment *( "/" segment )
*/
check("", {}, &parse_path);
check("/", {""}, &parse_path);
check("/a", {"a"}, &parse_path);
check("/:", {":"}, &parse_path);
check("/:/", {":",""}, &parse_path);
check("/a/", {"a",""}, &parse_path);
check("/a/b", {"a","b"}, &parse_path);
check("/%41/b", {"%41","b"}, &parse_path);
check("///b", {"","","b"}, &parse_path);
check("/%2f/b", {"%2f","b"}, &parse_path);
check("/%2541//", {"%2541","",""}, &parse_path);
check("/a/b/c", {"a","b","c"}, &parse_path);
check("a", {"a"}, &parse_path);
check("a/", {"a", ""}, &parse_path);
bad("/%2", &parse_path);
bad("/%%", &parse_path);
}
void
test_parse_path_abempty()
{
/*
path-abempty = *( "/" segment )
*/
check("", {}, &parse_path_abempty);
check("/", {""}, &parse_path_abempty);
check("/a", {"a"}, &parse_path_abempty);
check("/:", {":"}, &parse_path_abempty);
check("/:/", {":",""}, &parse_path_abempty);
check("/a/", {"a",""}, &parse_path_abempty);
check("/a/b", {"a","b"}, &parse_path_abempty);
check("/%41/b", {"%41","b"}, &parse_path_abempty);
check("///b", {"","","b"}, &parse_path_abempty);
check("/%2f/b", {"%2f","b"}, &parse_path_abempty);
check("/%2541//", {"%2541","",""}, &parse_path_abempty);
check("/a/b/c", {"a","b","c"}, &parse_path_abempty);
bad("a", &parse_path_abempty);
bad("a/", &parse_path_abempty);
bad("/%2", &parse_path_abempty);
bad("/%%", &parse_path_abempty);
}
void
test_parse_path_absolute()
{
/*
path-absolute = "/" [ segment-nz *( "/" segment ) ]
*/
check("/", {""}, &parse_path_absolute);
check("/a", {"a"}, &parse_path_absolute);
check("/a/", {"a",""}, &parse_path_absolute);
check("/:", {":"}, &parse_path_absolute);
check("/:/", {":",""}, &parse_path_absolute);
check("/a/b", {"a","b"}, &parse_path_absolute);
check("/%41/b", {"%41","b"}, &parse_path_absolute);
check("/%2f/b", {"%2f","b"}, &parse_path_absolute);
check("/%2541//", {"%2541","",""}, &parse_path_absolute);
check("/a/b/c", {"a","b","c"}, &parse_path_abempty);
bad("", &parse_path_absolute);
bad("//", &parse_path_absolute);
bad("///b", &parse_path_absolute);
bad("a", &parse_path_absolute);
bad("a/", &parse_path_absolute);
bad("/%2", &parse_path_absolute);
bad("/%%", &parse_path_absolute);
}
void
test_parse_path_noscheme()
{
/*
path-noscheme = segment-nz-nc *( "/" segment )
*/
check("a", {"a"}, &parse_path_noscheme);
check("a/", {"a",""}, &parse_path_noscheme);
check("a/b", {"a","b"}, &parse_path_noscheme);
check("%41/b", {"%41","b"}, &parse_path_noscheme);
check("%2f/b", {"%2f","b"}, &parse_path_noscheme);
check("%2541//", {"%2541","",""}, &parse_path_noscheme);
check("http%3a//a.htm", {"http%3a","","a.htm"}, &parse_path_noscheme);
check("a/b/c", {"a","b","c"}, &parse_path_noscheme);
bad("", &parse_path_noscheme);
bad("%2g/", &parse_path_noscheme);
bad("/", &parse_path_noscheme);
bad("/:", &parse_path_noscheme);
bad(":", &parse_path_noscheme);
bad("a:", &parse_path_noscheme);
bad(":/", &parse_path_noscheme);
bad("a:a", &parse_path_noscheme);
}
void
test_parse_path_rootless()
{
/*
path-rootless = segment-nz *( "/" segment )
*/
check(":", {":"}, &parse_path_rootless);
check("a:", {"a:"}, &parse_path_rootless);
check(":/", {":",""}, &parse_path_rootless);
check("a:a", {"a:a"}, &parse_path_rootless);
check("a", {"a"}, &parse_path_rootless);
check("a/", {"a",""}, &parse_path_rootless);
check("a/b", {"a","b"}, &parse_path_rootless);
check("%41/b", {"%41","b"}, &parse_path_rootless);
check("%2f/b", {"%2f","b"}, &parse_path_rootless);
check("%2541//", {"%2541","",""}, &parse_path_rootless);
check("http%3a//a.htm", {"http%3a","","a.htm"}, &parse_path_rootless);
check("a/b/c", {"a","b","c"}, &parse_path_rootless);
bad("", &parse_path_rootless);
bad("/", &parse_path_rootless);
bad("/:", &parse_path_rootless);
}
void
testCapacity()
{
segments_encoded_view sv;
BOOST_TEST(sv.empty());
BOOST_TEST(sv.size() == 0);
sv = parse_path("/path/to/file.txt").value();
BOOST_TEST(! sv.empty());
BOOST_TEST(sv.size() == 3);
sv = {};
BOOST_TEST(sv.empty());
BOOST_TEST(sv.size() == 0);
}
void
testOutput()
{
std::stringstream ss;
segments_encoded_view sv = parse_path(
"/path/to/file.txt").value();
ss << sv;
BOOST_TEST(ss.str() == "/path/to/file.txt");
}
void
testExamples()
{
{
segments_encoded_view sev = parse_path( "/path/to/file.txt" ).value();
for( auto it = sev.begin(); it != sev.end(); ++it )
std::cout << *it << std::endl;
}
{
url_view u = parse_uri( "http://example.com/path/to/file.txt" ).value();
segments_encoded_view sev = u.encoded_segments();
std::cout << sev << std::endl;
}
//---
{
segments_encoded_view sev = parse_path( "/%70%61%74%68/%74%6f/%66%69%6c%65%2e%74%78%74" ).value();
segments_view sv = sev.decoded();
std::stringstream ss;
ss << sv.front() << "/../" << sv.back();
assert( ss.str() == "path/../file.txt" );
}
}
void
run()
{
testMembers();
testElementAccess();
testIterators();
testCapacity();
testOutput();
test_parse_path();
test_parse_path_abempty();
test_parse_path_absolute();
test_parse_path_noscheme();
test_parse_path_rootless();
testExamples();
}
};
TEST_SUITE(
segments_encoded_view_test,
"boost.url.segments_encoded_view");
} // urls
} // boost