proximate.pass.cpp (4096B)
1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // UNSUPPORTED: c++98, c++03 11 12 // <filesystem> 13 14 // path proximate(const path& p, error_code &ec) 15 // path proximate(const path& p, const path& base = current_path()) 16 // path proximate(const path& p, const path& base, error_code& ec); 17 18 #include "filesystem_include.hpp" 19 #include <type_traits> 20 #include <vector> 21 #include <iostream> 22 #include <cassert> 23 24 #include "test_macros.h" 25 #include "test_iterators.h" 26 #include "count_new.hpp" 27 #include "rapid-cxx-test.hpp" 28 #include "filesystem_test_helper.hpp" 29 30 31 static int count_path_elems(const fs::path& p) { 32 int count = 0; 33 for (auto& elem : p) { 34 if (elem != "/" && elem != "") 35 ++count; 36 } 37 return count; 38 } 39 40 TEST_SUITE(filesystem_proximate_path_test_suite) 41 42 43 TEST_CASE(signature_test) 44 { 45 using fs::path; 46 const path p; ((void)p); 47 std::error_code ec; ((void)ec); 48 ASSERT_NOT_NOEXCEPT(proximate(p)); 49 ASSERT_NOT_NOEXCEPT(proximate(p, p)); 50 ASSERT_NOT_NOEXCEPT(proximate(p, ec)); 51 ASSERT_NOT_NOEXCEPT(proximate(p, p, ec)); 52 } 53 54 TEST_CASE(basic_test) { 55 using fs::path; 56 const path cwd = fs::current_path(); 57 const path parent_cwd = cwd.parent_path(); 58 const path curdir = cwd.filename(); 59 TEST_REQUIRE(!cwd.native().empty()); 60 int cwd_depth = count_path_elems(cwd); 61 path dot_dot_to_root; 62 for (int i=0; i < cwd_depth; ++i) 63 dot_dot_to_root /= ".."; 64 path relative_cwd = cwd.native().substr(1); 65 // clang-format off 66 struct { 67 std::string input; 68 std::string base; 69 std::string expect; 70 } TestCases[] = { 71 {"", "", "."}, 72 {cwd, "a", ".."}, 73 {parent_cwd, "a", "../.."}, 74 {"a", cwd, "a"}, 75 {"a", parent_cwd, "fs.op.proximate/a"}, 76 {"/", "a", dot_dot_to_root / ".."}, 77 {"/", "a/b", dot_dot_to_root / "../.."}, 78 {"/", "a/b/", dot_dot_to_root / "../.."}, 79 {"a", "/", relative_cwd / "a"}, 80 {"a/b", "/", relative_cwd / "a/b"}, 81 {"a", "/net", ".." / relative_cwd / "a"}, 82 {"//foo/", "//foo", "."}, 83 {"//foo", "//foo/", "."}, 84 {"//foo", "//foo", "."}, 85 {"//foo/", "//foo/", "."}, 86 {"//base", "a", dot_dot_to_root / "../base"}, 87 {"a", "a", "."}, 88 {"a/b", "a/b", "."}, 89 {"a/b/c/", "a/b/c/", "."}, 90 {"//foo/a/b", "//foo/a/b", "."}, 91 {"/a/d", "/a/b/c", "../../d"}, 92 {"/a/b/c", "/a/d", "../b/c"}, 93 {"a/b/c", "a", "b/c"}, 94 {"a/b/c", "a/b/c/x/y", "../.."}, 95 {"a/b/c", "a/b/c", "."}, 96 {"a/b", "c/d", "../../a/b"} 97 }; 98 // clang-format on 99 int ID = 0; 100 for (auto& TC : TestCases) { 101 ++ID; 102 std::error_code ec = GetTestEC(); 103 fs::path p(TC.input); 104 const fs::path output = fs::proximate(p, TC.base, ec); 105 if (ec) { 106 TEST_CHECK(!ec); 107 std::cerr << "TEST CASE #" << ID << " FAILED: \n"; 108 std::cerr << " Input: '" << TC.input << "'\n"; 109 std::cerr << " Base: '" << TC.base << "'\n"; 110 std::cerr << " Expected: '" << TC.expect << "'\n"; 111 112 std::cerr << std::endl; 113 } else if (!PathEq(output, TC.expect)) { 114 TEST_CHECK(PathEq(output, TC.expect)); 115 116 const path canon_input = fs::weakly_canonical(TC.input); 117 const path canon_base = fs::weakly_canonical(TC.base); 118 const path lexically_p = canon_input.lexically_proximate(canon_base); 119 std::cerr << "TEST CASE #" << ID << " FAILED: \n"; 120 std::cerr << " Input: '" << TC.input << "'\n"; 121 std::cerr << " Base: '" << TC.base << "'\n"; 122 std::cerr << " Expected: '" << TC.expect << "'\n"; 123 std::cerr << " Output: '" << output.native() << "'\n"; 124 std::cerr << " Lex Prox: '" << lexically_p.native() << "'\n"; 125 std::cerr << " Canon Input: " << canon_input << "\n"; 126 std::cerr << " Canon Base: " << canon_base << "\n"; 127 128 std::cerr << std::endl; 129 } 130 } 131 } 132 133 TEST_SUITE_END()