#!/usr/bin/perl # Main testing for Archive::Zip use strict; BEGIN { $| = 1; $^W = 1; } use Archive::SevenZip qw( :ERROR_CODES :CONSTANTS ); use FileHandle; use File::Path; use File::Spec; use Test::More; use vars qw($testZipDoesntWork $status); BEGIN { if( ! eval { require t::common; t::common->import; 1 }) { plan skip_all => "Archive::Zip not installed, skipping compatibility tests", 83; exit; } else { plan tests => 83; } } ##################################################################### # Testing Utility Functions #--------- check CRC is(TESTSTRINGCRC(), 0xac373f32, 'Testing CRC matches expected'); # Bad times die SCOPE: { my @errors = (); local $Archive::Zip::ErrorHandler = sub { push @errors, @_ }; eval { Archive::Zip::Member::_unixToDosTime(0) }; ok($errors[0] =~ /Tried to add member with zero or undef/, 'Got expected _unixToDosTime error'); } #--------- check time conversion foreach my $unix_time ( 315576062, 315576064, 315580000, 315600000, 316000000, 320000000, 400000000, 500000000, 600000000, 700000000, 800000000, 900000000, 1000000000, 1100000000, 1200000000, int(time() / 2) * 2, ) { my $dos_time = Archive::Zip::Member::_unixToDosTime($unix_time); my $round_trip = Archive::Zip::Member::_dosToUnixTime($dos_time); is($unix_time, $round_trip, 'Got expected DOS DateTime value'); } ##################################################################### # Testing Archives my $version = Archive::SevenZip->find_7z_executable(); if( ! $version ) { SKIP: { skip "7z binary not found (not installed?)", 65; } exit; }; diag "7-zip version $version"; if( $version <= 9.20) { SKIP: { skip "7z version $version does not support renaming", 65; } exit }; #--------- empty file # new # Archive::Zip # new # Archive::Zip::Archive my $zip = Archive::SevenZip->archiveZipApi(); isa_ok($zip, 'Archive::SevenZip::API::ArchiveZip'); # members # Archive::Zip::Archive my @members = $zip->members; is(scalar(@members), 0, '->members is 0'); # numberOfMembers # Archive::Zip::Archive my $numberOfMembers = $zip->numberOfMembers(); is($numberOfMembers, 0, '->numberofMembers is 0'); # writeToFileNamed # Archive::Zip::Archive my $status = $zip->writeToFileNamed(OUTPUTZIP()); is($status, AZ_OK, '->writeToFileNames ok'); my $zipout; SKIP: { skip("No 'unzip' program to test against", 1) unless HAVEUNZIP(); if ($^O eq 'MSWin32') { print STDERR "\n# You might see an expected 'zipfile is empty' warning now.\n"; } ($status, $zipout) = testZip(); # STDERR->print("status= $status, out=$zipout\n"); skip("test zip doesn't work", 1) if $testZipDoesntWork; skip("freebsd's unzip doesn't care about empty zips", 1) if $^O eq 'freebsd'; ok($status != 0); } # unzip -t returns error code=1 for warning on empty #--------- add a directory my $memberName = TESTDIR() . '/'; my $dirName = TESTDIR(); # addDirectory # Archive::Zip::Archive # new # Archive::Zip::Member my $member = $zip->addDirectory($memberName); ok(defined($member)); is($member->fileName(), $memberName); # On some (Windows systems) the modification time is # corrupted. Save this to check late. my $dir_time = $member->lastModFileDateTime(); # members # Archive::Zip::Archive @members = $zip->members(); is(scalar(@members), 1); is($members[0]->fileName, $member->fileName); # numberOfMembers # Archive::Zip::Archive $numberOfMembers = $zip->numberOfMembers(); is($numberOfMembers, 1); # writeToFileNamed # Archive::Zip::Archive $status = $zip->writeToFileNamed(OUTPUTZIP()); is($status, AZ_OK); # Does the modification time get corrupted? is(($zip->members)[0]->lastModFileDateTime(), $dir_time); SKIP: { skip("No 'unzip' program to test against", 1) unless HAVEUNZIP(); ($status, $zipout) = testZip(); # STDERR->print("status= $status, out=$zipout\n"); skip("test zip doesn't work", 1) if $testZipDoesntWork; is($status, 0); } #--------- extract the directory by name rmtree([TESTDIR()], 0, 0); $status = $zip->extractMember($memberName); is($status, AZ_OK); ok(-d $dirName); #--------- extract the directory by identity ok(rmdir($dirName)); # it's still empty $status = $zip->extractMember($member); is($status, AZ_OK); ok(-d $dirName); #--------- add a string member, uncompressed $memberName = TESTDIR() . '/string.txt'; # addString # Archive::Zip::Archive # newFromString # Archive::Zip::Member $member = $zip->addString(TESTSTRING(), $memberName); ok(defined($member)); is($member->fileName(), $memberName); # members # Archive::Zip::Archive @members = $zip->members(); is(scalar(@members), 2); #is($members[1]->fileName, $member->fileName); # numberOfMembers # Archive::Zip::Archive $numberOfMembers = $zip->numberOfMembers(); is($numberOfMembers, 2); # writeToFileNamed # Archive::Zip::Archive $status = $zip->writeToFileNamed(OUTPUTZIP()); is($status, AZ_OK); SKIP: { skip("No 'unzip' program to test against", 1) unless HAVEUNZIP(); ($status, $zipout) = testZip(); # STDERR->print("status= $status, out=$zipout\n"); skip("test zip doesn't work", 1) if $testZipDoesntWork; is($status, 0); } is($member->crc32(), TESTSTRINGCRC()); is($member->crc32String(), sprintf("%08x", TESTSTRINGCRC())); #--------- extract it by name $status = $zip->extractMember($memberName); is($status, AZ_OK); ok(-f $memberName); is(fileCRC($memberName), TESTSTRINGCRC()); #--------- now compress it and re-test #my $oldCompressionMethod = # $member->desiredCompressionMethod(COMPRESSION_DEFLATED); #is($oldCompressionMethod, COMPRESSION_STORED, 'old compression method OK'); # writeToFileNamed # Archive::Zip::Archive $status = $zip->writeToFileNamed(OUTPUTZIP()); is($status, AZ_OK, 'writeToFileNamed returns AZ_OK'); is($member->crc32(), TESTSTRINGCRC()); is($member->uncompressedSize(), TESTSTRINGLENGTH()); SKIP: { skip("No 'unzip' program to test against", 1) unless HAVEUNZIP(); ($status, $zipout) = testZip(); # STDERR->print("status= $status, out=$zipout\n"); skip("test zip doesn't work", 1) if $testZipDoesntWork; is($status, 0); } #--------- extract it by name $status = $zip->extractMember($memberName); is($status, AZ_OK); ok(-f $memberName); is(fileCRC($memberName), TESTSTRINGCRC()); #--------- add a file member, compressed ok(rename($memberName, TESTDIR() . '/file.txt')); $memberName = TESTDIR() . '/file.txt'; # addFile # Archive::Zip::Archive # newFromFile # Archive::Zip::Member $member = $zip->addFile($memberName); ok(defined($member)); is($member->desiredCompressionMethod(), COMPRESSION_DEFLATED); # writeToFileNamed # Archive::Zip::Archive $status = $zip->writeToFileNamed(OUTPUTZIP()); is($status, AZ_OK); is($member->crc32(), TESTSTRINGCRC()); is($member->uncompressedSize(), TESTSTRINGLENGTH()); SKIP: { skip("No 'unzip' program to test against", 1) unless HAVEUNZIP(); ($status, $zipout) = testZip(); # STDERR->print("status= $status, out=$zipout\n"); skip("test zip doesn't work", 1) if $testZipDoesntWork; is($status, 0); } #--------- extract it by name (note we have to rename it first #--------- or we will clobber the original file my $newName = $memberName; $newName =~ s/\.txt/2.txt/; $status = $zip->extractMember($memberName, $newName); is($status, AZ_OK); ok(-f $newName); is(fileCRC($newName), TESTSTRINGCRC()); #--------- now make it uncompressed and re-test #$oldCompressionMethod = $member->desiredCompressionMethod(COMPRESSION_STORED); #is($oldCompressionMethod, COMPRESSION_DEFLATED); # writeToFileNamed # Archive::Zip::Archive $status = $zip->writeToFileNamed(OUTPUTZIP()); is($status, AZ_OK); is($member->crc32(), TESTSTRINGCRC()); is($member->uncompressedSize(), TESTSTRINGLENGTH()); SKIP: { skip("No 'unzip' program to test against", 1) unless HAVEUNZIP(); ($status, $zipout) = testZip(); # STDERR->print("status= $status, out=$zipout\n"); skip("test zip doesn't work", 1) if $testZipDoesntWork; is($status, 0); } #--------- extract it by name $status = $zip->extractMember($memberName, $newName); is($status, AZ_OK); ok(-f $newName); is(fileCRC($newName), TESTSTRINGCRC()); # Now, the contents of OUTPUTZIP() are: # Length Method Size Ratio Date Time CRC-32 Name #-------- ------ ------- ----- ---- ---- ------ ---- # 0 Stored 0 0% 03-17-00 11:16 00000000 TESTDIR/ # 300 Defl:N 146 51% 03-17-00 11:16 ac373f32 TESTDIR/string.txt # 300 Stored 300 0% 03-17-00 11:16 ac373f32 TESTDIR/file.txt #-------- ------- --- ------- # 600 446 26% 3 files # members # Archive::Zip::Archive @members = $zip->members(); is(scalar(@members), 3); is_deeply([map {$_->fileName} grep { $_->fileName eq $member->fileName } @members ], [$member->fileName]) or do { diag "Have: " . $_->fileName for @members }; # memberNames # Archive::Zip::Archive my @memberNames = $zip->memberNames(); is(scalar(@memberNames), 3); is_deeply([ grep { $_ eq $member->fileName } @memberNames ], [ $member->fileName ]) or do { diag sprintf "[%s]", $member->fileName ; diag sprintf "[%s]", $_->fileName for @members }; # memberNamed # Archive::Zip::Archive is($zip->memberNamed($memberName)->fileName, $member->fileName); # membersMatching # Archive::Zip::Archive @members = $zip->membersMatching('file'); is(scalar(@members), 1); is($members[0]->fileName, $member->fileName); @members = sort { $a->fileName cmp $b->fileName } $zip->membersMatching('.txt$'); is(scalar(@members), 2); is($members[0]->fileName, $member->fileName); #--------- remove the string member and test the file # removeMember # Archive::Zip::Archive diag "Removing " . $members[0]->fileName; $member = $zip->removeMember($members[0]); is($member, $members[0]); $status = $zip->writeToFileNamed(OUTPUTZIP()); is($status, AZ_OK); SKIP: { skip("No 'unzip' program to test against", 1) unless HAVEUNZIP(); ($status, $zipout) = testZip(); # STDERR->print("status= $status, out=$zipout\n"); skip("test zip doesn't work", 1) if $testZipDoesntWork; is($status, 0); } #--------- add the string member at the end and test the file # addMember # Archive::Zip::Archive # This will never work in Archive::SevenZip, transplanting # zip entries in-memory # This also ruins all of the subsequent tests due to the weirdo # approach of not setting up a common baseline for each test # and the insistence on that the implementation maintains the # order on archive members # #$zip->addMember($member); #@members = $zip->members(); #is(scalar(@members), 3); #is($members[2], $member); # memberNames # Archive::Zip::Archive #@memberNames = $zip->memberNames(); #is(scalar(@memberNames), 3); #is($memberNames[1], $memberName); #$status = $zip->writeToFileNamed(OUTPUTZIP()); #is($status, AZ_OK); #SKIP: { # skip("No 'unzip' program to test against", 1) unless HAVEUNZIP(); # ($status, $zipout) = testZip(); # # STDERR->print("status= $status, out=$zipout\n"); # skip("test zip doesn't work", 1) if $testZipDoesntWork; # is($status, 0); #}