viva-rubyzip 0.9.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/test/ziptest.rb ADDED
@@ -0,0 +1,1690 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $VERBOSE = true
4
+
5
+ $: << "../lib"
6
+
7
+ require 'test/unit'
8
+ require 'zip/zip'
9
+ require 'gentestfiles'
10
+
11
+ include Zip
12
+
13
+
14
+ class ZipEntryTest < Test::Unit::TestCase
15
+ TEST_ZIPFILE = "someZipFile.zip"
16
+ TEST_COMMENT = "a comment"
17
+ TEST_COMPRESSED_SIZE = 1234
18
+ TEST_CRC = 325324
19
+ TEST_EXTRA = "Some data here"
20
+ TEST_COMPRESSIONMETHOD = ZipEntry::DEFLATED
21
+ TEST_NAME = "entry name"
22
+ TEST_SIZE = 8432
23
+ TEST_ISDIRECTORY = false
24
+
25
+ def test_constructorAndGetters
26
+ entry = ZipEntry.new(TEST_ZIPFILE,
27
+ TEST_NAME,
28
+ TEST_COMMENT,
29
+ TEST_EXTRA,
30
+ TEST_COMPRESSED_SIZE,
31
+ TEST_CRC,
32
+ TEST_COMPRESSIONMETHOD,
33
+ TEST_SIZE)
34
+
35
+ assert_equal(TEST_COMMENT, entry.comment)
36
+ assert_equal(TEST_COMPRESSED_SIZE, entry.compressed_size)
37
+ assert_equal(TEST_CRC, entry.crc)
38
+ assert_instance_of(Zip::ZipExtraField, entry.extra)
39
+ assert_equal(TEST_COMPRESSIONMETHOD, entry.compression_method)
40
+ assert_equal(TEST_NAME, entry.name)
41
+ assert_equal(TEST_SIZE, entry.size)
42
+ assert_equal(TEST_ISDIRECTORY, entry.is_directory)
43
+ end
44
+
45
+ def test_is_directoryAndIsFile
46
+ assert(ZipEntry.new(TEST_ZIPFILE, "hello").file?)
47
+ assert(! ZipEntry.new(TEST_ZIPFILE, "hello").directory?)
48
+
49
+ assert(ZipEntry.new(TEST_ZIPFILE, "dir/hello").file?)
50
+ assert(! ZipEntry.new(TEST_ZIPFILE, "dir/hello").directory?)
51
+
52
+ assert(ZipEntry.new(TEST_ZIPFILE, "hello/").directory?)
53
+ assert(! ZipEntry.new(TEST_ZIPFILE, "hello/").file?)
54
+
55
+ assert(ZipEntry.new(TEST_ZIPFILE, "dir/hello/").directory?)
56
+ assert(! ZipEntry.new(TEST_ZIPFILE, "dir/hello/").file?)
57
+ end
58
+
59
+ def test_equality
60
+ entry1 = ZipEntry.new("file.zip", "name", "isNotCompared",
61
+ "something extra", 123, 1234,
62
+ ZipEntry::DEFLATED, 10000)
63
+ entry2 = ZipEntry.new("file.zip", "name", "isNotComparedXXX",
64
+ "something extra", 123, 1234,
65
+ ZipEntry::DEFLATED, 10000)
66
+ entry3 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
67
+ "something extra", 123, 1234,
68
+ ZipEntry::DEFLATED, 10000)
69
+ entry4 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
70
+ "something extraXX", 123, 1234,
71
+ ZipEntry::DEFLATED, 10000)
72
+ entry5 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
73
+ "something extraXX", 12, 1234,
74
+ ZipEntry::DEFLATED, 10000)
75
+ entry6 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
76
+ "something extraXX", 12, 123,
77
+ ZipEntry::DEFLATED, 10000)
78
+ entry7 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
79
+ "something extraXX", 12, 123,
80
+ ZipEntry::STORED, 10000)
81
+ entry8 = ZipEntry.new("file.zip", "name2", "isNotComparedXXX",
82
+ "something extraXX", 12, 123,
83
+ ZipEntry::STORED, 100000)
84
+
85
+ assert_equal(entry1, entry1)
86
+ assert_equal(entry1, entry2)
87
+
88
+ assert(entry2 != entry3)
89
+ assert(entry3 != entry4)
90
+ assert(entry4 != entry5)
91
+ assert(entry5 != entry6)
92
+ assert(entry6 != entry7)
93
+ assert(entry7 != entry8)
94
+
95
+ assert(entry7 != "hello")
96
+ assert(entry7 != 12)
97
+ end
98
+
99
+ def test_compare
100
+ assert_equal(0, (ZipEntry.new("zf.zip", "a") <=> ZipEntry.new("zf.zip", "a")))
101
+ assert_equal(1, (ZipEntry.new("zf.zip", "b") <=> ZipEntry.new("zf.zip", "a")))
102
+ assert_equal(-1, (ZipEntry.new("zf.zip", "a") <=> ZipEntry.new("zf.zip", "b")))
103
+
104
+ entries = [
105
+ ZipEntry.new("zf.zip", "5"),
106
+ ZipEntry.new("zf.zip", "1"),
107
+ ZipEntry.new("zf.zip", "3"),
108
+ ZipEntry.new("zf.zip", "4"),
109
+ ZipEntry.new("zf.zip", "0"),
110
+ ZipEntry.new("zf.zip", "2")
111
+ ]
112
+
113
+ entries.sort!
114
+ assert_equal("0", entries[0].to_s)
115
+ assert_equal("1", entries[1].to_s)
116
+ assert_equal("2", entries[2].to_s)
117
+ assert_equal("3", entries[3].to_s)
118
+ assert_equal("4", entries[4].to_s)
119
+ assert_equal("5", entries[5].to_s)
120
+ end
121
+
122
+ def test_parentAsString
123
+ entry1 = ZipEntry.new("zf.zip", "aa")
124
+ entry2 = ZipEntry.new("zf.zip", "aa/")
125
+ entry3 = ZipEntry.new("zf.zip", "aa/bb")
126
+ entry4 = ZipEntry.new("zf.zip", "aa/bb/")
127
+ entry5 = ZipEntry.new("zf.zip", "aa/bb/cc")
128
+ entry6 = ZipEntry.new("zf.zip", "aa/bb/cc/")
129
+
130
+ assert_equal(nil, entry1.parent_as_string)
131
+ assert_equal(nil, entry2.parent_as_string)
132
+ assert_equal("aa/", entry3.parent_as_string)
133
+ assert_equal("aa/", entry4.parent_as_string)
134
+ assert_equal("aa/bb/", entry5.parent_as_string)
135
+ assert_equal("aa/bb/", entry6.parent_as_string)
136
+ end
137
+
138
+ def test_entry_name_cannot_start_with_slash
139
+ assert_raise(ZipEntryNameError) { ZipEntry.new("zf.zip", "/hej/der") }
140
+ end
141
+ end
142
+
143
+ module IOizeString
144
+ attr_reader :tell
145
+
146
+ def read(count = nil)
147
+ @tell ||= 0
148
+ count = size unless count
149
+ retVal = slice(@tell, count)
150
+ @tell += count
151
+ return retVal
152
+ end
153
+
154
+ def seek(index, offset)
155
+ @tell ||= 0
156
+ case offset
157
+ when IO::SEEK_END
158
+ newPos = size + index
159
+ when IO::SEEK_SET
160
+ newPos = index
161
+ when IO::SEEK_CUR
162
+ newPos = @tell + index
163
+ else
164
+ raise "Error in test method IOizeString::seek"
165
+ end
166
+ if (newPos < 0 || newPos >= size)
167
+ raise Errno::EINVAL
168
+ else
169
+ @tell=newPos
170
+ end
171
+ end
172
+
173
+ def reset
174
+ @tell = 0
175
+ end
176
+ end
177
+
178
+ class ZipLocalEntryTest < Test::Unit::TestCase
179
+ def test_read_local_entryHeaderOfFirstTestZipEntry
180
+ File.open(TestZipFile::TEST_ZIP3.zip_name, "rb") {
181
+ |file|
182
+ entry = ZipEntry.read_local_entry(file)
183
+
184
+ assert_equal("", entry.comment)
185
+ # Differs from windows and unix because of CR LF
186
+ # assert_equal(480, entry.compressed_size)
187
+ # assert_equal(0x2a27930f, entry.crc)
188
+ # extra field is 21 bytes long
189
+ # probably contains some unix attrutes or something
190
+ # disabled: assert_equal(nil, entry.extra)
191
+ assert_equal(ZipEntry::DEFLATED, entry.compression_method)
192
+ assert_equal(TestZipFile::TEST_ZIP3.entry_names[0], entry.name)
193
+ assert_equal(File.size(TestZipFile::TEST_ZIP3.entry_names[0]), entry.size)
194
+ assert(! entry.is_directory)
195
+ }
196
+ end
197
+
198
+ def test_readDateTime
199
+ File.open("data/rubycode.zip", "rb") {
200
+ |file|
201
+ entry = ZipEntry.read_local_entry(file)
202
+ assert_equal("zippedruby1.rb", entry.name)
203
+ assert_equal(Time.at(1019261638), entry.time)
204
+ }
205
+ end
206
+
207
+ def test_read_local_entryFromNonZipFile
208
+ File.open("data/file2.txt") {
209
+ |file|
210
+ assert_equal(nil, ZipEntry.read_local_entry(file))
211
+ }
212
+ end
213
+
214
+ def test_read_local_entryFromTruncatedZipFile
215
+ zipFragment=""
216
+ File.open(TestZipFile::TEST_ZIP2.zip_name) { |f| zipFragment = f.read(12) } # local header is at least 30 bytes
217
+ zipFragment.extend(IOizeString).reset
218
+ entry = ZipEntry.new
219
+ entry.read_local_entry(zipFragment)
220
+ fail "ZipError expected"
221
+ rescue ZipError
222
+ end
223
+
224
+ def test_writeEntry
225
+ entry = ZipEntry.new("file.zip", "entryName", "my little comment",
226
+ "thisIsSomeExtraInformation", 100, 987654,
227
+ ZipEntry::DEFLATED, 400)
228
+ write_to_file("localEntryHeader.bin", "centralEntryHeader.bin", entry)
229
+ entryReadLocal, entryReadCentral = read_from_file("localEntryHeader.bin", "centralEntryHeader.bin")
230
+ compare_local_entry_headers(entry, entryReadLocal)
231
+ compare_c_dir_entry_headers(entry, entryReadCentral)
232
+ end
233
+
234
+ private
235
+ def compare_local_entry_headers(entry1, entry2)
236
+ assert_equal(entry1.compressed_size , entry2.compressed_size)
237
+ assert_equal(entry1.crc , entry2.crc)
238
+ assert_equal(entry1.extra , entry2.extra)
239
+ assert_equal(entry1.compression_method, entry2.compression_method)
240
+ assert_equal(entry1.name , entry2.name)
241
+ assert_equal(entry1.size , entry2.size)
242
+ assert_equal(entry1.localHeaderOffset, entry2.localHeaderOffset)
243
+ end
244
+
245
+ def compare_c_dir_entry_headers(entry1, entry2)
246
+ compare_local_entry_headers(entry1, entry2)
247
+ assert_equal(entry1.comment, entry2.comment)
248
+ end
249
+
250
+ def write_to_file(localFileName, centralFileName, entry)
251
+ File.open(localFileName, "wb") { |f| entry.write_local_entry(f) }
252
+ File.open(centralFileName, "wb") { |f| entry.write_c_dir_entry(f) }
253
+ end
254
+
255
+ def read_from_file(localFileName, centralFileName)
256
+ localEntry = nil
257
+ cdirEntry = nil
258
+ File.open(localFileName, "rb") { |f| localEntry = ZipEntry.read_local_entry(f) }
259
+ File.open(centralFileName, "rb") { |f| cdirEntry = ZipEntry.read_c_dir_entry(f) }
260
+ return [localEntry, cdirEntry]
261
+ end
262
+ end
263
+
264
+
265
+ module DecompressorTests
266
+ # expects @refText, @refLines and @decompressor
267
+
268
+ TEST_FILE="data/file1.txt"
269
+
270
+ def setup
271
+ @refText=""
272
+ File.open(TEST_FILE) { |f| @refText = f.read }
273
+ @refLines = @refText.split($/)
274
+ end
275
+
276
+ def test_readEverything
277
+ assert_equal(@refText, @decompressor.sysread)
278
+ end
279
+
280
+ def test_readInChunks
281
+ chunkSize = 5
282
+ while (decompressedChunk = @decompressor.sysread(chunkSize))
283
+ assert_equal(@refText.slice!(0, chunkSize), decompressedChunk)
284
+ end
285
+ assert_equal(0, @refText.size)
286
+ end
287
+
288
+ def test_mixingReadsAndProduceInput
289
+ # Just some preconditions to make sure we have enough data for this test
290
+ assert(@refText.length > 1000)
291
+ assert(@refLines.length > 40)
292
+
293
+
294
+ assert_equal(@refText[0...100], @decompressor.sysread(100))
295
+
296
+ assert(! @decompressor.input_finished?)
297
+ buf = @decompressor.produce_input
298
+ assert_equal(@refText[100...(100+buf.length)], buf)
299
+ end
300
+ end
301
+
302
+ class InflaterTest < Test::Unit::TestCase
303
+ include DecompressorTests
304
+
305
+ def setup
306
+ super
307
+ @file = File.new("data/file1.txt.deflatedData", "rb")
308
+ @decompressor = Inflater.new(@file)
309
+ end
310
+
311
+ def teardown
312
+ @file.close
313
+ end
314
+ end
315
+
316
+
317
+ class PassThruDecompressorTest < Test::Unit::TestCase
318
+ include DecompressorTests
319
+ def setup
320
+ super
321
+ @file = File.new(TEST_FILE)
322
+ @decompressor = PassThruDecompressor.new(@file, File.size(TEST_FILE))
323
+ end
324
+
325
+ def teardown
326
+ @file.close
327
+ end
328
+ end
329
+
330
+
331
+ module AssertEntry
332
+ def assert_next_entry(filename, zis)
333
+ assert_entry(filename, zis, zis.get_next_entry.name)
334
+ end
335
+
336
+ def assert_entry(filename, zis, entryName)
337
+ assert_equal(filename, entryName)
338
+ assert_entryContentsForStream(filename, zis, entryName)
339
+ end
340
+
341
+ def assert_entryContentsForStream(filename, zis, entryName)
342
+ File.open(filename, "rb") {
343
+ |file|
344
+ expected = file.read
345
+ actual = zis.read
346
+ if (expected != actual)
347
+ if ((expected && actual) && (expected.length > 400 || actual.length > 400))
348
+ zipEntryFilename=entryName+".zipEntry"
349
+ File.open(zipEntryFilename, "wb") { |entryfile| entryfile << actual }
350
+ fail("File '#{filename}' is different from '#{zipEntryFilename}'")
351
+ else
352
+ assert_equal(expected, actual)
353
+ end
354
+ end
355
+ }
356
+ end
357
+
358
+ def AssertEntry.assert_contents(filename, aString)
359
+ fileContents = ""
360
+ File.open(filename, "rb") { |f| fileContents = f.read }
361
+ if (fileContents != aString)
362
+ if (fileContents.length > 400 || aString.length > 400)
363
+ stringFile = filename + ".other"
364
+ File.open(stringFile, "wb") { |f| f << aString }
365
+ fail("File '#{filename}' is different from contents of string stored in '#{stringFile}'")
366
+ else
367
+ assert_equal(fileContents, aString)
368
+ end
369
+ end
370
+ end
371
+
372
+ def assert_stream_contents(zis, testZipFile)
373
+ assert(zis != nil)
374
+ testZipFile.entry_names.each {
375
+ |entryName|
376
+ assert_next_entry(entryName, zis)
377
+ }
378
+ assert_equal(nil, zis.get_next_entry)
379
+ end
380
+
381
+ def assert_test_zip_contents(testZipFile)
382
+ ZipInputStream.open(testZipFile.zip_name) {
383
+ |zis|
384
+ assert_stream_contents(zis, testZipFile)
385
+ }
386
+ end
387
+
388
+ def assert_entryContents(zipFile, entryName, filename = entryName.to_s)
389
+ zis = zipFile.get_input_stream(entryName)
390
+ assert_entryContentsForStream(filename, zis, entryName)
391
+ ensure
392
+ zis.close if zis
393
+ end
394
+ end
395
+
396
+
397
+
398
+ class ZipInputStreamTest < Test::Unit::TestCase
399
+ include AssertEntry
400
+
401
+ def test_new
402
+ zis = ZipInputStream.new(TestZipFile::TEST_ZIP2.zip_name)
403
+ assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
404
+ assert_equal(true, zis.eof?)
405
+ zis.close
406
+
407
+ # with StringIO
408
+ sio = StringIO.new(File.open(TestZipFile::TEST_ZIP2.zip_name).read)
409
+ zis = ZipInputStream.new(sio)
410
+ assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
411
+ assert_equal(true, zis.eof?)
412
+ zis.close
413
+ end
414
+
415
+ def test_openWithBlock
416
+ ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
417
+ |zis|
418
+ assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
419
+ assert_equal(true, zis.eof?)
420
+ }
421
+
422
+ # with StringIO
423
+ sio = StringIO.new(File.open(TestZipFile::TEST_ZIP2.zip_name).read)
424
+ ZipInputStream.open(sio) {
425
+ |zis|
426
+ assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
427
+ assert_equal(true, zis.eof?)
428
+ }
429
+ end
430
+
431
+ def test_openWithoutBlock
432
+ zis = ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name)
433
+ assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
434
+
435
+ # with StringIO
436
+ sio = StringIO.new(File.open(TestZipFile::TEST_ZIP2.zip_name).read)
437
+ zis = ZipInputStream.open(sio)
438
+ assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
439
+ end
440
+
441
+ def test_incompleteReads
442
+ ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
443
+ |zis|
444
+ entry = zis.get_next_entry # longAscii.txt
445
+ assert_equal(false, zis.eof?)
446
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names[0], entry.name)
447
+ assert zis.gets.length > 0
448
+ assert_equal(false, zis.eof?)
449
+ entry = zis.get_next_entry # empty.txt
450
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names[1], entry.name)
451
+ assert_equal(0, entry.size)
452
+ assert_equal(nil, zis.gets)
453
+ assert_equal(true, zis.eof?)
454
+ entry = zis.get_next_entry # empty_chmod640.txt
455
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names[2], entry.name)
456
+ assert_equal(0, entry.size)
457
+ assert_equal(nil, zis.gets)
458
+ assert_equal(true, zis.eof?)
459
+ entry = zis.get_next_entry # short.txt
460
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names[3], entry.name)
461
+ assert zis.gets.length > 0
462
+ entry = zis.get_next_entry # longBinary.bin
463
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names[4], entry.name)
464
+ assert zis.gets.length > 0
465
+ }
466
+
467
+ # with StringIO
468
+ sio = StringIO.new(File.open(TestZipFile::TEST_ZIP2.zip_name).read)
469
+ ZipInputStream.open(sio) {
470
+ |zis|
471
+ entry = zis.get_next_entry # longAscii.txt
472
+ assert_equal(false, zis.eof?)
473
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names[0], entry.name)
474
+ assert zis.gets.length > 0
475
+ assert_equal(false, zis.eof?)
476
+ entry = zis.get_next_entry # empty.txt
477
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names[1], entry.name)
478
+ assert_equal(0, entry.size)
479
+ assert_equal(nil, zis.gets)
480
+ assert_equal(true, zis.eof?)
481
+ entry = zis.get_next_entry # empty_chmod640.txt
482
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names[2], entry.name)
483
+ assert_equal(0, entry.size)
484
+ assert_equal(nil, zis.gets)
485
+ assert_equal(true, zis.eof?)
486
+ entry = zis.get_next_entry # short.txt
487
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names[3], entry.name)
488
+ assert zis.gets.length > 0
489
+ entry = zis.get_next_entry # longBinary.bin
490
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names[4], entry.name)
491
+ assert zis.gets.length > 0
492
+ }
493
+ end
494
+
495
+ def test_rewind
496
+ ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
497
+ |zis|
498
+ e = zis.get_next_entry
499
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names[0], e.name)
500
+
501
+ # Do a little reading
502
+ buf = ""
503
+ buf << zis.read(100)
504
+ buf << (zis.gets || "")
505
+ buf << (zis.gets || "")
506
+ assert_equal(false, zis.eof?)
507
+
508
+ zis.rewind
509
+
510
+ buf2 = ""
511
+ buf2 << zis.read(100)
512
+ buf2 << (zis.gets || "")
513
+ buf2 << (zis.gets || "")
514
+
515
+ assert_equal(buf, buf2)
516
+
517
+ zis.rewind
518
+ assert_equal(false, zis.eof?)
519
+
520
+ assert_entry(e.name, zis, e.name)
521
+ }
522
+
523
+ # with StringIO
524
+ sio = StringIO.new(File.open(TestZipFile::TEST_ZIP2.zip_name).read)
525
+ ZipInputStream.open(sio) {
526
+ |zis|
527
+ e = zis.get_next_entry
528
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names[0], e.name)
529
+
530
+ # Do a little reading
531
+ buf = ""
532
+ buf << zis.read(100)
533
+ buf << (zis.gets || "")
534
+ buf << (zis.gets || "")
535
+ assert_equal(false, zis.eof?)
536
+
537
+ zis.rewind
538
+
539
+ buf2 = ""
540
+ buf2 << zis.read(100)
541
+ buf2 << (zis.gets || "")
542
+ buf2 << (zis.gets || "")
543
+
544
+ assert_equal(buf, buf2)
545
+
546
+ zis.rewind
547
+ assert_equal(false, zis.eof?)
548
+
549
+ assert_entry(e.name, zis, e.name)
550
+ }
551
+ end
552
+
553
+ def test_mix_read_and_gets
554
+ ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
555
+ |zis|
556
+ e = zis.get_next_entry
557
+ assert_equal("#!/usr/bin/env ruby", zis.gets.chomp)
558
+ assert_equal(false, zis.eof?)
559
+ assert_equal("", zis.gets.chomp)
560
+ assert_equal(false, zis.eof?)
561
+ assert_equal("$VERBOSE =", zis.read(10))
562
+ assert_equal(false, zis.eof?)
563
+ }
564
+
565
+ # wtih StringIO
566
+ sio = StringIO.new(File.open(TestZipFile::TEST_ZIP2.zip_name).read)
567
+ ZipInputStream.open(sio) {
568
+ |zis|
569
+ e = zis.get_next_entry
570
+ assert_equal("#!/usr/bin/env ruby", zis.gets.chomp)
571
+ assert_equal(false, zis.eof?)
572
+ assert_equal("", zis.gets.chomp)
573
+ assert_equal(false, zis.eof?)
574
+ assert_equal("$VERBOSE =", zis.read(10))
575
+ assert_equal(false, zis.eof?)
576
+ }
577
+ end
578
+ end
579
+
580
+
581
+ module CrcTest
582
+
583
+ class TestOutputStream
584
+ include IOExtras::AbstractOutputStream
585
+
586
+ attr_accessor :buffer
587
+
588
+ def initialize
589
+ @buffer = ""
590
+ end
591
+
592
+ def << (data)
593
+ @buffer << data
594
+ self
595
+ end
596
+ end
597
+
598
+ def run_crc_test(compressorClass)
599
+ str = "Here's a nice little text to compute the crc for! Ho hum, it is nice nice nice nice indeed."
600
+ fakeOut = TestOutputStream.new
601
+
602
+ deflater = compressorClass.new(fakeOut)
603
+ deflater << str
604
+ assert_equal(0x919920fc, deflater.crc)
605
+ end
606
+ end
607
+
608
+
609
+
610
+ class PassThruCompressorTest < Test::Unit::TestCase
611
+ include CrcTest
612
+
613
+ def test_size
614
+ File.open("dummy.txt", "wb") {
615
+ |file|
616
+ compressor = PassThruCompressor.new(file)
617
+
618
+ assert_equal(0, compressor.size)
619
+
620
+ t1 = "hello world"
621
+ t2 = ""
622
+ t3 = "bingo"
623
+
624
+ compressor << t1
625
+ assert_equal(compressor.size, t1.size)
626
+
627
+ compressor << t2
628
+ assert_equal(compressor.size, t1.size + t2.size)
629
+
630
+ compressor << t3
631
+ assert_equal(compressor.size, t1.size + t2.size + t3.size)
632
+ }
633
+ end
634
+
635
+ def test_crc
636
+ run_crc_test(PassThruCompressor)
637
+ end
638
+ end
639
+
640
+ class DeflaterTest < Test::Unit::TestCase
641
+ include CrcTest
642
+
643
+ def test_outputOperator
644
+ txt = load_file("data/file2.txt")
645
+ deflate(txt, "deflatertest.bin")
646
+ inflatedTxt = inflate("deflatertest.bin")
647
+ assert_equal(txt, inflatedTxt)
648
+ end
649
+
650
+ private
651
+ def load_file(fileName)
652
+ txt = nil
653
+ File.open(fileName, "rb") { |f| txt = f.read }
654
+ end
655
+
656
+ def deflate(data, fileName)
657
+ File.open(fileName, "wb") {
658
+ |file|
659
+ deflater = Deflater.new(file)
660
+ deflater << data
661
+ deflater.finish
662
+ assert_equal(deflater.size, data.size)
663
+ file << "trailing data for zlib with -MAX_WBITS"
664
+ }
665
+ end
666
+
667
+ def inflate(fileName)
668
+ txt = nil
669
+ File.open(fileName, "rb") {
670
+ |file|
671
+ inflater = Inflater.new(file)
672
+ txt = inflater.sysread
673
+ }
674
+ end
675
+
676
+ def test_crc
677
+ run_crc_test(Deflater)
678
+ end
679
+ end
680
+
681
+ class ZipOutputStreamTest < Test::Unit::TestCase
682
+ include AssertEntry
683
+
684
+ TEST_ZIP = TestZipFile::TEST_ZIP2.clone
685
+ TEST_ZIP.zip_name = "output.zip"
686
+
687
+ def test_new
688
+ zos = ZipOutputStream.new(TEST_ZIP.zip_name)
689
+ zos.comment = TEST_ZIP.comment
690
+ write_test_zip(zos)
691
+ zos.close
692
+ assert_test_zip_contents(TEST_ZIP)
693
+ end
694
+
695
+ def test_open
696
+ ZipOutputStream.open(TEST_ZIP.zip_name) {
697
+ |zos|
698
+ zos.comment = TEST_ZIP.comment
699
+ write_test_zip(zos)
700
+ }
701
+ assert_test_zip_contents(TEST_ZIP)
702
+ end
703
+
704
+ def test_writingToClosedStream
705
+ assert_i_o_error_in_closed_stream { |zos| zos << "hello world" }
706
+ assert_i_o_error_in_closed_stream { |zos| zos.puts "hello world" }
707
+ assert_i_o_error_in_closed_stream { |zos| zos.write "hello world" }
708
+ end
709
+
710
+ def test_cannotOpenFile
711
+ name = TestFiles::EMPTY_TEST_DIR
712
+ begin
713
+ zos = ZipOutputStream.open(name)
714
+ rescue Exception
715
+ assert($!.kind_of?(Errno::EISDIR) || # Linux
716
+ $!.kind_of?(Errno::EEXIST) || # Windows/cygwin
717
+ $!.kind_of?(Errno::EACCES), # Windows
718
+ "Expected Errno::EISDIR (or on win/cygwin: Errno::EEXIST), but was: #{$!.class}")
719
+ end
720
+ end
721
+
722
+ def assert_i_o_error_in_closed_stream
723
+ assert_raise(IOError) {
724
+ zos = ZipOutputStream.new("test_putOnClosedStream.zip")
725
+ zos.close
726
+ yield zos
727
+ }
728
+ end
729
+
730
+ def write_test_zip(zos)
731
+ TEST_ZIP.entry_names.each {
732
+ |entryName|
733
+ zos.put_next_entry(entryName)
734
+ File.open(entryName, "rb") { |f| zos.write(f.read) }
735
+ }
736
+ end
737
+ end
738
+
739
+
740
+
741
+ module Enumerable
742
+ def compare_enumerables(otherEnumerable)
743
+ otherAsArray = otherEnumerable.to_a
744
+ count=0
745
+ each_with_index {
746
+ |element, index|
747
+ count = index
748
+ return false unless yield(element, otherAsArray[index])
749
+ }
750
+ return count+1 == otherAsArray.size
751
+ end
752
+ end
753
+
754
+
755
+ class ZipCentralDirectoryEntryTest < Test::Unit::TestCase
756
+
757
+ def test_read_from_stream
758
+ File.open("data/testDirectory.bin", "rb") {
759
+ |file|
760
+ entry = ZipEntry.read_c_dir_entry(file)
761
+
762
+ assert_equal("longAscii.txt", entry.name)
763
+ assert_equal(ZipEntry::DEFLATED, entry.compression_method)
764
+ assert_equal(106490, entry.size)
765
+ assert_equal(3784, entry.compressed_size)
766
+ assert_equal(0xfcd1799c, entry.crc)
767
+ assert_equal("", entry.comment)
768
+
769
+ entry = ZipEntry.read_c_dir_entry(file)
770
+ assert_equal("empty.txt", entry.name)
771
+ assert_equal(ZipEntry::STORED, entry.compression_method)
772
+ assert_equal(0, entry.size)
773
+ assert_equal(0, entry.compressed_size)
774
+ assert_equal(0x0, entry.crc)
775
+ assert_equal("", entry.comment)
776
+
777
+ entry = ZipEntry.read_c_dir_entry(file)
778
+ assert_equal("short.txt", entry.name)
779
+ assert_equal(ZipEntry::STORED, entry.compression_method)
780
+ assert_equal(6, entry.size)
781
+ assert_equal(6, entry.compressed_size)
782
+ assert_equal(0xbb76fe69, entry.crc)
783
+ assert_equal("", entry.comment)
784
+
785
+ entry = ZipEntry.read_c_dir_entry(file)
786
+ assert_equal("longBinary.bin", entry.name)
787
+ assert_equal(ZipEntry::DEFLATED, entry.compression_method)
788
+ assert_equal(1000024, entry.size)
789
+ assert_equal(70847, entry.compressed_size)
790
+ assert_equal(0x10da7d59, entry.crc)
791
+ assert_equal("", entry.comment)
792
+
793
+ entry = ZipEntry.read_c_dir_entry(file)
794
+ assert_equal(nil, entry)
795
+ # Fields that are not check by this test:
796
+ # version made by 2 bytes
797
+ # version needed to extract 2 bytes
798
+ # general purpose bit flag 2 bytes
799
+ # last mod file time 2 bytes
800
+ # last mod file date 2 bytes
801
+ # compressed size 4 bytes
802
+ # uncompressed size 4 bytes
803
+ # disk number start 2 bytes
804
+ # internal file attributes 2 bytes
805
+ # external file attributes 4 bytes
806
+ # relative offset of local header 4 bytes
807
+
808
+ # file name (variable size)
809
+ # extra field (variable size)
810
+ # file comment (variable size)
811
+
812
+ }
813
+ end
814
+
815
+ def test_ReadEntryFromTruncatedZipFile
816
+ fragment=""
817
+ File.open("data/testDirectory.bin") { |f| fragment = f.read(12) } # cdir entry header is at least 46 bytes
818
+ fragment.extend(IOizeString)
819
+ entry = ZipEntry.new
820
+ entry.read_c_dir_entry(fragment)
821
+ fail "ZipError expected"
822
+ rescue ZipError
823
+ end
824
+
825
+ end
826
+
827
+
828
+ class ZipEntrySetTest < Test::Unit::TestCase
829
+ ZIP_ENTRIES = [
830
+ ZipEntry.new("zipfile.zip", "name1", "comment1"),
831
+ ZipEntry.new("zipfile.zip", "name2", "comment1"),
832
+ ZipEntry.new("zipfile.zip", "name3", "comment1"),
833
+ ZipEntry.new("zipfile.zip", "name4", "comment1"),
834
+ ZipEntry.new("zipfile.zip", "name5", "comment1"),
835
+ ZipEntry.new("zipfile.zip", "name6", "comment1")
836
+ ]
837
+
838
+ def setup
839
+ @zipEntrySet = ZipEntrySet.new(ZIP_ENTRIES)
840
+ end
841
+
842
+ def test_include
843
+ assert(@zipEntrySet.include?(ZIP_ENTRIES.first))
844
+ assert(! @zipEntrySet.include?(ZipEntry.new("different.zip", "different", "aComment")))
845
+ end
846
+
847
+ def test_size
848
+ assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
849
+ assert_equal(ZIP_ENTRIES.size, @zipEntrySet.length)
850
+ @zipEntrySet << ZipEntry.new("a", "b", "c")
851
+ assert_equal(ZIP_ENTRIES.size + 1, @zipEntrySet.length)
852
+ end
853
+
854
+ def test_add
855
+ zes = ZipEntrySet.new
856
+ entry1 = ZipEntry.new("zf.zip", "name1")
857
+ entry2 = ZipEntry.new("zf.zip", "name2")
858
+ zes << entry1
859
+ assert(zes.include?(entry1))
860
+ zes.push(entry2)
861
+ assert(zes.include?(entry2))
862
+ end
863
+
864
+ def test_delete
865
+ assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
866
+ entry = @zipEntrySet.delete(ZIP_ENTRIES.first)
867
+ assert_equal(ZIP_ENTRIES.size - 1, @zipEntrySet.size)
868
+ assert_equal(ZIP_ENTRIES.first, entry)
869
+
870
+ entry = @zipEntrySet.delete(ZIP_ENTRIES.first)
871
+ assert_equal(ZIP_ENTRIES.size - 1, @zipEntrySet.size)
872
+ assert_nil(entry)
873
+ end
874
+
875
+ def test_each
876
+ # Tested indirectly via each_with_index
877
+ count = 0
878
+ @zipEntrySet.each_with_index {
879
+ |entry, index|
880
+ assert(ZIP_ENTRIES.include?(entry))
881
+ count = count.succ
882
+ }
883
+ assert_equal(ZIP_ENTRIES.size, count)
884
+ end
885
+
886
+ def test_entries
887
+ assert_equal(ZIP_ENTRIES.sort, @zipEntrySet.entries.sort)
888
+ end
889
+
890
+ def test_compound
891
+ newEntry = ZipEntry.new("zf.zip", "new entry", "new entry's comment")
892
+ assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
893
+ @zipEntrySet << newEntry
894
+ assert_equal(ZIP_ENTRIES.size + 1, @zipEntrySet.size)
895
+ assert(@zipEntrySet.include?(newEntry))
896
+
897
+ @zipEntrySet.delete(newEntry)
898
+ assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
899
+ end
900
+
901
+ def test_dup
902
+ copy = @zipEntrySet.dup
903
+ assert_equal(@zipEntrySet, copy)
904
+
905
+ # demonstrate that this is a deep copy
906
+ copy.entries[0].name = "a totally different name"
907
+ assert(@zipEntrySet != copy)
908
+ end
909
+
910
+ def test_parent
911
+ entries = [
912
+ ZipEntry.new("zf.zip", "a"),
913
+ ZipEntry.new("zf.zip", "a/"),
914
+ ZipEntry.new("zf.zip", "a/b"),
915
+ ZipEntry.new("zf.zip", "a/b/"),
916
+ ZipEntry.new("zf.zip", "a/b/c"),
917
+ ZipEntry.new("zf.zip", "a/b/c/")
918
+ ]
919
+ entrySet = ZipEntrySet.new(entries)
920
+
921
+ assert_equal(nil, entrySet.parent(entries[0]))
922
+ assert_equal(nil, entrySet.parent(entries[1]))
923
+ assert_equal(entries[1], entrySet.parent(entries[2]))
924
+ assert_equal(entries[1], entrySet.parent(entries[3]))
925
+ assert_equal(entries[3], entrySet.parent(entries[4]))
926
+ assert_equal(entries[3], entrySet.parent(entries[5]))
927
+ end
928
+
929
+ def test_glob
930
+ res = @zipEntrySet.glob('name[2-4]')
931
+ assert_equal(3, res.size)
932
+ assert_equal(ZIP_ENTRIES[1,3], res)
933
+ end
934
+
935
+ def test_glob2
936
+ entries = [
937
+ ZipEntry.new("zf.zip", "a/"),
938
+ ZipEntry.new("zf.zip", "a/b/b1"),
939
+ ZipEntry.new("zf.zip", "a/b/c/"),
940
+ ZipEntry.new("zf.zip", "a/b/c/c1")
941
+ ]
942
+ entrySet = ZipEntrySet.new(entries)
943
+
944
+ assert_equal(entries[0,1], entrySet.glob("*"))
945
+ # assert_equal(entries[FIXME], entrySet.glob("**"))
946
+ # res = entrySet.glob('a*')
947
+ # assert_equal(entries.size, res.size)
948
+ # assert_equal(entrySet.map { |e| e.name }, res.map { |e| e.name })
949
+ end
950
+ end
951
+
952
+
953
+ class ZipCentralDirectoryTest < Test::Unit::TestCase
954
+
955
+ def test_read_from_stream
956
+ File.open(TestZipFile::TEST_ZIP2.zip_name, "rb") {
957
+ |zipFile|
958
+ cdir = ZipCentralDirectory.read_from_stream(zipFile)
959
+
960
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names.size, cdir.size)
961
+ assert(cdir.entries.sort.compare_enumerables(TestZipFile::TEST_ZIP2.entry_names.sort) {
962
+ |cdirEntry, testEntryName|
963
+ cdirEntry.name == testEntryName
964
+ })
965
+ assert_equal(TestZipFile::TEST_ZIP2.comment, cdir.comment)
966
+ }
967
+ end
968
+
969
+ def test_readFromInvalidStream
970
+ File.open("data/file2.txt", "rb") {
971
+ |zipFile|
972
+ cdir = ZipCentralDirectory.new
973
+ cdir.read_from_stream(zipFile)
974
+ }
975
+ fail "ZipError expected!"
976
+ rescue ZipError
977
+ end
978
+
979
+ def test_ReadFromTruncatedZipFile
980
+ fragment=""
981
+ File.open("data/testDirectory.bin") { |f| fragment = f.read }
982
+ fragment.slice!(12) # removed part of first cdir entry. eocd structure still complete
983
+ fragment.extend(IOizeString)
984
+ entry = ZipCentralDirectory.new
985
+ entry.read_from_stream(fragment)
986
+ fail "ZipError expected"
987
+ rescue ZipError
988
+ end
989
+
990
+ def test_write_to_stream
991
+ entries = [ ZipEntry.new("file.zip", "flimse", "myComment", "somethingExtra"),
992
+ ZipEntry.new("file.zip", "secondEntryName"),
993
+ ZipEntry.new("file.zip", "lastEntry.txt", "Has a comment too") ]
994
+ cdir = ZipCentralDirectory.new(entries, "my zip comment")
995
+ File.open("cdirtest.bin", "wb") { |f| cdir.write_to_stream(f) }
996
+ cdirReadback = ZipCentralDirectory.new
997
+ File.open("cdirtest.bin", "rb") { |f| cdirReadback.read_from_stream(f) }
998
+
999
+ assert_equal(cdir.entries.sort, cdirReadback.entries.sort)
1000
+ end
1001
+
1002
+ def test_equality
1003
+ cdir1 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
1004
+ "somethingExtra"),
1005
+ ZipEntry.new("file.zip", "secondEntryName"),
1006
+ ZipEntry.new("file.zip", "lastEntry.txt") ],
1007
+ "my zip comment")
1008
+ cdir2 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
1009
+ "somethingExtra"),
1010
+ ZipEntry.new("file.zip", "secondEntryName"),
1011
+ ZipEntry.new("file.zip", "lastEntry.txt") ],
1012
+ "my zip comment")
1013
+ cdir3 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
1014
+ "somethingExtra"),
1015
+ ZipEntry.new("file.zip", "secondEntryName"),
1016
+ ZipEntry.new("file.zip", "lastEntry.txt") ],
1017
+ "comment?")
1018
+ cdir4 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
1019
+ "somethingExtra"),
1020
+ ZipEntry.new("file.zip", "lastEntry.txt") ],
1021
+ "comment?")
1022
+ assert_equal(cdir1, cdir1)
1023
+ assert_equal(cdir1, cdir2)
1024
+
1025
+ assert(cdir1 != cdir3)
1026
+ assert(cdir2 != cdir3)
1027
+ assert(cdir2 != cdir3)
1028
+ assert(cdir3 != cdir4)
1029
+
1030
+ assert(cdir3 != "hello")
1031
+ end
1032
+ end
1033
+
1034
+
1035
+ class BasicZipFileTest < Test::Unit::TestCase
1036
+ include AssertEntry
1037
+
1038
+ def setup
1039
+ @zipFile = ZipFile.new(TestZipFile::TEST_ZIP2.zip_name)
1040
+ @testEntryNameIndex=0
1041
+ end
1042
+
1043
+ def test_entries
1044
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names.sort,
1045
+ @zipFile.entries.entries.sort.map {|e| e.name} )
1046
+ end
1047
+
1048
+ def test_each
1049
+ count = 0
1050
+ visited = {}
1051
+ @zipFile.each {
1052
+ |entry|
1053
+ assert(TestZipFile::TEST_ZIP2.entry_names.include?(entry.name))
1054
+ assert(! visited.include?(entry.name))
1055
+ visited[entry.name] = nil
1056
+ count = count.succ
1057
+ }
1058
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
1059
+ end
1060
+
1061
+ def test_foreach
1062
+ count = 0
1063
+ visited = {}
1064
+ ZipFile.foreach(TestZipFile::TEST_ZIP2.zip_name) {
1065
+ |entry|
1066
+ assert(TestZipFile::TEST_ZIP2.entry_names.include?(entry.name))
1067
+ assert(! visited.include?(entry.name))
1068
+ visited[entry.name] = nil
1069
+ count = count.succ
1070
+ }
1071
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
1072
+ end
1073
+
1074
+ def test_get_input_stream
1075
+ count = 0
1076
+ visited = {}
1077
+ @zipFile.each {
1078
+ |entry|
1079
+ assert_entry(entry.name, @zipFile.get_input_stream(entry), entry.name)
1080
+ assert(! visited.include?(entry.name))
1081
+ visited[entry.name] = nil
1082
+ count = count.succ
1083
+ }
1084
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
1085
+ end
1086
+
1087
+ def test_get_input_streamBlock
1088
+ fileAndEntryName = @zipFile.entries.first.name
1089
+ @zipFile.get_input_stream(fileAndEntryName) {
1090
+ |zis|
1091
+ assert_entryContentsForStream(fileAndEntryName,
1092
+ zis,
1093
+ fileAndEntryName)
1094
+ }
1095
+ end
1096
+ end
1097
+
1098
+ module CommonZipFileFixture
1099
+ include AssertEntry
1100
+
1101
+ EMPTY_FILENAME = "emptyZipFile.zip"
1102
+
1103
+ TEST_ZIP = TestZipFile::TEST_ZIP2.clone
1104
+ TEST_ZIP.zip_name = "5entry_copy.zip"
1105
+
1106
+ def setup
1107
+ File.delete(EMPTY_FILENAME) if File.exists?(EMPTY_FILENAME)
1108
+ FileUtils.copy(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name)
1109
+ end
1110
+ end
1111
+
1112
+ class ZipFileTest < Test::Unit::TestCase
1113
+ include CommonZipFileFixture
1114
+
1115
+ def test_createFromScratch
1116
+ comment = "a short comment"
1117
+
1118
+ zf = ZipFile.new(EMPTY_FILENAME, ZipFile::CREATE)
1119
+ zf.get_output_stream("myFile") { |os| os.write "myFile contains just this" }
1120
+ zf.mkdir("dir1")
1121
+ zf.comment = comment
1122
+ zf.close
1123
+
1124
+ zfRead = ZipFile.new(EMPTY_FILENAME)
1125
+ assert_equal(comment, zfRead.comment)
1126
+ assert_equal(2, zfRead.entries.length)
1127
+ end
1128
+
1129
+ def test_get_output_stream
1130
+ entryCount = nil
1131
+ ZipFile.open(TEST_ZIP.zip_name) {
1132
+ |zf|
1133
+ entryCount = zf.size
1134
+ zf.get_output_stream('newEntry.txt') {
1135
+ |os|
1136
+ os.write "Putting stuff in newEntry.txt"
1137
+ }
1138
+ assert_equal(entryCount+1, zf.size)
1139
+ assert_equal("Putting stuff in newEntry.txt", zf.read("newEntry.txt"))
1140
+
1141
+ zf.get_output_stream(zf.get_entry('data/generated/empty.txt')) {
1142
+ |os|
1143
+ os.write "Putting stuff in data/generated/empty.txt"
1144
+ }
1145
+ assert_equal(entryCount+1, zf.size)
1146
+ assert_equal("Putting stuff in data/generated/empty.txt", zf.read("data/generated/empty.txt"))
1147
+
1148
+ zf.get_output_stream('entry.bin') {
1149
+ |os|
1150
+ os.write(File.open('data/generated/5entry.zip', 'rb').read)
1151
+ }
1152
+ }
1153
+
1154
+ ZipFile.open(TEST_ZIP.zip_name) {
1155
+ |zf|
1156
+ assert_equal(entryCount+2, zf.size)
1157
+ assert_equal("Putting stuff in newEntry.txt", zf.read("newEntry.txt"))
1158
+ assert_equal("Putting stuff in data/generated/empty.txt", zf.read("data/generated/empty.txt"))
1159
+ assert_equal(File.open('data/generated/5entry.zip', 'rb').read, zf.read("entry.bin"))
1160
+ }
1161
+ end
1162
+
1163
+ def test_add
1164
+ srcFile = "data/file2.txt"
1165
+ entryName = "newEntryName.rb"
1166
+ assert(File.exists?(srcFile))
1167
+ zf = ZipFile.new(EMPTY_FILENAME, ZipFile::CREATE)
1168
+ zf.add(entryName, srcFile)
1169
+ zf.close
1170
+
1171
+ zfRead = ZipFile.new(EMPTY_FILENAME)
1172
+ assert_equal("", zfRead.comment)
1173
+ assert_equal(1, zfRead.entries.length)
1174
+ assert_equal(entryName, zfRead.entries.first.name)
1175
+ AssertEntry.assert_contents(srcFile,
1176
+ zfRead.get_input_stream(entryName) { |zis| zis.read })
1177
+ end
1178
+
1179
+ def test_addExistingEntryName
1180
+ assert_raise(ZipEntryExistsError) {
1181
+ ZipFile.open(TEST_ZIP.zip_name) {
1182
+ |zf|
1183
+ zf.add(zf.entries.first.name, "data/file2.txt")
1184
+ }
1185
+ }
1186
+ end
1187
+
1188
+ def test_addExistingEntryNameReplace
1189
+ gotCalled = false
1190
+ replacedEntry = nil
1191
+ ZipFile.open(TEST_ZIP.zip_name) {
1192
+ |zf|
1193
+ replacedEntry = zf.entries.first.name
1194
+ zf.add(replacedEntry, "data/file2.txt") { gotCalled = true; true }
1195
+ }
1196
+ assert(gotCalled)
1197
+ ZipFile.open(TEST_ZIP.zip_name) {
1198
+ |zf|
1199
+ assert_contains(zf, replacedEntry, "data/file2.txt")
1200
+ }
1201
+ end
1202
+
1203
+ def test_addDirectory
1204
+ ZipFile.open(TEST_ZIP.zip_name) {
1205
+ |zf|
1206
+ zf.add(TestFiles::EMPTY_TEST_DIR, TestFiles::EMPTY_TEST_DIR)
1207
+ }
1208
+ ZipFile.open(TEST_ZIP.zip_name) {
1209
+ |zf|
1210
+ dirEntry = zf.entries.detect { |e| e.name == TestFiles::EMPTY_TEST_DIR+"/" }
1211
+ assert(dirEntry.is_directory)
1212
+ }
1213
+ end
1214
+
1215
+ def test_remove
1216
+ entryToRemove, *remainingEntries = TEST_ZIP.entry_names
1217
+
1218
+ FileUtils.copy(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name)
1219
+
1220
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1221
+ assert(zf.entries.map { |e| e.name }.include?(entryToRemove))
1222
+ zf.remove(entryToRemove)
1223
+ assert(! zf.entries.map { |e| e.name }.include?(entryToRemove))
1224
+ assert_equal(zf.entries.map {|x| x.name }.sort, remainingEntries.sort)
1225
+ zf.close
1226
+
1227
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1228
+ assert(! zfRead.entries.map { |e| e.name }.include?(entryToRemove))
1229
+ assert_equal(zfRead.entries.map {|x| x.name }.sort, remainingEntries.sort)
1230
+ zfRead.close
1231
+ end
1232
+
1233
+
1234
+ def test_rename
1235
+ entryToRename, *remainingEntries = TEST_ZIP.entry_names
1236
+
1237
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1238
+ assert(zf.entries.map { |e| e.name }.include?(entryToRename))
1239
+
1240
+ newName = "changed entry name"
1241
+ assert(! zf.entries.map { |e| e.name }.include?(newName))
1242
+
1243
+ zf.rename(entryToRename, newName)
1244
+ assert(zf.entries.map { |e| e.name }.include?(newName))
1245
+
1246
+ zf.close
1247
+
1248
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1249
+ assert(zfRead.entries.map { |e| e.name }.include?(newName))
1250
+ File.delete(ZipFileExtractTest::EXTRACTED_FILENAME) if File.exists?(ZipFileExtractTest::EXTRACTED_FILENAME)
1251
+ zf.extract(newName, ZipFileExtractTest::EXTRACTED_FILENAME)
1252
+ zfRead.close
1253
+ end
1254
+
1255
+ def test_renameToExistingEntry
1256
+ oldEntries = nil
1257
+ ZipFile.open(TEST_ZIP.zip_name) { |zf| oldEntries = zf.entries }
1258
+
1259
+ assert_raise(ZipEntryExistsError) {
1260
+ ZipFile.open(TEST_ZIP.zip_name) {
1261
+ |zf|
1262
+ zf.rename(zf.entries[0], zf.entries[1].name)
1263
+ }
1264
+ }
1265
+
1266
+ ZipFile.open(TEST_ZIP.zip_name) {
1267
+ |zf|
1268
+ assert_equal(oldEntries.sort.map{ |e| e.name }, zf.entries.sort.map{ |e| e.name })
1269
+ }
1270
+ end
1271
+
1272
+ def test_renameToExistingEntryOverwrite
1273
+ oldEntries = nil
1274
+ ZipFile.open(TEST_ZIP.zip_name) { |zf| oldEntries = zf.entries }
1275
+
1276
+ gotCalled = false
1277
+ renamedEntryName = nil
1278
+ ZipFile.open(TEST_ZIP.zip_name) {
1279
+ |zf|
1280
+ renamedEntryName = zf.entries[0].name
1281
+ zf.rename(zf.entries[0], zf.entries[1].name) { gotCalled = true; true }
1282
+ }
1283
+
1284
+ assert(gotCalled)
1285
+ oldEntries.delete_if { |e| e.name == renamedEntryName }
1286
+ ZipFile.open(TEST_ZIP.zip_name) {
1287
+ |zf|
1288
+ assert_equal(oldEntries.sort.map{ |e| e.name },
1289
+ zf.entries.sort.map{ |e| e.name })
1290
+ }
1291
+ end
1292
+
1293
+ def test_renameNonEntry
1294
+ nonEntry = "bogusEntry"
1295
+ target_entry = "target_entryName"
1296
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1297
+ assert(! zf.entries.include?(nonEntry))
1298
+ assert_raise(Errno::ENOENT) {
1299
+ zf.rename(nonEntry, target_entry)
1300
+ }
1301
+ zf.commit
1302
+ assert(! zf.entries.include?(target_entry))
1303
+ ensure
1304
+ zf.close
1305
+ end
1306
+
1307
+ def test_renameEntryToExistingEntry
1308
+ entry1, entry2, *remaining = TEST_ZIP.entry_names
1309
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1310
+ assert_raise(ZipEntryExistsError) {
1311
+ zf.rename(entry1, entry2)
1312
+ }
1313
+ ensure
1314
+ zf.close
1315
+ end
1316
+
1317
+ def test_replace
1318
+ entryToReplace = TEST_ZIP.entry_names[2]
1319
+ newEntrySrcFilename = "data/file2.txt"
1320
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1321
+ zf.replace(entryToReplace, newEntrySrcFilename)
1322
+
1323
+ zf.close
1324
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1325
+ AssertEntry::assert_contents(newEntrySrcFilename,
1326
+ zfRead.get_input_stream(entryToReplace) { |is| is.read })
1327
+ AssertEntry::assert_contents(TEST_ZIP.entry_names[0],
1328
+ zfRead.get_input_stream(TEST_ZIP.entry_names[0]) { |is| is.read })
1329
+ AssertEntry::assert_contents(TEST_ZIP.entry_names[1],
1330
+ zfRead.get_input_stream(TEST_ZIP.entry_names[1]) { |is| is.read })
1331
+ AssertEntry::assert_contents(TEST_ZIP.entry_names[3],
1332
+ zfRead.get_input_stream(TEST_ZIP.entry_names[3]) { |is| is.read })
1333
+ zfRead.close
1334
+ end
1335
+
1336
+ def test_replaceNonEntry
1337
+ entryToReplace = "nonExistingEntryname"
1338
+ ZipFile.open(TEST_ZIP.zip_name) {
1339
+ |zf|
1340
+ assert_raise(Errno::ENOENT) {
1341
+ zf.replace(entryToReplace, "data/file2.txt")
1342
+ }
1343
+ }
1344
+ end
1345
+
1346
+ def test_commit
1347
+ newName = "renamedFirst"
1348
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1349
+ oldName = zf.entries.first
1350
+ zf.rename(oldName, newName)
1351
+ zf.commit
1352
+
1353
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1354
+ assert(zfRead.entries.detect { |e| e.name == newName } != nil)
1355
+ assert(zfRead.entries.detect { |e| e.name == oldName } == nil)
1356
+ zfRead.close
1357
+
1358
+ zf.close
1359
+ end
1360
+
1361
+ # This test tests that after commit, you
1362
+ # can delete the file you used to add the entry to the zip file
1363
+ # with
1364
+ def test_commitUseZipEntry
1365
+ FileUtils.copy(TestFiles::RANDOM_ASCII_FILE1, "okToDelete.txt")
1366
+ zf = ZipFile.open(TEST_ZIP.zip_name)
1367
+ zf.add("okToDelete.txt", "okToDelete.txt")
1368
+ assert_contains(zf, "okToDelete.txt")
1369
+ zf.commit
1370
+ FileUtils.move("okToDelete.txt", "okToDeleteMoved.txt")
1371
+ assert_contains(zf, "okToDelete.txt", "okToDeleteMoved.txt")
1372
+ end
1373
+
1374
+ # def test_close
1375
+ # zf = ZipFile.new(TEST_ZIP.zip_name)
1376
+ # zf.close
1377
+ # assert_raise(IOError) {
1378
+ # zf.extract(TEST_ZIP.entry_names.first, "hullubullu")
1379
+ # }
1380
+ # end
1381
+
1382
+ def test_compound1
1383
+ renamedName = "renamedName"
1384
+ originalEntries = []
1385
+ begin
1386
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1387
+ originalEntries = zf.entries.dup
1388
+
1389
+ assert_not_contains(zf, TestFiles::RANDOM_ASCII_FILE1)
1390
+ zf.add(TestFiles::RANDOM_ASCII_FILE1,
1391
+ TestFiles::RANDOM_ASCII_FILE1)
1392
+ assert_contains(zf, TestFiles::RANDOM_ASCII_FILE1)
1393
+
1394
+ zf.rename(zf.entries[0], renamedName)
1395
+ assert_contains(zf, renamedName)
1396
+
1397
+ TestFiles::BINARY_TEST_FILES.each {
1398
+ |filename|
1399
+ zf.add(filename, filename)
1400
+ assert_contains(zf, filename)
1401
+ }
1402
+
1403
+ assert_contains(zf, originalEntries.last.to_s)
1404
+ zf.remove(originalEntries.last.to_s)
1405
+ assert_not_contains(zf, originalEntries.last.to_s)
1406
+
1407
+ ensure
1408
+ zf.close
1409
+ end
1410
+ begin
1411
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1412
+ assert_contains(zfRead, TestFiles::RANDOM_ASCII_FILE1)
1413
+ assert_contains(zfRead, renamedName)
1414
+ TestFiles::BINARY_TEST_FILES.each {
1415
+ |filename|
1416
+ assert_contains(zfRead, filename)
1417
+ }
1418
+ assert_not_contains(zfRead, originalEntries.last.to_s)
1419
+ ensure
1420
+ zfRead.close
1421
+ end
1422
+ end
1423
+
1424
+ def test_compound2
1425
+ begin
1426
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1427
+ originalEntries = zf.entries.dup
1428
+
1429
+ originalEntries.each {
1430
+ |entry|
1431
+ zf.remove(entry)
1432
+ assert_not_contains(zf, entry)
1433
+ }
1434
+ assert(zf.entries.empty?)
1435
+
1436
+ TestFiles::ASCII_TEST_FILES.each {
1437
+ |filename|
1438
+ zf.add(filename, filename)
1439
+ assert_contains(zf, filename)
1440
+ }
1441
+ assert_equal(zf.entries.sort.map { |e| e.name }, TestFiles::ASCII_TEST_FILES)
1442
+
1443
+ zf.rename(TestFiles::ASCII_TEST_FILES[0], "newName")
1444
+ assert_not_contains(zf, TestFiles::ASCII_TEST_FILES[0])
1445
+ assert_contains(zf, "newName")
1446
+ ensure
1447
+ zf.close
1448
+ end
1449
+ begin
1450
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1451
+ asciiTestFiles = TestFiles::ASCII_TEST_FILES.dup
1452
+ asciiTestFiles.shift
1453
+ asciiTestFiles.each {
1454
+ |filename|
1455
+ assert_contains(zf, filename)
1456
+ }
1457
+
1458
+ assert_contains(zf, "newName")
1459
+ ensure
1460
+ zfRead.close
1461
+ end
1462
+ end
1463
+
1464
+ private
1465
+ def assert_contains(zf, entryName, filename = entryName)
1466
+ assert(zf.entries.detect { |e| e.name == entryName} != nil, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}")
1467
+ assert_entryContents(zf, entryName, filename) if File.exists?(filename)
1468
+ end
1469
+
1470
+ def assert_not_contains(zf, entryName)
1471
+ assert(zf.entries.detect { |e| e.name == entryName} == nil, "entry #{entryName} in #{zf.entries.join(', ')} in zip file #{zf}")
1472
+ end
1473
+ end
1474
+
1475
+ class ZipFileExtractTest < Test::Unit::TestCase
1476
+ include CommonZipFileFixture
1477
+ EXTRACTED_FILENAME = "extEntry"
1478
+ ENTRY_TO_EXTRACT, *REMAINING_ENTRIES = TEST_ZIP.entry_names.reverse
1479
+
1480
+ def setup
1481
+ super
1482
+ File.delete(EXTRACTED_FILENAME) if File.exists?(EXTRACTED_FILENAME)
1483
+ end
1484
+
1485
+ def test_extract
1486
+ ZipFile.open(TEST_ZIP.zip_name) {
1487
+ |zf|
1488
+ zf.extract(ENTRY_TO_EXTRACT, EXTRACTED_FILENAME)
1489
+
1490
+ assert(File.exists?(EXTRACTED_FILENAME))
1491
+ AssertEntry::assert_contents(EXTRACTED_FILENAME,
1492
+ zf.get_input_stream(ENTRY_TO_EXTRACT) { |is| is.read })
1493
+
1494
+
1495
+ File::unlink(EXTRACTED_FILENAME)
1496
+
1497
+ entry = zf.get_entry(ENTRY_TO_EXTRACT)
1498
+ entry.extract(EXTRACTED_FILENAME)
1499
+
1500
+ assert(File.exists?(EXTRACTED_FILENAME))
1501
+ AssertEntry::assert_contents(EXTRACTED_FILENAME,
1502
+ entry.get_input_stream() { |is| is.read })
1503
+
1504
+ }
1505
+ end
1506
+
1507
+ def test_extractExists
1508
+ writtenText = "written text"
1509
+ File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
1510
+
1511
+ assert_raise(ZipDestinationFileExistsError) {
1512
+ ZipFile.open(TEST_ZIP.zip_name) {
1513
+ |zf|
1514
+ zf.extract(zf.entries.first, EXTRACTED_FILENAME)
1515
+ }
1516
+ }
1517
+ File.open(EXTRACTED_FILENAME, "r") {
1518
+ |f|
1519
+ assert_equal(writtenText, f.read)
1520
+ }
1521
+ end
1522
+
1523
+ def test_extractExistsOverwrite
1524
+ writtenText = "written text"
1525
+ File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
1526
+
1527
+ gotCalledCorrectly = false
1528
+ ZipFile.open(TEST_ZIP.zip_name) {
1529
+ |zf|
1530
+ zf.extract(zf.entries.first, EXTRACTED_FILENAME) {
1531
+ |entry, extractLoc|
1532
+ gotCalledCorrectly = zf.entries.first == entry &&
1533
+ extractLoc == EXTRACTED_FILENAME
1534
+ true
1535
+ }
1536
+ }
1537
+
1538
+ assert(gotCalledCorrectly)
1539
+ File.open(EXTRACTED_FILENAME, "r") {
1540
+ |f|
1541
+ assert(writtenText != f.read)
1542
+ }
1543
+ end
1544
+
1545
+ def test_extractNonEntry
1546
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1547
+ assert_raise(Errno::ENOENT) { zf.extract("nonExistingEntry", "nonExistingEntry") }
1548
+ ensure
1549
+ zf.close if zf
1550
+ end
1551
+
1552
+ def test_extractNonEntry2
1553
+ outFile = "outfile"
1554
+ assert_raise(Errno::ENOENT) {
1555
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1556
+ nonEntry = "hotdog-diddelidoo"
1557
+ assert(! zf.entries.include?(nonEntry))
1558
+ zf.extract(nonEntry, outFile)
1559
+ zf.close
1560
+ }
1561
+ assert(! File.exists?(outFile))
1562
+ end
1563
+
1564
+ end
1565
+
1566
+ class ZipFileExtractDirectoryTest < Test::Unit::TestCase
1567
+ include CommonZipFileFixture
1568
+ TEST_OUT_NAME = "emptyOutDir"
1569
+
1570
+ def open_zip(&aProc)
1571
+ assert(aProc != nil)
1572
+ ZipFile.open(TestZipFile::TEST_ZIP4.zip_name, &aProc)
1573
+ end
1574
+
1575
+ def extract_test_dir(&aProc)
1576
+ open_zip {
1577
+ |zf|
1578
+ zf.extract(TestFiles::EMPTY_TEST_DIR, TEST_OUT_NAME, &aProc)
1579
+ }
1580
+ end
1581
+
1582
+ def setup
1583
+ super
1584
+
1585
+ Dir.rmdir(TEST_OUT_NAME) if File.directory? TEST_OUT_NAME
1586
+ File.delete(TEST_OUT_NAME) if File.exists? TEST_OUT_NAME
1587
+ end
1588
+
1589
+ def test_extractDirectory
1590
+ extract_test_dir
1591
+ assert(File.directory?(TEST_OUT_NAME))
1592
+ end
1593
+
1594
+ def test_extractDirectoryExistsAsDir
1595
+ Dir.mkdir TEST_OUT_NAME
1596
+ extract_test_dir
1597
+ assert(File.directory?(TEST_OUT_NAME))
1598
+ end
1599
+
1600
+ def test_extractDirectoryExistsAsFile
1601
+ File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
1602
+ assert_raise(ZipDestinationFileExistsError) { extract_test_dir }
1603
+ end
1604
+
1605
+ def test_extractDirectoryExistsAsFileOverwrite
1606
+ File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
1607
+ gotCalled = false
1608
+ extract_test_dir {
1609
+ |entry, destPath|
1610
+ gotCalled = true
1611
+ assert_equal(TEST_OUT_NAME, destPath)
1612
+ assert(entry.is_directory)
1613
+ true
1614
+ }
1615
+ assert(gotCalled)
1616
+ assert(File.directory?(TEST_OUT_NAME))
1617
+ end
1618
+ end
1619
+
1620
+ class ZipExtraFieldTest < Test::Unit::TestCase
1621
+ def test_new
1622
+ extra_pure = ZipExtraField.new("")
1623
+ extra_withstr = ZipExtraField.new("foo")
1624
+ assert_instance_of(ZipExtraField, extra_pure)
1625
+ assert_instance_of(ZipExtraField, extra_withstr)
1626
+ end
1627
+
1628
+ def test_unknownfield
1629
+ extra = ZipExtraField.new("foo")
1630
+ assert_equal(extra["Unknown"], "foo")
1631
+ extra.merge("a")
1632
+ assert_equal(extra["Unknown"], "fooa")
1633
+ extra.merge("barbaz")
1634
+ assert_equal(extra.to_s, "fooabarbaz")
1635
+ end
1636
+
1637
+
1638
+ def test_merge
1639
+ str = "UT\x5\0\x3\250$\r@Ux\0\0"
1640
+ extra1 = ZipExtraField.new("")
1641
+ extra2 = ZipExtraField.new(str)
1642
+ assert(! extra1.member?("UniversalTime"))
1643
+ assert(extra2.member?("UniversalTime"))
1644
+ extra1.merge(str)
1645
+ assert_equal(extra1["UniversalTime"].mtime, extra2["UniversalTime"].mtime)
1646
+ end
1647
+
1648
+ def test_length
1649
+ str = "UT\x5\0\x3\250$\r@Ux\0\0Te\0\0testit"
1650
+ extra = ZipExtraField.new(str)
1651
+ assert_equal(extra.local_length, extra.to_local_bin.length)
1652
+ assert_equal(extra.c_dir_length, extra.to_c_dir_bin.length)
1653
+ extra.merge("foo")
1654
+ assert_equal(extra.local_length, extra.to_local_bin.length)
1655
+ assert_equal(extra.c_dir_length, extra.to_c_dir_bin.length)
1656
+ end
1657
+
1658
+
1659
+ def test_to_s
1660
+ str = "UT\x5\0\x3\250$\r@Ux\0\0Te\0\0testit"
1661
+ extra = ZipExtraField.new(str)
1662
+ assert_instance_of(String, extra.to_s)
1663
+
1664
+ s = extra.to_s
1665
+ extra.merge("foo")
1666
+ assert_equal(s.length + 3, extra.to_s.length)
1667
+ end
1668
+
1669
+ def test_equality
1670
+ str = "UT\x5\0\x3\250$\r@"
1671
+ extra1 = ZipExtraField.new(str)
1672
+ extra2 = ZipExtraField.new(str)
1673
+ extra3 = ZipExtraField.new(str)
1674
+ assert_equal(extra1, extra2)
1675
+
1676
+ extra2["UniversalTime"].mtime = Time.now
1677
+ assert(extra1 != extra2)
1678
+
1679
+ extra3.create("IUnix")
1680
+ assert(extra1 != extra3)
1681
+
1682
+ extra1.create("IUnix")
1683
+ assert_equal(extra1, extra3)
1684
+ end
1685
+
1686
+ end
1687
+
1688
+ # Copyright (C) 2002-2005 Thomas Sondergaard
1689
+ # rubyzip is free software; you can redistribute it and/or
1690
+ # modify it under the terms of the ruby license.