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-08-03 12:12:18 +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> " ;
2016-07-22 08:44:00 +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 "
" 917 01/01/1980 00:00 docProps/app.xml \n "
" 609 01/01/1980 00:00 docProps/core.xml \n "
" 1254 01/01/1980 00:00 xl/_rels/workbook.xml.rels \n "
" 169 01/01/1980 00:00 xl/calcChain.xml \n "
" 233 01/01/1980 00:00 xl/sharedStrings.xml \n "
" 1724 01/01/1980 00:00 xl/styles.xml \n "
" 6995 01/01/1980 00:00 xl/theme/theme1.xml \n "
" 898 01/01/1980 00:00 xl/workbook.xml \n "
" 1068 07/21/2016 20:27 xl/worksheets/sheet1.xml \n "
" 4427 01/01/1980 00:00 xl/worksheets/sheet2.xml \n "
" 1032 01/01/1980 00:00 xl/worksheets/sheet3.xml \n "
" 1231 01/01/1980 00:00 xl/worksheets/sheet4.xml \n "
" --------- ------- \n "
" 22849 14 files \n " ;
2014-08-01 21:44:21 +08:00
}
2016-08-03 12:12:18 +08:00
bool files_equal ( const xlnt : : path & left , const xlnt : : path & right )
2014-08-01 21:44:21 +08:00
{
2016-08-03 12:12:18 +08:00
if ( left . to_string ( ) = = right . to_string ( ) )
2014-08-01 21:44:21 +08:00
{
return true ;
}
2016-08-03 12:12:18 +08:00
std : : ifstream stream_left ( left . to_string ( ) , std : : ios : : binary ) ;
std : : ifstream stream_right ( right . to_string ( ) , std : : ios : : binary ) ;
2014-08-01 21:44:21 +08:00
2016-08-03 12:12:18 +08:00
while ( stream_left & & stream_right )
2014-08-01 21:44:21 +08:00
{
2016-08-03 12:12:18 +08:00
if ( stream_left . get ( ) ! = stream_right . get ( ) )
2014-08-01 21:44:21 +08:00
{
return false ;
}
}
return true ;
}
void test_load_file ( )
{
2016-08-03 12:12:18 +08:00
temporary_file temp_file ;
2014-08-01 21:44:21 +08:00
xlnt : : zip_file f ( existing_file ) ;
2016-08-03 12:12:18 +08:00
f . save ( temp_file . get_path ( ) ) ;
TS_ASSERT ( files_equal ( existing_file , temp_file . get_path ( ) ) ) ;
2014-08-01 21:44:21 +08:00
}
void test_load_stream ( )
{
2016-08-03 12:12:18 +08:00
temporary_file temp ;
std : : ifstream in_stream ( existing_file . to_string ( ) , std : : ios : : binary ) ;
xlnt : : zip_file f ( in_stream ) ;
std : : ofstream out_stream ( temp . get_path ( ) . to_string ( ) , std : : ios : : binary ) ;
f . save ( out_stream ) ;
out_stream . close ( ) ;
TS_ASSERT ( files_equal ( existing_file , temp . get_path ( ) ) ) ;
2014-08-01 21:44:21 +08:00
}
void test_load_bytes ( )
{
2016-08-03 12:12:18 +08:00
temporary_file temp_file ;
std : : vector < std : : uint8_t > source_bytes ;
std : : ifstream in_stream ( existing_file . to_string ( ) , std : : ios : : binary ) ;
2014-08-01 21:44:21 +08:00
while ( in_stream )
{
2016-08-03 12:12:18 +08:00
source_bytes . push_back ( static_cast < std : : uint8_t > ( in_stream . get ( ) ) ) ;
2014-08-01 21:44:21 +08:00
}
2016-08-03 12:12:18 +08:00
2016-07-20 11:39:08 +08:00
xlnt : : zip_file f ( source_bytes ) ;
2016-08-03 12:12:18 +08:00
f . save ( temp_file . get_path ( ) ) ;
2014-08-01 21:44:21 +08:00
xlnt : : zip_file f2 ;
2016-08-03 12:12:18 +08:00
f2 . load ( temp_file . get_path ( ) ) ;
std : : vector < std : : uint8_t > result_bytes ;
2014-08-01 21:44:21 +08:00
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
}
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
{
2016-08-03 12:12:18 +08:00
f . read ( xlnt : : path ( " [Content_Types].xml " ) ) ;
2014-08-01 21:44:21 +08:00
}
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
{
2016-08-03 12:12:18 +08:00
f . read ( xlnt : : path ( " [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
2016-08-03 12:12:18 +08:00
f . write_string ( " b " , xlnt : : path ( " a " ) ) ;
2016-07-20 11:39:08 +08:00
f . reset ( ) ;
TS_ASSERT ( f . namelist ( ) . empty ( ) ) ;
2016-08-03 12:12:18 +08:00
f . write_string ( " b " , xlnt : : path ( " a " ) ) ;
2016-07-20 11:39:08 +08:00
2016-08-03 12:12:18 +08:00
TS_ASSERT_DIFFERS ( f . getinfo ( xlnt : : path ( " a " ) ) . file_size , 0 ) ;
2014-08-01 21:44:21 +08:00
}
void test_getinfo ( )
{
xlnt : : zip_file f ( existing_file ) ;
2016-08-03 12:12:18 +08:00
auto info = f . getinfo ( xlnt : : path ( " [Content_Types].xml " ) ) ;
TS_ASSERT ( info . filename . to_string ( ) = = " [Content_Types].xml " ) ;
2014-08-01 21:44:21 +08:00
}
void test_infolist ( )
{
xlnt : : zip_file f ( existing_file ) ;
2016-07-22 08:44:00 +08:00
TS_ASSERT_EQUALS ( f . infolist ( ) . size ( ) , 14 ) ;
2014-08-01 21:44:21 +08:00
}
void test_namelist ( )
{
xlnt : : zip_file f ( existing_file ) ;
2016-07-22 08:44:00 +08:00
TS_ASSERT_EQUALS ( 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 ;
2016-08-03 12:12:18 +08:00
ss < < f . open ( xlnt : : path ( " [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 ;
2016-08-03 12:12:18 +08:00
ss < < f . open ( xlnt : : path ( " [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_read ( )
{
xlnt : : zip_file f ( existing_file ) ;
2016-08-03 12:12:18 +08:00
TS_ASSERT ( f . read ( xlnt : : path ( " [Content_Types].xml " ) ) = = expected_content_types_string ) ;
TS_ASSERT ( f . read ( f . getinfo ( xlnt : : path ( " [Content_Types].xml " ) ) ) = = expected_content_types_string ) ;
2014-08-01 21:44:21 +08:00
}
void test_testzip ( )
{
xlnt : : zip_file f ( existing_file ) ;
2016-08-03 12:12:18 +08:00
TS_ASSERT ( ! f . check_crc ( ) ) ;
2014-08-01 21:44:21 +08:00
}
2016-08-03 12:12:18 +08:00
void test_write_file ( )
2014-08-01 21:44:21 +08:00
{
2016-08-03 12:12:18 +08:00
temporary_file temp_file ;
2014-08-01 21:44:21 +08:00
xlnt : : zip_file f ;
2016-08-03 12:12:18 +08:00
auto text_file = path_helper : : get_data_directory ( " reader/sharedStrings.xml " ) ;
f . write_file ( text_file ) ;
f . write_file ( text_file , xlnt : : path ( " sharedStrings2.xml " ) ) ;
f . save ( temp_file . get_path ( ) ) ;
2014-08-01 21:44:21 +08:00
2016-08-03 12:12:18 +08:00
xlnt : : zip_file f2 ( temp_file . get_path ( ) ) ;
2014-08-02 04:46:54 +08:00
for ( auto & info : f2 . infolist ( ) )
{
2016-08-03 12:12:18 +08:00
if ( info . filename . to_string ( ) = = " sharedStrings2.xml " )
2014-08-02 04:46:54 +08:00
{
TS_ASSERT ( f2 . read ( info ) = = expected_atxt_string ) ;
}
2016-08-03 12:12:18 +08:00
else if ( info . filename . basename ( ) = = " 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
}
2016-08-03 12:12:18 +08:00
void test_write_string ( )
2014-08-01 21:44:21 +08:00
{
xlnt : : zip_file f ;
2016-08-03 12:12:18 +08:00
f . write_string ( " a \n a " , xlnt : : path ( " a.txt " ) ) ;
2014-08-01 21:44:21 +08:00
xlnt : : zip_info info ;
2016-08-03 12:12:18 +08:00
info . filename = xlnt : : path ( " b.txt " ) ;
2014-08-02 04:46:54 +08:00
info . date_time . year = 2014 ;
2016-08-03 12:12:18 +08:00
f . write_string ( " b \n b " , info ) ;
temporary_file temp_file ;
f . save ( temp_file . get_path ( ) ) ;
2014-08-01 21:44:21 +08:00
2016-08-03 12:12:18 +08:00
xlnt : : zip_file f2 ( temp_file . get_path ( ) ) ;
TS_ASSERT ( f2 . read ( xlnt : : path ( " a.txt " ) ) = = " a \n a " ) ;
TS_ASSERT ( f2 . read ( f2 . getinfo ( xlnt : : path ( " b.txt " ) ) ) = = " b \n b " ) ;
2014-08-01 21:44:21 +08:00
}
void test_comment ( )
{
xlnt : : zip_file f ;
f . comment = " comment " ;
2016-08-03 12:12:18 +08:00
temporary_file temp_file ;
f . save ( temp_file . get_path ( ) ) ;
2014-08-01 21:44:21 +08:00
2016-08-03 12:12:18 +08:00
xlnt : : zip_file f2 ( temp_file . get_path ( ) ) ;
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 ) ;
2016-07-20 09:17:31 +08:00
}
2014-08-01 21:44:21 +08:00
private :
2016-08-03 12:12:18 +08:00
xlnt : : path existing_file ;
2015-11-11 07:58:54 +08:00
std : : string expected_content_types_string ;
std : : string expected_atxt_string ;
std : : string expected_printdir_string ;
2015-10-15 06:05:13 +08:00
} ;