summaryrefslogtreecommitdiff
path: root/t/02_main.t
diff options
context:
space:
mode:
Diffstat (limited to 't/02_main.t')
-rw-r--r--t/02_main.t592
1 files changed, 592 insertions, 0 deletions
diff --git a/t/02_main.t b/t/02_main.t
new file mode 100644
index 0000000..dc7ad17
--- /dev/null
+++ b/t/02_main.t
@@ -0,0 +1,592 @@
+#!/usr/bin/perl
+
+# Main testing for Archive::Zip
+
+use strict;
+
+BEGIN {
+ $| = 1;
+ $^W = 1;
+}
+
+use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
+use FileHandle;
+use File::Path;
+use File::Spec;
+
+use Test::More tests => 141;
+
+use t::common;
+
+#####################################################################
+# 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
+
+#--------- empty file
+# new # Archive::Zip
+# new # Archive::Zip::Archive
+my $zip = Archive::Zip->new();
+isa_ok($zip, 'Archive::Zip');
+
+# 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], $member);
+
+# 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], $member);
+
+# 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($members[2], $member);
+
+# memberNames # Archive::Zip::Archive
+my @memberNames = $zip->memberNames();
+is(scalar(@memberNames), 3);
+is($memberNames[2], $memberName);
+
+# memberNamed # Archive::Zip::Archive
+is($zip->memberNamed($memberName), $member);
+
+# membersMatching # Archive::Zip::Archive
+@members = $zip->membersMatching('file');
+is(scalar(@members), 1);
+is($members[0], $member);
+
+@members = $zip->membersMatching('.txt$');
+is(scalar(@members), 2);
+is($members[1], $member);
+
+#--------- remove the string member and test the file
+# removeMember # Archive::Zip::Archive
+$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
+$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);
+}
+
+#--------- remove the file member
+$member = $zip->removeMember($members[1]);
+is($member, $members[1]);
+is($zip->numberOfMembers(), 2);
+
+#--------- replace the string member with the file member
+# replaceMember # Archive::Zip::Archive
+$member = $zip->replaceMember($members[2], $member);
+is($member, $members[2]);
+is($zip->numberOfMembers(), 2);
+
+#--------- re-add the string member
+$zip->addMember($member);
+is($zip->numberOfMembers(), 3);
+
+@members = $zip->members();
+$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 compressed file
+$member = $zip->addFile(File::Spec->catfile(TESTDIR, 'file.txt'));
+ok(defined($member));
+$member->desiredCompressionMethod(COMPRESSION_DEFLATED);
+$member->fileName(TESTDIR . '/fileC.txt');
+
+#--------- add uncompressed string
+$member = $zip->addString(TESTSTRING, TESTDIR . '/stringU.txt');
+ok(defined($member));
+$member->desiredCompressionMethod(COMPRESSION_STORED);
+
+# Now, the file looks like this:
+# Length Method Size Ratio Date Time CRC-32 Name
+#-------- ------ ------- ----- ---- ---- ------ ----
+# 0 Stored 0 0% 03-17-00 12:30 00000000 testDir/
+# 300 Stored 300 0% 03-17-00 12:30 ac373f32 testDir/file.txt
+# 300 Defl:N 146 51% 03-17-00 12:30 ac373f32 testDir/string.txt
+# 300 Stored 300 0% 03-17-00 12:30 ac373f32 testDir/stringU.txt
+# 300 Defl:N 146 51% 03-17-00 12:30 ac373f32 testDir/fileC.txt
+#-------- ------- --- -------
+# 1200 892 26% 5 files
+
+@members = $zip->members();
+$numberOfMembers = $zip->numberOfMembers();
+is($numberOfMembers, 5);
+
+#--------- make sure the contents of the stored file member are OK.
+# contents # Archive::Zip::Archive
+is($zip->contents($members[1]), TESTSTRING);
+
+# contents # Archive::Zip::Member
+is($members[1]->contents(), TESTSTRING);
+
+#--------- make sure the contents of the compressed string member are OK.
+is($members[2]->contents(), TESTSTRING);
+
+#--------- make sure the contents of the stored string member are OK.
+is($members[3]->contents(), TESTSTRING);
+
+#--------- make sure the contents of the compressed file member are OK.
+is($members[4]->contents(), TESTSTRING);
+
+#--------- write to INPUTZIP
+$status = $zip->writeToFileNamed(INPUTZIP);
+is($status, AZ_OK);
+
+SKIP: {
+ skip("No 'unzip' program to test against", 1) unless HAVEUNZIP;
+ ($status, $zipout) = testZip(INPUTZIP);
+
+ # STDERR->print("status= $status, out=$zipout\n");
+ skip("test zip doesn't work", 1) if $testZipDoesntWork;
+ is($status, 0);
+}
+
+#--------- read from INPUTZIP (appending its entries)
+# read # Archive::Zip::Archive
+$status = $zip->read(INPUTZIP);
+is($status, AZ_OK);
+is($zip->numberOfMembers(), 10);
+
+#--------- clean up duplicate names
+@members = $zip->members();
+$member = $zip->removeMember($members[5]);
+is($member->fileName(), TESTDIR . '/');
+
+SCOPE: {
+ for my $i (6 .. 9) {
+ $memberName = $members[$i]->fileName();
+ $memberName =~ s/\.txt/2.txt/;
+ $members[$i]->fileName($memberName);
+ }
+}
+is(scalar($zip->membersMatching('2.txt')), 4);
+
+#--------- write zip out and test it.
+$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);
+}
+
+#--------- Make sure that we haven't renamed files (this happened!)
+is(scalar($zip->membersMatching('2\.txt$')), 4);
+
+#--------- Now try extracting everyone
+@members = $zip->members();
+is($zip->extractMember($members[0]), AZ_OK); #DM
+is($zip->extractMember($members[1]), AZ_OK); #NFM
+is($zip->extractMember($members[2]), AZ_OK);
+is($zip->extractMember($members[3]), AZ_OK); #NFM
+is($zip->extractMember($members[4]), AZ_OK);
+is($zip->extractMember($members[5]), AZ_OK);
+is($zip->extractMember($members[6]), AZ_OK);
+is($zip->extractMember($members[7]), AZ_OK);
+is($zip->extractMember($members[8]), AZ_OK);
+
+#--------- count dirs
+{
+ my @dirs = grep { $_->isDirectory() } @members;
+ is(scalar(@dirs), 1);
+ is($dirs[0], $members[0]);
+}
+
+#--------- count binary and text files
+{
+ my @binaryFiles = grep { $_->isBinaryFile() } @members;
+ my @textFiles = grep { $_->isTextFile() } @members;
+ is(scalar(@binaryFiles), 5);
+ is(scalar(@textFiles), 4);
+}
+
+#--------- Try writing zip file to file handle
+{
+ my $fh;
+ if ($catWorks) {
+ unlink(OUTPUTZIP);
+ $fh = FileHandle->new(CATPIPE . OUTPUTZIP);
+ binmode($fh);
+ }
+ SKIP: {
+ skip('cat does not work on this platform', 1) unless $catWorks;
+ ok($fh);
+ }
+
+ # $status = $zip->writeToFileHandle($fh, 0) if ($catWorks);
+ $status = $zip->writeToFileHandle($fh) if ($catWorks);
+ SKIP: {
+ skip('cat does not work on this platform', 1) unless $catWorks;
+ is($status, AZ_OK);
+ }
+ $fh->close() if ($catWorks);
+ SKIP: {
+ skip("No 'unzip' program to test against", 1) unless HAVEUNZIP;
+ ($status, $zipout) = testZip();
+ is($status, 0);
+ }
+}
+
+#--------- Change the contents of a string member
+is(ref($members[2]), 'Archive::Zip::StringMember');
+$members[2]->contents("This is my new contents\n");
+
+#--------- write zip out and test it.
+$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);
+}
+
+#--------- Change the contents of a file member
+is(ref($members[1]), 'Archive::Zip::NewFileMember');
+$members[1]->contents("This is my new contents\n");
+
+#--------- write zip out and test it.
+$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);
+}
+
+#--------- Change the contents of a zip member
+
+is(ref($members[7]), 'Archive::Zip::ZipFileMember');
+$members[7]->contents("This is my new contents\n");
+
+#--------- write zip out and test it.
+$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);
+}
+
+#--------- now clean up
+# END { system("rm -rf " . TESTDIR . " " . OUTPUTZIP . " " . INPUTZIP) }
+
+#--------------------- STILL UNTESTED IN THIS SCRIPT ---------------------
+
+# sub setChunkSize # Archive::Zip
+# sub _formatError # Archive::Zip
+# sub _error # Archive::Zip
+# sub _subclassResponsibility # Archive::Zip
+# sub diskNumber # Archive::Zip::Archive
+# sub diskNumberWithStartOfCentralDirectory # Archive::Zip::Archive
+# sub numberOfCentralDirectoriesOnThisDisk # Archive::Zip::Archive
+# sub numberOfCentralDirectories # Archive::Zip::Archive
+# sub centralDirectoryOffsetWRTStartingDiskNumber # Archive::Zip::Archive
+# sub extraField # Archive::Zip::Member
+# sub isEncrypted # Archive::Zip::Member
+# sub isTextFile # Archive::Zip::Member
+# sub isBinaryFile # Archive::Zip::Member
+# sub isDirectory # Archive::Zip::Member
+# sub lastModTime # Archive::Zip::Member
+# sub _writeDataDescriptor # Archive::Zip::Member
+# sub isDirectory # Archive::Zip::DirectoryMember
+# sub _becomeDirectory # Archive::Zip::DirectoryMember
+# sub diskNumberStart # Archive::Zip::ZipFileMember