LCOV - code coverage report
Current view: top level - tests - directoryentry.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1281 1289 99.4 %
Date: 2019-04-24 14:10:30 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   Zipios -- a small C++ library that provides easy access to .zip files.
       3             : 
       4             :   Copyright (C) 2000-2007  Thomas Sondergaard
       5             :   Copyright (C) 2015-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 DirectoryEntry class.
      25             :  */
      26             : 
      27             : #include "tests.hpp"
      28             : 
      29             : #include "zipios/directoryentry.hpp"
      30             : #include "zipios/zipiosexceptions.hpp"
      31             : #include "zipios/dosdatetime.hpp"
      32             : 
      33             : #include <fstream>
      34             : 
      35             : #include <sys/stat.h>
      36             : #include <unistd.h>
      37             : 
      38             : 
      39             : /** \brief Local definitions used globally in the DirectoryEntry tests.
      40             :  *
      41             :  */
      42             : namespace
      43             : {
      44             : 
      45             : 
      46             : /** \brief Expected level defined as a variable.
      47             :  *
      48             :  * This definition is used because otherwise catch fails seeing the
      49             :  * definition as a global and the linkage fails.
      50             :  */
      51             : zipios::FileEntry::CompressionLevel const g_expected_level(zipios::FileEntry::COMPRESSION_LEVEL_DEFAULT);
      52             : 
      53             : /** \brief Directories make use of level 'none'.
      54             :  *
      55             :  * This value is to verify that the compression level of a directory
      56             :  * is properly defined.
      57             :  */
      58             : zipios::FileEntry::CompressionLevel const g_directory_level(zipios::FileEntry::COMPRESSION_LEVEL_NONE);
      59             : 
      60             : 
      61             : } // no name namespace
      62             : 
      63             : 
      64          13 : SCENARIO("DirectoryEntry with invalid paths", "[DirectoryEntry] [FileEntry]")
      65             : {
      66          24 :     GIVEN("test a fantom file (path that \"cannot\" exists) and no comment")
      67             :     {
      68          24 :         zipios::DirectoryEntry de(zipios::FilePath("/this/file/really/should/not/exist/period.txt"), "");
      69             : 
      70             :         // first, check that the object is setup as expected
      71          24 :         SECTION("verify that the object looks as expected")
      72             :         {
      73           1 :             REQUIRE(de.isEqual(de));
      74           1 :             REQUIRE(de.getComment().empty());
      75           1 :             REQUIRE(de.getCompressedSize() == 0);
      76           1 :             REQUIRE(de.getCrc() == 0);
      77           1 :             REQUIRE(de.getEntryOffset() == 0);
      78           1 :             REQUIRE(de.getExtra().empty());
      79           1 :             REQUIRE(de.getHeaderSize() == 0);
      80           1 :             REQUIRE(de.getLevel() == g_expected_level);
      81           1 :             REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
      82           1 :             REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
      83           1 :             REQUIRE(de.getFileName() == "period.txt");
      84           1 :             REQUIRE(de.getSize() == 0);
      85           1 :             REQUIRE(de.getTime() == 0);  // invalid date
      86           1 :             REQUIRE(de.getUnixTime() == 0);
      87           1 :             REQUIRE_FALSE(de.hasCrc());
      88           1 :             REQUIRE_FALSE(de.isDirectory());
      89           1 :             REQUIRE_FALSE(de.isValid());
      90           1 :             REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
      91             : 
      92           1 :             REQUIRE_THROWS_AS(de.read(std::cin), zipios::IOException);
      93           1 :             REQUIRE_THROWS_AS(de.write(std::cout), zipios::IOException);
      94             : 
      95           2 :             zipios::FileEntry::pointer_t null_entry;
      96             : //            REQUIRE_FALSE(de.isEqual(*null_entry));  // here we are passing a NULL reference which most people think is something impossible to do...
      97             :             //REQUIRE_FALSE(null_entry->isEqual(de)); -- that would obviously crash!
      98             : 
      99           2 :             zipios::DirectoryEntry empty(zipios::FilePath(""), "");
     100           1 :             REQUIRE_FALSE(de.isEqual(empty));
     101           1 :             REQUIRE_FALSE(empty.isEqual(de));
     102             : 
     103             :             // attempt a clone now, should have the same content
     104           2 :             zipios::DirectoryEntry::pointer_t clone(de.clone());
     105             : 
     106           1 :             REQUIRE(clone->getComment().empty());
     107           1 :             REQUIRE(clone->getCompressedSize() == 0);
     108           1 :             REQUIRE(clone->getCrc() == 0);
     109           1 :             REQUIRE(clone->getEntryOffset() == 0);
     110           1 :             REQUIRE(clone->getExtra().empty());
     111           1 :             REQUIRE(clone->getHeaderSize() == 0);
     112           1 :             REQUIRE(clone->getLevel() == g_expected_level);
     113           1 :             REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
     114           1 :             REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
     115           1 :             REQUIRE(clone->getFileName() == "period.txt");
     116           1 :             REQUIRE(clone->getSize() == 0);
     117           1 :             REQUIRE(clone->getTime() == 0);  // invalid date
     118           1 :             REQUIRE(clone->getUnixTime() == 0);
     119           1 :             REQUIRE_FALSE(clone->hasCrc());
     120           1 :             REQUIRE_FALSE(clone->isDirectory());
     121           1 :             REQUIRE_FALSE(clone->isValid());
     122           1 :             REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
     123           1 :             REQUIRE(clone->isEqual(de));
     124           1 :             REQUIRE(de.isEqual(*clone));
     125             :         }
     126             : 
     127          24 :         WHEN("setting the comment")
     128             :         {
     129           1 :             de.setComment("new comment");
     130             : 
     131           2 :             THEN("we can read it and nothing else changed")
     132             :             {
     133           1 :                 REQUIRE(de.getComment() == "new comment");
     134           1 :                 REQUIRE(de.getCompressedSize() == 0);
     135           1 :                 REQUIRE(de.getCrc() == 0);
     136           1 :                 REQUIRE(de.getEntryOffset() == 0);
     137           1 :                 REQUIRE(de.getExtra().empty());
     138           1 :                 REQUIRE(de.getHeaderSize() == 0);
     139           1 :                 REQUIRE(de.getLevel() == g_expected_level);
     140           1 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
     141           1 :                 REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
     142           1 :                 REQUIRE(de.getFileName() == "period.txt");
     143           1 :                 REQUIRE(de.getSize() == 0);
     144           1 :                 REQUIRE(de.getTime() == 0);  // invalid date
     145           1 :                 REQUIRE(de.getUnixTime() == 0);
     146           1 :                 REQUIRE_FALSE(de.hasCrc());
     147           1 :                 REQUIRE_FALSE(de.isDirectory());
     148           1 :                 REQUIRE_FALSE(de.isValid());
     149           1 :                 REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
     150             : 
     151           2 :                 zipios::DirectoryEntry other(zipios::FilePath("another/path"), "");
     152           1 :                 REQUIRE_FALSE(de.isEqual(other));
     153           1 :                 REQUIRE_FALSE(other.isEqual(de));
     154             : 
     155             :                 // attempt a clone now, should have the same content
     156           2 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
     157             : 
     158           1 :                 REQUIRE(clone->getComment() == "new comment");
     159           1 :                 REQUIRE(clone->getCompressedSize() == 0);
     160           1 :                 REQUIRE(clone->getCrc() == 0);
     161           1 :                 REQUIRE(clone->getEntryOffset() == 0);
     162           1 :                 REQUIRE(clone->getExtra().empty());
     163           1 :                 REQUIRE(clone->getHeaderSize() == 0);
     164           1 :                 REQUIRE(clone->getLevel() == g_expected_level);
     165           1 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
     166           1 :                 REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
     167           1 :                 REQUIRE(clone->getFileName() == "period.txt");
     168           1 :                 REQUIRE(clone->getSize() == 0);
     169           1 :                 REQUIRE(clone->getTime() == 0);  // invalid date
     170           1 :                 REQUIRE(clone->getUnixTime() == 0);
     171           1 :                 REQUIRE_FALSE(clone->hasCrc());
     172           1 :                 REQUIRE_FALSE(clone->isDirectory());
     173           1 :                 REQUIRE_FALSE(clone->isValid());
     174           1 :                 REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
     175           1 :                 REQUIRE(clone->isEqual(de));
     176           1 :                 REQUIRE(de.isEqual(*clone));
     177             :             }
     178             :         }
     179             : 
     180          24 :         WHEN("setting the compressed size")
     181             :         {
     182             :             // zero would not really prove anything so skip such
     183             :             // (although it may be extremely rare...)
     184             :             size_t r;
     185           0 :             do
     186             :             {
     187           1 :                 r = zipios_test::rand_size_t();
     188             :             }
     189           1 :             while(r == 0);
     190           1 :             de.setCompressedSize(r);
     191             : 
     192           2 :             THEN("we ignore it")
     193             :             {
     194           1 :                 REQUIRE(de.getComment().empty());
     195           1 :                 REQUIRE(de.getCompressedSize() == 0);
     196           1 :                 REQUIRE(de.getCrc() == 0);
     197           1 :                 REQUIRE(de.getEntryOffset() == 0);
     198           1 :                 REQUIRE(de.getExtra().empty());
     199           1 :                 REQUIRE(de.getHeaderSize() == 0);
     200           1 :                 REQUIRE(de.getLevel() == g_expected_level);
     201           1 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
     202           1 :                 REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
     203           1 :                 REQUIRE(de.getFileName() == "period.txt");
     204           1 :                 REQUIRE(de.getSize() == 0);
     205           1 :                 REQUIRE(de.getTime() == 0);  // invalid date
     206           1 :                 REQUIRE(de.getUnixTime() == 0);
     207           1 :                 REQUIRE_FALSE(de.hasCrc());
     208           1 :                 REQUIRE_FALSE(de.isDirectory());
     209           1 :                 REQUIRE_FALSE(de.isValid());
     210           1 :                 REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
     211             : 
     212           2 :                 zipios::DirectoryEntry same(zipios::FilePath("/this/file/really/should/not/exist/period.txt"), "");
     213           1 :                 REQUIRE(de.isEqual(same));
     214           1 :                 REQUIRE(same.isEqual(de));
     215             : 
     216           2 :                 zipios::DirectoryEntry other(zipios::FilePath("this/file/really/should/not/exist/period.txt"), "");
     217           1 :                 REQUIRE_FALSE(de.isEqual(other));
     218           1 :                 REQUIRE_FALSE(other.isEqual(de));
     219             : 
     220             :                 // attempt a clone now, should have the same content
     221           2 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
     222             : 
     223           1 :                 REQUIRE(clone->getComment().empty());
     224           1 :                 REQUIRE(clone->getCompressedSize() == 0);
     225           1 :                 REQUIRE(clone->getCrc() == 0);
     226           1 :                 REQUIRE(clone->getEntryOffset() == 0);
     227           1 :                 REQUIRE(clone->getExtra().empty());
     228           1 :                 REQUIRE(clone->getHeaderSize() == 0);
     229           1 :                 REQUIRE(clone->getLevel() == g_expected_level);
     230           1 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
     231           1 :                 REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
     232           1 :                 REQUIRE(clone->getFileName() == "period.txt");
     233           1 :                 REQUIRE(clone->getSize() == 0);
     234           1 :                 REQUIRE(clone->getTime() == 0);  // invalid date
     235           1 :                 REQUIRE(clone->getUnixTime() == 0);
     236           1 :                 REQUIRE_FALSE(clone->hasCrc());
     237           1 :                 REQUIRE_FALSE(clone->isDirectory());
     238           1 :                 REQUIRE_FALSE(clone->isValid());
     239           1 :                 REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
     240           1 :                 REQUIRE(clone->isEqual(de));
     241           1 :                 REQUIRE(de.isEqual(*clone));
     242             :             }
     243             :         }
     244             : 
     245          24 :         WHEN("setting the CRC")
     246             :         {
     247             :             // zero would not really prove anything so skip such
     248             :             uint32_t r;
     249           0 :             do
     250             :             {
     251           1 :                 r = rand();
     252             :             }
     253           1 :             while(r == 0);
     254           1 :             de.setCrc(rand());
     255             : 
     256           2 :             THEN("we ignore it")
     257             :             {
     258           1 :                 REQUIRE(de.getComment().empty());
     259           1 :                 REQUIRE(de.getCompressedSize() == 0);
     260           1 :                 REQUIRE(de.getCrc() == 0);
     261           1 :                 REQUIRE(de.getEntryOffset() == 0);
     262           1 :                 REQUIRE(de.getExtra().empty());
     263           1 :                 REQUIRE(de.getHeaderSize() == 0);
     264           1 :                 REQUIRE(de.getLevel() == g_expected_level);
     265           1 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
     266           1 :                 REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
     267           1 :                 REQUIRE(de.getFileName() == "period.txt");
     268           1 :                 REQUIRE(de.getSize() == 0);
     269           1 :                 REQUIRE(de.getTime() == 0);  // invalid date
     270           1 :                 REQUIRE(de.getUnixTime() == 0);
     271           1 :                 REQUIRE_FALSE(de.hasCrc());
     272           1 :                 REQUIRE_FALSE(de.isDirectory());
     273           1 :                 REQUIRE_FALSE(de.isValid());
     274           1 :                 REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
     275             : 
     276           2 :                 zipios::DirectoryEntry other(zipios::FilePath("/this/file/really/should/not/exist/period"), "");
     277           1 :                 REQUIRE_FALSE(de.isEqual(other));
     278           1 :                 REQUIRE_FALSE(other.isEqual(de));
     279             : 
     280             :                 // attempt a clone now, should have the same content
     281           2 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
     282             : 
     283           1 :                 REQUIRE(clone->getComment().empty());
     284           1 :                 REQUIRE(clone->getCompressedSize() == 0);
     285           1 :                 REQUIRE(clone->getCrc() == 0);
     286           1 :                 REQUIRE(clone->getEntryOffset() == 0);
     287           1 :                 REQUIRE(clone->getExtra().empty());
     288           1 :                 REQUIRE(clone->getHeaderSize() == 0);
     289           1 :                 REQUIRE(clone->getLevel() == g_expected_level);
     290           1 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
     291           1 :                 REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
     292           1 :                 REQUIRE(clone->getFileName() == "period.txt");
     293           1 :                 REQUIRE(clone->getSize() == 0);
     294           1 :                 REQUIRE(clone->getTime() == 0);  // invalid date
     295           1 :                 REQUIRE(clone->getUnixTime() == 0);
     296           1 :                 REQUIRE_FALSE(clone->hasCrc());
     297           1 :                 REQUIRE_FALSE(clone->isDirectory());
     298           1 :                 REQUIRE_FALSE(clone->isValid());
     299           1 :                 REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
     300           1 :                 REQUIRE(clone->isEqual(de));
     301           1 :                 REQUIRE(de.isEqual(*clone));
     302             :             }
     303             :         }
     304             : 
     305          24 :         WHEN("setting an extra buffer")
     306             :         {
     307             :             // zero would not really prove anything so skip such
     308           2 :             zipios::FileEntry::buffer_t b;
     309           1 :             uint32_t size(rand() % 100 + 20);
     310          78 :             for(uint32_t i(0); i < size; ++i)
     311             :             {
     312          77 :                 b.push_back(rand());
     313             :             }
     314           1 :             de.setExtra(b);
     315             : 
     316           2 :             THEN("we ignore it")
     317             :             {
     318           1 :                 REQUIRE(de.getComment().empty());
     319           1 :                 REQUIRE(de.getCompressedSize() == 0);
     320           1 :                 REQUIRE(de.getCrc() == 0);
     321           1 :                 REQUIRE(de.getEntryOffset() == 0);
     322           1 :                 REQUIRE_FALSE(de.getExtra().empty());
     323           1 :                 REQUIRE(de.getHeaderSize() == 0);
     324           1 :                 REQUIRE(de.getLevel() == g_expected_level);
     325           1 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
     326           1 :                 REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
     327           1 :                 REQUIRE(de.getFileName() == "period.txt");
     328           1 :                 REQUIRE(de.getSize() == 0);
     329           1 :                 REQUIRE(de.getTime() == 0);  // invalid date
     330           1 :                 REQUIRE(de.getUnixTime() == 0);
     331           1 :                 REQUIRE_FALSE(de.hasCrc());
     332           1 :                 REQUIRE_FALSE(de.isDirectory());
     333           1 :                 REQUIRE_FALSE(de.isValid());
     334           1 :                 REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
     335           1 :                 REQUIRE(de.getExtra() == b);
     336             : 
     337           2 :                 zipios::DirectoryEntry other(zipios::FilePath("period.txt"), "");
     338           1 :                 REQUIRE_FALSE(de.isEqual(other));
     339           1 :                 REQUIRE_FALSE(other.isEqual(de));
     340             : 
     341             :                 // attempt a clone now, should have the same content
     342           2 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
     343             : 
     344           1 :                 REQUIRE(clone->getComment().empty());
     345           1 :                 REQUIRE(clone->getCompressedSize() == 0);
     346           1 :                 REQUIRE(clone->getCrc() == 0);
     347           1 :                 REQUIRE(clone->getEntryOffset() == 0);
     348           1 :                 REQUIRE_FALSE(clone->getExtra().empty());
     349           1 :                 REQUIRE(clone->getHeaderSize() == 0);
     350           1 :                 REQUIRE(clone->getLevel() == g_expected_level);
     351           1 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
     352           1 :                 REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
     353           1 :                 REQUIRE(clone->getFileName() == "period.txt");
     354           1 :                 REQUIRE(clone->getSize() == 0);
     355           1 :                 REQUIRE(clone->getTime() == 0);  // invalid date
     356           1 :                 REQUIRE(clone->getUnixTime() == 0);
     357           1 :                 REQUIRE_FALSE(clone->hasCrc());
     358           1 :                 REQUIRE_FALSE(clone->isDirectory());
     359           1 :                 REQUIRE_FALSE(clone->isValid());
     360           1 :                 REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
     361           1 :                 REQUIRE(clone->getExtra() == b);
     362           1 :                 REQUIRE(clone->isEqual(de));
     363           1 :                 REQUIRE(de.isEqual(*clone));
     364             :             }
     365             :         }
     366             : 
     367          24 :         SECTION("setting an invalid level")
     368             :         {
     369        2002 :             for(zipios::FileEntry::CompressionLevel level(-1000); level <= 1000; ++level)
     370             :             {
     371        2001 :                 if(level >= -3 && level <= 100)
     372             :                 {
     373             :                     // this is considered valid
     374         104 :                     de.setLevel(level);
     375             : 
     376         104 :                     REQUIRE(de.getComment().empty());
     377         104 :                     REQUIRE(de.getCompressedSize() == 0);
     378         104 :                     REQUIRE(de.getCrc() == 0);
     379         104 :                     REQUIRE(de.getEntryOffset() == 0);
     380         104 :                     REQUIRE(de.getExtra().empty());
     381         104 :                     REQUIRE(de.getHeaderSize() == 0);
     382         104 :                     REQUIRE(de.getLevel() == level);
     383         104 :                     REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
     384         104 :                     REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
     385         104 :                     REQUIRE(de.getFileName() == "period.txt");
     386         104 :                     REQUIRE(de.getSize() == 0);
     387         104 :                     REQUIRE(de.getTime() == 0);  // invalid date
     388         104 :                     REQUIRE(de.getUnixTime() == 0);
     389         104 :                     REQUIRE_FALSE(de.hasCrc());
     390         104 :                     REQUIRE_FALSE(de.isDirectory());
     391         104 :                     REQUIRE_FALSE(de.isValid());
     392         104 :                     REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
     393             : 
     394         208 :                     zipios::DirectoryEntry other(zipios::FilePath("/file/really/should/not/exist/period.txt"), "");
     395         104 :                     REQUIRE_FALSE(de.isEqual(other));
     396         104 :                     REQUIRE_FALSE(other.isEqual(de));
     397             : 
     398             :                     // attempt a clone now, should have the same content
     399         208 :                     zipios::DirectoryEntry::pointer_t clone(de.clone());
     400             : 
     401         104 :                     REQUIRE(clone->getComment().empty());
     402         104 :                     REQUIRE(clone->getCompressedSize() == 0);
     403         104 :                     REQUIRE(clone->getCrc() == 0);
     404         104 :                     REQUIRE(clone->getEntryOffset() == 0);
     405         104 :                     REQUIRE(clone->getExtra().empty());
     406         104 :                     REQUIRE(clone->getHeaderSize() == 0);
     407         104 :                     REQUIRE(clone->getLevel() == level);
     408         104 :                     REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
     409         104 :                     REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
     410         104 :                     REQUIRE(clone->getFileName() == "period.txt");
     411         104 :                     REQUIRE(clone->getSize() == 0);
     412         104 :                     REQUIRE(clone->getTime() == 0);  // invalid date
     413         104 :                     REQUIRE(clone->getUnixTime() == 0);
     414         104 :                     REQUIRE_FALSE(clone->hasCrc());
     415         104 :                     REQUIRE_FALSE(clone->isDirectory());
     416         104 :                     REQUIRE_FALSE(clone->isValid());
     417         104 :                     REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
     418         104 :                     REQUIRE(clone->isEqual(de));
     419         208 :                     REQUIRE(de.isEqual(*clone));
     420             :                 }
     421             :                 else
     422             :                 {
     423        1897 :                     REQUIRE_THROWS_AS(de.setLevel(level), zipios::InvalidStateException);
     424             :                 }
     425             :             }
     426             :         }
     427             : 
     428          24 :         SECTION("setting an invalid method")
     429             :         {
     430             :             // WARNING: the StorageMethod is a uint8_t so testing
     431             :             //          with negative and such would wrap the number...
     432             :             //          (i.e. no need to do more than the following)
     433         257 :             for(int i(0); i < 256; ++i)
     434             :             {
     435         256 :                 switch(i)
     436             :                 {
     437             :                 case 0: // Stored
     438             :                 case 8: // Deflated
     439           2 :                     break;
     440             : 
     441             :                 default:
     442         254 :                     REQUIRE_THROWS_AS(de.setMethod(static_cast<zipios::StorageMethod>(i)), zipios::InvalidStateException);
     443         254 :                     break;
     444             : 
     445             :                 }
     446             :             }
     447             :         }
     448             : 
     449          24 :         WHEN("setting the method")
     450             :         {
     451             :             // set a method other than STORED, which is 0
     452             :             // in the newer version, though, the set only accepts
     453             :             // with STORED and DEFLATED
     454             :             //
     455           1 :             zipios::StorageMethod storage_method(zipios::StorageMethod::DEFLATED);
     456           1 :             de.setMethod(storage_method);
     457             : 
     458           2 :             THEN("we ignore it")
     459             :             {
     460           1 :                 REQUIRE(de.getComment().empty());
     461           1 :                 REQUIRE(de.getCompressedSize() == 0);
     462           1 :                 REQUIRE(de.getCrc() == 0);
     463           1 :                 REQUIRE(de.getEntryOffset() == 0);
     464           1 :                 REQUIRE(de.getExtra().empty());
     465           1 :                 REQUIRE(de.getHeaderSize() == 0);
     466           1 :                 REQUIRE(de.getLevel() == g_expected_level);
     467           1 :                 REQUIRE(de.getMethod() == storage_method);
     468           1 :                 REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
     469           1 :                 REQUIRE(de.getFileName() == "period.txt");
     470           1 :                 REQUIRE(de.getSize() == 0);
     471           1 :                 REQUIRE(de.getTime() == 0);  // invalid date
     472           1 :                 REQUIRE(de.getUnixTime() == 0);
     473           1 :                 REQUIRE_FALSE(de.hasCrc());
     474           1 :                 REQUIRE_FALSE(de.isDirectory());
     475           1 :                 REQUIRE_FALSE(de.isValid());
     476           1 :                 REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
     477             : 
     478           2 :                 zipios::DirectoryEntry other(zipios::FilePath("/file/really/should/not/exist/period.txt"), "");
     479           1 :                 REQUIRE_FALSE(de.isEqual(other));
     480           1 :                 REQUIRE_FALSE(other.isEqual(de));
     481             : 
     482             :                 // attempt a clone now, should have the same content
     483           2 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
     484             : 
     485           1 :                 REQUIRE(clone->getComment().empty());
     486           1 :                 REQUIRE(clone->getCompressedSize() == 0);
     487           1 :                 REQUIRE(clone->getCrc() == 0);
     488           1 :                 REQUIRE(clone->getEntryOffset() == 0);
     489           1 :                 REQUIRE(clone->getExtra().empty());
     490           1 :                 REQUIRE(clone->getHeaderSize() == 0);
     491           1 :                 REQUIRE(clone->getLevel() == g_expected_level);
     492           1 :                 REQUIRE(clone->getMethod() == storage_method);
     493           1 :                 REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
     494           1 :                 REQUIRE(clone->getFileName() == "period.txt");
     495           1 :                 REQUIRE(clone->getSize() == 0);
     496           1 :                 REQUIRE(clone->getTime() == 0);  // invalid date
     497           1 :                 REQUIRE(clone->getUnixTime() == 0);
     498           1 :                 REQUIRE_FALSE(clone->hasCrc());
     499           1 :                 REQUIRE_FALSE(clone->isDirectory());
     500           1 :                 REQUIRE_FALSE(clone->isValid());
     501           1 :                 REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
     502           1 :                 REQUIRE(clone->isEqual(de));
     503           1 :                 REQUIRE(de.isEqual(*clone));
     504             :             }
     505             :         }
     506             : 
     507          24 :         WHEN("setting the uncompressed size")
     508             :         {
     509             :             // zero would not really prove anything so skip such
     510             :             // (although it may be extremely rare...)
     511             :             size_t r;
     512           0 :             do
     513             :             {
     514           1 :                 r = zipios_test::rand_size_t();
     515             :             }
     516           1 :             while(r == 0);
     517           1 :             de.setSize(r);
     518             : 
     519           2 :             THEN("we take it as is")
     520             :             {
     521           1 :                 REQUIRE(de.getComment().empty());
     522           1 :                 REQUIRE(de.getCompressedSize() == r);
     523           1 :                 REQUIRE(de.getCrc() == 0);
     524           1 :                 REQUIRE(de.getEntryOffset() == 0);
     525           1 :                 REQUIRE(de.getExtra().empty());
     526           1 :                 REQUIRE(de.getHeaderSize() == 0);
     527           1 :                 REQUIRE(de.getLevel() == g_expected_level);
     528           1 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
     529           1 :                 REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
     530           1 :                 REQUIRE(de.getFileName() == "period.txt");
     531           1 :                 REQUIRE(de.getSize() == r);
     532           1 :                 REQUIRE(de.getTime() == 0);  // invalid date
     533           1 :                 REQUIRE(de.getUnixTime() == 0);
     534           1 :                 REQUIRE(!de.hasCrc());
     535           1 :                 REQUIRE(!de.isDirectory());
     536           1 :                 REQUIRE(!de.isValid());
     537           1 :                 REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (" + std::to_string(r) + " bytes)");
     538             : 
     539           2 :                 zipios::DirectoryEntry other(zipios::FilePath("really/.should"), "");
     540           1 :                 REQUIRE_FALSE(de.isEqual(other));
     541           1 :                 REQUIRE_FALSE(other.isEqual(de));
     542             : 
     543             :                 // attempt a clone now, should have the same content
     544           2 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
     545             : 
     546           1 :                 REQUIRE(clone->getComment().empty());
     547           1 :                 REQUIRE(clone->getCompressedSize() == r);
     548           1 :                 REQUIRE(clone->getCrc() == 0);
     549           1 :                 REQUIRE(clone->getEntryOffset() == 0);
     550           1 :                 REQUIRE(clone->getExtra().empty());
     551           1 :                 REQUIRE(clone->getHeaderSize() == 0);
     552           1 :                 REQUIRE(clone->getLevel() == g_expected_level);
     553           1 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
     554           1 :                 REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
     555           1 :                 REQUIRE(clone->getFileName() == "period.txt");
     556           1 :                 REQUIRE(clone->getSize() == r);
     557           1 :                 REQUIRE(clone->getTime() == 0);  // invalid date
     558           1 :                 REQUIRE(clone->getUnixTime() == 0);
     559           1 :                 REQUIRE(!clone->hasCrc());
     560           1 :                 REQUIRE(!clone->isDirectory());
     561           1 :                 REQUIRE(!clone->isValid());
     562           1 :                 REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (" + std::to_string(r) + " bytes)");
     563           1 :                 REQUIRE(clone->isEqual(de));
     564           1 :                 REQUIRE(de.isEqual(*clone));
     565             :             }
     566             :         }
     567             : 
     568          24 :         WHEN("setting the DOS time")
     569             :         {
     570             :             // DOS time numbers are not linear so we test until we get one
     571             :             // that works...
     572             :             //
     573           1 :             std::time_t t((static_cast<std::time_t>(zipios_test::rand_size_t())) % (4354848000LL - 315561600LL) + 315561600);
     574           1 :             zipios::DOSDateTime r;
     575           1 :             r.setUnixTimestamp(t);
     576           1 :             de.setTime(r.getDOSDateTime());
     577             : 
     578           2 :             THEN("we take it as is")
     579             :             {
     580           1 :                 REQUIRE(de.getComment().empty());
     581           1 :                 REQUIRE(de.getCompressedSize() == 0);
     582           1 :                 REQUIRE(de.getCrc() == 0);
     583           1 :                 REQUIRE(de.getEntryOffset() == 0);
     584           1 :                 REQUIRE(de.getExtra().empty());
     585           1 :                 REQUIRE(de.getHeaderSize() == 0);
     586           1 :                 REQUIRE(de.getLevel() == g_expected_level);
     587           1 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
     588           1 :                 REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
     589           1 :                 REQUIRE(de.getFileName() == "period.txt");
     590           1 :                 REQUIRE(de.getSize() == 0);
     591           1 :                 REQUIRE(de.getTime() == r.getDOSDateTime());
     592           1 :                 REQUIRE(de.getUnixTime() == r.getUnixTimestamp());
     593           1 :                 REQUIRE(!de.hasCrc());
     594           1 :                 REQUIRE(!de.isDirectory());
     595           1 :                 REQUIRE(!de.isValid());
     596           1 :                 REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
     597             : 
     598           2 :                 zipios::DirectoryEntry other(zipios::FilePath("other-name.txt"), "");
     599           1 :                 REQUIRE_FALSE(de.isEqual(other));
     600           1 :                 REQUIRE_FALSE(other.isEqual(de));
     601             : 
     602             :                 // attempt a clone now, should have the same content
     603           2 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
     604             : 
     605           1 :                 REQUIRE(clone->getComment().empty());
     606           1 :                 REQUIRE(clone->getCompressedSize() == 0);
     607           1 :                 REQUIRE(clone->getCrc() == 0);
     608           1 :                 REQUIRE(clone->getEntryOffset() == 0);
     609           1 :                 REQUIRE(clone->getExtra().empty());
     610           1 :                 REQUIRE(clone->getHeaderSize() == 0);
     611           1 :                 REQUIRE(clone->getLevel() == g_expected_level);
     612           1 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
     613           1 :                 REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
     614           1 :                 REQUIRE(clone->getFileName() == "period.txt");
     615           1 :                 REQUIRE(clone->getSize() == 0);
     616           1 :                 REQUIRE(clone->getTime() == r.getDOSDateTime());
     617           1 :                 REQUIRE(clone->getUnixTime() == r.getUnixTimestamp());
     618           1 :                 REQUIRE(!clone->hasCrc());
     619           1 :                 REQUIRE(!clone->isDirectory());
     620           1 :                 REQUIRE(!clone->isValid());
     621           1 :                 REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
     622           1 :                 REQUIRE(clone->isEqual(de));
     623           1 :                 REQUIRE(de.isEqual(*clone));
     624             :             }
     625             :         }
     626             : 
     627          24 :         WHEN("setting the Unix time")
     628             :         {
     629             :             // DOS time are limited to a smaller range and on every other
     630             :             // second so we get a valid DOS time and convert it to a Unix time
     631           1 :             std::time_t r((static_cast<std::time_t>(zipios_test::rand_size_t())) % (4354848000LL - 315561600LL) + 315561600);
     632           1 :             de.setUnixTime(r);
     633             : 
     634           1 :             zipios::DOSDateTime dt;
     635           1 :             dt.setUnixTimestamp(r);
     636             : 
     637           2 :             THEN("we take it as is")
     638             :             {
     639           1 :                 REQUIRE(de.getComment().empty());
     640           1 :                 REQUIRE(de.getCompressedSize() == 0);
     641           1 :                 REQUIRE(de.getCrc() == 0);
     642           1 :                 REQUIRE(de.getEntryOffset() == 0);
     643           1 :                 REQUIRE(de.getExtra().empty());
     644           1 :                 REQUIRE(de.getHeaderSize() == 0);
     645           1 :                 REQUIRE(de.getLevel() == g_expected_level);
     646           1 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
     647           1 :                 REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
     648           1 :                 REQUIRE(de.getFileName() == "period.txt");
     649           1 :                 REQUIRE(de.getSize() == 0);
     650           1 :                 REQUIRE(de.getTime() == dt.getDOSDateTime());
     651           1 :                 REQUIRE(de.getUnixTime() == r);
     652           1 :                 REQUIRE(!de.hasCrc());
     653           1 :                 REQUIRE(!de.isDirectory());
     654           1 :                 REQUIRE(!de.isValid());
     655           1 :                 REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
     656             : 
     657           2 :                 zipios::DirectoryEntry other(zipios::FilePath("path/incorrect"), "");
     658           1 :                 REQUIRE_FALSE(de.isEqual(other));
     659           1 :                 REQUIRE_FALSE(other.isEqual(de));
     660             : 
     661             :                 // attempt a clone now, should have the same content
     662           2 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
     663             : 
     664           1 :                 REQUIRE(clone->getComment().empty());
     665           1 :                 REQUIRE(clone->getCompressedSize() == 0);
     666           1 :                 REQUIRE(clone->getCrc() == 0);
     667           1 :                 REQUIRE(clone->getEntryOffset() == 0);
     668           1 :                 REQUIRE(clone->getExtra().empty());
     669           1 :                 REQUIRE(clone->getHeaderSize() == 0);
     670           1 :                 REQUIRE(clone->getLevel() == g_expected_level);
     671           1 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
     672           1 :                 REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
     673           1 :                 REQUIRE(clone->getFileName() == "period.txt");
     674           1 :                 REQUIRE(clone->getSize() == 0);
     675           1 :                 REQUIRE(clone->getTime() == dt.getDOSDateTime());
     676           1 :                 REQUIRE(clone->getUnixTime() == r);
     677           1 :                 REQUIRE(!clone->hasCrc());
     678           1 :                 REQUIRE(!clone->isDirectory());
     679           1 :                 REQUIRE(!clone->isValid());
     680           1 :                 REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
     681           1 :                 REQUIRE(clone->isEqual(de));
     682           1 :                 REQUIRE(de.isEqual(*clone));
     683             :             }
     684             :         }
     685             : 
     686          24 :         WHEN("setting the entry offset")
     687             :         {
     688             :             // DOS time are limited to a smaller range and on every other
     689             :             // second so we get a valid DOS time and convert it to a Unix time
     690           1 :             std::streampos r(zipios_test::rand_size_t());
     691           1 :             de.setEntryOffset(r);
     692             : 
     693           2 :             THEN("we retrieve the same value")
     694             :             {
     695           1 :                 REQUIRE(de.getComment().empty());
     696           1 :                 REQUIRE(de.getCompressedSize() == 0);
     697           1 :                 REQUIRE(de.getCrc() == 0);
     698           1 :                 REQUIRE(de.getEntryOffset() == r);
     699           1 :                 REQUIRE(de.getExtra().empty());
     700           1 :                 REQUIRE(de.getHeaderSize() == 0);
     701           1 :                 REQUIRE(de.getLevel() == g_expected_level);
     702           1 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
     703           1 :                 REQUIRE(de.getName() == "/this/file/really/should/not/exist/period.txt");
     704           1 :                 REQUIRE(de.getFileName() == "period.txt");
     705           1 :                 REQUIRE(de.getSize() == 0);
     706           1 :                 REQUIRE(de.getTime() == 0);
     707           1 :                 REQUIRE(de.getUnixTime() == 0);
     708           1 :                 REQUIRE_FALSE(de.hasCrc());
     709           1 :                 REQUIRE_FALSE(de.isDirectory());
     710           1 :                 REQUIRE_FALSE(de.isValid());
     711           1 :                 REQUIRE(de.toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
     712             : 
     713           2 :                 zipios::DirectoryEntry other(zipios::FilePath("path/incorrect"), "");
     714           1 :                 REQUIRE_FALSE(de.isEqual(other));
     715           1 :                 REQUIRE_FALSE(other.isEqual(de));
     716             : 
     717             :                 // attempt a clone now, should have the same content
     718           2 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
     719             : 
     720           1 :                 REQUIRE(clone->getComment().empty());
     721           1 :                 REQUIRE(clone->getCompressedSize() == 0);
     722           1 :                 REQUIRE(clone->getCrc() == 0);
     723           1 :                 REQUIRE(clone->getEntryOffset() == r);
     724           1 :                 REQUIRE(clone->getExtra().empty());
     725           1 :                 REQUIRE(clone->getHeaderSize() == 0);
     726           1 :                 REQUIRE(clone->getLevel() == g_expected_level);
     727           1 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
     728           1 :                 REQUIRE(clone->getName() == "/this/file/really/should/not/exist/period.txt");
     729           1 :                 REQUIRE(clone->getFileName() == "period.txt");
     730           1 :                 REQUIRE(clone->getSize() == 0);
     731           1 :                 REQUIRE(clone->getTime() == 0);
     732           1 :                 REQUIRE(clone->getUnixTime() == 0);
     733           1 :                 REQUIRE_FALSE(clone->hasCrc());
     734           1 :                 REQUIRE_FALSE(clone->isDirectory());
     735           1 :                 REQUIRE_FALSE(clone->isValid());
     736           1 :                 REQUIRE(clone->toString() == "/this/file/really/should/not/exist/period.txt (0 bytes)");
     737           1 :                 REQUIRE(clone->isEqual(de));
     738           1 :                 REQUIRE(de.isEqual(*clone));
     739             :             }
     740             :         }
     741             :     }
     742          12 : }
     743             : 
     744             : 
     745           2 : TEST_CASE("DirectoryEntry with one valid file", "[DirectoryEntry] [FileEntry]")
     746             : {
     747          11 :     for(int i(0); i < 10; ++i)
     748             :     {
     749             :         // create a random file
     750          10 :         int const file_size(rand() % 100 + 20);
     751             :         {
     752             :             // create a file
     753          20 :             std::ofstream f("filepath-test.txt", std::ios::out | std::ios::binary);
     754         806 :             for(int j(0); j < file_size; ++j)
     755             :             {
     756         796 :                 char const c(rand());
     757         796 :                 f << c;
     758             :             }
     759             :         }
     760             : 
     761             :         {
     762          20 :             zipios::DirectoryEntry de(zipios::FilePath("filepath-test.txt"), "");
     763             : 
     764             :             struct stat file_stats;
     765          10 :             REQUIRE(stat("filepath-test.txt", &file_stats) == 0);
     766          10 :             zipios::DOSDateTime dt;
     767          10 :             dt.setUnixTimestamp(file_stats.st_mtime);
     768             : 
     769             :             {
     770          10 :                 REQUIRE(de.getComment().empty());
     771          10 :                 REQUIRE(de.getCompressedSize() == file_size);
     772          10 :                 REQUIRE(de.getCrc() == 0);
     773          10 :                 REQUIRE(de.getEntryOffset() == 0);
     774          10 :                 REQUIRE(de.getExtra().empty());
     775          10 :                 REQUIRE(de.getHeaderSize() == 0);
     776          10 :                 REQUIRE(de.getLevel() == g_expected_level);
     777          10 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
     778          10 :                 REQUIRE(de.getName() == "filepath-test.txt");
     779          10 :                 REQUIRE(de.getFileName() == "filepath-test.txt");
     780          10 :                 REQUIRE(de.getSize() == file_size);
     781          10 :                 REQUIRE(de.getTime() == dt.getDOSDateTime());
     782          10 :                 REQUIRE(de.getUnixTime() == file_stats.st_mtime);
     783          10 :                 REQUIRE(!de.hasCrc());
     784          10 :                 REQUIRE(!de.isDirectory());
     785          10 :                 REQUIRE(de.isValid());
     786          10 :                 REQUIRE(de.toString() == "filepath-test.txt (" + std::to_string(file_size) + " bytes)");
     787             : 
     788             :                 // attempt a clone now, should have the same content
     789          20 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
     790             : 
     791          10 :                 REQUIRE(clone->getComment().empty());
     792          10 :                 REQUIRE(clone->getCompressedSize() == file_size);
     793          10 :                 REQUIRE(clone->getCrc() == 0);
     794          10 :                 REQUIRE(clone->getEntryOffset() == 0);
     795          10 :                 REQUIRE(clone->getExtra().empty());
     796          10 :                 REQUIRE(clone->getHeaderSize() == 0);
     797          10 :                 REQUIRE(clone->getLevel() == g_expected_level);
     798          10 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
     799          10 :                 REQUIRE(clone->getName() == "filepath-test.txt");
     800          10 :                 REQUIRE(clone->getFileName() == "filepath-test.txt");
     801          10 :                 REQUIRE(clone->getSize() == file_size);
     802          10 :                 REQUIRE(clone->getTime() == dt.getDOSDateTime());
     803          10 :                 REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
     804          10 :                 REQUIRE(!clone->hasCrc());
     805          10 :                 REQUIRE(!clone->isDirectory());
     806          10 :                 REQUIRE(clone->isValid());
     807          10 :                 REQUIRE(clone->toString() == "filepath-test.txt (" + std::to_string(file_size) + " bytes)");
     808             :             }
     809             : 
     810             :             {
     811          10 :                 de.setComment("new comment");
     812             : 
     813          10 :                 REQUIRE(de.getComment() == "new comment");
     814          10 :                 REQUIRE(de.getCompressedSize() == file_size);
     815          10 :                 REQUIRE(de.getCrc() == 0);
     816          10 :                 REQUIRE(de.getEntryOffset() == 0);
     817          10 :                 REQUIRE(de.getExtra().empty());
     818          10 :                 REQUIRE(de.getHeaderSize() == 0);
     819          10 :                 REQUIRE(de.getLevel() == g_expected_level);
     820          10 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
     821          10 :                 REQUIRE(de.getName() == "filepath-test.txt");
     822          10 :                 REQUIRE(de.getFileName() == "filepath-test.txt");
     823          10 :                 REQUIRE(de.getSize() == file_size);
     824          10 :                 REQUIRE(de.getTime() == dt.getDOSDateTime());
     825          10 :                 REQUIRE(de.getUnixTime() == file_stats.st_mtime);
     826          10 :                 REQUIRE(!de.hasCrc());
     827          10 :                 REQUIRE(!de.isDirectory());
     828          10 :                 REQUIRE(de.isValid());
     829          10 :                 REQUIRE(de.toString() == "filepath-test.txt (" + std::to_string(file_stats.st_size) + " bytes)");
     830             : 
     831             :                 // attempt a clone now, should have the same content
     832          20 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
     833             : 
     834          10 :                 REQUIRE(clone->getComment() == "new comment");
     835          10 :                 REQUIRE(clone->getCompressedSize() == file_size);
     836          10 :                 REQUIRE(clone->getCrc() == 0);
     837          10 :                 REQUIRE(clone->getEntryOffset() == 0);
     838          10 :                 REQUIRE(clone->getExtra().empty());
     839          10 :                 REQUIRE(clone->getHeaderSize() == 0);
     840          10 :                 REQUIRE(clone->getLevel() == g_expected_level);
     841          10 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
     842          10 :                 REQUIRE(clone->getName() == "filepath-test.txt");
     843          10 :                 REQUIRE(clone->getFileName() == "filepath-test.txt");
     844          10 :                 REQUIRE(clone->getSize() == file_size);
     845          10 :                 REQUIRE(clone->getTime() == dt.getDOSDateTime());
     846          10 :                 REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
     847          10 :                 REQUIRE(!clone->hasCrc());
     848          10 :                 REQUIRE(!clone->isDirectory());
     849          10 :                 REQUIRE(clone->isValid());
     850          10 :                 REQUIRE(clone->toString() == "filepath-test.txt (" + std::to_string(file_stats.st_size) + " bytes)");
     851             : 
     852          10 :                 de.setComment("");
     853             :             }
     854             : 
     855             :             {
     856             :                 // zero would not really prove anything so skip such
     857             :                 // (although it may be extremely rare...)
     858             :                 size_t r;
     859           0 :                 do
     860             :                 {
     861          10 :                     r = zipios_test::rand_size_t();
     862             :                 }
     863          10 :                 while(r == 0);
     864          10 :                 de.setCompressedSize(r);
     865             : 
     866          10 :                 REQUIRE(de.getComment().empty());
     867          10 :                 REQUIRE(de.getCompressedSize() == file_size);
     868          10 :                 REQUIRE(de.getCrc() == 0);
     869          10 :                 REQUIRE(de.getEntryOffset() == 0);
     870          10 :                 REQUIRE(de.getExtra().empty());
     871          10 :                 REQUIRE(de.getHeaderSize() == 0);
     872          10 :                 REQUIRE(de.getLevel() == g_expected_level);
     873          10 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
     874          10 :                 REQUIRE(de.getName() == "filepath-test.txt");
     875          10 :                 REQUIRE(de.getFileName() == "filepath-test.txt");
     876          10 :                 REQUIRE(de.getSize() == file_size);
     877          10 :                 REQUIRE(de.getTime() == dt.getDOSDateTime());
     878          10 :                 REQUIRE(de.getUnixTime() == file_stats.st_mtime);
     879          10 :                 REQUIRE(!de.hasCrc());
     880          10 :                 REQUIRE(!de.isDirectory());
     881          10 :                 REQUIRE(de.isValid());
     882          10 :                 REQUIRE(de.toString() == "filepath-test.txt (" + std::to_string(file_stats.st_size) + " bytes)");
     883             : 
     884             :                 // attempt a clone now, should have the same content
     885          20 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
     886             : 
     887          10 :                 REQUIRE(clone->getComment().empty());
     888          10 :                 REQUIRE(clone->getCompressedSize() == file_size);
     889          10 :                 REQUIRE(clone->getCrc() == 0);
     890          10 :                 REQUIRE(clone->getEntryOffset() == 0);
     891          10 :                 REQUIRE(clone->getExtra().empty());
     892          10 :                 REQUIRE(clone->getHeaderSize() == 0);
     893          10 :                 REQUIRE(clone->getLevel() == g_expected_level);
     894          10 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
     895          10 :                 REQUIRE(clone->getName() == "filepath-test.txt");
     896          10 :                 REQUIRE(clone->getFileName() == "filepath-test.txt");
     897          10 :                 REQUIRE(clone->getSize() == file_size);
     898          10 :                 REQUIRE(clone->getTime() == dt.getDOSDateTime());
     899          10 :                 REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
     900          10 :                 REQUIRE(!clone->hasCrc());
     901          10 :                 REQUIRE(!clone->isDirectory());
     902          10 :                 REQUIRE(clone->isValid());
     903          10 :                 REQUIRE(clone->toString() == "filepath-test.txt (" + std::to_string(file_stats.st_size) + " bytes)");
     904             :             }
     905             : 
     906             :             {
     907             :                 // zero would not really prove anything so skip such
     908             :                 uint32_t r;
     909           0 :                 do
     910             :                 {
     911          10 :                     r = rand();
     912             :                 }
     913          10 :                 while(r == 0);
     914          10 :                 de.setCrc(rand());
     915             : 
     916          10 :                 REQUIRE(de.getComment().empty());
     917          10 :                 REQUIRE(de.getCompressedSize() == file_size);
     918          10 :                 REQUIRE(de.getCrc() == 0);
     919          10 :                 REQUIRE(de.getEntryOffset() == 0);
     920          10 :                 REQUIRE(de.getExtra().empty());
     921          10 :                 REQUIRE(de.getHeaderSize() == 0);
     922          10 :                 REQUIRE(de.getLevel() == g_expected_level);
     923          10 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
     924          10 :                 REQUIRE(de.getName() == "filepath-test.txt");
     925          10 :                 REQUIRE(de.getFileName() == "filepath-test.txt");
     926          10 :                 REQUIRE(de.getSize() == file_size);
     927          10 :                 REQUIRE(de.getTime() == dt.getDOSDateTime());
     928          10 :                 REQUIRE(de.getUnixTime() == file_stats.st_mtime);
     929          10 :                 REQUIRE(!de.hasCrc());
     930          10 :                 REQUIRE(!de.isDirectory());
     931          10 :                 REQUIRE(de.isValid());
     932          10 :                 REQUIRE(de.toString() == "filepath-test.txt (" + std::to_string(file_stats.st_size) + " bytes)");
     933             : 
     934             :                 // attempt a clone now, should have the same content
     935          20 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
     936             : 
     937          10 :                 REQUIRE(clone->getComment().empty());
     938          10 :                 REQUIRE(clone->getCompressedSize() == file_size);
     939          10 :                 REQUIRE(clone->getCrc() == 0);
     940          10 :                 REQUIRE(clone->getEntryOffset() == 0);
     941          10 :                 REQUIRE(clone->getExtra().empty());
     942          10 :                 REQUIRE(clone->getHeaderSize() == 0);
     943          10 :                 REQUIRE(clone->getLevel() == g_expected_level);
     944          10 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
     945          10 :                 REQUIRE(clone->getName() == "filepath-test.txt");
     946          10 :                 REQUIRE(clone->getFileName() == "filepath-test.txt");
     947          10 :                 REQUIRE(clone->getSize() == file_size);
     948          10 :                 REQUIRE(clone->getTime() == dt.getDOSDateTime());
     949          10 :                 REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
     950          10 :                 REQUIRE(!clone->hasCrc());
     951          10 :                 REQUIRE(!clone->isDirectory());
     952          10 :                 REQUIRE(clone->isValid());
     953          10 :                 REQUIRE(clone->toString() == "filepath-test.txt (" + std::to_string(file_stats.st_size) + " bytes)");
     954             :             }
     955             : 
     956             :             {
     957             :                 // zero would not really prove anything so skip such
     958          20 :                 zipios::FileEntry::buffer_t b;
     959          10 :                 uint32_t size(rand() % 100 + 20);
     960         545 :                 for(uint32_t j(0); j < size; ++j)
     961             :                 {
     962         535 :                     b.push_back(rand());
     963             :                 }
     964          10 :                 de.setExtra(b);
     965             : 
     966          10 :                 REQUIRE(de.getComment().empty());
     967          10 :                 REQUIRE(de.getCompressedSize() == file_size);
     968          10 :                 REQUIRE(de.getCrc() == 0);
     969          10 :                 REQUIRE(de.getEntryOffset() == 0);
     970          10 :                 REQUIRE_FALSE(de.getExtra().empty());
     971          10 :                 REQUIRE(de.getHeaderSize() == 0);
     972          10 :                 REQUIRE(de.getLevel() == g_expected_level);
     973          10 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
     974          10 :                 REQUIRE(de.getName() == "filepath-test.txt");
     975          10 :                 REQUIRE(de.getFileName() == "filepath-test.txt");
     976          10 :                 REQUIRE(de.getSize() == file_size);
     977          10 :                 REQUIRE(de.getTime() == dt.getDOSDateTime());
     978          10 :                 REQUIRE(de.getUnixTime() == file_stats.st_mtime);
     979          10 :                 REQUIRE_FALSE(de.hasCrc());
     980          10 :                 REQUIRE_FALSE(de.isDirectory());
     981          10 :                 REQUIRE(de.isValid());
     982          10 :                 REQUIRE(de.toString() == "filepath-test.txt (" + std::to_string(file_stats.st_size) + " bytes)");
     983          10 :                 REQUIRE(de.getExtra() == b);
     984             : 
     985             :                 // attempt a clone now, should have the same content
     986          20 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
     987             : 
     988          10 :                 REQUIRE(clone->getComment().empty());
     989          10 :                 REQUIRE(clone->getCompressedSize() == file_size);
     990          10 :                 REQUIRE(clone->getCrc() == 0);
     991          10 :                 REQUIRE(clone->getEntryOffset() == 0);
     992          10 :                 REQUIRE_FALSE(clone->getExtra().empty());
     993          10 :                 REQUIRE(clone->getHeaderSize() == 0);
     994          10 :                 REQUIRE(clone->getLevel() == g_expected_level);
     995          10 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
     996          10 :                 REQUIRE(clone->getName() == "filepath-test.txt");
     997          10 :                 REQUIRE(clone->getFileName() == "filepath-test.txt");
     998          10 :                 REQUIRE(clone->getSize() == file_size);
     999          10 :                 REQUIRE(clone->getTime() == dt.getDOSDateTime());
    1000          10 :                 REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
    1001          10 :                 REQUIRE_FALSE(clone->hasCrc());
    1002          10 :                 REQUIRE_FALSE(clone->isDirectory());
    1003          10 :                 REQUIRE(clone->isValid());
    1004          10 :                 REQUIRE(clone->toString() == "filepath-test.txt (" + std::to_string(file_stats.st_size) + " bytes)");
    1005          10 :                 REQUIRE(clone->getExtra() == b);
    1006             : 
    1007             :                 // reset the buffer
    1008          10 :                 de.setExtra(zipios::FileEntry::buffer_t());
    1009             :             }
    1010             : 
    1011          20 :             SECTION("setting all levels, including many invalid ones")
    1012             :             {
    1013        2002 :                 for(zipios::FileEntry::CompressionLevel level(-1000); level <= 1000; ++level)
    1014             :                 {
    1015        2001 :                     if(level >= -3 && level <= 100)
    1016             :                     {
    1017             :                         // this is considered valid for a standard file
    1018         104 :                         de.setLevel(level);
    1019             : 
    1020         104 :                         REQUIRE(de.getComment().empty());
    1021         104 :                         REQUIRE(de.getCompressedSize() == file_size);
    1022         104 :                         REQUIRE(de.getCrc() == 0);
    1023         104 :                         REQUIRE(de.getEntryOffset() == 0);
    1024         104 :                         REQUIRE(de.getExtra().empty());
    1025         104 :                         REQUIRE(de.getHeaderSize() == 0);
    1026         104 :                         REQUIRE(de.getLevel() == level);
    1027         104 :                         REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
    1028         104 :                         REQUIRE(de.getName() == "filepath-test.txt");
    1029         104 :                         REQUIRE(de.getFileName() == "filepath-test.txt");
    1030         104 :                         REQUIRE(de.getSize() == file_size);
    1031         104 :                         REQUIRE(de.getTime() == dt.getDOSDateTime());
    1032         104 :                         REQUIRE(de.getUnixTime() == file_stats.st_mtime);
    1033         104 :                         REQUIRE_FALSE(de.hasCrc());
    1034         104 :                         REQUIRE_FALSE(de.isDirectory());
    1035         104 :                         REQUIRE(de.isValid());
    1036         104 :                         REQUIRE(de.toString() == "filepath-test.txt (" + std::to_string(file_size) + " bytes)");
    1037             :                     }
    1038             :                     else
    1039             :                     {
    1040        1897 :                         REQUIRE_THROWS_AS(de.setLevel(level), zipios::InvalidStateException);
    1041             :                     }
    1042             :                 }
    1043             : 
    1044             :                 // restore before continuing test
    1045           1 :                 de.setLevel(g_expected_level);
    1046             :             }
    1047             : 
    1048             :             {
    1049             :                 // set a method other than STORED, which is 1, so just us % 8 instead of % 9 and do a +1
    1050          10 :                 de.setMethod(zipios::StorageMethod::DEFLATED);
    1051             : 
    1052          10 :                 REQUIRE(de.getComment().empty());
    1053          10 :                 REQUIRE(de.getCompressedSize() == file_size);
    1054          10 :                 REQUIRE(de.getCrc() == 0);
    1055          10 :                 REQUIRE(de.getEntryOffset() == 0);
    1056          10 :                 REQUIRE(de.getExtra().empty());
    1057          10 :                 REQUIRE(de.getHeaderSize() == 0);
    1058          10 :                 REQUIRE(de.getLevel() == g_expected_level);
    1059          10 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::DEFLATED);
    1060          10 :                 REQUIRE(de.getName() == "filepath-test.txt");
    1061          10 :                 REQUIRE(de.getFileName() == "filepath-test.txt");
    1062          10 :                 REQUIRE(de.getSize() == file_size);
    1063          10 :                 REQUIRE(de.getTime() == dt.getDOSDateTime());
    1064          10 :                 REQUIRE(de.getUnixTime() == file_stats.st_mtime);
    1065          10 :                 REQUIRE_FALSE(de.hasCrc());
    1066          10 :                 REQUIRE_FALSE(de.isDirectory());
    1067          10 :                 REQUIRE(de.isValid());
    1068          10 :                 REQUIRE(de.toString() == "filepath-test.txt (" + std::to_string(file_size) + " bytes)");
    1069             : 
    1070             :                 // attempt a clone now, should have the same content
    1071          20 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
    1072             : 
    1073          10 :                 REQUIRE(clone->getComment().empty());
    1074          10 :                 REQUIRE(clone->getCompressedSize() == file_size);
    1075          10 :                 REQUIRE(clone->getCrc() == 0);
    1076          10 :                 REQUIRE(clone->getEntryOffset() == 0);
    1077          10 :                 REQUIRE(clone->getExtra().empty());
    1078          10 :                 REQUIRE(clone->getHeaderSize() == 0);
    1079          10 :                 REQUIRE(clone->getLevel() == g_expected_level);
    1080          10 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::DEFLATED);
    1081          10 :                 REQUIRE(clone->getName() == "filepath-test.txt");
    1082          10 :                 REQUIRE(clone->getFileName() == "filepath-test.txt");
    1083          10 :                 REQUIRE(clone->getSize() == file_size);
    1084          10 :                 REQUIRE(clone->getTime() == dt.getDOSDateTime());
    1085          10 :                 REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
    1086          10 :                 REQUIRE_FALSE(clone->hasCrc());
    1087          10 :                 REQUIRE_FALSE(clone->isDirectory());
    1088          10 :                 REQUIRE(clone->isValid());
    1089          10 :                 REQUIRE(clone->toString() == "filepath-test.txt (" + std::to_string(file_size) + " bytes)");
    1090             :             }
    1091             : 
    1092             :             {
    1093             :                 // zero would not really prove anything so skip such
    1094             :                 // (although it may be extremely rare...)
    1095             :                 size_t r;
    1096             :                 {
    1097          10 :                     r = zipios_test::rand_size_t();
    1098             :                 }
    1099          10 :                 while(r == 0);
    1100          10 :                 de.setSize(r);
    1101             : 
    1102          10 :                 REQUIRE(de.getComment().empty());
    1103          10 :                 REQUIRE(de.getCompressedSize() == r);
    1104          10 :                 REQUIRE(de.getCrc() == 0);
    1105          10 :                 REQUIRE(de.getEntryOffset() == 0);
    1106          10 :                 REQUIRE(de.getExtra().empty());
    1107          10 :                 REQUIRE(de.getHeaderSize() == 0);
    1108          10 :                 REQUIRE(de.getLevel() == g_expected_level);
    1109          10 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::DEFLATED);
    1110          10 :                 REQUIRE(de.getName() == "filepath-test.txt");
    1111          10 :                 REQUIRE(de.getFileName() == "filepath-test.txt");
    1112          10 :                 REQUIRE(de.getSize() == r);
    1113          10 :                 REQUIRE(de.getTime() == dt.getDOSDateTime());
    1114          10 :                 REQUIRE(de.getUnixTime() == file_stats.st_mtime);
    1115          10 :                 REQUIRE(!de.hasCrc());
    1116          10 :                 REQUIRE(!de.isDirectory());
    1117          10 :                 REQUIRE(de.isValid());
    1118          10 :                 REQUIRE(de.toString() == "filepath-test.txt (" + std::to_string(r) + " bytes)");
    1119             : 
    1120             :                 // attempt a clone now, should have the same content
    1121          20 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
    1122             : 
    1123          10 :                 REQUIRE(clone->getComment().empty());
    1124          10 :                 REQUIRE(clone->getCompressedSize() == r);
    1125          10 :                 REQUIRE(clone->getCrc() == 0);
    1126          10 :                 REQUIRE(clone->getEntryOffset() == 0);
    1127          10 :                 REQUIRE(clone->getExtra().empty());
    1128          10 :                 REQUIRE(clone->getHeaderSize() == 0);
    1129          10 :                 REQUIRE(clone->getLevel() == g_expected_level);
    1130          10 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::DEFLATED);
    1131          10 :                 REQUIRE(clone->getName() == "filepath-test.txt");
    1132          10 :                 REQUIRE(clone->getFileName() == "filepath-test.txt");
    1133          10 :                 REQUIRE(clone->getSize() == r);
    1134          10 :                 REQUIRE(clone->getTime() == dt.getDOSDateTime());
    1135          10 :                 REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
    1136          10 :                 REQUIRE(!clone->hasCrc());
    1137          10 :                 REQUIRE(!clone->isDirectory());
    1138          10 :                 REQUIRE(clone->isValid());
    1139          10 :                 REQUIRE(clone->toString() == "filepath-test.txt (" + std::to_string(r) + " bytes)");
    1140             : 
    1141          10 :                 de.setSize(file_size);
    1142             :             }
    1143             : 
    1144             :             {
    1145             :                 // DOS time numbers are not linear so we use a Unix date and
    1146             :                 // convert to DOS time (since we know our convertor works)
    1147             :                 //
    1148             :                 // Jan 1, 1980 at 00:00:00  is  315561600   (min)
    1149             :                 // Dec 31, 2107 at 23:59:59  is 4354847999  (max)
    1150          10 :                 std::time_t t(static_cast<std::time_t>(zipios_test::rand_size_t()) % (4354848000LL - 315561600LL) + 315561600);
    1151          10 :                 zipios::DOSDateTime r;
    1152          10 :                 r.setUnixTimestamp(t);
    1153          10 :                 de.setTime(r.getDOSDateTime());
    1154             : 
    1155          10 :                 REQUIRE(de.getComment().empty());
    1156          10 :                 REQUIRE(de.getCompressedSize() == file_size);
    1157          10 :                 REQUIRE(de.getCrc() == 0);
    1158          10 :                 REQUIRE(de.getEntryOffset() == 0);
    1159          10 :                 REQUIRE(de.getExtra().empty());
    1160          10 :                 REQUIRE(de.getHeaderSize() == 0);
    1161          10 :                 REQUIRE(de.getLevel() == g_expected_level);
    1162          10 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::DEFLATED);
    1163          10 :                 REQUIRE(de.getName() == "filepath-test.txt");
    1164          10 :                 REQUIRE(de.getFileName() == "filepath-test.txt");
    1165          10 :                 REQUIRE(de.getSize() == file_size);
    1166          10 :                 REQUIRE(de.getTime() == r.getDOSDateTime());
    1167          10 :                 REQUIRE(de.getUnixTime() == r.getUnixTimestamp()); // WARNING: this is not always equal to t because setTime() may use the next even second
    1168          10 :                 REQUIRE(!de.hasCrc());
    1169          10 :                 REQUIRE(!de.isDirectory());
    1170          10 :                 REQUIRE(de.isValid());
    1171          10 :                 REQUIRE(de.toString() == "filepath-test.txt (" + std::to_string(file_size) + " bytes)");
    1172             : 
    1173             :                 // attempt a clone now, should have the same content
    1174          20 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
    1175             : 
    1176          10 :                 REQUIRE(clone->getComment().empty());
    1177          10 :                 REQUIRE(clone->getCompressedSize() == file_size);
    1178          10 :                 REQUIRE(clone->getCrc() == 0);
    1179          10 :                 REQUIRE(clone->getEntryOffset() == 0);
    1180          10 :                 REQUIRE(clone->getExtra().empty());
    1181          10 :                 REQUIRE(clone->getHeaderSize() == 0);
    1182          10 :                 REQUIRE(clone->getLevel() == g_expected_level);
    1183          10 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::DEFLATED);
    1184          10 :                 REQUIRE(clone->getName() == "filepath-test.txt");
    1185          10 :                 REQUIRE(clone->getFileName() == "filepath-test.txt");
    1186          10 :                 REQUIRE(clone->getSize() == file_size);
    1187          10 :                 REQUIRE(clone->getTime() == r.getDOSDateTime());
    1188          10 :                 REQUIRE(clone->getUnixTime() == r.getUnixTimestamp());
    1189          10 :                 REQUIRE(!clone->hasCrc());
    1190          10 :                 REQUIRE(!clone->isDirectory());
    1191          10 :                 REQUIRE(clone->isValid());
    1192          10 :                 REQUIRE(clone->toString() == "filepath-test.txt (" + std::to_string(file_size) + " bytes)");
    1193             :             }
    1194             : 
    1195             :             {
    1196             :                 // DOS time are limited to a smaller range and on every other
    1197             :                 // second so we get a valid DOS time and convert it to a Unix time
    1198          10 :                 std::time_t r(static_cast<std::time_t>(zipios_test::rand_size_t()) % (4354848000LL - 315561600LL) + 315561600);
    1199          10 :                 zipios::DOSDateTime dr;
    1200          10 :                 dr.setUnixTimestamp(r);
    1201          10 :                 de.setUnixTime(r);
    1202             : 
    1203          10 :                 REQUIRE(de.getComment().empty());
    1204          10 :                 REQUIRE(de.getCompressedSize() == file_size);
    1205          10 :                 REQUIRE(de.getCrc() == 0);
    1206          10 :                 REQUIRE(de.getEntryOffset() == 0);
    1207          10 :                 REQUIRE(de.getExtra().empty());
    1208          10 :                 REQUIRE(de.getHeaderSize() == 0);
    1209          10 :                 REQUIRE(de.getLevel() == g_expected_level);
    1210          10 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::DEFLATED);
    1211          10 :                 REQUIRE(de.getName() == "filepath-test.txt");
    1212          10 :                 REQUIRE(de.getFileName() == "filepath-test.txt");
    1213          10 :                 REQUIRE(de.getSize() == file_size);
    1214          10 :                 REQUIRE(de.getTime() == dr.getDOSDateTime());
    1215          10 :                 REQUIRE(de.getUnixTime() == r);
    1216          10 :                 REQUIRE(!de.hasCrc());
    1217          10 :                 REQUIRE(!de.isDirectory());
    1218          10 :                 REQUIRE(de.isValid());
    1219          10 :                 REQUIRE(de.toString() == "filepath-test.txt (" + std::to_string(file_size) + " bytes)");
    1220             : 
    1221             :                 // attempt a clone now, should have the same content
    1222          20 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
    1223             : 
    1224          10 :                 REQUIRE(clone->getComment().empty());
    1225          10 :                 REQUIRE(clone->getCompressedSize() == file_size);
    1226          10 :                 REQUIRE(clone->getCrc() == 0);
    1227          10 :                 REQUIRE(clone->getEntryOffset() == 0);
    1228          10 :                 REQUIRE(clone->getExtra().empty());
    1229          10 :                 REQUIRE(clone->getHeaderSize() == 0);
    1230          10 :                 REQUIRE(clone->getLevel() == g_expected_level);
    1231          10 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::DEFLATED);
    1232          10 :                 REQUIRE(clone->getName() == "filepath-test.txt");
    1233          10 :                 REQUIRE(clone->getFileName() == "filepath-test.txt");
    1234          10 :                 REQUIRE(clone->getSize() == file_size);
    1235          10 :                 REQUIRE(clone->getTime() == dr.getDOSDateTime());
    1236          10 :                 REQUIRE(clone->getUnixTime() == r);
    1237          10 :                 REQUIRE(!clone->hasCrc());
    1238          10 :                 REQUIRE(!clone->isDirectory());
    1239          10 :                 REQUIRE(clone->isValid());
    1240          10 :                 REQUIRE(clone->toString() == "filepath-test.txt (" + std::to_string(file_size) + " bytes)");
    1241             :             }
    1242             :         }
    1243             : 
    1244          10 :         unlink("filepath-test.txt");
    1245             :     }
    1246           1 : }
    1247             : 
    1248             : 
    1249          11 : SCENARIO("DirectoryEntry for a valid directory", "[DirectoryEntry] [FileEntry]")
    1250             : {
    1251          20 :     GIVEN("test an existing directory and no comment")
    1252             :     {
    1253             :         // make sure the directory is gone before re-creating it
    1254          10 :         REQUIRE(system("rm -rf filepath-test") == 0);
    1255             : 
    1256             :         // create a directory
    1257          10 :         REQUIRE(mkdir("filepath-test", 0777) == 0);
    1258             : 
    1259          20 :         zipios::DirectoryEntry de(zipios::FilePath("filepath-test"), "");
    1260             : 
    1261             :         struct stat file_stats;
    1262          10 :         REQUIRE(stat("filepath-test", &file_stats) == 0);
    1263             : 
    1264          10 :         zipios::DOSDateTime dt;
    1265          10 :         dt.setUnixTimestamp(file_stats.st_mtime);
    1266             : 
    1267             :         // first, check that the object is setup as expected
    1268          20 :         SECTION("verify that the object looks as expected")
    1269             :         {
    1270           1 :             REQUIRE(de.getComment().empty());
    1271           1 :             REQUIRE(de.getCompressedSize() == 0);
    1272           1 :             REQUIRE(de.getCrc() == 0);
    1273           1 :             REQUIRE(de.getEntryOffset() == 0);
    1274           1 :             REQUIRE(de.getExtra().empty());
    1275           1 :             REQUIRE(de.getHeaderSize() == 0);
    1276           1 :             REQUIRE(de.getLevel() == g_directory_level);
    1277           1 :             REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
    1278           1 :             REQUIRE(de.getName() == "filepath-test");
    1279           1 :             REQUIRE(de.getFileName() == "filepath-test");
    1280           1 :             REQUIRE(de.getSize() == 0);
    1281           1 :             REQUIRE(de.getTime() == dt.getDOSDateTime());
    1282           1 :             REQUIRE(de.getUnixTime() == file_stats.st_mtime);
    1283           1 :             REQUIRE(!de.hasCrc());
    1284           1 :             REQUIRE(de.isDirectory());
    1285           1 :             REQUIRE(de.isValid());
    1286           1 :             REQUIRE(de.toString() == "filepath-test (directory)");
    1287             : 
    1288             :             // attempt a clone now, should have the same content
    1289           2 :             zipios::DirectoryEntry::pointer_t clone(de.clone());
    1290             : 
    1291           1 :             REQUIRE(clone->getComment().empty());
    1292           1 :             REQUIRE(clone->getCompressedSize() == 0);
    1293           1 :             REQUIRE(clone->getCrc() == 0);
    1294           1 :             REQUIRE(clone->getEntryOffset() == 0);
    1295           1 :             REQUIRE(clone->getExtra().empty());
    1296           1 :             REQUIRE(clone->getHeaderSize() == 0);
    1297           1 :             REQUIRE(clone->getLevel() == g_directory_level);
    1298           1 :             REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
    1299           1 :             REQUIRE(clone->getName() == "filepath-test");
    1300           1 :             REQUIRE(clone->getFileName() == "filepath-test");
    1301           1 :             REQUIRE(clone->getSize() == 0);
    1302           1 :             REQUIRE(clone->getTime() == dt.getDOSDateTime());
    1303           1 :             REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
    1304           1 :             REQUIRE_FALSE(clone->hasCrc());
    1305           1 :             REQUIRE(clone->isDirectory());
    1306           1 :             REQUIRE(clone->isValid());
    1307           1 :             REQUIRE(clone->toString() == "filepath-test (directory)");
    1308             :         }
    1309             : 
    1310          20 :         WHEN("setting the comment")
    1311             :         {
    1312           1 :             de.setComment("new comment");
    1313             : 
    1314           2 :             THEN("we can read it and nothing else changed")
    1315             :             {
    1316           1 :                 REQUIRE(de.getComment() == "new comment");
    1317           1 :                 REQUIRE(de.getCompressedSize() == 0);
    1318           1 :                 REQUIRE(de.getCrc() == 0);
    1319           1 :                 REQUIRE(de.getEntryOffset() == 0);
    1320           1 :                 REQUIRE(de.getExtra().empty());
    1321           1 :                 REQUIRE(de.getHeaderSize() == 0);
    1322           1 :                 REQUIRE(de.getLevel() == g_directory_level);
    1323           1 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
    1324           1 :                 REQUIRE(de.getName() == "filepath-test");
    1325           1 :                 REQUIRE(de.getFileName() == "filepath-test");
    1326           1 :                 REQUIRE(de.getSize() == 0);
    1327           1 :                 REQUIRE(de.getTime() == dt.getDOSDateTime());
    1328           1 :                 REQUIRE(de.getUnixTime() == file_stats.st_mtime);
    1329           1 :                 REQUIRE_FALSE(de.hasCrc());
    1330           1 :                 REQUIRE(de.isDirectory());
    1331           1 :                 REQUIRE(de.isValid());
    1332           1 :                 REQUIRE(de.toString() == "filepath-test (directory)");
    1333             : 
    1334             :                 // attempt a clone now, should have the same content
    1335           2 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
    1336             : 
    1337           1 :                 REQUIRE(clone->getComment() == "new comment");
    1338           1 :                 REQUIRE(clone->getCompressedSize() == 0);
    1339           1 :                 REQUIRE(clone->getCrc() == 0);
    1340           1 :                 REQUIRE(clone->getEntryOffset() == 0);
    1341           1 :                 REQUIRE(clone->getExtra().empty());
    1342           1 :                 REQUIRE(clone->getHeaderSize() == 0);
    1343           1 :                 REQUIRE(clone->getLevel() == g_directory_level);
    1344           1 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
    1345           1 :                 REQUIRE(clone->getName() == "filepath-test");
    1346           1 :                 REQUIRE(clone->getFileName() == "filepath-test");
    1347           1 :                 REQUIRE(clone->getSize() == 0);
    1348           1 :                 REQUIRE(clone->getTime() == dt.getDOSDateTime());
    1349           1 :                 REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
    1350           1 :                 REQUIRE_FALSE(clone->hasCrc());
    1351           1 :                 REQUIRE(clone->isDirectory());
    1352           1 :                 REQUIRE(clone->isValid());
    1353           1 :                 REQUIRE(clone->toString() == "filepath-test (directory)");
    1354             :             }
    1355             :         }
    1356             : 
    1357          20 :         WHEN("setting the compressed size")
    1358             :         {
    1359             :             // zero would not really prove anything so skip such
    1360             :             // (although it may be extremely rare...)
    1361             :             size_t r;
    1362           0 :             do
    1363             :             {
    1364           1 :                 r = zipios_test::rand_size_t();
    1365             :             }
    1366           1 :             while(r == 0);
    1367           1 :             de.setCompressedSize(r);
    1368             : 
    1369           2 :             THEN("we ignore it")
    1370             :             {
    1371           1 :                 REQUIRE(de.getComment().empty());
    1372           1 :                 REQUIRE(de.getCompressedSize() == 0);
    1373           1 :                 REQUIRE(de.getCrc() == 0);
    1374           1 :                 REQUIRE(de.getEntryOffset() == 0);
    1375           1 :                 REQUIRE(de.getExtra().empty());
    1376           1 :                 REQUIRE(de.getHeaderSize() == 0);
    1377           1 :                 REQUIRE(de.getLevel() == g_directory_level);
    1378           1 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
    1379           1 :                 REQUIRE(de.getName() == "filepath-test");
    1380           1 :                 REQUIRE(de.getFileName() == "filepath-test");
    1381           1 :                 REQUIRE(de.getSize() == 0);
    1382           1 :                 REQUIRE(de.getTime() == dt.getDOSDateTime());
    1383           1 :                 REQUIRE(de.getUnixTime() == file_stats.st_mtime);
    1384           1 :                 REQUIRE_FALSE(de.hasCrc());
    1385           1 :                 REQUIRE(de.isDirectory());
    1386           1 :                 REQUIRE(de.isValid());
    1387           1 :                 REQUIRE(de.toString() == "filepath-test (directory)");
    1388             : 
    1389             :                 // attempt a clone now, should have the same content
    1390           2 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
    1391             : 
    1392           1 :                 REQUIRE(clone->getComment().empty());
    1393           1 :                 REQUIRE(clone->getCompressedSize() == 0);
    1394           1 :                 REQUIRE(clone->getCrc() == 0);
    1395           1 :                 REQUIRE(clone->getEntryOffset() == 0);
    1396           1 :                 REQUIRE(clone->getExtra().empty());
    1397           1 :                 REQUIRE(clone->getHeaderSize() == 0);
    1398           1 :                 REQUIRE(clone->getLevel() == g_directory_level);
    1399           1 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
    1400           1 :                 REQUIRE(clone->getName() == "filepath-test");
    1401           1 :                 REQUIRE(clone->getFileName() == "filepath-test");
    1402           1 :                 REQUIRE(clone->getSize() == 0);
    1403           1 :                 REQUIRE(clone->getTime() == dt.getDOSDateTime());
    1404           1 :                 REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
    1405           1 :                 REQUIRE_FALSE(clone->hasCrc());
    1406           1 :                 REQUIRE(clone->isDirectory());
    1407           1 :                 REQUIRE(clone->isValid());
    1408           1 :                 REQUIRE(clone->toString() == "filepath-test (directory)");
    1409             :             }
    1410             :         }
    1411             : 
    1412          20 :         WHEN("setting the CRC")
    1413             :         {
    1414             :             // zero would not really prove anything so skip such
    1415             :             uint32_t r;
    1416           0 :             do
    1417             :             {
    1418           1 :                 r = rand();
    1419             :             }
    1420           1 :             while(r == 0);
    1421           1 :             de.setCrc(rand());
    1422             : 
    1423           2 :             THEN("we ignore it")
    1424             :             {
    1425           1 :                 REQUIRE(de.getComment().empty());
    1426           1 :                 REQUIRE(de.getCompressedSize() == 0);
    1427           1 :                 REQUIRE(de.getCrc() == 0);
    1428           1 :                 REQUIRE(de.getEntryOffset() == 0);
    1429           1 :                 REQUIRE(de.getExtra().empty());
    1430           1 :                 REQUIRE(de.getHeaderSize() == 0);
    1431           1 :                 REQUIRE(de.getLevel() == g_directory_level);
    1432           1 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
    1433           1 :                 REQUIRE(de.getName() == "filepath-test");
    1434           1 :                 REQUIRE(de.getFileName() == "filepath-test");
    1435           1 :                 REQUIRE(de.getSize() == 0);
    1436           1 :                 REQUIRE(de.getTime() == dt.getDOSDateTime());
    1437           1 :                 REQUIRE(de.getUnixTime() == file_stats.st_mtime);
    1438           1 :                 REQUIRE(!de.hasCrc());
    1439           1 :                 REQUIRE(de.isDirectory());
    1440           1 :                 REQUIRE(de.isValid());
    1441           1 :                 REQUIRE(de.toString() == "filepath-test (directory)");
    1442             : 
    1443             :                 // attempt a clone now, should have the same content
    1444           2 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
    1445             : 
    1446           1 :                 REQUIRE(clone->getComment().empty());
    1447           1 :                 REQUIRE(clone->getCompressedSize() == 0);
    1448           1 :                 REQUIRE(clone->getCrc() == 0);
    1449           1 :                 REQUIRE(clone->getEntryOffset() == 0);
    1450           1 :                 REQUIRE(clone->getExtra().empty());
    1451           1 :                 REQUIRE(clone->getHeaderSize() == 0);
    1452           1 :                 REQUIRE(clone->getLevel() == g_directory_level);
    1453           1 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
    1454           1 :                 REQUIRE(clone->getName() == "filepath-test");
    1455           1 :                 REQUIRE(clone->getFileName() == "filepath-test");
    1456           1 :                 REQUIRE(clone->getSize() == 0);
    1457           1 :                 REQUIRE(clone->getTime() == dt.getDOSDateTime());
    1458           1 :                 REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
    1459           1 :                 REQUIRE(!clone->hasCrc());
    1460           1 :                 REQUIRE(clone->isDirectory());
    1461           1 :                 REQUIRE(clone->isValid());
    1462           1 :                 REQUIRE(clone->toString() == "filepath-test (directory)");
    1463             :             }
    1464             :         }
    1465             : 
    1466          20 :         WHEN("setting an extra buffer")
    1467             :         {
    1468             :             // zero would not really prove anything so skip such
    1469           2 :             zipios::FileEntry::buffer_t b;
    1470           1 :             uint32_t size(rand() % 100 + 20);
    1471          38 :             for(uint32_t i(0); i < size; ++i)
    1472             :             {
    1473          37 :                 b.push_back(rand());
    1474             :             }
    1475           1 :             de.setExtra(b);
    1476             : 
    1477           2 :             THEN("we ignore it")
    1478             :             {
    1479           1 :                 REQUIRE(de.getComment().empty());
    1480           1 :                 REQUIRE(de.getCompressedSize() == 0);
    1481           1 :                 REQUIRE(de.getCrc() == 0);
    1482           1 :                 REQUIRE(de.getEntryOffset() == 0);
    1483           1 :                 REQUIRE_FALSE(de.getExtra().empty());
    1484           1 :                 REQUIRE(de.getHeaderSize() == 0);
    1485           1 :                 REQUIRE(de.getLevel() == g_directory_level);
    1486           1 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
    1487           1 :                 REQUIRE(de.getName() == "filepath-test");
    1488           1 :                 REQUIRE(de.getFileName() == "filepath-test");
    1489           1 :                 REQUIRE(de.getSize() == 0);
    1490           1 :                 REQUIRE(de.getTime() == dt.getDOSDateTime());
    1491           1 :                 REQUIRE(de.getUnixTime() == file_stats.st_mtime);
    1492           1 :                 REQUIRE(!de.hasCrc());
    1493           1 :                 REQUIRE(de.isDirectory());
    1494           1 :                 REQUIRE(de.isValid());
    1495           1 :                 REQUIRE(de.toString() == "filepath-test (directory)");
    1496           1 :                 REQUIRE(de.getExtra() == b);
    1497             : 
    1498             :                 // attempt a clone now, should have the same content
    1499           2 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
    1500             : 
    1501           1 :                 REQUIRE(clone->getComment().empty());
    1502           1 :                 REQUIRE(clone->getCompressedSize() == 0);
    1503           1 :                 REQUIRE(clone->getCrc() == 0);
    1504           1 :                 REQUIRE(clone->getEntryOffset() == 0);
    1505           1 :                 REQUIRE_FALSE(clone->getExtra().empty());
    1506           1 :                 REQUIRE(clone->getHeaderSize() == 0);
    1507           1 :                 REQUIRE(clone->getLevel() == g_directory_level);
    1508           1 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
    1509           1 :                 REQUIRE(clone->getName() == "filepath-test");
    1510           1 :                 REQUIRE(clone->getFileName() == "filepath-test");
    1511           1 :                 REQUIRE(clone->getSize() == 0);
    1512           1 :                 REQUIRE(clone->getTime() == dt.getDOSDateTime());
    1513           1 :                 REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
    1514           1 :                 REQUIRE(!clone->hasCrc());
    1515           1 :                 REQUIRE(clone->isDirectory());
    1516           1 :                 REQUIRE(clone->isValid());
    1517           1 :                 REQUIRE(clone->toString() == "filepath-test (directory)");
    1518           1 :                 REQUIRE(clone->getExtra() == b);
    1519             :             }
    1520             :         }
    1521             : 
    1522          20 :         SECTION("setting all levels, including many invalid ones")
    1523             :         {
    1524        2002 :             for(zipios::FileEntry::CompressionLevel level(-1000); level <= 1000; ++level)
    1525             :             {
    1526             :                 // directories do not accept values from 1 to 100
    1527        2001 :                 if(level >= -3 && level <= 0)
    1528             :                 {
    1529             :                     // this is considered valid for a standard file
    1530           4 :                     de.setLevel(level);
    1531             : 
    1532           4 :                     REQUIRE(de.getComment().empty());
    1533           4 :                     REQUIRE(de.getCompressedSize() == 0);
    1534           4 :                     REQUIRE(de.getCrc() == 0);
    1535           4 :                     REQUIRE(de.getEntryOffset() == 0);
    1536           4 :                     REQUIRE(de.getExtra().empty());
    1537           4 :                     REQUIRE(de.getHeaderSize() == 0);
    1538           4 :                     REQUIRE(de.getLevel() == g_directory_level);
    1539           4 :                     REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
    1540           4 :                     REQUIRE(de.getName() == "filepath-test");
    1541           4 :                     REQUIRE(de.getFileName() == "filepath-test");
    1542           4 :                     REQUIRE(de.getSize() == 0);
    1543           4 :                     REQUIRE(de.getTime() == dt.getDOSDateTime());
    1544           4 :                     REQUIRE(de.getUnixTime() == file_stats.st_mtime);
    1545           4 :                     REQUIRE_FALSE(de.hasCrc());
    1546           4 :                     REQUIRE(de.isDirectory());
    1547           4 :                     REQUIRE(de.isValid());
    1548           4 :                     REQUIRE(de.toString() == "filepath-test (directory)");
    1549             :                 }
    1550             :                 else
    1551             :                 {
    1552        1997 :                     REQUIRE_THROWS_AS(de.setLevel(level), zipios::InvalidStateException);
    1553             :                 }
    1554             :             }
    1555             : 
    1556             :             // restore before continuing test
    1557           1 :             de.setLevel(g_expected_level);
    1558             :         }
    1559             : 
    1560          20 :         WHEN("setting the method")
    1561             :         {
    1562             :             // set to DEFLATED which has no effect because the de is a
    1563             :             // directory and directories accept DEFLATED but ignore it
    1564           1 :             de.setMethod(zipios::StorageMethod::DEFLATED);
    1565             : 
    1566           2 :             THEN("we ignore it")
    1567             :             {
    1568           1 :                 REQUIRE(de.getComment().empty());
    1569           1 :                 REQUIRE(de.getCompressedSize() == 0);
    1570           1 :                 REQUIRE(de.getCrc() == 0);
    1571           1 :                 REQUIRE(de.getEntryOffset() == 0);
    1572           1 :                 REQUIRE(de.getExtra().empty());
    1573           1 :                 REQUIRE(de.getHeaderSize() == 0);
    1574           1 :                 REQUIRE(de.getLevel() == g_directory_level);
    1575           1 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
    1576           1 :                 REQUIRE(de.getName() == "filepath-test");
    1577           1 :                 REQUIRE(de.getFileName() == "filepath-test");
    1578           1 :                 REQUIRE(de.getSize() == 0);
    1579           1 :                 REQUIRE(de.getTime() == dt.getDOSDateTime());
    1580           1 :                 REQUIRE(de.getUnixTime() == file_stats.st_mtime);
    1581           1 :                 REQUIRE_FALSE(de.hasCrc());
    1582           1 :                 REQUIRE(de.isDirectory());
    1583           1 :                 REQUIRE(de.isValid());
    1584           1 :                 REQUIRE(de.toString() == "filepath-test (directory)");
    1585             : 
    1586             :                 // attempt a clone now, should have the same content
    1587           2 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
    1588             : 
    1589           1 :                 REQUIRE(clone->getComment().empty());
    1590           1 :                 REQUIRE(clone->getCompressedSize() == 0);
    1591           1 :                 REQUIRE(clone->getCrc() == 0);
    1592           1 :                 REQUIRE(clone->getEntryOffset() == 0);
    1593           1 :                 REQUIRE(clone->getExtra().empty());
    1594           1 :                 REQUIRE(clone->getHeaderSize() == 0);
    1595           1 :                 REQUIRE(clone->getLevel() == g_directory_level);
    1596           1 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
    1597           1 :                 REQUIRE(clone->getName() == "filepath-test");
    1598           1 :                 REQUIRE(clone->getFileName() == "filepath-test");
    1599           1 :                 REQUIRE(clone->getSize() == 0);
    1600           1 :                 REQUIRE(clone->getTime() == dt.getDOSDateTime());
    1601           1 :                 REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
    1602           1 :                 REQUIRE_FALSE(clone->hasCrc());
    1603           1 :                 REQUIRE(clone->isDirectory());
    1604           1 :                 REQUIRE(clone->isValid());
    1605           1 :                 REQUIRE(clone->toString() == "filepath-test (directory)");
    1606             :             }
    1607             :         }
    1608             : 
    1609          20 :         WHEN("setting the uncompressed size")
    1610             :         {
    1611             :             // zero would not really prove anything so skip such
    1612             :             // (although it may be extremely rare...)
    1613             :             size_t r;
    1614           0 :             do
    1615             :             {
    1616           1 :                 r = zipios_test::rand_size_t();
    1617             :             }
    1618           1 :             while(r == 0);
    1619           1 :             de.setSize(r);
    1620             : 
    1621           2 :             THEN("we take it as is")
    1622             :             {
    1623           1 :                 REQUIRE(de.getComment().empty());
    1624           1 :                 REQUIRE(de.getCompressedSize() == r);
    1625           1 :                 REQUIRE(de.getCrc() == 0);
    1626           1 :                 REQUIRE(de.getEntryOffset() == 0);
    1627           1 :                 REQUIRE(de.getExtra().empty());
    1628           1 :                 REQUIRE(de.getHeaderSize() == 0);
    1629           1 :                 REQUIRE(de.getLevel() == g_directory_level);
    1630           1 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
    1631           1 :                 REQUIRE(de.getName() == "filepath-test");
    1632           1 :                 REQUIRE(de.getFileName() == "filepath-test");
    1633           1 :                 REQUIRE(de.getSize() == r);
    1634           1 :                 REQUIRE(de.getTime() == dt.getDOSDateTime());
    1635           1 :                 REQUIRE(de.getUnixTime() == file_stats.st_mtime);
    1636           1 :                 REQUIRE(!de.hasCrc());
    1637           1 :                 REQUIRE(de.isDirectory());
    1638           1 :                 REQUIRE(de.isValid());
    1639           1 :                 REQUIRE(de.toString() == "filepath-test (directory)");
    1640             : 
    1641             :                 // attempt a clone now, should have the same content
    1642           2 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
    1643             : 
    1644           1 :                 REQUIRE(clone->getComment().empty());
    1645           1 :                 REQUIRE(clone->getCompressedSize() == r);
    1646           1 :                 REQUIRE(clone->getCrc() == 0);
    1647           1 :                 REQUIRE(clone->getEntryOffset() == 0);
    1648           1 :                 REQUIRE(clone->getExtra().empty());
    1649           1 :                 REQUIRE(clone->getHeaderSize() == 0);
    1650           1 :                 REQUIRE(clone->getLevel() == g_directory_level);
    1651           1 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
    1652           1 :                 REQUIRE(clone->getName() == "filepath-test");
    1653           1 :                 REQUIRE(clone->getFileName() == "filepath-test");
    1654           1 :                 REQUIRE(clone->getSize() == r);
    1655           1 :                 REQUIRE(clone->getTime() == dt.getDOSDateTime());
    1656           1 :                 REQUIRE(clone->getUnixTime() == file_stats.st_mtime);
    1657           1 :                 REQUIRE(!clone->hasCrc());
    1658           1 :                 REQUIRE(clone->isDirectory());
    1659           1 :                 REQUIRE(clone->isValid());
    1660           1 :                 REQUIRE(clone->toString() == "filepath-test (directory)");
    1661             :             }
    1662             :         }
    1663             : 
    1664          20 :         WHEN("setting the DOS time")
    1665             :         {
    1666             :             // DOS time numbers are not linear so we test until we get one
    1667             :             // that works...
    1668           1 :             std::time_t t(static_cast<std::time_t>(zipios_test::rand_size_t()) % (4354848000LL - 315561600LL) + 315561600);
    1669           1 :             zipios::DOSDateTime r;
    1670           1 :             r.setUnixTimestamp(t);
    1671           1 :             de.setTime(r.getDOSDateTime());
    1672             : 
    1673           2 :             THEN("we take it as is")
    1674             :             {
    1675           1 :                 REQUIRE(de.getComment().empty());
    1676           1 :                 REQUIRE(de.getCompressedSize() == 0);
    1677           1 :                 REQUIRE(de.getCrc() == 0);
    1678           1 :                 REQUIRE(de.getEntryOffset() == 0);
    1679           1 :                 REQUIRE(de.getExtra().empty());
    1680           1 :                 REQUIRE(de.getHeaderSize() == 0);
    1681           1 :                 REQUIRE(de.getLevel() == g_directory_level);
    1682           1 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
    1683           1 :                 REQUIRE(de.getName() == "filepath-test");
    1684           1 :                 REQUIRE(de.getFileName() == "filepath-test");
    1685           1 :                 REQUIRE(de.getSize() == 0);
    1686           1 :                 REQUIRE(de.getTime() == r.getDOSDateTime());
    1687           1 :                 REQUIRE(de.getUnixTime() == r.getUnixTimestamp());
    1688           1 :                 REQUIRE(!de.hasCrc());
    1689           1 :                 REQUIRE(de.isDirectory());
    1690           1 :                 REQUIRE(de.isValid());
    1691           1 :                 REQUIRE(de.toString() == "filepath-test (directory)");
    1692             : 
    1693             :                 // attempt a clone now, should have the same content
    1694           2 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
    1695             : 
    1696           1 :                 REQUIRE(clone->getComment().empty());
    1697           1 :                 REQUIRE(clone->getCompressedSize() == 0);
    1698           1 :                 REQUIRE(clone->getCrc() == 0);
    1699           1 :                 REQUIRE(clone->getEntryOffset() == 0);
    1700           1 :                 REQUIRE(clone->getExtra().empty());
    1701           1 :                 REQUIRE(clone->getHeaderSize() == 0);
    1702           1 :                 REQUIRE(clone->getLevel() == g_directory_level);
    1703           1 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
    1704           1 :                 REQUIRE(clone->getName() == "filepath-test");
    1705           1 :                 REQUIRE(clone->getFileName() == "filepath-test");
    1706           1 :                 REQUIRE(clone->getSize() == 0);
    1707           1 :                 REQUIRE(clone->getTime() == r.getDOSDateTime());
    1708           1 :                 REQUIRE(clone->getUnixTime() == r.getUnixTimestamp());
    1709           1 :                 REQUIRE(!clone->hasCrc());
    1710           1 :                 REQUIRE(clone->isDirectory());
    1711           1 :                 REQUIRE(clone->isValid());
    1712           1 :                 REQUIRE(clone->toString() == "filepath-test (directory)");
    1713             :             }
    1714             :         }
    1715             : 
    1716          20 :         WHEN("setting the Unix time")
    1717             :         {
    1718             :             // DOS time are limited to a smaller range and on every other
    1719             :             // second so we get a valid DOS time and convert it to a Unix time
    1720           1 :             std::time_t r(static_cast<std::time_t>(zipios_test::rand_size_t()) % (4354848000LL - 315561600LL) + 315561600);
    1721           1 :             de.setUnixTime(r);
    1722             : 
    1723           1 :             zipios::DOSDateTime dr;
    1724           1 :             dr.setUnixTimestamp(r);
    1725             : 
    1726           2 :             THEN("we take it as is")
    1727             :             {
    1728           1 :                 REQUIRE(de.getComment().empty());
    1729           1 :                 REQUIRE(de.getCompressedSize() == 0);
    1730           1 :                 REQUIRE(de.getCrc() == 0);
    1731           1 :                 REQUIRE(de.getEntryOffset() == 0);
    1732           1 :                 REQUIRE(de.getExtra().empty());
    1733           1 :                 REQUIRE(de.getHeaderSize() == 0);
    1734           1 :                 REQUIRE(de.getLevel() == g_directory_level);
    1735           1 :                 REQUIRE(de.getMethod() == zipios::StorageMethod::STORED);
    1736           1 :                 REQUIRE(de.getName() == "filepath-test");
    1737           1 :                 REQUIRE(de.getFileName() == "filepath-test");
    1738           1 :                 REQUIRE(de.getSize() == 0);
    1739           1 :                 REQUIRE(de.getTime() == dr.getDOSDateTime());
    1740           1 :                 REQUIRE(de.getUnixTime() == r);
    1741           1 :                 REQUIRE(!de.hasCrc());
    1742           1 :                 REQUIRE(de.isDirectory());
    1743           1 :                 REQUIRE(de.isValid());
    1744           1 :                 REQUIRE(de.toString() == "filepath-test (directory)");
    1745             : 
    1746             :                 // attempt a clone now, should have the same content
    1747           2 :                 zipios::DirectoryEntry::pointer_t clone(de.clone());
    1748             : 
    1749           1 :                 REQUIRE(clone->getComment().empty());
    1750           1 :                 REQUIRE(clone->getCompressedSize() == 0);
    1751           1 :                 REQUIRE(clone->getCrc() == 0);
    1752           1 :                 REQUIRE(clone->getEntryOffset() == 0);
    1753           1 :                 REQUIRE(clone->getExtra().empty());
    1754           1 :                 REQUIRE(clone->getHeaderSize() == 0);
    1755           1 :                 REQUIRE(clone->getLevel() == g_directory_level);
    1756           1 :                 REQUIRE(clone->getMethod() == zipios::StorageMethod::STORED);
    1757           1 :                 REQUIRE(clone->getName() == "filepath-test");
    1758           1 :                 REQUIRE(clone->getFileName() == "filepath-test");
    1759           1 :                 REQUIRE(clone->getSize() == 0);
    1760           1 :                 REQUIRE(clone->getTime() == dr.getDOSDateTime());
    1761           1 :                 REQUIRE(clone->getUnixTime() == r);
    1762           1 :                 REQUIRE(!clone->hasCrc());
    1763           1 :                 REQUIRE(clone->isDirectory());
    1764           1 :                 REQUIRE(clone->isValid());
    1765           1 :                 REQUIRE(clone->toString() == "filepath-test (directory)");
    1766             :             }
    1767             :         }
    1768             : 
    1769          10 :         rmdir("filepath-test");
    1770             :     }
    1771          13 : }
    1772             : 
    1773             : 
    1774             : 
    1775             : 
    1776             : // Local Variables:
    1777             : // mode: cpp
    1778             : // indent-tabs-mode: nil
    1779             : // c-basic-offset: 4
    1780             : // tab-width: 4
    1781             : // End:
    1782             : 
    1783             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.12