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 rename(const path& old_p, const path& new_p);
15// void rename(const path& old_p,  const path& new_p, error_code& ec) noexcept;
16
17#include <experimental/filesystem>
18
19#include "test_macros.h"
20#include "rapid-cxx-test.hpp"
21#include "filesystem_test_helper.hpp"
22
23using namespace std::experimental::filesystem;
24namespace fs = std::experimental::filesystem;
25
26TEST_SUITE(filesystem_rename_test_suite)
27
28TEST_CASE(test_signatures)
29{
30    const path p; ((void)p);
31    std::error_code ec; ((void)ec);
32    ASSERT_SAME_TYPE(decltype(fs::rename(p, p)), void);
33    ASSERT_SAME_TYPE(decltype(fs::rename(p, p, ec)), void);
34
35    ASSERT_NOT_NOEXCEPT(fs::rename(p, p));
36    ASSERT_NOEXCEPT(fs::rename(p, p, ec));
37}
38
39TEST_CASE(test_error_reporting)
40{
41    auto checkThrow = [](path const& f, path const& t, const std::error_code& ec)
42    {
43#ifndef TEST_HAS_NO_EXCEPTIONS
44        try {
45            fs::rename(f, t);
46            return false;
47        } catch (filesystem_error const& err) {
48            return err.path1() == f
49                && err.path2() == t
50                && err.code() == ec;
51        }
52#else
53        ((void)f); ((void)t); ((void)ec);
54        return true;
55#endif
56    };
57    scoped_test_env env;
58    const path dne = env.make_env_path("dne");
59    const path file = env.create_file("file1", 42);
60    const path dir = env.create_dir("dir1");
61    struct TestCase {
62      path from;
63      path to;
64    } cases[] = {
65        {dne, dne},
66        {file, dir},
67        {dir, file}
68    };
69    for (auto& TC : cases) {
70        auto from_before = status(TC.from);
71        auto to_before = status(TC.to);
72        std::error_code ec;
73        rename(TC.from, TC.to, ec);
74        TEST_REQUIRE(ec);
75        TEST_CHECK(from_before.type() == status(TC.from).type());
76        TEST_CHECK(to_before.type() == status(TC.to).type());
77        TEST_CHECK(checkThrow(TC.from, TC.to, ec));
78    }
79}
80
81TEST_CASE(basic_rename_test)
82{
83    scoped_test_env env;
84
85    const std::error_code set_ec = std::make_error_code(std::errc::address_in_use);
86    const path file = env.create_file("file1", 42);
87    { // same file
88        std::error_code ec = set_ec;
89        rename(file, file, ec);
90        TEST_CHECK(!ec);
91        TEST_CHECK(is_regular_file(file));
92        TEST_CHECK(file_size(file) == 42);
93    }
94    const path sym = env.create_symlink(file, "sym");
95    { // file -> symlink
96        std::error_code ec = set_ec;
97        rename(file, sym, ec);
98        TEST_CHECK(!ec);
99        TEST_CHECK(!exists(file));
100        TEST_CHECK(is_regular_file(symlink_status(sym)));
101        TEST_CHECK(file_size(sym) == 42);
102    }
103    const path file2 = env.create_file("file2", 42);
104    const path file3 = env.create_file("file3", 100);
105    { // file -> file
106        std::error_code ec = set_ec;
107        rename(file2, file3, ec);
108        TEST_CHECK(!ec);
109        TEST_CHECK(!exists(file2));
110        TEST_CHECK(is_regular_file(file3));
111        TEST_CHECK(file_size(file3) == 42);
112    }
113    const path dne = env.make_env_path("dne");
114    const path bad_sym = env.create_symlink(dne, "bad_sym");
115    const path bad_sym_dest = env.make_env_path("bad_sym2");
116    { // bad-symlink
117        std::error_code ec = set_ec;
118        rename(bad_sym, bad_sym_dest, ec);
119        TEST_CHECK(!ec);
120        TEST_CHECK(!exists(symlink_status(bad_sym)));
121        TEST_CHECK(is_symlink(bad_sym_dest));
122        TEST_CHECK(read_symlink(bad_sym_dest) == dne);
123    }
124}
125
126TEST_SUITE_END()
127