zip 2.0.2

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