erawk-rubyzip 0.9.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.
@@ -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.
data/test/ziptest.rb ADDED
@@ -0,0 +1,1600 @@
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 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
+ zfRead.close
1163
+ end
1164
+
1165
+ def test_renameToExistingEntry
1166
+ oldEntries = nil
1167
+ ZipFile.open(TEST_ZIP.zip_name) { |zf| oldEntries = zf.entries }
1168
+
1169
+ assert_raise(ZipEntryExistsError) {
1170
+ ZipFile.open(TEST_ZIP.zip_name) {
1171
+ |zf|
1172
+ zf.rename(zf.entries[0], zf.entries[1].name)
1173
+ }
1174
+ }
1175
+
1176
+ ZipFile.open(TEST_ZIP.zip_name) {
1177
+ |zf|
1178
+ assert_equal(oldEntries.sort.map{ |e| e.name }, zf.entries.sort.map{ |e| e.name })
1179
+ }
1180
+ end
1181
+
1182
+ def test_renameToExistingEntryOverwrite
1183
+ oldEntries = nil
1184
+ ZipFile.open(TEST_ZIP.zip_name) { |zf| oldEntries = zf.entries }
1185
+
1186
+ gotCalled = false
1187
+ renamedEntryName = nil
1188
+ ZipFile.open(TEST_ZIP.zip_name) {
1189
+ |zf|
1190
+ renamedEntryName = zf.entries[0].name
1191
+ zf.rename(zf.entries[0], zf.entries[1].name) { gotCalled = true; true }
1192
+ }
1193
+
1194
+ assert(gotCalled)
1195
+ oldEntries.delete_if { |e| e.name == renamedEntryName }
1196
+ ZipFile.open(TEST_ZIP.zip_name) {
1197
+ |zf|
1198
+ assert_equal(oldEntries.sort.map{ |e| e.name },
1199
+ zf.entries.sort.map{ |e| e.name })
1200
+ }
1201
+ end
1202
+
1203
+ def test_renameNonEntry
1204
+ nonEntry = "bogusEntry"
1205
+ target_entry = "target_entryName"
1206
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1207
+ assert(! zf.entries.include?(nonEntry))
1208
+ assert_raise(Errno::ENOENT) {
1209
+ zf.rename(nonEntry, target_entry)
1210
+ }
1211
+ zf.commit
1212
+ assert(! zf.entries.include?(target_entry))
1213
+ ensure
1214
+ zf.close
1215
+ end
1216
+
1217
+ def test_renameEntryToExistingEntry
1218
+ entry1, entry2, *remaining = TEST_ZIP.entry_names
1219
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1220
+ assert_raise(ZipEntryExistsError) {
1221
+ zf.rename(entry1, entry2)
1222
+ }
1223
+ ensure
1224
+ zf.close
1225
+ end
1226
+
1227
+ def test_replace
1228
+ entryToReplace = TEST_ZIP.entry_names[2]
1229
+ newEntrySrcFilename = "data/file2.txt"
1230
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1231
+ zf.replace(entryToReplace, newEntrySrcFilename)
1232
+
1233
+ zf.close
1234
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1235
+ AssertEntry::assert_contents(newEntrySrcFilename,
1236
+ zfRead.get_input_stream(entryToReplace) { |is| is.read })
1237
+ AssertEntry::assert_contents(TEST_ZIP.entry_names[0],
1238
+ zfRead.get_input_stream(TEST_ZIP.entry_names[0]) { |is| is.read })
1239
+ AssertEntry::assert_contents(TEST_ZIP.entry_names[1],
1240
+ zfRead.get_input_stream(TEST_ZIP.entry_names[1]) { |is| is.read })
1241
+ AssertEntry::assert_contents(TEST_ZIP.entry_names[3],
1242
+ zfRead.get_input_stream(TEST_ZIP.entry_names[3]) { |is| is.read })
1243
+ zfRead.close
1244
+ end
1245
+
1246
+ def test_replaceNonEntry
1247
+ entryToReplace = "nonExistingEntryname"
1248
+ ZipFile.open(TEST_ZIP.zip_name) {
1249
+ |zf|
1250
+ assert_raise(Errno::ENOENT) {
1251
+ zf.replace(entryToReplace, "data/file2.txt")
1252
+ }
1253
+ }
1254
+ end
1255
+
1256
+ def test_commit
1257
+ newName = "renamedFirst"
1258
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1259
+ oldName = zf.entries.first
1260
+ zf.rename(oldName, newName)
1261
+ zf.commit
1262
+
1263
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1264
+ assert(zfRead.entries.detect { |e| e.name == newName } != nil)
1265
+ assert(zfRead.entries.detect { |e| e.name == oldName } == nil)
1266
+ zfRead.close
1267
+
1268
+ zf.close
1269
+ end
1270
+
1271
+ # This test tests that after commit, you
1272
+ # can delete the file you used to add the entry to the zip file
1273
+ # with
1274
+ def test_commitUseZipEntry
1275
+ FileUtils.copy(TestFiles::RANDOM_ASCII_FILE1, "okToDelete.txt")
1276
+ zf = ZipFile.open(TEST_ZIP.zip_name)
1277
+ zf.add("okToDelete.txt", "okToDelete.txt")
1278
+ assert_contains(zf, "okToDelete.txt")
1279
+ zf.commit
1280
+ FileUtils.move("okToDelete.txt", "okToDeleteMoved.txt")
1281
+ assert_contains(zf, "okToDelete.txt", "okToDeleteMoved.txt")
1282
+ end
1283
+
1284
+ # def test_close
1285
+ # zf = ZipFile.new(TEST_ZIP.zip_name)
1286
+ # zf.close
1287
+ # assert_raise(IOError) {
1288
+ # zf.extract(TEST_ZIP.entry_names.first, "hullubullu")
1289
+ # }
1290
+ # end
1291
+
1292
+ def test_compound1
1293
+ renamedName = "renamedName"
1294
+ originalEntries = []
1295
+ begin
1296
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1297
+ originalEntries = zf.entries.dup
1298
+
1299
+ assert_not_contains(zf, TestFiles::RANDOM_ASCII_FILE1)
1300
+ zf.add(TestFiles::RANDOM_ASCII_FILE1,
1301
+ TestFiles::RANDOM_ASCII_FILE1)
1302
+ assert_contains(zf, TestFiles::RANDOM_ASCII_FILE1)
1303
+
1304
+ zf.rename(zf.entries[0], renamedName)
1305
+ assert_contains(zf, renamedName)
1306
+
1307
+ TestFiles::BINARY_TEST_FILES.each {
1308
+ |filename|
1309
+ zf.add(filename, filename)
1310
+ assert_contains(zf, filename)
1311
+ }
1312
+
1313
+ assert_contains(zf, originalEntries.last.to_s)
1314
+ zf.remove(originalEntries.last.to_s)
1315
+ assert_not_contains(zf, originalEntries.last.to_s)
1316
+
1317
+ ensure
1318
+ zf.close
1319
+ end
1320
+ begin
1321
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1322
+ assert_contains(zfRead, TestFiles::RANDOM_ASCII_FILE1)
1323
+ assert_contains(zfRead, renamedName)
1324
+ TestFiles::BINARY_TEST_FILES.each {
1325
+ |filename|
1326
+ assert_contains(zfRead, filename)
1327
+ }
1328
+ assert_not_contains(zfRead, originalEntries.last.to_s)
1329
+ ensure
1330
+ zfRead.close
1331
+ end
1332
+ end
1333
+
1334
+ def test_compound2
1335
+ begin
1336
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1337
+ originalEntries = zf.entries.dup
1338
+
1339
+ originalEntries.each {
1340
+ |entry|
1341
+ zf.remove(entry)
1342
+ assert_not_contains(zf, entry)
1343
+ }
1344
+ assert(zf.entries.empty?)
1345
+
1346
+ TestFiles::ASCII_TEST_FILES.each {
1347
+ |filename|
1348
+ zf.add(filename, filename)
1349
+ assert_contains(zf, filename)
1350
+ }
1351
+ assert_equal(zf.entries.sort.map { |e| e.name }, TestFiles::ASCII_TEST_FILES)
1352
+
1353
+ zf.rename(TestFiles::ASCII_TEST_FILES[0], "newName")
1354
+ assert_not_contains(zf, TestFiles::ASCII_TEST_FILES[0])
1355
+ assert_contains(zf, "newName")
1356
+ ensure
1357
+ zf.close
1358
+ end
1359
+ begin
1360
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1361
+ asciiTestFiles = TestFiles::ASCII_TEST_FILES.dup
1362
+ asciiTestFiles.shift
1363
+ asciiTestFiles.each {
1364
+ |filename|
1365
+ assert_contains(zf, filename)
1366
+ }
1367
+
1368
+ assert_contains(zf, "newName")
1369
+ ensure
1370
+ zfRead.close
1371
+ end
1372
+ end
1373
+
1374
+ private
1375
+ def assert_contains(zf, entryName, filename = entryName)
1376
+ assert(zf.entries.detect { |e| e.name == entryName} != nil, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}")
1377
+ assert_entryContents(zf, entryName, filename) if File.exists?(filename)
1378
+ end
1379
+
1380
+ def assert_not_contains(zf, entryName)
1381
+ assert(zf.entries.detect { |e| e.name == entryName} == nil, "entry #{entryName} in #{zf.entries.join(', ')} in zip file #{zf}")
1382
+ end
1383
+ end
1384
+
1385
+ class ZipFileExtractTest < Test::Unit::TestCase
1386
+ include CommonZipFileFixture
1387
+ EXTRACTED_FILENAME = "extEntry"
1388
+ ENTRY_TO_EXTRACT, *REMAINING_ENTRIES = TEST_ZIP.entry_names.reverse
1389
+
1390
+ def setup
1391
+ super
1392
+ File.delete(EXTRACTED_FILENAME) if File.exists?(EXTRACTED_FILENAME)
1393
+ end
1394
+
1395
+ def test_extract
1396
+ ZipFile.open(TEST_ZIP.zip_name) {
1397
+ |zf|
1398
+ zf.extract(ENTRY_TO_EXTRACT, EXTRACTED_FILENAME)
1399
+
1400
+ assert(File.exists?(EXTRACTED_FILENAME))
1401
+ AssertEntry::assert_contents(EXTRACTED_FILENAME,
1402
+ zf.get_input_stream(ENTRY_TO_EXTRACT) { |is| is.read })
1403
+
1404
+
1405
+ File::unlink(EXTRACTED_FILENAME)
1406
+
1407
+ entry = zf.get_entry(ENTRY_TO_EXTRACT)
1408
+ entry.extract(EXTRACTED_FILENAME)
1409
+
1410
+ assert(File.exists?(EXTRACTED_FILENAME))
1411
+ AssertEntry::assert_contents(EXTRACTED_FILENAME,
1412
+ entry.get_input_stream() { |is| is.read })
1413
+
1414
+ }
1415
+ end
1416
+
1417
+ def test_extractExists
1418
+ writtenText = "written text"
1419
+ File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
1420
+
1421
+ assert_raise(ZipDestinationFileExistsError) {
1422
+ ZipFile.open(TEST_ZIP.zip_name) {
1423
+ |zf|
1424
+ zf.extract(zf.entries.first, EXTRACTED_FILENAME)
1425
+ }
1426
+ }
1427
+ File.open(EXTRACTED_FILENAME, "r") {
1428
+ |f|
1429
+ assert_equal(writtenText, f.read)
1430
+ }
1431
+ end
1432
+
1433
+ def test_extractExistsOverwrite
1434
+ writtenText = "written text"
1435
+ File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
1436
+
1437
+ gotCalledCorrectly = false
1438
+ ZipFile.open(TEST_ZIP.zip_name) {
1439
+ |zf|
1440
+ zf.extract(zf.entries.first, EXTRACTED_FILENAME) {
1441
+ |entry, extractLoc|
1442
+ gotCalledCorrectly = zf.entries.first == entry &&
1443
+ extractLoc == EXTRACTED_FILENAME
1444
+ true
1445
+ }
1446
+ }
1447
+
1448
+ assert(gotCalledCorrectly)
1449
+ File.open(EXTRACTED_FILENAME, "r") {
1450
+ |f|
1451
+ assert(writtenText != f.read)
1452
+ }
1453
+ end
1454
+
1455
+ def test_extractNonEntry
1456
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1457
+ assert_raise(Errno::ENOENT) { zf.extract("nonExistingEntry", "nonExistingEntry") }
1458
+ ensure
1459
+ zf.close if zf
1460
+ end
1461
+
1462
+ def test_extractNonEntry2
1463
+ outFile = "outfile"
1464
+ assert_raise(Errno::ENOENT) {
1465
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1466
+ nonEntry = "hotdog-diddelidoo"
1467
+ assert(! zf.entries.include?(nonEntry))
1468
+ zf.extract(nonEntry, outFile)
1469
+ zf.close
1470
+ }
1471
+ assert(! File.exists?(outFile))
1472
+ end
1473
+
1474
+ end
1475
+
1476
+ class ZipFileExtractDirectoryTest < Test::Unit::TestCase
1477
+ include CommonZipFileFixture
1478
+ TEST_OUT_NAME = "emptyOutDir"
1479
+
1480
+ def open_zip(&aProc)
1481
+ assert(aProc != nil)
1482
+ ZipFile.open(TestZipFile::TEST_ZIP4.zip_name, &aProc)
1483
+ end
1484
+
1485
+ def extract_test_dir(&aProc)
1486
+ open_zip {
1487
+ |zf|
1488
+ zf.extract(TestFiles::EMPTY_TEST_DIR, TEST_OUT_NAME, &aProc)
1489
+ }
1490
+ end
1491
+
1492
+ def setup
1493
+ super
1494
+
1495
+ Dir.rmdir(TEST_OUT_NAME) if File.directory? TEST_OUT_NAME
1496
+ File.delete(TEST_OUT_NAME) if File.exists? TEST_OUT_NAME
1497
+ end
1498
+
1499
+ def test_extractDirectory
1500
+ extract_test_dir
1501
+ assert(File.directory?(TEST_OUT_NAME))
1502
+ end
1503
+
1504
+ def test_extractDirectoryExistsAsDir
1505
+ Dir.mkdir TEST_OUT_NAME
1506
+ extract_test_dir
1507
+ assert(File.directory?(TEST_OUT_NAME))
1508
+ end
1509
+
1510
+ def test_extractDirectoryExistsAsFile
1511
+ File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
1512
+ assert_raise(ZipDestinationFileExistsError) { extract_test_dir }
1513
+ end
1514
+
1515
+ def test_extractDirectoryExistsAsFileOverwrite
1516
+ File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
1517
+ gotCalled = false
1518
+ extract_test_dir {
1519
+ |entry, destPath|
1520
+ gotCalled = true
1521
+ assert_equal(TEST_OUT_NAME, destPath)
1522
+ assert(entry.is_directory)
1523
+ true
1524
+ }
1525
+ assert(gotCalled)
1526
+ assert(File.directory?(TEST_OUT_NAME))
1527
+ end
1528
+ end
1529
+
1530
+ class ZipExtraFieldTest < Test::Unit::TestCase
1531
+ def test_new
1532
+ extra_pure = ZipExtraField.new("")
1533
+ extra_withstr = ZipExtraField.new("foo")
1534
+ assert_instance_of(ZipExtraField, extra_pure)
1535
+ assert_instance_of(ZipExtraField, extra_withstr)
1536
+ end
1537
+
1538
+ def test_unknownfield
1539
+ extra = ZipExtraField.new("foo")
1540
+ assert_equal(extra["Unknown"], "foo")
1541
+ extra.merge("a")
1542
+ assert_equal(extra["Unknown"], "fooa")
1543
+ extra.merge("barbaz")
1544
+ assert_equal(extra.to_s, "fooabarbaz")
1545
+ end
1546
+
1547
+
1548
+ def test_merge
1549
+ str = "UT\x5\0\x3\250$\r@Ux\0\0"
1550
+ extra1 = ZipExtraField.new("")
1551
+ extra2 = ZipExtraField.new(str)
1552
+ assert(! extra1.member?("UniversalTime"))
1553
+ assert(extra2.member?("UniversalTime"))
1554
+ extra1.merge(str)
1555
+ assert_equal(extra1["UniversalTime"].mtime, extra2["UniversalTime"].mtime)
1556
+ end
1557
+
1558
+ def test_length
1559
+ str = "UT\x5\0\x3\250$\r@Ux\0\0Te\0\0testit"
1560
+ extra = ZipExtraField.new(str)
1561
+ assert_equal(extra.local_length, extra.to_local_bin.length)
1562
+ assert_equal(extra.c_dir_length, extra.to_c_dir_bin.length)
1563
+ extra.merge("foo")
1564
+ assert_equal(extra.local_length, extra.to_local_bin.length)
1565
+ assert_equal(extra.c_dir_length, extra.to_c_dir_bin.length)
1566
+ end
1567
+
1568
+
1569
+ def test_to_s
1570
+ str = "UT\x5\0\x3\250$\r@Ux\0\0Te\0\0testit"
1571
+ extra = ZipExtraField.new(str)
1572
+ assert_instance_of(String, extra.to_s)
1573
+
1574
+ s = extra.to_s
1575
+ extra.merge("foo")
1576
+ assert_equal(s.length + 3, extra.to_s.length)
1577
+ end
1578
+
1579
+ def test_equality
1580
+ str = "UT\x5\0\x3\250$\r@"
1581
+ extra1 = ZipExtraField.new(str)
1582
+ extra2 = ZipExtraField.new(str)
1583
+ extra3 = ZipExtraField.new(str)
1584
+ assert_equal(extra1, extra2)
1585
+
1586
+ extra2["UniversalTime"].mtime = Time.now
1587
+ assert(extra1 != extra2)
1588
+
1589
+ extra3.create("IUnix")
1590
+ assert(extra1 != extra3)
1591
+
1592
+ extra1.create("IUnix")
1593
+ assert_equal(extra1, extra3)
1594
+ end
1595
+
1596
+ end
1597
+
1598
+ # Copyright (C) 2002-2005 Thomas Sondergaard
1599
+ # rubyzip is free software; you can redistribute it and/or
1600
+ # modify it under the terms of the ruby license.