1 //===----------------------------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // UNSUPPORTED: c++98, c++03
12 // <experimental/filesystem>
14 // class directory_iterator
16 // explicit directory_iterator(const path& p);
17 // directory_iterator(const path& p, directory_options options);
18 // directory_iterator(const path& p, error_code& ec) noexcept;
19 // directory_iterator(const path& p, directory_options options, error_code& ec) noexcept;
21 #include <experimental/filesystem>
22 #include <type_traits>
26 #include "test_macros.h"
27 #include "rapid-cxx-test.hpp"
28 #include "filesystem_test_helper.hpp"
30 using namespace std::experimental::filesystem;
32 TEST_SUITE(directory_iterator_constructor_tests)
34 TEST_CASE(test_constructor_signatures)
36 using D = directory_iterator;
38 // explicit directory_iterator(path const&);
39 static_assert(!std::is_convertible<path, D>::value, "");
40 static_assert(std::is_constructible<D, path>::value, "");
41 static_assert(!std::is_nothrow_constructible<D, path>::value, "");
43 // directory_iterator(path const&, error_code&) noexcept
44 static_assert(std::is_nothrow_constructible<D, path, std::error_code&>::value, "");
46 // directory_iterator(path const&, directory_options);
47 static_assert(std::is_constructible<D, path, directory_options>::value, "");
48 static_assert(!std::is_nothrow_constructible<D, path, directory_options>::value, "");
50 // directory_iterator(path const&, directory_options, error_code&) noexcept
51 static_assert(std::is_nothrow_constructible<D, path, directory_options, std::error_code&>::value, "");
54 TEST_CASE(test_construction_from_bad_path)
57 directory_options opts = directory_options::none;
58 const directory_iterator endIt;
60 const path testPaths[] = { StaticEnv::DNE, StaticEnv::BadSymlink };
61 for (path const& testPath : testPaths)
64 directory_iterator it(testPath, ec);
66 TEST_CHECK(it == endIt);
69 directory_iterator it(testPath, opts, ec);
71 TEST_CHECK(it == endIt);
74 TEST_CHECK_THROW(filesystem_error, directory_iterator(testPath));
75 TEST_CHECK_THROW(filesystem_error, directory_iterator(testPath, opts));
80 TEST_CASE(access_denied_test_case)
82 using namespace std::experimental::filesystem;
84 path const testDir = env.make_env_path("dir1");
85 path const testFile = testDir / "testFile";
86 env.create_dir(testDir);
87 env.create_file(testFile, 42);
89 // Test that we can iterator over the directory before changing the perms
91 directory_iterator it(testDir);
92 TEST_REQUIRE(it != directory_iterator{});
94 // Change the permissions so we can no longer iterate
95 permissions(testDir, perms::none);
97 // Check that the construction fails when skip_permissions_denied is
101 directory_iterator it(testDir, ec);
103 TEST_CHECK(it == directory_iterator{});
105 // Check that construction does not report an error when
106 // 'skip_permissions_denied' is given.
109 directory_iterator it(testDir, directory_options::skip_permission_denied, ec);
111 TEST_CHECK(it == directory_iterator{});
116 TEST_CASE(access_denied_to_file_test_case)
118 using namespace std::experimental::filesystem;
120 path const testFile = env.make_env_path("file1");
121 env.create_file(testFile, 42);
123 // Change the permissions so we can no longer iterate
124 permissions(testFile, perms::none);
126 // Check that the construction fails when skip_permissions_denied is
130 directory_iterator it(testFile, ec);
132 TEST_CHECK(it == directory_iterator{});
134 // Check that construction still fails when 'skip_permissions_denied' is given
135 // because we tried to open a file and not a directory.
138 directory_iterator it(testFile, directory_options::skip_permission_denied, ec);
140 TEST_CHECK(it == directory_iterator{});
144 TEST_CASE(test_open_on_empty_directory_equals_end)
147 const path testDir = env.make_env_path("dir1");
148 env.create_dir(testDir);
150 const directory_iterator endIt;
153 directory_iterator it(testDir, ec);
155 TEST_CHECK(it == endIt);
158 directory_iterator it(testDir);
159 TEST_CHECK(it == endIt);
163 TEST_CASE(test_open_on_directory_succeeds)
165 const path testDir = StaticEnv::Dir;
166 std::set<path> dir_contents(std::begin(StaticEnv::DirIterationList),
167 std::end( StaticEnv::DirIterationList));
168 const directory_iterator endIt{};
172 directory_iterator it(testDir, ec);
174 TEST_CHECK(it != endIt);
175 TEST_CHECK(dir_contents.count(*it));
178 directory_iterator it(testDir);
179 TEST_CHECK(it != endIt);
180 TEST_CHECK(dir_contents.count(*it));
184 TEST_CASE(test_open_on_file_fails)
186 const path testFile = StaticEnv::File;
187 const directory_iterator endIt{};
190 directory_iterator it(testFile, ec);
192 TEST_CHECK(it == endIt);
195 TEST_CHECK_THROW(filesystem_error, directory_iterator(testFile));
199 TEST_CASE(test_open_on_empty_string)
201 const path testPath = "";
202 const directory_iterator endIt{};
205 directory_iterator it(testPath, ec);
207 TEST_CHECK(it == endIt);
210 TEST_CASE(test_open_on_dot_dir)
212 const path testPath = ".";
215 directory_iterator it(testPath, ec);
219 TEST_CASE(test_open_on_symlink)
221 const path symlinkToDir = StaticEnv::SymlinkToDir;
222 std::set<path> dir_contents;
223 for (path const& p : StaticEnv::DirIterationList) {
224 dir_contents.insert(p.filename());
226 const directory_iterator endIt{};
230 directory_iterator it(symlinkToDir, ec);
232 TEST_CHECK(it != endIt);
233 path const& entry = *it;
234 TEST_CHECK(dir_contents.count(entry.filename()));
238 directory_iterator it(symlinkToDir,
239 directory_options::follow_directory_symlink, ec);
241 TEST_CHECK(it != endIt);
242 path const& entry = *it;
243 TEST_CHECK(dir_contents.count(entry.filename()));