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

Generated by: LCOV version 1.12