zip 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.