blob: 7b526507f0a80103356c84ae4781086c6e50059b [file] [log] [blame]
Eric Fiselier1e34c762018-04-02 23:03:41 +00001//===----------------------------------------------------------------------===//
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// <experimental/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
31static 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
40TEST_SUITE(filesystem_proximate_path_test_suite)
41
42
43TEST_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
54TEST_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 {"//net/", "//net", "/net/"},
83 {"//net", "//net/", ".."},
84 {"//net", "//net", "."},
85 {"//net/", "//net/", "."},
86 {"//base", "a", dot_dot_to_root / "../base"},
87 {"a", "a", "."},
88 {"a/b", "a/b", "."},
89 {"a/b/c/", "a/b/c/", "."},
90 {"//net/a/b", "//net/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 TEST_CHECK(!ec);
106 TEST_CHECK(PathEq(output, TC.expect));
107 if (!PathEq(output, TC.expect)) {
108 const path canon_input = fs::weakly_canonical(TC.input);
109 const path canon_base = fs::weakly_canonical(TC.base);
110 const path lexically_p = canon_input.lexically_proximate(canon_base);
111 std::cerr << "TEST CASE #" << ID << " FAILED: \n";
112 std::cerr << " Input: '" << TC.input << "'\n";
113 std::cerr << " Base: '" << TC.base << "'\n";
114 std::cerr << " Expected: '" << TC.expect << "'\n";
115 std::cerr << " Output: '" << output.native() << "'\n";
116 std::cerr << " Lex Prox: '" << lexically_p.native() << "'\n";
117 std::cerr << " Canon Input: " << canon_input << "\n";
118 std::cerr << " Canon Base: " << canon_base << "\n";
119
120 std::cerr << std::endl;
121 }
122 }
123}
124
125TEST_SUITE_END()