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