Added path views for abs and rel paths
This commit is contained in:
@@ -0,0 +1,948 @@
|
||||
#include "StdAfx.h"
|
||||
#include "tl/abs_path.h"
|
||||
#include "tl/rel_path.h"
|
||||
|
||||
#include "tl/utest.h"
|
||||
#include "TestHelpers.h"
|
||||
#include "tl/abs_path_view.h"
|
||||
|
||||
TL_DECLARE_STRING_LITERAL(posix_root_tag, "/");
|
||||
TL_DECLARE_STRING_VECTOR(posix_parse_separators, "/");
|
||||
TL_DECLARE_STRING_LITERAL(posix_format_separator, "/");
|
||||
using posix_system = tl::simple_path_system<posix_root_tag, posix_parse_separators, posix_format_separator>;
|
||||
|
||||
TL_DECLARE_STRING_LITERAL(unc_root_tag, "\\\\");
|
||||
TL_DECLARE_STRING_VECTOR(unc_parse_separators, "\\", "/");
|
||||
TL_DECLARE_STRING_LITERAL(unc_format_separator, "\\");
|
||||
using unc_system = tl::simple_path_system<unc_root_tag, unc_parse_separators, unc_format_separator>;
|
||||
|
||||
using test_abs_path = tl::abs_path<tl::path_systems<posix_system, unc_system>>;
|
||||
using test_rel_path = test_abs_path::rel_path_type;
|
||||
|
||||
using test_abs_path_view = tl::abs_path_view<tl::path_systems<posix_system, unc_system>>;
|
||||
using test_rel_path_view = test_abs_path_view::rel_path_view_type;
|
||||
|
||||
#define PATH_TEST_EQ(a, b) EXPECT_EQ(test_abs_path(a), test_abs_path(b))
|
||||
|
||||
UTEST(thread_safety, thread_safety)
|
||||
{
|
||||
std::thread thread1;
|
||||
std::thread thread2;
|
||||
|
||||
thread1 = std::thread([]
|
||||
{
|
||||
test_rel_path path;
|
||||
for (volatile size_t i = 0; i < 1000; i++)
|
||||
{
|
||||
path = "a/b/c/d";
|
||||
char result = 'a' + static_cast<char>(i % 20);
|
||||
char buf[2] = { result , 0 };
|
||||
path += (const char*)buf;
|
||||
}
|
||||
});
|
||||
|
||||
thread2 = std::thread([]
|
||||
{
|
||||
test_rel_path path;
|
||||
for (volatile size_t i = 0; i < 1000; i++)
|
||||
{
|
||||
path = "a/b/c/d";
|
||||
char result = 'a' + static_cast<char>(i % 20);
|
||||
char buf[2] = { result , 0 };
|
||||
path += (const char*)buf;
|
||||
}
|
||||
});
|
||||
|
||||
if (thread1.joinable())
|
||||
{
|
||||
thread1.join();
|
||||
}
|
||||
if (thread2.joinable())
|
||||
{
|
||||
thread2.join();
|
||||
}
|
||||
}
|
||||
|
||||
UTEST(Path, Path)
|
||||
{
|
||||
{
|
||||
test_abs_path path;
|
||||
EXPECT_TRUE(path.empty());
|
||||
EXPECT_EQ(path.size(), 0);
|
||||
}
|
||||
{
|
||||
test_abs_path path("/a");
|
||||
EXPECT_TRUE(!path.empty());
|
||||
EXPECT_EQ(path.size(), 1);
|
||||
EXPECT_TRUE(path.is<posix_system>());
|
||||
EXPECT_EQ(path[0], "a");
|
||||
|
||||
test_abs_path path2("/a");
|
||||
test_abs_path path3("/");
|
||||
EXPECT_EQ(path, path2);
|
||||
EXPECT_NE(path, path3);
|
||||
|
||||
test_abs_path path4("\\\\");
|
||||
EXPECT_NE(path3, path4);
|
||||
}
|
||||
{
|
||||
test_abs_path path("/a/");
|
||||
EXPECT_TRUE(!path.empty());
|
||||
EXPECT_EQ(path.size(), 1);
|
||||
EXPECT_TRUE(path.is<posix_system>());
|
||||
EXPECT_EQ(path[0], "a");
|
||||
}
|
||||
{
|
||||
test_abs_path path("\\\\a");
|
||||
EXPECT_TRUE(!path.empty());
|
||||
EXPECT_EQ(path.size(), 1);
|
||||
EXPECT_TRUE(path.is<unc_system>());
|
||||
EXPECT_EQ(path[0], "a");
|
||||
}
|
||||
{
|
||||
test_abs_path path("\\\\a\\");
|
||||
EXPECT_TRUE(!path.empty());
|
||||
EXPECT_EQ(path.size(), 1);
|
||||
EXPECT_TRUE(path.is<unc_system>());
|
||||
EXPECT_EQ(path[0], "a");
|
||||
}
|
||||
{
|
||||
test_abs_path path("/a/b");
|
||||
EXPECT_TRUE(!path.empty());
|
||||
EXPECT_EQ(path.size(), 2);
|
||||
EXPECT_EQ(path[0], "a");
|
||||
EXPECT_EQ(path[1], "b");
|
||||
}
|
||||
{
|
||||
//Note - Here we test that the posix path only uses / as separator
|
||||
test_abs_path path("/a\\b");
|
||||
EXPECT_TRUE(!path.empty());
|
||||
EXPECT_EQ(path.size(), 1);
|
||||
EXPECT_EQ(path[0], "a\\b");
|
||||
}
|
||||
{
|
||||
test_abs_path path("/");
|
||||
path += "a";
|
||||
EXPECT_TRUE(!path.empty());
|
||||
EXPECT_EQ(path.size(), 1);
|
||||
EXPECT_EQ(path[0], "a");
|
||||
}
|
||||
{
|
||||
test_abs_path path;
|
||||
{
|
||||
EXPECTED_ASSERT_GUARD("Failed to parse abs path");
|
||||
path += "a";
|
||||
}
|
||||
EXPECT_TRUE(path.empty());
|
||||
EXPECT_EQ(path.size(), 0);
|
||||
}
|
||||
{
|
||||
test_abs_path path;
|
||||
path += "/a/b";
|
||||
EXPECT_TRUE(!path.empty());
|
||||
EXPECT_EQ(path.size(), 2);
|
||||
EXPECT_EQ(path[0], "a");
|
||||
EXPECT_EQ(path[1], "b");
|
||||
}
|
||||
{
|
||||
test_abs_path path;
|
||||
{
|
||||
EXPECTED_ASSERT_GUARD("Failed to parse abs path");
|
||||
path += "a";
|
||||
}
|
||||
path += "/a/b";
|
||||
EXPECT_TRUE(!path.empty());
|
||||
EXPECT_EQ(path.size(), 2);
|
||||
EXPECT_EQ(path[0], "a");
|
||||
EXPECT_EQ(path[1], "b");
|
||||
}
|
||||
{
|
||||
test_abs_path path("\\\\");
|
||||
path += "a";
|
||||
path += "b/c/d";
|
||||
EXPECT_TRUE(!path.empty());
|
||||
EXPECT_EQ(path.size(), 4);
|
||||
EXPECT_EQ(path[0], "a");
|
||||
EXPECT_EQ(path[1], "b");
|
||||
EXPECT_EQ(path[3], "d");
|
||||
}
|
||||
{
|
||||
test_abs_path path("/");
|
||||
path += "a/b";
|
||||
path += "c";
|
||||
EXPECT_TRUE(!path.empty());
|
||||
EXPECT_EQ(path.size(), 3);
|
||||
EXPECT_EQ(path[0], "a");
|
||||
EXPECT_EQ(path[1], "b");
|
||||
EXPECT_EQ(path[2], "c");
|
||||
}
|
||||
{
|
||||
test_abs_path path("/");
|
||||
path += ("a/b" + tl::string("/df"));
|
||||
EXPECT_TRUE(!path.empty());
|
||||
EXPECT_EQ(path.size(), 3);
|
||||
EXPECT_EQ(path[0], "a");
|
||||
EXPECT_EQ(path[1], "b");
|
||||
EXPECT_EQ(path[2], "df");
|
||||
}
|
||||
{
|
||||
test_abs_path path(tl::string("/"));
|
||||
path += "a/b";
|
||||
path += "c";
|
||||
path += "..";
|
||||
EXPECT_TRUE(!path.empty());
|
||||
EXPECT_EQ(path.size(), 2);
|
||||
EXPECT_EQ(path[0], "a");
|
||||
EXPECT_EQ(path[1], "b");
|
||||
path += "../..";
|
||||
EXPECT_EQ(path.size(), 0);
|
||||
EXPECT_TRUE(path.empty());
|
||||
EXPECT_TRUE(path.is<posix_system>());
|
||||
}
|
||||
{
|
||||
test_abs_path path(tl::string("\\\\"));
|
||||
path += "a/b";
|
||||
EXPECTED_ASSERT_GUARD("Invalid path");
|
||||
path += "../../..";
|
||||
EXPECT_TRUE(path.empty());
|
||||
}
|
||||
{
|
||||
test_abs_path path(tl::string("\\\\"));
|
||||
EXPECTED_ASSERT_GUARD("Invalid path");
|
||||
path.push_back("..");
|
||||
EXPECT_TRUE(path.empty());
|
||||
}
|
||||
{
|
||||
test_abs_path path(tl::string("/"));
|
||||
EXPECTED_ASSERT_GUARD("Invalid path");
|
||||
test_abs_path newPath = path + "../..";
|
||||
EXPECT_TRUE(newPath.empty());
|
||||
}
|
||||
{
|
||||
test_abs_path path(tl::string("/"));
|
||||
EXPECTED_ASSERT_GUARD("Invalid path");
|
||||
auto pathParent = path.parent();
|
||||
EXPECT_TRUE(pathParent.empty());
|
||||
}
|
||||
{
|
||||
test_abs_path path(tl::string("\\\\"));
|
||||
EXPECTED_ASSERT_GUARD("Invalid path");
|
||||
auto pathParent = path.parent();
|
||||
EXPECT_TRUE(pathParent.empty());
|
||||
}
|
||||
{
|
||||
test_abs_path path(tl::string("/"));
|
||||
EXPECTED_ASSERT_GUARD("Invalid path");
|
||||
auto pathParent = path.parent();
|
||||
EXPECT_TRUE(pathParent.empty());
|
||||
}
|
||||
{
|
||||
test_abs_path path(tl::string("/a/b/c/d"));
|
||||
test_abs_path newPath = path.parent(2);
|
||||
EXPECT_EQ(newPath, test_abs_path("/a/b"));
|
||||
}
|
||||
{
|
||||
test_abs_path path(tl::string("/a"));
|
||||
EXPECTED_ASSERT_GUARD("Invalid path");
|
||||
test_abs_path newPath = path.parent(2);
|
||||
EXPECT_TRUE(newPath.empty());
|
||||
}
|
||||
{
|
||||
test_abs_path path("/a/b/c/../d");
|
||||
EXPECT_TRUE(!path.empty());
|
||||
EXPECT_EQ(path.size(), 3);
|
||||
EXPECT_EQ(path[0], "a");
|
||||
EXPECT_EQ(path[1], "b");
|
||||
EXPECT_EQ(path[2], "d");
|
||||
path.push_back("..");
|
||||
EXPECT_EQ(path.size(), 2);
|
||||
path.push_back("../..");
|
||||
EXPECT_EQ(path.size(), 3);
|
||||
EXPECT_TRUE(path.is<posix_system>());
|
||||
}
|
||||
{
|
||||
test_abs_path path("\\\\a/b/c/d");
|
||||
auto p = path.subpath(0, 0);
|
||||
EXPECT_EQ(p, test_rel_path("a/b/c/d"));
|
||||
}
|
||||
{
|
||||
test_abs_path path("/a/b/c/d");
|
||||
auto p = path.subpath(1, 0);
|
||||
EXPECT_EQ(p, test_rel_path("b/c/d"));
|
||||
}
|
||||
{
|
||||
test_abs_path path("\\\\a/b/c/d");
|
||||
auto p = path.subpath(0, -1);
|
||||
EXPECT_EQ(p, test_rel_path("a/b/c"));
|
||||
}
|
||||
{
|
||||
test_abs_path path("/a/b/c/d");
|
||||
auto p = path.subpath(0, 2);
|
||||
EXPECT_EQ(p, test_rel_path("a/b"));
|
||||
}
|
||||
{
|
||||
test_abs_path path("\\\\a/b/c");
|
||||
auto p = path.parent();
|
||||
EXPECT_EQ(p.str(), "\\\\a\\b");
|
||||
}
|
||||
{
|
||||
test_abs_path path("/a");
|
||||
auto p = path.parent();
|
||||
EXPECT_EQ(p.str(), "/");
|
||||
EXPECT_NE(p.str(), "\\\\");
|
||||
}
|
||||
{
|
||||
EXPECTED_ASSERT_GUARD("Failed to parse abs path");
|
||||
test_abs_path path("..");
|
||||
}
|
||||
{
|
||||
EXPECTED_ASSERT_GUARD("Failed to parse abs path");
|
||||
test_abs_path path(".");
|
||||
}
|
||||
{
|
||||
EXPECTED_ASSERT_GUARD("Invalid path");
|
||||
test_abs_path path("");
|
||||
auto p = path.parent();
|
||||
EXPECT_TRUE(p.empty());
|
||||
}
|
||||
{
|
||||
test_abs_path path("/a/b/../c");
|
||||
auto p = path.parent();
|
||||
EXPECT_EQ(p.str(), "/a");
|
||||
}
|
||||
{
|
||||
test_abs_path path("/a/b/c/d");
|
||||
path.shrink(2);
|
||||
EXPECT_EQ(path, test_abs_path("/a/b"));
|
||||
}
|
||||
{
|
||||
test_abs_path path("/a/b/c/d");
|
||||
EXPECT_EQ(path.back(), "d");
|
||||
EXPECT_EQ(path.front(), "a");
|
||||
}
|
||||
{
|
||||
test_abs_path from("/a/b/c/d");
|
||||
test_abs_path to("/a/b/x/y");
|
||||
auto rel = from.path_to(to);
|
||||
EXPECT_EQ(rel, test_rel_path("../../x/y"));
|
||||
rel += "..";
|
||||
rel.collapse_path();
|
||||
EXPECT_EQ(rel, test_rel_path("../../x"));
|
||||
|
||||
test_abs_path path("/a/b/c/d");
|
||||
path += rel;
|
||||
EXPECT_EQ(path, test_abs_path("/a/b/c/d/../../x"));
|
||||
}
|
||||
{
|
||||
test_abs_path from("/a/b");
|
||||
test_abs_path to("/a/b/x/y");
|
||||
auto rel = from.path_to(to);
|
||||
EXPECT_EQ(rel, test_rel_path("x/y"));
|
||||
}
|
||||
{
|
||||
test_abs_path from("/c/d");
|
||||
test_abs_path to("/a/b/x/y");
|
||||
auto rel = from.path_to(to);
|
||||
EXPECT_EQ(rel, test_rel_path("../../a/b/x/y"));
|
||||
}
|
||||
|
||||
{
|
||||
test_abs_path p("/c/d/m/a/../s/d/a");
|
||||
tl::string s = p.str();
|
||||
EXPECT_EQ(s, "/c/d/m/s/d/a");
|
||||
}
|
||||
|
||||
{
|
||||
EXPECTED_ASSERT_GUARD("Failed to parse abs path");
|
||||
test_abs_path p("/../s/d/a");
|
||||
EXPECT_TRUE(p.empty());
|
||||
}
|
||||
|
||||
{
|
||||
EXPECTED_ASSERT_GUARD("Failed to parse abs path");
|
||||
test_abs_path p("/s/../../d/a");
|
||||
EXPECT_TRUE(p.empty());
|
||||
}
|
||||
|
||||
{
|
||||
EXPECTED_ASSERT_GUARD("Failed to parse abs path");
|
||||
test_abs_path p("/s/d/../../../a");
|
||||
EXPECT_TRUE(p.empty());
|
||||
}
|
||||
|
||||
{
|
||||
EXPECTED_ASSERT_GUARD("Failed to parse abs path");
|
||||
test_abs_path p("\\\\../a");
|
||||
EXPECT_TRUE(p.empty());
|
||||
}
|
||||
|
||||
{
|
||||
test_abs_path p("/c/d/m");
|
||||
tl::string s = p.str();
|
||||
EXPECT_EQ(s, "/c/d/m");
|
||||
}
|
||||
|
||||
{
|
||||
test_abs_path p("/foo/..bar");
|
||||
tl::string s = p.str();
|
||||
EXPECT_EQ(s, "/foo/..bar");
|
||||
}
|
||||
|
||||
{
|
||||
test_abs_path p("/foo/...");
|
||||
tl::string s = p.str();
|
||||
EXPECT_EQ(s, "/foo/...");
|
||||
}
|
||||
|
||||
{
|
||||
test_abs_path path = test_abs_path::from_string(tl::string_view{ "/a" }, test_abs_path("/b"));
|
||||
EXPECT_EQ(test_abs_path("/a"), path);
|
||||
EXPECT_NE(test_abs_path("/b"), path);
|
||||
}
|
||||
|
||||
{
|
||||
test_abs_path path = test_abs_path::from_string(tl::string_view{ "a/b" }, test_abs_path("/x"));
|
||||
EXPECT_EQ(test_abs_path("/x/a/b"), path);
|
||||
}
|
||||
|
||||
{
|
||||
EXPECTED_ASSERT_GUARD("Invalid path");
|
||||
test_abs_path path = test_abs_path::from_string(tl::string_view{ ".." }, test_abs_path("/"));
|
||||
EXPECT_TRUE(path.empty());
|
||||
}
|
||||
|
||||
{
|
||||
test_abs_path path = test_abs_path::from_string(tl::string_view{ "../.." }, test_abs_path("/a/b/d"));
|
||||
EXPECT_TRUE(path.is_valid());
|
||||
EXPECT_EQ(path, test_abs_path("/a"));
|
||||
}
|
||||
|
||||
{
|
||||
test_abs_path path = test_abs_path::from_string(tl::string_view{ "/bla" }, test_abs_path(""));
|
||||
EXPECT_TRUE(path.is_valid());
|
||||
EXPECT_EQ(path, test_abs_path("/bla"));
|
||||
}
|
||||
|
||||
{
|
||||
test_abs_path path = test_abs_path::from_string(tl::string_view{ "bla" }, test_abs_path(""));
|
||||
EXPECT_TRUE(!path.is_valid());
|
||||
}
|
||||
{
|
||||
test_abs_path path = test_abs_path::from_string(tl::string_view{ "bla" }, test_abs_path());
|
||||
EXPECT_TRUE(!path.is_valid());
|
||||
}
|
||||
{
|
||||
test_abs_path path = test_abs_path::from_string(tl::string_view{ "bla" });
|
||||
EXPECT_TRUE(!path.is_valid());
|
||||
}
|
||||
{
|
||||
test_abs_path path = test_abs_path::from_string(tl::string_view{ "/bla" });
|
||||
EXPECT_TRUE(path.is_valid());
|
||||
EXPECT_EQ(path, test_abs_path("/bla"));
|
||||
}
|
||||
|
||||
{
|
||||
test_abs_path p1 = test_abs_path("/a/bc/d");
|
||||
test_abs_path p2 = test_abs_path("/a/bd");
|
||||
|
||||
EXPECT_LT(p1, p2);
|
||||
EXPECT_GE(p1, p1);
|
||||
EXPECT_GE(p2, p1);
|
||||
}
|
||||
}
|
||||
|
||||
// non_member_tests ----------------------------------------------------------------//
|
||||
|
||||
UTEST(non_member_tests, non_member_tests)
|
||||
{
|
||||
// test non-member functions, particularly operator overloads
|
||||
|
||||
test_abs_path e, e2;
|
||||
tl::string es, es2;
|
||||
|
||||
char acs[] = "a";
|
||||
tl::string as(acs);
|
||||
test_rel_path a(as);
|
||||
|
||||
char acs2[] = "a";
|
||||
tl::string as2(acs2);
|
||||
test_rel_path a2(as2);
|
||||
|
||||
char bcs[] = "b";
|
||||
tl::string bs(bcs);
|
||||
test_rel_path b(bs);
|
||||
|
||||
// swap
|
||||
a.swap(b);
|
||||
EXPECT_EQ(a.str<posix_system>(), "b");
|
||||
EXPECT_EQ(b.str<posix_system>(), "a");
|
||||
std::swap(a, b);
|
||||
EXPECT_EQ(a.str<posix_system>(), "a");
|
||||
EXPECT_EQ(b.str<posix_system>(), "b");
|
||||
|
||||
// probe operator /
|
||||
PATH_TEST_EQ(test_abs_path("/") + ".", "/.");
|
||||
{
|
||||
EXPECTED_ASSERT_GUARD("Failed to parse abs path");
|
||||
PATH_TEST_EQ(test_abs_path("/") + "..", "/..");
|
||||
}
|
||||
{
|
||||
PATH_TEST_EQ(test_abs_path("/a") + "b", "/a/b");
|
||||
{
|
||||
EXPECTED_ASSERT_GUARD("Invalid path");
|
||||
PATH_TEST_EQ(test_abs_path("/") + "..", "");
|
||||
}
|
||||
PATH_TEST_EQ(test_abs_path("/foo") + test_rel_path("bar"), "/foo/bar"); // path arg
|
||||
PATH_TEST_EQ(test_abs_path("/foo") + "bar", "/foo/bar"); // const char* arg
|
||||
PATH_TEST_EQ(test_abs_path("/foo") + test_rel_path("woo/bar").back(), "/foo/bar"); // const std::string & arg
|
||||
PATH_TEST_EQ(test_abs_path("/foo") + "..", "/");
|
||||
PATH_TEST_EQ(test_abs_path("/f") + ".." + "b", "/b");
|
||||
PATH_TEST_EQ(test_abs_path("/foo") + "bar" + "..", "/foo");
|
||||
PATH_TEST_EQ(test_abs_path("/foo") + "bar" + ".." + "..", "/");
|
||||
PATH_TEST_EQ(test_abs_path("/foo") + "bar" + ".." + "blah", "/foo/blah");
|
||||
PATH_TEST_EQ(test_abs_path("/f") + "b" + "..", "/f");
|
||||
PATH_TEST_EQ(test_abs_path("/foo") + "bar" + "blah" + ".." + "..", "/foo");
|
||||
PATH_TEST_EQ(test_abs_path("/foo") + "bar" + "blah" + ".." + ".." + "bletch", "/foo/bletch");
|
||||
|
||||
PATH_TEST_EQ(test_abs_path("/foo") + ".", "/foo");
|
||||
PATH_TEST_EQ(test_abs_path("/foo") + "." + "bar", "/foo/bar");
|
||||
PATH_TEST_EQ(test_abs_path("/foo") + "." + ".", "/foo");
|
||||
PATH_TEST_EQ(test_abs_path("/foo") + "." + "..", "/");
|
||||
|
||||
{
|
||||
test_abs_path path(tl::string("/."));
|
||||
EXPECTED_ASSERT_GUARD("Invalid path");
|
||||
path += "./..";
|
||||
EXPECT_TRUE(path.empty());
|
||||
}
|
||||
|
||||
{
|
||||
test_abs_path path(tl::string("/."));
|
||||
EXPECTED_ASSERT_GUARD("Invalid path");
|
||||
path += "../.";
|
||||
EXPECT_TRUE(path.empty());
|
||||
}
|
||||
}
|
||||
|
||||
// make sure basic_path overloads don't conflict with std::string overloads
|
||||
|
||||
//TEST_CHECK(!(as < as));
|
||||
//TEST_CHECK(!(as < acs));
|
||||
//TEST_CHECK(!(acs < as));
|
||||
|
||||
// character set reality check before lexicographical tests
|
||||
EXPECT_LT(std::string("a.b"), std::string("a/b"));
|
||||
// verify compare is actually lexicographical
|
||||
// EXPECT_LT(path("a/b") < path("a.b"));
|
||||
EXPECT_EQ(test_abs_path("/a/b"), test_abs_path("/a///b"));
|
||||
EXPECT_EQ(test_abs_path("\\\\/a/b"), test_abs_path("\\\\a///b"));
|
||||
|
||||
// operator == and != are implemented separately, so test separately
|
||||
|
||||
test_abs_path p1("/fe/fi/fo/fum");
|
||||
test_abs_path p2(p1);
|
||||
test_abs_path p3("/fe/fi/fo/fumm");
|
||||
EXPECT_NE(p1.str(), p3.str());
|
||||
|
||||
// check each overload
|
||||
EXPECT_NE(p1, p3);
|
||||
EXPECT_NE(p1.str(), p3.str());
|
||||
EXPECT_NE(p1.str(), p3.str().c_str());
|
||||
|
||||
p3 = p2;
|
||||
EXPECT_EQ(p1.str(), p3.str());
|
||||
|
||||
// check each overload
|
||||
EXPECT_EQ(p1, p3);
|
||||
EXPECT_EQ(p1.str(), p3.str());
|
||||
EXPECT_EQ(p1.str(), p3.str().c_str());
|
||||
|
||||
}
|
||||
|
||||
UTEST(is_prefix_tests, is_prefix_tests)
|
||||
{
|
||||
test_abs_path p1{ "\\\\windows" };
|
||||
test_abs_path p2{ "\\\\windows\\system" };
|
||||
test_abs_path p3{ "\\\\windows\\system32" };
|
||||
test_abs_path p4{ "\\\\windows\\system32\\" };
|
||||
test_abs_path w1{ "/windows" };
|
||||
test_abs_path w2{ "/windows/" };
|
||||
test_abs_path w3{ "/windows/system" };
|
||||
test_abs_path w4{ "/windows/system32" };
|
||||
test_abs_path w5{ "/windows/system32/" };
|
||||
|
||||
EXPECT_TRUE(p1.is_prefix_of(p2));
|
||||
EXPECT_TRUE(!p2.is_prefix_of(p3));
|
||||
EXPECT_TRUE(p3.is_prefix_of(p4));
|
||||
EXPECT_TRUE(!p4.is_prefix_of(p1));
|
||||
|
||||
EXPECT_TRUE(w1.is_prefix_of(w2));
|
||||
EXPECT_TRUE(w2.is_prefix_of(w3));
|
||||
EXPECT_TRUE(w2.is_prefix_of(w4));
|
||||
EXPECT_TRUE(!w3.is_prefix_of(w4));
|
||||
EXPECT_TRUE(w4.is_prefix_of(w5));
|
||||
}
|
||||
|
||||
// composition_tests ----------------------------------------------------------------//
|
||||
|
||||
// construction_tests ---------------------------------------------------------------//
|
||||
|
||||
UTEST(construction_tests, construction_tests)
|
||||
{
|
||||
PATH_TEST_EQ("", "");
|
||||
PATH_TEST_EQ("/", "/");
|
||||
PATH_TEST_EQ("\\\\", "\\\\");
|
||||
|
||||
PATH_TEST_EQ("/foo", "/foo");
|
||||
|
||||
PATH_TEST_EQ("/foo/", "/foo/");
|
||||
PATH_TEST_EQ("\\\\f/", "\\\\f/");
|
||||
PATH_TEST_EQ("/foo/..", "/foo/..");
|
||||
PATH_TEST_EQ("/foo/../", "/foo/../");
|
||||
PATH_TEST_EQ("/foo/bar/../..", "/foo/bar/../..");
|
||||
PATH_TEST_EQ("/foo/bar/../../", "/foo/bar/../../");
|
||||
PATH_TEST_EQ("/f", "/f");
|
||||
|
||||
PATH_TEST_EQ("/foo/bar/", "/foo/bar/");
|
||||
PATH_TEST_EQ("//foo//bar//", "//foo//bar//");
|
||||
PATH_TEST_EQ("///foo///bar///", "///foo///bar///");
|
||||
PATH_TEST_EQ("\\\\/foo\\/bar\\/", "\\\\/foo\\/bar\\/");
|
||||
PATH_TEST_EQ("\\\\//foo\\//bar\\//", "\\\\//foo\\//bar\\//");
|
||||
PATH_TEST_EQ("\\\\\\//foo\\//bar\\//", "\\\\//foo\\//bar\\//");
|
||||
|
||||
PATH_TEST_EQ("/foo/..", "/foo/..");
|
||||
PATH_TEST_EQ("/foo/..bar", "/foo/..bar");
|
||||
PATH_TEST_EQ("/f/../f", "/f/../f");
|
||||
PATH_TEST_EQ("/f/..", "/f/..");
|
||||
PATH_TEST_EQ("/foo/../bar", "/foo/../bar");
|
||||
PATH_TEST_EQ("/foo/bar/..", "/foo/bar/..");
|
||||
PATH_TEST_EQ("/foo/bar/../..", "/foo/bar/../..");
|
||||
PATH_TEST_EQ("/foo/bar/../blah", "/foo/bar/../blah");
|
||||
PATH_TEST_EQ("/f/../b", "/f/../b");
|
||||
PATH_TEST_EQ("/f/b/..", "/f/b/..");
|
||||
PATH_TEST_EQ("/f/b/../a", "/f/b/../a");
|
||||
PATH_TEST_EQ("/foo/bar/blah/../..", "/foo/bar/blah/../..");
|
||||
PATH_TEST_EQ("/foo/bar/blah/../../bletch", "/foo/bar/blah/../../bletch");
|
||||
PATH_TEST_EQ("/...", "/...");
|
||||
PATH_TEST_EQ("/....", "/....");
|
||||
PATH_TEST_EQ("/foo/...", "/foo/...");
|
||||
PATH_TEST_EQ("/abc.", "/abc.");
|
||||
PATH_TEST_EQ("/abc..", "/abc..");
|
||||
PATH_TEST_EQ("/foo/abc.", "/foo/abc.");
|
||||
PATH_TEST_EQ("/foo/abc..", "/foo/abc..");
|
||||
|
||||
PATH_TEST_EQ("/.abc", "/.abc");
|
||||
PATH_TEST_EQ("/a.c", "/a.c");
|
||||
PATH_TEST_EQ("/..abc", "/..abc");
|
||||
PATH_TEST_EQ("/a..c", "/a..c");
|
||||
PATH_TEST_EQ("/foo/.abc", "/foo/.abc");
|
||||
PATH_TEST_EQ("/foo/a.c", "/foo/a.c");
|
||||
PATH_TEST_EQ("/foo/..abc", "/foo/..abc");
|
||||
PATH_TEST_EQ("/foo/a..c", "/foo/a..c");
|
||||
}
|
||||
|
||||
// append_tests --------------------------------------------------------------------//
|
||||
|
||||
static void append_test_aux(const test_abs_path& p, const tl::string& s, const tl::string& expect, int* utest_result)
|
||||
{
|
||||
PATH_TEST_EQ((p + s.c_str()).str(), expect);
|
||||
PATH_TEST_EQ((p + s).str(), expect);
|
||||
|
||||
// path x(p);
|
||||
// x.append(s.begin(), s.end());
|
||||
// PATH_TEST_EQ(x.str<tl::string>(), expect);
|
||||
}
|
||||
|
||||
UTEST(append_tests, append_tests)
|
||||
{
|
||||
// There are many control paths to be exercised, since empty paths and arguments,
|
||||
// paths with trailing separators, arguments with leading separators, with or without
|
||||
// other characters being present, are all separate cases that need to be tested.
|
||||
// Furthermore, some of the code to be tested is specific to argument categories,
|
||||
// so that results in further permutations to be tested.
|
||||
|
||||
//// code to generate test cases
|
||||
////
|
||||
//// expected results must be checked by hand
|
||||
//// "foo\bar" expected result must be edited by hand and moved for Windows/POSIX
|
||||
////
|
||||
//const char* x[] = { "", "/", "foo", "foo/" };
|
||||
//const char* y[] = { "", "/", "bar", "/bar" };
|
||||
|
||||
//for (int i = 0; i < sizeof(x)/sizeof(char*); ++i)
|
||||
// for (int j = 0; j < sizeof(y)/sizeof(char*); ++j)
|
||||
// {
|
||||
// std::cout << "\n PATH_TEST_EQ(path(\"" << x[i] << "\") + \"" << y[j] << "\", \""
|
||||
// << path(x[i]) + y[j] << "\");\n";
|
||||
// std::cout << " append_test_aux(\"" << x[i] << "\", \"" << y[j] << "\", \""
|
||||
// << path(x[i]) + y[j] << "\");\n";
|
||||
// }
|
||||
|
||||
PATH_TEST_EQ(test_abs_path("") + "", "");
|
||||
// append_test_aux(test_abs_path(""), "", "");
|
||||
|
||||
test_abs_path abs = test_abs_path("") + "/";
|
||||
test_abs_path abs1 = test_abs_path(abs);
|
||||
test_abs_path abs2 = test_abs_path("/") + "/";
|
||||
|
||||
PATH_TEST_EQ(test_abs_path("") + "/", "/");
|
||||
append_test_aux(test_abs_path(""), "/", "/", utest_result);
|
||||
|
||||
PATH_TEST_EQ(test_abs_path("") + "/bar", "/bar");
|
||||
append_test_aux(test_abs_path(""), "/bar", "/bar", utest_result);
|
||||
|
||||
PATH_TEST_EQ(test_abs_path("/") + "", "/");
|
||||
append_test_aux(test_abs_path("/"), "", "/", utest_result);
|
||||
|
||||
PATH_TEST_EQ(test_abs_path("/") + "/", "//");
|
||||
append_test_aux(test_abs_path("/"), "/", "//", utest_result);
|
||||
|
||||
PATH_TEST_EQ(test_abs_path("/") + "bar", "/bar");
|
||||
append_test_aux(test_abs_path("/"), "bar", "/bar", utest_result);
|
||||
|
||||
PATH_TEST_EQ(test_abs_path("/") + "/bar", "//bar");
|
||||
append_test_aux(test_abs_path("/"), "/bar", "//bar", utest_result);
|
||||
|
||||
PATH_TEST_EQ(test_abs_path("/foo") + "", "/foo");
|
||||
append_test_aux(test_abs_path("/foo"), "", "/foo", utest_result);
|
||||
|
||||
PATH_TEST_EQ(test_abs_path("/foo") + "/", "/foo/");
|
||||
append_test_aux(test_abs_path("/foo"), "/", "/foo/", utest_result);
|
||||
|
||||
PATH_TEST_EQ(test_abs_path("/foo") + "/bar", "/foo/bar");
|
||||
append_test_aux(test_abs_path("/foo"), "/bar", "/foo/bar", utest_result);
|
||||
|
||||
PATH_TEST_EQ(test_abs_path("/foo/") + "", "/foo/");
|
||||
append_test_aux(test_abs_path("/foo/"), "", "/foo/", utest_result);
|
||||
|
||||
PATH_TEST_EQ(test_abs_path("/foo/") + "/", "/foo//");
|
||||
append_test_aux(test_abs_path("/foo/"), "/", "/foo//", utest_result);
|
||||
|
||||
PATH_TEST_EQ(test_abs_path("/foo/") + "bar", "/foo/bar");
|
||||
append_test_aux(test_abs_path("/foo/"), "bar", "/foo/bar", utest_result);
|
||||
|
||||
PATH_TEST_EQ(test_abs_path("/foo/") + "/bar", "/foo//bar");
|
||||
append_test_aux(test_abs_path("/foo/"), "/bar", "/foo//bar", utest_result);
|
||||
|
||||
{
|
||||
PATH_TEST_EQ(test_abs_path("/foo") + "bar", "/foo/bar");
|
||||
append_test_aux(test_abs_path("/foo"), "bar", "/foo/bar", utest_result);
|
||||
}
|
||||
|
||||
// ticket #6819
|
||||
union
|
||||
{
|
||||
char a[1];
|
||||
char b[3];
|
||||
} u;
|
||||
|
||||
u.b[0] = '/';
|
||||
u.b[1] = 'a';
|
||||
u.b[2] = '\0';
|
||||
|
||||
test_abs_path p6819;
|
||||
p6819 += (const char*)u.a;
|
||||
EXPECT_EQ(p6819, test_abs_path("/a"));
|
||||
}
|
||||
|
||||
// self_assign_and_append_tests ------------------------------------------------------//
|
||||
|
||||
UTEST(self_assign_and_append_tests, self_assign_and_append_tests)
|
||||
{
|
||||
test_abs_path p;
|
||||
|
||||
p = "/snafubar";
|
||||
PATH_TEST_EQ(p = p, "/snafubar");
|
||||
|
||||
p = "/snafubar";
|
||||
p = p.str().c_str();
|
||||
PATH_TEST_EQ(p, "/snafubar");
|
||||
|
||||
// p = "snafubar";
|
||||
// p.assign(p.str<tl::string>().c_str(), path::codecvt());
|
||||
// PATH_TEST_EQ(p, "snafubar");
|
||||
|
||||
p = "/snafu/bar";
|
||||
PATH_TEST_EQ(p = p.str().c_str() + 6, "/bar");
|
||||
|
||||
// p = "snafubar";
|
||||
// PATH_TEST_EQ(p.assign(p.c_str() + 5, p.c_str() + 7), "ba");
|
||||
|
||||
p = "/snafubar";
|
||||
p += p.str().c_str();
|
||||
PATH_TEST_EQ(p, "/snafubar/snafubar");
|
||||
|
||||
// p = "snafubar";
|
||||
// p.append(p.c_str());
|
||||
// PATH_TEST_EQ(p, "snafubar/snafubar");
|
||||
|
||||
// p = "snafubar";
|
||||
// PATH_TEST_EQ(p.append(p.c_str() + 5, p.c_str() + 7), "snafubar" BOOST_DIR_SEP "ba");
|
||||
}
|
||||
|
||||
|
||||
|
||||
UTEST(PathView, PathView)
|
||||
{
|
||||
{
|
||||
test_abs_path path;
|
||||
test_abs_path_view pathView = path;
|
||||
EXPECT_TRUE(pathView.empty());
|
||||
EXPECT_FALSE(pathView.is_valid());
|
||||
EXPECT_EQ(pathView.size(), 0);
|
||||
EXPECT_EQ(pathView.hash(), path.hash());
|
||||
}
|
||||
{
|
||||
test_abs_path path("/caca/maca");
|
||||
test_abs_path_view pathView = path;
|
||||
EXPECT_FALSE(pathView.empty());
|
||||
EXPECT_TRUE(pathView.is_valid());
|
||||
EXPECT_EQ(pathView.size(), path.size());
|
||||
EXPECT_EQ(pathView.hash(), path.hash());
|
||||
}
|
||||
{
|
||||
test_abs_path path("/caca/maca");
|
||||
test_abs_path_view pathView = path;
|
||||
pathView.pop_back();
|
||||
EXPECT_FALSE(pathView.empty());
|
||||
EXPECT_TRUE(pathView.is_valid());
|
||||
EXPECT_EQ(pathView.size(), path.size() - 1);
|
||||
EXPECT_EQ(pathView.str(), "/caca");
|
||||
EXPECT_EQ(pathView.hash(), test_abs_path("/caca").hash());
|
||||
EXPECT_EQ(pathView.hash(), test_abs_path(pathView).hash());
|
||||
}
|
||||
|
||||
|
||||
|
||||
{
|
||||
test_abs_path path("/a");
|
||||
test_abs_path_view pathView = path;
|
||||
|
||||
EXPECT_TRUE(!pathView.empty());
|
||||
EXPECT_EQ(pathView.size(), 1);
|
||||
EXPECT_TRUE(pathView.is<posix_system>());
|
||||
EXPECT_EQ(pathView[0], "a");
|
||||
|
||||
test_abs_path path2("/a");
|
||||
test_abs_path_view pathView2 = path2;
|
||||
test_abs_path path3("/");
|
||||
test_abs_path_view pathView3 = path3;
|
||||
EXPECT_EQ(pathView, pathView2);
|
||||
EXPECT_NE(pathView, pathView3);
|
||||
|
||||
test_abs_path path4("\\\\");
|
||||
test_abs_path_view pathView4(path4);
|
||||
EXPECT_NE(pathView3, pathView4);
|
||||
}
|
||||
{
|
||||
test_abs_path path("\\\\a");
|
||||
test_abs_path_view pathView(path);
|
||||
EXPECT_TRUE(!pathView.empty());
|
||||
EXPECT_EQ(pathView.size(), 1);
|
||||
EXPECT_TRUE(pathView.is<unc_system>());
|
||||
EXPECT_EQ(pathView[0], "a");
|
||||
}
|
||||
{
|
||||
test_abs_path path("/a/b");
|
||||
test_abs_path_view pathView(path);
|
||||
EXPECT_TRUE(!pathView.empty());
|
||||
EXPECT_EQ(pathView.size(), 2);
|
||||
EXPECT_EQ(pathView[0], "a");
|
||||
EXPECT_EQ(pathView[1], "b");
|
||||
}
|
||||
//xxx
|
||||
{
|
||||
test_abs_path path(tl::string("/"));
|
||||
path += "a/b";
|
||||
path += "c";
|
||||
path += "..";
|
||||
EXPECT_TRUE(!path.empty());
|
||||
EXPECT_EQ(path.size(), 2);
|
||||
EXPECT_EQ(path[0], "a");
|
||||
EXPECT_EQ(path[1], "b");
|
||||
path += "../..";
|
||||
EXPECT_EQ(path.size(), 0);
|
||||
EXPECT_TRUE(path.empty());
|
||||
EXPECT_TRUE(path.is<posix_system>());
|
||||
}
|
||||
//xxx
|
||||
{
|
||||
test_abs_path path(tl::string("\\\\"));
|
||||
path += "a/b";
|
||||
EXPECTED_ASSERT_GUARD("Invalid path");
|
||||
path += "../../..";
|
||||
EXPECT_TRUE(path.empty());
|
||||
}
|
||||
//xxx
|
||||
{
|
||||
test_abs_path path(tl::string("\\\\"));
|
||||
EXPECTED_ASSERT_GUARD("Invalid path");
|
||||
path.push_back("..");
|
||||
EXPECT_TRUE(path.empty());
|
||||
}
|
||||
//xxx
|
||||
{
|
||||
test_abs_path path(tl::string("/"));
|
||||
EXPECTED_ASSERT_GUARD("Invalid path");
|
||||
test_abs_path newPath = path + "../..";
|
||||
EXPECT_TRUE(newPath.empty());
|
||||
}
|
||||
{
|
||||
EXPECTED_ASSERT_GUARD("Invalid path");
|
||||
test_abs_path path(tl::string("/"));
|
||||
test_abs_path_view pathView(path);
|
||||
auto pathParentView = pathView.parent();
|
||||
EXPECT_TRUE(pathParentView.empty());
|
||||
}
|
||||
{
|
||||
test_abs_path path(tl::string("/a/b/c/d"));
|
||||
test_abs_path_view pathView(path);
|
||||
test_abs_path_view newPathView = pathView.parent(2);
|
||||
EXPECT_EQ(newPathView.str(), "/a/b");
|
||||
}
|
||||
{
|
||||
EXPECTED_ASSERT_GUARD("Invalid path");
|
||||
test_abs_path path(tl::string("/a"));
|
||||
test_abs_path_view pathView(path);
|
||||
test_abs_path_view newPathView = pathView.parent(2);
|
||||
EXPECT_TRUE(newPathView.empty());
|
||||
}
|
||||
//{
|
||||
// test_abs_path path("\\\\a/b/c/d");
|
||||
// auto p = path.subpath(0, 0);
|
||||
// EXPECT_EQ(p, test_rel_path("a/b/c/d"));
|
||||
//}
|
||||
//{
|
||||
// test_abs_path path("/a/b/c/d");
|
||||
// auto p = path.subpath(1, 0);
|
||||
// EXPECT_EQ(p, test_rel_path("b/c/d"));
|
||||
//}
|
||||
//{
|
||||
// test_abs_path path("\\\\a/b/c/d");
|
||||
// auto p = path.subpath(0, -1);
|
||||
// EXPECT_EQ(p, test_rel_path("a/b/c"));
|
||||
//}
|
||||
//{
|
||||
// test_abs_path path("/a/b/c/d");
|
||||
// auto p = path.subpath(0, 2);
|
||||
// EXPECT_EQ(p, test_rel_path("a/b"));
|
||||
//}
|
||||
{
|
||||
test_abs_path path("\\\\a/b/c");
|
||||
auto p = path.parent();
|
||||
EXPECT_EQ(p, test_abs_path("\\\\a/b"));
|
||||
}
|
||||
{
|
||||
test_abs_path path("/a");
|
||||
auto p = path.parent();
|
||||
EXPECT_EQ(p, test_abs_path("/"));
|
||||
EXPECT_NE(p, test_abs_path("\\\\"));
|
||||
}
|
||||
|
||||
{
|
||||
test_abs_path path("/a/b/../c");
|
||||
auto p = path.parent();
|
||||
EXPECT_EQ(p, test_abs_path("/a"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user