2
0
mirror of https://github.com/boostorg/url.git synced 2026-01-21 17:32:21 +00:00
Files
url/test/unit/segments.cpp
alandefreitas 5c307a889a use pct_encoded_view
fix #235, fix #223, fix #168, fix #164, fix #163, fix #159
2022-07-26 17:46:56 -03:00

531 lines
16 KiB
C++

//
// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
// Copyright (c) 2022 Alan de Freitas (alandefreitas@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.hpp>
#include <boost/url/static_pool.hpp>
#include <boost/url/url.hpp>
#include <boost/static_assert.hpp>
#include <boost/core/ignore_unused.hpp>
#include <initializer_list>
#include <iterator>
#include "test_suite.hpp"
namespace boost {
namespace urls {
//------------------------------------------------
class segments_test
{
public:
static_pool<4096> p_;
void
testMembers()
{
// operator=(segments const&)
{
url u1;
url u2;
segments p1 = u1.segments();
segments p2 = u2.segments();
p2 = p1;
BOOST_TEST_EQ(p1.begin(), p2.begin());
}
url_view const u0 = parse_uri(
"x://y/path/to/the/file.txt?q#f").value();
{
url u = u0;
u.segments() = { "etc", "index.htm" };
BOOST_TEST_EQ(u.encoded_path(), "/etc/index.htm");
BOOST_TEST_EQ(u.string(), "x://y/etc/index.htm?q#f");
}
}
void
testElementAccess()
{
url_view const u0 = parse_relative_ref(
"/path/to/the/file.txt").value();
// at
{
url u = u0;
auto se = u.segments();
auto const& cs = se;
BOOST_TEST_EQ(*se.begin(), "path");
BOOST_TEST_EQ(*std::next(se.begin()), "to");
BOOST_TEST_EQ(*std::next(se.begin(), 2), "the");
BOOST_TEST_EQ(*std::next(se.begin(), 3), "file.txt");
BOOST_TEST_EQ(*std::next(cs.begin(), 0), "path");
BOOST_TEST_EQ(*std::next(cs.begin()), "to");
BOOST_TEST_EQ(*std::next(cs.begin(), 2), "the");
BOOST_TEST_EQ(*std::next(cs.begin(), 3), "file.txt");
se.replace(std::next(se.begin()), "from");
// comparison
BOOST_TEST_EQ(*std::next(se.begin()), "from");
BOOST_TEST_EQ(*std::next(cs.begin()), "from");
BOOST_TEST_NE(*std::next(se.begin()), "path");
BOOST_TEST_NE(*std::next(cs.begin()), "path");
}
// operator[]
{
url u = u0;
auto se = u.segments();
auto const& cs = se;
BOOST_TEST_EQ(*se.begin(), "path");
BOOST_TEST_EQ(*std::next(se.begin()), "to");
BOOST_TEST_EQ(*std::next(se.begin(), 2), "the");
BOOST_TEST_EQ(*std::next(se.begin(), 3), "file.txt");
BOOST_TEST_EQ(*std::next(cs.begin(), 0), "path");
BOOST_TEST_EQ(*std::next(cs.begin()), "to");
BOOST_TEST_EQ(*std::next(cs.begin(), 2), "the");
BOOST_TEST_EQ(*std::next(cs.begin(), 3), "file.txt");
// assign
se.replace(std::next(se.begin()), "from");
// comparison
BOOST_TEST_EQ(*std::next(se.begin()), "from");
BOOST_TEST_EQ(*std::next(cs.begin()), "from");
BOOST_TEST_NE(*std::next(se.begin()), "path");
BOOST_TEST_NE(*std::next(cs.begin()), "path");
}
// front
{
url u = u0;
auto se = u.segments();
auto const& cs = se;
BOOST_TEST_EQ(se.front(), "path");
BOOST_TEST_EQ(cs.front(), "path");
// assign
se.replace(se.begin(), "etc");
BOOST_TEST_EQ(u.string(),
"/etc/to/the/file.txt");
// comparison
BOOST_TEST_EQ(se.front(), "etc");
BOOST_TEST_EQ(cs.front(), "etc");
BOOST_TEST_EQ(*std::next(se.begin()), "to");
BOOST_TEST_EQ(*std::next(cs.begin()), "to");
BOOST_TEST_NE(se.front(), "path");
BOOST_TEST_NE(cs.front(), "path");
}
// back
{
url u = u0;
auto se = u.segments();
auto const& cs = se;
BOOST_TEST_EQ(se.back(), "file.txt");
BOOST_TEST_EQ(cs.back(), "file.txt");
// assign
se.replace(std::prev(se.end()), "index.htm");
BOOST_TEST_EQ(u.string(),
"/path/to/the/index.htm");
// comparison
BOOST_TEST_EQ(se.back(), "index.htm");
BOOST_TEST_EQ(cs.back(), "index.htm");
BOOST_TEST_NE(se.back(), "file.txt");
BOOST_TEST_NE(cs.back(), "file.txt");
}
}
void
testIterators()
{
url_view const u0 = parse_uri(
"x://y/path/to/the/file.txt").value();
// (default-ctor)
{
segments::iterator it;
boost::ignore_unused(it);
}
// begin
{
url u = u0;
auto se = u.segments();
auto const& cs = se;
BOOST_TEST_EQ(se.begin(), cs.begin());
BOOST_TEST_NE(se.end(), se.begin());
}
// end
{
url u = u0;
auto se = u.segments();
auto const& cs = se;
BOOST_TEST_EQ(se.end(), cs.end());
BOOST_TEST_NE(se.begin(), se.end());
}
//
// iterator
//
{
url u = u0;
auto se = u.segments();
auto const& cs(se);
segments::iterator it = se.begin();
BOOST_TEST_EQ(*it, "path");
BOOST_TEST_EQ(*++it, "to");
BOOST_TEST_EQ(*it++, "to");
BOOST_TEST_EQ(*it--, "the");
BOOST_TEST_EQ(*it, "to");
BOOST_TEST_EQ(*--it, "path");
BOOST_TEST_EQ(it, se.begin());
BOOST_TEST_NE(it, se.end());
std::advance(it, 1);
BOOST_TEST_EQ(*it, "to");
BOOST_TEST_EQ(*std::next(it), "the");
BOOST_TEST_EQ(*std::next(it), "the");
--it;
BOOST_TEST_EQ(*it, "path");
std::advance(it, 2);
BOOST_TEST_EQ(*std::prev(it), "to");
--it;
BOOST_TEST_EQ(std::distance(se.begin(), it), 1);
BOOST_TEST_EQ(std::distance(it, se.end()), 3);
BOOST_TEST_EQ(*it, "to");
BOOST_TEST_EQ(*std::next(it), "the");
BOOST_TEST_NE(it, se.begin());
BOOST_TEST_NE(it, cs.begin());
}
// value_type outlives reference
{
segments::value_type v;
{
url u = u0;
segments se = u.segments();
segments::reference r =
*se.begin();
v = segments::value_type(r);
}
BOOST_TEST_EQ(v, "path");
}
}
void
testCapacity()
{
url_view const u0 = parse_uri(
"x://y/path/to/the/file.txt").value();
// empty
{
url u = u0;
auto se = u.segments();
auto const& cs = se;
BOOST_TEST(! se.empty());
BOOST_TEST(! cs.empty());
}
// size
{
url u = u0;
auto se = u.segments();
auto const& cs = se;
BOOST_TEST_EQ(se.size(), 4u);
BOOST_TEST_EQ(cs.size(), 4u);
}
}
void
testModifiers()
{
// clear
{
url u = parse_uri("x://y/path/to/the/file.txt").value();
auto se = u.segments();
BOOST_TEST(! se.empty());
BOOST_TEST_EQ(se.size(), 4u);
se.clear();
BOOST_TEST(se.empty());
BOOST_TEST_EQ(se.size(), 0u);
BOOST_TEST_EQ(u.encoded_path(), "/");
BOOST_TEST_EQ(u.string(), "x://y/");
}
// insert( const_iterator, string_view )
{
url u = parse_uri("x://y/path/file.txt?q#f").value();
auto se = u.segments();
auto const& cs(se);
BOOST_TEST_EQ(se.size(), 2u);
auto it =
se.insert(std::next(se.begin()), "to");
BOOST_TEST_EQ(se.size(), 3u);
BOOST_TEST_EQ(u.encoded_path(), "/path/to/file.txt");
BOOST_TEST_EQ(u.string(), "x://y/path/to/file.txt?q#f");
BOOST_TEST_EQ(*it, "to");
it = se.insert(cs.end(), "");
BOOST_TEST_EQ(se.size(), 4u);
BOOST_TEST_EQ(u.encoded_path(), "/path/to/file.txt/");
BOOST_TEST_EQ(u.string(), "x://y/path/to/file.txt/?q#f");
BOOST_TEST_EQ(*it, "");
it = se.insert(se.begin(), "etc");
BOOST_TEST_EQ(se.size(), 5u);
BOOST_TEST_EQ(u.encoded_path(), "/etc/path/to/file.txt/");
BOOST_TEST_EQ(u.string(), "x://y/etc/path/to/file.txt/?q#f");
BOOST_TEST_EQ(*it, "etc");
}
{
// rootless
url u = parse_uri("x:path/file.txt?q#f").value();
auto se = u.segments();
auto const& cs(se);
BOOST_TEST_EQ(se.size(), 2u);
auto it =
se.insert(std::next(se.begin()), "to");
BOOST_TEST_EQ(se.size(), 3u);
BOOST_TEST_EQ(u.encoded_path(), "path/to/file.txt");
BOOST_TEST_EQ(u.string(), "x:path/to/file.txt?q#f");
BOOST_TEST_EQ(*it, "to");
it = se.insert(cs.end(), "");
BOOST_TEST_EQ(se.size(), 4u);
BOOST_TEST_EQ(u.encoded_path(), "path/to/file.txt/");
BOOST_TEST_EQ(u.string(), "x:path/to/file.txt/?q#f");
BOOST_TEST_EQ(*it, "");
it = se.insert(se.begin(), "etc");
BOOST_TEST_EQ(se.size(), 5u);
BOOST_TEST_EQ(u.encoded_path(), "etc/path/to/file.txt/");
BOOST_TEST_EQ(u.string(), "x:etc/path/to/file.txt/?q#f");
BOOST_TEST_EQ(*it, "etc");
}
// insert( const_iterator, FwdIt, FwdIt )
{
url u = parse_uri("x://y/path/file.txt?q#f").value();
auto se = u.segments();
auto const& cs(se);
std::initializer_list<string_view> init = {"to", "the" };
auto it = se.insert(
std::next(se.begin()), init.begin(), init.end());
BOOST_TEST_EQ(cs.size(), 4u);
BOOST_TEST_EQ(*it, "to");
BOOST_TEST_EQ(u.encoded_path(), "/path/to/the/file.txt");
BOOST_TEST_EQ(u.string(), "x://y/path/to/the/file.txt?q#f");
// empty range
it = se.insert(std::next(se.begin()),
init.begin(), init.begin());
BOOST_TEST_EQ(u.encoded_path(), "/path/to/the/file.txt");
BOOST_TEST_EQ(it, std::next(se.begin()));
}
{
// rootless
url u = parse_uri("x:the/file.txt?q#f").value();
auto se = u.segments();
auto const& cs(se);
std::initializer_list<string_view> init = {"path", "to" };
auto it = se.insert(
se.begin(), init.begin(), init.end());
BOOST_TEST_EQ(cs.size(), 4u);
BOOST_TEST_EQ(*it, "path");
BOOST_TEST_EQ(u.encoded_path(), "path/to/the/file.txt");
BOOST_TEST_EQ(u.string(), "x:path/to/the/file.txt?q#f");
// empty range
it = se.insert(std::next(se.begin()),
init.begin(), init.begin());
BOOST_TEST_EQ(u.encoded_path(), "path/to/the/file.txt");
BOOST_TEST_EQ(it, std::next(se.begin()));
}
// insert( const_iterator, initializer_list )
{
url u = parse_uri("x://y/path/file.txt?q#f").value();
auto se = u.segments();
auto const& cs(se);
std::initializer_list<
string_view> init = {
"to", "the" };
auto it = se.insert(std::next(se.begin()), init);
BOOST_TEST_EQ(cs.size(), 4u);
BOOST_TEST_EQ(*it, "to");
BOOST_TEST_EQ(u.encoded_path(), "/path/to/the/file.txt");
BOOST_TEST_EQ(u.string(), "x://y/path/to/the/file.txt?q#f");
}
// erase( const_iterator )
{
url u = parse_uri("x://y/path/to/the/file.txt?q#f").value();
auto se = u.segments();
se.erase(std::next(se.begin()));
BOOST_TEST_EQ(se.size(), 3u);
BOOST_TEST_EQ(u.encoded_path(), "/path/the/file.txt");
BOOST_TEST_EQ(u.string(), "x://y/path/the/file.txt?q#f");
se.erase(se.begin());
BOOST_TEST_EQ(se.size(), 2u);
BOOST_TEST_EQ(u.encoded_path(), "/the/file.txt");
BOOST_TEST_EQ(u.string(), "x://y/the/file.txt?q#f");
se.erase(std::prev(se.end()));
BOOST_TEST_EQ(se.size(), 1u);
BOOST_TEST_EQ(u.encoded_path(), "/the");
BOOST_TEST_EQ(u.string(), "x://y/the?q#f");
se.erase(se.begin());
BOOST_TEST(se.empty());
BOOST_TEST_EQ(u.encoded_path(), "/");
BOOST_TEST_EQ(u.string(), "x://y/?q#f");
}
// erase( const_iterator, const_iterator )
{
url u = parse_uri(
"x://y/home/etc/path/to/the/file.txt?q#f").value();
auto se = u.segments();
se.erase(se.begin(), std::next(se.begin(), 2));
BOOST_TEST_EQ(u.encoded_path(), "/path/to/the/file.txt");
BOOST_TEST_EQ(u.string(), "x://y/path/to/the/file.txt?q#f");
se.erase(se.begin(), se.end());
BOOST_TEST_EQ(u.encoded_path(), "/");
BOOST_TEST_EQ(u.string(), "x://y/?q#f");
}
// replace(iterator, iterator, initializer-list)
{
// initializer_list<String>
url u = parse_relative_ref(
"/a/b/c/d/e/f/g").value();
segments ss = u.segments();
auto it = ss.replace(
std::next(ss.begin()),
std::next(ss.begin(), 3),
{ "x", "y", "z" });
BOOST_TEST_EQ(it, std::next(ss.begin()));
BOOST_TEST(u.encoded_path() ==
"/a/x/y/z/d/e/f/g");
}
{
// initializer_list<string_view>
url u = parse_relative_ref(
"/a/b/c/d/e/f/g").value();
segments ss = u.segments();
auto it = ss.replace(
std::next(ss.begin()),
std::next(ss.begin(), 3), {
string_view("x"),
string_view("y"),
string_view("z") });
BOOST_TEST_EQ(it, std::next(ss.begin()));
BOOST_TEST(u.encoded_path() ==
"/a/x/y/z/d/e/f/g");
}
// push_back(string_view)
// push_back(String)
#if 0
{
url u;
auto se = u.segments();
se.push_back("path");
BOOST_TEST_EQ(u.encoded_path(), "path");
se.push_back("to");
BOOST_TEST_EQ(u.encoded_path(), "path/to");
se.push_back("file.txt");
BOOST_TEST_EQ(u.encoded_path(), "path/to/file.txt");
}
{
url u;
auto se = u.segments();
u.set_path_absolute(true);
se.push_back("path");
BOOST_TEST_EQ(u.encoded_path(), "/path");
se.push_back("to");
BOOST_TEST_EQ(u.encoded_path(), "/path/to");
se.push_back("file.txt");
BOOST_TEST_EQ(u.encoded_path(), "/path/to/file.txt");
}
#endif
// pop_back
{
url u = parse_uri(
"x://y/path/to/file.txt?q#f").value();
auto se = u.segments();
BOOST_TEST_EQ(se.size(), 3u);
se.pop_back();
BOOST_TEST_EQ(se.size(), 2u);
BOOST_TEST_EQ(u.encoded_path(), "/path/to");
BOOST_TEST_EQ(u.string(), "x://y/path/to?q#f");
se.pop_back();
BOOST_TEST_EQ(se.size(), 1u);
BOOST_TEST_EQ(u.encoded_path(), "/path");
BOOST_TEST_EQ(u.string(), "x://y/path?q#f");
se.pop_back();
BOOST_TEST_EQ(se.size(), 0u);
BOOST_TEST_EQ(u.encoded_path(), "/");
BOOST_TEST_EQ(u.string(), "x://y/?q#f");
}
}
void
run()
{
testMembers();
testElementAccess();
testIterators();
testCapacity();
testModifiers();
}
};
TEST_SUITE(
segments_test,
"boost.url.segments");
} // urls
} // boost