3 # Main testing for Archive::Zip
6 use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
11 use Test::More tests => 141;
15 require( File::Spec->catfile('t', 'common.pl') )
16 or die "Can't load t/common.pl";
23 #####################################################################
24 # Testing Utility Functions
27 is(TESTSTRINGCRC, 0xac373f32, 'Testing CRC matches expected');
32 local $Archive::Zip::ErrorHandler = sub { push @errors, @_ };
33 eval { Archive::Zip::Member::_unixToDosTime( 0 ) };
34 ok( $errors[0] =~ /Tried to add member with zero or undef/,
35 'Got expected _unixToDosTime error' );
38 #--------- check time conversion
40 foreach my $unix_time (
41 315576062, 315576064, 315580000, 315600000,
42 316000000, 320000000, 400000000, 500000000,
43 600000000, 700000000, 800000000, 900000000,
44 1000000000, 1100000000, 1200000000,
47 my $dos_time = Archive::Zip::Member::_unixToDosTime( $unix_time );
48 my $round_trip = Archive::Zip::Member::_dosToUnixTime( $dos_time );
49 is( $unix_time, $round_trip, 'Got expected DOS DateTime value' );
56 #####################################################################
61 # new # Archive::Zip::Archive
62 my $zip = Archive::Zip->new();
63 isa_ok( $zip, 'Archive::Zip' );
65 # members # Archive::Zip::Archive
66 my @members = $zip->members;
67 is(scalar(@members), 0, '->members is 0' );
69 # numberOfMembers # Archive::Zip::Archive
70 my $numberOfMembers = $zip->numberOfMembers();
71 is($numberOfMembers, 0, '->numberofMembers is 0' );
73 # writeToFileNamed # Archive::Zip::Archive
74 my $status = $zip->writeToFileNamed( OUTPUTZIP );
75 is($status, AZ_OK, '->writeToFileNames ok' );
79 skip( "No 'unzip' program to test against", 1 ) unless HAVEUNZIP;
80 if ( $^O eq 'MSWin32' ) {
81 print STDERR "\n# You might see an expected 'zipfile is empty' warning now.\n";
83 ($status, $zipout) = testZip();
84 # STDERR->print("status= $status, out=$zipout\n");
86 skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;
89 # unzip -t returns error code=1 for warning on empty
91 #--------- add a directory
92 my $memberName = TESTDIR . '/';
93 my $dirName = TESTDIR;
95 # addDirectory # Archive::Zip::Archive
96 # new # Archive::Zip::Member
97 my $member = $zip->addDirectory($memberName);
99 is($member->fileName(), $memberName);
101 # On some (Windows systems) the modification time is
102 # corrupted. Save this to check late.
103 my $dir_time = $member->lastModFileDateTime();
105 # members # Archive::Zip::Archive
106 @members = $zip->members();
107 is(scalar(@members), 1);
108 is($members[0], $member);
110 # numberOfMembers # Archive::Zip::Archive
111 $numberOfMembers = $zip->numberOfMembers();
112 is($numberOfMembers, 1);
114 # writeToFileNamed # Archive::Zip::Archive
115 $status = $zip->writeToFileNamed( OUTPUTZIP );
118 # Does the modification time get corrupted?
119 is( ($zip->members)[0]->lastModFileDateTime(), $dir_time );
122 skip( "No 'unzip' program to test against", 1 ) unless HAVEUNZIP;
123 ($status, $zipout) = testZip();
124 # STDERR->print("status= $status, out=$zipout\n");
125 skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;
129 #--------- extract the directory by name
130 rmtree([ TESTDIR ], 0, 0);
131 $status = $zip->extractMember($memberName);
135 #--------- extract the directory by identity
136 ok(rmdir($dirName)); # it's still empty
137 $status = $zip->extractMember($member);
141 #--------- add a string member, uncompressed
142 $memberName = TESTDIR . '/string.txt';
143 # addString # Archive::Zip::Archive
144 # newFromString # Archive::Zip::Member
145 $member = $zip->addString(TESTSTRING, $memberName);
146 ok(defined($member));
148 is($member->fileName(), $memberName);
150 # members # Archive::Zip::Archive
151 @members = $zip->members();
152 is(scalar(@members), 2);
153 is($members[1], $member);
155 # numberOfMembers # Archive::Zip::Archive
156 $numberOfMembers = $zip->numberOfMembers();
157 is($numberOfMembers, 2);
159 # writeToFileNamed # Archive::Zip::Archive
160 $status = $zip->writeToFileNamed( OUTPUTZIP );
164 skip( "No 'unzip' program to test against", 1 ) unless HAVEUNZIP;
165 ($status, $zipout) = testZip();
166 # STDERR->print("status= $status, out=$zipout\n");
167 skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;
171 is($member->crc32(), TESTSTRINGCRC);
173 is($member->crc32String(), sprintf("%08x", TESTSTRINGCRC));
175 #--------- extract it by name
176 $status = $zip->extractMember($memberName);
179 is(fileCRC($memberName), TESTSTRINGCRC);
181 #--------- now compress it and re-test
182 my $oldCompressionMethod =
183 $member->desiredCompressionMethod(COMPRESSION_DEFLATED);
184 is($oldCompressionMethod, COMPRESSION_STORED, 'old compression method OK');
186 # writeToFileNamed # Archive::Zip::Archive
187 $status = $zip->writeToFileNamed( OUTPUTZIP );
188 is($status, AZ_OK, 'writeToFileNamed returns AZ_OK');
189 is($member->crc32(), TESTSTRINGCRC);
190 is($member->uncompressedSize(), TESTSTRINGLENGTH);
193 skip( "No 'unzip' program to test against", 1 ) unless HAVEUNZIP;
194 ($status, $zipout) = testZip();
195 # STDERR->print("status= $status, out=$zipout\n");
196 skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;
200 #--------- extract it by name
201 $status = $zip->extractMember($memberName);
204 is(fileCRC($memberName), TESTSTRINGCRC);
206 #--------- add a file member, compressed
207 ok(rename($memberName, TESTDIR . '/file.txt'));
208 $memberName = TESTDIR . '/file.txt';
210 # addFile # Archive::Zip::Archive
211 # newFromFile # Archive::Zip::Member
212 $member = $zip->addFile($memberName);
213 ok(defined($member));
215 is($member->desiredCompressionMethod(), COMPRESSION_DEFLATED);
217 # writeToFileNamed # Archive::Zip::Archive
218 $status = $zip->writeToFileNamed( OUTPUTZIP );
220 is($member->crc32(), TESTSTRINGCRC);
221 is($member->uncompressedSize(), TESTSTRINGLENGTH);
224 skip( "No 'unzip' program to test against", 1 ) unless HAVEUNZIP;
225 ($status, $zipout) = testZip();
226 # STDERR->print("status= $status, out=$zipout\n");
227 skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;
231 #--------- extract it by name (note we have to rename it first
232 #--------- or we will clobber the original file
233 my $newName = $memberName;
234 $newName =~ s/\.txt/2.txt/;
235 $status = $zip->extractMember($memberName, $newName);
238 is(fileCRC($newName), TESTSTRINGCRC);
240 #--------- now make it uncompressed and re-test
241 $oldCompressionMethod =
242 $member->desiredCompressionMethod(COMPRESSION_STORED);
244 is($oldCompressionMethod, COMPRESSION_DEFLATED);
246 # writeToFileNamed # Archive::Zip::Archive
247 $status = $zip->writeToFileNamed( OUTPUTZIP );
249 is($member->crc32(), TESTSTRINGCRC);
250 is($member->uncompressedSize(), TESTSTRINGLENGTH);
253 skip( "No 'unzip' program to test against", 1 ) unless HAVEUNZIP;
254 ($status, $zipout) = testZip();
255 # STDERR->print("status= $status, out=$zipout\n");
256 skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;
260 #--------- extract it by name
261 $status = $zip->extractMember($memberName, $newName);
264 is(fileCRC($newName), TESTSTRINGCRC);
266 # Now, the contents of OUTPUTZIP are:
267 # Length Method Size Ratio Date Time CRC-32 Name
268 #-------- ------ ------- ----- ---- ---- ------ ----
269 # 0 Stored 0 0% 03-17-00 11:16 00000000 testDir/
270 # 300 Defl:N 146 51% 03-17-00 11:16 ac373f32 testDir/string.txt
271 # 300 Stored 300 0% 03-17-00 11:16 ac373f32 testDir/file.txt
272 #-------- ------- --- -------
273 # 600 446 26% 3 files
275 # members # Archive::Zip::Archive
276 @members = $zip->members();
277 is(scalar(@members), 3);
278 is($members[2], $member);
280 # memberNames # Archive::Zip::Archive
281 my @memberNames = $zip->memberNames();
282 is(scalar(@memberNames), 3);
283 is($memberNames[2], $memberName);
285 # memberNamed # Archive::Zip::Archive
286 is($zip->memberNamed($memberName), $member);
288 # membersMatching # Archive::Zip::Archive
289 @members = $zip->membersMatching('file');
290 is(scalar(@members), 1);
291 is($members[0], $member);
293 @members = $zip->membersMatching('.txt$');
294 is(scalar(@members), 2);
295 is($members[1], $member);
297 #--------- remove the string member and test the file
298 # removeMember # Archive::Zip::Archive
299 $member = $zip->removeMember($members[0]);
300 is($member, $members[0]);
302 $status = $zip->writeToFileNamed( OUTPUTZIP );
306 skip( "No 'unzip' program to test against", 1 ) unless HAVEUNZIP;
307 ($status, $zipout) = testZip();
308 # STDERR->print("status= $status, out=$zipout\n");
309 skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;
313 #--------- add the string member at the end and test the file
314 # addMember # Archive::Zip::Archive
315 $zip->addMember($member);
316 @members = $zip->members();
318 is(scalar(@members), 3);
319 is($members[2], $member);
321 # memberNames # Archive::Zip::Archive
322 @memberNames = $zip->memberNames();
323 is(scalar(@memberNames), 3);
324 is($memberNames[1], $memberName);
326 $status = $zip->writeToFileNamed( OUTPUTZIP );
330 skip( "No 'unzip' program to test against", 1 ) unless HAVEUNZIP;
331 ($status, $zipout) = testZip();
332 # STDERR->print("status= $status, out=$zipout\n");
333 skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;
337 #--------- remove the file member
338 $member = $zip->removeMember($members[1]);
339 is($member, $members[1]);
340 is($zip->numberOfMembers(), 2);
342 #--------- replace the string member with the file member
343 # replaceMember # Archive::Zip::Archive
344 $member = $zip->replaceMember($members[2], $member);
345 is($member, $members[2]);
346 is($zip->numberOfMembers(), 2);
348 #--------- re-add the string member
349 $zip->addMember($member);
350 is($zip->numberOfMembers(), 3);
352 @members = $zip->members();
353 $status = $zip->writeToFileNamed( OUTPUTZIP );
357 skip( "No 'unzip' program to test against", 1 ) unless HAVEUNZIP;
358 ($status, $zipout) = testZip();
359 # STDERR->print("status= $status, out=$zipout\n");
360 skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;
364 #--------- add compressed file
365 $member = $zip->addFile(File::Spec->catfile(TESTDIR, 'file.txt'));
366 ok(defined($member));
367 $member->desiredCompressionMethod(COMPRESSION_DEFLATED);
368 $member->fileName(TESTDIR . '/fileC.txt');
370 #--------- add uncompressed string
371 $member = $zip->addString(TESTSTRING, TESTDIR . '/stringU.txt');
372 ok(defined($member));
373 $member->desiredCompressionMethod(COMPRESSION_STORED);
375 # Now, the file looks like this:
376 # Length Method Size Ratio Date Time CRC-32 Name
377 #-------- ------ ------- ----- ---- ---- ------ ----
378 # 0 Stored 0 0% 03-17-00 12:30 00000000 testDir/
379 # 300 Stored 300 0% 03-17-00 12:30 ac373f32 testDir/file.txt
380 # 300 Defl:N 146 51% 03-17-00 12:30 ac373f32 testDir/string.txt
381 # 300 Stored 300 0% 03-17-00 12:30 ac373f32 testDir/stringU.txt
382 # 300 Defl:N 146 51% 03-17-00 12:30 ac373f32 testDir/fileC.txt
383 #-------- ------- --- -------
384 # 1200 892 26% 5 files
386 @members = $zip->members();
387 $numberOfMembers = $zip->numberOfMembers();
388 is($numberOfMembers, 5);
390 #--------- make sure the contents of the stored file member are OK.
391 # contents # Archive::Zip::Archive
392 is($zip->contents($members[1]), TESTSTRING);
394 # contents # Archive::Zip::Member
395 is($members[1]->contents(), TESTSTRING);
397 #--------- make sure the contents of the compressed string member are OK.
398 is($members[2]->contents(), TESTSTRING);
400 #--------- make sure the contents of the stored string member are OK.
401 is($members[3]->contents(), TESTSTRING);
403 #--------- make sure the contents of the compressed file member are OK.
404 is($members[4]->contents(), TESTSTRING);
406 #--------- write to INPUTZIP
407 $status = $zip->writeToFileNamed( INPUTZIP );
411 skip( "No 'unzip' program to test against", 1 ) unless HAVEUNZIP;
412 ($status, $zipout) = testZip(INPUTZIP);
413 # STDERR->print("status= $status, out=$zipout\n");
414 skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;
418 #--------- read from INPUTZIP (appending its entries)
419 # read # Archive::Zip::Archive
420 $status = $zip->read(INPUTZIP);
422 is($zip->numberOfMembers(), 10);
424 #--------- clean up duplicate names
425 @members = $zip->members();
426 $member = $zip->removeMember($members[5]);
427 is($member->fileName(), TESTDIR . '/');
432 $memberName = $members[$i]->fileName();
433 $memberName =~ s/\.txt/2.txt/;
434 $members[$i]->fileName($memberName);
437 is(scalar($zip->membersMatching('2.txt')), 4);
439 #--------- write zip out and test it.
440 $status = $zip->writeToFileNamed( OUTPUTZIP );
444 skip( "No 'unzip' program to test against", 1 ) unless HAVEUNZIP;
445 ($status, $zipout) = testZip();
446 # STDERR->print("status= $status, out=$zipout\n");
447 skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;
451 #--------- Make sure that we haven't renamed files (this happened!)
452 is(scalar($zip->membersMatching('2\.txt$')), 4);
454 #--------- Now try extracting everyone
455 @members = $zip->members();
456 is($zip->extractMember($members[0]), AZ_OK); #DM
457 is($zip->extractMember($members[1]), AZ_OK); #NFM
458 is($zip->extractMember($members[2]), AZ_OK);
459 is($zip->extractMember($members[3]), AZ_OK); #NFM
460 is($zip->extractMember($members[4]), AZ_OK);
461 is($zip->extractMember($members[5]), AZ_OK);
462 is($zip->extractMember($members[6]), AZ_OK);
463 is($zip->extractMember($members[7]), AZ_OK);
464 is($zip->extractMember($members[8]), AZ_OK);
466 #--------- count dirs
468 my @dirs = grep { $_->isDirectory() } @members;
469 is(scalar(@dirs), 1);
470 is($dirs[0], $members[0]);
473 #--------- count binary and text files
475 my @binaryFiles = grep { $_->isBinaryFile() } @members;
476 my @textFiles = grep { $_->isTextFile() } @members;
477 is(scalar(@binaryFiles), 5);
478 is(scalar(@textFiles), 4);
481 #--------- Try writing zip file to file handle
487 $fh = FileHandle->new( CATPIPE . OUTPUTZIP );
491 skip('cat does not work on this platform', 1) unless $catWorks;
494 # $status = $zip->writeToFileHandle($fh, 0) if ($catWorks);
495 $status = $zip->writeToFileHandle($fh) if ($catWorks);
497 skip('cat does not work on this platform', 1) unless $catWorks;
498 is( $status, AZ_OK );
500 $fh->close() if ($catWorks);
502 skip( "No 'unzip' program to test against", 1 ) unless HAVEUNZIP;
503 ($status, $zipout) = testZip();
508 #--------- Change the contents of a string member
509 is(ref($members[2]), 'Archive::Zip::StringMember');
510 $members[2]->contents( "This is my new contents\n" );
512 #--------- write zip out and test it.
513 $status = $zip->writeToFileNamed( OUTPUTZIP );
517 skip( "No 'unzip' program to test against", 1 ) unless HAVEUNZIP;
518 ($status, $zipout) = testZip();
519 # STDERR->print("status= $status, out=$zipout\n");
520 skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;
524 #--------- Change the contents of a file member
525 is(ref($members[1]), 'Archive::Zip::NewFileMember');
526 $members[1]->contents( "This is my new contents\n" );
528 #--------- write zip out and test it.
529 $status = $zip->writeToFileNamed( OUTPUTZIP );
533 skip( "No 'unzip' program to test against", 1 ) unless HAVEUNZIP;
534 ($status, $zipout) = testZip();
535 # STDERR->print("status= $status, out=$zipout\n");
536 skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;
540 #--------- Change the contents of a zip member
542 is(ref($members[7]), 'Archive::Zip::ZipFileMember');
543 $members[7]->contents( "This is my new contents\n" );
545 #--------- write zip out and test it.
546 $status = $zip->writeToFileNamed( OUTPUTZIP );
550 skip( "No 'unzip' program to test against", 1 ) unless HAVEUNZIP;
551 ($status, $zipout) = testZip();
552 # STDERR->print("status= $status, out=$zipout\n");
553 skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;
558 #--------- now clean up
559 # END { system("rm -rf " . TESTDIR . " " . OUTPUTZIP . " " . INPUTZIP) }
561 #--------------------- STILL UNTESTED IN THIS SCRIPT ---------------------
563 # sub setChunkSize # Archive::Zip
564 # sub _formatError # Archive::Zip
565 # sub _error # Archive::Zip
566 # sub _subclassResponsibility # Archive::Zip
567 # sub diskNumber # Archive::Zip::Archive
568 # sub diskNumberWithStartOfCentralDirectory # Archive::Zip::Archive
569 # sub numberOfCentralDirectoriesOnThisDisk # Archive::Zip::Archive
570 # sub numberOfCentralDirectories # Archive::Zip::Archive
571 # sub centralDirectoryOffsetWRTStartingDiskNumber # Archive::Zip::Archive
572 # sub extraField # Archive::Zip::Member
573 # sub isEncrypted # Archive::Zip::Member
574 # sub isTextFile # Archive::Zip::Member
575 # sub isBinaryFile # Archive::Zip::Member
576 # sub isDirectory # Archive::Zip::Member
577 # sub lastModTime # Archive::Zip::Member
578 # sub _writeDataDescriptor # Archive::Zip::Member
579 # sub isDirectory # Archive::Zip::DirectoryMember
580 # sub _becomeDirectory # Archive::Zip::DirectoryMember
581 # sub diskNumberStart # Archive::Zip::ZipFileMember