febeling-rubyzip 0.9.2

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.
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $VERBOSE = true
4
+
5
+ $: << "../lib"
6
+
7
+ require 'test/unit'
8
+ require 'zip/ziprequire'
9
+
10
+ $: << 'data/rubycode.zip' << 'data/rubycode2.zip'
11
+
12
+ class ZipRequireTest < Test::Unit::TestCase
13
+ def test_require
14
+ assert(require('data/notzippedruby'))
15
+ assert(!require('data/notzippedruby'))
16
+
17
+ assert(require('zippedruby1'))
18
+ assert(!require('zippedruby1'))
19
+
20
+ assert(require('zippedruby2'))
21
+ assert(!require('zippedruby2'))
22
+
23
+ assert(require('zippedruby3'))
24
+ assert(!require('zippedruby3'))
25
+
26
+ c1 = NotZippedRuby.new
27
+ assert(c1.returnTrue)
28
+ assert(ZippedRuby1.returnTrue)
29
+ assert(!ZippedRuby2.returnFalse)
30
+ assert_equal(4, ZippedRuby3.multiplyValues(2, 2))
31
+ end
32
+
33
+ def test_get_resource
34
+ get_resource("aResource.txt") {
35
+ |f|
36
+ assert_equal("Nothing exciting in this file!", f.read)
37
+ }
38
+ end
39
+ end
40
+
41
+ # Copyright (C) 2002 Thomas Sondergaard
42
+ # rubyzip is free software; you can redistribute it and/or
43
+ # modify it under the terms of the ruby license.
@@ -0,0 +1,1602 @@
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
+ end
407
+
408
+ def test_openWithBlock
409
+ ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
410
+ |zis|
411
+ assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
412
+ assert_equal(true, zis.eof?)
413
+ }
414
+ end
415
+
416
+ def test_openWithoutBlock
417
+ zis = ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name)
418
+ assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
419
+ end
420
+
421
+ def test_incompleteReads
422
+ ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
423
+ |zis|
424
+ entry = zis.get_next_entry # longAscii.txt
425
+ assert_equal(false, zis.eof?)
426
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names[0], entry.name)
427
+ assert zis.gets.length > 0
428
+ assert_equal(false, zis.eof?)
429
+ entry = zis.get_next_entry # empty.txt
430
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names[1], entry.name)
431
+ assert_equal(0, entry.size)
432
+ assert_equal(nil, zis.gets)
433
+ assert_equal(true, zis.eof?)
434
+ entry = zis.get_next_entry # empty_chmod640.txt
435
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names[2], entry.name)
436
+ assert_equal(0, entry.size)
437
+ assert_equal(nil, zis.gets)
438
+ assert_equal(true, zis.eof?)
439
+ entry = zis.get_next_entry # short.txt
440
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names[3], entry.name)
441
+ assert zis.gets.length > 0
442
+ entry = zis.get_next_entry # longBinary.bin
443
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names[4], entry.name)
444
+ assert zis.gets.length > 0
445
+ }
446
+ end
447
+
448
+ def test_rewind
449
+ ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
450
+ |zis|
451
+ e = zis.get_next_entry
452
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names[0], e.name)
453
+
454
+ # Do a little reading
455
+ buf = ""
456
+ buf << zis.read(100)
457
+ buf << (zis.gets || "")
458
+ buf << (zis.gets || "")
459
+ assert_equal(false, zis.eof?)
460
+
461
+ zis.rewind
462
+
463
+ buf2 = ""
464
+ buf2 << zis.read(100)
465
+ buf2 << (zis.gets || "")
466
+ buf2 << (zis.gets || "")
467
+
468
+ assert_equal(buf, buf2)
469
+
470
+ zis.rewind
471
+ assert_equal(false, zis.eof?)
472
+
473
+ assert_entry(e.name, zis, e.name)
474
+ }
475
+ end
476
+
477
+ def test_mix_read_and_gets
478
+ ZipInputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
479
+ |zis|
480
+ e = zis.get_next_entry
481
+ assert_equal("#!/usr/bin/env ruby", zis.gets.chomp)
482
+ assert_equal(false, zis.eof?)
483
+ assert_equal("", zis.gets.chomp)
484
+ assert_equal(false, zis.eof?)
485
+ assert_equal("$VERBOSE =", zis.read(10))
486
+ assert_equal(false, zis.eof?)
487
+ }
488
+ end
489
+
490
+ end
491
+
492
+
493
+ module CrcTest
494
+
495
+ class TestOutputStream
496
+ include IOExtras::AbstractOutputStream
497
+
498
+ attr_accessor :buffer
499
+
500
+ def initialize
501
+ @buffer = ""
502
+ end
503
+
504
+ def << (data)
505
+ @buffer << data
506
+ self
507
+ end
508
+ end
509
+
510
+ def run_crc_test(compressorClass)
511
+ str = "Here's a nice little text to compute the crc for! Ho hum, it is nice nice nice nice indeed."
512
+ fakeOut = TestOutputStream.new
513
+
514
+ deflater = compressorClass.new(fakeOut)
515
+ deflater << str
516
+ assert_equal(0x919920fc, deflater.crc)
517
+ end
518
+ end
519
+
520
+
521
+
522
+ class PassThruCompressorTest < Test::Unit::TestCase
523
+ include CrcTest
524
+
525
+ def test_size
526
+ File.open("dummy.txt", "wb") {
527
+ |file|
528
+ compressor = PassThruCompressor.new(file)
529
+
530
+ assert_equal(0, compressor.size)
531
+
532
+ t1 = "hello world"
533
+ t2 = ""
534
+ t3 = "bingo"
535
+
536
+ compressor << t1
537
+ assert_equal(compressor.size, t1.size)
538
+
539
+ compressor << t2
540
+ assert_equal(compressor.size, t1.size + t2.size)
541
+
542
+ compressor << t3
543
+ assert_equal(compressor.size, t1.size + t2.size + t3.size)
544
+ }
545
+ end
546
+
547
+ def test_crc
548
+ run_crc_test(PassThruCompressor)
549
+ end
550
+ end
551
+
552
+ class DeflaterTest < Test::Unit::TestCase
553
+ include CrcTest
554
+
555
+ def test_outputOperator
556
+ txt = load_file("data/file2.txt")
557
+ deflate(txt, "deflatertest.bin")
558
+ inflatedTxt = inflate("deflatertest.bin")
559
+ assert_equal(txt, inflatedTxt)
560
+ end
561
+
562
+ private
563
+ def load_file(fileName)
564
+ txt = nil
565
+ File.open(fileName, "rb") { |f| txt = f.read }
566
+ end
567
+
568
+ def deflate(data, fileName)
569
+ File.open(fileName, "wb") {
570
+ |file|
571
+ deflater = Deflater.new(file)
572
+ deflater << data
573
+ deflater.finish
574
+ assert_equal(deflater.size, data.size)
575
+ file << "trailing data for zlib with -MAX_WBITS"
576
+ }
577
+ end
578
+
579
+ def inflate(fileName)
580
+ txt = nil
581
+ File.open(fileName, "rb") {
582
+ |file|
583
+ inflater = Inflater.new(file)
584
+ txt = inflater.sysread
585
+ }
586
+ end
587
+
588
+ def test_crc
589
+ run_crc_test(Deflater)
590
+ end
591
+ end
592
+
593
+ class ZipOutputStreamTest < Test::Unit::TestCase
594
+ include AssertEntry
595
+
596
+ TEST_ZIP = TestZipFile::TEST_ZIP2.clone
597
+ TEST_ZIP.zip_name = "output.zip"
598
+
599
+ def test_new
600
+ zos = ZipOutputStream.new(TEST_ZIP.zip_name)
601
+ zos.comment = TEST_ZIP.comment
602
+ write_test_zip(zos)
603
+ zos.close
604
+ assert_test_zip_contents(TEST_ZIP)
605
+ end
606
+
607
+ def test_open
608
+ ZipOutputStream.open(TEST_ZIP.zip_name) {
609
+ |zos|
610
+ zos.comment = TEST_ZIP.comment
611
+ write_test_zip(zos)
612
+ }
613
+ assert_test_zip_contents(TEST_ZIP)
614
+ end
615
+
616
+ def test_writingToClosedStream
617
+ assert_i_o_error_in_closed_stream { |zos| zos << "hello world" }
618
+ assert_i_o_error_in_closed_stream { |zos| zos.puts "hello world" }
619
+ assert_i_o_error_in_closed_stream { |zos| zos.write "hello world" }
620
+ end
621
+
622
+ def test_cannotOpenFile
623
+ name = TestFiles::EMPTY_TEST_DIR
624
+ begin
625
+ zos = ZipOutputStream.open(name)
626
+ rescue Exception
627
+ assert($!.kind_of?(Errno::EISDIR) || # Linux
628
+ $!.kind_of?(Errno::EEXIST) || # Windows/cygwin
629
+ $!.kind_of?(Errno::EACCES), # Windows
630
+ "Expected Errno::EISDIR (or on win/cygwin: Errno::EEXIST), but was: #{$!.class}")
631
+ end
632
+ end
633
+
634
+ def assert_i_o_error_in_closed_stream
635
+ assert_raise(IOError) {
636
+ zos = ZipOutputStream.new("test_putOnClosedStream.zip")
637
+ zos.close
638
+ yield zos
639
+ }
640
+ end
641
+
642
+ def write_test_zip(zos)
643
+ TEST_ZIP.entry_names.each {
644
+ |entryName|
645
+ zos.put_next_entry(entryName)
646
+ File.open(entryName, "rb") { |f| zos.write(f.read) }
647
+ }
648
+ end
649
+ end
650
+
651
+
652
+
653
+ module Enumerable
654
+ def compare_enumerables(otherEnumerable)
655
+ otherAsArray = otherEnumerable.to_a
656
+ count=0
657
+ each_with_index {
658
+ |element, index|
659
+ count = index
660
+ return false unless yield(element, otherAsArray[index])
661
+ }
662
+ return count+1 == otherAsArray.size
663
+ end
664
+ end
665
+
666
+
667
+ class ZipCentralDirectoryEntryTest < Test::Unit::TestCase
668
+
669
+ def test_read_from_stream
670
+ File.open("data/testDirectory.bin", "rb") {
671
+ |file|
672
+ entry = ZipEntry.read_c_dir_entry(file)
673
+
674
+ assert_equal("longAscii.txt", entry.name)
675
+ assert_equal(ZipEntry::DEFLATED, entry.compression_method)
676
+ assert_equal(106490, entry.size)
677
+ assert_equal(3784, entry.compressed_size)
678
+ assert_equal(0xfcd1799c, entry.crc)
679
+ assert_equal("", entry.comment)
680
+
681
+ entry = ZipEntry.read_c_dir_entry(file)
682
+ assert_equal("empty.txt", entry.name)
683
+ assert_equal(ZipEntry::STORED, entry.compression_method)
684
+ assert_equal(0, entry.size)
685
+ assert_equal(0, entry.compressed_size)
686
+ assert_equal(0x0, entry.crc)
687
+ assert_equal("", entry.comment)
688
+
689
+ entry = ZipEntry.read_c_dir_entry(file)
690
+ assert_equal("short.txt", entry.name)
691
+ assert_equal(ZipEntry::STORED, entry.compression_method)
692
+ assert_equal(6, entry.size)
693
+ assert_equal(6, entry.compressed_size)
694
+ assert_equal(0xbb76fe69, entry.crc)
695
+ assert_equal("", entry.comment)
696
+
697
+ entry = ZipEntry.read_c_dir_entry(file)
698
+ assert_equal("longBinary.bin", entry.name)
699
+ assert_equal(ZipEntry::DEFLATED, entry.compression_method)
700
+ assert_equal(1000024, entry.size)
701
+ assert_equal(70847, entry.compressed_size)
702
+ assert_equal(0x10da7d59, entry.crc)
703
+ assert_equal("", entry.comment)
704
+
705
+ entry = ZipEntry.read_c_dir_entry(file)
706
+ assert_equal(nil, entry)
707
+ # Fields that are not check by this test:
708
+ # version made by 2 bytes
709
+ # version needed to extract 2 bytes
710
+ # general purpose bit flag 2 bytes
711
+ # last mod file time 2 bytes
712
+ # last mod file date 2 bytes
713
+ # compressed size 4 bytes
714
+ # uncompressed size 4 bytes
715
+ # disk number start 2 bytes
716
+ # internal file attributes 2 bytes
717
+ # external file attributes 4 bytes
718
+ # relative offset of local header 4 bytes
719
+
720
+ # file name (variable size)
721
+ # extra field (variable size)
722
+ # file comment (variable size)
723
+
724
+ }
725
+ end
726
+
727
+ def test_ReadEntryFromTruncatedZipFile
728
+ fragment=""
729
+ File.open("data/testDirectory.bin") { |f| fragment = f.read(12) } # cdir entry header is at least 46 bytes
730
+ fragment.extend(IOizeString)
731
+ entry = ZipEntry.new
732
+ entry.read_c_dir_entry(fragment)
733
+ fail "ZipError expected"
734
+ rescue ZipError
735
+ end
736
+
737
+ end
738
+
739
+
740
+ class ZipEntrySetTest < Test::Unit::TestCase
741
+ ZIP_ENTRIES = [
742
+ ZipEntry.new("zipfile.zip", "name1", "comment1"),
743
+ ZipEntry.new("zipfile.zip", "name2", "comment1"),
744
+ ZipEntry.new("zipfile.zip", "name3", "comment1"),
745
+ ZipEntry.new("zipfile.zip", "name4", "comment1"),
746
+ ZipEntry.new("zipfile.zip", "name5", "comment1"),
747
+ ZipEntry.new("zipfile.zip", "name6", "comment1")
748
+ ]
749
+
750
+ def setup
751
+ @zipEntrySet = ZipEntrySet.new(ZIP_ENTRIES)
752
+ end
753
+
754
+ def test_include
755
+ assert(@zipEntrySet.include?(ZIP_ENTRIES.first))
756
+ assert(! @zipEntrySet.include?(ZipEntry.new("different.zip", "different", "aComment")))
757
+ end
758
+
759
+ def test_size
760
+ assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
761
+ assert_equal(ZIP_ENTRIES.size, @zipEntrySet.length)
762
+ @zipEntrySet << ZipEntry.new("a", "b", "c")
763
+ assert_equal(ZIP_ENTRIES.size + 1, @zipEntrySet.length)
764
+ end
765
+
766
+ def test_add
767
+ zes = ZipEntrySet.new
768
+ entry1 = ZipEntry.new("zf.zip", "name1")
769
+ entry2 = ZipEntry.new("zf.zip", "name2")
770
+ zes << entry1
771
+ assert(zes.include?(entry1))
772
+ zes.push(entry2)
773
+ assert(zes.include?(entry2))
774
+ end
775
+
776
+ def test_delete
777
+ assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
778
+ entry = @zipEntrySet.delete(ZIP_ENTRIES.first)
779
+ assert_equal(ZIP_ENTRIES.size - 1, @zipEntrySet.size)
780
+ assert_equal(ZIP_ENTRIES.first, entry)
781
+
782
+ entry = @zipEntrySet.delete(ZIP_ENTRIES.first)
783
+ assert_equal(ZIP_ENTRIES.size - 1, @zipEntrySet.size)
784
+ assert_nil(entry)
785
+ end
786
+
787
+ def test_each
788
+ # Tested indirectly via each_with_index
789
+ count = 0
790
+ @zipEntrySet.each_with_index {
791
+ |entry, index|
792
+ assert(ZIP_ENTRIES.include?(entry))
793
+ count = count.succ
794
+ }
795
+ assert_equal(ZIP_ENTRIES.size, count)
796
+ end
797
+
798
+ def test_entries
799
+ assert_equal(ZIP_ENTRIES.sort, @zipEntrySet.entries.sort)
800
+ end
801
+
802
+ def test_compound
803
+ newEntry = ZipEntry.new("zf.zip", "new entry", "new entry's comment")
804
+ assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
805
+ @zipEntrySet << newEntry
806
+ assert_equal(ZIP_ENTRIES.size + 1, @zipEntrySet.size)
807
+ assert(@zipEntrySet.include?(newEntry))
808
+
809
+ @zipEntrySet.delete(newEntry)
810
+ assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
811
+ end
812
+
813
+ def test_dup
814
+ copy = @zipEntrySet.dup
815
+ assert_equal(@zipEntrySet, copy)
816
+
817
+ # demonstrate that this is a deep copy
818
+ copy.entries[0].name = "a totally different name"
819
+ assert(@zipEntrySet != copy)
820
+ end
821
+
822
+ def test_parent
823
+ entries = [
824
+ ZipEntry.new("zf.zip", "a"),
825
+ ZipEntry.new("zf.zip", "a/"),
826
+ ZipEntry.new("zf.zip", "a/b"),
827
+ ZipEntry.new("zf.zip", "a/b/"),
828
+ ZipEntry.new("zf.zip", "a/b/c"),
829
+ ZipEntry.new("zf.zip", "a/b/c/")
830
+ ]
831
+ entrySet = ZipEntrySet.new(entries)
832
+
833
+ assert_equal(nil, entrySet.parent(entries[0]))
834
+ assert_equal(nil, entrySet.parent(entries[1]))
835
+ assert_equal(entries[1], entrySet.parent(entries[2]))
836
+ assert_equal(entries[1], entrySet.parent(entries[3]))
837
+ assert_equal(entries[3], entrySet.parent(entries[4]))
838
+ assert_equal(entries[3], entrySet.parent(entries[5]))
839
+ end
840
+
841
+ def test_glob
842
+ res = @zipEntrySet.glob('name[2-4]')
843
+ assert_equal(3, res.size)
844
+ assert_equal(ZIP_ENTRIES[1,3], res)
845
+ end
846
+
847
+ def test_glob2
848
+ entries = [
849
+ ZipEntry.new("zf.zip", "a/"),
850
+ ZipEntry.new("zf.zip", "a/b/b1"),
851
+ ZipEntry.new("zf.zip", "a/b/c/"),
852
+ ZipEntry.new("zf.zip", "a/b/c/c1")
853
+ ]
854
+ entrySet = ZipEntrySet.new(entries)
855
+
856
+ assert_equal(entries[0,1], entrySet.glob("*"))
857
+ # assert_equal(entries[FIXME], entrySet.glob("**"))
858
+ # res = entrySet.glob('a*')
859
+ # assert_equal(entries.size, res.size)
860
+ # assert_equal(entrySet.map { |e| e.name }, res.map { |e| e.name })
861
+ end
862
+ end
863
+
864
+
865
+ class ZipCentralDirectoryTest < Test::Unit::TestCase
866
+
867
+ def test_read_from_stream
868
+ File.open(TestZipFile::TEST_ZIP2.zip_name, "rb") {
869
+ |zipFile|
870
+ cdir = ZipCentralDirectory.read_from_stream(zipFile)
871
+
872
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names.size, cdir.size)
873
+ assert(cdir.entries.sort.compare_enumerables(TestZipFile::TEST_ZIP2.entry_names.sort) {
874
+ |cdirEntry, testEntryName|
875
+ cdirEntry.name == testEntryName
876
+ })
877
+ assert_equal(TestZipFile::TEST_ZIP2.comment, cdir.comment)
878
+ }
879
+ end
880
+
881
+ def test_readFromInvalidStream
882
+ File.open("data/file2.txt", "rb") {
883
+ |zipFile|
884
+ cdir = ZipCentralDirectory.new
885
+ cdir.read_from_stream(zipFile)
886
+ }
887
+ fail "ZipError expected!"
888
+ rescue ZipError
889
+ end
890
+
891
+ def test_ReadFromTruncatedZipFile
892
+ fragment=""
893
+ File.open("data/testDirectory.bin") { |f| fragment = f.read }
894
+ fragment.slice!(12) # removed part of first cdir entry. eocd structure still complete
895
+ fragment.extend(IOizeString)
896
+ entry = ZipCentralDirectory.new
897
+ entry.read_from_stream(fragment)
898
+ fail "ZipError expected"
899
+ rescue ZipError
900
+ end
901
+
902
+ def test_write_to_stream
903
+ entries = [ ZipEntry.new("file.zip", "flimse", "myComment", "somethingExtra"),
904
+ ZipEntry.new("file.zip", "secondEntryName"),
905
+ ZipEntry.new("file.zip", "lastEntry.txt", "Has a comment too") ]
906
+ cdir = ZipCentralDirectory.new(entries, "my zip comment")
907
+ File.open("cdirtest.bin", "wb") { |f| cdir.write_to_stream(f) }
908
+ cdirReadback = ZipCentralDirectory.new
909
+ File.open("cdirtest.bin", "rb") { |f| cdirReadback.read_from_stream(f) }
910
+
911
+ assert_equal(cdir.entries.sort, cdirReadback.entries.sort)
912
+ end
913
+
914
+ def test_equality
915
+ cdir1 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
916
+ "somethingExtra"),
917
+ ZipEntry.new("file.zip", "secondEntryName"),
918
+ ZipEntry.new("file.zip", "lastEntry.txt") ],
919
+ "my zip comment")
920
+ cdir2 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
921
+ "somethingExtra"),
922
+ ZipEntry.new("file.zip", "secondEntryName"),
923
+ ZipEntry.new("file.zip", "lastEntry.txt") ],
924
+ "my zip comment")
925
+ cdir3 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
926
+ "somethingExtra"),
927
+ ZipEntry.new("file.zip", "secondEntryName"),
928
+ ZipEntry.new("file.zip", "lastEntry.txt") ],
929
+ "comment?")
930
+ cdir4 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
931
+ "somethingExtra"),
932
+ ZipEntry.new("file.zip", "lastEntry.txt") ],
933
+ "comment?")
934
+ assert_equal(cdir1, cdir1)
935
+ assert_equal(cdir1, cdir2)
936
+
937
+ assert(cdir1 != cdir3)
938
+ assert(cdir2 != cdir3)
939
+ assert(cdir2 != cdir3)
940
+ assert(cdir3 != cdir4)
941
+
942
+ assert(cdir3 != "hello")
943
+ end
944
+ end
945
+
946
+
947
+ class BasicZipFileTest < Test::Unit::TestCase
948
+ include AssertEntry
949
+
950
+ def setup
951
+ @zipFile = ZipFile.new(TestZipFile::TEST_ZIP2.zip_name)
952
+ @testEntryNameIndex=0
953
+ end
954
+
955
+ def test_entries
956
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names.sort,
957
+ @zipFile.entries.entries.sort.map {|e| e.name} )
958
+ end
959
+
960
+ def test_each
961
+ count = 0
962
+ visited = {}
963
+ @zipFile.each {
964
+ |entry|
965
+ assert(TestZipFile::TEST_ZIP2.entry_names.include?(entry.name))
966
+ assert(! visited.include?(entry.name))
967
+ visited[entry.name] = nil
968
+ count = count.succ
969
+ }
970
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
971
+ end
972
+
973
+ def test_foreach
974
+ count = 0
975
+ visited = {}
976
+ ZipFile.foreach(TestZipFile::TEST_ZIP2.zip_name) {
977
+ |entry|
978
+ assert(TestZipFile::TEST_ZIP2.entry_names.include?(entry.name))
979
+ assert(! visited.include?(entry.name))
980
+ visited[entry.name] = nil
981
+ count = count.succ
982
+ }
983
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
984
+ end
985
+
986
+ def test_get_input_stream
987
+ count = 0
988
+ visited = {}
989
+ @zipFile.each {
990
+ |entry|
991
+ assert_entry(entry.name, @zipFile.get_input_stream(entry), entry.name)
992
+ assert(! visited.include?(entry.name))
993
+ visited[entry.name] = nil
994
+ count = count.succ
995
+ }
996
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
997
+ end
998
+
999
+ def test_get_input_streamBlock
1000
+ fileAndEntryName = @zipFile.entries.first.name
1001
+ @zipFile.get_input_stream(fileAndEntryName) {
1002
+ |zis|
1003
+ assert_entryContentsForStream(fileAndEntryName,
1004
+ zis,
1005
+ fileAndEntryName)
1006
+ }
1007
+ end
1008
+ end
1009
+
1010
+ module CommonZipFileFixture
1011
+ include AssertEntry
1012
+
1013
+ EMPTY_FILENAME = "emptyZipFile.zip"
1014
+
1015
+ TEST_ZIP = TestZipFile::TEST_ZIP2.clone
1016
+ TEST_ZIP.zip_name = "5entry_copy.zip"
1017
+
1018
+ def setup
1019
+ File.delete(EMPTY_FILENAME) if File.exists?(EMPTY_FILENAME)
1020
+ FileUtils.copy(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name)
1021
+ end
1022
+ end
1023
+
1024
+ class ZipFileTest < Test::Unit::TestCase
1025
+ include CommonZipFileFixture
1026
+
1027
+ def test_createFromScratch
1028
+ comment = "a short comment"
1029
+
1030
+ zf = ZipFile.new(EMPTY_FILENAME, ZipFile::CREATE)
1031
+ zf.get_output_stream("myFile") { |os| os.write "myFile contains just this" }
1032
+ zf.mkdir("dir1")
1033
+ zf.comment = comment
1034
+ zf.close
1035
+
1036
+ zfRead = ZipFile.new(EMPTY_FILENAME)
1037
+ assert_equal(comment, zfRead.comment)
1038
+ assert_equal(2, zfRead.entries.length)
1039
+ end
1040
+
1041
+ def test_get_output_stream
1042
+ entryCount = nil
1043
+ ZipFile.open(TEST_ZIP.zip_name) {
1044
+ |zf|
1045
+ entryCount = zf.size
1046
+ zf.get_output_stream('newEntry.txt') {
1047
+ |os|
1048
+ os.write "Putting stuff in newEntry.txt"
1049
+ }
1050
+ assert_equal(entryCount+1, zf.size)
1051
+ assert_equal("Putting stuff in newEntry.txt", zf.read("newEntry.txt"))
1052
+
1053
+ zf.get_output_stream(zf.get_entry('data/generated/empty.txt')) {
1054
+ |os|
1055
+ os.write "Putting stuff in data/generated/empty.txt"
1056
+ }
1057
+ assert_equal(entryCount+1, zf.size)
1058
+ assert_equal("Putting stuff in data/generated/empty.txt", zf.read("data/generated/empty.txt"))
1059
+
1060
+ zf.get_output_stream('entry.bin') {
1061
+ |os|
1062
+ os.write(File.open('data/generated/5entry.zip', 'rb').read)
1063
+ }
1064
+ }
1065
+
1066
+ ZipFile.open(TEST_ZIP.zip_name) {
1067
+ |zf|
1068
+ assert_equal(entryCount+2, zf.size)
1069
+ assert_equal("Putting stuff in newEntry.txt", zf.read("newEntry.txt"))
1070
+ assert_equal("Putting stuff in data/generated/empty.txt", zf.read("data/generated/empty.txt"))
1071
+ assert_equal(File.open('data/generated/5entry.zip', 'rb').read, zf.read("entry.bin"))
1072
+ }
1073
+ end
1074
+
1075
+ def test_add
1076
+ srcFile = "data/file2.txt"
1077
+ entryName = "newEntryName.rb"
1078
+ assert(File.exists?(srcFile))
1079
+ zf = ZipFile.new(EMPTY_FILENAME, ZipFile::CREATE)
1080
+ zf.add(entryName, srcFile)
1081
+ zf.close
1082
+
1083
+ zfRead = ZipFile.new(EMPTY_FILENAME)
1084
+ assert_equal("", zfRead.comment)
1085
+ assert_equal(1, zfRead.entries.length)
1086
+ assert_equal(entryName, zfRead.entries.first.name)
1087
+ AssertEntry.assert_contents(srcFile,
1088
+ zfRead.get_input_stream(entryName) { |zis| zis.read })
1089
+ end
1090
+
1091
+ def test_addExistingEntryName
1092
+ assert_raise(ZipEntryExistsError) {
1093
+ ZipFile.open(TEST_ZIP.zip_name) {
1094
+ |zf|
1095
+ zf.add(zf.entries.first.name, "data/file2.txt")
1096
+ }
1097
+ }
1098
+ end
1099
+
1100
+ def test_addExistingEntryNameReplace
1101
+ gotCalled = false
1102
+ replacedEntry = nil
1103
+ ZipFile.open(TEST_ZIP.zip_name) {
1104
+ |zf|
1105
+ replacedEntry = zf.entries.first.name
1106
+ zf.add(replacedEntry, "data/file2.txt") { gotCalled = true; true }
1107
+ }
1108
+ assert(gotCalled)
1109
+ ZipFile.open(TEST_ZIP.zip_name) {
1110
+ |zf|
1111
+ assert_contains(zf, replacedEntry, "data/file2.txt")
1112
+ }
1113
+ end
1114
+
1115
+ def test_addDirectory
1116
+ ZipFile.open(TEST_ZIP.zip_name) {
1117
+ |zf|
1118
+ zf.add(TestFiles::EMPTY_TEST_DIR, TestFiles::EMPTY_TEST_DIR)
1119
+ }
1120
+ ZipFile.open(TEST_ZIP.zip_name) {
1121
+ |zf|
1122
+ dirEntry = zf.entries.detect { |e| e.name == TestFiles::EMPTY_TEST_DIR+"/" }
1123
+ assert(dirEntry.is_directory)
1124
+ }
1125
+ end
1126
+
1127
+ def test_remove
1128
+ entryToRemove, *remainingEntries = TEST_ZIP.entry_names
1129
+
1130
+ FileUtils.copy(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name)
1131
+
1132
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1133
+ assert(zf.entries.map { |e| e.name }.include?(entryToRemove))
1134
+ zf.remove(entryToRemove)
1135
+ assert(! zf.entries.map { |e| e.name }.include?(entryToRemove))
1136
+ assert_equal(zf.entries.map {|x| x.name }.sort, remainingEntries.sort)
1137
+ zf.close
1138
+
1139
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1140
+ assert(! zfRead.entries.map { |e| e.name }.include?(entryToRemove))
1141
+ assert_equal(zfRead.entries.map {|x| x.name }.sort, remainingEntries.sort)
1142
+ zfRead.close
1143
+ end
1144
+
1145
+
1146
+ def test_rename
1147
+ entryToRename, *remainingEntries = TEST_ZIP.entry_names
1148
+
1149
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1150
+ assert(zf.entries.map { |e| e.name }.include?(entryToRename))
1151
+
1152
+ newName = "changed entry name"
1153
+ assert(! zf.entries.map { |e| e.name }.include?(newName))
1154
+
1155
+ zf.rename(entryToRename, newName)
1156
+ assert(zf.entries.map { |e| e.name }.include?(newName))
1157
+
1158
+ zf.close
1159
+
1160
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1161
+ assert(zfRead.entries.map { |e| e.name }.include?(newName))
1162
+ File.delete(ZipFileExtractTest::EXTRACTED_FILENAME) if File.exists?(ZipFileExtractTest::EXTRACTED_FILENAME)
1163
+ zf.extract(newName, ZipFileExtractTest::EXTRACTED_FILENAME)
1164
+ zfRead.close
1165
+ end
1166
+
1167
+ def test_renameToExistingEntry
1168
+ oldEntries = nil
1169
+ ZipFile.open(TEST_ZIP.zip_name) { |zf| oldEntries = zf.entries }
1170
+
1171
+ assert_raise(ZipEntryExistsError) {
1172
+ ZipFile.open(TEST_ZIP.zip_name) {
1173
+ |zf|
1174
+ zf.rename(zf.entries[0], zf.entries[1].name)
1175
+ }
1176
+ }
1177
+
1178
+ ZipFile.open(TEST_ZIP.zip_name) {
1179
+ |zf|
1180
+ assert_equal(oldEntries.sort.map{ |e| e.name }, zf.entries.sort.map{ |e| e.name })
1181
+ }
1182
+ end
1183
+
1184
+ def test_renameToExistingEntryOverwrite
1185
+ oldEntries = nil
1186
+ ZipFile.open(TEST_ZIP.zip_name) { |zf| oldEntries = zf.entries }
1187
+
1188
+ gotCalled = false
1189
+ renamedEntryName = nil
1190
+ ZipFile.open(TEST_ZIP.zip_name) {
1191
+ |zf|
1192
+ renamedEntryName = zf.entries[0].name
1193
+ zf.rename(zf.entries[0], zf.entries[1].name) { gotCalled = true; true }
1194
+ }
1195
+
1196
+ assert(gotCalled)
1197
+ oldEntries.delete_if { |e| e.name == renamedEntryName }
1198
+ ZipFile.open(TEST_ZIP.zip_name) {
1199
+ |zf|
1200
+ assert_equal(oldEntries.sort.map{ |e| e.name },
1201
+ zf.entries.sort.map{ |e| e.name })
1202
+ }
1203
+ end
1204
+
1205
+ def test_renameNonEntry
1206
+ nonEntry = "bogusEntry"
1207
+ target_entry = "target_entryName"
1208
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1209
+ assert(! zf.entries.include?(nonEntry))
1210
+ assert_raise(Errno::ENOENT) {
1211
+ zf.rename(nonEntry, target_entry)
1212
+ }
1213
+ zf.commit
1214
+ assert(! zf.entries.include?(target_entry))
1215
+ ensure
1216
+ zf.close
1217
+ end
1218
+
1219
+ def test_renameEntryToExistingEntry
1220
+ entry1, entry2, *remaining = TEST_ZIP.entry_names
1221
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1222
+ assert_raise(ZipEntryExistsError) {
1223
+ zf.rename(entry1, entry2)
1224
+ }
1225
+ ensure
1226
+ zf.close
1227
+ end
1228
+
1229
+ def test_replace
1230
+ entryToReplace = TEST_ZIP.entry_names[2]
1231
+ newEntrySrcFilename = "data/file2.txt"
1232
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1233
+ zf.replace(entryToReplace, newEntrySrcFilename)
1234
+
1235
+ zf.close
1236
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1237
+ AssertEntry::assert_contents(newEntrySrcFilename,
1238
+ zfRead.get_input_stream(entryToReplace) { |is| is.read })
1239
+ AssertEntry::assert_contents(TEST_ZIP.entry_names[0],
1240
+ zfRead.get_input_stream(TEST_ZIP.entry_names[0]) { |is| is.read })
1241
+ AssertEntry::assert_contents(TEST_ZIP.entry_names[1],
1242
+ zfRead.get_input_stream(TEST_ZIP.entry_names[1]) { |is| is.read })
1243
+ AssertEntry::assert_contents(TEST_ZIP.entry_names[3],
1244
+ zfRead.get_input_stream(TEST_ZIP.entry_names[3]) { |is| is.read })
1245
+ zfRead.close
1246
+ end
1247
+
1248
+ def test_replaceNonEntry
1249
+ entryToReplace = "nonExistingEntryname"
1250
+ ZipFile.open(TEST_ZIP.zip_name) {
1251
+ |zf|
1252
+ assert_raise(Errno::ENOENT) {
1253
+ zf.replace(entryToReplace, "data/file2.txt")
1254
+ }
1255
+ }
1256
+ end
1257
+
1258
+ def test_commit
1259
+ newName = "renamedFirst"
1260
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1261
+ oldName = zf.entries.first
1262
+ zf.rename(oldName, newName)
1263
+ zf.commit
1264
+
1265
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1266
+ assert(zfRead.entries.detect { |e| e.name == newName } != nil)
1267
+ assert(zfRead.entries.detect { |e| e.name == oldName } == nil)
1268
+ zfRead.close
1269
+
1270
+ zf.close
1271
+ end
1272
+
1273
+ # This test tests that after commit, you
1274
+ # can delete the file you used to add the entry to the zip file
1275
+ # with
1276
+ def test_commitUseZipEntry
1277
+ FileUtils.copy(TestFiles::RANDOM_ASCII_FILE1, "okToDelete.txt")
1278
+ zf = ZipFile.open(TEST_ZIP.zip_name)
1279
+ zf.add("okToDelete.txt", "okToDelete.txt")
1280
+ assert_contains(zf, "okToDelete.txt")
1281
+ zf.commit
1282
+ FileUtils.move("okToDelete.txt", "okToDeleteMoved.txt")
1283
+ assert_contains(zf, "okToDelete.txt", "okToDeleteMoved.txt")
1284
+ end
1285
+
1286
+ # def test_close
1287
+ # zf = ZipFile.new(TEST_ZIP.zip_name)
1288
+ # zf.close
1289
+ # assert_raise(IOError) {
1290
+ # zf.extract(TEST_ZIP.entry_names.first, "hullubullu")
1291
+ # }
1292
+ # end
1293
+
1294
+ def test_compound1
1295
+ renamedName = "renamedName"
1296
+ originalEntries = []
1297
+ begin
1298
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1299
+ originalEntries = zf.entries.dup
1300
+
1301
+ assert_not_contains(zf, TestFiles::RANDOM_ASCII_FILE1)
1302
+ zf.add(TestFiles::RANDOM_ASCII_FILE1,
1303
+ TestFiles::RANDOM_ASCII_FILE1)
1304
+ assert_contains(zf, TestFiles::RANDOM_ASCII_FILE1)
1305
+
1306
+ zf.rename(zf.entries[0], renamedName)
1307
+ assert_contains(zf, renamedName)
1308
+
1309
+ TestFiles::BINARY_TEST_FILES.each {
1310
+ |filename|
1311
+ zf.add(filename, filename)
1312
+ assert_contains(zf, filename)
1313
+ }
1314
+
1315
+ assert_contains(zf, originalEntries.last.to_s)
1316
+ zf.remove(originalEntries.last.to_s)
1317
+ assert_not_contains(zf, originalEntries.last.to_s)
1318
+
1319
+ ensure
1320
+ zf.close
1321
+ end
1322
+ begin
1323
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1324
+ assert_contains(zfRead, TestFiles::RANDOM_ASCII_FILE1)
1325
+ assert_contains(zfRead, renamedName)
1326
+ TestFiles::BINARY_TEST_FILES.each {
1327
+ |filename|
1328
+ assert_contains(zfRead, filename)
1329
+ }
1330
+ assert_not_contains(zfRead, originalEntries.last.to_s)
1331
+ ensure
1332
+ zfRead.close
1333
+ end
1334
+ end
1335
+
1336
+ def test_compound2
1337
+ begin
1338
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1339
+ originalEntries = zf.entries.dup
1340
+
1341
+ originalEntries.each {
1342
+ |entry|
1343
+ zf.remove(entry)
1344
+ assert_not_contains(zf, entry)
1345
+ }
1346
+ assert(zf.entries.empty?)
1347
+
1348
+ TestFiles::ASCII_TEST_FILES.each {
1349
+ |filename|
1350
+ zf.add(filename, filename)
1351
+ assert_contains(zf, filename)
1352
+ }
1353
+ assert_equal(zf.entries.sort.map { |e| e.name }, TestFiles::ASCII_TEST_FILES)
1354
+
1355
+ zf.rename(TestFiles::ASCII_TEST_FILES[0], "newName")
1356
+ assert_not_contains(zf, TestFiles::ASCII_TEST_FILES[0])
1357
+ assert_contains(zf, "newName")
1358
+ ensure
1359
+ zf.close
1360
+ end
1361
+ begin
1362
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1363
+ asciiTestFiles = TestFiles::ASCII_TEST_FILES.dup
1364
+ asciiTestFiles.shift
1365
+ asciiTestFiles.each {
1366
+ |filename|
1367
+ assert_contains(zf, filename)
1368
+ }
1369
+
1370
+ assert_contains(zf, "newName")
1371
+ ensure
1372
+ zfRead.close
1373
+ end
1374
+ end
1375
+
1376
+ private
1377
+ def assert_contains(zf, entryName, filename = entryName)
1378
+ assert(zf.entries.detect { |e| e.name == entryName} != nil, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}")
1379
+ assert_entryContents(zf, entryName, filename) if File.exists?(filename)
1380
+ end
1381
+
1382
+ def assert_not_contains(zf, entryName)
1383
+ assert(zf.entries.detect { |e| e.name == entryName} == nil, "entry #{entryName} in #{zf.entries.join(', ')} in zip file #{zf}")
1384
+ end
1385
+ end
1386
+
1387
+ class ZipFileExtractTest < Test::Unit::TestCase
1388
+ include CommonZipFileFixture
1389
+ EXTRACTED_FILENAME = "extEntry"
1390
+ ENTRY_TO_EXTRACT, *REMAINING_ENTRIES = TEST_ZIP.entry_names.reverse
1391
+
1392
+ def setup
1393
+ super
1394
+ File.delete(EXTRACTED_FILENAME) if File.exists?(EXTRACTED_FILENAME)
1395
+ end
1396
+
1397
+ def test_extract
1398
+ ZipFile.open(TEST_ZIP.zip_name) {
1399
+ |zf|
1400
+ zf.extract(ENTRY_TO_EXTRACT, EXTRACTED_FILENAME)
1401
+
1402
+ assert(File.exists?(EXTRACTED_FILENAME))
1403
+ AssertEntry::assert_contents(EXTRACTED_FILENAME,
1404
+ zf.get_input_stream(ENTRY_TO_EXTRACT) { |is| is.read })
1405
+
1406
+
1407
+ File::unlink(EXTRACTED_FILENAME)
1408
+
1409
+ entry = zf.get_entry(ENTRY_TO_EXTRACT)
1410
+ entry.extract(EXTRACTED_FILENAME)
1411
+
1412
+ assert(File.exists?(EXTRACTED_FILENAME))
1413
+ AssertEntry::assert_contents(EXTRACTED_FILENAME,
1414
+ entry.get_input_stream() { |is| is.read })
1415
+
1416
+ }
1417
+ end
1418
+
1419
+ def test_extractExists
1420
+ writtenText = "written text"
1421
+ File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
1422
+
1423
+ assert_raise(ZipDestinationFileExistsError) {
1424
+ ZipFile.open(TEST_ZIP.zip_name) {
1425
+ |zf|
1426
+ zf.extract(zf.entries.first, EXTRACTED_FILENAME)
1427
+ }
1428
+ }
1429
+ File.open(EXTRACTED_FILENAME, "r") {
1430
+ |f|
1431
+ assert_equal(writtenText, f.read)
1432
+ }
1433
+ end
1434
+
1435
+ def test_extractExistsOverwrite
1436
+ writtenText = "written text"
1437
+ File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
1438
+
1439
+ gotCalledCorrectly = false
1440
+ ZipFile.open(TEST_ZIP.zip_name) {
1441
+ |zf|
1442
+ zf.extract(zf.entries.first, EXTRACTED_FILENAME) {
1443
+ |entry, extractLoc|
1444
+ gotCalledCorrectly = zf.entries.first == entry &&
1445
+ extractLoc == EXTRACTED_FILENAME
1446
+ true
1447
+ }
1448
+ }
1449
+
1450
+ assert(gotCalledCorrectly)
1451
+ File.open(EXTRACTED_FILENAME, "r") {
1452
+ |f|
1453
+ assert(writtenText != f.read)
1454
+ }
1455
+ end
1456
+
1457
+ def test_extractNonEntry
1458
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1459
+ assert_raise(Errno::ENOENT) { zf.extract("nonExistingEntry", "nonExistingEntry") }
1460
+ ensure
1461
+ zf.close if zf
1462
+ end
1463
+
1464
+ def test_extractNonEntry2
1465
+ outFile = "outfile"
1466
+ assert_raise(Errno::ENOENT) {
1467
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1468
+ nonEntry = "hotdog-diddelidoo"
1469
+ assert(! zf.entries.include?(nonEntry))
1470
+ zf.extract(nonEntry, outFile)
1471
+ zf.close
1472
+ }
1473
+ assert(! File.exists?(outFile))
1474
+ end
1475
+
1476
+ end
1477
+
1478
+ class ZipFileExtractDirectoryTest < Test::Unit::TestCase
1479
+ include CommonZipFileFixture
1480
+ TEST_OUT_NAME = "emptyOutDir"
1481
+
1482
+ def open_zip(&aProc)
1483
+ assert(aProc != nil)
1484
+ ZipFile.open(TestZipFile::TEST_ZIP4.zip_name, &aProc)
1485
+ end
1486
+
1487
+ def extract_test_dir(&aProc)
1488
+ open_zip {
1489
+ |zf|
1490
+ zf.extract(TestFiles::EMPTY_TEST_DIR, TEST_OUT_NAME, &aProc)
1491
+ }
1492
+ end
1493
+
1494
+ def setup
1495
+ super
1496
+
1497
+ Dir.rmdir(TEST_OUT_NAME) if File.directory? TEST_OUT_NAME
1498
+ File.delete(TEST_OUT_NAME) if File.exists? TEST_OUT_NAME
1499
+ end
1500
+
1501
+ def test_extractDirectory
1502
+ extract_test_dir
1503
+ assert(File.directory?(TEST_OUT_NAME))
1504
+ end
1505
+
1506
+ def test_extractDirectoryExistsAsDir
1507
+ Dir.mkdir TEST_OUT_NAME
1508
+ extract_test_dir
1509
+ assert(File.directory?(TEST_OUT_NAME))
1510
+ end
1511
+
1512
+ def test_extractDirectoryExistsAsFile
1513
+ File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
1514
+ assert_raise(ZipDestinationFileExistsError) { extract_test_dir }
1515
+ end
1516
+
1517
+ def test_extractDirectoryExistsAsFileOverwrite
1518
+ File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
1519
+ gotCalled = false
1520
+ extract_test_dir {
1521
+ |entry, destPath|
1522
+ gotCalled = true
1523
+ assert_equal(TEST_OUT_NAME, destPath)
1524
+ assert(entry.is_directory)
1525
+ true
1526
+ }
1527
+ assert(gotCalled)
1528
+ assert(File.directory?(TEST_OUT_NAME))
1529
+ end
1530
+ end
1531
+
1532
+ class ZipExtraFieldTest < Test::Unit::TestCase
1533
+ def test_new
1534
+ extra_pure = ZipExtraField.new("")
1535
+ extra_withstr = ZipExtraField.new("foo")
1536
+ assert_instance_of(ZipExtraField, extra_pure)
1537
+ assert_instance_of(ZipExtraField, extra_withstr)
1538
+ end
1539
+
1540
+ def test_unknownfield
1541
+ extra = ZipExtraField.new("foo")
1542
+ assert_equal(extra["Unknown"], "foo")
1543
+ extra.merge("a")
1544
+ assert_equal(extra["Unknown"], "fooa")
1545
+ extra.merge("barbaz")
1546
+ assert_equal(extra.to_s, "fooabarbaz")
1547
+ end
1548
+
1549
+
1550
+ def test_merge
1551
+ str = "UT\x5\0\x3\250$\r@Ux\0\0"
1552
+ extra1 = ZipExtraField.new("")
1553
+ extra2 = ZipExtraField.new(str)
1554
+ assert(! extra1.member?("UniversalTime"))
1555
+ assert(extra2.member?("UniversalTime"))
1556
+ extra1.merge(str)
1557
+ assert_equal(extra1["UniversalTime"].mtime, extra2["UniversalTime"].mtime)
1558
+ end
1559
+
1560
+ def test_length
1561
+ str = "UT\x5\0\x3\250$\r@Ux\0\0Te\0\0testit"
1562
+ extra = ZipExtraField.new(str)
1563
+ assert_equal(extra.local_length, extra.to_local_bin.length)
1564
+ assert_equal(extra.c_dir_length, extra.to_c_dir_bin.length)
1565
+ extra.merge("foo")
1566
+ assert_equal(extra.local_length, extra.to_local_bin.length)
1567
+ assert_equal(extra.c_dir_length, extra.to_c_dir_bin.length)
1568
+ end
1569
+
1570
+
1571
+ def test_to_s
1572
+ str = "UT\x5\0\x3\250$\r@Ux\0\0Te\0\0testit"
1573
+ extra = ZipExtraField.new(str)
1574
+ assert_instance_of(String, extra.to_s)
1575
+
1576
+ s = extra.to_s
1577
+ extra.merge("foo")
1578
+ assert_equal(s.length + 3, extra.to_s.length)
1579
+ end
1580
+
1581
+ def test_equality
1582
+ str = "UT\x5\0\x3\250$\r@"
1583
+ extra1 = ZipExtraField.new(str)
1584
+ extra2 = ZipExtraField.new(str)
1585
+ extra3 = ZipExtraField.new(str)
1586
+ assert_equal(extra1, extra2)
1587
+
1588
+ extra2["UniversalTime"].mtime = Time.now
1589
+ assert(extra1 != extra2)
1590
+
1591
+ extra3.create("IUnix")
1592
+ assert(extra1 != extra3)
1593
+
1594
+ extra1.create("IUnix")
1595
+ assert_equal(extra1, extra3)
1596
+ end
1597
+
1598
+ end
1599
+
1600
+ # Copyright (C) 2002-2005 Thomas Sondergaard
1601
+ # rubyzip is free software; you can redistribute it and/or
1602
+ # modify it under the terms of the ruby license.