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