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 // <experimental/filesystem>
13 
14 // void copy_symlink(const path& existing_symlink, const path& new_symlink);
15 // void copy_symlink(const path& existing_symlink, const path& new_symlink,
16 //                   error_code& ec) noexcept;
17 
18 #include <experimental/filesystem>
19 #include <type_traits>
20 #include <cassert>
21 
22 #include "test_macros.h"
23 #include "rapid-cxx-test.hpp"
24 #include "filesystem_test_helper.hpp"
25 
26 using namespace std::experimental::filesystem;
27 namespace fs = std::experimental::filesystem;
28 
29 TEST_SUITE(filesystem_copy_symlink_test_suite)
30 
TEST_CASE(test_signatures)31 TEST_CASE(test_signatures)
32 {
33     const path p; ((void)p);
34     std::error_code ec; ((void)ec);
35     ASSERT_NOT_NOEXCEPT(fs::copy_symlink(p, p));
36     ASSERT_NOEXCEPT(fs::copy_symlink(p, p, ec));
37 }
38 
39 
TEST_CASE(test_error_reporting)40 TEST_CASE(test_error_reporting)
41 {
42     auto checkThrow = [](path const& f, path const& t, const std::error_code& ec)
43     {
44 #ifndef TEST_HAS_NO_EXCEPTIONS
45         try {
46             fs::copy_symlink(f, t);
47             return true;
48         } catch (filesystem_error const& err) {
49             return err.path1() == f
50                 && err.code() == ec;
51         }
52 #else
53         ((void)f); ((void)t); ((void)ec);
54         return true;
55 #endif
56     };
57 
58     scoped_test_env env;
59     const path file = env.create_file("file1", 42);
60     const path file2 = env.create_file("file2", 55);
61     const path sym = env.create_symlink(file, "sym");
62     const path dir = env.create_dir("dir");
63     const path dne = env.make_env_path("dne");
64     { // from is a file, not a symlink
65         std::error_code ec;
66         fs::copy_symlink(file, dne, ec);
67         TEST_REQUIRE(ec);
68         TEST_CHECK(checkThrow(file, dne, ec));
69     }
70     { // from is a file, not a symlink
71         std::error_code ec;
72         fs::copy_symlink(dir, dne, ec);
73         TEST_REQUIRE(ec);
74         TEST_CHECK(checkThrow(dir, dne, ec));
75     }
76     { // destination exists
77         std::error_code ec;
78         fs::copy_symlink(sym, file2, ec);
79         TEST_REQUIRE(ec);
80     }
81 }
82 
TEST_CASE(copy_symlink_basic)83 TEST_CASE(copy_symlink_basic)
84 {
85     scoped_test_env env;
86     const path dir = env.create_dir("dir");
87     const path dir_sym = env.create_symlink(dir, "dir_sym");
88     const path file = env.create_file("file", 42);
89     const path file_sym = env.create_symlink(file, "file_sym");
90     { // test for directory symlinks
91         const path dest = env.make_env_path("dest1");
92         std::error_code ec;
93         fs::copy_symlink(dir_sym, dest, ec);
94         TEST_REQUIRE(!ec);
95         TEST_CHECK(is_symlink(dest));
96         TEST_CHECK(equivalent(dest, dir));
97     }
98     { // test for file symlinks
99         const path dest = env.make_env_path("dest2");
100         std::error_code ec;
101         fs::copy_symlink(file_sym, dest, ec);
102         TEST_REQUIRE(!ec);
103         TEST_CHECK(is_symlink(dest));
104         TEST_CHECK(equivalent(dest, file));
105     }
106 }
107 
108 
109 TEST_SUITE_END()
110