Finishing 02_main.t
[archive-zip.git] / t / 02_main.t
blobfed6cff0bf01ed2431b5e9d4aa0ab451c5d6e7a0
1 #!perl -w\r
2 # vim: ts=4 sw=4 ft=perl\r
3 \r
4 $^W = 1;\r
5 use strict;\r
6 use Archive::Zip qw( :ERROR_CODES :CONSTANTS );\r
7 use FileHandle;\r
8 use File::Path;\r
9 use File::Spec;\r
11 use Test::More tests => 141;\r
13 BEGIN {\r
14     unshift @INC, "t/"; \r
15     require( File::Spec->catfile('t', 'common.pl') )\r
16                 or die "Can't get t/common.pl";\r
17 }\r
23 #####################################################################\r
24 # Testing Utility Functions\r
26 #--------- check CRC\r
27 is(TESTSTRINGCRC, 0xac373f32, 'Testing CRC matches expected');\r
29 # Bad times die\r
30 SCOPE: {\r
31         my @errors = ();\r
32         local $Archive::Zip::ErrorHandler = sub { push @errors, @_ };\r
33         eval { Archive::Zip::Member::_unixToDosTime( 0 ) };\r
34         ok( $errors[0] =~ /Tried to add member with zero or undef/,\r
35                 'Got expected _unixToDosTime error' );\r
36 }\r
38 #--------- check time conversion\r
40 foreach my $unix_time (\r
41         315576062, 315576064, 315580000, 315600000,\r
42         316000000, 320000000, 400000000, 500000000,\r
43         600000000, 700000000, 800000000, 900000000,\r
44         1000000000, 1100000000, 1200000000,\r
45         int(time()/2)*2,\r
46 ) {\r
47         my $dos_time   = Archive::Zip::Member::_unixToDosTime( $unix_time );\r
48         my $round_trip = Archive::Zip::Member::_dosToUnixTime( $dos_time  );\r
49         is( $unix_time, $round_trip, 'Got expected DOS DateTime value' );\r
50 }\r
56 #####################################################################\r
57 # Testing Archives\r
59 #--------- empty file\r
60 # new   # Archive::Zip\r
61 # new   # Archive::Zip::Archive\r
62 my $zip = Archive::Zip->new();\r
63 isa_ok( $zip, 'Archive::Zip' );\r
65 # members       # Archive::Zip::Archive\r
66 my @members = $zip->members;\r
67 is(scalar(@members), 0, '->members is 0' );\r
69 # numberOfMembers       # Archive::Zip::Archive\r
70 my $numberOfMembers = $zip->numberOfMembers();\r
71 is($numberOfMembers, 0, '->numberofMembers is 0' );\r
73 # writeToFileNamed      # Archive::Zip::Archive\r
74 my $status = $zip->writeToFileNamed( OUTPUTZIP );\r
75 is($status, AZ_OK, '->writeToFileNames ok' );\r
77 if ( $^O eq 'MSWin32' ) {\r
78         print STDERR "\n# You might see an expected 'zipfile is empty' warning now.\n";\r
79 }\r
80 my $zipout;\r
81 ($status, $zipout) = testZip();\r
82 # STDERR->print("status= $status, out=$zipout\n");\r
83 SKIP: {\r
84         skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;\r
85         ok( $status != 0 );\r
86 }\r
87 # unzip -t returns error code=1 for warning on empty\r
89 #--------- add a directory\r
90 my $memberName = TESTDIR . '/';\r
91 my $dirName = TESTDIR;\r
93 # addDirectory  # Archive::Zip::Archive\r
94 # new   # Archive::Zip::Member\r
95 my $member = $zip->addDirectory($memberName);\r
96 ok(defined($member));\r
97 is($member->fileName(), $memberName);\r
99 # On some (Windows systems) the modification time is\r
100 # corrupted. Save this to check late.\r
101 my $dir_time = $member->lastModFileDateTime();\r
103 # members       # Archive::Zip::Archive\r
104 @members = $zip->members();\r
105 is(scalar(@members), 1);\r
106 is($members[0], $member);\r
108 # numberOfMembers       # Archive::Zip::Archive\r
109 $numberOfMembers = $zip->numberOfMembers();\r
110 is($numberOfMembers, 1);\r
112 # writeToFileNamed      # Archive::Zip::Archive\r
113 $status = $zip->writeToFileNamed( OUTPUTZIP );\r
114 is($status, AZ_OK);\r
116 # Does the modification time get corrupted?\r
117 is( ($zip->members)[0]->lastModFileDateTime(), $dir_time );\r
119 ($status, $zipout) = testZip();\r
120 # STDERR->print("status= $status, out=$zipout\n");\r
121 SKIP: {\r
122         skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;\r
123         is( $status, 0 );\r
126 #--------- extract the directory by name\r
127 rmtree([ TESTDIR ], 0, 0);\r
128 $status = $zip->extractMember($memberName);\r
129 is($status, AZ_OK);\r
130 ok(-d $dirName);\r
132 #--------- extract the directory by identity\r
133 ok(rmdir($dirName));    # it's still empty\r
134 $status = $zip->extractMember($member);\r
135 is($status, AZ_OK);\r
136 ok(-d $dirName);\r
138 #--------- add a string member, uncompressed\r
139 $memberName = TESTDIR . '/string.txt';\r
140 # addString     # Archive::Zip::Archive\r
141 # newFromString # Archive::Zip::Member\r
142 $member = $zip->addString(TESTSTRING, $memberName);\r
143 ok(defined($member));\r
145 is($member->fileName(), $memberName);\r
147 # members       # Archive::Zip::Archive\r
148 @members = $zip->members();\r
149 is(scalar(@members), 2);\r
150 is($members[1], $member);\r
152 # numberOfMembers       # Archive::Zip::Archive\r
153 $numberOfMembers = $zip->numberOfMembers();\r
154 is($numberOfMembers, 2);\r
156 # writeToFileNamed      # Archive::Zip::Archive\r
157 $status = $zip->writeToFileNamed( OUTPUTZIP );\r
158 is($status, AZ_OK);\r
160 ($status, $zipout) = testZip();\r
161 # STDERR->print("status= $status, out=$zipout\n");\r
162 SKIP: {\r
163         skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;\r
164         is( $status, 0 );\r
167 is($member->crc32(), TESTSTRINGCRC);\r
169 is($member->crc32String(), sprintf("%08x", TESTSTRINGCRC));\r
171 #--------- extract it by name\r
172 $status = $zip->extractMember($memberName);\r
173 is($status, AZ_OK);\r
174 ok(-f $memberName);\r
175 is(fileCRC($memberName), TESTSTRINGCRC);\r
177 #--------- now compress it and re-test\r
178 my $oldCompressionMethod = \r
179         $member->desiredCompressionMethod(COMPRESSION_DEFLATED);\r
180 is($oldCompressionMethod, COMPRESSION_STORED, 'old compression method OK');\r
182 # writeToFileNamed      # Archive::Zip::Archive\r
183 $status = $zip->writeToFileNamed( OUTPUTZIP );\r
184 is($status, AZ_OK, 'writeToFileNamed returns AZ_OK');\r
185 is($member->crc32(), TESTSTRINGCRC);\r
186 is($member->uncompressedSize(), TESTSTRINGLENGTH);\r
188 ($status, $zipout) = testZip();\r
189 # STDERR->print("status= $status, out=$zipout\n");\r
190 SKIP: {\r
191         skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;\r
192         is( $status, 0 );\r
195 #--------- extract it by name\r
196 $status = $zip->extractMember($memberName);\r
197 is($status, AZ_OK);\r
198 ok(-f $memberName);\r
199 is(fileCRC($memberName), TESTSTRINGCRC);\r
201 #--------- add a file member, compressed\r
202 ok(rename($memberName, TESTDIR . '/file.txt'));\r
203 $memberName = TESTDIR . '/file.txt';\r
205 # addFile       # Archive::Zip::Archive\r
206 # newFromFile   # Archive::Zip::Member\r
207 $member = $zip->addFile($memberName);\r
208 ok(defined($member));\r
210 is($member->desiredCompressionMethod(), COMPRESSION_DEFLATED);\r
212 # writeToFileNamed      # Archive::Zip::Archive\r
213 $status = $zip->writeToFileNamed( OUTPUTZIP );\r
214 is($status, AZ_OK);\r
215 is($member->crc32(), TESTSTRINGCRC);\r
216 is($member->uncompressedSize(), TESTSTRINGLENGTH);\r
218 ($status, $zipout) = testZip();\r
219 # STDERR->print("status= $status, out=$zipout\n");\r
220 SKIP: {\r
221         skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;\r
222         is( $status, 0 );\r
225 #--------- extract it by name (note we have to rename it first\r
226 #--------- or we will clobber the original file\r
227 my $newName = $memberName;\r
228 $newName =~ s/\.txt/2.txt/;\r
229 $status = $zip->extractMember($memberName, $newName);\r
230 is($status, AZ_OK);\r
231 ok(-f $newName);\r
232 is(fileCRC($newName), TESTSTRINGCRC);\r
234 #--------- now make it uncompressed and re-test\r
235 $oldCompressionMethod =\r
236         $member->desiredCompressionMethod(COMPRESSION_STORED);\r
238 is($oldCompressionMethod, COMPRESSION_DEFLATED);\r
240 # writeToFileNamed      # Archive::Zip::Archive\r
241 $status = $zip->writeToFileNamed( OUTPUTZIP );\r
242 is($status, AZ_OK);\r
243 is($member->crc32(), TESTSTRINGCRC);\r
244 is($member->uncompressedSize(), TESTSTRINGLENGTH);\r
246 ($status, $zipout) = testZip();\r
247 # STDERR->print("status= $status, out=$zipout\n");\r
248 SKIP: {\r
249         skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;\r
250         is( $status, 0 );\r
253 #--------- extract it by name\r
254 $status = $zip->extractMember($memberName, $newName);\r
255 is($status, AZ_OK);\r
256 ok(-f $newName);\r
257 is(fileCRC($newName), TESTSTRINGCRC);\r
259 # Now, the contents of OUTPUTZIP are:\r
260 # Length   Method    Size  Ratio   Date   Time   CRC-32    Name\r
261 #--------  ------  ------- -----   ----   ----   ------    ----\r
262 #       0  Stored        0   0%  03-17-00 11:16  00000000  testDir/\r
263 #     300  Defl:N      146  51%  03-17-00 11:16  ac373f32  testDir/string.txt\r
264 #     300  Stored      300   0%  03-17-00 11:16  ac373f32  testDir/file.txt\r
265 #--------          -------  ---                            -------\r
266 #     600              446  26%                            3 files\r
268 # members       # Archive::Zip::Archive\r
269 @members = $zip->members();\r
270 is(scalar(@members), 3);\r
271 is($members[2], $member);\r
273 # memberNames   # Archive::Zip::Archive\r
274 my @memberNames = $zip->memberNames();\r
275 is(scalar(@memberNames), 3);\r
276 is($memberNames[2], $memberName);\r
278 # memberNamed   # Archive::Zip::Archive\r
279 is($zip->memberNamed($memberName), $member);\r
281 # membersMatching       # Archive::Zip::Archive\r
282 @members = $zip->membersMatching('file');\r
283 is(scalar(@members), 1);\r
284 is($members[0], $member);\r
286 @members = $zip->membersMatching('.txt$');\r
287 is(scalar(@members), 2);\r
288 is($members[1], $member);\r
290 #--------- remove the string member and test the file\r
291 # removeMember  # Archive::Zip::Archive\r
292 $member = $zip->removeMember($members[0]);\r
293 is($member, $members[0]);\r
295 $status = $zip->writeToFileNamed( OUTPUTZIP );\r
296 is($status, AZ_OK);\r
298 ($status, $zipout) = testZip();\r
299 # STDERR->print("status= $status, out=$zipout\n");\r
300 SKIP: {\r
301         skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;\r
302         is( $status, 0 );\r
305 #--------- add the string member at the end and test the file\r
306 # addMember     # Archive::Zip::Archive\r
307 $zip->addMember($member);\r
308 @members = $zip->members();\r
310 is(scalar(@members), 3);\r
311 is($members[2], $member);\r
313 # memberNames   # Archive::Zip::Archive\r
314 @memberNames = $zip->memberNames();\r
315 is(scalar(@memberNames), 3);\r
316 is($memberNames[1], $memberName);\r
318 $status = $zip->writeToFileNamed( OUTPUTZIP );\r
319 is($status, AZ_OK);\r
321 ($status, $zipout) = testZip();\r
322 # STDERR->print("status= $status, out=$zipout\n");\r
323 SKIP: {\r
324         skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;\r
325         is( $status, 0 );\r
328 #--------- remove the file member\r
329 $member = $zip->removeMember($members[1]);\r
330 is($member, $members[1]);\r
331 is($zip->numberOfMembers(), 2);\r
333 #--------- replace the string member with the file member\r
334 # replaceMember # Archive::Zip::Archive\r
335 $member = $zip->replaceMember($members[2], $member);\r
336 is($member, $members[2]);\r
337 is($zip->numberOfMembers(), 2);\r
339 #--------- re-add the string member\r
340 $zip->addMember($member);\r
341 is($zip->numberOfMembers(), 3);\r
343 @members = $zip->members();\r
344 $status = $zip->writeToFileNamed( OUTPUTZIP );\r
345 is($status, AZ_OK);\r
347 ($status, $zipout) = testZip();\r
348 # STDERR->print("status= $status, out=$zipout\n");\r
349 SKIP: {\r
350         skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;\r
351         is( $status, 0 );\r
354 #--------- add compressed file\r
355 $member = $zip->addFile(File::Spec->catfile(TESTDIR, 'file.txt'));\r
356 ok(defined($member));\r
357 $member->desiredCompressionMethod(COMPRESSION_DEFLATED);\r
358 $member->fileName(TESTDIR . '/fileC.txt');\r
360 #--------- add uncompressed string\r
361 $member = $zip->addString(TESTSTRING, TESTDIR . '/stringU.txt');\r
362 ok(defined($member));\r
363 $member->desiredCompressionMethod(COMPRESSION_STORED);\r
365 # Now, the file looks like this:\r
366 # Length   Method    Size  Ratio   Date   Time   CRC-32    Name\r
367 #--------  ------  ------- -----   ----   ----   ------    ----\r
368 #       0  Stored        0   0%  03-17-00 12:30  00000000  testDir/\r
369 #     300  Stored      300   0%  03-17-00 12:30  ac373f32  testDir/file.txt\r
370 #     300  Defl:N      146  51%  03-17-00 12:30  ac373f32  testDir/string.txt\r
371 #     300  Stored      300   0%  03-17-00 12:30  ac373f32  testDir/stringU.txt\r
372 #     300  Defl:N      146  51%  03-17-00 12:30  ac373f32  testDir/fileC.txt\r
373 #--------          -------  ---                            -------\r
374 #    1200              892  26%                            5 files\r
376 @members = $zip->members();\r
377 $numberOfMembers = $zip->numberOfMembers();\r
378 is($numberOfMembers, 5);\r
380 #--------- make sure the contents of the stored file member are OK.\r
381 # contents      # Archive::Zip::Archive\r
382 is($zip->contents($members[1]), TESTSTRING);\r
384 # contents      # Archive::Zip::Member\r
385 is($members[1]->contents(), TESTSTRING);\r
387 #--------- make sure the contents of the compressed string member are OK.\r
388 is($members[2]->contents(), TESTSTRING);\r
390 #--------- make sure the contents of the stored string member are OK.\r
391 is($members[3]->contents(), TESTSTRING);\r
393 #--------- make sure the contents of the compressed file member are OK.\r
394 is($members[4]->contents(), TESTSTRING);\r
396 #--------- write to INPUTZIP\r
397 $status = $zip->writeToFileNamed( INPUTZIP );\r
398 is($status, AZ_OK);\r
400 ($status, $zipout) = testZip(INPUTZIP);\r
401 # STDERR->print("status= $status, out=$zipout\n");\r
402 SKIP: {\r
403         skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;\r
404         is( $status, 0 );\r
407 #--------- read from INPUTZIP (appending its entries)\r
408 # read  # Archive::Zip::Archive\r
409 $status = $zip->read(INPUTZIP);\r
410 is($status, AZ_OK);\r
411 is($zip->numberOfMembers(), 10);\r
413 #--------- clean up duplicate names\r
414 @members = $zip->members();\r
415 $member = $zip->removeMember($members[5]);\r
416 is($member->fileName(), TESTDIR . '/');\r
419         for my $i (6..9)\r
420         {\r
421                 $memberName = $members[$i]->fileName();\r
422                 $memberName =~ s/\.txt/2.txt/;\r
423                 $members[$i]->fileName($memberName);\r
424         }\r
426 is(scalar($zip->membersMatching('2.txt')), 4);\r
428 #--------- write zip out and test it.\r
429 $status = $zip->writeToFileNamed( OUTPUTZIP );\r
430 is($status, AZ_OK);\r
432 ($status, $zipout) = testZip();\r
433 # STDERR->print("status= $status, out=$zipout\n");\r
434 SKIP: {\r
435         skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;\r
436         is( $status, 0 );\r
439 #--------- Make sure that we haven't renamed files (this happened!)\r
440 is(scalar($zip->membersMatching('2\.txt$')), 4);\r
442 #--------- Now try extracting everyone\r
443 @members = $zip->members();\r
444 is($zip->extractMember($members[0]), AZ_OK);    #DM\r
445 is($zip->extractMember($members[1]), AZ_OK);    #NFM\r
446 is($zip->extractMember($members[2]), AZ_OK);\r
447 is($zip->extractMember($members[3]), AZ_OK);    #NFM\r
448 is($zip->extractMember($members[4]), AZ_OK);\r
449 is($zip->extractMember($members[5]), AZ_OK);\r
450 is($zip->extractMember($members[6]), AZ_OK);\r
451 is($zip->extractMember($members[7]), AZ_OK);\r
452 is($zip->extractMember($members[8]), AZ_OK);\r
454 #--------- count dirs\r
456         my @dirs = grep { $_->isDirectory() } @members;\r
457         is(scalar(@dirs), 1); \r
458         is($dirs[0], $members[0]);\r
461 #--------- count binary and text files\r
463         my @binaryFiles = grep { $_->isBinaryFile() } @members;\r
464         my @textFiles = grep { $_->isTextFile() } @members;\r
465         is(scalar(@binaryFiles), 5); \r
466         is(scalar(@textFiles), 4); \r
469 #--------- Try writing zip file to file handle\r
471         my $fh;\r
472         if ($catWorks)\r
473         {\r
474                 unlink( OUTPUTZIP );\r
475                 $fh = FileHandle->new( CATPIPE . OUTPUTZIP );\r
476                 binmode($fh);\r
477         }\r
478         SKIP: {\r
479                 skip('cat does not work on this platform', 1) unless $catWorks;\r
480                 ok( $fh );\r
481         }\r
482 #       $status = $zip->writeToFileHandle($fh, 0) if ($catWorks);\r
483         $status = $zip->writeToFileHandle($fh) if ($catWorks);\r
484         SKIP: {\r
485                 skip('cat does not work on this platform', 1) unless $catWorks;\r
486                 is( $status, AZ_OK );\r
487         }\r
488         $fh->close() if ($catWorks);\r
489         ($status, $zipout) = testZip();\r
490         is($status, 0);\r
493 #--------- Change the contents of a string member\r
494 is(ref($members[2]), 'Archive::Zip::StringMember');\r
495 $members[2]->contents( "This is my new contents\n" );\r
497 #--------- write zip out and test it.\r
498 $status = $zip->writeToFileNamed( OUTPUTZIP );\r
499 is($status, AZ_OK);\r
501 ($status, $zipout) = testZip();\r
502 # STDERR->print("status= $status, out=$zipout\n");\r
503 SKIP: {\r
504         skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;\r
505         is( $status, 0 );\r
508 #--------- Change the contents of a file member\r
509 is(ref($members[1]), 'Archive::Zip::NewFileMember');\r
510 $members[1]->contents( "This is my new contents\n" );\r
512 #--------- write zip out and test it.\r
513 $status = $zip->writeToFileNamed( OUTPUTZIP );\r
514 is($status, AZ_OK);\r
516 ($status, $zipout) = testZip();\r
517 # STDERR->print("status= $status, out=$zipout\n");\r
518 SKIP: {\r
519         skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;\r
520         is( $status, 0 );\r
523 #--------- Change the contents of a zip member\r
525 is(ref($members[7]), 'Archive::Zip::ZipFileMember');\r
526 $members[7]->contents( "This is my new contents\n" );\r
528 #--------- write zip out and test it.\r
529 $status = $zip->writeToFileNamed( OUTPUTZIP );\r
530 is($status, AZ_OK);\r
532 ($status, $zipout) = testZip();\r
533 # STDERR->print("status= $status, out=$zipout\n");\r
534 SKIP: {\r
535         skip( "test zip doesn't work", 1 ) if $testZipDoesntWork;\r
536         is( $status, 0 );\r
540 #--------- now clean up\r
541 # END { system("rm -rf " . TESTDIR . " " . OUTPUTZIP . " " . INPUTZIP) }\r
543 #--------------------- STILL UNTESTED IN THIS SCRIPT --------------------- \r
545 # sub setChunkSize      # Archive::Zip\r
546 # sub _formatError      # Archive::Zip\r
547 # sub _error    # Archive::Zip\r
548 # sub _subclassResponsibility   # Archive::Zip\r
549 # sub diskNumber        # Archive::Zip::Archive\r
550 # sub diskNumberWithStartOfCentralDirectory     # Archive::Zip::Archive\r
551 # sub numberOfCentralDirectoriesOnThisDisk      # Archive::Zip::Archive\r
552 # sub numberOfCentralDirectories        # Archive::Zip::Archive\r
553 # sub centralDirectoryOffsetWRTStartingDiskNumber       # Archive::Zip::Archive\r
554 # sub extraField        # Archive::Zip::Member\r
555 # sub isEncrypted       # Archive::Zip::Member\r
556 # sub isTextFile        # Archive::Zip::Member\r
557 # sub isBinaryFile      # Archive::Zip::Member\r
558 # sub isDirectory       # Archive::Zip::Member\r
559 # sub lastModTime       # Archive::Zip::Member\r
560 # sub _writeDataDescriptor      # Archive::Zip::Member\r
561 # sub isDirectory       # Archive::Zip::DirectoryMember\r
562 # sub _becomeDirectory  # Archive::Zip::DirectoryMember\r
563 # sub diskNumberStart   # Archive::Zip::ZipFileMember\r