blob: c9c9128aa2a6aa7e7424512a3daecbb8855a9184 [file] [log] [blame]
Eric Fiselier6e9a6942016-06-17 19:46:40 +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
Eric Fiselier1e34c762018-04-02 23:03:41 +000014// path canonical(const path& p);
Eric Fiselier6e9a6942016-06-17 19:46:40 +000015// path canonical(const path& p, error_code& ec);
Eric Fiselier6e9a6942016-06-17 19:46:40 +000016
Eric Fiselierf1471a32018-03-26 05:46:57 +000017#include "filesystem_include.hpp"
Eric Fiselier6e9a6942016-06-17 19:46:40 +000018#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
Eric Fiselierf1471a32018-03-26 05:46:57 +000025using namespace fs;
Eric Fiselier6e9a6942016-06-17 19:46:40 +000026
Eric Fiselier1e34c762018-04-02 23:03:41 +000027struct CWDGuard {
28 path OldCWD;
29 CWDGuard() : OldCWD(fs::current_path()) { }
30 ~CWDGuard() { fs::current_path(OldCWD); }
31
32 CWDGuard(CWDGuard const&) = delete;
33 CWDGuard& operator=(CWDGuard const&) = delete;
34};
35
Eric Fiselier6e9a6942016-06-17 19:46:40 +000036TEST_SUITE(filesystem_canonical_path_test_suite)
37
38TEST_CASE(signature_test)
39{
40 const path p; ((void)p);
41 std::error_code ec; ((void)ec);
42 ASSERT_NOT_NOEXCEPT(canonical(p));
Eric Fiselier6e9a6942016-06-17 19:46:40 +000043 ASSERT_NOT_NOEXCEPT(canonical(p, ec));
Eric Fiselier6e9a6942016-06-17 19:46:40 +000044}
45
46// There are 4 cases is the proposal for absolute path.
47// Each scope tests one of the cases.
48TEST_CASE(test_canonical)
49{
Eric Fiselier1e34c762018-04-02 23:03:41 +000050 CWDGuard guard;
Eric Fiselier6e9a6942016-06-17 19:46:40 +000051 // 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;
Eric Fiselier5c8a3682016-06-17 22:36:47 +000059 path base;
60 TestCase(path p1, path e, path b = StaticEnv::Root)
61 : p(p1), expect(e), base(b) {}
Eric Fiselier6e9a6942016-06-17 19:46:40 +000062 };
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) {
Eric Fiselier1e34c762018-04-02 23:03:41 +000075 std::error_code ec = GetTestEC();
76 fs::current_path(TC.base);
77 const path ret = canonical(TC.p, ec);
Eric Fiselier6e9a6942016-06-17 19:46:40 +000078 TEST_REQUIRE(!ec);
Eric Fiselier1e34c762018-04-02 23:03:41 +000079 const path ret2 = canonical(TC.p);
80 TEST_CHECK(PathEq(ret, TC.expect));
81 TEST_CHECK(PathEq(ret, ret2));
Eric Fiselier6e9a6942016-06-17 19:46:40 +000082 TEST_CHECK(ret.is_absolute());
83 }
84}
85
86TEST_CASE(test_dne_path)
87{
Eric Fiselier1e34c762018-04-02 23:03:41 +000088 std::error_code ec = GetTestEC();
Eric Fiselier6e9a6942016-06-17 19:46:40 +000089 {
90 const path ret = canonical(StaticEnv::DNE, ec);
Eric Fiselier1e34c762018-04-02 23:03:41 +000091 TEST_CHECK(ec != GetTestEC());
Eric Fiselier6e9a6942016-06-17 19:46:40 +000092 TEST_REQUIRE(ec);
93 TEST_CHECK(ret == path{});
94 }
95 {
96 TEST_CHECK_THROW(filesystem_error, canonical(StaticEnv::DNE));
Eric Fiselier6e9a6942016-06-17 19:46:40 +000097 }
98}
99
100TEST_CASE(test_exception_contains_paths)
101{
102#ifndef TEST_HAS_NO_EXCEPTIONS
Eric Fiselier1e34c762018-04-02 23:03:41 +0000103 CWDGuard guard;
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000104 const path p = "blabla/dne";
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000105 try {
106 canonical(p);
107 TEST_REQUIRE(false);
108 } catch (filesystem_error const& err) {
109 TEST_CHECK(err.path1() == p);
Eric Fiselier1e34c762018-04-02 23:03:41 +0000110 // 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));
Eric Fiselier6e9a6942016-06-17 19:46:40 +0000120 }
121#endif
122}
123
124TEST_SUITE_END()