• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 canonical(const path& p);
15 // path canonical(const path& p, error_code& ec);
16 
17 #include "filesystem_include.hpp"
18 #include <type_traits>
19 #include <cassert>
20 
21 #include "test_macros.h"
22 #include "rapid-cxx-test.hpp"
23 #include "filesystem_test_helper.hpp"
24 
25 using namespace fs;
26 
27 struct CWDGuard {
28   path OldCWD;
CWDGuardCWDGuard29   CWDGuard() : OldCWD(fs::current_path()) { }
~CWDGuardCWDGuard30   ~CWDGuard() { fs::current_path(OldCWD); }
31 
32   CWDGuard(CWDGuard const&) = delete;
33   CWDGuard& operator=(CWDGuard const&) = delete;
34 };
35 
36 TEST_SUITE(filesystem_canonical_path_test_suite)
37 
TEST_CASE(signature_test)38 TEST_CASE(signature_test)
39 {
40     const path p; ((void)p);
41     std::error_code ec; ((void)ec);
42     ASSERT_NOT_NOEXCEPT(canonical(p));
43     ASSERT_NOT_NOEXCEPT(canonical(p, ec));
44 }
45 
46 // There are 4 cases is the proposal for absolute path.
47 // Each scope tests one of the cases.
TEST_CASE(test_canonical)48 TEST_CASE(test_canonical)
49 {
50     CWDGuard guard;
51     // has_root_name() && has_root_directory()
52     const path Root = StaticEnv::Root;
53     const path RootName = Root.filename();
54     const path DirName = StaticEnv::Dir.filename();
55     const path SymlinkName = StaticEnv::SymlinkToFile.filename();
56     struct TestCase {
57         path p;
58         path expect;
59         path base;
60         TestCase(path p1, path e, path b = StaticEnv::Root)
61             : p(p1), expect(e), base(b) {}
62     };
63     const TestCase testCases[] = {
64         { ".", Root, Root},
65         { DirName / ".." / "." / DirName, StaticEnv::Dir, Root},
66         { StaticEnv::Dir2 / "..",    StaticEnv::Dir },
67         { StaticEnv::Dir3 / "../..", StaticEnv::Dir },
68         { StaticEnv::Dir / ".",      StaticEnv::Dir },
69         { Root / "." / DirName / ".." / DirName, StaticEnv::Dir},
70         { path("..") / "." / RootName / DirName / ".." / DirName, StaticEnv::Dir, Root},
71         { StaticEnv::SymlinkToFile,  StaticEnv::File },
72         { SymlinkName, StaticEnv::File, StaticEnv::Root}
73     };
74     for (auto& TC : testCases) {
75         std::error_code ec = GetTestEC();
76         fs::current_path(TC.base);
77         const path ret = canonical(TC.p, ec);
78         TEST_REQUIRE(!ec);
79         const path ret2 = canonical(TC.p);
80         TEST_CHECK(PathEq(ret, TC.expect));
81         TEST_CHECK(PathEq(ret, ret2));
82         TEST_CHECK(ret.is_absolute());
83     }
84 }
85 
TEST_CASE(test_dne_path)86 TEST_CASE(test_dne_path)
87 {
88     std::error_code ec = GetTestEC();
89     {
90         const path ret = canonical(StaticEnv::DNE, ec);
91         TEST_CHECK(ec != GetTestEC());
92         TEST_REQUIRE(ec);
93         TEST_CHECK(ret == path{});
94     }
95     {
96         TEST_CHECK_THROW(filesystem_error, canonical(StaticEnv::DNE));
97     }
98 }
99 
TEST_CASE(test_exception_contains_paths)100 TEST_CASE(test_exception_contains_paths)
101 {
102 #ifndef TEST_HAS_NO_EXCEPTIONS
103     CWDGuard guard;
104     const path p = "blabla/dne";
105     try {
106         canonical(p);
107         TEST_REQUIRE(false);
108     } catch (filesystem_error const& err) {
109         TEST_CHECK(err.path1() == p);
110         // libc++ provides the current path as the second path in the exception
111         LIBCPP_ONLY(TEST_CHECK(err.path2() == current_path()));
112     }
113     fs::current_path(StaticEnv::Dir);
114     try {
115         canonical(p);
116         TEST_REQUIRE(false);
117     } catch (filesystem_error const& err) {
118         TEST_CHECK(err.path1() == p);
119         LIBCPP_ONLY(TEST_CHECK(err.path2() == StaticEnv::Dir));
120     }
121 #endif
122 }
123 
124 TEST_SUITE_END()
125