// // 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 #include #include "test_suite.hpp" #include #include #include #include #include namespace boost { namespace urls { class segments_encoded_view_test { public: template static std::reverse_iterator reverse(It const& it) { return std::reverse_iterator(it); } void bad(string_view s, result ( *f)(string_view)) { segments_encoded_view p; BOOST_TEST_THROWS(p = f(s).value(), std::exception); BOOST_TEST(p.empty()); BOOST_TEST_EQ(p.begin(), p.end()); } void check( string_view s, std::vector< string_view> const& v0, result( *f)(string_view)) { segments_encoded_view sv; BOOST_TEST_NO_THROW(sv = f(s).value()); // forward { std::vector v1; std::copy( sv.begin(), sv.end(), std::back_inserter(v1)); BOOST_TEST_EQ(v0, v1); } // reverse { std::vector v1; std::copy( reverse(sv.end()), reverse(sv.begin()), std::back_inserter(v1)); std::reverse(v1.begin(), v1.end()); BOOST_TEST_EQ(v0, v1); } } //-------------------------------------------- void testMembers() { // default constructor { segments_encoded_view sv; BOOST_TEST(sv.empty()); BOOST_TEST_EQ(sv.size(), 0u); BOOST_TEST( sv.begin() == sv.end()); } // operator=(segments_view const&) { segments_encoded_view s1; segments_encoded_view s2; s1 = s2; BOOST_TEST_EQ(s1.begin(), s2.begin()); } // 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(); BOOST_TEST_EQ(sv.size(), 3u); 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_EQ(sv.front(), "path"); BOOST_TEST_EQ(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_EQ(it1, it2); BOOST_TEST_NE(it1, sv.begin()); BOOST_TEST_NE(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_EQ(it2, it1); BOOST_TEST_EQ(*it1, *it2); BOOST_TEST_EQ(*it1, "path"); BOOST_TEST_EQ(*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_NE(it2, it1); it2 = it1; BOOST_TEST_EQ(it2, it1); BOOST_TEST_EQ(*it1, *it2); BOOST_TEST_EQ(*it1, "path"); BOOST_TEST_EQ(*it2, "path"); } // operator* // operator++ // operator++(int) { segments_encoded_view sv = parse_path( "/path/to/file.txt").value(); iter_t it = sv.begin(); BOOST_TEST_EQ(*it, "path"); BOOST_TEST_EQ(*++it, "to"); BOOST_TEST_EQ(*it++, "to"); BOOST_TEST_EQ(*it++, "file.txt"); BOOST_TEST_EQ(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_EQ(*--it, "file.txt"); BOOST_TEST_EQ(*it--, "file.txt"); BOOST_TEST_EQ(*it, "to"); BOOST_TEST_EQ(*--it, "path"); BOOST_TEST_EQ(it, sv.begin()); } // operator == // operator != { segments_encoded_view sv = parse_path( "/path/to/file.txt").value(); iter_t it = sv.begin(); BOOST_TEST_EQ(it, sv.begin()); BOOST_TEST_NE(it, sv.end()); BOOST_TEST_NE(++it, sv.begin()); BOOST_TEST_NE(it++, sv.end()); } // value_type outlives reference { segments_encoded_view::value_type v; { segments_encoded_view sv = parse_path( "/path/to/file.txt").value(); segments_encoded_view::reference r = *sv.begin(); v = segments_encoded_view::value_type(r); } BOOST_TEST_EQ(v, "path"); } } //-------------------------------------------- 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 testCapacity() { segments_encoded_view sv; BOOST_TEST(sv.empty()); BOOST_TEST_EQ(sv.size(), 0u); sv = parse_path("/path/to/file.txt").value(); BOOST_TEST(! sv.empty()); BOOST_TEST_EQ(sv.size(), 3u); sv = {}; BOOST_TEST(sv.empty()); BOOST_TEST_EQ(sv.size(), 0u); } void testOutput() { std::stringstream ss; segments_encoded_view sv = parse_path( "/path/to/file.txt").value(); ss << sv; BOOST_TEST_EQ(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(); testExamples(); } }; TEST_SUITE( segments_encoded_view_test, "boost.url.segments_encoded_view"); } // urls } // boost