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 // class directory_iterator 15 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; 20 21 #include <experimental/filesystem> 22 #include <type_traits> 23 #include <set> 24 #include <cassert> 25 26 #include "test_macros.h" 27 #include "rapid-cxx-test.hpp" 28 #include "filesystem_test_helper.hpp" 29 30 using namespace std::experimental::filesystem; 31 32 TEST_SUITE(directory_iterator_constructor_tests) 33 34 TEST_CASE(test_constructor_signatures) 35 { 36 using D = directory_iterator; 37 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, ""); 42 43 // directory_iterator(path const&, error_code&) noexcept 44 static_assert(std::is_nothrow_constructible<D, path, std::error_code&>::value, ""); 45 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, ""); 49 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, ""); 52 } 53 54 TEST_CASE(test_construction_from_bad_path) 55 { 56 std::error_code ec; 57 directory_options opts = directory_options::none; 58 const directory_iterator endIt; 59 60 const path testPaths[] = { StaticEnv::DNE, StaticEnv::BadSymlink }; 61 for (path const& testPath : testPaths) 62 { 63 { 64 directory_iterator it(testPath, ec); 65 TEST_CHECK(ec); 66 TEST_CHECK(it == endIt); 67 } 68 { 69 directory_iterator it(testPath, opts, ec); 70 TEST_CHECK(ec); 71 TEST_CHECK(it == endIt); 72 } 73 { 74 TEST_CHECK_THROW(filesystem_error, directory_iterator(testPath)); 75 TEST_CHECK_THROW(filesystem_error, directory_iterator(testPath, opts)); 76 } 77 } 78 } 79 80 TEST_CASE(access_denied_test_case) 81 { 82 using namespace std::experimental::filesystem; 83 scoped_test_env env; 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); 88 89 // Test that we can iterator over the directory before changing the perms 90 { 91 directory_iterator it(testDir); 92 TEST_REQUIRE(it != directory_iterator{}); 93 } 94 // Change the permissions so we can no longer iterate 95 permissions(testDir, perms::none); 96 97 // Check that the construction fails when skip_permissions_denied is 98 // not given. 99 { 100 std::error_code ec; 101 directory_iterator it(testDir, ec); 102 TEST_REQUIRE(ec); 103 TEST_CHECK(it == directory_iterator{}); 104 } 105 // Check that construction does not report an error when 106 // 'skip_permissions_denied' is given. 107 { 108 std::error_code ec; 109 directory_iterator it(testDir, directory_options::skip_permission_denied, ec); 110 TEST_REQUIRE(!ec); 111 TEST_CHECK(it == directory_iterator{}); 112 } 113 } 114 115 116 TEST_CASE(access_denied_to_file_test_case) 117 { 118 using namespace std::experimental::filesystem; 119 scoped_test_env env; 120 path const testFile = env.make_env_path("file1"); 121 env.create_file(testFile, 42); 122 123 // Change the permissions so we can no longer iterate 124 permissions(testFile, perms::none); 125 126 // Check that the construction fails when skip_permissions_denied is 127 // not given. 128 { 129 std::error_code ec; 130 directory_iterator it(testFile, ec); 131 TEST_REQUIRE(ec); 132 TEST_CHECK(it == directory_iterator{}); 133 } 134 // Check that construction still fails when 'skip_permissions_denied' is given 135 // because we tried to open a file and not a directory. 136 { 137 std::error_code ec; 138 directory_iterator it(testFile, directory_options::skip_permission_denied, ec); 139 TEST_REQUIRE(ec); 140 TEST_CHECK(it == directory_iterator{}); 141 } 142 } 143 144 TEST_CASE(test_open_on_empty_directory_equals_end) 145 { 146 scoped_test_env env; 147 const path testDir = env.make_env_path("dir1"); 148 env.create_dir(testDir); 149 150 const directory_iterator endIt; 151 { 152 std::error_code ec; 153 directory_iterator it(testDir, ec); 154 TEST_CHECK(!ec); 155 TEST_CHECK(it == endIt); 156 } 157 { 158 directory_iterator it(testDir); 159 TEST_CHECK(it == endIt); 160 } 161 } 162 163 TEST_CASE(test_open_on_directory_succeeds) 164 { 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{}; 169 170 { 171 std::error_code ec; 172 directory_iterator it(testDir, ec); 173 TEST_REQUIRE(!ec); 174 TEST_CHECK(it != endIt); 175 TEST_CHECK(dir_contents.count(*it)); 176 } 177 { 178 directory_iterator it(testDir); 179 TEST_CHECK(it != endIt); 180 TEST_CHECK(dir_contents.count(*it)); 181 } 182 } 183 184 TEST_CASE(test_open_on_file_fails) 185 { 186 const path testFile = StaticEnv::File; 187 const directory_iterator endIt{}; 188 { 189 std::error_code ec; 190 directory_iterator it(testFile, ec); 191 TEST_REQUIRE(ec); 192 TEST_CHECK(it == endIt); 193 } 194 { 195 TEST_CHECK_THROW(filesystem_error, directory_iterator(testFile)); 196 } 197 } 198 199 TEST_CASE(test_open_on_empty_string) 200 { 201 const path testPath = ""; 202 const directory_iterator endIt{}; 203 204 std::error_code ec; 205 directory_iterator it(testPath, ec); 206 TEST_CHECK(ec); 207 TEST_CHECK(it == endIt); 208 } 209 210 TEST_CASE(test_open_on_dot_dir) 211 { 212 const path testPath = "."; 213 214 std::error_code ec; 215 directory_iterator it(testPath, ec); 216 TEST_CHECK(!ec); 217 } 218 219 TEST_CASE(test_open_on_symlink) 220 { 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()); 225 } 226 const directory_iterator endIt{}; 227 228 { 229 std::error_code ec; 230 directory_iterator it(symlinkToDir, ec); 231 TEST_REQUIRE(!ec); 232 TEST_CHECK(it != endIt); 233 path const& entry = *it; 234 TEST_CHECK(dir_contents.count(entry.filename())); 235 } 236 { 237 std::error_code ec; 238 directory_iterator it(symlinkToDir, 239 directory_options::follow_directory_symlink, ec); 240 TEST_REQUIRE(!ec); 241 TEST_CHECK(it != endIt); 242 path const& entry = *it; 243 TEST_CHECK(dir_contents.count(entry.filename())); 244 } 245 } 246 247 TEST_SUITE_END() 248