agraham-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.
@@ -0,0 +1,1601 @@
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") { |file| file << 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
+ index=0
657
+ each_with_index {
658
+ |element, index|
659
+ return false unless yield(element, otherAsArray[index])
660
+ }
661
+ return index+1 == otherAsArray.size
662
+ end
663
+ end
664
+
665
+
666
+ class ZipCentralDirectoryEntryTest < Test::Unit::TestCase
667
+
668
+ def test_read_from_stream
669
+ File.open("data/testDirectory.bin", "rb") {
670
+ |file|
671
+ entry = ZipEntry.read_c_dir_entry(file)
672
+
673
+ assert_equal("longAscii.txt", entry.name)
674
+ assert_equal(ZipEntry::DEFLATED, entry.compression_method)
675
+ assert_equal(106490, entry.size)
676
+ assert_equal(3784, entry.compressed_size)
677
+ assert_equal(0xfcd1799c, entry.crc)
678
+ assert_equal("", entry.comment)
679
+
680
+ entry = ZipEntry.read_c_dir_entry(file)
681
+ assert_equal("empty.txt", entry.name)
682
+ assert_equal(ZipEntry::STORED, entry.compression_method)
683
+ assert_equal(0, entry.size)
684
+ assert_equal(0, entry.compressed_size)
685
+ assert_equal(0x0, entry.crc)
686
+ assert_equal("", entry.comment)
687
+
688
+ entry = ZipEntry.read_c_dir_entry(file)
689
+ assert_equal("short.txt", entry.name)
690
+ assert_equal(ZipEntry::STORED, entry.compression_method)
691
+ assert_equal(6, entry.size)
692
+ assert_equal(6, entry.compressed_size)
693
+ assert_equal(0xbb76fe69, entry.crc)
694
+ assert_equal("", entry.comment)
695
+
696
+ entry = ZipEntry.read_c_dir_entry(file)
697
+ assert_equal("longBinary.bin", entry.name)
698
+ assert_equal(ZipEntry::DEFLATED, entry.compression_method)
699
+ assert_equal(1000024, entry.size)
700
+ assert_equal(70847, entry.compressed_size)
701
+ assert_equal(0x10da7d59, entry.crc)
702
+ assert_equal("", entry.comment)
703
+
704
+ entry = ZipEntry.read_c_dir_entry(file)
705
+ assert_equal(nil, entry)
706
+ # Fields that are not check by this test:
707
+ # version made by 2 bytes
708
+ # version needed to extract 2 bytes
709
+ # general purpose bit flag 2 bytes
710
+ # last mod file time 2 bytes
711
+ # last mod file date 2 bytes
712
+ # compressed size 4 bytes
713
+ # uncompressed size 4 bytes
714
+ # disk number start 2 bytes
715
+ # internal file attributes 2 bytes
716
+ # external file attributes 4 bytes
717
+ # relative offset of local header 4 bytes
718
+
719
+ # file name (variable size)
720
+ # extra field (variable size)
721
+ # file comment (variable size)
722
+
723
+ }
724
+ end
725
+
726
+ def test_ReadEntryFromTruncatedZipFile
727
+ fragment=""
728
+ File.open("data/testDirectory.bin") { |f| fragment = f.read(12) } # cdir entry header is at least 46 bytes
729
+ fragment.extend(IOizeString)
730
+ entry = ZipEntry.new
731
+ entry.read_c_dir_entry(fragment)
732
+ fail "ZipError expected"
733
+ rescue ZipError
734
+ end
735
+
736
+ end
737
+
738
+
739
+ class ZipEntrySetTest < Test::Unit::TestCase
740
+ ZIP_ENTRIES = [
741
+ ZipEntry.new("zipfile.zip", "name1", "comment1"),
742
+ ZipEntry.new("zipfile.zip", "name2", "comment1"),
743
+ ZipEntry.new("zipfile.zip", "name3", "comment1"),
744
+ ZipEntry.new("zipfile.zip", "name4", "comment1"),
745
+ ZipEntry.new("zipfile.zip", "name5", "comment1"),
746
+ ZipEntry.new("zipfile.zip", "name6", "comment1")
747
+ ]
748
+
749
+ def setup
750
+ @zipEntrySet = ZipEntrySet.new(ZIP_ENTRIES)
751
+ end
752
+
753
+ def test_include
754
+ assert(@zipEntrySet.include?(ZIP_ENTRIES.first))
755
+ assert(! @zipEntrySet.include?(ZipEntry.new("different.zip", "different", "aComment")))
756
+ end
757
+
758
+ def test_size
759
+ assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
760
+ assert_equal(ZIP_ENTRIES.size, @zipEntrySet.length)
761
+ @zipEntrySet << ZipEntry.new("a", "b", "c")
762
+ assert_equal(ZIP_ENTRIES.size + 1, @zipEntrySet.length)
763
+ end
764
+
765
+ def test_add
766
+ zes = ZipEntrySet.new
767
+ entry1 = ZipEntry.new("zf.zip", "name1")
768
+ entry2 = ZipEntry.new("zf.zip", "name2")
769
+ zes << entry1
770
+ assert(zes.include?(entry1))
771
+ zes.push(entry2)
772
+ assert(zes.include?(entry2))
773
+ end
774
+
775
+ def test_delete
776
+ assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
777
+ entry = @zipEntrySet.delete(ZIP_ENTRIES.first)
778
+ assert_equal(ZIP_ENTRIES.size - 1, @zipEntrySet.size)
779
+ assert_equal(ZIP_ENTRIES.first, entry)
780
+
781
+ entry = @zipEntrySet.delete(ZIP_ENTRIES.first)
782
+ assert_equal(ZIP_ENTRIES.size - 1, @zipEntrySet.size)
783
+ assert_nil(entry)
784
+ end
785
+
786
+ def test_each
787
+ # Tested indirectly via each_with_index
788
+ count = 0
789
+ @zipEntrySet.each_with_index {
790
+ |entry, index|
791
+ assert(ZIP_ENTRIES.include?(entry))
792
+ count = count.succ
793
+ }
794
+ assert_equal(ZIP_ENTRIES.size, count)
795
+ end
796
+
797
+ def test_entries
798
+ assert_equal(ZIP_ENTRIES.sort, @zipEntrySet.entries.sort)
799
+ end
800
+
801
+ def test_compound
802
+ newEntry = ZipEntry.new("zf.zip", "new entry", "new entry's comment")
803
+ assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
804
+ @zipEntrySet << newEntry
805
+ assert_equal(ZIP_ENTRIES.size + 1, @zipEntrySet.size)
806
+ assert(@zipEntrySet.include?(newEntry))
807
+
808
+ @zipEntrySet.delete(newEntry)
809
+ assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
810
+ end
811
+
812
+ def test_dup
813
+ copy = @zipEntrySet.dup
814
+ assert_equal(@zipEntrySet, copy)
815
+
816
+ # demonstrate that this is a deep copy
817
+ copy.entries[0].name = "a totally different name"
818
+ assert(@zipEntrySet != copy)
819
+ end
820
+
821
+ def test_parent
822
+ entries = [
823
+ ZipEntry.new("zf.zip", "a"),
824
+ ZipEntry.new("zf.zip", "a/"),
825
+ ZipEntry.new("zf.zip", "a/b"),
826
+ ZipEntry.new("zf.zip", "a/b/"),
827
+ ZipEntry.new("zf.zip", "a/b/c"),
828
+ ZipEntry.new("zf.zip", "a/b/c/")
829
+ ]
830
+ entrySet = ZipEntrySet.new(entries)
831
+
832
+ assert_equal(nil, entrySet.parent(entries[0]))
833
+ assert_equal(nil, entrySet.parent(entries[1]))
834
+ assert_equal(entries[1], entrySet.parent(entries[2]))
835
+ assert_equal(entries[1], entrySet.parent(entries[3]))
836
+ assert_equal(entries[3], entrySet.parent(entries[4]))
837
+ assert_equal(entries[3], entrySet.parent(entries[5]))
838
+ end
839
+
840
+ def test_glob
841
+ res = @zipEntrySet.glob('name[2-4]')
842
+ assert_equal(3, res.size)
843
+ assert_equal(ZIP_ENTRIES[1,3], res)
844
+ end
845
+
846
+ def test_glob2
847
+ entries = [
848
+ ZipEntry.new("zf.zip", "a/"),
849
+ ZipEntry.new("zf.zip", "a/b/b1"),
850
+ ZipEntry.new("zf.zip", "a/b/c/"),
851
+ ZipEntry.new("zf.zip", "a/b/c/c1")
852
+ ]
853
+ entrySet = ZipEntrySet.new(entries)
854
+
855
+ assert_equal(entries[0,1], entrySet.glob("*"))
856
+ # assert_equal(entries[FIXME], entrySet.glob("**"))
857
+ # res = entrySet.glob('a*')
858
+ # assert_equal(entries.size, res.size)
859
+ # assert_equal(entrySet.map { |e| e.name }, res.map { |e| e.name })
860
+ end
861
+ end
862
+
863
+
864
+ class ZipCentralDirectoryTest < Test::Unit::TestCase
865
+
866
+ def test_read_from_stream
867
+ File.open(TestZipFile::TEST_ZIP2.zip_name, "rb") {
868
+ |zipFile|
869
+ cdir = ZipCentralDirectory.read_from_stream(zipFile)
870
+
871
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names.size, cdir.size)
872
+ assert(cdir.entries.sort.compare_enumerables(TestZipFile::TEST_ZIP2.entry_names.sort) {
873
+ |cdirEntry, testEntryName|
874
+ cdirEntry.name == testEntryName
875
+ })
876
+ assert_equal(TestZipFile::TEST_ZIP2.comment, cdir.comment)
877
+ }
878
+ end
879
+
880
+ def test_readFromInvalidStream
881
+ File.open("data/file2.txt", "rb") {
882
+ |zipFile|
883
+ cdir = ZipCentralDirectory.new
884
+ cdir.read_from_stream(zipFile)
885
+ }
886
+ fail "ZipError expected!"
887
+ rescue ZipError
888
+ end
889
+
890
+ def test_ReadFromTruncatedZipFile
891
+ fragment=""
892
+ File.open("data/testDirectory.bin") { |f| fragment = f.read }
893
+ fragment.slice!(12) # removed part of first cdir entry. eocd structure still complete
894
+ fragment.extend(IOizeString)
895
+ entry = ZipCentralDirectory.new
896
+ entry.read_from_stream(fragment)
897
+ fail "ZipError expected"
898
+ rescue ZipError
899
+ end
900
+
901
+ def test_write_to_stream
902
+ entries = [ ZipEntry.new("file.zip", "flimse", "myComment", "somethingExtra"),
903
+ ZipEntry.new("file.zip", "secondEntryName"),
904
+ ZipEntry.new("file.zip", "lastEntry.txt", "Has a comment too") ]
905
+ cdir = ZipCentralDirectory.new(entries, "my zip comment")
906
+ File.open("cdirtest.bin", "wb") { |f| cdir.write_to_stream(f) }
907
+ cdirReadback = ZipCentralDirectory.new
908
+ File.open("cdirtest.bin", "rb") { |f| cdirReadback.read_from_stream(f) }
909
+
910
+ assert_equal(cdir.entries.sort, cdirReadback.entries.sort)
911
+ end
912
+
913
+ def test_equality
914
+ cdir1 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
915
+ "somethingExtra"),
916
+ ZipEntry.new("file.zip", "secondEntryName"),
917
+ ZipEntry.new("file.zip", "lastEntry.txt") ],
918
+ "my zip comment")
919
+ cdir2 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
920
+ "somethingExtra"),
921
+ ZipEntry.new("file.zip", "secondEntryName"),
922
+ ZipEntry.new("file.zip", "lastEntry.txt") ],
923
+ "my zip comment")
924
+ cdir3 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
925
+ "somethingExtra"),
926
+ ZipEntry.new("file.zip", "secondEntryName"),
927
+ ZipEntry.new("file.zip", "lastEntry.txt") ],
928
+ "comment?")
929
+ cdir4 = ZipCentralDirectory.new([ ZipEntry.new("file.zip", "flimse", nil,
930
+ "somethingExtra"),
931
+ ZipEntry.new("file.zip", "lastEntry.txt") ],
932
+ "comment?")
933
+ assert_equal(cdir1, cdir1)
934
+ assert_equal(cdir1, cdir2)
935
+
936
+ assert(cdir1 != cdir3)
937
+ assert(cdir2 != cdir3)
938
+ assert(cdir2 != cdir3)
939
+ assert(cdir3 != cdir4)
940
+
941
+ assert(cdir3 != "hello")
942
+ end
943
+ end
944
+
945
+
946
+ class BasicZipFileTest < Test::Unit::TestCase
947
+ include AssertEntry
948
+
949
+ def setup
950
+ @zipFile = ZipFile.new(TestZipFile::TEST_ZIP2.zip_name)
951
+ @testEntryNameIndex=0
952
+ end
953
+
954
+ def test_entries
955
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names.sort,
956
+ @zipFile.entries.entries.sort.map {|e| e.name} )
957
+ end
958
+
959
+ def test_each
960
+ count = 0
961
+ visited = {}
962
+ @zipFile.each {
963
+ |entry|
964
+ assert(TestZipFile::TEST_ZIP2.entry_names.include?(entry.name))
965
+ assert(! visited.include?(entry.name))
966
+ visited[entry.name] = nil
967
+ count = count.succ
968
+ }
969
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
970
+ end
971
+
972
+ def test_foreach
973
+ count = 0
974
+ visited = {}
975
+ ZipFile.foreach(TestZipFile::TEST_ZIP2.zip_name) {
976
+ |entry|
977
+ assert(TestZipFile::TEST_ZIP2.entry_names.include?(entry.name))
978
+ assert(! visited.include?(entry.name))
979
+ visited[entry.name] = nil
980
+ count = count.succ
981
+ }
982
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
983
+ end
984
+
985
+ def test_get_input_stream
986
+ count = 0
987
+ visited = {}
988
+ @zipFile.each {
989
+ |entry|
990
+ assert_entry(entry.name, @zipFile.get_input_stream(entry), entry.name)
991
+ assert(! visited.include?(entry.name))
992
+ visited[entry.name] = nil
993
+ count = count.succ
994
+ }
995
+ assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
996
+ end
997
+
998
+ def test_get_input_streamBlock
999
+ fileAndEntryName = @zipFile.entries.first.name
1000
+ @zipFile.get_input_stream(fileAndEntryName) {
1001
+ |zis|
1002
+ assert_entryContentsForStream(fileAndEntryName,
1003
+ zis,
1004
+ fileAndEntryName)
1005
+ }
1006
+ end
1007
+ end
1008
+
1009
+ module CommonZipFileFixture
1010
+ include AssertEntry
1011
+
1012
+ EMPTY_FILENAME = "emptyZipFile.zip"
1013
+
1014
+ TEST_ZIP = TestZipFile::TEST_ZIP2.clone
1015
+ TEST_ZIP.zip_name = "5entry_copy.zip"
1016
+
1017
+ def setup
1018
+ File.delete(EMPTY_FILENAME) if File.exists?(EMPTY_FILENAME)
1019
+ File.copy(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name)
1020
+ end
1021
+ end
1022
+
1023
+ class ZipFileTest < Test::Unit::TestCase
1024
+ include CommonZipFileFixture
1025
+
1026
+ def test_createFromScratch
1027
+ comment = "a short comment"
1028
+
1029
+ zf = ZipFile.new(EMPTY_FILENAME, ZipFile::CREATE)
1030
+ zf.get_output_stream("myFile") { |os| os.write "myFile contains just this" }
1031
+ zf.mkdir("dir1")
1032
+ zf.comment = comment
1033
+ zf.close
1034
+
1035
+ zfRead = ZipFile.new(EMPTY_FILENAME)
1036
+ assert_equal(comment, zfRead.comment)
1037
+ assert_equal(2, zfRead.entries.length)
1038
+ end
1039
+
1040
+ def test_get_output_stream
1041
+ entryCount = nil
1042
+ ZipFile.open(TEST_ZIP.zip_name) {
1043
+ |zf|
1044
+ entryCount = zf.size
1045
+ zf.get_output_stream('newEntry.txt') {
1046
+ |os|
1047
+ os.write "Putting stuff in newEntry.txt"
1048
+ }
1049
+ assert_equal(entryCount+1, zf.size)
1050
+ assert_equal("Putting stuff in newEntry.txt", zf.read("newEntry.txt"))
1051
+
1052
+ zf.get_output_stream(zf.get_entry('data/generated/empty.txt')) {
1053
+ |os|
1054
+ os.write "Putting stuff in data/generated/empty.txt"
1055
+ }
1056
+ assert_equal(entryCount+1, zf.size)
1057
+ assert_equal("Putting stuff in data/generated/empty.txt", zf.read("data/generated/empty.txt"))
1058
+
1059
+ zf.get_output_stream('entry.bin') {
1060
+ |os|
1061
+ os.write(File.open('data/generated/5entry.zip', 'rb').read)
1062
+ }
1063
+ }
1064
+
1065
+ ZipFile.open(TEST_ZIP.zip_name) {
1066
+ |zf|
1067
+ assert_equal(entryCount+2, zf.size)
1068
+ assert_equal("Putting stuff in newEntry.txt", zf.read("newEntry.txt"))
1069
+ assert_equal("Putting stuff in data/generated/empty.txt", zf.read("data/generated/empty.txt"))
1070
+ assert_equal(File.open('data/generated/5entry.zip', 'rb').read, zf.read("entry.bin"))
1071
+ }
1072
+ end
1073
+
1074
+ def test_add
1075
+ srcFile = "data/file2.txt"
1076
+ entryName = "newEntryName.rb"
1077
+ assert(File.exists?(srcFile))
1078
+ zf = ZipFile.new(EMPTY_FILENAME, ZipFile::CREATE)
1079
+ zf.add(entryName, srcFile)
1080
+ zf.close
1081
+
1082
+ zfRead = ZipFile.new(EMPTY_FILENAME)
1083
+ assert_equal("", zfRead.comment)
1084
+ assert_equal(1, zfRead.entries.length)
1085
+ assert_equal(entryName, zfRead.entries.first.name)
1086
+ AssertEntry.assert_contents(srcFile,
1087
+ zfRead.get_input_stream(entryName) { |zis| zis.read })
1088
+ end
1089
+
1090
+ def test_addExistingEntryName
1091
+ assert_raise(ZipEntryExistsError) {
1092
+ ZipFile.open(TEST_ZIP.zip_name) {
1093
+ |zf|
1094
+ zf.add(zf.entries.first.name, "data/file2.txt")
1095
+ }
1096
+ }
1097
+ end
1098
+
1099
+ def test_addExistingEntryNameReplace
1100
+ gotCalled = false
1101
+ replacedEntry = nil
1102
+ ZipFile.open(TEST_ZIP.zip_name) {
1103
+ |zf|
1104
+ replacedEntry = zf.entries.first.name
1105
+ zf.add(replacedEntry, "data/file2.txt") { gotCalled = true; true }
1106
+ }
1107
+ assert(gotCalled)
1108
+ ZipFile.open(TEST_ZIP.zip_name) {
1109
+ |zf|
1110
+ assert_contains(zf, replacedEntry, "data/file2.txt")
1111
+ }
1112
+ end
1113
+
1114
+ def test_addDirectory
1115
+ ZipFile.open(TEST_ZIP.zip_name) {
1116
+ |zf|
1117
+ zf.add(TestFiles::EMPTY_TEST_DIR, TestFiles::EMPTY_TEST_DIR)
1118
+ }
1119
+ ZipFile.open(TEST_ZIP.zip_name) {
1120
+ |zf|
1121
+ dirEntry = zf.entries.detect { |e| e.name == TestFiles::EMPTY_TEST_DIR+"/" }
1122
+ assert(dirEntry.is_directory)
1123
+ }
1124
+ end
1125
+
1126
+ def test_remove
1127
+ entryToRemove, *remainingEntries = TEST_ZIP.entry_names
1128
+
1129
+ File.copy(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name)
1130
+
1131
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1132
+ assert(zf.entries.map { |e| e.name }.include?(entryToRemove))
1133
+ zf.remove(entryToRemove)
1134
+ assert(! zf.entries.map { |e| e.name }.include?(entryToRemove))
1135
+ assert_equal(zf.entries.map {|x| x.name }.sort, remainingEntries.sort)
1136
+ zf.close
1137
+
1138
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1139
+ assert(! zfRead.entries.map { |e| e.name }.include?(entryToRemove))
1140
+ assert_equal(zfRead.entries.map {|x| x.name }.sort, remainingEntries.sort)
1141
+ zfRead.close
1142
+ end
1143
+
1144
+
1145
+ def test_rename
1146
+ entryToRename, *remainingEntries = TEST_ZIP.entry_names
1147
+
1148
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1149
+ assert(zf.entries.map { |e| e.name }.include?(entryToRename))
1150
+
1151
+ newName = "changed entry name"
1152
+ assert(! zf.entries.map { |e| e.name }.include?(newName))
1153
+
1154
+ zf.rename(entryToRename, newName)
1155
+ assert(zf.entries.map { |e| e.name }.include?(newName))
1156
+
1157
+ zf.close
1158
+
1159
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1160
+ assert(zfRead.entries.map { |e| e.name }.include?(newName))
1161
+ File.delete(ZipFileExtractTest::EXTRACTED_FILENAME) if File.exists?(ZipFileExtractTest::EXTRACTED_FILENAME)
1162
+ zf.extract(newName, ZipFileExtractTest::EXTRACTED_FILENAME)
1163
+ zfRead.close
1164
+ end
1165
+
1166
+ def test_renameToExistingEntry
1167
+ oldEntries = nil
1168
+ ZipFile.open(TEST_ZIP.zip_name) { |zf| oldEntries = zf.entries }
1169
+
1170
+ assert_raise(ZipEntryExistsError) {
1171
+ ZipFile.open(TEST_ZIP.zip_name) {
1172
+ |zf|
1173
+ zf.rename(zf.entries[0], zf.entries[1].name)
1174
+ }
1175
+ }
1176
+
1177
+ ZipFile.open(TEST_ZIP.zip_name) {
1178
+ |zf|
1179
+ assert_equal(oldEntries.sort.map{ |e| e.name }, zf.entries.sort.map{ |e| e.name })
1180
+ }
1181
+ end
1182
+
1183
+ def test_renameToExistingEntryOverwrite
1184
+ oldEntries = nil
1185
+ ZipFile.open(TEST_ZIP.zip_name) { |zf| oldEntries = zf.entries }
1186
+
1187
+ gotCalled = false
1188
+ renamedEntryName = nil
1189
+ ZipFile.open(TEST_ZIP.zip_name) {
1190
+ |zf|
1191
+ renamedEntryName = zf.entries[0].name
1192
+ zf.rename(zf.entries[0], zf.entries[1].name) { gotCalled = true; true }
1193
+ }
1194
+
1195
+ assert(gotCalled)
1196
+ oldEntries.delete_if { |e| e.name == renamedEntryName }
1197
+ ZipFile.open(TEST_ZIP.zip_name) {
1198
+ |zf|
1199
+ assert_equal(oldEntries.sort.map{ |e| e.name },
1200
+ zf.entries.sort.map{ |e| e.name })
1201
+ }
1202
+ end
1203
+
1204
+ def test_renameNonEntry
1205
+ nonEntry = "bogusEntry"
1206
+ target_entry = "target_entryName"
1207
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1208
+ assert(! zf.entries.include?(nonEntry))
1209
+ assert_raise(Errno::ENOENT) {
1210
+ zf.rename(nonEntry, target_entry)
1211
+ }
1212
+ zf.commit
1213
+ assert(! zf.entries.include?(target_entry))
1214
+ ensure
1215
+ zf.close
1216
+ end
1217
+
1218
+ def test_renameEntryToExistingEntry
1219
+ entry1, entry2, *remaining = TEST_ZIP.entry_names
1220
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1221
+ assert_raise(ZipEntryExistsError) {
1222
+ zf.rename(entry1, entry2)
1223
+ }
1224
+ ensure
1225
+ zf.close
1226
+ end
1227
+
1228
+ def test_replace
1229
+ entryToReplace = TEST_ZIP.entry_names[2]
1230
+ newEntrySrcFilename = "data/file2.txt"
1231
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1232
+ zf.replace(entryToReplace, newEntrySrcFilename)
1233
+
1234
+ zf.close
1235
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1236
+ AssertEntry::assert_contents(newEntrySrcFilename,
1237
+ zfRead.get_input_stream(entryToReplace) { |is| is.read })
1238
+ AssertEntry::assert_contents(TEST_ZIP.entry_names[0],
1239
+ zfRead.get_input_stream(TEST_ZIP.entry_names[0]) { |is| is.read })
1240
+ AssertEntry::assert_contents(TEST_ZIP.entry_names[1],
1241
+ zfRead.get_input_stream(TEST_ZIP.entry_names[1]) { |is| is.read })
1242
+ AssertEntry::assert_contents(TEST_ZIP.entry_names[3],
1243
+ zfRead.get_input_stream(TEST_ZIP.entry_names[3]) { |is| is.read })
1244
+ zfRead.close
1245
+ end
1246
+
1247
+ def test_replaceNonEntry
1248
+ entryToReplace = "nonExistingEntryname"
1249
+ ZipFile.open(TEST_ZIP.zip_name) {
1250
+ |zf|
1251
+ assert_raise(Errno::ENOENT) {
1252
+ zf.replace(entryToReplace, "data/file2.txt")
1253
+ }
1254
+ }
1255
+ end
1256
+
1257
+ def test_commit
1258
+ newName = "renamedFirst"
1259
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1260
+ oldName = zf.entries.first
1261
+ zf.rename(oldName, newName)
1262
+ zf.commit
1263
+
1264
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1265
+ assert(zfRead.entries.detect { |e| e.name == newName } != nil)
1266
+ assert(zfRead.entries.detect { |e| e.name == oldName } == nil)
1267
+ zfRead.close
1268
+
1269
+ zf.close
1270
+ end
1271
+
1272
+ # This test tests that after commit, you
1273
+ # can delete the file you used to add the entry to the zip file
1274
+ # with
1275
+ def test_commitUseZipEntry
1276
+ File.copy(TestFiles::RANDOM_ASCII_FILE1, "okToDelete.txt")
1277
+ zf = ZipFile.open(TEST_ZIP.zip_name)
1278
+ zf.add("okToDelete.txt", "okToDelete.txt")
1279
+ assert_contains(zf, "okToDelete.txt")
1280
+ zf.commit
1281
+ File.move("okToDelete.txt", "okToDeleteMoved.txt")
1282
+ assert_contains(zf, "okToDelete.txt", "okToDeleteMoved.txt")
1283
+ end
1284
+
1285
+ # def test_close
1286
+ # zf = ZipFile.new(TEST_ZIP.zip_name)
1287
+ # zf.close
1288
+ # assert_raise(IOError) {
1289
+ # zf.extract(TEST_ZIP.entry_names.first, "hullubullu")
1290
+ # }
1291
+ # end
1292
+
1293
+ def test_compound1
1294
+ renamedName = "renamedName"
1295
+ originalEntries = []
1296
+ begin
1297
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1298
+ originalEntries = zf.entries.dup
1299
+
1300
+ assert_not_contains(zf, TestFiles::RANDOM_ASCII_FILE1)
1301
+ zf.add(TestFiles::RANDOM_ASCII_FILE1,
1302
+ TestFiles::RANDOM_ASCII_FILE1)
1303
+ assert_contains(zf, TestFiles::RANDOM_ASCII_FILE1)
1304
+
1305
+ zf.rename(zf.entries[0], renamedName)
1306
+ assert_contains(zf, renamedName)
1307
+
1308
+ TestFiles::BINARY_TEST_FILES.each {
1309
+ |filename|
1310
+ zf.add(filename, filename)
1311
+ assert_contains(zf, filename)
1312
+ }
1313
+
1314
+ assert_contains(zf, originalEntries.last.to_s)
1315
+ zf.remove(originalEntries.last.to_s)
1316
+ assert_not_contains(zf, originalEntries.last.to_s)
1317
+
1318
+ ensure
1319
+ zf.close
1320
+ end
1321
+ begin
1322
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1323
+ assert_contains(zfRead, TestFiles::RANDOM_ASCII_FILE1)
1324
+ assert_contains(zfRead, renamedName)
1325
+ TestFiles::BINARY_TEST_FILES.each {
1326
+ |filename|
1327
+ assert_contains(zfRead, filename)
1328
+ }
1329
+ assert_not_contains(zfRead, originalEntries.last.to_s)
1330
+ ensure
1331
+ zfRead.close
1332
+ end
1333
+ end
1334
+
1335
+ def test_compound2
1336
+ begin
1337
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1338
+ originalEntries = zf.entries.dup
1339
+
1340
+ originalEntries.each {
1341
+ |entry|
1342
+ zf.remove(entry)
1343
+ assert_not_contains(zf, entry)
1344
+ }
1345
+ assert(zf.entries.empty?)
1346
+
1347
+ TestFiles::ASCII_TEST_FILES.each {
1348
+ |filename|
1349
+ zf.add(filename, filename)
1350
+ assert_contains(zf, filename)
1351
+ }
1352
+ assert_equal(zf.entries.sort.map { |e| e.name }, TestFiles::ASCII_TEST_FILES)
1353
+
1354
+ zf.rename(TestFiles::ASCII_TEST_FILES[0], "newName")
1355
+ assert_not_contains(zf, TestFiles::ASCII_TEST_FILES[0])
1356
+ assert_contains(zf, "newName")
1357
+ ensure
1358
+ zf.close
1359
+ end
1360
+ begin
1361
+ zfRead = ZipFile.new(TEST_ZIP.zip_name)
1362
+ asciiTestFiles = TestFiles::ASCII_TEST_FILES.dup
1363
+ asciiTestFiles.shift
1364
+ asciiTestFiles.each {
1365
+ |filename|
1366
+ assert_contains(zf, filename)
1367
+ }
1368
+
1369
+ assert_contains(zf, "newName")
1370
+ ensure
1371
+ zfRead.close
1372
+ end
1373
+ end
1374
+
1375
+ private
1376
+ def assert_contains(zf, entryName, filename = entryName)
1377
+ assert(zf.entries.detect { |e| e.name == entryName} != nil, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}")
1378
+ assert_entryContents(zf, entryName, filename) if File.exists?(filename)
1379
+ end
1380
+
1381
+ def assert_not_contains(zf, entryName)
1382
+ assert(zf.entries.detect { |e| e.name == entryName} == nil, "entry #{entryName} in #{zf.entries.join(', ')} in zip file #{zf}")
1383
+ end
1384
+ end
1385
+
1386
+ class ZipFileExtractTest < Test::Unit::TestCase
1387
+ include CommonZipFileFixture
1388
+ EXTRACTED_FILENAME = "extEntry"
1389
+ ENTRY_TO_EXTRACT, *REMAINING_ENTRIES = TEST_ZIP.entry_names.reverse
1390
+
1391
+ def setup
1392
+ super
1393
+ File.delete(EXTRACTED_FILENAME) if File.exists?(EXTRACTED_FILENAME)
1394
+ end
1395
+
1396
+ def test_extract
1397
+ ZipFile.open(TEST_ZIP.zip_name) {
1398
+ |zf|
1399
+ zf.extract(ENTRY_TO_EXTRACT, EXTRACTED_FILENAME)
1400
+
1401
+ assert(File.exists?(EXTRACTED_FILENAME))
1402
+ AssertEntry::assert_contents(EXTRACTED_FILENAME,
1403
+ zf.get_input_stream(ENTRY_TO_EXTRACT) { |is| is.read })
1404
+
1405
+
1406
+ File::unlink(EXTRACTED_FILENAME)
1407
+
1408
+ entry = zf.get_entry(ENTRY_TO_EXTRACT)
1409
+ entry.extract(EXTRACTED_FILENAME)
1410
+
1411
+ assert(File.exists?(EXTRACTED_FILENAME))
1412
+ AssertEntry::assert_contents(EXTRACTED_FILENAME,
1413
+ entry.get_input_stream() { |is| is.read })
1414
+
1415
+ }
1416
+ end
1417
+
1418
+ def test_extractExists
1419
+ writtenText = "written text"
1420
+ File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
1421
+
1422
+ assert_raise(ZipDestinationFileExistsError) {
1423
+ ZipFile.open(TEST_ZIP.zip_name) {
1424
+ |zf|
1425
+ zf.extract(zf.entries.first, EXTRACTED_FILENAME)
1426
+ }
1427
+ }
1428
+ File.open(EXTRACTED_FILENAME, "r") {
1429
+ |f|
1430
+ assert_equal(writtenText, f.read)
1431
+ }
1432
+ end
1433
+
1434
+ def test_extractExistsOverwrite
1435
+ writtenText = "written text"
1436
+ File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
1437
+
1438
+ gotCalledCorrectly = false
1439
+ ZipFile.open(TEST_ZIP.zip_name) {
1440
+ |zf|
1441
+ zf.extract(zf.entries.first, EXTRACTED_FILENAME) {
1442
+ |entry, extractLoc|
1443
+ gotCalledCorrectly = zf.entries.first == entry &&
1444
+ extractLoc == EXTRACTED_FILENAME
1445
+ true
1446
+ }
1447
+ }
1448
+
1449
+ assert(gotCalledCorrectly)
1450
+ File.open(EXTRACTED_FILENAME, "r") {
1451
+ |f|
1452
+ assert(writtenText != f.read)
1453
+ }
1454
+ end
1455
+
1456
+ def test_extractNonEntry
1457
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1458
+ assert_raise(Errno::ENOENT) { zf.extract("nonExistingEntry", "nonExistingEntry") }
1459
+ ensure
1460
+ zf.close if zf
1461
+ end
1462
+
1463
+ def test_extractNonEntry2
1464
+ outFile = "outfile"
1465
+ assert_raise(Errno::ENOENT) {
1466
+ zf = ZipFile.new(TEST_ZIP.zip_name)
1467
+ nonEntry = "hotdog-diddelidoo"
1468
+ assert(! zf.entries.include?(nonEntry))
1469
+ zf.extract(nonEntry, outFile)
1470
+ zf.close
1471
+ }
1472
+ assert(! File.exists?(outFile))
1473
+ end
1474
+
1475
+ end
1476
+
1477
+ class ZipFileExtractDirectoryTest < Test::Unit::TestCase
1478
+ include CommonZipFileFixture
1479
+ TEST_OUT_NAME = "emptyOutDir"
1480
+
1481
+ def open_zip(&aProc)
1482
+ assert(aProc != nil)
1483
+ ZipFile.open(TestZipFile::TEST_ZIP4.zip_name, &aProc)
1484
+ end
1485
+
1486
+ def extract_test_dir(&aProc)
1487
+ open_zip {
1488
+ |zf|
1489
+ zf.extract(TestFiles::EMPTY_TEST_DIR, TEST_OUT_NAME, &aProc)
1490
+ }
1491
+ end
1492
+
1493
+ def setup
1494
+ super
1495
+
1496
+ Dir.rmdir(TEST_OUT_NAME) if File.directory? TEST_OUT_NAME
1497
+ File.delete(TEST_OUT_NAME) if File.exists? TEST_OUT_NAME
1498
+ end
1499
+
1500
+ def test_extractDirectory
1501
+ extract_test_dir
1502
+ assert(File.directory?(TEST_OUT_NAME))
1503
+ end
1504
+
1505
+ def test_extractDirectoryExistsAsDir
1506
+ Dir.mkdir TEST_OUT_NAME
1507
+ extract_test_dir
1508
+ assert(File.directory?(TEST_OUT_NAME))
1509
+ end
1510
+
1511
+ def test_extractDirectoryExistsAsFile
1512
+ File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
1513
+ assert_raise(ZipDestinationFileExistsError) { extract_test_dir }
1514
+ end
1515
+
1516
+ def test_extractDirectoryExistsAsFileOverwrite
1517
+ File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
1518
+ gotCalled = false
1519
+ extract_test_dir {
1520
+ |entry, destPath|
1521
+ gotCalled = true
1522
+ assert_equal(TEST_OUT_NAME, destPath)
1523
+ assert(entry.is_directory)
1524
+ true
1525
+ }
1526
+ assert(gotCalled)
1527
+ assert(File.directory?(TEST_OUT_NAME))
1528
+ end
1529
+ end
1530
+
1531
+ class ZipExtraFieldTest < Test::Unit::TestCase
1532
+ def test_new
1533
+ extra_pure = ZipExtraField.new("")
1534
+ extra_withstr = ZipExtraField.new("foo")
1535
+ assert_instance_of(ZipExtraField, extra_pure)
1536
+ assert_instance_of(ZipExtraField, extra_withstr)
1537
+ end
1538
+
1539
+ def test_unknownfield
1540
+ extra = ZipExtraField.new("foo")
1541
+ assert_equal(extra["Unknown"], "foo")
1542
+ extra.merge("a")
1543
+ assert_equal(extra["Unknown"], "fooa")
1544
+ extra.merge("barbaz")
1545
+ assert_equal(extra.to_s, "fooabarbaz")
1546
+ end
1547
+
1548
+
1549
+ def test_merge
1550
+ str = "UT\x5\0\x3\250$\r@Ux\0\0"
1551
+ extra1 = ZipExtraField.new("")
1552
+ extra2 = ZipExtraField.new(str)
1553
+ assert(! extra1.member?("UniversalTime"))
1554
+ assert(extra2.member?("UniversalTime"))
1555
+ extra1.merge(str)
1556
+ assert_equal(extra1["UniversalTime"].mtime, extra2["UniversalTime"].mtime)
1557
+ end
1558
+
1559
+ def test_length
1560
+ str = "UT\x5\0\x3\250$\r@Ux\0\0Te\0\0testit"
1561
+ extra = ZipExtraField.new(str)
1562
+ assert_equal(extra.local_length, extra.to_local_bin.length)
1563
+ assert_equal(extra.c_dir_length, extra.to_c_dir_bin.length)
1564
+ extra.merge("foo")
1565
+ assert_equal(extra.local_length, extra.to_local_bin.length)
1566
+ assert_equal(extra.c_dir_length, extra.to_c_dir_bin.length)
1567
+ end
1568
+
1569
+
1570
+ def test_to_s
1571
+ str = "UT\x5\0\x3\250$\r@Ux\0\0Te\0\0testit"
1572
+ extra = ZipExtraField.new(str)
1573
+ assert_instance_of(String, extra.to_s)
1574
+
1575
+ s = extra.to_s
1576
+ extra.merge("foo")
1577
+ assert_equal(s.length + 3, extra.to_s.length)
1578
+ end
1579
+
1580
+ def test_equality
1581
+ str = "UT\x5\0\x3\250$\r@"
1582
+ extra1 = ZipExtraField.new(str)
1583
+ extra2 = ZipExtraField.new(str)
1584
+ extra3 = ZipExtraField.new(str)
1585
+ assert_equal(extra1, extra2)
1586
+
1587
+ extra2["UniversalTime"].mtime = Time.now
1588
+ assert(extra1 != extra2)
1589
+
1590
+ extra3.create("IUnix")
1591
+ assert(extra1 != extra3)
1592
+
1593
+ extra1.create("IUnix")
1594
+ assert_equal(extra1, extra3)
1595
+ end
1596
+
1597
+ end
1598
+
1599
+ # Copyright (C) 2002-2005 Thomas Sondergaard
1600
+ # rubyzip is free software; you can redistribute it and/or
1601
+ # modify it under the terms of the ruby license.