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++98, 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 
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 
37 TEST_CASE(equivalent_test) {
38   struct TestCase {
39     path lhs;
40     path rhs;
41     bool expect;
42   };
43   const TestCase testCases[] = {
44       {StaticEnv::Dir, StaticEnv::Dir, true},
45       {StaticEnv::File, StaticEnv::Dir, false},
46       {StaticEnv::Dir, StaticEnv::SymlinkToDir, true},
47       {StaticEnv::Dir, StaticEnv::SymlinkToFile, false},
48       {StaticEnv::File, StaticEnv::File, true},
49       {StaticEnv::File, StaticEnv::SymlinkToFile, true},
50   };
51   for (auto& TC : testCases) {
52     std::error_code ec;
53     TEST_CHECK(equivalent(TC.lhs, TC.rhs, ec) == TC.expect);
54     TEST_CHECK(!ec);
55   }
56 }
57 
58 TEST_CASE(equivalent_reports_error_if_input_dne) {
59   const path E = StaticEnv::File;
60   const path DNE = StaticEnv::DNE;
61   { // Test that an error is reported when either of the paths don't exist
62     std::error_code ec = GetTestEC();
63     TEST_CHECK(equivalent(E, DNE, ec) == false);
64     TEST_CHECK(ec);
65     TEST_CHECK(ec != GetTestEC());
66   }
67   {
68     std::error_code ec = GetTestEC();
69     TEST_CHECK(equivalent(DNE, E, ec) == false);
70     TEST_CHECK(ec);
71     TEST_CHECK(ec != GetTestEC());
72   }
73   {
74     TEST_CHECK_THROW(filesystem_error, equivalent(DNE, E));
75     TEST_CHECK_THROW(filesystem_error, equivalent(E, DNE));
76   }
77   { // Test that an exception is thrown if both paths do not exist.
78     TEST_CHECK_THROW(filesystem_error, equivalent(DNE, DNE));
79   }
80   {
81     std::error_code ec = GetTestEC();
82     TEST_CHECK(equivalent(DNE, DNE, ec) == false);
83     TEST_CHECK(ec);
84     TEST_CHECK(ec != GetTestEC());
85   }
86 }
87 
88 TEST_CASE(equivalent_hardlink_succeeds) {
89   scoped_test_env env;
90   path const file = env.create_file("file", 42);
91   const path hl1 = env.create_hardlink(file, "hl1");
92   const path hl2 = env.create_hardlink(file, "hl2");
93   TEST_CHECK(equivalent(file, hl1));
94   TEST_CHECK(equivalent(file, hl2));
95   TEST_CHECK(equivalent(hl1, hl2));
96 }
97 
98 TEST_CASE(equivalent_is_other_succeeds) {
99   scoped_test_env env;
100   path const file = env.create_file("file", 42);
101   const path fifo1 = env.create_fifo("fifo1");
102   const path fifo2 = env.create_fifo("fifo2");
103   // Required to test behavior for inputs where is_other(p) is true.
104   TEST_REQUIRE(is_other(fifo1));
105   TEST_CHECK(!equivalent(file, fifo1));
106   TEST_CHECK(!equivalent(fifo2, file));
107   TEST_CHECK(!equivalent(fifo1, fifo2));
108   TEST_CHECK(equivalent(fifo1, fifo1));
109 }
110 
111 TEST_SUITE_END()
112