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

Generated by: LCOV version 1.12