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

Generated by: LCOV version 1.10