1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03
10 
11 // <filesystem>
12 
13 // bool equivalent(path const& lhs, path const& rhs);
14 // bool equivalent(path const& lhs, path const& rhs, std::error_code& ec) noexcept;
15 
16 #include "filesystem_include.h"
17 #include <type_traits>
18 #include <cassert>
19 
20 #include "test_macros.h"
21 #include "rapid-cxx-test.h"
22 #include "filesystem_test_helper.h"
23 
24 using namespace fs;
25 
26 TEST_SUITE(equivalent_test_suite)
27 
TEST_CASE(signature_test)28 TEST_CASE(signature_test) {
29   const path p;
30   ((void)p);
31   std::error_code ec;
32   ((void)ec);
33   ASSERT_NOEXCEPT(equivalent(p, p, ec));
34   ASSERT_NOT_NOEXCEPT(equivalent(p, p));
35 }
36 
TEST_CASE(equivalent_test)37 TEST_CASE(equivalent_test) {
38   static_test_env static_env;
39   struct TestCase {
40     path lhs;
41     path rhs;
42     bool expect;
43   };
44   const TestCase testCases[] = {
45       {static_env.Dir, static_env.Dir, true},
46       {static_env.File, static_env.Dir, false},
47       {static_env.Dir, static_env.SymlinkToDir, true},
48       {static_env.Dir, static_env.SymlinkToFile, false},
49       {static_env.File, static_env.File, true},
50       {static_env.File, static_env.SymlinkToFile, true},
51   };
52   for (auto& TC : testCases) {
53     std::error_code ec;
54     TEST_CHECK(equivalent(TC.lhs, TC.rhs, ec) == TC.expect);
55     TEST_CHECK(!ec);
56   }
57 }
58 
TEST_CASE(equivalent_reports_error_if_input_dne)59 TEST_CASE(equivalent_reports_error_if_input_dne) {
60   static_test_env static_env;
61   const path E = static_env.File;
62   const path DNE = static_env.DNE;
63   { // Test that an error is reported when either of the paths don't exist
64     std::error_code ec = GetTestEC();
65     TEST_CHECK(equivalent(E, DNE, ec) == false);
66     TEST_CHECK(ec);
67     TEST_CHECK(ec != GetTestEC());
68   }
69   {
70     std::error_code ec = GetTestEC();
71     TEST_CHECK(equivalent(DNE, E, ec) == false);
72     TEST_CHECK(ec);
73     TEST_CHECK(ec != GetTestEC());
74   }
75   {
76     TEST_CHECK_THROW(filesystem_error, equivalent(DNE, E));
77     TEST_CHECK_THROW(filesystem_error, equivalent(E, DNE));
78   }
79   { // Test that an exception is thrown if both paths do not exist.
80     TEST_CHECK_THROW(filesystem_error, equivalent(DNE, DNE));
81   }
82   {
83     std::error_code ec = GetTestEC();
84     TEST_CHECK(equivalent(DNE, DNE, ec) == false);
85     TEST_CHECK(ec);
86     TEST_CHECK(ec != GetTestEC());
87   }
88 }
89 
TEST_CASE(equivalent_hardlink_succeeds)90 TEST_CASE(equivalent_hardlink_succeeds) {
91   scoped_test_env env;
92   path const file = env.create_file("file", 42);
93   const path hl1 = env.create_hardlink(file, "hl1");
94   const path hl2 = env.create_hardlink(file, "hl2");
95   TEST_CHECK(equivalent(file, hl1));
96   TEST_CHECK(equivalent(file, hl2));
97   TEST_CHECK(equivalent(hl1, hl2));
98 }
99 
100 #ifndef _WIN32
TEST_CASE(equivalent_is_other_succeeds)101 TEST_CASE(equivalent_is_other_succeeds) {
102   scoped_test_env env;
103   path const file = env.create_file("file", 42);
104   const path fifo1 = env.create_fifo("fifo1");
105   const path fifo2 = env.create_fifo("fifo2");
106   // Required to test behavior for inputs where is_other(p) is true.
107   TEST_REQUIRE(is_other(fifo1));
108   TEST_CHECK(!equivalent(file, fifo1));
109   TEST_CHECK(!equivalent(fifo2, file));
110   TEST_CHECK(!equivalent(fifo1, fifo2));
111   TEST_CHECK(equivalent(fifo1, fifo1));
112 }
113 #endif
114 
115 TEST_SUITE_END()
116