LCOV - code coverage report
Current view: top level - tests - catch_directorycollection.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 629 629 100.0 %
Date: 2024-06-15 08:26:09 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   Zipios -- a small C++ library that provides easy access to .zip files.
       3             : 
       4             :   Copyright (C) 2000-2007  Thomas Sondergaard
       5             :   Copyright (c) 2015-2022  Made to Order Software Corp.  All Rights Reserved
       6             : 
       7             :   This library is free software; you can redistribute it and/or
       8             :   modify it under the terms of the GNU Lesser General Public
       9             :   License as published by the Free Software Foundation; either
      10             :   version 2.1 of the License, or (at your option) any later version.
      11             : 
      12             :   This library is distributed in the hope that it will be useful,
      13             :   but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :   Lesser General Public License for more details.
      16             : 
      17             :   You should have received a copy of the GNU Lesser General Public
      18             :   License along with this library; if not, write to the Free Software
      19             :   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
      20             : */
      21             : 
      22             : /** \file
      23             :  *
      24             :  * Zipios unit tests for the DirectoryCollection class.
      25             :  */
      26             : 
      27             : #include "catch_main.hpp"
      28             : 
      29             : #include <zipios/directorycollection.hpp>
      30             : #include <zipios/zipiosexceptions.hpp>
      31             : #include <zipios/dosdatetime.hpp>
      32             : 
      33             : #include <fstream>
      34             : #include <memory>
      35             : #include <vector>
      36             : 
      37             : #include <unistd.h>
      38             : #include <string.h>
      39             : 
      40             : 
      41             : 
      42             : 
      43             : 
      44           2 : CATCH_SCENARIO("DirectoryCollection with invalid paths", "[DirectoryCollection] [FileCollection]")
      45             : {
      46           2 :     CATCH_GIVEN("an empty directory collection")
      47             :     {
      48           2 :         zipios::DirectoryCollection dc;
      49             : 
      50             :         // first, check that the object is setup as expected
      51           2 :         CATCH_START_SECTION("verify that the object looks as expected")
      52             :         {
      53           1 :             CATCH_REQUIRE(dc.isValid());
      54           1 :             CATCH_REQUIRE_FALSE(dc.entries().empty());
      55           1 :             CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
      56           1 :             CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
      57           1 :             CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
      58           1 :             CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
      59           1 :             CATCH_REQUIRE(dc.getName() == "-");   // default name is "-"
      60           1 :             CATCH_REQUIRE(dc.size() == 1);
      61           1 :             dc.mustBeValid();
      62             : 
      63           1 :             zipios::DirectoryCollection copy_constructor(dc);
      64           1 :             CATCH_REQUIRE(copy_constructor.isValid());
      65           1 :             CATCH_REQUIRE_FALSE(copy_constructor.entries().empty());
      66           1 :             CATCH_REQUIRE_FALSE(copy_constructor.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
      67           1 :             CATCH_REQUIRE_FALSE(copy_constructor.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
      68           1 :             CATCH_REQUIRE_FALSE(copy_constructor.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
      69           1 :             CATCH_REQUIRE_FALSE(copy_constructor.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
      70           1 :             CATCH_REQUIRE(copy_constructor.getName() == "-");   // copy name as is
      71           1 :             CATCH_REQUIRE(copy_constructor.size() == 1);
      72           1 :             copy_constructor.mustBeValid();
      73             : 
      74           1 :             zipios::DirectoryCollection copy_assignment;
      75           1 :             copy_assignment = dc;
      76           1 :             CATCH_REQUIRE(copy_assignment.isValid());
      77           1 :             CATCH_REQUIRE_FALSE(copy_assignment.entries().empty());
      78           1 :             CATCH_REQUIRE_FALSE(copy_assignment.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
      79           1 :             CATCH_REQUIRE_FALSE(copy_assignment.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
      80           1 :             CATCH_REQUIRE_FALSE(copy_assignment.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
      81           1 :             CATCH_REQUIRE_FALSE(copy_assignment.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
      82           1 :             CATCH_REQUIRE(copy_assignment.getName() == "-");   // copy name as is
      83           1 :             CATCH_REQUIRE(copy_assignment.size() == 1);
      84           1 :             copy_assignment.mustBeValid();
      85             : 
      86           1 :             zipios::FileCollection::pointer_t clone(dc.clone());
      87           1 :             CATCH_REQUIRE(dynamic_cast<zipios::DirectoryCollection *>(clone.get()));
      88           1 :             CATCH_REQUIRE(clone->isValid());
      89           1 :             CATCH_REQUIRE_FALSE(clone->entries().empty());
      90           1 :             CATCH_REQUIRE_FALSE(clone->getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
      91           1 :             CATCH_REQUIRE_FALSE(clone->getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
      92           1 :             CATCH_REQUIRE_FALSE(clone->getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
      93           1 :             CATCH_REQUIRE_FALSE(clone->getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
      94           1 :             CATCH_REQUIRE(clone->getName() == "-");   // copy name as is
      95           1 :             CATCH_REQUIRE(clone->size() == 1);
      96           1 :             clone->mustBeValid();
      97           1 :         }
      98           2 :         CATCH_END_SECTION()
      99             : 
     100           2 :         CATCH_WHEN("closing the directory")
     101             :         {
     102           1 :             dc.close();
     103             : 
     104           1 :             CATCH_THEN("it is still the same")
     105             :             {
     106           1 :                 CATCH_REQUIRE_FALSE(dc.isValid());
     107           1 :                 CATCH_REQUIRE_THROWS_AS(dc.entries().empty(), zipios::InvalidStateException);
     108           3 :                 CATCH_REQUIRE_THROWS_AS(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
     109           3 :                 CATCH_REQUIRE_THROWS_AS(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
     110           3 :                 CATCH_REQUIRE_THROWS_AS(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
     111           3 :                 CATCH_REQUIRE_THROWS_AS(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
     112           1 :                 CATCH_REQUIRE_THROWS_AS(dc.getName(), zipios::InvalidStateException);   // default name is "-"
     113           1 :                 CATCH_REQUIRE_THROWS_AS(dc.size(), zipios::InvalidStateException);
     114           1 :                 CATCH_REQUIRE_THROWS_AS(dc.mustBeValid(), zipios::InvalidStateException);
     115             : 
     116           1 :                 zipios::DirectoryCollection copy_constructor(dc);
     117           1 :                 CATCH_REQUIRE_FALSE(copy_constructor.isValid());
     118           1 :                 CATCH_REQUIRE_THROWS_AS(copy_constructor.entries().empty(), zipios::InvalidStateException);
     119           3 :                 CATCH_REQUIRE_THROWS_AS(copy_constructor.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
     120           3 :                 CATCH_REQUIRE_THROWS_AS(copy_constructor.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
     121           3 :                 CATCH_REQUIRE_THROWS_AS(copy_constructor.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
     122           3 :                 CATCH_REQUIRE_THROWS_AS(copy_constructor.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
     123           1 :                 CATCH_REQUIRE_THROWS_AS(copy_constructor.getName(), zipios::InvalidStateException);   // copy name as is
     124           1 :                 CATCH_REQUIRE_THROWS_AS(copy_constructor.size(), zipios::InvalidStateException);
     125           1 :                 CATCH_REQUIRE_THROWS_AS(copy_constructor.mustBeValid(), zipios::InvalidStateException);
     126             : 
     127           1 :                 zipios::DirectoryCollection copy_assignment;
     128           1 :                 copy_assignment = dc;
     129           1 :                 CATCH_REQUIRE_FALSE(copy_assignment.isValid());
     130           1 :                 CATCH_REQUIRE_THROWS_AS(copy_assignment.entries().empty(), zipios::InvalidStateException);
     131           3 :                 CATCH_REQUIRE_THROWS_AS(copy_assignment.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
     132           3 :                 CATCH_REQUIRE_THROWS_AS(copy_assignment.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
     133           3 :                 CATCH_REQUIRE_THROWS_AS(copy_assignment.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
     134           3 :                 CATCH_REQUIRE_THROWS_AS(copy_assignment.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
     135           1 :                 CATCH_REQUIRE_THROWS_AS(copy_assignment.getName(), zipios::InvalidStateException);   // copy name as is
     136           1 :                 CATCH_REQUIRE_THROWS_AS(copy_assignment.size(), zipios::InvalidStateException);
     137           1 :                 CATCH_REQUIRE_THROWS_AS(copy_assignment.mustBeValid(), zipios::InvalidStateException);
     138             : 
     139           1 :                 zipios::FileCollection::pointer_t clone(dc.clone());
     140           1 :                 CATCH_REQUIRE(dynamic_cast<zipios::DirectoryCollection *>(clone.get()));
     141           1 :                 CATCH_REQUIRE_FALSE(clone->isValid());
     142           1 :                 CATCH_REQUIRE_THROWS_AS(clone->entries().empty(), zipios::InvalidStateException);
     143           3 :                 CATCH_REQUIRE_THROWS_AS(clone->getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
     144           3 :                 CATCH_REQUIRE_THROWS_AS(clone->getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
     145           3 :                 CATCH_REQUIRE_THROWS_AS(clone->getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
     146           3 :                 CATCH_REQUIRE_THROWS_AS(clone->getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
     147           1 :                 CATCH_REQUIRE_THROWS_AS(clone->getName(), zipios::InvalidStateException);   // copy name as is
     148           1 :                 CATCH_REQUIRE_THROWS_AS(clone->size(), zipios::InvalidStateException);
     149           1 :                 CATCH_REQUIRE_THROWS_AS(clone->mustBeValid(), zipios::InvalidStateException);
     150           2 :             }
     151           2 :         }
     152           4 :     }
     153           2 : }
     154             : 
     155             : 
     156           2 : CATCH_TEST_CASE("DirectoryCollection_with_a_valid_file_but_no_directory", "[DirectoryCollection][FileCollection]")
     157             : {
     158           2 :     zipios_test::safe_chdir cwd(SNAP_CATCH2_NAMESPACE::g_tmp_dir());
     159           4 :     zipios_test::auto_unlink_t auto_unlink("directory-collection-test.txt", true);
     160             : 
     161             :     // create a small random file
     162           2 :     int const file_size(rand() % 100 + 20);
     163             :     {
     164             :         // create a file
     165           2 :         std::ofstream f("directory-collection-test.txt", std::ios::out | std::ios::binary);
     166          76 :         for(int j(0); j < file_size; ++j)
     167             :         {
     168          74 :             char const c(rand());
     169          74 :             f << c;
     170             :         }
     171           2 :     }
     172             : 
     173           2 :     CATCH_START_SECTION("verify that the object looks as expected in recursive mode")
     174             :     {
     175             :         // recursive reading
     176           2 :         zipios::DirectoryCollection dc("directory-collection-test.txt", true);
     177             : 
     178             :         // not valid because it is not a directory
     179           1 :         CATCH_REQUIRE(dc.isValid());
     180           1 :         CATCH_REQUIRE_FALSE(dc.entries().empty());
     181           1 :         CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
     182           1 :         CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     183           1 :         CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
     184           1 :         CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     185           1 :         CATCH_REQUIRE(dc.getName() == "directory-collection-test.txt");
     186           1 :         CATCH_REQUIRE(dc.size() == 1);
     187           1 :         dc.mustBeValid();
     188             : 
     189           1 :         dc.close();
     190             : 
     191             :         // not valid because it is not a directory
     192           1 :         CATCH_REQUIRE_FALSE(dc.isValid());
     193           1 :         CATCH_REQUIRE_THROWS_AS(dc.entries().empty(), zipios::InvalidStateException);
     194           3 :         CATCH_REQUIRE_THROWS_AS(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
     195           3 :         CATCH_REQUIRE_THROWS_AS(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
     196           3 :         CATCH_REQUIRE_THROWS_AS(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
     197           3 :         CATCH_REQUIRE_THROWS_AS(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
     198           1 :         CATCH_REQUIRE_THROWS_AS(dc.getName(), zipios::InvalidStateException);
     199           1 :         CATCH_REQUIRE_THROWS_AS(dc.size(), zipios::InvalidStateException);
     200           1 :         CATCH_REQUIRE_THROWS_AS(dc.mustBeValid(), zipios::InvalidStateException);
     201           1 :     }
     202           2 :     CATCH_END_SECTION()
     203             : 
     204           2 :     CATCH_START_SECTION("verify that the object looks as expected in non-recursive mode")
     205             :     {
     206             :         // recursive reading
     207           2 :         zipios::DirectoryCollection dc("directory-collection-test.txt", false);
     208             : 
     209             :         // not valid because it is not a directory
     210           1 :         CATCH_REQUIRE(dc.isValid());
     211           1 :         CATCH_REQUIRE_FALSE(dc.entries().empty());
     212           1 :         CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
     213           1 :         CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     214           1 :         CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
     215           1 :         CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     216           1 :         CATCH_REQUIRE(dc.getName() == "directory-collection-test.txt");
     217           1 :         CATCH_REQUIRE(dc.size() == 1);
     218           1 :         dc.mustBeValid();
     219             : 
     220           1 :         dc.close();
     221             : 
     222             :         // not valid because it is not a directory
     223           1 :         CATCH_REQUIRE_FALSE(dc.isValid());
     224           1 :         CATCH_REQUIRE_THROWS_AS(dc.entries().empty(), zipios::InvalidStateException);
     225           3 :         CATCH_REQUIRE_THROWS_AS(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
     226           3 :         CATCH_REQUIRE_THROWS_AS(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
     227           3 :         CATCH_REQUIRE_THROWS_AS(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
     228           3 :         CATCH_REQUIRE_THROWS_AS(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
     229           1 :         CATCH_REQUIRE_THROWS_AS(dc.getName(), zipios::InvalidStateException);
     230           1 :         CATCH_REQUIRE_THROWS_AS(dc.size(), zipios::InvalidStateException);
     231           1 :         CATCH_REQUIRE_THROWS_AS(dc.mustBeValid(), zipios::InvalidStateException);
     232           1 :     }
     233           2 :     CATCH_END_SECTION()
     234           2 : }
     235             : 
     236             : 
     237           1 : CATCH_TEST_CASE("DirectoryCollection_with_valid_trees_of_files", "[DirectoryCollection][FileCollection]")
     238             : {
     239           1 :     zipios_test::safe_chdir cwd(SNAP_CATCH2_NAMESPACE::g_tmp_dir());
     240             : 
     241           7 :     for(int i(0); i < 6; ++i)
     242             :     {
     243             :         // create a directory tree starting in "tree"
     244           6 :         CATCH_REQUIRE(system("rm -rf tree") == 0); // clean up, just in case
     245           6 :         size_t const start_count(rand() % 40 + 80);
     246          12 :         zipios_test::file_t tree(zipios_test::file_t::type_t::DIRECTORY, start_count, "tree");
     247             : 
     248             :         {
     249          12 :             zipios::DirectoryCollection dc(zipios::DirectoryCollection("tree", true));
     250             : 
     251             :             {
     252           6 :                 CATCH_REQUIRE(dc.isValid());
     253           6 :                 CATCH_REQUIRE_FALSE(dc.entries().empty());
     254           6 :                 CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
     255           6 :                 CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     256           6 :                 CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
     257           6 :                 CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     258           6 :                 CATCH_REQUIRE(dc.getName() == "tree");
     259           6 :                 CATCH_REQUIRE(dc.size() == tree.size());
     260           6 :                 dc.mustBeValid(); // not throwing
     261             : 
     262             :                 {
     263           6 :                     std::ostringstream expected_output;
     264           6 :                     expected_output << "collection 'tree' {";
     265           6 :                     zipios::FileEntry::vector_t v(dc.entries());
     266        7145 :                     for(auto it(v.begin()); it != v.end(); ++it)
     267             :                     {
     268        7139 :                         zipios::FileEntry::pointer_t entry(*it);
     269             : 
     270        7139 :                         if(it != v.begin())
     271             :                         {
     272        7133 :                             expected_output << ", ";
     273             :                         }
     274        7139 :                         expected_output << entry->getName();
     275             : 
     276             :                         // verify that our tree knows about this file
     277        7139 :                         zipios_test::file_t::type_t t(tree.find(entry->getName()));
     278        7139 :                         CATCH_REQUIRE(t != zipios_test::file_t::type_t::UNKNOWN);
     279             : 
     280             :                         struct stat file_stats;
     281        7139 :                         CATCH_REQUIRE(stat(entry->getName().c_str(), &file_stats) == 0);
     282             : 
     283        7139 :                         CATCH_REQUIRE((*it)->getComment().empty());
     284        7139 :                         CATCH_REQUIRE((*it)->getCompressedSize() == (*it)->getSize());
     285        7139 :                         CATCH_REQUIRE((*it)->getCrc() == 0);
     286        7139 :                         CATCH_REQUIRE((*it)->getEntryOffset() == 0);
     287        7139 :                         CATCH_REQUIRE((*it)->getExtra().empty());
     288        7139 :                         CATCH_REQUIRE((*it)->getHeaderSize() == 0);
     289        7139 :                         CATCH_REQUIRE((*it)->getMethod() == zipios::StorageMethod::STORED);
     290             :                         //CATCH_REQUIRE((*it)->getName() == ...);
     291             :                         //CATCH_REQUIRE((*it)->getFileName() == ...);
     292        7139 :                         zipios::DOSDateTime dt;
     293        7139 :                         dt.setUnixTimestamp(file_stats.st_mtime);
     294        7139 :                         CATCH_REQUIRE((*it)->getTime() == dt.getDOSDateTime());
     295        7139 :                         CATCH_REQUIRE((*it)->getUnixTime() == file_stats.st_mtime);
     296        7139 :                         CATCH_REQUIRE_FALSE((*it)->hasCrc());
     297        7139 :                         if(t == zipios_test::file_t::type_t::DIRECTORY)
     298             :                         {
     299         732 :                             CATCH_REQUIRE((*it)->isDirectory());
     300         732 :                             CATCH_REQUIRE((*it)->getSize() == 0); // size is zero for directories
     301             :                         }
     302             :                         else
     303             :                         {
     304        6407 :                             CATCH_REQUIRE_FALSE((*it)->isDirectory());
     305        6407 :                             CATCH_REQUIRE((*it)->getSize() == static_cast<std::size_t>(file_stats.st_size));
     306             :                         }
     307        7139 :                         CATCH_REQUIRE((*it)->isValid());
     308             :                         //CATCH_REQUIRE((*it)->toString() == "... (0 bytes)");
     309             : 
     310        7139 :                         CATCH_REQUIRE_THROWS_AS((*it)->read(std::cin), zipios::IOException);
     311        7139 :                         CATCH_REQUIRE_THROWS_AS((*it)->write(std::cout), zipios::IOException);
     312        7139 :                     }
     313           6 :                     expected_output << "}";
     314             : 
     315           6 :                     std::ostringstream output;
     316           6 :                     output << dc;
     317           6 :                     CATCH_REQUIRE(expected_output.str() == output.str());
     318           6 :                 }
     319             :             }
     320             : 
     321             :             {
     322           6 :                 zipios::DirectoryCollection copy_constructor(dc);
     323           6 :                 CATCH_REQUIRE(copy_constructor.isValid());
     324           6 :                 CATCH_REQUIRE_FALSE(copy_constructor.entries().empty());
     325           6 :                 CATCH_REQUIRE_FALSE(copy_constructor.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
     326           6 :                 CATCH_REQUIRE_FALSE(copy_constructor.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     327           6 :                 CATCH_REQUIRE_FALSE(copy_constructor.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
     328           6 :                 CATCH_REQUIRE_FALSE(copy_constructor.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     329           6 :                 CATCH_REQUIRE(copy_constructor.getName() == "tree");
     330           6 :                 CATCH_REQUIRE(copy_constructor.size() == tree.size());
     331           6 :                 copy_constructor.mustBeValid();
     332             : 
     333             :                 {
     334           6 :                     zipios::FileEntry::vector_t v(copy_constructor.entries());
     335        7145 :                     for(auto it(v.begin()); it != v.end(); ++it)
     336             :                     {
     337        7139 :                         zipios::FileEntry::pointer_t entry(*it);
     338             : 
     339             :                         // verify that our tree knows about this file
     340        7139 :                         zipios_test::file_t::type_t t(tree.find(entry->getName()));
     341        7139 :                         CATCH_REQUIRE(t != zipios_test::file_t::type_t::UNKNOWN);
     342             : 
     343             :                         struct stat file_stats;
     344        7139 :                         CATCH_REQUIRE(stat(entry->getName().c_str(), &file_stats) == 0);
     345             : 
     346        7139 :                         CATCH_REQUIRE((*it)->getComment().empty());
     347        7139 :                         CATCH_REQUIRE((*it)->getCompressedSize() == (*it)->getSize());
     348        7139 :                         CATCH_REQUIRE((*it)->getCrc() == 0);
     349        7139 :                         CATCH_REQUIRE((*it)->getEntryOffset() == 0);
     350        7139 :                         CATCH_REQUIRE((*it)->getExtra().empty());
     351        7139 :                         CATCH_REQUIRE((*it)->getHeaderSize() == 0);
     352        7139 :                         CATCH_REQUIRE((*it)->getMethod() == zipios::StorageMethod::STORED);
     353             :                         //CATCH_REQUIRE((*it)->getName() == ...);
     354             :                         //CATCH_REQUIRE((*it)->getFileName() == ...);
     355        7139 :                         zipios::DOSDateTime dt;
     356        7139 :                         dt.setUnixTimestamp(file_stats.st_mtime);
     357        7139 :                         CATCH_REQUIRE((*it)->getTime() == dt.getDOSDateTime());
     358        7139 :                         CATCH_REQUIRE((*it)->getUnixTime() == file_stats.st_mtime);
     359        7139 :                         CATCH_REQUIRE_FALSE((*it)->hasCrc());
     360        7139 :                         if(t == zipios_test::file_t::type_t::DIRECTORY)
     361             :                         {
     362         732 :                             CATCH_REQUIRE((*it)->isDirectory());
     363         732 :                             CATCH_REQUIRE((*it)->getSize() == 0); // size is zero for directories
     364             :                         }
     365             :                         else
     366             :                         {
     367        6407 :                             CATCH_REQUIRE_FALSE((*it)->isDirectory());
     368        6407 :                             CATCH_REQUIRE((*it)->getSize() == static_cast<std::size_t>(file_stats.st_size));
     369             :                         }
     370        7139 :                         CATCH_REQUIRE((*it)->isValid());
     371             :                         //CATCH_REQUIRE((*it)->toString() == "... (0 bytes)");
     372             : 
     373        7139 :                         CATCH_REQUIRE_THROWS_AS((*it)->read(std::cin), zipios::IOException);
     374        7139 :                         CATCH_REQUIRE_THROWS_AS((*it)->write(std::cout), zipios::IOException);
     375        7139 :                     }
     376           6 :                 }
     377           6 :             }
     378             : 
     379             :             {
     380           6 :                 zipios::DirectoryCollection copy_assignment;
     381           6 :                 copy_assignment = dc;
     382           6 :                 CATCH_REQUIRE(copy_assignment.isValid());
     383           6 :                 CATCH_REQUIRE_FALSE(copy_assignment.entries().empty());
     384           6 :                 CATCH_REQUIRE_FALSE(copy_assignment.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
     385           6 :                 CATCH_REQUIRE_FALSE(copy_assignment.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     386           6 :                 CATCH_REQUIRE_FALSE(copy_assignment.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
     387           6 :                 CATCH_REQUIRE_FALSE(copy_assignment.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     388           6 :                 CATCH_REQUIRE(copy_assignment.getName() == "tree");   // copy name as is
     389           6 :                 CATCH_REQUIRE(copy_assignment.size() == tree.size());
     390           6 :                 copy_assignment.mustBeValid();
     391             : 
     392             :                 {
     393           6 :                     zipios::FileEntry::vector_t v(copy_assignment.entries());
     394        7145 :                     for(auto it(v.begin()); it != v.end(); ++it)
     395             :                     {
     396        7139 :                         zipios::FileEntry::pointer_t entry(*it);
     397             : 
     398             :                         // verify that our tree knows about this file
     399        7139 :                         zipios_test::file_t::type_t t(tree.find(entry->getName()));
     400        7139 :                         CATCH_REQUIRE(t != zipios_test::file_t::type_t::UNKNOWN);
     401             : 
     402             :                         struct stat file_stats;
     403        7139 :                         CATCH_REQUIRE(stat(entry->getName().c_str(), &file_stats) == 0);
     404             : 
     405        7139 :                         CATCH_REQUIRE((*it)->getComment().empty());
     406        7139 :                         CATCH_REQUIRE((*it)->getCompressedSize() == (*it)->getSize());
     407        7139 :                         CATCH_REQUIRE((*it)->getCrc() == 0);
     408        7139 :                         CATCH_REQUIRE((*it)->getEntryOffset() == 0);
     409        7139 :                         CATCH_REQUIRE((*it)->getExtra().empty());
     410        7139 :                         CATCH_REQUIRE((*it)->getHeaderSize() == 0);
     411        7139 :                         CATCH_REQUIRE((*it)->getMethod() == zipios::StorageMethod::STORED);
     412             :                         //CATCH_REQUIRE((*it)->getName() == ...);
     413             :                         //CATCH_REQUIRE((*it)->getFileName() == ...);
     414        7139 :                         zipios::DOSDateTime dt;
     415        7139 :                         dt.setUnixTimestamp(file_stats.st_mtime);
     416        7139 :                         CATCH_REQUIRE((*it)->getTime() == dt.getDOSDateTime());
     417        7139 :                         CATCH_REQUIRE((*it)->getUnixTime() == file_stats.st_mtime);
     418        7139 :                         CATCH_REQUIRE_FALSE((*it)->hasCrc());
     419        7139 :                         if(t == zipios_test::file_t::type_t::DIRECTORY)
     420             :                         {
     421         732 :                             CATCH_REQUIRE((*it)->isDirectory());
     422         732 :                             CATCH_REQUIRE((*it)->getSize() == 0); // size is zero for directories
     423             :                         }
     424             :                         else
     425             :                         {
     426        6407 :                             CATCH_REQUIRE_FALSE((*it)->isDirectory());
     427        6407 :                             CATCH_REQUIRE((*it)->getSize() == static_cast<std::size_t>(file_stats.st_size));
     428             :                         }
     429        7139 :                         CATCH_REQUIRE((*it)->isValid());
     430             :                         //CATCH_REQUIRE((*it)->toString() == "... (0 bytes)");
     431             : 
     432        7139 :                         CATCH_REQUIRE_THROWS_AS((*it)->read(std::cin), zipios::IOException);
     433        7139 :                         CATCH_REQUIRE_THROWS_AS((*it)->write(std::cout), zipios::IOException);
     434        7139 :                     }
     435           6 :                 }
     436           6 :             }
     437             : 
     438             :             {
     439           6 :                 zipios::FileCollection::pointer_t clone(dc.clone());
     440           6 :                 CATCH_REQUIRE(dynamic_cast<zipios::DirectoryCollection *>(clone.get()));
     441           6 :                 CATCH_REQUIRE(clone->isValid());
     442           6 :                 CATCH_REQUIRE_FALSE(clone->entries().empty());
     443           6 :                 CATCH_REQUIRE_FALSE(clone->getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
     444           6 :                 CATCH_REQUIRE_FALSE(clone->getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     445           6 :                 CATCH_REQUIRE_FALSE(clone->getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
     446           6 :                 CATCH_REQUIRE_FALSE(clone->getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     447           6 :                 CATCH_REQUIRE(clone->getName() == "tree");
     448           6 :                 CATCH_REQUIRE(clone->size() == tree.size());
     449           6 :                 clone->mustBeValid();
     450             : 
     451             :                 {
     452           6 :                     zipios::FileEntry::vector_t v(clone->entries());
     453        7145 :                     for(auto it(v.begin()); it != v.end(); ++it)
     454             :                     {
     455        7139 :                         zipios::FileEntry::pointer_t entry(*it);
     456             : 
     457             :                         // verify that our tree knows about this file
     458        7139 :                         zipios_test::file_t::type_t t(tree.find(entry->getName()));
     459        7139 :                         CATCH_REQUIRE(t != zipios_test::file_t::type_t::UNKNOWN);
     460             : 
     461             :                         struct stat file_stats;
     462        7139 :                         CATCH_REQUIRE(stat(entry->getName().c_str(), &file_stats) == 0);
     463             : 
     464        7139 :                         CATCH_REQUIRE((*it)->getComment().empty());
     465        7139 :                         CATCH_REQUIRE((*it)->getCompressedSize() == (*it)->getSize());
     466        7139 :                         CATCH_REQUIRE((*it)->getCrc() == 0);
     467        7139 :                         CATCH_REQUIRE((*it)->getEntryOffset() == 0);
     468        7139 :                         CATCH_REQUIRE((*it)->getExtra().empty());
     469        7139 :                         CATCH_REQUIRE((*it)->getHeaderSize() == 0);
     470        7139 :                         CATCH_REQUIRE((*it)->getMethod() == zipios::StorageMethod::STORED);
     471             :                         //CATCH_REQUIRE((*it)->getName() == ...);
     472             :                         //CATCH_REQUIRE((*it)->getFileName() == ...);
     473        7139 :                         zipios::DOSDateTime dt;
     474        7139 :                         dt.setUnixTimestamp(file_stats.st_mtime);
     475        7139 :                         CATCH_REQUIRE((*it)->getTime() == dt.getDOSDateTime());
     476        7139 :                         CATCH_REQUIRE((*it)->getUnixTime() == file_stats.st_mtime);
     477        7139 :                         CATCH_REQUIRE_FALSE((*it)->hasCrc());
     478        7139 :                         if(t == zipios_test::file_t::type_t::DIRECTORY)
     479             :                         {
     480         732 :                             CATCH_REQUIRE((*it)->isDirectory());
     481         732 :                             CATCH_REQUIRE((*it)->getSize() == 0); // size is zero for directories
     482             :                         }
     483             :                         else
     484             :                         {
     485        6407 :                             CATCH_REQUIRE_FALSE((*it)->isDirectory());
     486        6407 :                             CATCH_REQUIRE((*it)->getSize() == static_cast<std::size_t>(file_stats.st_size));
     487             :                         }
     488        7139 :                         CATCH_REQUIRE((*it)->isValid());
     489             :                         //CATCH_REQUIRE((*it)->toString() == "... (0 bytes)");
     490             : 
     491        7139 :                         CATCH_REQUIRE_THROWS_AS((*it)->read(std::cin), zipios::IOException);
     492        7139 :                         CATCH_REQUIRE_THROWS_AS((*it)->write(std::cout), zipios::IOException);
     493        7139 :                     }
     494           6 :                 }
     495           6 :             }
     496             : 
     497             :             {
     498             :                 // this one is recursive so we get ALL the files in
     499             :                 // the collection
     500           6 :                 zipios_test::file_t::filenames_t all_files(tree.get_all_filenames());
     501             : 
     502        7145 :                 for(auto it(all_files.begin()); it != all_files.end(); ++it)
     503             :                 {
     504        7139 :                     std::string const name(*it);
     505             : 
     506        7139 :                     if(!name.empty() && name.back() == '/')  // Directory?
     507             :                     {
     508             :                         // directories cannot be attached to an istream
     509         732 :                         zipios::DirectoryCollection::stream_pointer_t is1(dc.getInputStream(name));
     510         732 :                         CATCH_REQUIRE_FALSE(is1);
     511             : 
     512             :                         // also test without the ending '/', just in case
     513         732 :                         zipios::DirectoryCollection::stream_pointer_t is2(dc.getInputStream(name.substr(0, name.length() - 1)));
     514         732 :                         CATCH_REQUIRE_FALSE(is2);
     515             : 
     516             :                         // now also test the getEntry() which works with MATCH
     517             :                         // or IGNORE -- prove it!
     518         732 :                         zipios::FileEntry::pointer_t entry_match(dc.getEntry(name.substr(0, name.length() - 1), zipios::FileCollection::MatchPath::MATCH));
     519         732 :                         CATCH_REQUIRE(entry_match);
     520             : 
     521         732 :                         std::string::size_type pos(name.rfind('/', name.length() - 2));
     522         732 :                         if(pos == std::string::npos)
     523             :                         {
     524           6 :                             pos = 0;
     525             :                         }
     526             :                         else
     527             :                         {
     528         726 :                             ++pos;
     529             :                         }
     530         732 :                         zipios::FileEntry::pointer_t entry_ignore(dc.getEntry(name.substr(pos, name.length() - 1 - pos), zipios::FileCollection::MatchPath::IGNORE));
     531         732 :                         CATCH_REQUIRE(entry_ignore);
     532         732 :                     }
     533             :                     else
     534             :                     {
     535             :                         // files must all work and we can read them and
     536             :                         // compare with the "real thing" and it is equal
     537        6407 :                         zipios::FileCollection::stream_pointer_t is(dc.getInputStream(name));
     538        6407 :                         CATCH_REQUIRE(is);
     539             : 
     540        6407 :                         std::ifstream in(name, std::ios::in | std::ios::binary);
     541             : 
     542       49786 :                         while(in && *is)
     543             :                         {
     544             :                             char buf1[BUFSIZ], buf2[BUFSIZ];
     545             : 
     546       43379 :                             in.read(buf1, sizeof(buf1));
     547       43379 :                             std::streamsize sz1(in.gcount());
     548             : 
     549       43379 :                             is->read(buf2, sizeof(buf2));
     550       43379 :                             std::streamsize sz2(is->gcount());
     551             : 
     552       43379 :                             CATCH_REQUIRE(sz1 == sz2);
     553       43379 :                             CATCH_REQUIRE(memcmp(buf1, buf2, sz1) == 0);
     554             :                         }
     555             : 
     556        6407 :                         CATCH_REQUIRE_FALSE(in);
     557        6407 :                         CATCH_REQUIRE_FALSE(*is);
     558             : 
     559             :                         // now also test the getEntry() which works with MATCH
     560             :                         // or IGNORE -- prove it!
     561        6407 :                         zipios::FileEntry::pointer_t entry_match(dc.getEntry(name, zipios::FileCollection::MatchPath::MATCH));
     562        6407 :                         CATCH_REQUIRE(entry_match);
     563             : 
     564        6407 :                         std::string::size_type pos(name.rfind('/'));
     565        6407 :                         if(pos == std::string::npos)
     566             :                         {
     567             :                             pos = 0; // LCOV_EXCL_LINE
     568             :                         }
     569             :                         else
     570             :                         {
     571        6407 :                             ++pos;
     572             :                         }
     573        6407 :                         zipios::FileEntry::pointer_t entry_ignore(dc.getEntry(name.substr(pos, name.length() - pos), zipios::FileCollection::MatchPath::IGNORE));
     574        6407 :                         CATCH_REQUIRE(entry_ignore);
     575        6407 :                     }
     576        7139 :                 }
     577           6 :             }
     578             : 
     579             :             {
     580           6 :                 dc.close();
     581             : 
     582             :                 // not valid because it was closed
     583           6 :                 CATCH_REQUIRE_FALSE(dc.isValid());
     584           6 :                 CATCH_REQUIRE_THROWS_AS(dc.entries().empty(), zipios::InvalidStateException);
     585          18 :                 CATCH_REQUIRE_THROWS_AS(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
     586          18 :                 CATCH_REQUIRE_THROWS_AS(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
     587          18 :                 CATCH_REQUIRE_THROWS_AS(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
     588          18 :                 CATCH_REQUIRE_THROWS_AS(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
     589           6 :                 CATCH_REQUIRE_THROWS_AS(dc.getName(), zipios::InvalidStateException);
     590           6 :                 CATCH_REQUIRE_THROWS_AS(dc.size(), zipios::InvalidStateException);
     591           6 :                 CATCH_REQUIRE_THROWS_AS(dc.mustBeValid(), zipios::InvalidStateException);
     592             :             }
     593           6 :         }
     594             : 
     595             :         {
     596          12 :             zipios::DirectoryCollection dc(zipios::DirectoryCollection("tree", false));
     597             : 
     598             :             {
     599           6 :                 CATCH_REQUIRE(dc.isValid());
     600           6 :                 CATCH_REQUIRE_FALSE(dc.entries().empty());
     601           6 :                 CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
     602           6 :                 CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     603           6 :                 CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
     604           6 :                 CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     605           6 :                 CATCH_REQUIRE(dc.getName() == "tree");
     606           6 :                 CATCH_REQUIRE(dc.size() == tree.children().size() + 1);
     607           6 :                 dc.mustBeValid(); // not throwing
     608             : 
     609             :                 {
     610           6 :                     zipios::FileEntry::vector_t v(dc.entries());
     611         651 :                     for(auto it(v.begin()); it != v.end(); ++it)
     612             :                     {
     613         645 :                         zipios::FileEntry::pointer_t entry(*it);
     614             : 
     615             :                         // verify that our tree knows about this file
     616         645 :                         zipios_test::file_t::type_t t(tree.find(entry->getName()));
     617         645 :                         CATCH_REQUIRE(t != zipios_test::file_t::type_t::UNKNOWN);
     618             : 
     619             :                         struct stat file_stats;
     620         645 :                         CATCH_REQUIRE(stat(entry->getName().c_str(), &file_stats) == 0);
     621             : 
     622         645 :                         CATCH_REQUIRE((*it)->getComment().empty());
     623         645 :                         CATCH_REQUIRE((*it)->getCompressedSize() == (*it)->getSize());
     624         645 :                         CATCH_REQUIRE((*it)->getCrc() == 0);
     625         645 :                         CATCH_REQUIRE((*it)->getEntryOffset() == 0);
     626         645 :                         CATCH_REQUIRE((*it)->getExtra().empty());
     627         645 :                         CATCH_REQUIRE((*it)->getHeaderSize() == 0);
     628         645 :                         CATCH_REQUIRE((*it)->getMethod() == zipios::StorageMethod::STORED);
     629             :                         //CATCH_REQUIRE((*it)->getName() == ...);
     630             :                         //CATCH_REQUIRE((*it)->getFileName() == ...);
     631         645 :                         zipios::DOSDateTime dt;
     632         645 :                         dt.setUnixTimestamp(file_stats.st_mtime);
     633         645 :                         CATCH_REQUIRE((*it)->getTime() == dt.getDOSDateTime());
     634         645 :                         CATCH_REQUIRE((*it)->getUnixTime() == file_stats.st_mtime);
     635         645 :                         CATCH_REQUIRE_FALSE((*it)->hasCrc());
     636         645 :                         if(t == zipios_test::file_t::type_t::DIRECTORY)
     637             :                         {
     638          77 :                             CATCH_REQUIRE((*it)->isDirectory());
     639          77 :                             CATCH_REQUIRE((*it)->getSize() == 0); // size is zero for directories
     640             :                         }
     641             :                         else
     642             :                         {
     643         568 :                             CATCH_REQUIRE_FALSE((*it)->isDirectory());
     644         568 :                             CATCH_REQUIRE((*it)->getSize() == static_cast<std::size_t>(file_stats.st_size));
     645             :                         }
     646         645 :                         CATCH_REQUIRE((*it)->isValid());
     647             :                         //CATCH_REQUIRE((*it)->toString() == "... (0 bytes)");
     648             : 
     649         645 :                         CATCH_REQUIRE_THROWS_AS((*it)->read(std::cin), zipios::IOException);
     650         645 :                         CATCH_REQUIRE_THROWS_AS((*it)->write(std::cout), zipios::IOException);
     651         645 :                     }
     652           6 :                 }
     653             : 
     654           6 :                 zipios::DirectoryCollection copy_constructor(dc);
     655           6 :                 CATCH_REQUIRE(copy_constructor.isValid());
     656           6 :                 CATCH_REQUIRE_FALSE(copy_constructor.entries().empty());
     657           6 :                 CATCH_REQUIRE_FALSE(copy_constructor.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
     658           6 :                 CATCH_REQUIRE_FALSE(copy_constructor.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     659           6 :                 CATCH_REQUIRE_FALSE(copy_constructor.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
     660           6 :                 CATCH_REQUIRE_FALSE(copy_constructor.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     661           6 :                 CATCH_REQUIRE(copy_constructor.getName() == "tree");
     662           6 :                 CATCH_REQUIRE(copy_constructor.size() == tree.children().size() + 1);
     663           6 :                 copy_constructor.mustBeValid();
     664             : 
     665             :                 {
     666           6 :                     zipios::FileEntry::vector_t v(copy_constructor.entries());
     667         651 :                     for(auto it(v.begin()); it != v.end(); ++it)
     668             :                     {
     669         645 :                         zipios::FileEntry::pointer_t entry(*it);
     670             : 
     671             :                         // verify that our tree knows about this file
     672         645 :                         zipios_test::file_t::type_t t(tree.find(entry->getName()));
     673         645 :                         CATCH_REQUIRE(t != zipios_test::file_t::type_t::UNKNOWN);
     674             : 
     675             :                         struct stat file_stats;
     676         645 :                         CATCH_REQUIRE(stat(entry->getName().c_str(), &file_stats) == 0);
     677             : 
     678         645 :                         CATCH_REQUIRE((*it)->getComment().empty());
     679         645 :                         CATCH_REQUIRE((*it)->getCompressedSize() == (*it)->getSize());
     680         645 :                         CATCH_REQUIRE((*it)->getCrc() == 0);
     681         645 :                         CATCH_REQUIRE((*it)->getEntryOffset() == 0);
     682         645 :                         CATCH_REQUIRE((*it)->getExtra().empty());
     683         645 :                         CATCH_REQUIRE((*it)->getHeaderSize() == 0);
     684         645 :                         CATCH_REQUIRE((*it)->getMethod() == zipios::StorageMethod::STORED);
     685             :                         //CATCH_REQUIRE((*it)->getName() == ...);
     686             :                         //CATCH_REQUIRE((*it)->getFileName() == ...);
     687         645 :                         zipios::DOSDateTime dt;
     688         645 :                         dt.setUnixTimestamp(file_stats.st_mtime);
     689         645 :                         CATCH_REQUIRE((*it)->getTime() == dt.getDOSDateTime());
     690         645 :                         CATCH_REQUIRE((*it)->getUnixTime() == file_stats.st_mtime);
     691         645 :                         CATCH_REQUIRE_FALSE((*it)->hasCrc());
     692         645 :                         if(t == zipios_test::file_t::type_t::DIRECTORY)
     693             :                         {
     694          77 :                             CATCH_REQUIRE((*it)->isDirectory());
     695          77 :                             CATCH_REQUIRE((*it)->getSize() == 0); // size is zero for directories
     696             :                         }
     697             :                         else
     698             :                         {
     699         568 :                             CATCH_REQUIRE_FALSE((*it)->isDirectory());
     700         568 :                             CATCH_REQUIRE((*it)->getSize() == static_cast<std::size_t>(file_stats.st_size));
     701             :                         }
     702         645 :                         CATCH_REQUIRE((*it)->isValid());
     703             :                         //CATCH_REQUIRE((*it)->toString() == "... (0 bytes)");
     704             : 
     705         645 :                         CATCH_REQUIRE_THROWS_AS((*it)->read(std::cin), zipios::IOException);
     706         645 :                         CATCH_REQUIRE_THROWS_AS((*it)->write(std::cout), zipios::IOException);
     707         645 :                     }
     708           6 :                 }
     709             : 
     710           6 :                 zipios::DirectoryCollection copy_assignment;
     711           6 :                 copy_assignment = dc;
     712           6 :                 CATCH_REQUIRE(copy_assignment.isValid());
     713           6 :                 CATCH_REQUIRE_FALSE(copy_assignment.entries().empty());
     714           6 :                 CATCH_REQUIRE_FALSE(copy_assignment.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
     715           6 :                 CATCH_REQUIRE_FALSE(copy_assignment.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     716           6 :                 CATCH_REQUIRE_FALSE(copy_assignment.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
     717           6 :                 CATCH_REQUIRE_FALSE(copy_assignment.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     718           6 :                 CATCH_REQUIRE(copy_assignment.getName() == "tree");   // copy name as is
     719           6 :                 CATCH_REQUIRE(copy_assignment.size() == tree.children().size() + 1);
     720           6 :                 copy_assignment.mustBeValid();
     721             : 
     722             :                 {
     723           6 :                     zipios::FileEntry::vector_t v(copy_assignment.entries());
     724         651 :                     for(auto it(v.begin()); it != v.end(); ++it)
     725             :                     {
     726         645 :                         zipios::FileEntry::pointer_t entry(*it);
     727             : 
     728             :                         // verify that our tree knows about this file
     729         645 :                         zipios_test::file_t::type_t t(tree.find(entry->getName()));
     730         645 :                         CATCH_REQUIRE(t != zipios_test::file_t::type_t::UNKNOWN);
     731             : 
     732             :                         struct stat file_stats;
     733         645 :                         CATCH_REQUIRE(stat(entry->getName().c_str(), &file_stats) == 0);
     734             : 
     735         645 :                         CATCH_REQUIRE((*it)->getComment().empty());
     736         645 :                         CATCH_REQUIRE((*it)->getCompressedSize() == (*it)->getSize());
     737         645 :                         CATCH_REQUIRE((*it)->getCrc() == 0);
     738         645 :                         CATCH_REQUIRE((*it)->getEntryOffset() == 0);
     739         645 :                         CATCH_REQUIRE((*it)->getExtra().empty());
     740         645 :                         CATCH_REQUIRE((*it)->getHeaderSize() == 0);
     741         645 :                         CATCH_REQUIRE((*it)->getMethod() == zipios::StorageMethod::STORED);
     742             :                         //CATCH_REQUIRE((*it)->getName() == ...);
     743             :                         //CATCH_REQUIRE((*it)->getFileName() == ...);
     744         645 :                         zipios::DOSDateTime dt;
     745         645 :                         dt.setUnixTimestamp(file_stats.st_mtime);
     746         645 :                         CATCH_REQUIRE((*it)->getTime() == dt.getDOSDateTime());
     747         645 :                         CATCH_REQUIRE((*it)->getUnixTime() == file_stats.st_mtime);
     748         645 :                         CATCH_REQUIRE_FALSE((*it)->hasCrc());
     749         645 :                         if(t == zipios_test::file_t::type_t::DIRECTORY)
     750             :                         {
     751          77 :                             CATCH_REQUIRE((*it)->isDirectory());
     752          77 :                             CATCH_REQUIRE((*it)->getSize() == 0); // size is zero for directories
     753             :                         }
     754             :                         else
     755             :                         {
     756         568 :                             CATCH_REQUIRE_FALSE((*it)->isDirectory());
     757         568 :                             CATCH_REQUIRE((*it)->getSize() == static_cast<std::size_t>(file_stats.st_size));
     758             :                         }
     759         645 :                         CATCH_REQUIRE((*it)->isValid());
     760             :                         //CATCH_REQUIRE((*it)->toString() == "... (0 bytes)");
     761             : 
     762         645 :                         CATCH_REQUIRE_THROWS_AS((*it)->read(std::cin), zipios::IOException);
     763         645 :                         CATCH_REQUIRE_THROWS_AS((*it)->write(std::cout), zipios::IOException);
     764         645 :                     }
     765           6 :                 }
     766             : 
     767           6 :                 zipios::FileCollection::pointer_t clone(dc.clone());
     768           6 :                 CATCH_REQUIRE(dynamic_cast<zipios::DirectoryCollection *>(clone.get()));
     769           6 :                 CATCH_REQUIRE(clone->isValid());
     770           6 :                 CATCH_REQUIRE_FALSE(clone->entries().empty());
     771           6 :                 CATCH_REQUIRE_FALSE(clone->getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
     772           6 :                 CATCH_REQUIRE_FALSE(clone->getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     773           6 :                 CATCH_REQUIRE_FALSE(clone->getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
     774           6 :                 CATCH_REQUIRE_FALSE(clone->getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     775           6 :                 CATCH_REQUIRE(clone->getName() == "tree");
     776           6 :                 CATCH_REQUIRE(clone->size() == tree.children().size() + 1);
     777           6 :                 clone->mustBeValid();
     778             : 
     779             :                 {
     780           6 :                     zipios::FileEntry::vector_t v(clone->entries());
     781         651 :                     for(auto it(v.begin()); it != v.end(); ++it)
     782             :                     {
     783         645 :                         zipios::FileEntry::pointer_t entry(*it);
     784             : 
     785             :                         // verify that our tree knows about this file
     786         645 :                         zipios_test::file_t::type_t t(tree.find(entry->getName()));
     787         645 :                         CATCH_REQUIRE(t != zipios_test::file_t::type_t::UNKNOWN);
     788             : 
     789             :                         struct stat file_stats;
     790         645 :                         CATCH_REQUIRE(stat(entry->getName().c_str(), &file_stats) == 0);
     791             : 
     792         645 :                         CATCH_REQUIRE((*it)->getComment().empty());
     793         645 :                         CATCH_REQUIRE((*it)->getCompressedSize() == (*it)->getSize());
     794         645 :                         CATCH_REQUIRE((*it)->getCrc() == 0);
     795         645 :                         CATCH_REQUIRE((*it)->getEntryOffset() == 0);
     796         645 :                         CATCH_REQUIRE((*it)->getExtra().empty());
     797         645 :                         CATCH_REQUIRE((*it)->getHeaderSize() == 0);
     798         645 :                         CATCH_REQUIRE((*it)->getMethod() == zipios::StorageMethod::STORED);
     799             :                         //CATCH_REQUIRE((*it)->getName() == ...);
     800             :                         //CATCH_REQUIRE((*it)->getFileName() == ...);
     801         645 :                         zipios::DOSDateTime dt;
     802         645 :                         dt.setUnixTimestamp(file_stats.st_mtime);
     803         645 :                         CATCH_REQUIRE((*it)->getTime() == dt.getDOSDateTime());
     804         645 :                         CATCH_REQUIRE((*it)->getUnixTime() == file_stats.st_mtime);
     805         645 :                         CATCH_REQUIRE_FALSE((*it)->hasCrc());
     806         645 :                         if(t == zipios_test::file_t::type_t::DIRECTORY)
     807             :                         {
     808          77 :                             CATCH_REQUIRE((*it)->isDirectory());
     809          77 :                             CATCH_REQUIRE((*it)->getSize() == 0); // size is zero for directories
     810             :                         }
     811             :                         else
     812             :                         {
     813         568 :                             CATCH_REQUIRE_FALSE((*it)->isDirectory());
     814         568 :                             CATCH_REQUIRE((*it)->getSize() == static_cast<std::size_t>(file_stats.st_size));
     815             :                         }
     816         645 :                         CATCH_REQUIRE((*it)->isValid());
     817             :                         //CATCH_REQUIRE((*it)->toString() == "... (0 bytes)");
     818             : 
     819         645 :                         CATCH_REQUIRE_THROWS_AS((*it)->read(std::cin), zipios::IOException);
     820         645 :                         CATCH_REQUIRE_THROWS_AS((*it)->write(std::cout), zipios::IOException);
     821         645 :                     }
     822           6 :                 }
     823           6 :             }
     824             : 
     825             :             {
     826             :                 // in this case the DirectoryCollection is not recursive
     827             :                 // so only the top children are available
     828           6 :                 zipios_test::file_t::vector_t all_files(tree.children());
     829             : 
     830         645 :                 for(auto it(all_files.begin()); it != all_files.end(); ++it)
     831             :                 {
     832         639 :                     zipios_test::file_t::pointer_t f(*it);
     833             : 
     834         639 :                     if(f->type() == zipios_test::file_t::type_t::DIRECTORY)  // Directory?
     835             :                     {
     836             :                         // directories cannot be attached to an istream
     837          71 :                         zipios::DirectoryCollection::stream_pointer_t is1(dc.getInputStream(f->filename()));
     838          71 :                         CATCH_REQUIRE_FALSE(is1);
     839          71 :                     }
     840             :                     else
     841             :                     {
     842             :                         // WARNING: in this case we get a "bare" filename
     843             :                         //          from the file_t object
     844             :                         //
     845             :                         // files must all work and we can read them and
     846             :                         // compare with the "real thing" and it is equal
     847             : 
     848             :                         // "tree/" missing...
     849         568 :                         zipios::DirectoryCollection::stream_pointer_t bad_is(dc.getInputStream(f->filename(), zipios::FileCollection::MatchPath::MATCH));
     850         568 :                         CATCH_REQUIRE_FALSE(bad_is);
     851             : 
     852             :                         // in this case we ignore to see that we can indeed
     853             :                         // get the file... unfortunately it could be another
     854             :                         // file with the same name (although unlikely, it
     855             :                         // is very much possible)
     856         568 :                         zipios::DirectoryCollection::stream_pointer_t is(dc.getInputStream(f->filename(), zipios::FileCollection::MatchPath::IGNORE));
     857         568 :                         CATCH_REQUIRE(is);
     858             : 
     859             :                         // So here we verify that it find the correct
     860             :                         // entry, if so then we can compare the files
     861         568 :                         zipios::FileEntry::pointer_t entry_match(dc.getEntry("tree/" + f->filename(), zipios::FileCollection::MatchPath::MATCH));
     862         568 :                         zipios::FileEntry::pointer_t entry_ignore(dc.getEntry(f->filename(), zipios::FileCollection::MatchPath::IGNORE));
     863         568 :                         if(entry_match == entry_ignore)
     864             :                         {
     865         568 :                             std::ifstream in("tree/" + f->filename(), std::ios::in | std::ios::binary);
     866             : 
     867        4390 :                             while(in && *is)
     868             :                             {
     869             :                                 char buf1[BUFSIZ], buf2[BUFSIZ];
     870             : 
     871        3822 :                                 in.read(buf1, sizeof(buf1));
     872        3822 :                                 std::streamsize sz1(in.gcount());
     873             : 
     874        3822 :                                 is->read(buf2, sizeof(buf2));
     875        3822 :                                 std::streamsize sz2(is->gcount());
     876             : 
     877        3822 :                                 CATCH_REQUIRE(sz1 == sz2);
     878        3822 :                                 CATCH_REQUIRE(memcmp(buf1, buf2, sz1) == 0);
     879             :                             }
     880             : 
     881         568 :                             CATCH_REQUIRE_FALSE(in);
     882         568 :                             CATCH_REQUIRE_FALSE(*is);
     883         568 :                         }
     884         568 :                     }
     885         639 :                 }
     886           6 :             }
     887             : 
     888             :             {
     889           6 :                 dc.close();
     890             : 
     891             :                 // not valid because it is not a directory
     892           6 :                 CATCH_REQUIRE_FALSE(dc.isValid());
     893           6 :                 CATCH_REQUIRE_THROWS_AS(dc.entries().empty(), zipios::InvalidStateException);
     894          18 :                 CATCH_REQUIRE_THROWS_AS(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
     895          18 :                 CATCH_REQUIRE_THROWS_AS(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
     896          18 :                 CATCH_REQUIRE_THROWS_AS(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH), zipios::InvalidStateException);
     897          18 :                 CATCH_REQUIRE_THROWS_AS(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE), zipios::InvalidStateException);
     898           6 :                 CATCH_REQUIRE_THROWS_AS(dc.getName(), zipios::InvalidStateException);
     899           6 :                 CATCH_REQUIRE_THROWS_AS(dc.size(), zipios::InvalidStateException);
     900           6 :                 CATCH_REQUIRE_THROWS_AS(dc.mustBeValid(), zipios::InvalidStateException);
     901             :             }
     902           6 :         }
     903           6 :     }
     904           1 : }
     905             : 
     906             : 
     907           1 : CATCH_TEST_CASE("DirectoryCollection with an existing directory that gets deleted", "[DirectoryCollection] [FileCollection]")
     908             : {
     909           1 :     zipios_test::safe_chdir cwd(SNAP_CATCH2_NAMESPACE::g_tmp_dir());
     910             : 
     911             :     // create a directory
     912           1 :     CATCH_REQUIRE(system("rm -rf tree") == 0); // clean up, just in case
     913           1 :     CATCH_REQUIRE(mkdir("tree", 0777) == 0);
     914             : 
     915             :     // the initialization works as expected!
     916           2 :     zipios::DirectoryCollection dc(zipios::DirectoryCollection("tree", false));
     917           1 :     CATCH_REQUIRE(dc.isValid());
     918             : 
     919             :     // now we delete that directory!
     920           1 :     CATCH_REQUIRE(rmdir("tree") == 0);
     921             : 
     922             :     // attempt the get the size, it throws
     923           1 :     CATCH_REQUIRE_THROWS_AS(dc.size(), zipios::IOException);
     924           1 :     CATCH_REQUIRE_FALSE(dc.isValid());
     925           1 : }
     926             : 
     927             : 
     928           1 : CATCH_TEST_CASE("DirectoryCollection with an empty directory", "[DirectoryCollection] [FileCollection]")
     929             : {
     930           1 :     zipios_test::safe_chdir cwd(SNAP_CATCH2_NAMESPACE::g_tmp_dir());
     931             : 
     932             :     // create a directory
     933           1 :     CATCH_REQUIRE(system("rm -rf tree") == 0); // clean up, just in case
     934           1 :     CATCH_REQUIRE(mkdir("tree", 0777) == 0);
     935             : 
     936           1 :     CATCH_START_SECTION("verify that the object looks as expected")
     937             :     {
     938           2 :         zipios::DirectoryCollection dc(zipios::DirectoryCollection("tree", true));
     939             : 
     940           1 :         CATCH_REQUIRE(dc.isValid());
     941           1 :         CATCH_REQUIRE_FALSE(dc.entries().empty());
     942           1 :         CATCH_REQUIRE(dc.entries().size() == 1);
     943           1 :         CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::MATCH));
     944           1 :         CATCH_REQUIRE_FALSE(dc.getEntry("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     945           1 :         CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::MATCH));
     946           1 :         CATCH_REQUIRE_FALSE(dc.getInputStream("inexistant", zipios::FileCollection::MatchPath::IGNORE));
     947           1 :         CATCH_REQUIRE(dc.getName() == "tree");
     948           1 :         CATCH_REQUIRE(dc.size() == 1);
     949           1 :         dc.mustBeValid(); // not throwing
     950             : 
     951             :         {
     952           1 :             zipios::FileEntry::vector_t v(dc.entries());
     953           2 :             for(auto it(v.begin()); it != v.end(); ++it)
     954             :             {
     955           1 :                 zipios::FileEntry::pointer_t entry(*it);
     956             : 
     957             :                 // verify that our tree knows about this file
     958           1 :                 CATCH_REQUIRE(entry->getName() == "tree");
     959             : 
     960             :                 struct stat file_stats;
     961           1 :                 CATCH_REQUIRE(stat(entry->getName().c_str(), &file_stats) == 0);
     962             : 
     963           1 :                 CATCH_REQUIRE((*it)->getComment().empty());
     964           1 :                 CATCH_REQUIRE((*it)->getCompressedSize() == 0);
     965           1 :                 CATCH_REQUIRE((*it)->getCrc() == 0);
     966           1 :                 CATCH_REQUIRE((*it)->getEntryOffset() == 0);
     967           1 :                 CATCH_REQUIRE((*it)->getExtra().empty());
     968           1 :                 CATCH_REQUIRE((*it)->getHeaderSize() == 0);
     969           1 :                 CATCH_REQUIRE((*it)->getMethod() == zipios::StorageMethod::STORED);
     970           1 :                 CATCH_REQUIRE((*it)->getName() == "tree");
     971           1 :                 CATCH_REQUIRE((*it)->getFileName() == "tree");
     972           1 :                 zipios::DOSDateTime t;
     973           1 :                 t.setUnixTimestamp(file_stats.st_mtime);
     974           1 :                 CATCH_REQUIRE((*it)->getTime() == t.getDOSDateTime());
     975           1 :                 CATCH_REQUIRE((*it)->getUnixTime() == file_stats.st_mtime);
     976           1 :                 CATCH_REQUIRE_FALSE((*it)->hasCrc());
     977           1 :                 CATCH_REQUIRE((*it)->isDirectory());
     978           1 :                 CATCH_REQUIRE((*it)->getSize() == 0); // size is zero for directories
     979           1 :                 CATCH_REQUIRE((*it)->isValid());
     980           1 :                 CATCH_REQUIRE((*it)->toString() == "tree (directory)");
     981             : 
     982             :                 // using the << operator to a stream we get the toString() value
     983           1 :                 std::ostringstream output;
     984           1 :                 output << **it;
     985           1 :                 CATCH_REQUIRE(output.str() == "tree (directory)");
     986             : 
     987           1 :                 CATCH_REQUIRE_THROWS_AS((*it)->read(std::cin), zipios::IOException);
     988           1 :                 CATCH_REQUIRE_THROWS_AS((*it)->write(std::cout), zipios::IOException);
     989           1 :             }
     990           1 :         }
     991           1 :     }
     992           1 :     CATCH_END_SECTION()
     993             : 
     994           1 :     rmdir("tree");
     995           1 : }
     996             : 
     997             : 
     998             : // Local Variables:
     999             : // mode: cpp
    1000             : // indent-tabs-mode: nil
    1001             : // c-basic-offset: 4
    1002             : // tab-width: 4
    1003             : // End:
    1004             : 
    1005             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.14

Snap C++ | List of projects | List of versions