2014-08-01 21:44:21 +08:00
# include <cassert>
# include <fstream>
# include <cxxtest/TestSuite.h>
# include <xlnt/xlnt.hpp>
# include "helpers/path_helper.hpp"
# include "helpers/temporary_file.hpp"
class test_zip_file : public CxxTest : : TestSuite
{
public :
test_zip_file ( )
{
2016-07-21 07:04:44 +08:00
existing_file = path_helper : : get_data_directory ( " /genuine/empty.xlsx " ) ;
2014-08-01 21:44:21 +08:00
expected_content_types_string = " <?xml version= \" 1.0 \" encoding= \" UTF-8 \" standalone= \" yes \" ?> \r \n <Types xmlns= \" http://schemas.openxmlformats.org/package/2006/content-types \" ><Default Extension= \" xml \" ContentType= \" application/xml \" /><Default Extension= \" rels \" ContentType= \" application/vnd.openxmlformats-package.relationships+xml \" /><Override PartName= \" /xl/workbook.xml \" ContentType= \" application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml \" /><Override PartName= \" /xl/worksheets/sheet1.xml \" ContentType= \" application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml \" /><Override PartName= \" /xl/worksheets/sheet2.xml \" ContentType= \" application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml \" /><Override PartName= \" /xl/worksheets/sheet3.xml \" ContentType= \" application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml \" /><Override PartName= \" /xl/worksheets/sheet4.xml \" ContentType= \" application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml \" /><Override PartName= \" /xl/theme/theme1.xml \" ContentType= \" application/vnd.openxmlformats-officedocument.theme+xml \" /><Override PartName= \" /xl/styles.xml \" ContentType= \" application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml \" /><Override PartName= \" /xl/sharedStrings.xml \" ContentType= \" application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml \" /><Override PartName= \" /xl/calcChain.xml \" ContentType= \" application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml \" /><Override PartName= \" /docProps/core.xml \" ContentType= \" application/vnd.openxmlformats-package.core-properties+xml \" /><Override PartName= \" /docProps/app.xml \" ContentType= \" application/vnd.openxmlformats-officedocument.extended-properties+xml \" /></Types> " ;
2015-10-02 06:14:42 +08:00
expected_atxt_string = " <?xml version= \" 1.0 \" ?> \n <sst xmlns= \" http://schemas.openxmlformats.org/spreadsheetml/2006/main \" count= \" 3 \" uniqueCount= \" 2 \" ><si><t>This is cell A1 in Sheet 1</t></si><si><t>This is cell G5</t></si></sst> " ;
2014-08-01 21:44:21 +08:00
expected_printdir_string = " Length Date Time Name \n --------- ---------- ----- ---- \n 1704 01/01/1980 00:00 [Content_Types].xml \n 588 01/01/1980 00:00 _rels/.rels \n 1254 01/01/1980 00:00 xl/_rels/workbook.xml.rels \n 898 01/01/1980 00:00 xl/workbook.xml \n 1231 01/01/1980 00:00 xl/worksheets/sheet4.xml \n 4427 01/01/1980 00:00 xl/worksheets/sheet2.xml \n 1032 01/01/1980 00:00 xl/worksheets/sheet3.xml \n 1026 01/01/1980 00:00 xl/worksheets/sheet1.xml \n 6995 01/01/1980 00:00 xl/theme/theme1.xml \n 233 01/01/1980 00:00 xl/sharedStrings.xml \n 1724 01/01/1980 00:00 xl/styles.xml \n 169 01/01/1980 00:00 xl/calcChain.xml \n 917 01/01/1980 00:00 docProps/app.xml \n 609 01/01/1980 00:00 docProps/core.xml \n --------- ------- \n 22807 14 files \n " ;
}
void remove_temp_file ( )
{
2015-11-11 07:58:54 +08:00
std : : remove ( temp_file . GetFilename ( ) . c_str ( ) ) ;
2014-08-01 21:44:21 +08:00
}
void make_temp_directory ( )
{
}
void remove_temp_directory ( )
{
}
2015-11-11 07:58:54 +08:00
bool files_equal ( const std : : string & a , const std : : string & b )
2014-08-01 21:44:21 +08:00
{
if ( a = = b )
{
return true ;
}
2015-11-11 07:58:54 +08:00
std : : ifstream stream_a ( a , std : : ios : : binary ) , stream_b ( a , std : : ios : : binary ) ;
2014-08-01 21:44:21 +08:00
while ( stream_a & & stream_b )
{
if ( stream_a . get ( ) ! = stream_b . get ( ) )
{
return false ;
}
}
return true ;
}
void test_load_file ( )
{
remove_temp_file ( ) ;
xlnt : : zip_file f ( existing_file ) ;
f . save ( temp_file . GetFilename ( ) ) ;
2014-08-02 04:46:54 +08:00
TS_ASSERT ( files_equal ( existing_file , temp_file . GetFilename ( ) ) ) ;
2014-08-01 21:44:21 +08:00
remove_temp_file ( ) ;
}
void test_load_stream ( )
{
remove_temp_file ( ) ;
{
2015-11-11 07:58:54 +08:00
std : : ifstream in_stream ( existing_file , std : : ios : : binary ) ;
2014-08-01 21:44:21 +08:00
xlnt : : zip_file f ( in_stream ) ;
2015-11-11 07:58:54 +08:00
std : : ofstream out_stream ( temp_file . GetFilename ( ) , std : : ios : : binary ) ;
2014-08-01 21:44:21 +08:00
f . save ( out_stream ) ;
}
2014-08-02 04:46:54 +08:00
TS_ASSERT ( files_equal ( existing_file , temp_file . GetFilename ( ) ) ) ;
2014-08-01 21:44:21 +08:00
remove_temp_file ( ) ;
}
void test_load_bytes ( )
{
remove_temp_file ( ) ;
std : : vector < unsigned char > source_bytes , result_bytes ;
2015-11-11 07:58:54 +08:00
std : : ifstream in_stream ( existing_file , std : : ios : : binary ) ;
2014-08-01 21:44:21 +08:00
while ( in_stream )
{
source_bytes . push_back ( ( unsigned char ) in_stream . get ( ) ) ;
}
2016-07-20 11:39:08 +08:00
xlnt : : zip_file f ( source_bytes ) ;
2014-08-01 21:44:21 +08:00
f . save ( temp_file . GetFilename ( ) ) ;
xlnt : : zip_file f2 ;
f2 . load ( temp_file . GetFilename ( ) ) ;
result_bytes = std : : vector < unsigned char > ( ) ;
f2 . save ( result_bytes ) ;
2014-08-02 04:46:54 +08:00
TS_ASSERT ( source_bytes = = result_bytes ) ;
2014-08-01 21:44:21 +08:00
remove_temp_file ( ) ;
}
void test_reset ( )
{
xlnt : : zip_file f ( existing_file ) ;
2014-08-02 04:46:54 +08:00
TS_ASSERT ( ! f . namelist ( ) . empty ( ) ) ;
2014-08-01 21:44:21 +08:00
try
{
f . read ( " [Content_Types].xml " ) ;
}
catch ( std : : exception e )
{
2014-08-02 04:46:54 +08:00
TS_ASSERT ( false ) ;
2014-08-01 21:44:21 +08:00
}
f . reset ( ) ;
2014-08-02 04:46:54 +08:00
TS_ASSERT ( f . namelist ( ) . empty ( ) ) ;
2014-08-01 21:44:21 +08:00
try
{
f . read ( " [Content_Types].xml " ) ;
2014-08-02 04:46:54 +08:00
TS_ASSERT ( false ) ;
2014-08-01 21:44:21 +08:00
}
catch ( std : : exception e )
{
}
2016-07-20 11:39:08 +08:00
f . writestr ( " a " , " b " ) ;
f . reset ( ) ;
TS_ASSERT ( f . namelist ( ) . empty ( ) ) ;
f . writestr ( " a " , " b " ) ;
TS_ASSERT_DIFFERS ( f . getinfo ( " a " ) . file_size , 0 ) ;
2014-08-01 21:44:21 +08:00
}
void test_getinfo ( )
{
xlnt : : zip_file f ( existing_file ) ;
auto info = f . getinfo ( " [Content_Types].xml " ) ;
2014-08-02 04:46:54 +08:00
TS_ASSERT ( info . filename = = " [Content_Types].xml " ) ;
2014-08-01 21:44:21 +08:00
}
void test_infolist ( )
{
xlnt : : zip_file f ( existing_file ) ;
2014-08-02 04:46:54 +08:00
TS_ASSERT ( f . infolist ( ) . size ( ) = = 14 ) ;
2014-08-01 21:44:21 +08:00
}
void test_namelist ( )
{
xlnt : : zip_file f ( existing_file ) ;
2014-08-02 04:46:54 +08:00
TS_ASSERT ( f . namelist ( ) . size ( ) = = 14 ) ;
2014-08-01 21:44:21 +08:00
}
void test_open_by_name ( )
{
xlnt : : zip_file f ( existing_file ) ;
std : : stringstream ss ;
ss < < f . open ( " [Content_Types].xml " ) . rdbuf ( ) ;
2015-11-11 07:58:54 +08:00
std : : string result = ss . str ( ) ;
2014-08-02 04:46:54 +08:00
TS_ASSERT ( result = = expected_content_types_string ) ;
2014-08-01 21:44:21 +08:00
}
void test_open_by_info ( )
{
xlnt : : zip_file f ( existing_file ) ;
std : : stringstream ss ;
ss < < f . open ( " [Content_Types].xml " ) . rdbuf ( ) ;
2015-11-11 07:58:54 +08:00
std : : string result = ss . str ( ) ;
2014-08-02 04:46:54 +08:00
TS_ASSERT ( result = = expected_content_types_string ) ;
2014-08-01 21:44:21 +08:00
}
void test_extract_current_directory ( )
{
xlnt : : zip_file f ( existing_file ) ;
}
void test_extract_path ( )
{
xlnt : : zip_file f ( existing_file ) ;
}
void test_extractall_current_directory ( )
{
xlnt : : zip_file f ( existing_file ) ;
}
void test_extractall_path ( )
{
xlnt : : zip_file f ( existing_file ) ;
}
void test_extractall_members_name ( )
{
xlnt : : zip_file f ( existing_file ) ;
}
void test_extractall_members_info ( )
{
xlnt : : zip_file f ( existing_file ) ;
}
void test_printdir ( )
{
xlnt : : zip_file f ( existing_file ) ;
std : : stringstream ss ;
f . printdir ( ss ) ;
2015-11-11 07:58:54 +08:00
auto printed = ss . str ( ) ;
2014-08-02 04:46:54 +08:00
TS_ASSERT ( printed = = expected_printdir_string ) ;
2014-08-01 21:44:21 +08:00
}
void test_read ( )
{
xlnt : : zip_file f ( existing_file ) ;
2014-08-02 04:46:54 +08:00
TS_ASSERT ( f . read ( " [Content_Types].xml " ) = = expected_content_types_string ) ;
TS_ASSERT ( f . read ( f . getinfo ( " [Content_Types].xml " ) ) = = expected_content_types_string ) ;
2014-08-01 21:44:21 +08:00
}
void test_testzip ( )
{
xlnt : : zip_file f ( existing_file ) ;
2014-08-02 04:46:54 +08:00
TS_ASSERT ( f . testzip ( ) . first ) ;
2014-08-01 21:44:21 +08:00
}
void test_write ( )
{
remove_temp_file ( ) ;
xlnt : : zip_file f ;
2016-07-21 07:04:44 +08:00
auto text_file = path_helper : : get_data_directory ( " /reader/sharedStrings.xml " ) ;
2014-08-01 21:44:21 +08:00
f . write ( text_file ) ;
f . write ( text_file , " sharedStrings2.xml " ) ;
f . save ( temp_file . GetFilename ( ) ) ;
xlnt : : zip_file f2 ( temp_file . GetFilename ( ) ) ;
2014-08-02 04:46:54 +08:00
for ( auto & info : f2 . infolist ( ) )
{
if ( info . filename = = " sharedStrings2.xml " )
{
TS_ASSERT ( f2 . read ( info ) = = expected_atxt_string ) ;
}
2015-11-11 07:58:54 +08:00
else if ( info . filename . substr ( info . filename . size ( ) - 17 ) = = " sharedStrings.xml " )
2014-08-02 04:46:54 +08:00
{
TS_ASSERT ( f2 . read ( info ) = = expected_atxt_string ) ;
}
}
2014-08-01 21:44:21 +08:00
remove_temp_file ( ) ;
}
void test_writestr ( )
{
remove_temp_file ( ) ;
xlnt : : zip_file f ;
f . writestr ( " a.txt " , " a \n a " ) ;
xlnt : : zip_info info ;
info . filename = " b.txt " ;
2014-08-02 04:46:54 +08:00
info . date_time . year = 2014 ;
2014-08-01 21:44:21 +08:00
f . writestr ( info , " b \n b " ) ;
f . save ( temp_file . GetFilename ( ) ) ;
xlnt : : zip_file f2 ( temp_file . GetFilename ( ) ) ;
2014-08-02 04:46:54 +08:00
TS_ASSERT ( f2 . read ( " a.txt " ) = = " a \n a " ) ;
TS_ASSERT ( f2 . read ( f2 . getinfo ( " b.txt " ) ) = = " b \n b " ) ;
2014-08-01 21:44:21 +08:00
remove_temp_file ( ) ;
}
void test_comment ( )
{
remove_temp_file ( ) ;
xlnt : : zip_file f ;
f . comment = " comment " ;
f . save ( temp_file . GetFilename ( ) ) ;
xlnt : : zip_file f2 ( temp_file . GetFilename ( ) ) ;
2014-08-02 04:46:54 +08:00
TS_ASSERT ( f2 . comment = = " comment " ) ;
2016-07-20 11:39:08 +08:00
xlnt : : zip_file f3 ;
std : : vector < std : : uint8_t > bytes { 1 , 2 , 3 } ;
TS_ASSERT_THROWS ( f3 . load ( bytes ) , std : : runtime_error ) ;
2014-08-01 21:44:21 +08:00
remove_temp_file ( ) ;
}
2016-07-20 09:17:31 +08:00
void test_extract ( )
{
xlnt : : zip_file f ;
2016-07-21 07:04:44 +08:00
f . load ( path_helper : : get_data_directory ( " /genuine/empty.xlsx " ) ) ;
2016-07-20 09:17:31 +08:00
2016-07-21 07:04:44 +08:00
auto expected = path_helper : : get_working_directory ( ) + " /xl/styles.xml " ;
2016-07-20 09:17:31 +08:00
2016-07-21 07:04:44 +08:00
TS_ASSERT ( ! path_helper : : file_exists ( expected ) ) ;
2016-07-20 09:17:31 +08:00
f . extract ( " xl/styles.xml " ) ;
2016-07-21 07:04:44 +08:00
TS_ASSERT ( path_helper : : file_exists ( expected ) ) ;
path_helper : : delete_file ( expected ) ;
2016-07-20 09:17:31 +08:00
auto info = f . getinfo ( " xl/styles.xml " ) ;
2016-07-21 07:04:44 +08:00
TS_ASSERT ( ! path_helper : : file_exists ( expected ) ) ;
2016-07-20 09:17:31 +08:00
f . extract ( info ) ;
2016-07-21 07:04:44 +08:00
TS_ASSERT ( path_helper : : file_exists ( expected ) ) ;
path_helper : : delete_file ( expected ) ;
2016-07-20 09:17:31 +08:00
}
2014-08-01 21:44:21 +08:00
private :
TemporaryFile temp_file ;
2015-11-11 07:58:54 +08:00
std : : string existing_file ;
std : : string expected_content_types_string ;
std : : string expected_atxt_string ;
std : : string expected_printdir_string ;
2015-10-15 06:05:13 +08:00
} ;